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?
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?