PROLOG
% General to specific induction algorithm
% run_general() :- Calls general_to_specific with H initialized
% to the most general feature vector and N initialized to []
% Also, provides the types for specializing simple vectors of
% type [size, color, shape].
run_general :-
general_to_specific([[_,_,_]], [],
[[small, medium, large], [red, blue, green], [ball, brick, cube]]).
% general_to_specific(List_of_hypotheses, List_of_positives, List_of_types) :-
% This is the top level control loop. It reads in a new positive or
% negative instance and calls process to update List_of_hypotheses
% and List_of_positives. List_of_types is passed in for specializing
% descriptions.
general_to_specific(H, P, Types) :-
write("H = "), write(H),nl,
write("P = "), write(P),nl,
write("Enter Instance "),
read(Instance),
process(Instance, H, P, Updated_H, Updated_P, Types),
general_to_specific(Updated_H, Updated_P, Types).
% process(Instance, List_of_hypotheses, List_of_positives,
% Updated_hypotheses, Updated_positives, List_of_types) :-
% updates List_of_hypotheses and List_of_types in response to
% Instance. LIst_of_types is passed through to enable specialization.
process(negative(Instance), H, P, Updated_H, P, Types) :-
specialize_set(H,Spec_H, Instance, Types),
delete(X, Spec_H, (member(Y, Spec_H), more_general(Y, X)), Pruned_H),
delete(X, Pruned_H, (member(Y, P), not(covers(X, Y))), Updated_H).
process(positive(Instance), H, P, Updated_H, [Instance|P], _) :-
delete(X, H, not(covers(X, Instance)), Updated_H).
process(Input, H, P, H, P,_):-
Input \= positive(_),
Input \= negative(_),
write("Enter either 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).
% more_general(Feature_vector_1, Feature_vector_2) :- succeeds if
% Feature_vector_1 is strictly more general than Feature_vector_2
more_general(X, Y) :- not(covers(Y, X)), covers(X, Y).
% covers(Feature_list_1, Feature_list_2) :- Succeeds if Feature_list_1
% covers Feature_list_2. Note that covers, unlike unification is
% not symmetric: variables in Feature_list_2 will not match constants
% in Feature_list_1.
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).
% delete(Element, List1, Goal, List2) :- List2 contains all bindings
% of Element to a member of List1 except thos that cause
% Goal to succeed
delete(X, L, Goal, New_L) :-
(bagof(X, (member(X, L), not(Goal)), New_L);New_L = []).
Close Window