-1
我一直在尋找在序言PROGRM和無法理解以下如何在prolog中編寫早期語句?
earlier(X, _, [X|_]).
earlier(_, Y, [Y|_]) :- !, fail.
earlier(X, Y, [_|T]) :- earlier(X, Y, T).
誰能解釋這是什麼意思?
我一直在尋找在序言PROGRM和無法理解以下如何在prolog中編寫早期語句?
earlier(X, _, [X|_]).
earlier(_, Y, [Y|_]) :- !, fail.
earlier(X, Y, [_|T]) :- earlier(X, Y, T).
誰能解釋這是什麼意思?
顧名思義,earlier(X, Y, Zs)
顯然應該檢查元素X
是否早於列表Zs
中的第一個出現Y
。它種做到這一點:
?- earlier(a, b, [a, b, c, d]).
true ;
false.
?- earlier(b, d, [a, b, c, d]).
true ;
false.
憑藉獨特的處理,如果第二個參數是不是在給定列表:
?- earlier(a, not_in_list, [a, b, c, d]).
true ;
false.
這是如何工作的?第一個條款說,如果X
是列表的頭部,則X
出現在列表的前面,而不是任何內容,由匿名變量_
表示。第二個條款說,如果Y
是列表的頭部,則沒有任何內容(_
在第一個參數位置)在Y
之前。在這種情況下,謂詞失敗並使用剪切來避免發現虛假解。第三個條款只適用於第一個和第二個條款的列表。
由於切,這個定義不是很聲明,併爲人們所預料的一些有趣的用途不起作用:
?- earlier(X, Y, Zs).
Zs = [X|_G947] ;
false.
?- earlier(a, b, Zs).
Zs = [a|_G923] ;
false.
?- earlier(X, Y, [a, b, c, d]).
X = a ;
false.
最後一種情況,特別是可能對某些使用案例有趣。這裏是一個更聲明版本:
earlier_than(X, Y, Zs) :-
append(InitialPart, [X | _Rest], Zs),
notmember_of(Y, InitialPart).
notmember_of(_X, []).
notmember_of(X, [Y|Xs]) :-
dif(X, Y),
notmember_of(X, Xs).
你可以使用這個更漂亮列舉的解決方案:
?- earlier_than(X, Y, Zs).
Zs = [X|_G947] ;
Zs = [_G1162, X|_G1166],
dif(Y, _G1162) ;
Zs = [_G1254, _G1257, X|_G1261],
dif(Y, _G1257),
dif(Y, _G1254) ;
Zs = [_G1346, _G1349, _G1352, X|_G1356],
dif(Y, _G1352),
dif(Y, _G1349),
dif(Y, _G1346) .
?- earlier_than(a, b, Zs).
Zs = [a|_G923] ;
Zs = [_G1086, a|_G1090],
dif(_G1086, b) ;
Zs = [_G1169, _G1172, a|_G1176],
dif(_G1169, b),
dif(_G1172, b) ;
Zs = [_G1252, _G1255, _G1258, a|_G1262],
dif(_G1252, b),
dif(_G1255, b),
dif(_G1258, b) .
?- earlier_than(X, Y, [a, b, c, d]).
X = a ;
X = b,
dif(Y, a) ;
X = c,
dif(Y, b),
dif(Y, a) ;
X = d,
dif(Y, c),
dif(Y, b),
dif(Y, a) ;
false.
就個人而言,如果規範允許,我會還新增了member(Y, Rest)
到earlier_than/3
定義。這使事情更好:
?- earlier_than(X, Y, Zs).
Zs = [X, Y|_G950] ;
Zs = [X, _G949, Y|_G953] ;
Zs = [X, _G949, _G952, Y|_G956] .
?- earlier_than(a, b, Zs).
Zs = [a, b|_G926] ;
Zs = [a, _G925, b|_G929] ;
Zs = [a, _G925, _G928, b|_G932] .
?- earlier_than(X, Y, [a, b, c, d]).
X = a,
Y = b ;
X = a,
Y = c ;
X = a,
Y = d ;
X = b,
Y = c ;
X = b,
Y = d ;
X = c,
Y = d ;
false.
謝謝你的解釋。 –
如果您對此答案滿意,請點擊旁邊的複選標記以「接受」。 –