1:- module(ic_parser,
2 [translate_ics/2,
3 translate_ics_files/2,
4 download_ics/1,
5 parse_ics/2,
6 parse_ics_string/2,
7 add_var/2]). 8
9:- use_module(library(lists),
10 [append/3,
11 member/2]). 15:- use_module(parser_utils). 16:- use_module(debug). 17
19
32
33download_ics(URLstring):-
34 atom_codes(URL,URLstring),
35 translate_ics_files([URL],'./temp.pl'),
36 open('./temp.pl',read,Stream),
37 call_terms(Stream),
38 close(Stream).
39
40call_terms(Stream):-
41 read(Stream,Term),
42 (Term=end_of_file -> true
43 ; (Term = ics(Body,Head)-> call(user:ic(Body,Head)) 44 ; true),
45 call_terms(Stream)
46 ).
47
48translate_ics_files(FileList,OutFile):-
49 open(OutFile,write,Stream),
50 write(Stream,':-module(ics,[ics/2]).'),nl(Stream),nl(Stream),
51 translate_ics_list(FileList,Stream),
52 close(Stream).
53
54translate_ics_list([],_).
55translate_ics_list([InFile|FileList],Stream):-
56 write_debug('Parsing file '), write_debug(InFile),
57 translate_ics_opened(InFile,Stream),!,
58 write_debug(' --> OK'), nl,
59 translate_ics_list(FileList,Stream).
60
61merge_files(FileList,OutFile):-
63 open(OutFile,write,Stream),
65 FileList=[H|T],write(H),nl,write(T),nl,
66 merge_files_to_stream(FileList,Stream),
67 close(Stream).
68
69merge_files_to_stream([],_):-write('empty list'),nl.
70merge_files_to_stream([File|MoreFiles],OutStream):-
71 read_file_to_string(File,String),
72 write_string_to_stream(String,OutStream),
73 merge_files_to_stream(MoreFiles,OutStream).
74
75write_string_to_stream([],_).
76write_string_to_stream([Code|MoreCodes],Stream):-
77 put_code(Stream,Code),
78 write_string_to_stream(MoreCodes,Stream).
79
80translate_ics(InFile,OutFile):-
81 open(OutFile,write,Stream),
82 write(Stream,':-module(ics,[ics/2]).'),nl(Stream),nl(Stream),
83 translate_ics_opened(InFile,Stream),
84 close(Stream).
85
87translate_ics_opened(InFile,Stream):-
88 89 ruleml_parse_file(InFile,ICSR,Error),
90 (Error = no_ruleml
91 -> parse_ics(InFile,ICS),
92 write_ics_to_stream(ICS,Stream)
93 ; write_ics_to_stream(ICSR,Stream)
94 ).
95
96parse_ics(FileName,ICList):-
97 read_file_to_string(FileName,FileString),
98 phrase(elementList(FileString2),FileString),
99 drop_whites(FileString2, NoWhitesString),
100 phrase(ic_list(ICList,1), NoWhitesString).
101
102parse_ics_string(S,ICList):-
103 string_codes(S,String),
104 phrase(elementList(FileString2),String),
105 drop_whites(FileString2, NoWhitesString),
106 phrase(ic_list(ICList,1), NoWhitesString).
107
108
109
113
114ic_list([],_) -->
115 [].
116ic_list([IC|MoreICs],N) -->
117 ic(IC),
118 !,
119 {N1 is N+1},
120 ic_list(MoreICs,N1).
121ic_list([_|_],N) -->
122 {write('Error in IC number '),
123 write(N), write(' ***'), nl, fail}.
124
125ic(rule(((Head,_):-(Body,_)),0,P)) -->
126 number(P),
127 "::",
128 body(Body),
129 impl_symbol,!,
130 head2(Head).
131ic(_) -->
132 {nl, write('*** Error in Body or could not find implication symbol: '), nl, fail}.
133
134body([BodyAtom|MoreAtoms]) -->
135 abducible(BodyAtom),!,
136 body_tail(MoreAtoms).
137body([BodyAtom|MoreAtoms]) -->
138 event(BodyAtom),!,
139 body_tail(MoreAtoms).
140body([BodyAtom|MoreAtoms]) -->
141 body_atom(BodyAtom),!,
142 body_tail(MoreAtoms).
143body([true]) -->"true".
144body(_) -->
145 {nl, write('*** Body must begin with event or abducible.'), nl, fail}.
146
147body_tail([BodyAtom|MoreBodyAtoms]) -->
148 and_symbol,
149 body_atom(BodyAtom),
150 !,
151 body_tail(MoreBodyAtoms).
152body_tail([]) -->
153 [].
154body_tail(_) -->
155 comma,
156 {nl, write('*** Error in body conjunct: comma instead of /\\ symbol?'), fail}.
157
158body_atom(BodyAtom) -->
159 abducible(BodyAtom).
160body_atom(BodyAtom) -->
161 event(BodyAtom).
162body_atom(BodyAtom) -->
163 atom(BodyAtom).
164body_atom(BodyAtom) -->
165 relat(BodyAtom).
166
167relat(Relation) -->
168 clp_relation(Relation),
169 !.
170relat(Relation) -->
171 unify_relation(Relation).
172
173unify_relation(Relation) -->
174 term(Term1),
175 unify_operator(Operator),
176 term(Term2),
177 {Relation=..[Operator,Term1,Term2]}.
178
179clp_relation(Relation) -->
180 expression(Expression1),
181 clp_relop(Relop),
182 expression(Expression2),
183 {Relation=..[Relop,Expression1,Expression2]}.
184
185
186
187expression(Expression) -->
188 operand(Operand1),
189 clp_operator(CLPOperator),
190 operand(Operand2),
191 {Expression=..[CLPOperator,Operand1,Operand2]}.
192expression(Expression) -->
193 operand(Expression).
194expression(Expression) -->
195 term(Expression).
196
197is_constraint(C):-
198 C=..[R|_],
199 member(R,[=,<>,>=,>,=<,<,::]).
200
201clp_relop(=) -->
202 "==",
203 !.
204clp_relop(<>) -->
205 "<>",
206 !.
207clp_relop(>=) -->
208 ">=",
209 !.
210clp_relop(>) -->
211 ">",
212 !.
213clp_relop(=<) -->
214 "<=",
215 !.
216clp_relop(<) -->
217 "<".
218clp_relop(::) -->
219 "::".
220
221clp_operator(+) -->
222 "+".
223clp_operator(-) -->
224 "-".
225clp_operator(*) -->
226 "*".
227clp_operator(/) -->
228 "/".
229
230
231unify_operator(unif) -->
232 "=".
233unify_operator(not_unif) -->
234 "!=".
235
236operand(Number) -->
237 number(Number).
238operand(Variable) -->
239 variable(Variable).
240
241head2(Head) -->
242 head1(Head),
243 full_stop,!.
244head2(_) -->
245 {nl, write('*** Error in Head or could not find full stop: '), fail}.
246
247head1([])-->"false",!.
248head1(Head)-->head(Head).
249
250head([Disjunct|MoreDisjuncts]) -->
251 disjunct(Disjunct),
252 head_tail(MoreDisjuncts).
253
254
255disjunct_1(Disjunct1) -->
256 disjunct(Disjunct),
257 {constraints_before(Disjunct,Disjunct1)}.
258
259constraints_before(L1,L2):-
260 divide_constraints_from_abducibles(L1,Constraints,Abducibles),
261 append(Constraints,Abducibles,L2).
262
263divide_constraints_from_abducibles([],[],[]).
264divide_constraints_from_abducibles([H|T],[H|T1],L2):-
265 is_constraint(H),
266 !,
267 divide_constraints_from_abducibles(T,T1,L2).
268divide_constraints_from_abducibles([H|T],L1,[H|T2]):-
269 divide_constraints_from_abducibles(T,L1,T2).
270
271
272
273head_tail([Disjunct|MoreDisjuncts]) -->
274 or_symbol,
275 disjunct(Disjunct),
276 !,
277 head_tail(MoreDisjuncts).
278head_tail([]) -->
279 [].
280
281disjunct((-,[Conjunct|MoreConjuncts])) -->
282 en(Conjunct),
283 disjunct_tail(MoreConjuncts),!,
284 closing_parenthesis.
285
286disjunct((+,[Conjunct|MoreConjuncts])) -->
287 content(Conjunct),
288 disjunct_tail(MoreConjuncts).
289
290
291en(Content) -->
292 "not",
293 opening_parenthesis,
294 content(Content).
295
296
309disjunct_tail([Conjunct|MoreConjuncts]) -->
310 and_symbol,
311 head_conjunct(Conjunct),
312 !,
313 disjunct_tail(MoreConjuncts).
314disjunct_tail([]) -->
315 [].
316disjunct_tail(_) -->
317 comma,
318 {nl, write('*** Error in conjunct: comma instead of /\\ symbol?'), fail}.
319
320head_conjunct(Conjunct) -->
321 abducible(Conjunct).
322head_conjunct(Conjunct) -->
323 atom(Conjunct).
324head_conjunct(Conjunct) -->
325 relat(Conjunct).
326
327atom(Atom) -->
328 funct(Functor),
329 opening_parenthesis,
330 !,
331 term_list(Arguments),
332 closing_parenthesis,
333 {Atom=..[Functor|Arguments]}.
334
335
336
337abducible(Abducible) -->
338 abducible_functor(Functor),
339 opening_parenthesis,
340 content(Content),
341 closing_parenthesis,
342 {Abducible=..[Functor,Content]}.
343
344event(Event) -->
345 event_functor(hap),
346 opening_parenthesis,
347 content(Content),
348 comma,
349 time(Time),
350 closing_parenthesis,
351 {Event=..[hap,Content,Time]}.
352
353event((\+ Event)) -->
354 event_functor(noth),
355 opening_parenthesis,
356 content(Content),
357 comma,
358 time(Time),
359 closing_parenthesis,
360 {Event=..[hap,Content,Time]}.
361
362
363abducible_functor(e) -->
364 "E".
365abducible_functor(en) -->
366 "EN".
367abducible_functor(note) -->
368 "!E".
369abducible_functor(noten) -->
370 "!EN".
371abducible_functor(abd) -->
372 "ABD".
373
374event_functor(hap) -->
375 "hap".
376event_functor(noth) -->
377 "!hap".
378
379
380content(Content) -->
381 term(Content).
382
383
384
385
386
387
388
389
390
391
392
393
394or_symbol -->
395 "\\/".
396and_symbol -->
397 "/\\".
398
399impl_symbol -->
400 "--->".
401
402
403
404
405
406
407write_ics_to_file(FileName,ICList):-
408 open(FileName,write,Stream),
409 write_ics_to_stream(ICList,Stream),
410 close(Stream).
411
412write_ics_to_stream([],_).
413write_ics_to_stream([IC|MoreICs],Stream):-
414 write_ic_to_stream(IC,Stream),
415 write_ics_to_stream(MoreICs,Stream).
416
417write_ic_to_stream(ic(Body,Head),Stream):-
418 write(Stream,'ics('),
419 write(Stream,Body),write(Stream,','),
420 nl(Stream),
421 spaces(Stream),
422 write(Stream,'['),
423 write_head_to_stream(Head,Stream),
424 write(Stream,']).'),
425 nl(Stream),
426 nl(Stream).
427
428write_head_to_stream([Disjunct],Stream):-
429 write(Stream,Disjunct).
430write_head_to_stream([Disjunct1,Disjunct2|MoreDisjuncts],Stream):-
431 write(Stream,Disjunct1),
432 write(Stream,','),
433 nl(Stream),
434 spaces(Stream),
435 write_head_to_stream([Disjunct2|MoreDisjuncts],Stream).
436
437
438spaces(Stream):-
439 write(Stream,' ').
440
441
442
443
444add_var([],[]).
445
446add_var([rule(C,S,P)|T],[rule(CV,S,P)|TV]):-
447 add_var_ic(C,CV),
448 add_var(T,TV).
449
450add_var_ic(((H,HL):-(B,BL)),((HV,HL):-(BV,BL))):-
451 collect_vars([H,B],[],VA),
452 length(VA,N),
453 length(V,N),
454 replace_vars([H,B],[HV,BV],VA,V).
455
456replace_vars([],[],_VA,_V).
457
458replace_vars([A|T],[Var|T1],VA,V):-
459 atomic(A),
460 nth1(N, VA, A),!,
461 nth1(N,V,Var),
462 replace_vars(T,T1,VA,V).
463
464replace_vars([A|T],[A|T1],VA,V):-
465 (atomic(A);var(A)),!,
466 replace_vars(T,T1,VA,V).
467
468replace_vars([A|T],[AV|T1],VA,V):-
469 A=..[F|Args],
470 replace_vars(Args,ArgsV,VA,V),
471 AV=..[F|ArgsV],
472 replace_vars(T,T1,VA,V).
473
474
475
476collect_vars([],V,V).
477
478collect_vars([A|T],VIn,VOut):-
479 atomic(A),
480 \+number(A),
481 A\=[],
482 atom_codes(A,AC),
483 is_var(AC),!,
484 (member(A,VIn)->
485 V1=VIn
486 ;
487 V1=[A|VIn]
488 ),
489 collect_vars(T,V1,VOut).
490
491collect_vars([A|T],VIn,VOut):-
492 (atomic(A);var(A);number(A)),!,
493 collect_vars(T,VIn,VOut).
494
495collect_vars([A|T],VIn,VOut):-
496 A=..[_F|Args],
497 collect_vars(Args,VIn,V1),
498 collect_vars(T,V1,VOut).
499
500is_var([H|_T]):-
501 (H>=65,
502 H=<90);
503 H=95