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

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

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)


arrow_upward
1
arrow_downward

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

?- 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