memberchk/2
次の回答は、 ;に関する元の質問とは直接関係ありません。代わりに、 meta-predicateを定義したこの以前の回答へのフォローアップです。 tmember/2
イディオムtmember/2
を次のように一般化することを提案します。
t_non_empty_suffix(P_3, [X|Xs]) :-
if_(call(P_3,Xs,X), true, t_non_empty_suffix(P_3,Xs)).
Prolog lambdasに基づいて構築するt_non_empty_suffix/2
と、次のように定義できます。tmemberX/2
:- use_module(ライブラリ(ラムダ) ).
tmemberX(P_2, Xs) :-
t_non_empty_suffix(P_2+\_^call(P_2), Xs)。
の代わりに以下old_memberX/2
をold_memberdX/2
使用します。tmemberX/2
tmember/2
old_memberX(X, Xs) :-
tmemberX(X+\E^T^( X = E, T = true ; T = false ), Xs).
old_memberdX(X, Xs) :-
tmemberX(=(X), Xs).
old_member/2
比較してみましょう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.
...old_memberd/2
そして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.
わかった!old_member
/old_memberd
に基づいて直接定義するのはどう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).
これらの述語を使用して上記のクエリを実行すると、次のようになります。
?- 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.
大丈夫!前と同じ結果。
もう少し掘り下げてみましょう!t_non_empty_suffix/2
検討のためのショーケースとしてduplicate_in/2
。
、Prolog ラムダ 、、を使用
して、以下を定義します。t_non_empty_suffix/2
(=)/3
memberd_t/3
','(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).
サンプルクエリ:
?- duplicate_in(X, [1,2,3,2,3,4,3,4,5])。
X = 2 % [1, 2 ,3, 2 ,3,4,3,4,5] (2 が 2 回発生)
; X = 3 % [1,2, 3 ,2, 3 ,4, 3 ,4,5] (3 が 3 回発生)
; X = 4 % [1,2,3,2,3, 4 ,3, 4 ,5] (4 が 2 回発生)
; 間違い。