Пролог Невозможно получить СУММУ результаты из полного предиката - PullRequest
1 голос
/ 08 апреля 2020

Я пытаюсь вычислить каждый биномиальный коэффициент в Прологе, используя предикат Форалла. После вычисления коэффициента я делю его с помощью sqrt (5), а затем я хотел бы объединить все результаты в один результат, но я получаю сообщение об ошибке и не знаю, что мне нужно изменить в своем коде, чтобы работать должным образом.

Я использую предикат forL oop для итерации от 0 (ноль) до N и предиката calcCoeficient для каждого шага.

Это мой код:

forLoop(Low,High,_,Low):-
    Low=<High.
forLoop(Low,High,Step,Var):-
    Inc is Low+Step, Inc =< High, forLoop(Inc,High,Step,Var).

pow2(X,Y,Z):-Z is X**Y.

permutari(0,1).
permutari(1,1).
permutari(N,R):-N1 is N-1,permutari(N1,R1), R is N*R1.

aranjamente(N,K,R):-permutari(N,R1),N1 is N-K,permutari(N1,R2), R is round(R1/R2).

combinari(N,K,R):-aranjamente(N,K,R1), permutari(K,R2), R is round(R1/R2).

calculateCoeficient(A,B,N,K,R):-
    combinari(N,K,C1), pow2(A,N-K,C2),pow2(B,K,C3), R is C1*C2*C3.


calculateFibo2(N,Step,R,S):-
    Radical is sqrt(5),
    Phi is Radical/2+0.5,
    F1 is float_integer_part(Phi),
    F2 is float_fractional_part(Phi),
    forall(
        forLoop(0,N,Step,K),
        calculateCoeficient(F1,F2,N,K,S),
        R1 is round(S/Radical),
        R := R+R1
    ).


Для звонка: CalculateFibo2 (2,1, R, S) получаю следующее исключение

ERROR: Undefined procedure: forall/4
ERROR:   However, there are definitions for:
ERROR:         forall/2
ERROR:         forall/2
ERROR: 
ERROR: In:
ERROR:    [9] forall(forLoop(0,2,1,_16156),calculateCoeficient(1.0,0.6180339887498949,2,_16166,_16168),_16172 is round(...),_16182:=_16188+_16190)
ERROR:    [8] calculateFibo2(2,1,_16218,_16220) 
   Exception: (9) forall(forLoop(0, 2, 1, _15580), calculateCoeficient(1.0, 0.6180339887498949, 2, _15580, _15268), _15596 is round(_15268/2.23606797749979), _15266:=_15266+_15596) ?

1 Ответ

2 голосов
/ 08 апреля 2020

Просто примечание, которое не подходит для комментария.

Де-факто стандартный предикат forall/2 использует отрицание в своей реализации. Это эквивалентно:

:- meta_predicate(forall(0, 0)).

forall(Generate, Test) :-
    \+ (Generate, \+ Test).

Из-за использования отрицания никакие привязки не возвращаются при успешном вызове предиката forall/2. Таким образом, вы не можете использовать для вычислений, которые вы пытаетесь реализовать.

PS R := R+R1 должно быть R is R+R1.

...