Пролог - проверка количества случаев не работает должным образом
В Прологе: у меня есть следующая функция, которая подсчитывает вхождения определенного элемента в списке:
%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).