簡體   English   中英

序言:從列表B中刪除列表A中出現的所有元素

[英]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:我無法斷定我的謂詞無法正常運行的情況,因為它是由學校系統測試的,該系統無法告訴我它針對哪些測試用例失敗了。

很親密

剩下的一個問題是,您正在對不允許這種讀法的謂詞應用完全合理的邏輯推理。 如果您僅應用以下極其簡單的更改,則您的代碼將按預期工作:

  1. 代替(\\=)/2 ,使用dif/2
  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM