[英]Prolog: removing all elements that occur in list A from list B
我試圖定義一個謂詞“ delete(L1,L2,L3)”,當L3等於L2減去L1中包含的任何這些元素時,該謂詞有效。 例如delete([1],[1,2,3],X)=>對於X = [2,3]將統一。 我的代碼如下:
isNonElement(_, []).
isNonElement(X, [Y|Z]) :- X \= Y, isNonElement(X,Z).
delete(_, [], []).
delete(Y, [X|W], Z) :- \+(isNonElement(X, Y)), delete(Y, W, Z).
delete(Y, [X|W], [X|Z]) :- isNonElement(X, Y), delete(Y, W, Z).
但是,這似乎不適用於每個測試用例。 誰能幫助我解決我的代碼可能存在的問題?
提前致謝!
最好的問候,Skyfe。
PS:我無法斷定我的謂詞無法正常運行的情況,因為它是由學校系統測試的,該系統無法告訴我它針對哪些測試用例失敗了。
你很親密 !
剩下的一個問題是,您正在對不允許這種讀法的謂詞應用完全合理的邏輯推理。 如果您僅應用以下極其簡單的更改,則您的代碼將按預期工作:
(\\=)/2
,使用dif/2
\\+(isNonElement(X, Y))
,只需編寫: member(X, Y)
。 始終建議進行第一個更改:通常可以使程序在更多方向上可用。 第二個更改是通過使用純謂詞來避免使用不純否定。
總的來說,我們現在有:
isNonElement(_, []). isNonElement(X, [Y|Z]) :- dif(X, Y), isNonElement(X,Z). delete(_, [], []). delete(Y, [X|W], Z) :- member(X, Y), delete(Y, W, Z). delete(Y, [X|W], [X|Z]) :- isNonElement(X, Y), delete(Y, W, Z).
現在檢查一下:首先,您的測試用例:
?- delete([1], [1,2,3], X). X = [2, 3] ; false.
可以正常工作!
其次,一個L2
變量的情況:
?- delete([], L2, []). L2 = [] ; false.
這似乎也很好。
第三,另一個變量:
?- delete([X], [1,2,3], Ls3). X = 1, Ls3 = [2, 3] ; X = 2, Ls3 = [1, 3] ; X = 3, Ls3 = [1, 2] ; Ls3 = [1, 2, 3], dif(X, 3), dif(X, 2), dif(X, 1) ; false.
現在請注意X
的不同可能性,以及在答案中如何使用dif/2
來表示X
在這種情況下必須與某些整數不同 。
不純謂詞的使用會排除這種更一般的用法,您的評分系統也可能會嘗試這種情況。
請注意,您當然可以輕松地自己實現member/2
。 這是最直接的關系之一。 但是,也請注意delete/3
的命名非常嚴格: 命令式總是表示特定的使用方向,但是我們在此考慮的關系也允許許多其他使用方式!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.