变量列表中的变量出现

fal*_*lse 18 prolog iso-prolog

考虑一个(元逻辑)谓词var_in_vars(Var, Vars),它采用变量Var和变量列表,Vars如果Var出现则成功Vars.所以我们不需要确保它Var是变量,也不Vars是变量列表.

在ISO Prolog中表达这一点的最紧凑和规范的方法是什么?以下是ISO/IEC 13211-1:1995中内置插件概述,包括Cor.2:2012.

?- var_in_vars(V, [U,V,W]).
true.

?- var_in_vars(V, [X,Y,Z]).
false.
Run Code Online (Sandbox Code Playgroud)

mat*_*mat 8

一种可能性:

var_in_vars(V, Vs) :- \+ unify_with_occurs_check(V, Vs).
Run Code Online (Sandbox Code Playgroud)

更短:

var_in_vars(V, Vs) :- \+ subsumes_term(V, Vs).
Run Code Online (Sandbox Code Playgroud)

编辑:未来的读者,请考虑问题的背景,这是一个特定的紧凑性挑战,涉及在特定情况下ISO谓词的表达性.

在其他情况下,您可能会从以下定义中获益更多:

var_in_vars(V, Vs) :-
        must_be(list, Vs),
        once((member(X, Vs), V == X)).
Run Code Online (Sandbox Code Playgroud)


Cap*_*liC 7

这个定义通过了测试,但是......我是否会错过一些微妙之处?

var_in_vars(V, [H|_]) :- V == H, !.
var_in_vars(V, [_|T]) :- var_in_vars(V, T).
Run Code Online (Sandbox Code Playgroud)

  • 非常好的第一次尝试!参与需要勇气 - > +1! (2认同)

fal*_*lse 5

这是另一个,虽然有点复杂:

var_in_vars(V, Vs) :-
   term_variables(Vs+V, Ws),
   Ws == Vs.
Run Code Online (Sandbox Code Playgroud)

所以这依赖于变量访问的精确顺序.由于这在标准中得到了很好的定义,我们可以依赖它们

...根据他们在从左到右遍历中的第一次出现...

该定义的缺点是它具有与长度成比例的最小成本Vs.但由于内部遍历通常非常有效地实现,因此这不是一个问题.

它有一个很大的优点:只有Vs变量列表才能成功.