Peano算术中的“less/2”关系

问题描述

Peano 算术中的这个小于谓词

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

何时循环

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

有没有更好的写法less/2(仅使用 Horn 子句)?

解决方法

您可以使用 when/2。使它不再是一个无限枚举的谓词,并且仍然保持 100% 纯净。 when/2 修改了 SLD-Resolution 中的 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/2less2/2 类似于表格改写。您插入一个存根并重命名子句标题。但是主体中的递归调用并没有被重写,而是再次调用存根。

你现在变得坚定了:

?- 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 Prolog 中,感谢 block/1 directive

你只会写:

:- block less(-,?),less(?,-).
less(0,s(_)).
less(s(X),Y).

对于 1980 年代的论文,请参见示例:

WAM 中 diff 和 freeze 的实现
Mats Carlsson - 1986 年 12 月 18 日
http://www.softwarepreservation.com/projects/prolog/sics/doc/Carlsson-SICS-TR-86-12.pdf/view