Вычислить GCD с помощью алгоритма Евклида в прологе - PullRequest
0 голосов
/ 31 мая 2019

Я пытаюсь выучить пролог и хочу создать функцию GCD, которая оценивает с помощью алгоритма Евклида. Это то, что я до сих пор:

gcd(X, 0, X) :- !.
gcd(0, Y, Y) :- !.
gcd(X, Y, Z) :- X > Y, !, X1 is X mod Y, gcd(X1, Y, Z).
gcd(X, Y, Z) :- X =< Y, X1 is Y mod X, gcd(X1, X, Z).

Он работает для определения таких вещей, как:

gcd(8,2,2). --> true
gcd(2,8,2). --> true

Но они должны вывести false, но вместо этого выдает ошибку:

gcd(8,3,2).
gcd(3,8,2).

Ошибка:

ERROR: Arithmetic: evaluation error: `zero_divisor'
ERROR: In:
ERROR:   [10] _5542 is 4 mod 0
ERROR:    [9] gcd(0,4,2) at /home/kopio/Desktop/Aral/Prolog/prologme.pl:5
ERROR:    [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

Кроме того, я не могу запустить это с переменными:

gcd(8,X,2). 

Я получаю эту ошибку:

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:    [9] 8>_5726
ERROR:    [8] gcd(8,_5752,2) at /home/zula/prologme.pl:5
ERROR:    [7] <user>

Решение:

:- use_module(library(clpfd)).
gcd(X, 0, X) :- !.
gcd(0, Y, Y) :- !.
gcd(X, Y, Z) :- X > Y, !, X1 #= X mod Y, gcd(X1, Y, Z).
gcd(X, Y, Z) :- X =< Y, X1 #= Y mod X, gcd(X1, X, Z).
...