Вопрос

Я только начинаю с Prolog, и я не могу понять, почему следующее не работает так, как я ожидаю.Я пытаюсь создать предикат, который возвращает true, если список 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", при этом contains(L1, L2) преобразуется рекурсивно до тех пор, пока либо все члены не будут пройдены, и у нас останется последний вариант, либо мы найдем элемент, которого нет в L1, и он не выполнит предикат.

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

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

Это было полезно?

Решение

Я не совсем понял ваш вопрос, но я бы написал 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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top