Prolog基本递归分部

时间:2012-03-02 00:12:12

标签: math prolog

我是Prolog的新手,在修复第一个程序的错误方面遇到了一些困难。

程序要求是它使用递归划分2个输入,如果被除数大于除数则返回0,并忽略余数。

%Author: Justin Taylor

testquotient :-
    repeat,

    var(Divident), var(Divisor), var(Answer), var(End),

    write('Enter Divident: '),
    read(Divident),

    write('Enter Divisor: '),
    read(Divisor),

    quotient(Divident, Divisor, Answer),
    nl,
    write('Quotient is = '),
    write(Answer),
    nl,

    write('Enter 0 to quit, 1 to continue: '),
    read(End),

    (End =:= 0),!.

    quotient(_, 0, 'Undefined').
    quotient(0, _, 0).
    quotient(Divisor == Divident -> Answer = 1).
    quotient(Divisor < Divident -> Answer = 0).

quotient(Divident, Divisor, Answer) :-
    (Divisor > Divident -> Divisor = Divisor - Divident,
    quotient(Divident, Divisor, Answer + 1);
    Answer = Answer).

1 个答案:

答案 0 :(得分:1)

首先,阅读is。在SWI-Prolog的提示符下键入help(is).。仔细阅读关于“算术”的整个部分。其次,quotient的前几个条款完全偏离基础,语法无效。我将告诉你如何改写其中一个,你必须自己做另一个:

%% WRONG: quotient(Divisor == Divident -> Answer = 1).
quotient(Divisor, Divident, Answer) :-
    Divisor =:= Divident -> Answer = 1.
%% WRONG: quotient(Divisor < Divident -> Answer = 0).
....

请注意使用=:=代替==

quotient的最后一句似乎乍看之下几乎是正确的,除了主要的失礼:prolog的统一,=不是,重复不是,一个赋值运算符!我们不会更改分配给逻辑变量的值(如果X 5,那么它的变化是什么?它就是这样)。不,我们定义 new 逻辑变量,就像这样

( Divisor > Divident -> NewDivisor = Divisor - Divident,

我们在递归调用

中使用 it
%% WRONG: quotient(Divident, NewDivisor, Answer + 1) ; 

但这也是错的,w.r.t。新的Answer。如果你在路上添加1(当你从Divident中减去Divisor时 - 顺便说一句不应该是另一种方式吗?检查你的逻辑或至少交换你的名字,“除数”是你将除以),这意味着你应该提供初始值。但是你似乎提供了终端值0,这意味着你应该在从递归深度回来的路上构建你的结果:

%%not quite right yet
quotient(Divident, NewDivisor, NewAnswer), Answer = NewAnswer + 1 ;

接下来,Answer = Answer总是成功。在这种情况下我们只写true

最后,你真的应该在每个递归步骤中使用is,而不仅仅是在最后:

( Divisor > Divident -> NewDivisor is Divisor - Divident,           %% use "is"
  quotient(Divident, NewDivisor, NewAnswer), Answer is NewAnswer+1  %% use "is"
; true ).                                          %% is this really necessary?

'Undefined' 0会导致var出现错误,但暂时还是错误。此外,您无需在Prolog中“声明”您的var(Divident), ..., var(End),。第{{1}}行无用。