Search code examples
prologprolog-metainterpreter

meta-Programming Prolog ,List of ground facts


I must generate a list that contains all the ground terms that pass through a meta-programming in Prolog. I did it , but the last element I don't know why is duplicate, here my code :

KB:

parent(aa,vv).
parent(bb,aa). 
parent(bb,cc).
parent(dd,bb).

ancestor(X,Y):- parent(X,Y).
ancestor(X,Y):- ancestor(X,Z),parent(Z,Y).

Here is the meta-interpreter :

 solve(true,true,_):-!.
 solve((A,B),(ProofA,ProofB),Rest):- !, solve(A,ProofA,Rest), solve(B,ProofB,Rest).
 solve(A,(A:-Proof), [A:-Proof|Rest]):- ground(A),clause(A,B),solve(B,Proof,Rest).
 solve(A,(A:-Proof), List):- clause(A,B),solve(B,Proof,List).

My query is: solve(ancestor(dd,vv),H,N).

As I said previously, the interpreter inserts all ground facts in the list but it duplicates the last element. You can see it compiling my code.

Could you help me?


Solution

  • Your last clause of the solve/3 predicate overlaps with the previous one. I.e. it doesn't verify that the current goal that you're trying to prove is not ground. You can either add that test, \+ ground(A) or combine the two last clauses in a single one using an if-then-else control construct:

    solve(A, (A:-Proof), List) :-
        (   ground(A) ->
            List = [A:-Proof| Rest],
            clause(A, B),
            solve(B, Proof, Rest)
        ;   clause(A, B),
            solve(B, Proof, List)
        ).
    

    But your definition of this predicate is odd. Shouldn't the ground/1 test be done after calling clause? And shouldn't you verify that B == true to ensure that you're using facts from the KB?