gpt4 book ai didi

prolog - Memberchk/2的声明性使用

转载 作者:行者123 更新时间:2023-12-03 14:19:44 27 4
gpt4 key购买 nike

memberchk/2是一个常用定义的谓词,它是根据member/2定义的,如下所示:

memberchk(X, Xs) :-
once(member(X, Xs)).


因此,它仅对 member/2的第一个答案成功。它的完整的程序含义并不适合纯粹的关系。作为其非关系行为的示例,请考虑

?- memberchk(b, [X,b]), X = a.
false.

?- X = a, memberchk(b, [X,b]).
X = a.


另一方面,在许多情况下, memberchk/2都将使用足够实例化的参数来调用,在这种情况下,可以将其视为对纯关系的有效近似。

memberd/2(使用 if_/3)是这样的一种纯关系:

memberd(E, [X|Xs]) :-
if_(E = X, true, memberd(E, Xs) ).


对于足够实例化的情况,还有没有其他可以由 memberchk/2近似的纯关系?

换句话说: memberd/2是对 memberchk/2的完全声明式替换吗?还是在某些合法情况下 memberchk/2无法用 memberd/2替换?

最佳答案

这是member/2不能用memberd/2表示的一个著名示例用法:bridge.pl Pascal Van Hentenryck给出的桥调度问题。

在设置阶段,使用member/2

setup(K,Ende,Disj):-
jobs(L),
make_vars(L,K),
member([stop,_,Ende],K),
....


因此,在这里,有效地使用三元素列表中的第一个元素来选择特定任务,而 memberd/2使用整个元素进行比较。结果,此 setup/3留下了许多选择点(实际上是219个)。有些情况(例如SICStus)在这种情况下使用 memberchk/2,因此存在非单调性的风险。

使用以下纯替代品,可以避免所有选择点。

member3l([N,D,A], Plan) :-
tmember(l3_t(N,D,A), Plan).

l3_t(N,D,A, X, T) :-
X = [Ni|_],
if_(N = Ni, ( X=[N,D,A], T = true ), T = false ).

tmember(P_2, [X|Xs]) :-
if_( call(P_2, X), true, tmember(P_2, Xs) ).


或者使用 library(lambda)

member3li([N,Nd,Na], Plan) :-
tmember([N,Nd,Na]+\X^T^
( X=[Nk|_],
if_( Nk = N, ( X=[N,Nd,Na], T = true ), T = false ) ),
Plan).


tmember/2的其他用途:

old_member(X, Xs) :-
tmember( X+\E^T^( X = E, T = true ; T = false ), Xs).

old_memberd(X, Xs) :-
tmember(=(X), Xs).


这是一个更紧凑的表示形式:

member3l([N,D,A], Plan) :-
tmember({N,D,A}+\[Ni,Di,Ai]^cond_t(N = Ni, [D,A] = [Di,Ai] ), Plan).


使用 library(lambda)cond_t/3

cond_t(If_1, Then_0, T) :-
if_(If_1, ( Then_0, T = true ), T = false ).

关于prolog - Memberchk/2的声明性使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33328762/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com