Newsgroups: comp.lang.prolog
Path: cantaloupe.srv.cs.cmu.edu!europa.chnt.gtegsc.com!gatech!news.sprintlink.net!tank.news.pipex.net!pipex!sunsite.doc.ic.ac.uk!hgmp.mrc.ac.uk!news.dcs.warwick.ac.uk!not-for-mail
From: N.Parekh@dcs.warwick.ac.uk (Neelesh)
Subject: Candidate Elimination / Version Spaces
X-Nntp-Posting-Host: nop
Message-ID: <1995Jul27.163459.8854@dcs.warwick.ac.uk>
Originator: N.Pa@nop
Sender: neepar@nop (Neelesh Parekh)
Organization: Department of Computer Science, Warwick University, England
Date: Thu, 27 Jul 1995 16:34:59 GMT
Lines: 180


Ok,
	I've implemented a Candidate Elimination algorithm (Machine Learning) as
outlined by Mitchell,T (1977). I can't see for the life of me what is going
wrong, i've included the code below (compiler is IC Prolog but the code below
should be generic) with a short series of sequences of learning examples.... but
the result isn't as it should be.
	I have a feeling that the problem lies in the specialize/specialize_set
clauses - but i can't seem to put my finger on it. If anyone can help me find
the err' of my ways i would be forever indebted to them.
Also, if anyone has a working solution of the most general form (or otherwise) i
would appreciate i if they could forward me a copy.
	Thanks in advance,
			Neelesh.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
covers([],[]).
covers([H1|T1],[H2|T2]) :-
	var(H1), var(H2),
	covers(T1,T2).
covers([H1|T1],[H2|T2]) :-
	var(H1), atom(H2),
	covers(T1,T2).
covers([H1|T1],[H2|T2]) :-
	atom(H1), atom(H2), H1 = H2,
	covers(T1,T2).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
generalize([],[],[]). 

generalize([Feature|Rest],[Inst_prop|Rest_inst],[Feature|Rest_gen]) :-
	not(Feature \= Inst_prop),
	generalize(Rest,Rest_inst,Rest_gen).

generalize([Feature|Rest],[Inst_prop|Rest_inst],[_|Rest_gen]) :-
	Feature \= Inst_prop,
	generalize(Rest,Rest_inst,Rest_gen).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
generalize_set([],[],_).

generalize_set([Hypothesis|Rest],Updated_H,Instance) :-
	not(covers(Hypothesis, Instance)),
	(bagof(X,generalize(Hypothesis,Instance,X), Updated_head);
	    Updated_head=[]),
	generalize_set(Rest,Updated_rest,Instance),
	append(Updated_head,Updated_rest,Updated_H).    

generalize_set([Hypothesis|Rest],[Hypothesis|Updated_rest],Instance) :-
	covers(Hypothesis,Instance),
	generalize_set(Rest,Updated_rest,Instance).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
delete(X,L,Goal,New_L) :-
	(bagof(X,(member(X,L),not(Goal)),New_L);New_L=[]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
more_general(X,Y) :- not(covers(Y,X)),covers(X,Y).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
process(negative(Instance),G,S,Updated_G,Updated_S,Types):-
	delete(X,S,covers(X,Instance),Updated_S),                      
	specialize_set(G,Spec_G,Instance,Types),                        
	delete(X,Spec_G,(member(Y,Spec_G),more_general(Y,X)),Pruned_G), 
	delete(X,Pruned_G,(member(Y,Updated_S),not(covers(X,Y))),Updated_G),

process(positive(Instance),G,[],Updated_G,[Instance],_):-
	delete(X,G,not(covers(X,Instance)),Updated_G).

process(positive(Instance),G,S,Updated_G,Updated_S,_) :-
	delete(X,G,not(covers(X,Instance)),Updated_G),
	generalize_set(S,Gen_S,Instance),
	delete(X,Gen_S,(member(Y,Gen_S),more_general(X,Y)),Pruned_S),
	delete(X,Pruned_S,not((member(Y,Updated_G),covers(Y,X))),Updated_S).

process(Input,G,P,G,P,_) :-
	Input \= positve(_),
	Input \= negative(_),
	write('Enter positive(Instance) or negative(Instance)'),nl.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
specialize_set([],[],_,_).

specialize_set([Hypothesis|Rest],Updated_H,Instance,Types) :-
	covers(Hypothesis,Instance),
	(bagof(Hypothesis,specialize(Hypothesis,Instance,Types),Updated_head);
	    Updated_head=[]),
	specialize_set(Rest,Updated_rest,Instance,Types),
	append(Updated_head,Updated_rest,Updated_H).
	
specialize_set([Hypothesis|Rest],[Hypothesis|Updated_rest],Instance,Types) :-
	not(covers(Hypothesis,Instance)),
	specialize_set(Rest,Updated_rest,Instance,Types).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
specialize([Prop|_],[Inst_prop|_],[Instance_values|_]) :-
	var(Prop),
	member(Prop,Instance_values),
	Prop \= Inst_prop.

specialize([_|Tail],[_|Inst_tail],[_|Types]) :-
	specialize(Tail,Inst_tail,Types).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
candidate_elim([G],[S],_) :-
	covers(G,S),covers(S,G),
	write('Target concept is'),
	write(G),nl.

candidate_elim(G,S,Types) :-
	nl,
	write('G='),write(G),nl,
	write('S='),write(S),nl,
	write('Enter an Instance:'),nl,
	read(Instance),nl,
	process(Instance,G,S,Updated_G,Updated_S,Types),
	candidate_elim(Updated_G,Updated_S,Types).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*

These are the sequence of training examples, starting with an initialisation
sequence
			**************************

candidate_elim([[_,_,_]],[],[[small,medium,large],[red,blue,green],[ball,brick,cube]]).

positive([small,red,ball]).
negative([large,green,cube]).
negative([small,blue,brick]).
positive([small,green,ball]).
positive([large,red,ball]).

			**************************

The results are supposed to be of the form:

?- candidate_elim([[_,_,_]],[],[[small,medium,large],[red,blue,green],[ball,brick,cube]]).
G= [[_01,_02,_03]] 
S= [] 

?- positive([small,red,ball]).
G= [[_01,_02,_03]] 
S= [[small,red,ball]] 

?- negative([large,green,cube]).
G= [[small,_96,_97],[_86,red,_87],[_76,_77,ball]] 
S= [[small,red,ball]] 

?- negative([small,blue,brick]).
G= [[_86,red,_87],[_76,_77,ball]] 
S= [[small,red,ball]] 

?- positive([small,green,ball]).
G= [[_76,_77,ball]] 
S= [[small,_351,ball]] 

?- positive([large,red,ball]).
Target concept is [_76,_77,ball]
yes


*/



-- 
_______________________________________________________________
Neelesh Parekh			Department of Computer Science.
neepar@dcs.warwick.ac.uk	University of Warwick. England.
_______________________________________________________________
-- 
_______________________________________________________________
Neelesh Parekh			Department of Computer Science.
neepar@dcs.warwick.ac.uk	University of Warwick. England.
_______________________________________________________________
