簡體   English   中英

Prolog檢查列表中的第一個元素是否不相等,列表中的第二個元素是否相等

[英]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表示法可用於訪問列表headtail 列表的尾部本身就是一個(可能為空)列表。 但是在您的情況下,您想訪問第一個和第二個元素,您可以通過編寫[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.

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