% Figure 19.4 MINIHYPER - a simple ILP program. :- op( 900, fy, not). % not Goal): negation as failure; % Note: This is often available as a built-in predicate, % often written as prefix operator "\+", e.g. \+ likes(mary,snakes) not Goal :- Goal, !, fail ; true. % Program MINIHYPER % induce( Hyp): % induce a consistent and complete hypothesis Hyp by gradually % refining start hypotheses induce( Hyp) :- iter_deep( Hyp, 0). % Iterative deepening starting with max. depth 0 iter_deep( Hyp, MaxD) :- write( 'MaxD = '), write( MaxD), nl, start_hyp( Hyp0), complete( Hyp0), % Hyp0 covers all positive examples depth_first( Hyp0, Hyp, MaxD) % Depth-limited depth-first search ; NewMaxD is MaxD + 1, iter_deep( Hyp, NewMaxD). % depth_first( Hyp0, Hyp, MaxD): % refine Hyp0 into consistent and complete Hyp in at most MaxD steps depth_first( Hyp, Hyp, _) :- consistent( Hyp). depth_first( Hyp0, Hyp, MaxD0) :- MaxD0 > 0, MaxD1 is MaxD0 - 1, refine_hyp( Hyp0, Hyp1), complete( Hyp1), % Hyp1 covers all positive examples depth_first( Hyp1, Hyp, MaxD1). complete( Hyp) :- % Hyp covers all positive examples not (ex( E), % A positive example once( prove( E, Hyp, Answer)), % Prove it with Hyp Answer \== yes). % Possibly not proved consistent( Hyp) :- % Hypothesis does not possibly cover any negative example not (nex( E), % A negative example once( prove( E, Hyp, Answer)), % Prove it with Hyp Answer \== no). % Possibly provable % refine_hyp( Hyp0, Hyp): % refine hypothesis Hyp0 into Hyp refine_hyp( Hyp0, Hyp) :- conc( Clauses1, [Clause0/Vars0 | Clauses2], Hyp0), % Choose Clause0 from Hyp0 conc( Clauses1, [Clause/Vars | Clauses2], Hyp), % New hypothesis refine( Clause0, Vars0, Clause, Vars). % Refine the Clause % refine( Clause, Args, NewClause, NewArgs): % refine Clause with arguments Args giving NewClause with NewArgs % Refine by unifying arguments refine( Clause, Args, Clause, NewArgs) :- conc( Args1, [A | Args2], Args), % Select a variable A member( A, Args2), % Match it with another one conc( Args1, Args2, NewArgs). % Refine by adding a literal refine( Clause, Args, NewClause, NewArgs) :- length( Clause, L), max_clause_length( MaxL), L < MaxL, backliteral( Lit, Vars), % Background knowledge literal conc( Clause, [Lit], NewClause), % Add literal to body of clause conc( Args, Vars, NewArgs). % Add literal's variables % Default parameter settings max_proof_length( 6). % Max. proof length, counting calls to 'non-prolog' pred. max_clause_length( 3). % Max. number of literals in a clause