/*****************************************************************************/ /* */ /* Christophe DELORD */ /* */ /* Stage 1997/98 : ENSEEIHT - Traitement du langage naturel */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* Analyse de phrases : grammaire catégorielle généralisée de Lambek-Gentzen */ /* */ /*****************************************************************************/ :-use_module(log_int). /*****************************************************************************/ /* */ /* Définition des catégories syntagmatiques */ /* */ /*****************************************************************************/ :-op(400,yfx,'/'). :-op(400,yfx,'\'). categorie(jean,sn). categorie(marie,sn). categorie(pierre,sn). categorie(anne,sn). categorie(est,(p\sn)/sa). categorie(apparente,sa/sp). categorie(a,sp/sn). categorie(il,sn). categorie(juge,(((p\sn)/sa)/sn)). categorie(incompetente,sa). /*****************************************************************************/ /* */ /* Construction de la liste de catégories */ /* */ /*****************************************************************************/ liste_categories([],[],[]). liste_categories([M|PH],[CM|CPH],[M|SVS]):- categorie(M,CM), liste_categories(PH,CPH,SVS). /*****************************************************************************/ /* */ /* R1 f: x/y, a: y -> f(a): x applicativité */ /* a: y, f: x\y -> f(a): x */ /* */ /*****************************************************************************/ reduire([F,A|SPH],[(X/Y),Y|ST],[VSF,VSA|SVS],NPH,NT,NVS):- reduire([[F,A]|SPH],[X|ST],[VSF@VSA|SVS],NPH,NT,NVS). reduire([A,F|SPH],[Y,(X\Y)|ST],[VSA,VSF|SVS],NPH,NT,NVS):- reduire([[A,F]|SPH],[X|ST],[VSF@VSA|SVS],NPH,NT,NVS). /*****************************************************************************/ /* */ /* R2 f: x/y, g: y/z -> lv[f(g(v))]: x/z composition */ /* g: y\z, f: x\y -> lv[f(g(v))]: x\z */ /* */ /*****************************************************************************/ reduire([F,G|SPH],[(X/Y),(Y/Z)|ST],[VSF,VSG|SVS],NPH,NT,NVS):- reduire([[F,G]|SPH],[(X/Z)|ST],[V#VSF@(VSG@V)|SVS],NPH,NT,NVS). reduire([G,F|SPH],[(Y\Z),(X\Y)|ST],[VSG,VSF|SVS],NPH,NT,NVS):- reduire([[G,F]|SPH],[(X\Z)|ST],[V#VSF@(VSG@V)|SVS],NPH,NT,NVS). /*****************************************************************************/ /* */ /* R3 f: (x\z)/y -> lv[lw[f(w)(v)]]: (x/y)\z associativité */ /* f: (x/y)\z -> lv[lw[f(w)(v)]]: (x\z)/y */ /* */ /*****************************************************************************/ reduire([F|SPH],[((X\Z)/Y)|ST],[VSF|SVS],NPH,NT,NVS):- reduire([F|SPH],[((X/Y)\Z)|ST],[V#W#VSF@W@V|SVS],NPH,NT,NVS). reduire([F|SPH],[((X/Y)\Z)|ST],[VSF|SVS],NPH,NT,NVS):- reduire([F|SPH],[((X\Z)/Y)|ST],[V#W#VSF@W@V|SVS],NPH,NT,NVS). /*****************************************************************************/ /* */ /* R4 a: x, b: (y\x) -> lv[v(a)]: y/(y\x), b: (y\x) montée */ /* b: (y/x), a: x -> b: (y/x), lv[v(a)]: y\(y/x) */ /* */ /*****************************************************************************/ reduire([A,B|SPH],[X,(Y\X)|ST],[VSA,VSB|SVS],NPH,NT,NVS):- reduire([A,B|SPH],[(Y/(Y\X)),(Y\X)|ST],[V#V@VSA,VSB|SVS],NPH,NT,NVS). reduire([B,A|SPH],[(Y/X),X|ST],[VSB,VSA|SVS],NPH,NT,NVS):- reduire([B,A|SPH],[(Y/X),(Y\(Y/X))|ST],[VSB,V#V@VSA|SVS],NPH,NT,NVS). /*****************************************************************************/ /* */ /* R5 f: x/y, g: y/z -> lv[lw[f(v(w))]]: (x/z)/(y/z), g: y/z division */ /* g: y\z, f: x\y -> g: y\z, lv[lw[f(v(w))]]: (x\z)\(y\z) foncteur */ /* principal */ /*****************************************************************************/ reduire([F,G|SPH],[(X/Y),(Y/Z)|ST],[VSF,VSG|SVS],NPH,NT,NVS):- reduire([F,G|SPH],[((X/Z)/(Y/Z)),(Y/Z)|ST],[V#W#VSF@(V@W),VSG|SVS], NPH,NT,NVS). reduire([G,F|SPH],[(Y\Z),(X\Y)|ST],[VSG,VSF|SVS],NPH,NT,NVS):- reduire([G,F|SPH],[(Y\Z),((X\Z)\(Y\Z))|ST],[VSG,V#W#VSF@(V@W)|SVS], NPH,NT,NVS). /*****************************************************************************/ /* */ /* R6 g: z/x, f: x/y -> g: z/x, lv[lw[v(f(w))]]: (z/y)\(z/x) division */ /* f: x\y, g: z\x -> lv[lw[v(f(w))]]: (z\y)/(z\x), g: z\x foncteur */ /* subordonné */ /*****************************************************************************/ reduire([G,F|SPH],[(Z/X),(X/Y)|ST],[VSG,VSF|SVS],NPH,NT,NVS):- reduire([G,F|SPH],[(Z/X),((Z/Y)\(Z/X))|ST],[VSG,V#W#V@(VSF@W)|SVS], NPH,NT,NVS). reduire([F,G|SPH],[(X\Y),(Z\X)|ST],[VSF,VSG|SVS],NPH,NT,NVS):- reduire([F,G|SPH],[((Z\Y)/(Z\X)),(Z\X)|ST],[V#W#V@(VSF@W),VSG|SVS], NPH,NT,NVS). /*****************************************************************************/ /* */ /* P t: z/y, a: x, b: y -> t: z/y, b: y, a: x permutation */ /* a: x, b: y, t: z\x -> b: y, a: x, t: z\x */ /* */ /*****************************************************************************/ reduire([T,A,B|SPH],[(Z/Y),X,Y|ST],[VST,VSA,VSB|SVS],NPH,NT,NVS):- reduire([T,B,A|SPH],[(Z/Y),Y,X|ST],[VST,VSB,VSA|SVS],NPH,NT,NVS). reduire([A,B,T|SPH],[X,Y,(Z\X)|ST],[VSA,VSB,VST|SVS],NPH,NT,NVS):- reduire([B,A,T|SPH],[Y,X,(Z\X)|ST],[VSB,VSA,VST|SVS],NPH,NT,NVS). /*****************************************************************************/ /* */ /* C a: x, b: x -> (a,b): x contraction */ /* */ /*****************************************************************************/ reduire([A,B|SPH],[X,X|ST],[VSA,VSB|SVS],NPH,NT,NVS):- reduire([[A,B]|SPH],[X|ST],[contraction(VSA,VSB)|SVS],NPH,NT,NVS). /*****************************************************************************/ /* */ /* Cas où l'on ne peut pas simplifier => on avance */ /* */ /*****************************************************************************/ reduire([A|SPH],[X|ST],[VSA|SVS],NPH,NT,NVS):- reduire(SPH,ST,SVS,NPH1,NT1,NVS1), ST\=NT1, % sinon, ça boucle reduire([A|NPH1],[X|NT1],[VSA|NVS1],NPH,NT,NVS). reduire(A,X,V,A,X,V). /*****************************************************************************/ /* */ /* Analyse d'une phrase */ /* */ /*****************************************************************************/ analyser(PH,VS_S):- liste_categories(PH,LC,LVS), reduire(PH,LC,LVS,NPH,[p],[VS]), writef("%t <=> \n\t%t\n",[NPH,VS]), simplifier(VS,VS_S), writef("\t%t\n",[VS_S]). test:- analyser([il,juge,incompetente,marie],_).