Recursion 序言中的欧几里得(最大公分母)

Recursion 序言中的欧几里得(最大公分母),recursion,prolog,greatest-common-divisor,Recursion,Prolog,Greatest Common Divisor,我们得到了一个伪代码,我们应该将其翻译成Prolog: 这就是我能想到的解决方案: % if y = 0: return x test(X, 0, Output) :- Output is X. % if x = 0: return y test(0, Y, Output) :- Output is Y. % if if x > y: return euclid_recursive(x - y, y) test(X,Y,Output) :- % if x > y: ret

我们得到了一个伪代码,我们应该将其翻译成Prolog:

这就是我能想到的解决方案:

% if y = 0: return x
test(X, 0, Output) :- Output is X.
% if x = 0: return y
test(0, Y, Output) :- Output is Y.
% if if x > y: return euclid_recursive(x - y, y)
test(X,Y,Output) :- 
    % if x > y: return euclid_recursive(x - y, y)
    (   X > Y ->  Temp is X - Y ,
        test(Temp, Y,Output);
    % return euclid_recursive(x, y - x) 
        Temp is Y - X,
        test(X, Temp, Output)
    ).
我用几个例子对它进行了测试,它似乎是有效的。如果你们能再看一眼,我将不胜感激。

你们只需要用它来计算一个数值表达式。因此,您可以在这里使用统一:

另一个主要问题是Prolog将继续进行递归调用,即使其中一个元素为零。因此,它将不断提出新的解决方案:

?- test(36, 63, R).
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
R = 9 ;
…
这似乎不是一个(主要)问题,但如果您将
test/3
用作另一个程序的一部分,它可能会陷入无限循环中,
test/3
不断提出
R=9
,并且每次下一个谓词调用都会拒绝这个问题

test(X, 0, X).
test(0, X, X) :-
    X > 0.
test(X, Y, Output) :- 
    X > 0,
    Y > 0,
    ( X > Y
    -> Temp is X - Y,
       test(Temp, Y,Output)
    ; Temp is Y - X,
      test(X, Temp, Output)
    ).
test(X, 0, X).
test(0, X, X) :-
    X > 0.
test(X, Y, Output) :- 
    X > 0,
    Y > 0,
    ( X > Y
    -> Temp is X - Y,
       test(Temp, Y,Output)
    ; Temp is Y - X,
      test(X, Temp, Output)
    ).
?- test(36, 63, R).
R = 9 ;
false.