PROLOG
% Specific to general induction algorithm
% run_specific():-Calls specific_to_general with both H and N initialized to []
run_specific :- specific_to_general([],[]).
% specific_to_general(List_of_hypotheses, List_of_negatives) :-
% 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_negatives.
specific_to_general(H, N) :-
write("H = "), write(H),nl,
write("N = "), write(N),nl,
write("Enter Instance "),
read(Instance),
process(Instance, H, N, Updated_H, Updated_N),
specific_to_general(Updated_H, Updated_N).
% process(Instance, List_of_hypotheses, List_of_negatives,
% Updated_hypotheses, Updated_negatives) :-
% updates List_of_hypotheses and List_of_negatives in response to
% Instance.
process(positive(Instance), [], N, [Instance], N).
% Initialize H
process(positive(Instance), H, N, Updated_H, N) :-
generalize_set(H,Gen_H, Instance),
delete(X, Gen_H, (member(Y, Gen_H), more_general(X, Y)), Pruned_H),
delete(X, Pruned_H, (member(Y, N), covers(X, Y)), Updated_H).
process(negative(Instance), H, N, Updated_H, [Instance|N]) :-
delete(X, H, covers(X, Instance), Updated_H).
process(Input, H, N, H, N):-
Input \= positive(_),
Input \= negative(_),
write("Enter either positive(Instance) or negative(Instance) "), nl.
%
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).
%
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).
% 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 those that cause
% Goal to succeed
delete(X, L, Goal, New_L) :-
(bagof(X, (member(X, L), not(Goal)), New_L);New_L = []).
Close Window