1

我正在尝试在 prolog 中编写一个递归函数,该函数在R = (2*X + Y)^N不使用指数运算符的情况下进行计算。我用 if-else 语句编写了一个递归函数,但出现错误:) or operator expected. 在我看来,我的语法是正确的,但我一定遗漏了一些东西。代码如下。

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)
        )
    ).
4

3 回答 3

2

你一直在使用这个表达式2*X+Y。为什么不计算它,然后使用该结果进行实际计算呢?也许你错过了问题陈述中的一些东西?

为什么要排除X和都是 0Y的情况?N...虽然你不排除这种情况N < 0

参数顺序

Prolog 中通常将结果放在相应的输入参数之后。这条规则也有例外,(is)/2是最常见的例子,但它被写成中缀运算符。

错误信号

对于无法正确处理的情况,Prolog 中有两个选项。要么你默默地失败,要么你发出一个干净的错误。(还有第三种——循环,虽然不理想,但总比成功好。)目前,你写出一段文字,然后你就成功了。因此,您假设有人会阅读您的消息。但是程序经常在无人看管的情况下运行并且消息被忽略。

想象一下,我想用你的定义来证明你的定义是答案的问题

?- expbar(42, 0, 0, 0)。

这是我在重写X =:= Y =:= N =:= 0X =:= 0, Y =:= 0, 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.!而上面的这些数字肯定是来自如此高度复杂的计算的一些进度信息......所以很容易误读你的信息。如果您使用单引号会更容易一些。更多关于单引号和双引号。但即使有更易读的消息,也很容易跳过它。

处理这种情况的正确方法是发出错误:

    抛出(错误(Error_term,_More_info))

以这种方式,计算被中止,错误由顶层(或catch/3处理它的下一个地方)处理。这降低了错误被误解的可能性。

理想情况下,Error_term应该是现有误差项之一。这是ISO Prolog 中错误的完整列表。在您的情况下,它可能evaluation_error(undefined)类似于exponentiation 的定义

于 2012-04-22T13:46:47.867 回答
0

您应该在初始条件下遇到语法错误。添加到 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
        )
    ).
于 2012-04-22T07:35:51.913 回答
0

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
    )
).
于 2012-04-22T07:00:13.857 回答