Почему мой предикат prolog работает только с четным числом элементов в своем списке?

#list #prolog #predicate

#Список #prolog #предикат

Вопрос:

Мой предикат eo должен функционировать как so,

 ?- eo([a,b,c,d,e,f],L).

L = [b,d,f]
  

Мой код прямо сейчас,

 eo([], []).
eo([_,X|L], [X | R]) :-
    eo(L, R).
  

Но это работает только тогда, когда данный список содержит четное число элементов. Когда задается список с нечетным числом элементов, он просто выводит false . Есть какие-нибудь советы?

Редактировать:

 ?- eo([a,b,c,d,e,f,g],L).

L = [b,d,f]
  

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

Комментарии:

1. Рассмотрим простейший случай: что он должен делать со списком, состоящим всего из одного элемента? У вас нет никакого предложения, которое обрабатывает это. Поскольку рекурсивный вызов всегда уменьшает длину списка на 2, все списки нечетной длины в конечном итоге попадают в регистр одного элемента, следовательно, в настоящее время они терпят неудачу.

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

3. @EchoMike444 обновлено

Ответ №1:

Это решение работает

 eo([],[]).
eo([_],[]).
eo([_,X|L],[X|R]) :- eo(L,R).
  

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

Комментарии:

1. Это идеально! Большое вам спасибо. Однако еще один вопрос. Как мне изменить код для работы с подсписками? Например, если бы мой список содержал подсписок, как бы я изменил код, чтобы повлиять и на элементы подсписка (например, удалить все остальные элементы в подсписке)?

2. используя подсписки, вы увеличиваете сложность проблемы. Пожалуйста, предоставьте больше информации и немного кода.

Ответ №2:

QuickCheck может помочь не только в поиске неудачных запросов для предикатов с ошибками, но и сузить количество этих неудачных запросов до самого простого. В этом случае с помощью lgtunit инструмента быстрой проверки Logtalk:

 ?- lgtunit::quick_check(eo( list(character), -list(character))).
*     quick check test failure:
*       eo([d],[])
false.
  

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

Но помните, что QuickCheck генерирует случайные тестовые запросы и, таким образом, способен показывать только неудачный запрос, не доказывая правильность.