Syntax 变量如何在prolog';s函子?

Syntax 变量如何在prolog';s函子?,syntax,prolog,Syntax,Prolog,(追踪过程的屏幕截图) 上面是我用输入列表“[4、[3、[2、[1、[]]]]”和一个变量“X”调用函子flatts2的屏幕截图 下面是我跟踪的函数,从这个问题中盗取: 所以我的基本问题是,在递归过程中,变量X及其值会发生什么变化?为什么“调用1”中的“X”显示为“295”,prolog语法如何计算该值 flatten2([], []) :- !. flatten2([L|Ls], FlatL) :- !, flatten2(L, NewL), flatten2(Ls,

(追踪过程的屏幕截图)

上面是我用输入列表“[4、[3、[2、[1、[]]]]”和一个变量“X”调用函子flatts2的屏幕截图

下面是我跟踪的函数,从这个问题中盗取:

所以我的基本问题是,在递归过程中,变量X及其值会发生什么变化?为什么“调用1”中的“X”显示为“295”,prolog语法如何计算该值

flatten2([], []) :- !.
flatten2([L|Ls], FlatL) :-
    !,
    flatten2(L, NewL),
    flatten2(Ls, NewLs),
    append(NewL, NewLs, FlatL).
flatten2(L, [L]).

X
只是保存在“术语库”中的“全球可见的东西”的本地名称

X
指定(或命名或表示):

  • 具体内容:一个术语,通常是一棵树。该变量称为“绑定”或“实例化”。树的叶子要么是具体内容(原子、数字等),要么是没有内容的细胞(见下文)。内部节点称为复合术语。如果
    X
    指定了一个术语,则查询
    nonvar(X)
    成功。当打印
    X
    时,它“消失”:改为打印内容
  • 一个没有内容的单元格(我喜欢称之为“洞”),这意味着最终会占用一个术语。在这种情况下,变量称为“未绑定”或“未实例化”。如果
    X
    是这样一个未绑定的变量,即如果它指定了一个孔,则查询
    var(X)
    成功。打印
    X
    时,将打印其名称
令人困惑的是(我应该补充一点,相当草率地),一个“变量名”通常也被称为“术语”。这是一个开场白,这两个概念应该分开,但它们不是

如果您编写Prolog子句,您将使用漂亮的变量名

flatten2(L, [L]).
请记住,这些变量名称没有特殊意义,它们是子句的局部变量

当Prolog运行时,它必须“从帽子里”取出与任何其他名称不同的新变量名称。这些新的变量名看起来像
\u 295
。不同的实现在这里有不同的约定

例如,必须创建新的变量名来描述包含某个位置(至少一个位置)的成员
foo
的列表。将生成长度不断增加的列表模板。在列表的每个位置,除了存放
foo
(一个具体术语)的位置外,都有一个“无内容单元格”/“孔”。为了表达这一点,将生成并打印一个与任何其他变量名不同的随机新变量名。变量名可能直接从孔地址派生

?- member(foo,L).
L = [foo|_23302] ;
L = [_23300, foo|_24038] ;
L = [_23300, _24036, foo|_24774] ;
L = [_23300, _24036, _24772, foo|_25510] ;
L = [_23300, _24036, _24772, _25508, foo|_26246] ;
L = [_23300, _24036, _24772, _25508, _26244, foo|_26982] 

\u 295
不是一个值。它是变量
X
的内部名称。由于Prolog经常递归,因此每个调用都定义了一个新的
X
,因此Prolog为每个调用创建一个新变量。