Пролог - Повторить после неудачного оператора if приводит к необработанной переменной? - PullRequest
0 голосов
/ 06 марта 2020

Решено: Прочитать ответы, похоже, проблема с форматированием. Поставьте квадратные скобки вокруг строки 4.

Я пытаюсь использовать if-> then, иначе в прологе суммируем только четные числа в списке. Я просто пытаюсь пропустить цифры, если они не четные. Вот мой код ниже.

sum_even([], 0).
sum_even([H|T], Sum):-
    sum_even(T, Temp),
    even(H) -> Sum is H + Temp; Sum is Temp.

even([]).
even(Num):-
    0 is Num mod 2.

Проблема в том, что когда даже (H) происходит сбой, он вызывает 'redo' (не уверен, что это означает) в строке выше, что затем приводит к необоснованности Temp ? Так что Sum is Temp терпит неудачу, а затем все проваливается Может кто-нибудь объяснить, что я делаю не так и как это исправить.

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

Вот рабочий код. Тестовые случаи приведены ниже.

sum_even([],0).
sum_even([H|T], Sum):-
    sum_even(T,Sum0),
    (
        even(H)
    ->
        Sum is H + Sum0
    ;
        Sum = Sum0
    ).

even(Num):-
    0 is Num mod 2.

Первым изменением было форматирование кода.

Вы можете оставить -> / 2, как вы это делали, но также обычно можно видеть это как

(
   <test>
->
   <true>
;
   <false
)

, чтобы сделать ; очевидным. ; часто можно спутать с , при быстром сканировании кода глазами.

Поскольку в вашей версии отсутствует скобка, это приведет к ошибкам, таким как

received error: is/2: Arguments are not sufficiently instantiated

Далее удаление

even([]).

не нужно проверять, является ли значение четным.

Далее Temp был изменен на Sum0 в соответствии со стандартным соглашением по присвоению имен Prolog.

Также Sum is Temp был изменен на Sum = Sum0, потому что нет необходимости использовать is/2 здесь, когда =/2 работает.


Контрольные примеры

:- begin_tests(sum_even).

sum_even_test_case_generator([],0).
sum_even_test_case_generator([0],0).
sum_even_test_case_generator([1],0).
sum_even_test_case_generator([2],2).
sum_even_test_case_generator([0,1],0).
sum_even_test_case_generator([0,1,2],2).
sum_even_test_case_generator([-4],-4).
sum_even_test_case_generator([-2,-1,0,1,2,3,4],4).
sum_even_test_case_generator([-4,3,-2,-1,0,1,2,3,4],0).

test(sum_even,[forall(sum_even_test_case_generator(List,Sum))]) :-
    sum_even(List,Sum).

:- end_tests(sum_even).

Пример выполнения контрольных примеров.

?- make.
% c:/users/grut/documents/projects/prolog/so_question_167 compiled 0.00 sec, 0 clauses
% PL-Unit: sum_even ......... done
% All 9 tests passed
true.
0 голосов
/ 06 марта 2020

Вам не хватает скобок вокруг конструкции if-then-else . Приоритет оператора делает , если часть, sum_even(T, Temp), even(H) в вашем коде. Попробуйте вместо:

sum_even([], 0).
sum_even([H|T], Sum):-
    sum_even(T, Temp),
    (even(H) -> Sum is H + Temp; Sum is Temp).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...