自反傳遞閉包的定義許多謂詞本質(zhì)上使用某種形式的傳遞閉包,結(jié)果發(fā)現(xiàn)終止也必須解決。為什么不一勞永逸地用closure0/3::- meta_predicate closure0(2,?,?).
:- meta_predicate closure(2,?,?).
:- meta_predicate closure0(2,?,?,+). % internal
closure0(R_2, X0,X) :-
closure0(R_2, X0,X, [X0]).
closure(R_2, X0,X) :-
call(R_2, X0,X1),
closure0(R_2, X1,X, [X1,X0]).
closure0(_R_2, X,X, _).
closure0(R_2, X0,X, Xs) :-
call(R_2, X0,X1),
non_member(X1, Xs),
closure0(R_2, X1,X, [X1|Xs]).
non_member(_E, []).
non_member(E, [X|Xs]) :-
dif(E,X),
non_member(E, Xs).是否有這種定義不能用于實(shí)現(xiàn)傳遞閉包的情況?為什么是dif/2?要詳細(xì)回答@WouterBeek的評(píng)論:dif/2或iso_dif/2是理想的,因?yàn)樗麄兡軌蝻@示或暗示潛在的問題。然而,在當(dāng)前的實(shí)現(xiàn)中,頂層循環(huán)常常隱藏實(shí)際問題??紤]一下目標(biāo)closure0(\_^_^true,a,b)這本身就有相當(dāng)大的問題。當(dāng)使用以下系統(tǒng)時(shí),實(shí)際問題直接不可見。| ?- closure0(\_^_^true,a,b). % SICStus
yes
?- closure0(\_^_^true,a,b). % SWI
true ;
true ;
true ...兩個(gè)頂級(jí)循環(huán)都沒有顯示我們真正想看到的東西:懸空約束。在SICStus中,我們需要一個(gè)偽變量來產(chǎn)生某種替換,在SWI中,查詢必須用call_residue_vars/2..現(xiàn)在以這種方式顯示所有附加約束的變量。| ?- closure0(\_^_^true,a,b), Alt=t. % SICStus
Alt = t ? ;
Alt = t,
prolog:dif(_A,a),
prolog:dif(b,_A) ? ;
Alt = t,
prolog:dif(_A,a),
prolog:dif(_B,_A),
prolog:dif(_B,a),
prolog:dif(b,_B),
prolog:dif(b,_A) ...
?- call_residue_vars(closure0(\_^_^true,a,b),Vs). % SWI
Vs = [] ;
Vs = [_G1744, _G1747, _G1750],
dif(_G1744, a),
dif(b, _G1744) ;
Vs = [_G1915, _G1918, _G1921, _G1924, _G1927, _G1930, _G1933],
dif(_G1915, a),
dif(b, _G1915),
dif(_G1921, _G1915),
dif(_G1921, a),
dif(b, _G1921) ...
自反傳遞閉包的定義
小唯快跑啊
2019-07-02 11:26:39