Lecture de règles et de requêtes
Lecture de termes
Le terme est le seul type de donnée prolog. Une formule (requête, règle) est donc (au moins syntaxiquement) un terme. Il existe en prolog des primitives de lecture de termes. Pour être lisible par ces primitives, le terme doit être suivi d’une marque de terminaison constituée du caractère point .() suivit d’un blanc (retour-chariot, espace, tabulation, commentaire-ligne 10, . . . )
On appelle littéral tout terme d’une des formes suivantes :
– atome,
– atome(t1; : : : ; tn), les ti étant des termes.
– ! (dit cut) qui est la fameuse coupure des points de choix.
Requêtes
Une requête est une formule, c.à.d. une combinaison de littéraux agencés par des conjonctions, disjonctions, et quantifications existentielles, tout ceci éventuellement imbriqué sur plusieurs niveaux ; on peut être amené à utiliser des parenthèses pour exprimer la formule voulue. Toute formule doit se terminer par la marque de terminaison (point suivi d’espace.) Voici quelques exemples de requêtes :
write(‘Bonjour a tous’), nl.
X ex Y = cos(X), int(Y).
Y ex Ville ex habite(jean,Ville), habite(Y, Ville), dif(Y, jean).
X=1;X=2.
Règles
Il existe deux formes de règle11 (du point de vue syntaxique) :
– Celle qu’on appelle fait, c.à.d. juste un littéral qui est la tête de la règle (et qui peut contenir des pseudo-termes). Le fait est terminé par la marque de terminaison.
– Celle qu’on appelle règle proprement dit, qui est une construction de la forme :
tête-de-règle :- queue-de-règle .
où tête-de-règleest un littéral, et où queue-de-règle a exactement la syntaxe d’une formule représentant une requête possible.
Un fait peut être vu comme une règle dont la queue ne contient que le littéral true.
Quelques exemples de règles :
fait(noir(nuit)).
10. un commentaire bloc ne peut convenir pour la bonne raison qu’il ne peut être reconnu comme tel. En effet, les caractères./* s’agglutinent pour former un atome.
11. essentiellement pour des raisons historiques.
element_de(X, [Y|L]) :- element_de(X, L).
distance(X1,Y1, X2,Y2, D) :-
D ~ sqrt(square(X2.-.X1).+.square(Y2.-.Y1)). somme([X | L], X.+.Y) :- somme(L, Y).
Transformation des règles (et requêtes) en codage interne
Tout terme lu sensé repésenter une règle destinée à augmenter la base de règles est codé. Il n’est bien entendu pas question de détailler ce codage, mais il est nécessaire de connaître certains points de cette transformation, dépendante du mode syntaxique, et décrite pour chacun d’entre eux.
Mode prolog4
– Les entités numériques entrées avec la notation flottante sont codés par des nombres précis (rationnel).
– Tout littéral où figure la quantification existentielle ( X ex p) est trans-formé enp0, tiré du littéralp en remplaçant dans celui-ci toute occurence de la variable X par une variable neuve ne figurant pas déjà dans la règle. Ce processus est effectué en postordre dans la formule (du plus profond vers la surface).
– Tout terme fonctionnel figurant dans un littéral est traduit en un nœud de terme logique, si le nom et l’arité du nœud n’est pas celui d’une relation prédéfinie. Sinon, le terme en question est un pseudo-terme, et la transformation suivante est appliquée sur le littéral :
Le pseudo-terme est remplacé dans le littéral par une variable neuve.
Un littéral construit à l’aide du pseudo-terme est inséréavant celui qu’on est en train de traiter.
La variable neuve est inséréeavant les autres arguments du nou-veau littéral.
Le littéral
p(a1; : : : ; rel(b1; : : : ; bn); : : : ; am)
est donc remplacé par :
rel(X; b1; : : : ; bn); p(a1; : : : ; X; : : :; am)
la variable X ne figurant pas déjà dans la règle.
Les littéraux insérés sont également traités de cette façon. L’ordre d’ex-pansion des pseudo-termes entre eux est indéfini.
– Si le premier caractère d’un identificateur est un « ^ », alors ce qui est codé est l’identificateur privé de ce caractère, sauf dans le seul cas de l’identificateur « ^ », qui reste inchangé. Cette règle de transformation est appliquée après toutes les autres.
Mode iso
– Les entités numériques entrées avec la notation flottante sont codées par un nombre flottant IEEE double précision.
– Tout terme fonctionnel figurant dans un littéral est traduit en un nœud de terme logique.
Différence entre le modeprolog4 et le mode iso
Voici essentiellement ce qu’on perd quand on est en mode iso :
– Pas de pseudo-termes dans l’interprétation des requêtes et des règles lues (toute structure est un constructeur). Il faut donc utiliser la nota-tion relationnelle pour écrire des contraintes, il n’est pas possible d’en imbriquer.
– Pas de quantification existentielle.
– Une entité ayant la notation flottante est traduite en nombre flottant IEEE double précision, et non pas en nombre rationnel de précision parfaite ; il faut donc utiliser les entités étendues pour pouvoir utiliser des nom-bres rationnels dans ce mode.
– Des opérateurs en moins (ceux qui sont des raccourcis de relations).
ANNEXE A : Questions et Réponses
Attention : le caractère « » est un guillemet inversé, comme l’accent grave.
Q: Peut-on entrer un nombre flottant binaire (de valeur 1:2 par exemple) en étant dans le modeprolog4?
R: Il faut le rentrer sous la forme f1.2 (- f1.2 si on voulait entrer
,1:2).
Q: Comment peut-on en mode iso entrer un nombre fractionnaire ( je sais qu’on fait 1/10 en mode prolog4) ?
R: Il faut le rentrer sous la forme r1/10 (- r1/10 si on voulait entrer la fraction négative, 1 ).
10
Q: Quelles différences il y a t-il entre les primitiveswrite et writeq?
R: Ce qu’affiche write est destiné à la lecture par des humains, writeq est destiné à la lecture par un programme (par read par exemple.) write n’affiche aucune apostrophe autour des entités écrites. writeq en mettra partout où c’est nécessaire, ainsi que des espaces, afin de lever toute ambiguïté à la relecture.
Q: Les nombres flottants n’ont pas l’air d’être pris en compte dans mes con-traintes ?
R: En effet, seuls les nombres précis (quelle que soit la notation em-ployée) sont utilisés dans dans les solveurs numériques.
Q: Alors à quoi peuvent bien servir ces nombres flottants ?
R: Ils font partie de la norme prolog, et peuvent servir dans des calculs par le biais des primitives is/2 et assimilées, ainsi que dans des appels de fonctions écrites dans un autre langage de programmation (comme C).