Prolog:var,nonvar和ground之间的区别

时间:2020-08-17 18:00:18

标签: prolog

在Prolog中,尤其是在元编程方面,人们经常谈论 ground non-ground 变量。以及使用诸如 var / 1 nonvar / 1 ground / 1 之类的谓词。但是它们之间的区别到底是什么?

我目前的理解如下:

  • var 完全未被实例化(例如X)
  • 实例化了 nonvar ,但可能包含一些更深的变量(例如term(1,2,Y))。这类似于Haskell的弱头法线形式。
  • 地面变量被完全实例化,一直向下(例如term(1,2,3))。

这正确吗?

1 个答案:

答案 0 :(得分:0)

近。

  • 如果var(X),则变量X表示未实例化的“孔”。 X是“新鲜变量”。 注意:该谓词应确实命名为fresh(...)X是否为变量实际上是有关程序文本的问题。但是我们想知道的是,括号之间的内容是否为新鲜变量(在进行调用的那一刻,因为在逻辑上这是可以改变的)。

  • nonvar(X)只是var(X)的补语,与\+ var(X)相同。括号之间的任何内容表示某事(如果它是变量)或 某事(如果它是不变变量,例如nonvar(foo))不是“空洞”。

  • ground(X)意味着括号之间的任何内容表示某种东西,或者其结构上没有孔(实际上,该术语的叶子上没有孔)。

一些测试代码。我希望编译器发出比它更多的警告。

:- begin_tests(var_nonvar).

% Amazingly, the compiler does not warn about the code below.

test("var(duh) is always false", fail) :-
  var(duh). 

% Amazingly, the compiler does not warn about the code below.

test("var(X) is true if X is a fresh variable (X designates a 'hole')") :-
   var(_). 

% Compiler warning: " Singleton variable, Test is always true: var(X)"

test("var(X) is true if X is a fresh variable (X designates a 'hole')") :-
   var(X). 
   
% The hole designated by X is filled with f(_), which has its own hole.
% the result is nonvar (and also nonground)

test("var(X) maybe true but become false as computation progresses") :-
   var(X),X=f(_),nonvar(X).
   
test("var(X) is false otherwise") :-
   var(_).   

% The hole is designated by an anonymous variable

test("a fresh variable is not ground, it designates a 'hole'", fail) :-
   ground(_). 
   
% Both hhe holes are designated by anonymous variables

test("a structure with 'holes' at the leaves is non-ground", fail) :-
   ground(f(_,_)). 
   
test("a structure with no 'holes' is ground") :-
   ground(f(x,y)).

test("a structure with no 'holes' is ground, take 2") :-
   X=f(x,y), ground(X).
   
% var/1 or ground/1 are questions about the state of computation,
% not about any problem in logic that one models. For example:

test("a structure that is non-ground can be filled as computation progresses") :-
   K=f(X,Y), \+ ground(f(X,Y)), X=x, Y=y, ground(f(X,Y)).
   
:- end_tests(var_nonvar).