Как получить все факты, полученные в результате вывода правил цепочки в Prolog

Я реализовал несколько правил цепочки таким образом, чтобы последнее правило получало желаемый результат в зависимости от результата предыдущих.

rule1(X,Y) :-
   pred1(X,Z),
   pred1(Y,Z).

rule2(Z,T) :- 
   rule1(X,Y),
   pred2(Z,X),
   pred2(T,Y).

Мне нужно получить каждый факт, который был выведен для каждого из правил. Я делаю это с Java, используя библиотеку jpl.

String stringFileQuery = "rule1(X,Y)";
System.out.println(stringFileQuery + " "
   + (Query.hasSolution(stringFileQuery) ? "succeeded" : "failed"));
Query fileQuery = new Query(stringFileQuery);
System.out.println("all solutions of " + stringFileQuery);
while (fileQuery.hasMoreSolutions()) {
    Map<String, Term> s10 = fileQuery.nextSolution();
    System.out.println("First -> " + s10.get("X") + ", Second ->" + 10.get("Y"));
}

Как я могу получить все эти факты даже на Прологе? В реальной программе у меня больше двух правил.


person Caleb    schedule 17.06.2016    source источник
comment
Вы имели в виду rule1(X,Y) :- pred1(X,Z), pred1(Y,Z). и rule2(Z,T) :- rule1(X,Y), pred2(Z,X), pred2(T,Y).?   -  person SQB    schedule 21.06.2016
comment
Да, идея состоит в том, что верхнее правило строится поверх другого путем соединения его предикатов; и для каждого вызова правила2 мне нужно получить полученные факты.   -  person Caleb    schedule 21.06.2016
comment
Итак, если вы проверяете rule1(X,Y), вы хотели бы видеть pred1(X,Z), pred1(Y,Z), а если проверяете rule2(Z,T), вы хотели бы видеть pred1(X,Z), pred1(Y,Z), pred2(Z,X), pred2(T,Y)?   -  person SQB    schedule 21.06.2016
comment
Но мне нужно было знать, можно ли проверить верхнее правило, например rule1 и получить все результаты процесса вывода для других правил, например, отследить весь процесс с возвратом.   -  person Caleb    schedule 21.06.2016
comment
Не могли бы вы дополнить свой вопрос примерами того, что вы ищете? Как я вставил pred1(X, Y), поэтому я ожидаю вывода ...; Я вставил pred2(Z,T), поэтому ожидаю вывода ...?   -  person SQB    schedule 21.06.2016


Ответы (1)


Здесь вы ищете метаинтерпретатор. для Prolog, который записывает факты по мере продвижения. Поскольку Prolog - это гомоиконический язык, написать простой метаинтерпретатор будет тривиально.

Вероятно, вы захотите использовать clause_property/2, чтобы проверить, является ли рассматриваемое предложение фактом, например так

recordFacts(Goal, [Goal|Facts]) :-
    clause(Goal, _Body, Ref),
    clause_property(Ref, fact).

Редактировать

Полный пример будет примерно таким:

recordFacts(Goal, Facts) :-
    recordFacts(Goal, [], AllFacts),
    list_to_set(AllFacts, Facts).

recordFacts((Goal, RestOfGoals), FactsIn, FactsOut) :-
    recordFacts(Goal, FactsIn, FactsH),
    recordFacts(RestOfGoals, FactsH, FactsOut).

recordFacts(Goal, Facts, [Goal|Facts]) :-
    clause(Goal, _, Ref),
    clause_property(Ref, fact).

recordFacts(Goal, FactsIn, FactsOut) :-
    clause(Goal, Body, Ref),
    not(clause_property(Ref, fact)),
    not(clause_property(Ref, predicate(system: (',')/2))),
    recordFacts(Body, FactsIn, FactsOut).
person SQB    schedule 22.06.2016