Prolog `Peano算法中的less/2`关系

Prolog `Peano算法中的less/2`关系,prolog,successor-arithmetics,logical-purity,Prolog,Successor Arithmetics,Logical Purity,这是Peano算术中的小于谓词 less(0, s(_)). less(s(X), s(Y)) :- less(X, Y). 循环时 ?- less(X, Y), X=s(0), Y=0. 是否有更好的方法编写less/2(仅使用Horn子句)?您可以在/2时使用。使它不再是一个无限枚举谓词,并且仍然保持100%的纯。when/2修改了中的S(选择规则),这一想法可以追溯到阿兰·科默劳尔(Alain Colmerauer) less(X, Y) :- when((nonvar(X),nonv

这是Peano算术中的小于谓词

less(0, s(_)).
less(s(X), s(Y)) :- less(X, Y).
循环时

?- less(X, Y), X=s(0), Y=0.

是否有更好的方法编写
less/2
(仅使用Horn子句)?

您可以在/2时使用
。使它不再是一个无限枚举谓词,并且仍然保持100%的纯。
when/2
修改了中的S(选择规则),这一想法可以追溯到阿兰·科默劳尔(Alain Colmerauer)

less(X, Y) :- when((nonvar(X),nonvar(Y)), less2(X,Y)).
less2(0, s(_)).
less2(s(X), s(Y)) :- less(X, Y).
less/2
重写为
less/2
less2/2
类似于表格重写。插入一个存根并将子句重命名为head。但是主体中的递归调用没有被重写,而是再次调用存根

你现在得到了坚定:

?- less(s(s(0)), s(s(s(0)))).
true.

?- less(X, Y), X = s(s(0)), Y = s(s(s(0))).
X = s(s(0)),
Y = s(s(s(0))).
有时甚至是失败和真实:

?- less(s(s(_)), s(0)).
false.

?- less(s(0), s(s(_))).
true.
一些Prolog系统甚至提供了一个类似于table/1的指令,这样您就不需要重写,只需要进行声明。一个这样的系统是SICStus Prolog。在SICStus序言中,由于

你只会写:

:- block less(-,?), less(?,-).
less(0, s(_)).
less(s(X), s(Y)) :- less(X, Y).
有关1980年代的论文,请参见示例:

在WAM中实现dif和冻结
Mats Carlsson-1986年12月18日

注意@false的评论是关于一个“天真的”
neq/2
构建在
less/2
之上。它并没有指出
less/2
的问题,而是说在序言中,两个目标的分离,每个目标都有无限的解决方案,将不会公平地运行。@IsabelleNewbie你不会发现
less/2
的这种行为本身就令人不安吗?如果你想要一个能够列举答案的
less/2
,那就不会了。如果它可以枚举答案,那么这个查询会说“枚举N,M的所有对,使Nneq/2
的差异很重要,因为与
less/2
不同,赋值
X=s(0),Y=0
是有效的解决方案。当您要求
neq/2
搜索此解决方案时,循环是不必要的。@IsabelleNewbie我现在明白您和@false的意思了。谢谢。@IsabelleNewbie:“两个目标的析取,每个目标都有无穷多个解,这样做是不公平的”反例:
(X=f(u);X=g(u))
。这是两个目标的分离,每个目标有无限的解。它甚至终止,因此公平地列举了解决方案。需要进一步要求的是,这些无限解只能用无限多个答案来描述。否则,我完全同意你的看法。
less(X,0)
now flounders。对,你需要更复杂的条件或中间谓词。问题是:flounding真的比循环好吗?让我们来看看。