Один основной вопрос с логикой вашего предиката в целом является то, что она основана неудача и вас пытаются сделать успех неудачным. Это, как правило, обратное тому, что вы хотите, чтобы ваша логика была. Вы хотите, чтобы успех был основан, то есть вы хотите установить факты и правила, которые описывают, что истинно.
Вы можете воспроизвести это следующим образом. Вы знаете, что если элемент находится во главе списка, это элемент списка. Таким образом, справедливо следующее:
memberCheckSimple([H|T], H). /* H is a member of [H|T] */
Это также верно, что элемент является членом списка, если он состоит из хвоста списка:
memberCheckSimple([_|T], H) :- memberCheckSimple(T, H).
Эти два правила действительно все, что вы необходимость. Запрос, который не соответствует одному из приведенных выше правил, не будет выполнен, и это то, что вы хотите.
Теперь, глядя на то, почему ваш отказ на основе предиката не работает правильно и преуспевает в случаях отказа, это из-за этого правила:
memberCheckSimple(_, _).
Это говорит о том, что все является членом чего-либо. Вы должны признать, что это не кажется логичным (потому что это не так). Учитывая ваше предварительное условие с разрезом:
memberCheckSimple([], _) :- !, fail.
Это предотвращает откат к вашей «универсально истинной» статье, если первый аргумент является пустым списком ([]
), но если ее не пусто. Например, memberCheckSimple([a], b)
в конечном итоге провалится через путь, в котором он соответствует второму предложению, а затем соответствует первому предложению. Но сокращение в первом предложении не мешает memberCheckSimple([a], b)
от возврата (и последующего) по третьему предложению. Вы можете наблюдать это, делая trace
.
Чтобы завершить метод, основанный на отказе (который я еще раз подчеркнуть, это неправильный подход к проблеме и другие проблемы, такие как не реляционные), вам также потребуется разрезать во втором разделе:
memberCheckSimple([H|T], Elem) :-
Elem \= H, /* check if element equals head of list and negate it */
!,
memberCheckSimple(T, Elem). /* loop */
Ваши комментарии в коде указывают на неотложный мыслительный процесс. Например, вы называете «цикл», например, «рекурсией». Кроме того, как упоминалось в другом комментарии, упорядочение аргументов более естественно указано как элемент, за которым следует список, поскольку вы назвали его «членом», а не «содержит».
Обратите внимание, что обычно аргументы: 'member (El, Els)'. – false
'memberCheckSimple (non_element, non_list)' successs – false
@false yes Я знаю, но все мои функции проекта теперь наоборот, и я просто испорчу вещи, если я попытаюсь изменить их все сейчас. Так может также сделать его согласованным x) Btw, вы на каждом прологе, который я вижу здесь, в stackoverflow! : p – Tirafesi