1
votes

I have implemented several chain rules in a way that the last rule obtain the desired result depending on the result of the previous ones.

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

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

I need to obtain every fact that has been inferred for each one of the rules. I'm doing this from Java using the jpl library.

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"));
}

How can I obtain all these facts, even in Prolog? In the real program, I have more that two rules.

1
Did you mean rule1(X,Y) :- pred1(X,Z), pred1(Y,Z). and rule2(Z,T) :- rule1(X,Y), pred2(Z,X), pred2(T,Y).?SQB
Yes, the idea is that the top rule is built on top of the other by connecting its predicates; and for every call of the rule2 I need to obtain the obtained facts.Caleb
So if you check for rule1(X,Y), you'd like to see pred1(X,Z), pred1(Y,Z) and if you check for rule2(Z,T), you'd like to see pred1(X,Z), pred1(Y,Z), pred2(Z,X), pred2(T,Y)?SQB
But I needed to know whether is possible to check the top rule, e.g. rule1, and retrieve all the results of the inference process for the other rules, like backtracking all the process.Caleb
Could you please update your question with examples of what you're looking for? Like "I put in pred1(X, Y), so I expect the output ...; I put in pred2(Z,T), so I expect the output ..."?SQB

1 Answers

1
votes

What you're looking for here, is a meta-interpreter for Prolog that records the facts as it goes along. Since Prolog is a homoiconic language, writing a simple meta-interpreter is trivial.

You probably will want to use clause_property/2 to check if a clause you're examining is a fact, like so

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

Edit

A complete example would be something like

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).