операции над элементами внутри списков в прологе

Я пишу код пролога, и в середине я хочу проверить, все ли элементы в списке не включены в определенный предикат

Here is the code:
 trap(a).
 trap(b).

not_trap([A|B]):-
\+trap(A),
not_trap(B).

not_trap(B):-
\+trap(B).

но это не сработает, может ли кто-нибудь сказать мне, где я ошибся? Спасибо


person Aya Abdelsalam    schedule 30.12.2011    source источник


Ответы (1)


Ваш базовый случай неверен. Какой бы список вы ни дали этому предикату, он будет классифицирован как не содержащий ловушки, так как ему соответствует второе предложение:

?- trace.
true.

[trace]  ?- not_trap([a]).
   Call: (6) not_trap([a]) ? creep
   Call: (7) trap(a) ? creep
   Exit: (7) trap(a) ? creep
   Call: (7) trap([a]) ? creep
   Fail: (7) trap([a]) ? creep
   Exit: (6) not_trap([a]) ? creep
true.

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

not_trap([]).

или переписав его без явной рекурсии как

not_trap(L) :-
    \+ (member(X, L), trap(X)).

(Читайте это так: нет члена X из L, который был бы ловушкой.)

person Fred Foo    schedule 30.12.2011
comment
или даже forall(member(X, L), \+ trap(X)). - person m09; 30.12.2011
comment
@Mog: судя по руководству SWI-Prolog, forall не похоже на предикат стандарта ISO. - person Fred Foo; 30.12.2011
comment
Большое спасибо, ваш ответ очень полезен - person Aya Abdelsalam; 30.12.2011
comment
@larsmans ага, но похоже, что в большинстве прологов это все равно есть. - person m09; 30.12.2011