-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.
谢谢你的解释。 –
如果您对此答案满意,请点击旁边的复选标记以“接受”。 –