EXERCICE 1 :
DATALOG,
sémantiques
Soit le programme DATALOG :
progr1
f(a).
h(a,b).
h(a,c).
h(b,a).
h(X , Y) :- h(Z , X) , h(Z , Y).
g(Z) :- f(Y). |
QUESTION 1 : quel est l'univers de
Herbrand de progr1 ?
QUESTION 2 : Calculer la
sémantique de point fixe de progr1 (fonction Tp)
QUESTION 3 : Calculer la
sémantique en chaînage arrière de ce prog1 en utilisant Prolog.
EXERCICE 2 : DATALOG,
Programmation
énoncé Alice
Alice est dans la forêt de l'oubli, elle
n'oublie pas tout mais certaines choses l'ennuient beaucoup comme
oublier le jour de la semaine.Dans cette forêt il y a un lion et une
licorne "binaires" i.e. le lion ment les lundis, les mardis et les
mercredis et dit la vérité les autres jours de la semaine et la
licorne ment les jeudis, les vendredis et les samedi et dit la
vérité les autres jours de la semaine. Un jour alice les rencontre
allongés sous un arbre. Elle est très ennuyée, elle a à nouveau
oublié le jour de la semaine, alors elle demande au lion et à la
licorne :
quel jour sommes nous ?
Le Lion et la licorne répondent ensemble:
Hier je mentais !!!
Alice réfléchit un peu et s'en va
satisfaite... |
En ED nous avons résolu cette
enigme par le programme DATALOG :
Alice1
%Hier d'aujourd'hui..
hier(mercredi, mardi).
hier(mardi, lundi).
hier(lundi, dimanche).
hier(dimanche, samedi).
hier(samedi, vendredi).
hier(vendredi, jeudi).
hier(jeudi, mercredi).
%quand ils mentent...
mensonge(licorne, vendredi ).
mensonge(licorne, samedi ).
mensonge(lion, lundi).
mensonge(lion, mardi ).
mensonge(lion, mercredi ).
mensonge(licorne, jeudi ).
%quand ils disent la vérité...
vérité(lion, vendredi ).
vérité(lion, samedi ).
vérité(lion, dimanche ).
vérité(licorne, dimanche ).
vérité(licorne, lundi).
vérité(licorne, mardi ).
vérité(licorne, mercredi ).
vérité(lion, jeudi ).
%quand le lion (ou la licorne) parle d'un jour
et dit qu'il mentait ce Jour
quandJeDisQueJeMens(L, Quand, Jour) :-
vérité(L, Quand), mensonge(L,Jour).
quandJeDisQueJeMens(L, Quand, Jour) :-
mensonge(L, Quand ) , vérité(L, Jour ).
|
% la question d'alice sous trois formes : |
%Questions :
question_1_Alice(AUJOURDHUI) :-
hier( AUJOURDHUI, HIER),
quandJeDisQueJeMens(lion, AUJOURDHUI, HIER),
quandJeDisQueJeMens(licorne, AUJOURDHUI, HIER).
question_2_Alice(AUJOURDHUI) :-
quandJeDisQueJeMens(lion, AUJOURDHUI, HIER),
hier( AUJOURDHUI, HIER),
quandJeDisQueJeMens(licorne, AUJOURDHUI, HIER).
question_3_Alice(AUJOURDHUI) :-
quandJeDisQueJeMens(lion, AUJOURDHUI, HIER),
quandJeDisQueJeMens(licorne, AUJOURDHUI, HIER) ,
hier( AUJOURDHUI, HIER).
|
QUESTION 1 : Constater que
les 3 questions d'Alice donnent le même résultat unique : "jeudi"
(répondre par une copie de la session Prolog.)
Donc la place de "hier( AUJOURDHUI,
HIER)" dans la queue de règle n'a pas d'importance.
On "améliore" le programme en se
débarrassant du prédicat vérité/2 et en utilisant le 'not' Prolog ce qui
correspond mieux à l'énoncé ( .... et dit la vérité les autres jours
... )
Alice2
%Hier d'aujourd'hui..
hier(mercredi, mardi).
hier(mardi, lundi).
hier(lundi, dimanche).
hier(dimanche, samedi).
hier(samedi, vendredi).
hier(vendredi, jeudi).
hier(jeudi, mercredi).
%quand ils mentent...
mensonge(licorne, vendredi ).
mensonge(licorne, samedi ).
mensonge(lion, lundi).
mensonge(lion, mardi ).
mensonge(lion, mercredi ).
mensonge(licorne, jeudi ).
%quand le lion (ou la licorne) parle d'un jour et
dit qu'il mentait ce Jour
quandJeDisQueJeMensNeg(L, Quand, Jour) :-
not mensonge(L, Quand), mensonge(L,Jour).
quandJeDisQueJeMensNeg(L, Quand, Jour) :-
mensonge(L, Quand ) , not mensonge(L, Jour ).
|
% la question d'alice sous trois formes : |
%Questions :
question_neg1_Alice(AUJOURDHUI) :-
hier( AUJOURDHUI, HIER),
quandJeDisQueJeMensNeg(lion, AUJOURDHUI, HIER),
quandJeDisQueJeMensNeg(licorne, AUJOURDHUI, HIER).
question_neg2_Alice(AUJOURDHUI) :-
quandJeDisQueJeMensNeg(lion, AUJOURDHUI, HIER),
hier( AUJOURDHUI, HIER),
quandJeDisQueJeMensNeg(licorne, AUJOURDHUI, HIER).
question_neg3_Alice(AUJOURDHUI) :-
quandJeDisQueJeMensNeg(lion, AUJOURDHUI, HIER),
quandJeDisQueJeMensNeg(licorne, AUJOURDHUI, HIER) ,
hier( AUJOURDHUI, HIER).
|
QUESTION 2 : Constater que les 3
questions d'Alice ne donnent pas le même résultat unique : "jeudi"
(répondre par une copie de la session Prolog.). Pour quelle raison ?
Quelle question est la bonne ?
pincemi et pincemoi
Le lion et la licorne s'absentent pendant
un mois pour aller combattre les derniers dinosaures. Mais à cette
époque pincemi et pincemoi sont dans la forêt. Pincemi est comme le
lion et pincemoi comme la licorne, mais Alice ne sait pas qui est
comme qui ni qui est qui car ils sont jumeaux et se ressemblent
complètement. Un jour Alice les rencontre alors qu'elle a à nouveau
oublié le jour de la semaine. A sa question quel jour sommes nous ?
le premier affirme "je suis pincemi" et le
second affirme naturellement "je suis pincemoi".
Alice réfléchit un peu et s'en va
satisfaite... |
QUESTION 3 :
Répondre en Prolog à la question d'Alice en
apprenant par la même occasion "Qui est qui ?"
Remarques : On dispose toujours des
programmes précédents, mais maintenant on sait :
mensonge(pincemi, J):- mensonge(lion, J).
mensonge(pincemoi, J):- mensonge(licorne, J).
quandJeDisQueJeMensNeg(L, Quand, Jour) n'est
pas utile ici. En effet les affirmations des deux font que soit ils
mentent tous les deux, soit ils disent vrais tous les deux .
et il faut définir une nouvelle question
d'Alice :
questionAlicePP(PREMIER , SECOND , AUJOURDHUI)
:- ...
ATTENTION à l'utilisation de la négation,
pensez à l'utilisation d'un prédicat comme : jour/1 ci dessous
jour(lundi).
jour(mardi).
jour(mercredi).
jour(jeudi).
jour(vendredi).
jour(samedi).
jour(dimanche).
|
EXERCICE
3 : DATALOG,
et Base de données
Les réponses aux questions de cet exercice
seront données dans un tableau à deux colonnes : colonne de gauche les
tuples des relations, les requêtes SQL et le résultat escompté, colonne
de droite les faits Prolog et les règles DATALOG et la copie d'une
session Prolog avec la question posée et des résultats équivalents aux
résultats en colonne de gauche.
Soient les schémas de relations :
AIME(BUVEUR, BIERE)
VEND(BAR, BIERE, PRIX)
FREQUENTE(BUVEUR, BAR)
QUESTION 1 :
imaginez (colonne de gauche) : une Base
de Données contenant les 3 tables AIME , VEND , FREQUENTE, chaque table
contenant au moins 6 tuples i.e. il y a plusieurs buveurs, plusieurs
bars , plusieurs bières à plusieurs prix et dans la colonne de droite
l'ensemble de faits DATALOG équivalents.
remarque : un buveur peut aimer plusieurs
bières, un bar peut vendre plusieurs bières, une bière peut être vendues
à plusieurs prix.
"les buveurs heureux sont des buveurs qui
fréquentent des bars qui vendent de la bière qu'ils aiment".
QUESTION 2 : Quels sont les buveurs heureux ?
répondez à cette question : colonne de gauche par une requête SQL et
colonne de droite en DATALOG par la définition de la règle
buveurHEUREUX(BUVEUR) :- % à compléter...
et la copie de la session Prolog avec toutes
les réponses à la question :
?- buveurHEUREUX(BUVEUR).
QUESTION 3 : Quels sont les bars qui
vendent 2 bières différentes au même prix ? répondez à cette question :
colonne de gauche par une requête SQL et colonne de droite en DATALOG
par la définition de la règle
bar2(BAR) :- % à compléter...
et la copie de la session Prolog avec toutes
les réponses à la question :
?- bar2(BAR).
Ajouter à la Base de Données la table
BIERE(NOM , BRASSEURS) avec au moins 6 tuples.
QUESTION 4 :
Quels sont les brasseurs qui fournissent le bar "joe"
? répondez à cette question : colonne de gauche par une requête SQL et
colonne de droite en DATALOG par la définition de la règle
barJOE(BRASSEUR) :- % à compléter...
et la copie de la session Prolog avec toutes
les réponses à la question :
?- barJOE(B).
EXERCICE 4 :
DATALOG,
négation
Soit le programme de reconnaisssance de la
parité des nombres {0,1,2,3,4}
nbre01234.pl
suc(0,1).
suc(1,2).
suc(2,3).
suc(3,4).
pair(0).
pair(X) :- suc(Z , Y) , suc(Y,X) , pair(Z).
impair(X) :- not pair(X).
|
QUESTION 1 :
Donnez l'univers de Herbrand de nbre01234.pl,
la cardinalité de sa Base de Herbrand et calculez sa sémantique de point
fixe (ATTENTION : du fait de la présence de 'not' il faut stratifier le
programme).
Remarque : à la question ?-
impair(N)
la négation est toujours appliquée de manière NON sûre donc en chaînage
arrière on n'atteint pas en Prolog la sémantique 'attendue'.
?- impair(N).
No
?-
Pour retrouver la sémantique attendue i.e.
la sémantique identique à celle de point fixe on se donne le prédicat nbre/1
qui va permettre d'instancier la variable sous le not :
nbre/1
nbre(0).
nbre(1).
nbre(2).
nbre(3).
nbre(4).
|
QUESTION 2 : modifiez le prédicat impair/1 en
utilisant nbre/1 et calculez la sémantique en chaînage arrière du
programme. (répondre par une copie de la session Prolog).
QUESTION 3 : calculez le complété du programme
(y compris les différents axiomes et règles à ajouter aux formules
logiques correspondant au programme. ATTENTION : le programme
complete.pl ne donne pas ces "suppléments").
EXERCICE -1-
Question -1- |
L'univers de Herbrand de progr1 est l'ensemble des constantes du programme :
Up ={a, b, c}
|
Question -2- |
Tp(Ø) = {f(a), h(a,b), h(a,c), h(b,a)}
Tp(Tp(Ø)) = Tp(Ø) U {g(a), g(b), g(c)}
Tp(Tp(Tp(Ø))) = Tp(Tp(Ø)) U {h(a,a), h(b,b), h(c,c)}
Tp(Tp(Tp(Tp(Ø)))) = Tp(Tp(Tp(Ø))) U {h(b,a), h(c,a), h(b,c), h(c,b)}
Tp(Tp(Tp(Tp(Tp(Ø))))) = Tp(Tp(Tp(Tp(Ø)))) =
{f(a), h(a,b), h(a,c), h(b,a), g(a), g(b), g(c), h(a,a), h(b,b), h(c,c), h(b,a), h(c,a), h(b,c), h(c,b)}
|
Question -3- |
?- f(a).
Yes
?- f(b).
No
?- f(c).
No
?- g(a).
Yes
?- g(b).
Yes
?- g(c).
Yes
?- h(a,a).
Yes
?- h(a,b).
Yes
?- h(a,c).
---il manque la constatation que les deux sémantiques sont identiques---
|
Yes
?- h(b,a).
Yes
?- h(b,b).
Yes
?- h(b,c).
Yes
?- h(c,a).
Yes
?- h(c,b).
Yes
?- h(c,c).
Yes
|
EXERCICE -2-
Question -1- |
?- question_1_Alice(Aujourdhui).
Aujourdhui = jeudi ;
No
?- question_2_Alice(Aujourdhui).
Aujourdhui = jeudi ;
No
?- question_3_Alice(Aujourdhui).
Aujourdhui = jeudi ;
No
|
Question -2- |
?- question_neg1_Alice(J).
J = jeudi ;
No
?- question_neg2_Alice(J).
No
?- question_neg3_Alice(J).
No
Négation NON-sure ;
Un but négatif (commençant par 'not' ou '\+') doit toujours être clos au moment de son appel.
La question question_neg1_Alice(J) est la bonne;
A l'appel du prédicat quandJeDisQueJeMensNeg(L, AUJOURDHUI, HIER),
les variables AUJOURDHUI et HIER sont déjà instanciées.
|
Question -3- |
quiESTqui(pincemoi, pincemi, JOUR) :-
jour(JOUR),
not(mensonge(pincemi, JOUR)),
not(mensonge(pincemoi, JOUR)).
quiESTqui(pincemi, pincemoi, JOUR) :-
jour(JOUR),
mensonge(pincemi, JOUR),
mensonge(pincemoi, JOUR).
questionAlicePP(PREMIER , SECOND , AUJOURDHUI) :- quiESTqui(PREMIER , SECOND, AUJOURDHUI).
Question Prolog:
?- questionAlicePP(PREMIER,SECOND,AUJOURDHUI).
PREMIER = pincemoi
SECOND = pincemi
AUJOURDHUI = dimanche ;
No
|
EXERCICE -3-
Question -1- |
SQL
|
DATALOG
|
AIME |
buveur |
bière |
pers1 |
stella1 |
pers1 |
stella5 |
pers1 |
stella3 |
pers2 |
stella5 |
pers2 |
stella6 |
pers3 |
stella5 |
pers3 |
stella4 |
pers3 |
stella2 |
pers4 |
stella1 |
pers4 |
stella2 |
pers5 |
stella3 |
pers5 |
stella4 |
|
'AIME'(pers1 , stella1).
'AIME'(pers1 , stella5).
'AIME'(pers1 , stella3).
'AIME'(pers2 , stella5).
'AIME'(pers2 , stella6).
'AIME'(pers3 , stella5).
'AIME'(pers3 , stella4).
'AIME'(pers3 , stella2).
'AIME'(pers4 , stella1).
'AIME'(pers4 , stella2).
'AIME'(pers5 , stella3).
'AIME'(pers5 , stella4).
|
VEND |
bar |
bière |
prix |
au chien qui fume |
stella1 |
20 |
au chien qui fume |
stella2 |
10 |
au chien qui fume |
stella3 |
10 |
au chien qui fume |
stella4 |
15 |
au chien qui fume |
stella5 |
14 |
au chien qui fume |
stella6 |
18 |
la cigale |
stella4 |
21 |
la cigale |
stella5 |
15 |
la cigale |
stella6 |
16 |
joe |
stella2 |
12 |
joe |
stella5 |
10 |
joe |
stella4 |
12 |
|
'VEND'('au chien qui fume' , stella1 , 20).
'VEND'('au chien qui fume' , stella2 , 10).
'VEND'('au chien qui fume' , stella3 , 10).
'VEND'('au chien qui fume' , stella4 , 15).
'VEND'('au chien qui fume' , stella5 , 14).
'VEND'('au chien qui fume' , stella6 , 18).
'VEND'('la cigale' , stella4 , 21).
'VEND'('la cigale' , stella5 , 15).
'VEND'('la cigale' , stella6 , 16).
'VEND'(joe , stella2 , 12).
'VEND'(joe , stella5 , 10).
'VEND'(joe , stella4 , 12).
|
FREQUENTE |
buveur |
bar |
pers1 |
au chien qui fume |
pers2 |
joe |
pers3 |
au chien qui frime |
pers4 |
la cigalle |
pers5 |
au chien qui fume |
|
'FREQUENTE'(pers1 , 'au chien qui fume').
'FREQUENTE'(pers2 , joe).
'FREQUENTE'(pers3 , 'au chien qui frime').
'FREQUENTE'(pers4 , 'la cigalle').
'FREQUENTE'(pers5 , 'au chien qui fume').
|
|
Question -2- |
SQL |
DATALOG |
La requête SQL:
select AIME.buveur from AIME, VEND, FREQUENTE
where AIME.buveur = FREQUENTE.buveur
and VEND.bière = AIME.bière
and FREQUENTE.bar = VEND.bar
|
buveurHEUREUX(BUVEUR) :-
'AIME'(BUVEUR , BIERE) ,
'VEND'(BAR , BIERE, _),
'FREQUENTE'(BUVEUR , BAR).
?- buveurHEUREUX(BUVEUR).
BUVEUR = pers1 ;
BUVEUR = pers1 ;
BUVEUR = pers1 ;
BUVEUR = pers2 ;
BUVEUR = pers5 ;
BUVEUR = pers5 ;
No
|
|
Question -3- |
SQL |
DATALOG |
La requête SQL:
créer une vue :
create view VEND_VIEW as select bar, bière, prix from VEND
exécuter la requête :
select VEND.bar from VEND, VEND_VIEW
where VEND.bière <> VEND_VIEW.bière
and VEND.prix = VEND_VIEW.prix
|
bar2(BAR) :-
'VEND'(BAR , BIERE1, PRIX),
'VEND'(BAR , BIERE2, PRIX),
BIERE1 \== BIERE2.
?- bar2(BAR).
BAR = 'au chien qui fume' ;
BAR = 'au chien qui fume' ;
BAR = joe ;
BAR = joe ;
No
|
|
Question -4- |
SQL |
DATALOG |
BIERE |
nom |
brasseur |
|
stella1 |
brasseurParis |
|
stella2 |
brasseurCheles |
|
stella3 |
brasseurIssy |
|
stella4 |
brasseurAuber |
|
stella5 |
brasseurBourgognes |
|
stella6 |
brasseurItaly |
|
La requête SQL:
select nom from BIERE, VEND
where BIERE.nom = VEND.bière and Vend.bar = 'joe'
|
'BIERE'(stella1 , brasseurParis).
'BIERE'(stella2 , brasseurChelles).
'BIERE'(stella3 , brasseurIssy).
'BIERE'(stella4 , brasseurAuber).
'BIERE'(stella5 , brasseurBourgognes).
'BIERE'(stella6 , brasseurItaly).
barJOE(BRASSEUR) :-
'BIERE'(Biere, BRASSEUR),
'VEND'(joe, Biere, _).
?- barJOE(BRASSEUR).
BRASSEUR = brasseurChelles ;
BRASSEUR = brasseurAuber ;
BRASSEUR = brasseurBourgognes ;
No
|
|
EXERCICE -4-
Question -1- |
Univers de Herbrand : UP = {0, 1, 2, 3, 4}
Base de Herbrand : Bp = {suc(0 , 0), suc(0 , 1), suc(0 , 2), suc(0 , 3), suc(0 , 4),
suc(1 , 0), suc(1 , 1), suc(1 , 2), suc(1 , 3), suc(1 , 4),
suc(2 , 0), suc(2 , 1), suc(2 , 2), suc(2 , 3), suc(2 , 4),
suc(3 , 0), suc(3 , 1), suc(3 , 2), suc(3 , 3), suc(3 , 4),
suc(4 , 0), suc(4 , 1), suc(4 , 2), suc(4 , 3), suc(4 , 4),
pair(0), pair(1), pair(2), pair(3), pair(4),
impair(0), impair(1), impair(2), impair(3), impair(4)
}
|Bp| = 35
Sémantique du point fixe :
Stratification du programme :
pair -~-> suc
pair ---> pair
impair -~-> pair
S1 = {pair, suc}
TpS10 = {suc(0 , 1, suc(1 , 2), suc(2 , 3), suc(3 , 4), pair(0)}
TpS11 = TpS10 U {pair(2), pair(4)} = TpS1¥
S2 = {impair}
TpS20 = TpS1¥ U {impair(1), impair(3)} = TpS2¥
|
Question -2- |
impair(X) :- nbre(X), not(pair(X)).
?- impair(N).
N = 1 ;
N = 3 ;
No
|
Question -3- |
Forme homogène des clauses
suc(X, Y) :- X = 0, Y = 1.
suc(X, Y) :- X = 1, Y = 2.
suc(X, Y) :- X = 2, Y = 3.
suc(X, Y) :- X = 3, Y = 4.
pair(X) :- X = 0.
pair(X) :- suc(Z, Y), suc(Y, X), pair(Z).
nbre(X) :- X = 0.
nbre(X) :- X = 1.
nbre(X) :- X = 2.
nbre(X) :- X = 3.
nbre(X) :- X = 4.
impair(X):- nbre(X), not pair(X).
Equivalences
'A'x,y suc(x,y) <=> (x=0 & y=1) v (x=1 & y=2) v (x=2 & y=3) v
(x=3 & y=4)
'A'x nbre(x) <=> (x = 0) v (x = 1) v (x = 2) v (x = 3) v (x =
4)
'A'x pair(x) <=> 'E'(y,z) ((x = 0) v (suc(z,y), suc(y,x),
pair(z)))
'A'x impair(x) <=> (nbre(x) & ¬ pair(x))
Axiomes de l'égalité :
Reflexivité
'A' x : x = x
Symétrie
'A' x,y x = y => y = x
Transitivité
'A' x,y,z x = y & y = z => x = z
Substitution des égaux :
'A'(x1,x2,y1,y2) ((x1 = y1 & x2 = y2) => (x1 = x2 => y1 =
y2))
'A'(x1,x2,y1,y2) ((x1 = y1 & x2 = y2) => (suc(x1,x2) =>
suc(y1,y2)))
'A'(x1,y1) ((x1 = y1) => (nbre(x1) => nbre(y1)))
'A'(x1,y1) ((x1 = y1) => (pair(x1) => pair(y1)))
'A'(x1,y1) ((x1 = y1) => (impair(x1) => impair(y1)))
Différenciation des constantes :
¬(0 = 1)
¬(0 = 2)
¬(0 = 3)
¬(0 = 4)
¬(1 = 2)
¬(1 = 3)
¬(1 = 4)
¬(2 = 3)
¬(2 = 4)
¬(3 = 4) |
|
|