/****************************************************************************/
/******************************* 02/08/92 ***********************************/
/****************************************************************************/
/********** **********/
/********** **********/
/********** TP NUMERO 5 **********/
/********** **********/
/********** **********/
/********** CONSTRUCTION D'UN ANALYSEUR INTERACTIF **********/
/********** **********/
/********** **********/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* BASE DE FAITS INITIALE */
/****************************************************************************/
det(le,masculin).
det(la,feminin).
adj(petit,masculin,avant).
adj(verte,feminin,apres).
verbe(trottine,intransitif).
verbe(rampe,intransitif).
verbe(croque,transitif).
verbe(est,etat).
nom(herisson,masculin).
nom(chenille,feminin).
adv(tres).
adv(rapidement).
/****************************************************************************/
e:-emacs('ph5.pro').
/****************************************************************************/
/* Affichage d'une phrase */
/****************************************************************************/
putphrase([],_):-
write(' ').
putphrase([T|Q],o):- /* Phrase affirmative. */
write(' '),write(T),putphrase(Q,o).
putphrase([T|Q],n):- /* Phrase negative. */
write(' '),
(verbe(T,_),write('ne '),write(T),write(' pas');write(T))
,putphrase(Q,n).
/****************************************************************************/
/* Lecture d'une phrase */
/* Type indique si la phrase lue est une question ou une affirmation. */
/****************************************************************************/
getphrase(L,Type):-
get0(Car),
getreste(Car,L1),
(L1=[est,ce,que|L],
Type=question;
Type=affirm,
L=L1).
/****************************************************************************/
/* Decomposition de la lecture d'une phrase et transformation de la phrase */
/* en une liste de mots. */
/****************************************************************************/
getreste(46,[]):-!.
getreste(32,L):-!,getphrase(L,_).
getreste(Lettre,[Mot|Mliste]):-
getmot(Lettre,Lliste,Suivant),
name(Mot,Lliste),!,
getreste(Suivant,Mliste).
/****************************************************************************/
/* Lecture d'un mot. Les majuscules sont transformees en minuscules. */
/****************************************************************************/
getmot(46,[],46):-!.
getmot(32,[],32):-!.
getmot(Lettre,Liste,Suiv):-
Lettre=<90,
Lettre>=64,!,
Lettre1 is Lettre+32,
getmot(Lettre1,Liste,Suiv).
getmot(Lettre,[Lettre|Lliste],Suiv):-
get0(C),
getmot(C,Lliste,Suiv).
/****************************************************************************/
/* Analyse syntaxique et grammaticale d'une phrase. */
/****************************************************************************/
phrase(L,ph(SN,SV),Type):-trace,
sn(L,RL,Nom,SN,Type),
abolish(gramcorrect,0),
sv(RL,[],Nom,SV,Type).
/****************************************************************************/
/* Verification de l'appartenance du determinant T a la base de faits et en */
/* cas d'echec, on interroge l'utilisateur puis on verifie si les */
/* renseignements qu'il a fourni correspondent au fait recherche. */
/****************************************************************************/
deter([T|Q],Q,Genre,det(T)):-
det(T,Genre),!;
question(det,T),!,
det(T,Genre).
/***************************************************************************/
/* On refait la meme chose que pour le determinant. Cependant, du fait */
/* qu'une phrase ne comporte pas forcement d'adjectif, on ajoute une */
/* clause qui traite ce cas particulier. */
/***************************************************************************/
adject([],[],_,_,'').
adject([T|Q],[T|Q],Genre,Place,''):- /* phrase sans adjectif. */
not(adj(T,Genre,Place)),
(Place=avant,
sujet([T],_,Genre,_);
Place=apres,
gverbal([T|Q],_,_,_)).
adject([T|Q],Q1,Genre,Place,(adjectif(T),A)):-
(adj(T,Genre,Place),!;
question(adj,T),!,
adj(T,Genre,Place)),
adject(Q,Q1,Genre,Place,A).
/****************************************************************************/
/* Pour le nom, on refait comme pour le determinant, mais connaissant deja */
/* le genre du determinant, on provoque l'echec si le genre du nom n'est */
/* pas identique. */
/****************************************************************************/
sujet([T|Q],Q,Genre,nom(T)):-
nom(T,Genre1),!,
Genre1==Genre;
question(nom,T),!,
nom(T,Genre).
/***************************************************************************/
/* Analyse syntaxique puis semantique du syntagme nominal. */
/***************************************************************************/
sn([],[],_,'',_).
sn(L,RL,T3,sn(D,Av,N,Ap),Type):-
deter(L,[T2|Q],Genre,D),
adject([T2|Q],[T3|Q3],Genre,avant,Av),
sujet([T3|Q3],RL3,Genre,N),
adject(RL3,RL,Genre,apres,Ap),
assertz(gramcorrect),!,
([T2|Q]\==[T3|Q3],
sens([T2,T3],Type);
true),!,
(RL3\==RL,
RL3=[T4|_],
sens([T4,T3],Type);
true).
/***************************************************************************/
/* Recherche d'un verbe dans la base de faits, et en cas d'echec, on */
/* interroge l'utilisateur. On verifie ensuite les renseignements qu'il a */
/* fourni. */
/***************************************************************************/
gverbal([T|Q],Q,verbe(T),Mode):-
verbe(T,Mode),!;
question(verbe,T),!,
verbe(T,Mode).
/***************************************************************************/
/* On procede pour l'adverbe de la meme maniere que pour l'adjectif. */
/***************************************************************************/
adverbe([],[],'').
adverbe([T|Q],[T|Q],''):-
not(adv(T)),
(det(T,_),!;
adject([T],[],_,_,_),!).
adverbe([T|Q],Q,adverbe(T)):-
adv(T),!;
question(adverbe,T).
/***************************************************************************/
/* Analyse syntaxique puis semantique du syntagme verbal. */
/***************************************************************************/
sv([T|Q],RL,Nom,sv(V,Adv,SN),Type):- /* Verbe transitif */
gverbal([T|Q],RL1,V,Mode), /* ou */
adverbe(RL1,RL2,Adv), /* intransitif. */
(Mode==transitif,
sn(RL2,RL,Complement,SN,Type);
RL=RL2,
SN=''),
assertz(gramcorrect),!,
(RL1\==RL2,RL1=[T1|_],
sens([T1,T],Type);
true),!,
sens([T,Nom,Complement],Type).
sv([T|Q],RL,Nom,sv(V,Adv,Adj),Type):- /* Verbe d'etat. */
gverbal([T|Q],[T1|Q1],V,etat),
adverbe([T1|Q1],[T2],Adv),
nom(Nom,Genre),
adject([T2],RL,Genre,_,Adj),
assertz(gramcorrect),!,
([T1|Q1]\==[T2],
sens([T1,T],Type);
true),!,
sens([T2,Nom],Type).
/****************************************************************************/
/* Questionnaire syntaxique permettant de definir les nouveaux mots */
/* entres par l'utilisateur. */
/****************************************************************************/
question(det,Mot):-
write('Le mot "'),write(Mot),write('" est-il un determinant ? '),nl,
read(R),!,
R==oui,!,
write('Ce determinant est-il masculin ? '),nl,
read(G),
(G==oui,
Genre=masculin;
G==non,
Genre=feminin),
assertz(det(Mot,Genre)).
question(nom,Mot):-
write('Le mot "'),write(Mot),write('" est-il un nom ? '),nl,
read(R),!,
R==oui,!,
write('Ce nom est-il masculin ? '),nl,
read(G),
(G==oui,
Genre=masculin;
G==non,
Genre=feminin),
assertz(nom(Mot,Genre)).
question(adj,Mot):-
write('Le mot "'),write(Mot),write('" est-il un adjectif ? '),nl,
read(R),!,
R==oui,!,
write('Cet adjectif est-il masculin ? '),nl,
read(G),
(G==oui,
Genre=masculin;
G==non,
Genre=feminin),!,
write('Cet adjectif se place devant le nom ?'),nl,
read(P),
(P==oui,
Place=avant;
P==non,
Place=apres),
assertz(adj(Mot,Genre,Place)).
question(verbe,Mot):-
write('Le mot "'),write(Mot),write('" est-il un verbe ? '),nl,
read(R),!,
R==oui,!,
write('Ce verbe est-il transitif ? '),nl,
read(G),
(G==oui,
Genre=transitif;
G==non,
write('Ce verbe est-il intransitif ? '),nl,
read(G2),!,
(G2==oui,
Genre=intransitif;
G2==non,
Genre=etat)),
assertz(verbe(Mot,Genre)).
question(adverbe,Mot):-
write('Le mot "'),write(Mot),write('" est-il un adverbe ? '),nl,
read(R),!,
R==oui,
assertz(adv(Mot)).
/****************************************************************************/
/* Verification semantique. Si la base de faits ne contient pas la clause */
/* semantique recherchee, alors si la phrase etudiee est une affirmation, */
/* on demande a l'utilisateur de confirmer la semantique de sa phrase. */
/****************************************************************************/
sens([X|Q],Type):-
Y=..[X|Q],!,
(Y,!;
Type==affirm,
quest_sens(X,Q),
assertz(Y)).
/****************************************************************************/
/* Questionnaire semantique obligeant l'utilisateur a confirmer la */
/* semantique de la phrase dont il vient de demander l'analyse. */
/****************************************************************************/
quest_sens(F,[Mot]):- /* Confirmation de la semantique */
nom(Mot,Genre), /* entre un adjectif et le nom */
det(D,Genre), /* auquel il se rapporte. */
write('Est ce que '),
write(D),write(' '),write(Mot),write(' peut etre '),write(F),
write(' ?'),nl,
read(R),!,
R==oui.
quest_sens(F,[Mot]):- /* Idem entre adverbe et verbe. */
write('est ce que l''adverbe "'),write(F),
write('" peut suivre le verbe "'),write(Mot),
write('" du point de vue semantique ? '),nl,
read(R),!,
R==oui.
quest_sens(F,[Nom,Complement]):- /* Idem entre sujet, verbe, compl. */
write('Est ce que la phrase "'),
nom(Nom,Genre),det(D,Genre),
write(D),write(' '),write(Nom),write(' '),write(F),write(' '),
(var(Complement);
nom(Complement,Genre1),
det(D1,Genre1),
write(D1),write(' '),write(Complement)),
write('" a un sens ?'),nl,
read(R),!,
R==oui.
/****************************************************************************/
/* La clause essai permet de lancer l'analyse syntaxique et semantique */
/* d'une phrase. Si la phrase est une question, alors la clause essai */
/* repond oui ou non en fonction de la reussite ou de l'echec de la clause */
/* d'analyse. Si la phrase est une affirmation, alors la clause renvoie */
/* l'analyse syntaxique de la phrase a condition bien sur que l'analyse ait */
/* reussie. Si l'analyse a echoue, alors grace au fait gramcorrect, on */
/* indique la cause de l'echec : raison grammaticale ou semantique. */
/****************************************************************************/
essai:-write('Tapez une phrase'),nl,
getphrase(L,Type),get0(C),nl,
(phrase(L,Phrase_Analysee,Type),nl,
(Type==affirm,
write('La phrase "'),
putphrase(L,o),
write('" est correcte ! '),nl,
write('Analyse syntaxique de la phrase :'),nl,
write(Phrase_Analysee);
write('Oui,'),
putphrase(L,o),
write('.')),
nl;
(gramcorrect,
(Type==affirm,
write('La phrase "'),
putphrase(L,o),
write('" est semantiquement incorrecte !');
write('Non,'),
putphrase(L,n),
write('.')),
nl;
write('La phrase "'),
putphrase(L,o),
write('" est grammaticalement incorrecte'),nl)),
nl,nl,
essai.