2014-01-11 90 views
0

我已經寫了下面的代碼在序言:的Prolog變量變得沒有價值

contains(L1, []). 
contains(L1, [X | T2]) :- member(X, L1), contains(L1, T2). 

minus(L, [], L). 
minus(L1, L2, L3) :- contains(L1, L3), nomembers(L3, L2). 

nomembers(L1, []). 
nomembers(L1, [X | T2]) :- not(member(X, L1)), nomembers(L1, T2). 

contains(L1, L2)返回true,如果所有在L2成員出現在L1。 (contains([1,2],[1,1,1])是真的)。

minus(L1, L2, L3)返回true,如果L3=L1\L2,意思L3L1成員但不是L2

當我問minus([1,2,3,4],[2,1],L),我得到的答案是L=[],雖然邏輯上它應該是L=[3,4]。有人知道爲什麼嗎?

+1

問題出在'contains/2'上。儘管'contains/2'在兩個變量都被實例化時給出了正確的響應,如果你查詢,比如說'contains([a,b],L)',它將生成'L = []',那麼'L = [a ]',那麼'L = [a,a]'等等。因此,在你的「minus/3」謂詞中包含(L1,L3)的查詢沒有做你想要的。 – lurker

回答

1

以上評論mbratch是非常有幫助的。

注意,您目前的minus(L1, L2, L3)的定義是:的L3所有成員都在L1並沒有從L3構件處於L2

序言給你很好的答案L3 = [],它適合我上面寫的定義。

編輯:下面的代碼應該做你想做的,但是目前我沒有在我的電腦上使用prolog,所以我無法測試它。

remove(X, [X|T], T) :- !. 
remove(X, [H|T], [H|T2]) :- remove(X, T, T2). 

minus(L1,[],L1). 
minus(L1,[H|T2],T3) :- member(H, L1), !, remove(H,L1,L4), minus(L4, T2, T3). 
minus(L1,[H|T2],[H|T3]) :- minus(L1, T2, T3). 

remove(X,LA,LB)它說:LBLA沒有它的X第一次出現,所以它只是從列表中刪除元素。

+0

該代碼不起作用,但它給了我另一個思考方向。我會盡量在後面解決。謝謝:) –

+0

現在檢查。現在應該是好的,在'swi-prolog'上測試。 ':)' –

+0

非常感謝! –