Результат PROLOG vs истина

У меня есть следующий код в файле с именем "testing.pl":

fact(1).
fact(2).
fact(3).

funcA(X) :- funcB(X).

funcB(X) :- fact(X).

testing :- funcA(_X).

Затем в интерпретаторе SWI-Prolog я запрашиваю funcA(X)., и на выходе получается:

X = 1 ;
X = 2 ;
X = 3.

Но всякий раз, когда я запрашиваю testing., результат будет:

true ;
true ;
true.

Итак, мои вопросы:

Как я могу использовать заключение правила как предпосылку другого правила (funcA(X) справа от testing), но иметь такой же эффект, как если бы я запрашивал эту предпосылку (funcA(X))?

В приведенном выше примере я хотел бы написать testing. в какой-то момент моего файла "testing.pl" и заставить funcA (X) делать то же самое, что и при запросе с помощью интерпретатора, поэтому funcB (X) будет проверять наличие все значения, которые X может взять из fact (N) и вернуть.

Результатом моего желания было бы написать testing. и попасть на экран:

X = 1 ;
X = 2 ;
X = 3.

Спасибо.


person Haddex    schedule 13.04.2017    source источник
comment
Если вы хотите, чтобы testing. приводил к X = 1, ..., вам нужно, чтобы X был аргументом для testing. Итак, testing(X) :- funcA(X). (что, похоже, не добавляет смысла). В качестве альтернативы, что менее предпочтительно, вы можете записать результаты: testing :- funcA(X), write('X = '), write(X), nl.   -  person lurker    schedule 13.04.2017


Ответы (1)


Вы можете вручную распечатать что угодно на терминале, используя, например, такие предикаты, как portray_clause/1, format/2 и т. Д.

Единственное, что вам нужно, это способ принудительного возврата для всех ответов. Один из способов сделать это - использовать false/0.

Итак, в вашем случае вы можете написать, например:

testing :-
        funcA(X),
        format("X = ~q ;~n", [X]),
        false.

А теперь вызов testing/0 дает без дальнейшего взаимодействия:

?- testing.
X = 1 ;
X = 2 ;
X = 3 ;

Кроме того, теперь предикаты не работают, поэтому вы также получаете false/0, если используете его в интерактивном режиме (с верхнего уровня), но нет, если вы вызываете testing из оболочки через swipl -g testing ....

Также обратите внимание на важную variable_names/1 опцию, которая доступна для использования предполагаемых имен переменных.

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

person mat    schedule 13.04.2017
comment
Действительно хороший ответ, но проблема, которую я представил, была просто абстракцией моего реального кода, который, к сожалению, интерактивен (находится в цикле меню). Так что он застревает на ложном. Во всяком случае, это ответ на то, что я спросил, большое вам спасибо. - person Haddex; 13.04.2017
comment
Пожалуйста. Позвольте мне также обратиться к вашему фактическому коду: один чистый выход - сначала отделить примеси (т.е. ввод / вывод) от фактической логики программы. Например, чтобы представить меню чистым способом, используйте предикат типа menu0_key_menu/3, связывающий одно состояние меню с новым состоянием меню, в зависимости от того, какой Key нажата. Таким образом, вы можете на самом деле протестировать, как ваше меню ведет себя, рассуждая об этой чистой связи, имитируя фактические нажатия клавиш, просто указывая их в целях, например menu0_key_menu(M0, q, exit)., что должно успешно (Например). - person mat; 13.04.2017