Skip to content

Commit 0dc7945

Browse files
committed
Sections 9.2-3
1 parent f333457 commit 0dc7945

File tree

2 files changed

+542
-0
lines changed

2 files changed

+542
-0
lines changed

section92.pl

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2+
% %
3+
% Prolog programs from Section 9.2 of the book %
4+
% SIMPLY LOGICAL: Intelligent reasoning by example %
5+
% (c) Peter A. Flach/John Wiley & Sons, 1994. %
6+
% %
7+
% Predicates: induce_rlgg/2 %
8+
% rlgg/4 %
9+
% %
10+
% NB. This file needs predicates defined in %
11+
% the file 'library'. %
12+
% %
13+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14+
15+
16+
%:-consult(library).
17+
18+
19+
%%% 9.2 Bottom-up induction %%%
20+
21+
induce_rlgg(Exs,Clauses):-
22+
writeln('%%% Bottom-up induction %%%'),
23+
writeln('Examples'),
24+
writelns(Exs),
25+
pos_neg(Exs,Poss,Negs),
26+
bg_model(BG),
27+
append(Poss,BG,Model),
28+
induce_rlgg(Poss,Negs,Model,Clauses).
29+
30+
induce_rlgg(Poss,Negs,Model,Clauses):-
31+
covering(Poss,Negs,Model,[],Clauses).
32+
33+
% split positive and negative examples
34+
pos_neg([],[],[]).
35+
pos_neg([+E|Exs],[E|Poss],Negs):-
36+
pos_neg(Exs,Poss,Negs).
37+
pos_neg([-E|Exs],Poss,[E|Negs]):-
38+
pos_neg(Exs,Poss,Negs).
39+
40+
% covering algorithm
41+
covering(Poss,Negs,Model,H0,H):-
42+
construct_hypothesis(Poss,Negs,Model,Hyp),!,
43+
remove_pos(Poss,Model,Hyp,NewPoss),
44+
nl,writeln('<return> to continue'),
45+
readln(_),nl,nl,
46+
covering(NewPoss,Negs,Model,[Hyp|H0],H).
47+
covering(P,_N,_M,H0,H):-
48+
append(H0,P,H). % add uncovered examples to hypothesis
49+
50+
% remove covered positive examples
51+
remove_pos([],_M,_H,[]).
52+
remove_pos([P|Ps],Model,Hyp,NewP):-
53+
covers_ex(Hyp,P,Model),!,
54+
write('Covered example: '),write(P),nl,
55+
remove_pos(Ps,Model,Hyp,NewP).
56+
remove_pos([P|Ps],Model,Hyp,[P|NewP]):-
57+
remove_pos(Ps,Model,Hyp,NewP).
58+
59+
60+
% extensional coverage, relative to a ground model
61+
covers_ex((Head:-Body),Example,Model):-
62+
try((Head=Example,forall(element(L,Body),element(L,Model)))).
63+
64+
% construct a clause by means of RLGG
65+
construct_hypothesis([E1,E2|_Es],Negs,Model,Clause):-
66+
write('RLGG of '),write(E1),write(' and '),write(E2),write(' is'),
67+
rlgg(E1,E2,Model,Cl),
68+
reduce(Cl,Negs,Model,Clause),!,
69+
nl,portray_clause(Clause),nl.
70+
construct_hypothesis([_E1,E2|Es],Negs,Model,Clause):-
71+
write(' too general'),nl,
72+
construct_hypothesis([E2|Es],Negs,Model,Clause).
73+
74+
75+
% rlgg(E1,E2,M,C) <- C is RLGG of E1 and E2 relative to M
76+
rlgg(E1,E2,M,(H:-B)):-
77+
anti_unify(E1,E2,H,[],S10,[],S20),
78+
varsin(H,V), % determine variables in head of clause
79+
rlgg_bodies(M,M,[],B,S10,_S1,S20,_S2,V).
80+
81+
rlgg_bodies([],_B2,B,B,S1,S1,S2,S2,_V).
82+
rlgg_bodies([L|B1],B2,B0,B,S10,S1,S20,S2,V):-
83+
rlgg_literal(L,B2,B0,B00,S10,S11,S20,S21,V),
84+
rlgg_bodies(B1,B2,B00,B,S11,S1,S21,S2,V).
85+
86+
rlgg_literal(_L1,[],B,B,S1,S1,S2,S2,_V).
87+
rlgg_literal(L1,[L2|B2],B0,B,S10,S1,S20,S2,V):-
88+
same_predicate(L1,L2),
89+
anti_unify(L1,L2,L,S10,S11,S20,S21),
90+
varsin(L,Vars),var_proper_subset(Vars,V), % no new variables in literal
91+
!,rlgg_literal(L1,B2,[L|B0],B,S11,S1,S21,S2,V).
92+
rlgg_literal(L1,[_L2|B2],B0,B,S10,S1,S20,S2,V):-
93+
rlgg_literal(L1,B2,B0,B,S10,S1,S20,S2,V).
94+
95+
96+
:-op(600,xfx,'<-').
97+
98+
anti_unify(Term1,Term2,Term):-
99+
anti_unify(Term1,Term2,Term,[],_S1,[],_S2).
100+
101+
anti_unify(Term1,Term2,Term1,S1,S1,S2,S2):-
102+
Term1 == Term2,!.
103+
anti_unify(Term1,Term2,V,S1,S1,S2,S2):-
104+
subs_lookup(S1,S2,Term1,Term2,V),!.
105+
anti_unify(Term1,Term2,Term,S10,S1,S20,S2):-
106+
nonvar(Term1),nonvar(Term2),
107+
functor(Term1,F,N),functor(Term2,F,N),!,
108+
functor(Term,F,N),
109+
anti_unify_args(N,Term1,Term2,Term,S10,S1,S20,S2).
110+
anti_unify(Term1,Term2,V,S10,[Term1<-V|S10],S20,[Term2<-V|S20]).
111+
112+
anti_unify_args(0,_Term1,_Term2,_Term,S1,S1,S2,S2).
113+
anti_unify_args(N,Term1,Term2,Term,S10,S1,S20,S2):-
114+
N>0,N1 is N-1,
115+
arg(N,Term1,Arg1),
116+
arg(N,Term2,Arg2),
117+
arg(N,Term,Arg),
118+
anti_unify(Arg1,Arg2,Arg,S10,S11,S20,S21),
119+
anti_unify_args(N1,Term1,Term2,Term,S11,S1,S21,S2).
120+
121+
subs_lookup([T1<-V|_Subs1],[T2<-V|_Subs2],Term1,Term2,V):-
122+
T1 == Term1,
123+
T2 == Term2,!.
124+
subs_lookup([_S1|Subs1],[_S2|Subs2],Term1,Term2,V):-
125+
subs_lookup(Subs1,Subs2,Term1,Term2,V).
126+
127+
128+
% remove redundant literals
129+
reduce((H:-B0),Negs,M,(H:-B)):-
130+
setof0(L,(element(L,B0),not(var_element(L,M))),B1),
131+
reduce_negs(H,B1,[],B,Negs,M).
132+
133+
% reduce_negs(H,B1,B0,B,N,M) <- B is a subsequence of B1
134+
% such that H:-B does not
135+
% cover elements of N
136+
reduce_negs(H,[_L|B0],In,B,Negs,M):-
137+
append(In,B0,Body),
138+
not(covers_neg((H:-Body),Negs,M,_N)),!,
139+
reduce_negs(H,B0,In,B,Negs,M).
140+
reduce_negs(H,[L|B0],In,B,Negs,M):-
141+
reduce_negs(H,B0,[L|In],B,Negs,M).
142+
reduce_negs(H,[],Body,Body,Negs,M):-
143+
not(covers_neg((H:-Body),Negs,M,_N)).
144+
145+
covers_neg(Clause,Negs,Model,N):-
146+
element(N,Negs),
147+
covers_ex(Clause,N,Model).
148+
149+
150+
%%% From library %%%
151+
152+
%%% Lists and sets
153+
154+
% element(X,Ys) <- X is an element of the list Ys
155+
element(X,[X|_Ys]).
156+
element(X,[_Y|Ys]):-
157+
element(X,Ys).
158+
159+
var_element(X,[Y|_Ys]):-
160+
X == Y. % syntactic identity
161+
var_element(X,[_Y|Ys]):-
162+
var_element(X,Ys).
163+
164+
var_remove_one(X,[Y|Ys],Ys):-
165+
X == Y. % syntactic identity
166+
var_remove_one(X,[Y|Ys],[Y|Zs]):-
167+
var_remove_one(X,Ys,Zs).
168+
169+
var_proper_subset([],Ys):-
170+
Ys \= [].
171+
var_proper_subset([X|Xs],Ys):-
172+
var_remove_one(X,Ys,Zs),
173+
var_proper_subset(Xs,Zs).
174+
175+
176+
% try(Goal) <- Goal succeeds, but variables are not instantiated
177+
try(Goal):-
178+
not(not(Goal)).
179+
180+
181+
%%% Various.
182+
183+
% variant of setof/3 which succeeds with the empty list
184+
% if no solutions can be found
185+
setof0(X,G,L):-
186+
setof(X,G,L),!.
187+
setof0(_X,_G,[]).
188+
189+
% same_predicate(L1,L2) <- literals L1 and L2 have
190+
% the same predicate and arity
191+
same_predicate(L1,L2):-
192+
functor(L1,P,N),functor(L2,P,N).
193+
194+
varsin(Term,Vars):-
195+
varsin(Term,[],V),
196+
sort(V,Vars).
197+
198+
varsin(V,Vars,[V|Vars]):-
199+
var(V),!.
200+
varsin(Term,V0,V):-
201+
functor(Term,_,N),
202+
varsin_args(N,Term,V0,V).
203+
204+
varsin_args(0,_,Vars,Vars).
205+
varsin_args(N,Term,V0,V):-
206+
N>0, N1 is N-1,
207+
arg(N,Term,ArgN),
208+
varsin(ArgN,V0,V1),
209+
varsin_args(N1,Term,V1,V).
210+
211+
212+
%%% For lectures
213+
214+
writelns(X):-
215+
( X=[] -> nl
216+
; X=[H|T] -> writelns(H),writelns(T)
217+
; otherwise -> write(X),nl
218+
).
219+
220+
221+
%%% Queries %%%
222+
223+
%%%%%%%%%%%%%%%%%% element/2 %%%%%%%%%%%%%%%%%%%%%%%%
224+
225+
% bg_model([]).
226+
227+
query1(Clauses):-
228+
induce_rlgg([+element(b,[b]),
229+
+element(2,[2,3]),
230+
+element(3,[1,2,3]),
231+
+element(b,[a,b]),
232+
+element(3,[2,3]),
233+
+element(3,[3]),
234+
-element(3,[a,b]),
235+
-element(a,[])
236+
],Clauses).
237+
238+
%%%%%%%%%%%%%%%%%% append/3 %%%%%%%%%%%%%%%%%%%%%%%
239+
240+
% bg_model([]).
241+
242+
query2(Clauses):-
243+
induce_rlgg([+append([1,2],[3,4],[1,2,3,4]),
244+
+append([a],[],[a]),
245+
+append([],[],[]),
246+
+append([],[1,2,3],[1,2,3]),
247+
+append([2],[3,4],[2,3,4]),
248+
+append([],[3,4],[3,4]),
249+
-append([a],[b],[b]),
250+
-append([c],[b],[c,a]),
251+
-append([1,2],[],[1,3])
252+
],Clauses).
253+
254+
%%%%%%%%%%%%%%%%%% num/2 %%%%%%%%%%%%%%%%%%%%%%%
255+
256+
bg_model([num(1,one),
257+
num(2,two),
258+
num(3,three),
259+
num(4,four),
260+
num(5,five)
261+
]).
262+
263+
query3(Clauses):-
264+
induce_rlgg([+listnum([],[]),
265+
+listnum([2,three,4],[two,3,four]),
266+
+listnum([4],[four]),
267+
+listnum([three,4],[3,four]),
268+
+listnum([two],[2]),
269+
-listnum([1,4],[1,four]),
270+
-listnum([2,three,4],[two]),
271+
-listnum([five],[5,5])
272+
],Clauses).
273+
274+
%%%%%%%%%%%%%%%%%% names/2 %%%%%%%%%%%%%%%%%%%%%%%
275+
276+
/*
277+
bg_model([person(mick,jagger),
278+
person(david,bowie),
279+
person(tina,turner),
280+
person(johann,sebastian),
281+
person(ludwig,van)
282+
]).
283+
*/
284+
285+
query4(Clauses):-
286+
induce_rlgg([+names([],[]),
287+
+names([david,turner,johann],[p(david,bowie),p(tina,turner),p(johann,sebastian)]),
288+
+names([johann],[p(johann,sebastian)]),
289+
+names([turner,johann],[p(tina,turner),p(johann,sebastian)]),
290+
+names([bowie],[p(david,bowie)]),
291+
-names([mick,johann],[p(mick,mick),p(johann,sebastian)]),
292+
-names([david,turner,johann],[p(david,bowie)]),
293+
-names([van],[p(ludwig,van),p(ludwig,van)])
294+
],Clauses).
295+
296+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297+
298+
299+
300+
301+

0 commit comments

Comments
 (0)