这件事激起了我对理论的兴趣:
是否可以编写一个不一致的 Prolog 程序,即根据查询方式,只使用纯 Prolog、cut 和来回答false和true的程序false
?
例如,一个人可以查询p(1)
,Prolog 处理器会说false
。但是当有人查询p(X)
Prolog 处理器时,它会给出一组答案1
,2
,3
。
这可以通过“计算状态检查谓词”轻松实现,例如var/1
(更好地称为fresh/1
)+ el cut:
p(X) :- nonvar(X),!,member(X,[2,3]).
p(X) :- member(X,[1,2,3]).
Run Code Online (Sandbox Code Playgroud)
然后
?- p(1).
false.
?- p(X).
X = 1 ;
X = 2 ;
X = 3.
Run Code Online (Sandbox Code Playgroud)
如果这是高保证软件,就会出现“哎哟时间”。自然地,任何命令式程序在其他任何一行上都不会像这样脱轨。
所以。可以没有那些“计算状态检查谓词”吗?
聚苯乙烯
上面说明了 Prolog 的所有谓词实际上都携带了一个“计算状态”的线程隐藏参数:
p(X,StateIn,StateOut).
Run Code Online (Sandbox Code Playgroud)
这可以用来解释var/1
和朋友的行为。当 Prolog 程序只调用既不咨询也不修改那个的谓词时,它就是“纯”的State
。好吧,至少这似乎是查看正在发生的事情的好方法。我认为。
这是一个非常简单的:
f(X,X) :- !, false.
f(0,1).
Run Code Online (Sandbox Code Playgroud)
然后:
| ?- f(0,1).
yes
| ?- f(X,1).
no
| ?- f(0,Y).
no
Run Code Online (Sandbox Code Playgroud)
因此,Prolog 声称对于带有变量的查询没有解决方案,尽管它f(0,1)
是正确的,并且可以同时解决两者。