% This program uses three predicates defined elsewhere:
%    est - the procedure that establishes a query
%    background - the background knowledge to be used
%    predicate - an atom that can be used in a rule

induce(Q,R) :- background(K), rule(R), est([R|K],Q).
rule([H|B]) :- hb(H,B,_,_), \+ B=[].

% hb(H,B,P,V): H is an atom with pred P and vars V and
% B is a list of literals with pred not P and vars among the V.
hb(H,[],P,V) :- predicate(H,P,V).
hb(H,[L|B],P,V) :- hb(H,B,P,V), lit(L,Q,U,B), \+ Q=P, subl(U,V).

% lit(L,P,V,B): L is a literal with pred P and vars V, where the 
% neg case can only be used if the literals in B are also neg.
lit(A,P,V,_) :- predicate(A,P,V).            % the positive case
lit(not(A),P,V,[]) :- predicate(A,P,V).      % the 1st neg case
lit(not(A),P,V,[not(_)|_]) :- predicate(A,P,V).    % a 2nd case

% subl(L1,L2): the elements of list L1 are all elements of L2.
subl([],_).
subl([X|L1],L2) :- member(X,L2), subl(L1,L2).
