试着学习prolog

试着学习prolog,prolog,Prolog,有人问我: 定义一个2位谓词“increment”,该谓词仅在其第二个参数 是一个大于其第一个参数的整数。例如,增量(4,5)应保持不变,但增量(4,6)不应保持不变 于是我写道: increment(0, 1) :- !. increment(A, B) :- A is A - 1, B is B - 1, increment(A, B). 但这似乎不像我想象的那样有效。有人能给我解释一下发生了什么事以及为什么不能正常工作,也许能给我指出正确的方向吗?试试看:

有人问我:

定义一个2位谓词“increment”,该谓词仅在其第二个参数 是一个大于其第一个参数的整数。例如,增量(4,5)应保持不变,但增量(4,6)不应保持不变

于是我写道:

increment(0, 1) :-
    !.
increment(A, B) :-
    A is A - 1,
    B is B - 1,
    increment(A, B).
但这似乎不像我想象的那样有效。有人能给我解释一下发生了什么事以及为什么不能正常工作,也许能给我指出正确的方向吗?

试试看:

increment(X,Y) :- Y is X+1.
我认为问题中的代码有一个问题,那就是
a是a-1
B是B-1
总是会失败

A是-1
将失败,因为与
A
统一的任何数字都不能与
A
减1相同。您可能希望
A是-1
A
重新分配给
A
减1(这与其他编程语言的工作方式一致),但Prolog不是这样工作的。一旦一个变量被统一为一个术语,那么它将与该术语保持统一,直到Prolog回溯寻找替代解决方案

另一种更接近问题中建议的方法是引入两个新变量,用于与减法结果统一,然后在递归调用中使用这两个变量:

increment(0, 1) :- !.
increment(A, B) :- X is A - 1, Y is B - 1, increment(X, Y).
(我建议执行增量(X,Y):-Y是X+1。。

试试看:

increment(X,Y) :- Y is X+1.
我认为问题中的代码有一个问题,那就是
a是a-1
B是B-1
总是会失败

A是-1
将失败,因为与
A
统一的任何数字都不能与
A
减1相同。您可能希望
A是-1
A
重新分配给
A
减1(这与其他编程语言的工作方式一致),但Prolog不是这样工作的。一旦一个变量被统一为一个术语,那么它将与该术语保持统一,直到Prolog回溯寻找替代解决方案

另一种更接近问题中建议的方法是引入两个新变量,用于与减法结果统一,然后在递归调用中使用这两个变量:

increment(0, 1) :- !.
increment(A, B) :- X is A - 1, Y is B - 1, increment(X, Y).

(我建议执行增量(X,Y):-Y是X+1。

这里有一个不使用
is/2
(即RHS的强制算术评估)

这基本上是的扩展版本,不仅允许ℕ - 最重要的是,它可以“双向”工作:
X
Y
可以在调用时解除绑定/刷新

它使用来自的约束运算符,这比
is/2
=:=
更方便,这两种运算符都要求在运算符的左侧和右侧显示内容

我免费投了一些。这些通常可以节省开支和/或作为“实时文档”使用。我听说传统上,人们会使用calls来代替,但我发现这很脆弱,很像C。将整个目标传递给断言/1,这正是高级编程应该是什么样子

用以下方法进行测试:

因此:

?- run_tests.
% PL-Unit: increment .... done
% All 4 tests passed
true.

这里有一个不使用is/2的函数(即RHS的强制算术求值)

这基本上是的扩展版本,不仅允许ℕ - 最重要的是,它可以“双向”工作:
X
Y
可以在调用时解除绑定/刷新

它使用来自的约束运算符,这比
is/2
=:=
更方便,这两种运算符都要求在运算符的左侧和右侧显示内容

我免费投了一些。这些通常可以节省开支和/或作为“实时文档”使用。我听说传统上,人们会使用calls来代替,但我发现这很脆弱,很像C。将整个目标传递给断言/1,这正是高级编程应该是什么样子

用以下方法进行测试:

因此:

?- run_tests.
% PL-Unit: increment .... done
% All 4 tests passed
true.

Prolog中的变量与命令式语言(如C#或Java)中的变量不同。Prolog中的变量是未绑定(无值)或绑定(一个值)-变量只能从未绑定到绑定一次。一旦设置了该值,它就不能更改,除非代码回溯。因此,如果
A
的值为,比如说,
2
,那么
A
就不能等于
A-1
,因为
3
不等于
2
。Prolog中的变量与命令式语言(如C#或Java)中的变量不同。Prolog中的变量是未绑定(无值)或绑定(一个值)-变量只能从未绑定到绑定一次。一旦设置了该值,它就不能更改,除非代码回溯。因此,如果
A
的值为,比如说
2
,那么
A
不能等于
A-1
,因为
3
不等于
2