2010-11-02 71 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