[英]Python . How to sort elements of sub-list if second elements are equal sort the sub-lists by first element
[英]Prolog check if first element in lists are not equal and second item in list is equal
我想比較2個列表,第一個元素不應該相等,第二個元素應該相等。
示例數據庫:
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
因此,對於同一個([josh,muse],[sam,muse]),它應該返回true。
這是我到目前為止嘗試過的:
same([H1|R1], [H2|R2]):-
H1 \= H2,
same(R1,R2).
每種組合都返回false。
在same/2
謂詞的定義中使用的列表的[Head|Tail]
Prolog表示法可用於訪問列表head和tail 。 列表的尾部本身就是一個(可能為空)列表。 但是在您的情況下,您想訪問第一個和第二個元素,您可以通過編寫[First, Second| _]
[First, Second| _]
(即枚舉用逗號分隔的元素;這里我在尾部使用匿名變量 ,因為我們不需要它,因此可以忽略它)。
您的謂詞可以通過將其重寫為:
same([F1,S1|_], [F2,S2|_]):-
F1 \== F2,
S1 == S2.
如果您知道參數始終是包含兩個元素的列表,則可以將謂詞簡化為:
same([F1,S1], [F2,S2]):-
F1 \== F2,
S1 == S2.
通話樣本:
?- same([josh,muse], [sam,muse]).
true.
?- same([sam,muse], [sam,muse]).
false.
?- same([josh,muse], [sam,maria]).
false.
最后一點,您的問題是關於術語相等的,但在解決方案嘗試中,您正在使用術語統一 。 它們具有不同的語義,不應混淆。
在閱讀您的問題時,您首先提供了一個事實數據庫
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
但隨后將列表用作謂詞
same([josh,muse], [sam,muse]).
Paulo從列表開始回答,我將從事實開始回答。
首先是創建一個謂詞,以讀取事實,進行一些邏輯運算並返回結果。
same_1(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item).
這使
?- same_1(P1,P2,Item).
P1 = P2, P2 = josh,
Item = muse ;
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
P1 = P2, P2 = sam,
Item = muse ;
P1 = P2, P2 = josh,
Item = gnr ;
P1 = P2, P2 = sam,
Item = radiohead.
因此,這需要確保P1與P2不同。
same_2(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item),
P1 \= P2.
這使
?- same_2(P1,P2,Item).
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
仍然有兩個答案是有效的,但實際上是重復的。 要刪除這些重復項,需要存儲所有結果,以便可以對照現有結果檢查每個新結果,而不將其添加到當前結果中。 同樣,在存儲結果之前,還需要對它們進行規范化處理,以便無論在最初創建時以哪種方式對名稱進行排序,在保存之前進行比較時,它們的順序都相同。
修改代碼以創建規范化的條目。
same_3(P1,P2,Item) :-
likes(T1,Item),
likes(T2,Item),
T1 \= T2,
normalize(T1,T2,P1,P2).
normalize(P1,P2,P1,P2) :- P1 @> P2.
normalize(P1,P2,P2,P1) :- P1 @=< P2.
哪個返回
?- same_3(P1,P2,Item).
P1 = sam,
P2 = josh,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
請注意,此結果的名稱順序相同。
現在只保存結果生成的結果,並僅向結果添加唯一項。 這是使用setof / 3完成的 。
?- setof((P1,P2,Item),(same_3(P1,P2,Item)),Bag).
Bag = [(sam, josh, muse)].
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.