变量列表中的变量出现

时间:2014-12-09 21:28:47

标签: prolog iso-prolog

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

在ISO Prolog中表达这一点的最紧凑和规范的方法是什么?这是ISO / IEC 13211-1:1995中的overview of the built-ins,包括Cor.2:2012。

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

?- var_in_vars(V, [X,Y,Z]).
false.

6 个答案:

答案 0 :(得分:8)

一种可能性:

var_in_vars(V, Vs) :- \+ unify_with_occurs_check(V, Vs).

和更短:

var_in_vars(V, Vs) :- \+ subsumes_term(V, Vs).

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

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

var_in_vars(V, Vs) :-
        must_be(list, Vs),
        once((member(X, Vs), V == X)).

答案 1 :(得分:7)

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

var_in_vars(V, [H|_]) :- V == H, !.
var_in_vars(V, [_|T]) :- var_in_vars(V, T).

答案 2 :(得分:5)

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

var_in_vars(V, Vs) :-
   term_variables(Vs+V, Ws),
   Ws == Vs.

所以这依赖于变量访问的精确顺序。由于标准中这是well defined,我们可以依赖它们

  

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

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

它有一个很大的优势:只有Vs是变量列表才能成功。

答案 3 :(得分:2)

另一种解决方案是:

var_in_vars(V, Vs) :-
    \+ (V = Vs, acyclic_term(Vs)).

但是@mat的解决方案更好,更优雅,而@CapelliC的解决方案在很长一段时间内是最便携的解决方案(subsumes_term/2谓词最近才被标准化,并非所有系统都提供{{1谓词)。

答案 4 :(得分:2)

解决方案@false可以简化为:

var_in_vars(V, Vs) :-
    term_variables(Vs+V, Vs).

VVs列表的成员时,第二个参数返回Vs(由于Vs+V项的从左到右的遍历)。当V不是Vs的成员时,第二个参数返回的列表中包含的元素多于Vs,因此无法与其统一。虽然在第二个论证中存在隐含的统一,但在任何情况下都不存在创建循环术语的危险。即统一是STO在这个简化的解决方案中不是问题。

但是简化值得它w.r.t.性能?使用等式(==)/2有可能提前失败,从而使原始解决方案更快。

答案 5 :(得分:0)

溶液合成

解决方案: 简短

var_in_vars(V, Vs) :- \+ subsumes_term(V, Vs).

备选方案1: 简单

var_in_vars(V, Vs) :- \+ unify_with_occurs_check(V, Vs).

备选方案2: 视情况而定,这可能更合适

var_in_vars(V, Vs) :-
        must_be(list, Vs),
        once((member(X, Vs), V == X)).

备选方案3: 更复杂

var_in_vars(V, Vs) :-
   term_variables(Vs+V, Ws),
   Ws == Vs.

备选方案4: 其他可能性

var_in_vars(V, [H|_]) :- V == H, !.
var_in_vars(V, [_|T]) :- var_in_vars(V, T).

链接:

Standard

注意:问题的上下文,这是一个特定的紧凑性挑战,涉及在特定情况下ISO谓词的表达性。

相关问题