14
15
16:- module(prologfeatures, [
17 resolve_features/1 18 ]).
47:- op(700, xfx, :=). 48:- op(695, xfx, intro). 49:- op(580, xfy, &). 50:- op(570, xfy, !). 51:- op(550, fx, @). 52:- op(550, fx, <). 53:- op(590, xfy, or).
60resolve_features(Sourcefiles) :-
61 cleanup,
62 read_sourcefiles(Sourcefiles),
63 write_targetfiles.
71:- dynamic(sort_feature/2).
79:- dynamic(feature/3).
86:- dynamic(subsort/2).
93:- dynamic(template/2).
100:- dynamic(term/1).
107:- dynamic(error_occurred/0).
114cleanup :-
115 retractall(sort_features(_,_)),
116 retractall(feature(_,_,_)),
117 retractall(subsort(_,_)),
118 retractall(term(_)),
119 retractall(template(_,_)),
120 retractall(error_occurred).
127read_sourcefiles([]).
128
129read_sourcefiles([File|Rest]) :-
130 read_sourcefiles(File),
131 read_sourcefiles(Rest).
132
133read_sourcefiles(File) :-
134 \+ is_list(File),
135 atom_concat(File, '.fit', FileC),
136 open(FileC, read, In),
137 write(user_error, 'Reading "'),
138 write(user_error, FileC),
139 write(user_error, '"\n'),
140 assert(term('*** file ***'(File))),
141 repeat,
142 read_term(In, Term, [module(prologfeatures)]),
143 store_term(Term),
144 Term = end_of_file,
145 close(In).
152store_term(end_of_file) :-
153 !.
154
155store_term(Sort > Subsorts intro Features) :-
156 atom(Sort),
157 \+ sort_features(Sort, _),
158 \+ subsort(_, Sort),
159 ground(Features),
160 Features = [_|_],
161 prune_features(Features, FeaturesT),
162 ground(Subsorts),
163 Subsorts = [_|_],
164 store_subsorts(Subsorts, Sort),
165 !,
166 assert(sort_features(Sort, FeaturesT)),
167 store_features(Features, Sort).
168
169store_term(Sort > Subsorts intro Features) :-
170 !,
171 write_error_message('Invalid command', Sort > Subsorts intro Features).
172
173store_term(Sort intro Features) :-
174 atom(Sort),
175 \+ sort_features(Sort, _),
176 ground(Features),
177 Features = [_|_],
178 prune_features(Features, FeaturesT),
179 !,
180 assert(sort_features(Sort,FeaturesT)),
181 store_features(Features, Sort).
182
183store_term(Sort intro Features) :-
184 !,
185 write_error_message('Invalid command', Sort intro Features).
186
187store_term(Sort > Subsorts) :-
188 atom(Sort),
189 \+ subsort(_, Sort),
190 ground(Subsorts),
191 Subsorts = [_|_],
192 store_subsorts(Subsorts, Sort),
193 !.
194
195store_term(Sort > Subsorts) :-
196 !,
197 write_error_message('Invalid command', Sort > Subsorts).
198
199store_term(TemplateName := Template) :-
200 atom(TemplateName),
201 !,
202 assert(template(TemplateName, Template)).
203
204store_term(TemplateName := Template) :-
205 !,
206 write_error_message('Invalid command', TemplateName := Template).
207
208store_term(Term) :-
209 assert(term(Term)).
217prune_features([], []).
218
219prune_features([Feature|FeaturesRestIn], [Feature|FeaturesRestOut]) :-
220 atom(Feature),
221 \+ member(Feature, FeaturesRestIn),
222 \+ member(Feature:_, FeaturesRestIn),
223 !,
224 prune_features(FeaturesRestIn, FeaturesRestOut).
225
226prune_features([Feature:FeatureRestr|FeaturesRestIn], [Feature|FeaturesRestOut]) :-
227 atom(Feature),
228 atom(FeatureRestr),
229 \+ member(Feature, FeaturesRestIn),
230 \+ member(Feature:_, FeaturesRestIn),
231 !,
232 prune_features(FeaturesRestIn, FeaturesRestOut).
233
234prune_features([Feature|_], _) :-
235 write_error_message('Invalid or duplicated feature', Feature),
236 fail.
243store_features([], _).
244
245store_features([Feature:FeatureRestr|FeaturesRest], Sort) :-
246 !,
247 assert(feature(Feature, Sort, FeatureRestr)),
248 store_features(FeaturesRest, Sort).
249
250store_features([Feature|FeaturesRest], Sort) :-
251 assert(feature(Feature, Sort, '')),
252 store_features(FeaturesRest, Sort).
259store_subsorts([], _).
260
261store_subsorts([Subsort|_], Sort) :-
262 is_subsort_of(Sort, Subsort),
263 !,
264 write_error_message('Cycle introduced in sort hierarchy', Sort > Subsort),
265 fail.
266
267store_subsorts([Subsort|SubsortsRest], Sort) :-
268 assert(subsort(Subsort, Sort)),
269 store_subsorts(SubsortsRest, Sort).
277write_targetfiles :-
278 error_occurred,
279 !,
280 write(user_error, 'EXECUTION ABORTED.\n').
281
282write_targetfiles :-
283 term(Term),
284 process_term(Term),
285 fail.
286
287write_targetfiles :-
288 told.
295process_term('*** file ***'(FileName)) :-
296 !,
297 told,
298 atom_concat(FileName, '.plp', OutFile),
299 write(user_error, 'Writing "'),
300 write(user_error, OutFile),
301 write(user_error, '"\n'),
302 tell(OutFile).
303
304process_term(Term) :-
305 findall(TermT, transform(Term, TermT, []), TermsT),
306 TermsT = [_|_], 307 !,
308 write_terms(TermsT).
309
310process_term(Term) :-
311 write_error_message('Invalid term', Term).
318write_terms([]).
319
320write_terms([Term|TermsRest]) :-
321 numbervars(Term, 0, _),
322 write_term(Term, [character_escapes(true), quoted(true), numbervars(true), module(prologfeatures)]),
323 write('.\n'),
324 write_terms(TermsRest).
333transform(Var, Var, _) :-
334 var(Var),
335 !.
336
337transform([], [], _) :-
338 !.
339
340transform([H1|T1], [H2|T2], Templates) :-
341 !,
342 transform(H1, H2, Templates),
343 transform(T1, T2, Templates).
344
345transform(Term, Term, _) :-
346 Term =.. [Term],
347 !.
348
349transform(Feature ! Value, Term, Templates) :-
350 !,
351 atom(Feature),
352 build_feature(Feature, Value, Term, Templates).
353
354transform(< Sort, Term, _) :-
355 !,
356 build_sort(Sort, _, Term, _, _).
357
358transform(@ TemplateName, Term, Templates) :-
359 \+ member(TemplateName, Templates),
360 !,
361 template(TemplateName, Template),
362 transform(Template, Term, [TemplateName|Templates]).
363
364transform(@ TemplateName, _, Templates) :-
365 !,
366 write_error_message('Cyclic template definition', [TemplateName|Templates]),
367 fail.
368
369transform(T1 & T2, Term, Templates) :-
370 !,
371 transform(T1, Term, Templates),
372 transform(T2, Term, Templates).
373
374transform(T1 or T2, Term, Templates) :-
375 !,
376 (
377 transform(T1, Term, Templates)
378 ;
379 transform(T2, Term, Templates)
380 ).
381
382transform(Term1, Term2, Templates) :-
383 !,
384 Term1 =.. List1,
385 transform(List1, List2, Templates),
386 Term2 =.. List2.
394build_feature(Feature, Value, Term, Templates) :-
395 feature(Feature, Sort, FeatureRestr),
396 build_sort(Sort, _, Term, Feature, FeatureVar),
397 transform(Value, ValueTerm, Templates),
398 build_sort(FeatureRestr, _, ValueTerm, _, _),
399 FeatureVar = ValueTerm.
406build_sort(Sort, _, _, _, _) :-
407 Sort == '',
408 !.
409
410build_sort(Sort, Content, Term, Feature, FeatureVar) :-
411 subsort(Sort, top),
412 build_sort_args(1, Sort, Content, Args, Feature, FeatureVar),
413 atom_concat('$', Sort, SortT),
414 Term =.. [SortT,_|Args].
415
416build_sort(Sort, Content, Term, Feature, FeatureVar) :-
417 subsort(Sort, SuperSort),
418 SuperSort \= top,
419 build_sort_args(1, Sort, Content, Args, Feature, FeatureVar),
420 atom_concat('$', Sort, SortT),
421 TempTerm =.. [SortT|Args],
422 build_sort(SuperSort, TempTerm, Term, _, _).
429build_sort_args(1, Sort, Content, [Content|Args], Feature, FeatureVar) :-
430 subsort(_, Sort),
431 !,
432 build_sort_args(2, Sort, Content, Args, Feature, FeatureVar).
433
434build_sort_args(1, Sort, Content, Args, Feature, FeatureVar) :-
435 build_sort_args(2, Sort, Content, Args, Feature, FeatureVar).
436
437build_sort_args(2, Sort, _, FeatureVarList, Feature, FeatureVar) :-
438 sort_features(Sort, Features),
439 !,
440 create_featurevarlist(Features, FeatureVarList, Feature, FeatureVar).
441
442build_sort_args(2, _, _, [], _, _).
450create_featurevarlist([], [], _, _).
451
452create_featurevarlist([Feature|FeaturesRest], [FeatureVar|FeatureVarListRest], Feature, FeatureVar) :-
453 !,
454 create_featurevarlist(FeaturesRest, FeatureVarListRest, Feature, FeatureVar).
455
456create_featurevarlist([_|FeaturesRest], [_|FeatureVarListRest], Feature, FeatureVar) :-
457 !,
458 create_featurevarlist(FeaturesRest, FeatureVarListRest, Feature, FeatureVar).
465is_subsort_of(Sort, Sort).
466
467is_subsort_of(Subsort, Sort) :-
468 subsort(Subsort, T),
469 is_subsort_of(T, Sort).
476write_error_message(Message, Term) :-
477 assert(error_occurred),
478 write(user_error, 'ERROR: '),
479 write(user_error, Message),
480 write(user_error, ': '),
481 write_term(user_error, Term, [module(prologfeatures), quoted(true)]),
482 write(user_error, '\n')
Prolog-Features
This module reimplements a part of the ProFIT transformation that is introduced in [1]. It transforms Prolog programms that contain feature structures into plain Prolog programs. The following constructs are supported (the numbers refer to the paper):
[1] Gregor Erbach. ProFIT: Prolog with Features, Inheritance and Templates. In Proceedings of the seventh conference on European chapter of the Association for Computational Linguistics. Morgan Kaufmann Publishers Inc., 1995.