/* Copyright (C) Wolfgang Menzel, Universität Hamburg, 2003-06-27 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ % a diagnostic engine based on constraint satisfaction % for utterances with a fixed structure % no insertion/omission errors during variable assignment :- [engl1]. % consults a knowledge base :- nl. :- write_ln('a simple constraint checker for fixed phrases'). :- write_ln('call: ?- diagnose([these,man,are,happy],D)'). :- nl. %%% structure identification %%%%%%%%%%% % assign(+Words,+Variables,-Errors). % call: assign([the,man,is,cool],[det,noun,verb,adv],Errors). % tries to assign each word to a variable assign([ ],[ ],[ ]). % all word in the input processed assign([Word|Words],[Var|Vars],Err) :- category(Word,Cat), % get the category of the next word true ==> cat(Var,Cat), % check the category constraint features(Word,Feats), % get the features of the next word clean_var(Var), % housekeeping in the database assert(vword(Var,Word)), % assert(vcat(Var,Cat)), % initializing the variable assert(vfeat(Var,Feats)), % assign(Words,Vars,Err). % recursive descent assign([Word|Words],[Var|Vars],[cat(Word,Cat,Cats)|Err]) :- category(Word,Cat), % get the category of the next word \+ true ==> cat(Var,Cat), % check the category constraint findall(C,true ==> cat(Var,C),Cats), % collect possible categories assign(Words,Vars,Err). % recursive descent % clean_var(Variable) % resets a variable (to be used for housekeeping) clean_var(Var) :- retractall(vword(Var,_)), retractall(vcat(Var,_)), retractall(vpos(Var,_)), retractall(vfeat(Var,_)). %%% the diagnosis proper %%%%%%%%%%%%%%%%%%%%%% % diagnose(+Input,-Diagnoses) % takes a List of input word forms and returns several lists % with diagnostic results diagnose(WordList,Errors) :- vars(Vars), forall(member(Var,Vars),clean_var(Var)), % reset all variables assign(WordList,Vars,AErrors), % call the variable assignment check_constraints(CErrors), % call the constraint checker append(AErrors,CErrors,Errors). % check_constraints(-ErrorDescription) % applies all but cat-constraints % returns a list of error descriptions check_constraints(Err) :- findall(Conclusio, (Premise ==> Conclusio, \+ check_constraint(Premise,Conclusio)), Err). % check_constraint(Premise,Conclusio) % applies a single constraint as long as it is not % a cat-constraint check_constraint(_,cat(_,_)) :- !, true. check_constraint(Prem,Concl) :- Prem -> Concl. %%% the semantics of constraints %%%%%%%%%%%%%% % lp(Variable1,Variable2) % checks the linear precedence between two variables lp(Var1,Var2) :- ((vpos(Var1,Pos1), vpos(Var2,Pos2)) -> Pos1 < Pos2 ; true). % agreement(Variable1,Variable2,Feature) % checks the agreement between two Variables with respect to % a particular feature agree(Var1,Var2,Feature) :- featurepos(Feature,Pos), ((vfeat(Var1,Feats1), vfeat(Var2,Feats2) -> nth1(Pos,Feats1,Feat), nth1(Pos,Feats2,Feat)) ; true ).