If statement Prolog中带有If-Else语句的递归函数
我试图在prolog中编写一个递归函数,该函数计算If statement Prolog中带有If-Else语句的递归函数,if-statement,recursion,prolog,iso-prolog,If Statement,Recursion,Prolog,Iso Prolog,我试图在prolog中编写一个递归函数,该函数计算R=(2*X+Y)^N,而不使用指数运算符。我用if-else语句编写了一个递归函数,得到了错误:)或预期的运算符。在我看来,我的语法是正确的,但我肯定遗漏了什么。代码如下 expbar(R, X, Y, N) :- (X =:= Y =:= N =:= 0 -> write("No two variables can equal 0 at the same time."); (N =:= 0 -&
R=(2*X+Y)^N
,而不使用指数运算符。我用if-else语句编写了一个递归函数,得到了错误:)或预期的运算符。在我看来,我的语法是正确的,但我肯定遗漏了什么。代码如下
expbar(R, X, Y, N) :-
(X =:= Y =:= N =:= 0 ->
write("No two variables can equal 0 at the same time.");
(N =:= 0 ->
R is 2 * X + Y;
R is (2 * X + Y) * expbar(R, X, Y, N-1)
)
).
expbar不是一个函数。正确的是
expbar(R, X, Y, N) :-
(X =:= Y =:= N =:= 0 ->
write("No two variables can equal 0 at the same time.");
(N =:= 0 ->
R is 2 * X + Y;
N1 is N - 1,
expbar(R1, X, Y, N1)
R is (2 * X + Y) * R1
)
).
您在初始条件下应该有语法错误。
对joel76的补充回答:
expbar(R, X, Y, N) :-
( ( X =:= 0, Y =:= 0 ; X =:= 0, N =:= 0 ; Y =:= 0, N =:= 0 )
-> write("No two variables can equal 0 at the same time.")
; ( N =:= 0
-> R is 2 * X + Y
; N1 is N - 1,
expbar(R1, X, Y, N1),
R is (2 * X + Y) * R1
)
).
您一直在使用表达式2*X+Y
。为什么不先计算它,然后将结果用于实际计算?也许你在问题陈述中遗漏了什么
为什么要排除X
、Y
和N
均为0的情况。。。当您不排除N<0
的情况时
参数顺序
在Prolog中,通常将结果放在相应的输入参数之后。此规则也有例外,(is)/2
是最常见的示例,但它是作为中缀运算符编写的
错误信号
对于无法正确处理的情况,Prolog中有两个选项。要么默默地失败,要么发出一个干净的错误。(还有第三种——循环,虽然不理想,但仍然比成功好。)目前,你写一篇文章,然后你就成功了。所以你假设有人会读你的信息。但是,程序经常在无人值守的情况下运行,消息被忽略
假设我想用你的定义来证明你的定义就是答案的问题:
它说的是真的。
!以上这些数字肯定是来自如此复杂计算的一些进展信息。。。所以很容易误读你的信息。如果你用单引号的话会容易一些。但是,即使有更可读的消息,也很容易跳过它
处理这种情况的正确方法是发出错误:
throw(error(Error_term,_More_info))
抛出(错误(错误项、更多信息))
以这种方式,计算被中止,错误由顶层处理(或由catch/3
处理的下一个地方)。这降低了错误被误解的可能性
Error\u术语
最好是现有的错误术语之一。
这是你的电话号码。
在您的情况下,它可能是一个计算错误(未定义)
类似于。如果N=:=0
则1
大于2*X+Y
。表达式是可计算的,只要2*X+Y
或N与0
不同,测试用例可能太宽。我实现了这段代码,但仍然得到了“)或运算符预期的“这是什么,如何修复它?”@aclark,请查看其他答案X=:=Y=:=N=:=0
语法无效
?- expbar(42, 0, 0, 0).
[78,111,32,116,119,111,32,118,97,114,105,97,98,108,101,115,32,99,97,110,32,101,113,117,97,108,32,48,32,97,116,32,116,104,101,32,115,97,109,101,32,116,105,109,101,46]
true.
throw(error(Error_term,_More_info))