:- dynamic
    base/2,
    closure_cache/2,
    needs_recomputing/0.

c_assert(Fact) :-
    (    clause(Fact,true) -> true
     ;   assert(Fact)
     ).

add_base(P,C) :-
	(   base(P,C)   -> true
	;   assert(base(P,C)),
	    c_assert(needs_recomputing)
	).

	
del_base(P,C) :-
    (    retract(base(P,C)) ->
         c_assert(needs_recomputing)
     ;   true
     ).

recompute_if_necessary :-
    (    needs_recomputing,
         retractall(closure_cache(_,_)),
         setof(Parent-Children,
	       setof(Child, base(Parent, Child), Children),
	       Graph),
         warshall(Graph,Closure),
	 member(Ancestor-Descendents,Closure),
	 member(Descendent,Descendents),
	 assert(closure_cache(Ancestor,Descendent)),
	 fail
     ;   retract(needs_recomputing)
     ).

closure(X,Y) :-
    recompute_if_necessary,
    closure_cache(X,Y).


startout :- 
    add_base(1,2),
    add_base(2,3).

