I just started learning prolog recently and am confused about how the recursion works. I have written this code:
我刚刚开始学习prolog,并对递归的工作原理感到困惑。我写了这段代码:
test(X,B):- B is X + 2, B < 22, test(B,_).
test(X,Y).
I want it to return 20 or 21, but instead, if I call, say, test(4,X) it returns 6 over and over again (7 times to be exact), like this:
我希望它返回20或21,但相反,如果我打电话,比如说,测试(4,X)它会一遍又一遍地返回6(确切地说是7次),如下所示:
X = 6 ;
X = 6 ;
X = 6 ;
...
etc. So I was wondering what I was doing wrong. Thanks in advance for the help! Really appreciate it.
所以我想知道我做错了什么。在此先感谢您的帮助!真的很感激。
1 个解决方案
#1
You misinterpreted the result you got, look:
你错误地解释了你得到的结果,看:
?- test(4,X). X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; true. % <====
Note the true
at the end, it means: Yes, this is true for any X
!
注意最后的真实,它意味着:是的,任何X都是如此!
Here is what you probably meant to write - trying to simulate your exact way of expression:
以下是您可能要编写的内容 - 尝试模拟您的确切表达方式:
mtest(X0, X) :-
X1 is X0+2,
X1 < 22,
mtest(X1, X).
mtest(X0, X) :-
X is X0,
X+2 >= 22.
Some things are remarkable:
有些事情是非凡的:
-
Note variable
X
in the first clause: It "hands back" the result.注意第一个子句中的变量X:它“反对”结果。
-
The second clause needs to express the opposite of the very condition you gave in the first clause, because clauses are read independently of each other. In your original program the fact
test(X,Y).
stated that the relation is true for everything! (You got a warning for that, didn't you?) For example, alsotest(7,1000).
succeeded.第二个句子需要表达与第一个子句中给出的条件相反的条件,因为子句是相互独立的。在你的原始程序中,事实测试(X,Y)。说这种关系对一切都是正确的! (你得到了警告,不是吗?)例如,也测试(7,1000)。成功了。
-
The
X is X0
is here to ensure that the second argument will be only a number but not an expression.X是X0,这是为了确保第二个参数只是一个数字而不是一个表达式。
In any case, as a beginner, try to use library(clpfd)
, clpfd instead of (is)/2
. Or even better, start with successor-arithmetics.
在任何情况下,作为初学者,尝试使用库(clpfd),clpfd而不是(是)/ 2。或者甚至更好,从继承算术开始。
#1
You misinterpreted the result you got, look:
你错误地解释了你得到的结果,看:
?- test(4,X). X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; X = 6 ; true. % <====
Note the true
at the end, it means: Yes, this is true for any X
!
注意最后的真实,它意味着:是的,任何X都是如此!
Here is what you probably meant to write - trying to simulate your exact way of expression:
以下是您可能要编写的内容 - 尝试模拟您的确切表达方式:
mtest(X0, X) :-
X1 is X0+2,
X1 < 22,
mtest(X1, X).
mtest(X0, X) :-
X is X0,
X+2 >= 22.
Some things are remarkable:
有些事情是非凡的:
-
Note variable
X
in the first clause: It "hands back" the result.注意第一个子句中的变量X:它“反对”结果。
-
The second clause needs to express the opposite of the very condition you gave in the first clause, because clauses are read independently of each other. In your original program the fact
test(X,Y).
stated that the relation is true for everything! (You got a warning for that, didn't you?) For example, alsotest(7,1000).
succeeded.第二个句子需要表达与第一个子句中给出的条件相反的条件,因为子句是相互独立的。在你的原始程序中,事实测试(X,Y)。说这种关系对一切都是正确的! (你得到了警告,不是吗?)例如,也测试(7,1000)。成功了。
-
The
X is X0
is here to ensure that the second argument will be only a number but not an expression.X是X0,这是为了确保第二个参数只是一个数字而不是一个表达式。
In any case, as a beginner, try to use library(clpfd)
, clpfd instead of (is)/2
. Or even better, start with successor-arithmetics.
在任何情况下,作为初学者,尝试使用库(clpfd),clpfd而不是(是)/ 2。或者甚至更好,从继承算术开始。