[英]why do you define a rule twice in prolog
follows(A, B, Seen) :- not_member(B, Seen); isFriendsWith(A, B).
follows(A, B, Seen) :- isFriendsWith(A, X), not_member(X, Seen), follows(X, B, [X|Seen]).
為什么相同的規則被定義了兩次。 當您運行查詢時,如果第一條規則為真。 是否解決。
這在某種程度上是 Prolog 解析過程的核心。
假設您在問題中定義了上述規則,另外還有一些事實:
isFriendsWith(john,mary).
isFriendsWith(mary,peter).
然后查詢
?- follows(john, Who, []);
首先嘗試第一個規則(因為它是第一個)並返回:
Who = mary
因為 isFriendsWith 事實將 X 與 mary 匹配。
但你不高興,所以你通過輸入詢問更多的答案
;
這導致 Prolog回溯。 實際上,Prolog 將回溯其步驟,尋找替代的事實和規則。 在這里沒有關於約翰與任何人成為朋友的其他事實,所以第一條規則失敗了。
第二條規則生效,Prolog 試圖證明(在模式匹配之后):
isFriendsWith(john, X),
not_member(X, []),
follows(X, B, [X]).
它找到了一個事實(再次,但它應用了一個新規則)X=mary,它不在空列表中,然后去證明
follows(mary, B, [mary])
這確實有一個解決方案,因為瑪麗是彼得的朋友,所以系統已經證明了第二個結果和答案:
Who = mary
如果此時詢問更多證據,系統會再次回溯並尋求規則的更多應用。 只有這兩個事實沒有,所以系統回答
no
並返回。
總體而言,您的兩個規則導致系統通過“isFriendsWith”圖遞歸地識別所有“跟隨”路徑。 Seen 列表是為了確保它不遵循會導致它無限循環的循環路徑。
如果你覺得這個例子令人困惑,首先在 Prolog 中查找回溯的例子。 它對其定理證明器至關重要,沒有它您將無法理解任何 Prolog。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.