/*--------------------------------------------------------*/ /* Rule Induction by Set Covering (Sicstus Prolog) */ /*--------------------------------------------------------*/ /* (C) 1994 Zdravko Markov */ /*--------------------------------------------------------*/ /* Call: lrn */ /*--------------------------------------------------------*/ ?- op(100,fx,if). ?- op(99,xfy,then). /*--------------------------------------------------------*/ lrn :- initialize, build_sets, class(Class,Examples), write('Processing class' - Class/Examples),nl, lrn(Class,Cover), write('Cover' = Cover),nl, assert_rules(Cover,Class), fail. lrn. lrn(Class,GeneralRules) :- class(Class,Examples), cover(Examples,Examples,Rules), !, remove_subsumed(Rules,GeneralRules). initialize :- retractall(class(_,_)), retractall(attribute(_,_)), retractall(if(_)), !. cover([],_,[]). cover([E|Es],Examples,[Rule/CoverSet|Rules]) :- example(E,_,L), !, combine(Rule,L), intersect(Rule,CoverSet), subset(CoverSet,Examples), !, difference(Es,CoverSet,Rest), cover(Rest,Examples,Rules). remove_subsumed([],[]) :- !. remove_subsumed([_/Cover|Rest],Rules) :- subsumed(Cover,Rest), !, remove_subsumed(Rest,Rules). remove_subsumed([Rule/_|Rest],[Rule|Rules]) :- remove_subsumed(Rest,Rules). subsumed(X,[_/Y|_]) :- subset(X,Y), !. subsumed(X,[_|T]) :- subsumed(X,T). build_sets :- example(E,C,L), class_sets(E,C), member_all(A=V,L), attribute_sets(E,A=V), fail. build_sets. class_sets(E,C) :- retract(class(C,L)), asserta(class(C,[E|L])), !. class_sets(E,C) :- asserta(class(C,[E])). attribute_sets(E,A=V) :- retract(attribute(A=V,L)), asserta(attribute(A=V,[E|L])), !. attribute_sets(E,A=V) :- asserta(attribute(A=V,[E])). assert_rules([],_) :- !. assert_rules([Cond|T],Class) :- assertz(if Cond then Class), assert_rules(T,Class). /*------------------- Auxiliary --------------------------*/ intersect([X],A) :- attribute(X,A), !. intersect([X|T],C) :- intersect(T,B), !, attribute(X,A), intersect2(A,B,C). intersect2([],_,[]) :- !. intersect2([X|T],L,[X|R]) :- member(X,L), !, intersect2(T,L,R). intersect2([_|T],L,R) :- intersect2(T,L,R). member_all(X,[X|_]). member_all(X,[_|T]) :- member_all(X,T). subset([],_) :- !. subset([X|T],L) :- member(X,L), !, subset(T,L). difference([],_,[]) :- !. difference([X|T],L,V) :- member(X,L), !, difference(T,L,V). difference([X|T],L,[X|V]) :- difference(T,L,V). efface(X,[X|T],T) :- !. efface(X,[Y|T],[Y|L]) :- efface(X,T,L). combine(S,L) :- length(L,N), gen_list(S,N), sublist(S,L). gen_list(_,0) :- !,fail. gen_list([_],_). gen_list([_|T],N) :- M is N-1, gen_list(T,M). sublist([X],[X|_]). sublist(X,[_|T]) :- sublist(X,T). sublist([X|T],[X|V]) :- sublist(T,V). member(X,[X|_]) :- !. member(X,[_|T]) :- member(X,T).