% Bottom-Up Evaluation
% ====================

:- dynamic fact/1.
:- dynamic database_changed/0.

iterate_tp :- tp.
iterate_tp :- retract(database_changed), iterate_tp.
iterate_tp :- showfacts.

tp :- my_clause(H,B),  prove(B), cond_assert(fact(H)), fail.

prove((B,Bs)) :- fact(B), prove(Bs).  
prove(B) :- fact(B).

cond_assert(G) :- in_database(G) , !.
cond_assert(G) :- assert(G), cond_assert(database_changed).

in_database(fact(F)) :-
        numbervars(F,0,_), fact(F). 
in_database(database_changed) :- database_changed.

fact(true).

showfacts :- 
        fact(F), copy_term(F,FCopy), 
        numbervars(FCopy,0,_),write(FCopy), nl, fail.
showfacts.



%%
%% INPUT EXAMPLE
%% =============
%%
%%
%%  the program :
%%
%%    path(X,Y) :- edge(X,Y).
%%    path(X,Y) :- path(X,Z) ,path(Z,Y).
%%   
%%    edge(a,b).
%%    edge(b,c).
%%    edge(a,d).
%%    edge(c,d).
%%    edge(d,a).
%%
%%
%%  the code in the above Meta-Interpreter format will be :
%%
my_clause( path(X,Y) , edge(X,Y) ).                  % path(X,Y) :- edge(X,Y).
my_clause( path(X,Y) , ( path(X,Z) ,path(Z,Y) ) ).   % path(X,Y) :- path(X,Z) ,path(Z,Y).
my_clause( edge(a,b) , true).                        % edge(a,b).
my_clause( edge(b,c) , true).                        % edge(b,c).
my_clause( edge(a,d) , true).                        % edge(a,d).
my_clause( edge(c,d) , true).                        % edge(c,d).
my_clause( edge(d,a) , true).                        % edge(d,a).
