Новичок в Прологе - аргументы недостаточно обоснованы - PullRequest
0 голосов
/ 08 мая 2020

Новое в Prolog. Я поигрался с именами переменных и убедился, что переменные имеют вычисленное значение, но мне что-то не хватает. Не могли бы вы все взглянуть и помочь мне выяснить, что мне не хватает?

lgstar(N,Answer)                        :- var(N) -> write('undefined'); lgstaranswer(N,Answer).

lgstaranswer(N1,Answer1)                :- lgstarcompute(N1,Iterations),
                                           var(Answer1) -> Answer1 is Iterations, write(Answer1);
                                           (Answer1 is Iterations -> write('yes'); write('no')).

lgstarcompute(N2,Iterations1)           :- N3 is floor(log10(N2)/log10(2)), write(N2), write(N3),
                                           N3=<1 -> Iterations1 = 1;
                                           lgstarcompute(N3,Iterations2),
                                           Iterations1 is Iterations2+1.

Вы вызываете lgstar (), чтобы начать работу. Ошибки, которые я получаю, выглядят следующим образом:

Arguments are not sufficiently instantiated
In:
   [4] _672 is floor(... / ...)
   [3] lgstarcompute(_738,_740) at  line 7
   [2] lgstarcompute(70000,_796) at  line 9
   [1] lgstaranswer(70000,4) at  line 3

Рабочий код

Благодаря принятому ниже ответу код работает. Пожалуйста, прочтите их объяснение. Ниже приведен рабочий код для всей функции. Просто помните, что ваши профессора знают, как использовать Google!

lgstar(N,Answer)                        :- var(N) -> write('undefined'); lgstaranswer(N,Answer).

lgstaranswer(N1,Answer1)                :- lgstarcompute(N1,Iterations),
                                           ((var(Answer1) -> Answer1 = Iterations);
                                           (Answer1 == Iterations -> write('yes'); write('no'))).

lgstarcompute(N2,Iterations)            :- N3 is floor(log10(N2)/log10(2)),
                                           (N3 =< 1 -> Iterations = 1;
                                           (lgstarcompute(N3,Iterations2), Iterations is Iterations2+1)).

1 Ответ

0 голосов
/ 08 мая 2020

Оказывается, это частая ошибка. Вы должны заключать свои выражения в скобки из-за приоритета операторов.

Это то, что у вас есть:

lgstarcompute(N2,Iterations1)   :- N3 is floor(log10(N2)/log10(2)), write(N2), write(N3),
                                   N3=<1 -> Iterations1 = 1;
                                   lgstarcompute(N3,Iterations2),
                                   Iterations1 is Iterations2+1.

Если я отформатирую это немного лучше, я получу:

lgstarcompute(N2, Iterations1) :-
    N3 is floor(log10(N2)/log10(2)),
    write(N2), write(N3),
    N3 =< 1 -> Iterations1 = 1
;
    lgstarcompute(N3, Iterations2),
    Iterations1 is Iterations2+1.

В Prolog, по крайней мере в SWI Prolog, , имеет более высокий приоритет, чем ->, который выше, чем ;. Таким образом, это эквивалентно:

lgstarcompute(N2, Iterations1) :-
    (
        (
            N3 is floor(log10(N2)/log10(2)),
            write(N2), write(N3),
            N3 =< 1 
        ) -> Iterations1 = 1
    )
;
    (
        lgstarcompute(N3, Iterations2),
        Iterations1 is Iterations2+1.
    ).

Что происходит, так это то, что когда N3 =< 1 терпит неудачу, Prolog возвращается назад до того, как происходит N3 is floor(...), чтобы достичь самой последней точки выбора, а N3 - нет. более длинный экземпляр. Затем он переходит к первому запросу после ;, который равен lgstarcompute(N3, Iterations2) с N3 неустановленным.

Чтобы исправить это, вам нужно сгруппировать его, используя круглые скобки:

lgstarcompute(N2, Iterations1) :-
    N3 is floor(log10(N2)/log10(2)),
    write(N2), write(N3),
    (    N3 =< 1
    ->   Iterations1 = 1
    ;    lgstarcompute(N3, Iterations2),
         Iterations1 is Iterations2+1
    ).

Теперь когда N3 =< 1 терпит неудачу, он не будет возвращаться к write(N3) и полностью вернуться к N3 is floor(...), а скорее примет соединение с N3, все еще созданным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...