Пролог - проверка количества случаев не работает должным образом

В Прологе: у меня есть следующая функция, которая подсчитывает вхождения определенного элемента в списке:

%count(L:list,E:int,N:int) (i,i,o)
count([],_,0).
count([H|T],E,C):-H == E,count(T,E,C1),C is C1+1.
count([_|T],E,C):-count(T,E,C).

Я проверил это, и это работает хорошо. Но здесь возникает проблема, у меня есть другая функция, которая должна проверить, встречается ли "1" менее 2 раз в списке.

check(L):-count(L,1,C),C<2.

Всякий раз, когда я пытаюсь проверить список [1,1,1,1] например, результат, который я получаю, является "истинным", что неверно, и я понятия не имею, почему. Я пытался внести некоторые изменения, но функция просто не будет работать.

3 ответа

Решение

Это происходит потому что count([1,1,1,1],1,1) тоже верно! В твоем последнем count он также может быть сопоставлен, когда H равен E. Чтобы проиллюстрировать это, используйте ; заставить пролог искать больше ответов на count([1,1,1,1],1,R), Вы увидите, что происходит.

count([],_,0).
count([E|T],E,C):-
    count(T,E,C1),
    C is C1+1.
count([H|T],E,C):-
    H \= E,
    count(T,E,C).

check(L) :- 
    count(L,1,C),
    C < 2.


?- check([1,1,1,1,1]).
false
?- check([1]).
true

Улучшите свои навыки тестирования!

При тестировании кода Пролога не только посмотрите на первый ответ на какой-либо запрос и сделайте вывод, чтоон работает.

Недетерминизм занимает центральное место в Прологе.

Довольно часто некоторый код, кажется, работает правильно с первого взгляда (при взгляде на первый ответ), но обнаруживает проблемы (в основном неправильные ответы и / или отсутствие завершения) при возврате.


Возвращаясь к исходному вопросу... Если вы хотите / хотите сохранить логическую чистоту, рассмотрите возможность использования следующего минимального варианта кода @Ruben, представленного в его ответе:

кол-([],_,0).
считать ([E|T],E,C):-
   рассчитывать (T,E,C1),
   С представляет собой С1+1.
считать ([H|T],E,C):- 
   диф (Н, Е),
   рассчитывать (Т, Е, С).

dif/2 выражает синтаксический термин неравенство в логической форме. Информацию об этом смотрите в прологе-диф!

Главы второго и третьего пунктов соответствуют обеим одинаковым последовательностям. В качестве минимальной коррекции я бы совершил тест

count([],_,0).
count([H|T],E,C):-H == E,!,count(T,E,C1),C is C1+1.
count([_|T],E,C):-count(T,E,C).
Другие вопросы по тегам