Я пытаюсь выучить пролог и хочу создать функцию 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).