2010-11-02 84 views
1

使用SWI-Prolog的上市謂詞(或SICStus'在其列表庫謂語)之間的差異,我們有:序言 - 兩個列表但

lists:subtract([], _, []) :- !. 
lists:subtract([A|C], B, D) :- 
    memberchk(A, B), !, 
    subtract(C, B, D). 
lists:subtract([A|B], C, [A|D]) :- 
    subtract(B, C, D). 

它做到這一點成功:

?- subtract([2,3,4,5],[3,4],X). 
X = [2, 5]. 

BUT ,如果我想做的事:

?- new_subtract([2,3,4,5],[3,X],Y). 
X = [3, 2], 
X = [3, 4], 
X = [3, 5], 

y時,有通過採取從三個X解決方案的三種解決方案[2,3,4,5]。

但是,減/ 2不允許這樣做。

我一直試圖通過從內置的謂詞體中取出切割(!)來試圖解決這個問題,並試圖讓它回溯並找到所有的解決方案。

回答

4

我假定你的意思

?- new_subtract([2,3,4,5],[3,X],Y). 
Y = [3, 2] ; 
Y = [3, 4] ; 
Y = [3, 5] 

下面的定義確實如此,但不保留所有的subtract/3的行爲:

sub(List,[],List). 
sub(List,[X|Sub],Rem) :- select(X,List,Rem0), sub(Rem0,Sub,Rem). 

用法:

?- sub([2,3,4,5],[3,X],Y). 
X = 2, 
Y = [4, 5] ; 
X = 4, 
Y = [2, 5] ; 
X = 5, 
Y = [2, 4] ; 
false. 
+1

再次感謝larsmans ,現在我明白這一點非常簡單!保持良好的工作 :)。 – ale 2010-11-02 12:46:20