Прологовые проблемы предикатов - PullRequest
0 голосов
/ 27 июня 2009

Я только начинаю с Пролога, и я не могу понять, почему следующее не работает так, как я ожидаю. Я пытаюсь создать предикат, который возвращает истину, если список L2 содержится в L1. Вот что я написал:

assert(contains (L1, L1)).
assert(contains(L1, [X|L2]):-member(X, L1), contains(L1, L2)).
assert(contains(L1, [])).

Я полагал, что это будет эквивалентно «если X из L3 = X | L2 находится в L1, а также L2 находится в L1, то true», причем содержит (L1, L2), рекурсивно транслируемый до тех пор, пока все члены не будут были пройдены, и у нас остался последний вариант, или мы находим элемент, которого нет в L1, и он не выполнит предикат.

К сожалению, похоже, это не работает. Кажется, он только возвращает значение члена (X, L1), поэтому содержит ([1,2,3], [1,4,5]) проходов, но содержит ([1,2,3], [4, 1,5]) нет.

Что я делаю не так?

Ответы [ 2 ]

5 голосов
/ 28 июня 2009

Я не совсем понял ваш вопрос, но я бы написал предикат contains/2 так:

% An empty list is contained by any list
contains(_, []).

% If a list is not empty, then its
% first element must be an element of L1,
% and its tail must be contained by L1.
contains(L1, [X | L2]) :-
    member(X, L1),
    contains(L1, L2).

Кстати, обратите внимание, что ваше первое правило (факт)

contains (L1, L1).

- синтаксическая ошибка (после имени предиката не должно быть пробела). Также, если исправить, это создаст нежелательную точку выбора. Итак, скорее удалите его.

Если вы хотите использовать assert/1 в приглашении Prolog, тогда выполните

?- assert(contains(_, [])).

Yes
?- assert(contains(L1, [X | L2]) :- (member(X, L1), contains(L1, L2))).

Yes

Чтобы увидеть, что попало в базу знаний, используйте listing/0.

?- listing.

:- dynamic contains/2.

contains(_, []).
contains(B, [A|C]) :-
    member(A, B),
    contains(B, C).

Yes

Я не думаю, что проблема в «утверждении свободных переменных», как вы указали в своем собственном ответе. Скорее проверьте ваш брекетинг.

0 голосов
/ 29 июня 2009

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

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