Prolog中的参数运算



在Prolog中,我想将一个平凡的逻辑归纳谓词i实现为(1):

i(0).
i(N) :- i(N-1).

或(2):

i(0).
i(N+1) :- i(N).

但这并不奏效;对于(1),查询i(3).导致堆栈溢出;对于(2),i(3).返回false.

相反,我必须做(3):

i(0).
i(N) :- M is N-1, i(M).

简单地说,(3)和(1)之间的区别似乎是一个微不足道的语法变化,在更大的程序中声明中间变量感觉很麻烦。Prolog编译器拒绝(1)和(2)的原因是什么?是否存在变通办法?为什么(1)与(2)表现不同?

令人惊讶的是,这并不是一个微不足道的语法转换。Python中的N-1总是算术的;您可以将5-1替换为4,而"cat"-1是一个错误。

在Prolog中,短划线不是算术,它是一个连接左/右与短划线的术语。你可以写"cat"-1("cat-dash-one")把两个东西配对并一起传递,人们会这样做:

?- "cat"-1 = N-1.    % unify against it,
N="cat"              % reason that N must be "cat" for this to be true.
?- N-1 = -(N,1)      % rewrite it in normal name(X,Y) format,
true                 % where dash is the name.

% make a list of pairs joined with dash:
?- pairs_keys_values(Ps, [cat,dog,cow,fish], [1,2,chicken,N-1])
Ps = [cat-1, dog-2, cow-chicken, fish-(N-1)]

因此,人们想要一种将数学融入逻辑关系语言的方法,并提出了一个谓词,它知道如何根据名称+-/*等进行计算。一个像math_evaluate(Result, Term)这样的谓词,如果你有它,你可以把它写成Result math_evaluate N-1,这样它看起来更整洁。math_evaluate谓词是is(Result, Term):

?- N=5, is(Result, N-1)
N = 5,
Result = 4

可以用类似于将-(N,1)重写为N - 1的方式来编写Result is N-1

最新更新