#prolog
#prolog
Вопрос:
Вот в чем моя проблема.
Мои факты и правила:
fact1(green, red, blue).
fact1(purple, white, gray).
fact2(green, orange).
fact2(purple, cyan).
fact3(green, pink).
fact3(purple, black).
foo(A,B,C,D,E) :-
fact1(A,B,C),
fact2(A,D),
fact3(A,E),
write(A),
write(B).
Теперь, если я спрошу SWI-Prolog foo(A,B,C,D,E).
, результат будет
?- foo(A,B,C,D,E).
greenred
A = green, B = red, C = blue, D = orange, E = pink ;
purplewhite
A = purple, B = white, C = gray, D = cyan, E = black.
Моя цель состоит в том, чтобы пользователь видел только строки
greenred
purplewhite
Для достижения этого я попытался изменить определение foo
вот так:
foo() :-
fact1(A,B,C),
fact2(A,D),
fact3(A,E),
write(A),
write(B).
Но вывод этого предиката — это только:
?- foo().
greenred
true.
и не то, что я ожидал:
?- foo().
greenred
purplewhite
true.
Любая помощь приветствуется.
Комментарии:
1. Что вы имеете в виду «но, конечно, всегда выводит …»? Вы не сказали нам, как выглядят ваши факты, поэтому мы не знаем, каков ваш ожидаемый результат. У вас действительно есть несколько совпадающих фактов? Можете ли вы включить некоторые минимальные (фиктивные) данные, с помощью которых мы можем это воспроизвести? Я пробовал некоторые и не могу воспроизвести вашу проблему. Так что либо проблема в коде, который вы нам не показываете, либо я не понимаю, что вы имеете в виду. Как вы это запускаете? Что вы делаете, чтобы попытаться получить несколько совпадений?
2. спасибо за ваш ответ, я отредактировал свой вопрос с помощью некоторого фиктивного кода. Надеюсь, теперь вы понимаете, что я имею в виду.
3. Спасибо за обновление. О, у вас проблема с
true
выводом? Нажатие пробела по-прежнему выдает мне последующие совпадения даже приfoo().
но он также печатаетtrue
после каждого совпадения, чегоfoo(A,B,C,D,E).
не происходит?4. Я протестировал это снова, и я действительно получаю только первое совпадение с foo (), затем true, а затем ничего. И да, как вы сказали, я также не получаю true между строками, что также является тем, что я хочу, если это возможно. Может быть, это swi-prolog? Или вы знаете другой способ, как я мог бы достичь желаемого результата?
5. Хорошо, итак, я протестировал свой код с помощью редактора swish only, и теперь я получаю тот же результат, что и @mercator. Интересно
Ответ №1:
Добавление fail/ 0 в конце настраивает это в цикл, управляемый сбоем, так что после получения ответа предикат завершается ошибкой и пробует другие точки выбора.
foo :-
fact1(A,B,_),
fact2(A,_),
fact3(A,_),
write(A),
write(B),
nl,
fail.
Пример запуска.
?- foo.
greenred
purplewhite
false.
Чтобы заставить Prolog вернуть true (на заднем плане злой голос говорит: «У нас есть способы заставить вас рассказать нам правду»), он должен быть успешным после сбоя, поэтому Prolog ищет другое предложение с именем foo
. Добавив просто foo.
в качестве второго предложения, Prolog теперь может найти это предложение и выполнить его. Поскольку он ничего не делает, он завершается успешно и возвращает true.
foo.
Пример выполнения
?- foo.
greenred
purplewhite
true.
Полный исходный код
foo :-
fact1(A,B,_),
fact2(A,_),
fact3(A,_),
write(A),
write(B),
nl,
fail.
foo.
Комментарии:
1. Терминология: вы хотели сказать «предложение», а не «предикат». В «полном» коде у вас есть 1 предикат, который состоит из 2 предложений (1 правило и 1 факт).
2. Большое спасибо! Очень интересно, что SWISH обрабатывает это по-разному по сравнению с prolog. Это то, что я должен иметь в виду.
3. @repeat Спасибо. Изменено.