2014-01-05 2 views
1

Когда вы вызываете member(Item, List) с неосведомленным списком, Prolog объединяет и возвращает список, содержащий элемент. Я хочу правило, которое возвращает true/false и не пытается объединить. Есть ли такое правило?Предикат-член

ответ

1

Я хотел бы использовать охранник, как

is_member(E, L) :- nonvar(L), memberchk(E, L). 

memberchk/2 это детерминированная версия элемента/2, который будет использоваться, чтобы найти, если список содержит, по меньшей мере, 1 вхождение элемента. Не может действовать как генератор , но он более эффективен. В любом случае охранник требуется.

+0

Согласно OP, 'is_member (E, L)' должно быть истинным, но ваше определение терпит неудачу. – false

+0

@false: ну, вы должны прочитать что-то * очень * отличное от меня в вопросе OP. – CapelliC

+0

Я читал вопросы OP как желающий предиката, который вернет false, если будет задан экземпляр 'E' и неосуществимый' L', он не сработает, а вернет список в 'L', который содержит' E'. Однако, похоже, они приняли этот ответ, поэтому, возможно, они точно не уточнили свой вопрос. – lurker

3

Быстрый ответ: используйте \+ \+ member(Item, List).

Обратите внимание, что такие тесты часто не имеют большого смысла, когда ваши программы представляют собой логические отношения.

Вы указали, что member(Item, List) «возвращает список». Ну, это не совсем так. List унифицирован с частичными списками, то есть List = [Item|_Rest] ; List = [_,Item|_Rest] ; ... с _Rest являющийся непредубежденной переменной. То есть цель member(Item, List) не гарантирует, что (после успеха) List - это список. Вот контрпример: member(Item, List), List = [_|nonlist]

+0

Спасибо! Что означают \ +? – saadtaame

+0

@saadtaame: '(\ +)/1' - не доказуемо – false