memberchk/2 的声明式使用 [英] Declarative uses of memberchk/2

查看:10
本文介绍了memberchk/2 的声明式使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

memberchk/2 is a commonly defined predicate that is defined in terms of member/2 like so:

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

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

It therefore succeeds only for the first answer of member/2. Its full procedural meaning does not fit into a pure relation. As an example for its non-relational behavior consider

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

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

另一方面,在许多情况下,memberchk/2 将使用 充分实例化 参数调用,在这种情况下,它可以被视为纯关系的有效近似.

On the other hand, in many cases memberchk/2 will be called with sufficiently instantiated arguments, where it can be seen as an efficient approximation of a pure relation.

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

One such pure relation behind is memberd/2 (using if_/3):

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

对于充分实例化的情况,是否有任何其他可以通过 memberchk/2 近似的纯关系?

Are there any other pure relations that can be approximated by memberchk/2 for sufficiently instantiated cases?

换句话说:memberd/2memberchk/2 的完整声明式替代,还是仍然存在 memberchk/2 的合法情况> 不能用 memberd/2 代替吗?

In other words: Is memberd/2 a full, declarative replacement for memberchk/2 or are there still legitimate cases where memberchk/2 cannot be replaced by memberd/2?

推荐答案

这里有一个众所周知的使用 member/2 的例子,它不能用 memberd/2: bridge.pl Pascal Van Hentenryck 给出的桥梁调度问题.

Here is a well-known example use of member/2 that cannot be represented by memberd/2: bridge.pl the bridge scheduling problem given by 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,从而冒着非单调性的风险.

So here, effectively the first element in the three-element list is used to select a particular task whereas memberd/2 uses the entire element for comparison. As a consequence this setup/3 leaves open a lot of choicepoints (actually, 219). Some (like SICStus) use memberchk/2 in that situation, thereby risking non-monotonicity.

使用以下纯替换,可以避免所有选择点.

Using the following pure replacement, all choicepoints are avoided.

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).

这是一个更紧凑的表示:

Here is a more compact representation:

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 ).

这篇关于memberchk/2 的声明式使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆