The following answer does not directly relate to the original question regarding memberchk/2
; instead, it is a follow-up to this previous answer which defined meta-predicate tmember/2
.
We propose generalizing the idiom tmember/2
like so:
t_non_empty_suffix(P_3, [X|Xs]) :-
if_(call(P_3,Xs,X), true, t_non_empty_suffix(P_3,Xs)).
Building on t_non_empty_suffix/2
and Prolog lambdas, we can define tmemberX/2
like so:
:- use_module(library(lambda)).
tmemberX(P_2, Xs) :-
t_non_empty_suffix(P_2+\_^call(P_2), Xs).
The following old_memberX/2
and old_memberdX/2
use tmemberX/2
instead of tmember/2
:
old_memberX(X, Xs) :-
tmemberX(X+\E^T^( X = E, T = true ; T = false ), Xs).
old_memberdX(X, Xs) :-
tmemberX(=(X), Xs).
Let's compare old_member/2
to old_memberX/2
...
?- old_member(X, [1,2,3,2,3,4,3,4,5]).
X = 1 ; X = 2 ; X = 3 ; X = 2 ; X = 3 ; X = 4 ; X = 3 ; X = 4 ; X = 5 ; false.
?- old_memberX(X, [1,2,3,2,3,4,3,4,5]).
X = 1 ; X = 2 ; X = 3 ; X = 2 ; X = 3 ; X = 4 ; X = 3 ; X = 4 ; X = 5 ; false.
... and old_memberd/2
to old_memberdX/2
!
?- old_memberd(X, [1,2,3,2,3,4,3,4,5]).
X = 1 ; X = 2 ; X = 3 ; X = 4 ; X = 5 ; false.
?- old_memberdX(X, [1,2,3,2,3,4,3,4,5]).
X = 1 ; X = 2 ; X = 3 ; X = 4 ; X = 5 ; false.
OK! How about defining old_member
/ old_memberd
directly based on t_non_empty_suffix/2
?
old_memberSFX(X, Xs) :-
t_non_empty_suffix(X+\_^E^T^( X = E, T = true ; T = false ), Xs).
old_memberdSFX(X, Xs) :-
t_non_empty_suffix(X+\_^E^( X = E ), Xs).
Running above queries with these predicates we get:
?- old_memberSFX(X, [1,2,3,2,3,4,3,4,5]).
X = 1 ; X = 2 ; X = 3 ; X = 2 ; X = 3 ; X = 4 ; X = 3 ; X = 4 ; X = 5 ; false.
?- old_memberdSFX(X, [1,2,3,2,3,4,3,4,5]).
X = 1 ; X = 2 ; X = 3 ; X = 4 ; X = 5 ; false.
Alright! Same results as before.
Let's dig a bit deeper! As a show-case for t_non_empty_suffix/2
consider duplicate_in/2
.
Using t_non_empty_suffix/2
, Prolog lambdas, (=)/3
, and memberd_t/3
we define:
','(P_1, Q_1, T) :-
if_(P_1, call(Q_1,T), T = false).
duplicate_in(X, Xs) :-
t_non_empty_suffix(X+\Es^E^( X = E, memberd_t(E, Es) ), Xs).
Sample query:
?- duplicate_in(X, [1,2,3,2,3,4,3,4,5]).
X = 2 % [1,2,3,2,3,4,3,4,5] (2 occurs twice)
; X = 3 % [1,2,3,2,3,4,3,4,5] (3 occurs thrice)
; X = 4 % [1,2,3,2,3,4,3,4,5] (4 occurs twice)
; false.