EPITA
Introduction à Prolog, cours n° 3
La résolution dans le cas propositionnel
- Forme clausale
- Forme
clausale
- Notion de clause : définition
- Notion de clause : interprétation
- Forme clausale
- Forme clausale réduite et algorithme de Wang
- Forme
clausale et preuve par réfutation
- Réfutation
- Exemple
simple
- Retour
à Prolog
- La résolution
- L'opération de base : la réduction
- Résolvante
- Exemples
- La
résolution propositionnelle linéaire
- Principe
- La résolution propositionnelle SLD
pour les clauses de Horn
- La
résolution simplifiée à la Prolog
Pour la réalisation en Prolog de tout ce discours, voir ici.
-
-
Rappel : un littéral est
- soit un atome (variable propositionnelle ou application
d'un prédicat), qui sera appelé un littéral positif
- soit la négation d'un atome, qui sera qualifié de
littéral négatif.
Une clause est une disjonction de littéraux.
Exemples : (a ⋁ ¬b ⋁ d), (c
⋁ ¬a ⋁ d), (b ⋁ c)
et (¬f)
sont des clauses,
mais ni (a ⋁ ¬(b ⋁
d))
ni (b ⋁ (c ⋀ ¬f))
n'en sont.
L'idée sous-jacente à l'intérêt porté à cette notion est le désir de
simplifier les structures logiques
pour ramener les raisonnements à des calculs, suivant le souhait de
Leibniz calculemus.
Le mot calcul (en latin calculus) est à prendre ici en
sons sens premier de petit caillou :
comme on le verra, la résolution consiste en quelque sorte à
entrechoquer les littéraux comme des cailloux,
certains d'entre eux s'annihilant et faisant ainsi progresser la
démonstration...
-
Dans une clause on peut toujours regrouper les littéraux positifs d'un
côté et les littéraux négatifs de l'autre ;
la disjonction des littéraux négatifs s'interprète alors, d'après la
règle de De Morgan,
comme la négation de la conjonction des mêmes littéraux "changés de
signe".
(a⋁b⋁c...) ⋁ (¬x⋁¬y⋁¬z...)
= (a⋁b⋁c...)
⋁ ¬(x⋀y⋀z...)
En raison de la définition de l'implication matérielle X ⊃ Y
<==> ¬X ⋁ Y
,
la clause s'interprète alors comme une implication
(x⋀y⋀z...) ⊃ (a⋁b⋁c...)
c'est à dire comme un séquent de complexité zéro.
N.B. La clause vide, disjonction d'aucun littéral,
a la valeur de vérité faux
(comme le séquent dont l'antécédent et le conséquent sont vides).
Une clause de Horn est une clause ne comportant pas
plus d'un littéral positif.
- Si elle ne contient pas de littéral négatif, elle
s'interprète comme (l'affirmation d') un fait.
- Si elle ne contient que des littéraux négatifs, elle
s'intrprète comme une requête.
-
Une proposition est en forme clausale, ou en forme (normale) conjonctive
si elle est
une conjonction de clauses.
Exemple : (a ⋁ ¬b ⋁ d) ⋀ (c
⋁ ¬a ⋁ d) ⋀ (b ⋁ c) ⋀ (¬f)
,
mais pas (a ⋁ ¬(b ⋁
d)) ⋀ (c ⋁ ¬a ⋁ d) ⋁
(b ⋁ (c ⋀ ¬f))
.
N.B. une forme clausale vide, conjonction d'aucune
clause, a la valeur de vérité vrai.
Toute proposition exprimée avec les connecteurs traditionnels peut se
mettre sous forme clausale,
en appliquant la définition de l'implication et les lois de De Morgan.
Il peut arriver que cette forme clausale soit beaucoup plus longue que
la proposition initiale,
cette croissance peut être exponentielle.
Exemple : proposition initiale : ¬([(p ⊃ q)
⋀ (q ⊃ r) ⋀ (r⊃ s) ⋀ (t ⊃ ¬s)] ⊃
(p ⊃ ¬t))
- On applique la définition "p ⊃ q" <-> "¬p
⋁ q"
[(¬p ⋁ q) ⋀ (¬q ⋁ r) ⋀
(¬r ⋁ s) ⋀ (¬t
⋁ ¬s)] ⊃ (¬p ⋁ ¬t)
¬[(¬p ⋁ q) ⋀ (¬q ⋁ r) ⋀
(¬r ⋁ s) ⋀ (¬t
⋁ ¬s)] ⋁ (¬p ⋁ ¬t)
- puis les lois de De Morgan : ¬(p⋀q) <->
¬p⋁¬q
[¬(¬p ⋁ q) ⋁ ¬(¬q ⋁
r) ⋁ ¬(¬r ⋁
s) ⋁ ¬(¬t ⋁ ¬s)] ⋁ (¬p ⋁ ¬t)
- et ¬(p⋁q) <-> ¬p⋀¬q en même temps que ¬¬p
<->p
[(p ⋀
¬q) ⋁ (q ⋀¬r) ⋁ (r ⋀¬s) ⋁ (t ⋀ s)]
⋁ (¬p ⋁ ¬t)
- Par associativité de "⋁", on obtient une forme
disjonctive
(p ⋀
¬q) ⋁ (q ⋀¬r) ⋁ (r ⋀¬s) ⋁ (t ⋀ s)
⋁ ¬p ⋁ ¬t
- dont on prend la négation, qui donne
la forme conjonctive cherchée
(¬p ⋁ q) ⋀ (¬q ⋁
r) ⋀ (¬r ⋁
s) ⋀ (¬t ⋁ ¬s) ⋀ p ⋀ t
-
Une
forme conjonctive est réduite
si chaque atome (variable propositionnelle)
apparaît au plus une fois dans chaque terme de la conjonction.
L'exemple de forme clausale
ci-dessus
(a ⋁ ¬b ⋁ d) ⋀ (c
⋁ ¬a ⋁ d) ⋀ (b ⋁ c) ⋀ (¬f)
,
est réduit.
Manifestement, toute forme conjonctive est logiquement équivalente à
une forme réduite :
il suffit d'appliquer les lois "a⋁a = a", "¬a⋁¬a = ¬a"
"a ⋁ ¬a = vrai".
Il est également clair que dans une proposition en forme conjonctive
réduite,
on peut associer à chacun des termes de la conjonction un
système de valeurs des variables
qui donne à ce terme (et donc à la conjonction toute entière)
la valeur faux.
Dans notre exemple, prendre
- a = d = faux, b = vrai
pour le 1er terme
- c = d = faux, a = vrai
pour le 2ème
- b = c = faux pour le 3ème
- f = vrai pour le 4ème.
Il s'ensuit qu'une forme conjonctive réduite est une tautologie si et
seulement si elle ne contient
aucun terme : c'est alors une conjonction vide, qui vaut vrai.
La forme clausale réduite
associée à une proposition quelconque est exactement
le "résidu" calculé par l'algorithme de Wang (le 3ème argument du
prédicat valide
de notre programme Prolog).
Illustration avec l'exemple ci-dessus :
?- wang((a ou non b ou d) et (c ou non a ou d) et
(b ou c) et non f, X).
Pas une tautologie
Pas une tautologie
Pas une tautologie
Pas une tautologie
OK
X = [[[b], [d, a]], [[a], [d, c]], [[], [b, c]], [[f], []]].
Pour vérifier que cette formule représente bien le même énoncé que la
forme conjonctive réduite donnée,
voir plus loin.
L'algorithme de Wang peut donc s'interpréter comme la mise sous forme
clausale d'une proposition donnée.
En effet, on obtient au terme du processus Wang une conjonction de
séquents de compexité 0, i.e.
une conjonction de clauses.
-
-
Pour établir qu'une proposition donnée est une tautologie,
l'idée de la preuve par réfutation
est de
démontrer que sa négation est contradictoire.
Comme on va le voir plus loin, la technique de résolution permet
justement de trouver une réfutation
à une formule donnée en forme clausale.
Dans une perspective de programmation logique, on cherche à prouver
qu'un certain énoncé But
est conséquence logique d'une certaine théorie Th.
La théorie est représentée par le programme, l'énoncé à prouver est
donné à résoudre par l'utilisateur.
Il s'agit donc d'établir que l'implication Th ⊃ But
est une tautologie, i.e. que ¬(Th ⊃ But)
est contradictoire.
Pour cela, on reformule l'implication Th ⊃ But
en ¬Th ⋁ But et en
passant à la négation on obtient
Th ⋀ ¬But.
Si la théorie Th est donnée sous forme clausale, c'est à
dire comme un ensemble (conjonction) de clauses,
- ce qui est le cas en Prolog : le programme est une collection de
clauses de Horn -
alors le complexe Th ⋀ ¬But est
aussi sous forme clausale.
On peut alors chercher une réfutation en appliquant la résolution.
-
Soit à démontrer que la théorie zoologique suivante (Th)
herbivore ⊃ girafe ⋁ buffle⋁
antilope
herbivore ⊃ ¬félin
panthère ⊃ félin
tacheté ⊃ panthère ⋁
girafe
a pour conséquence logique que "herbivore ⋀
tacheté ⊃ girafe
"
(But).
N. B. On peut traiter ce problème directement par
l'algorithme de Wang :
?- wang((herbivore imp girafe ou buffle ou
antilope) et (herbivore imp non félin)
| et (panthère imp félin) et (tacheté imp
panthère ou girafe)
| imp (herbivore et tacheté imp girafe),
X).
OK
X = [].
Notons qu'une conclusion erronée comme "herbivore
⋀
tacheté ⊃ panthère"
est bien
détectée :
?- wang((herbivore imp girafe ou buffle ou
antilope) et
(herbivore imp
non félin)
et (panthère imp félin) et (tacheté imp panthère ou girafe)
imp (herbivore et tacheté imp panthère), X).
Pas une tautologie
Pas une tautologie
Pas une tautologie
OK
X
= [[[girafe, girafe, herbivore, tacheté], [panthère, félin, panthère]],
[[girafe, buffle, herbivore, tacheté], [panthère, félin, panthère]],
[[girafe, antilope, herbivore, tacheté], [panthère, félin, panthère]]].
Les cinq implications en cause se traduisent en autant de clauses, 4
pour Th :
¬ herbivore ⋁ girafe ⋁ buffle⋁ antilope
¬ herbivore ⋁ ¬félin
¬ panthère ⋁ félin
¬ tacheté ⋁ >
panthère ⋁ girafe
et une pour But : ¬herbivore ⋁ ¬tacheté ⋁
girafe
.
La négation de cette dernière donne une conjonction de 3 clauses
unitaires :
herbivore ⋀ tacheté ⋀ ¬girafe
.
Le complexe à réfuter ( Th ⋀ ¬But,
sous forme clausale) est donc la conjonction de 7 clauses.
"(¬herbivore ⋁
girafe ⋁ buffle⋁ antilope) ⋀
(¬herbivore ⋁
¬félin) ⋀ (¬panthère ⋁
félin) ⋀
(¬tacheté ⋁
panthère ⋁ girafe) ⋀ herbivore ⋀ tacheté ⋀ ¬girafe
".
On notera qu'on aurait obtenu le même complexe en demandant de prouver
que
Th + les hypothèses herbivore
et tacheté
entraîne girafe
.
En effet lesdites hypothèses se traduisent comme deux clauses unitaires
"herbivore"
et "tacheté"
ajoutées à la liste des 4 clauses de Th, d'où au
total 6 clauses plus le but nié " ¬girafe"
.
C'est bien normal !
Pour l'exécution effective de la procédure de réfutation par la
résolution, voir plus
loin.
-
C'est de cette manière, dans une optique de réfutation, qu'il
faut lire les calculs de Prolog :
- Quand on lui demande "
:- pere(cesar, X).
",
- Prolog ne cherche pas à démontrer que "
pere(cesar,
marc)
"
est vrai !
- Prolog cherche à démontrer que l'assertion
"
∀X ¬pere(cesar,X)
" est incompatible
avec sa base de connaissances (règles
& faits),
- c'est-à-dire qu'il cherche à réfuter cette
assertion en s'appuyant sur son programme
- et il produit
tous les contre-exemples
qu'il peut trouver, notamment "
X = marc
".
-
Étant donné deux clauses différentes A et B contenant
des littéraux de signes opposés,
c'est-à-dire que A contient le littéral positif a
,
et B le littéral
opposé ¬a
ou vice-versa,
l'opération de réduction consiste à construire une troisième clause C
en réunissant
- A privée de son littéral positif
a
,
- et B privée de son littéral négatif
¬a
(ou vice-versa).
En somme, les deux littéraux opposés s'éliminent l'un l'autre...
La clause C ainsi construite s'appelle une résolvante
de A et B.
Par exemple : A = (¬r ⋁
s)
et B = (¬t ⋁ ¬s)
,
en prenant a
= s
,
on construit C = (¬r ⋁
¬t
)
.
-
(terme emprunté à la tradition des algébristes : résolution des
équations...)
La propriété essentielle d'une résolvante quelconque R de deux
clauses A et B est l'implication
A⋀
B ⊃ R.
En effet, vu que les deux littéraux opposés a
et ¬a
ne peuvent
être vrais en même temps,
la conjonction du membre gauche ne
peut être vraie que si "les restes de chaque clause" sont
simultanément
vrais,
ce qui entraîne a fortiori que
leur disjonction, qui compose la clause R, soit vraie.
Dans notre exemple il s'agit de ¬r
et ¬t
.
Le même exemple montre que l'implication A⋀
B
⊃ R n'est pas une équivalence !
La résolvante R peut être vraie sans que la conjonction A⋀
B le soit.
Cette implication a pour conséquence que si R est vide,
donc fausse,
alors nécessairement A et B sont incompatibles.
Attention ! Il est essentiel de supposer que les deux clauses A
et B sont différentes,
sans quoi on tirerait une résolvante vide de la clause tautologique (¬a
⋁ a)
résolue contre
elle-même !
La stratégie de réfutation par résolution va donc consister en la
recherche d'une résolvante vide
en répétant les opérations de réduction à partir du système de clauses
initial.
-
- La négation de la proposition "
[(p ⊃ q) ⋀ (q
⊃ r) ⋀ (r⊃ s) ⋀ (t ⊃ ¬s)] ⊃ (p ⊃ ¬t)
"
en forme clausale "(¬p ⋁ q) ⋀ (¬q ⋁ r) ⋀ (¬r ⋁
s) ⋀ (¬t ⋁ ¬s) ⋀ p ⋀ t
"
---------------------
|
|
|
(¬p ⋁ r)
|
|
|
---------------------------
|
|
(¬p ⋁ s)
| |
-------------------------------
|
(¬p ⋁
¬t
)
|
----------------------------
(¬t ⋁
¬t
)
---------
()
- La girafe
"(¬herbivore ⋁ girafe ⋁ buffle⋁ antilope) ⋀
(¬herbivore ⋁ ¬félin) ⋀ ( ¬ panthère ⋁ félin ) ⋀
(¬tacheté ⋁ panthère ⋁ girafe ) ⋀ herbivore ⋀ tacheté ⋀ ¬girafe
"
ou pour abréger
"(¬h ⋁ g ⋁ b ⋁ a) ⋀ (¬h ⋁ ¬f) ⋀ (¬p ⋁ f) ⋀ (¬t ⋁ p ⋁ g) ⋀ h
⋀ t ⋀
¬g
"
-----------------
-- |
|
|
|
-----------------------------------------------------
|
(g ⋁ b ⋁ a)
|
------------------------------------------
(b ⋁ a)
Cette tentative n'aboutit pas (aucun moyen d'éliminer a
et b
). Essayons autre chose.
(¬h ⋁ g ⋁ b ⋁ a) ⋀ (¬h ⋁ ¬f) ⋀ (¬p ⋁ f) ⋀ (¬t ⋁
p ⋁ g) ⋀ h
⋀ t ⋀
¬g
-------------------
| | |
|
(¬h ⋁ ¬p)
| | | |
------------------------------- | |
|
(¬h
⋁ ¬t ⋁ g)
| |
|
----------------------------
| |
(¬t
⋁ g)
| |
----------------------
|
( g )
|
--------------------
()
Et si on remplaçait la conclusion
girafe
par panthère
?
On voit que la seule façon d'éliminer panthère
va
faire apparaître girafe
dans la
résolvante,
qui restera indélébile...
-
Comme on l'imagine, le processus de résolution exhaustif, tel que nous
l'avons défini, est extrêmement coûteux,
puisque le but poursuivi n'est pas de construire toutes les
résolvantes, mais
- soit de parvenir au plus vite à la clause
vide,
- soit de constater que cette dernière ne sera jamais atteinte.
Depuis l'invention de la règle de résolution en 1965, la recherche
s'est orientée vers l'élaboration de stratégies efficaces.
La principale de ces stratégies est la résolution linéaire.
Son principe est que l'une des deux clauses qu'on tente de réduire
à
chaque étape est
la résolvante produite à l'étape précédente. .
Les deux exemples de résolution que nous avons vus plus haut étaient
l'un et l'autre linéaires.
Le
second montre que le choix de la clause choisie pour lancer le
processus peut être décisif,
et qu'on doit parfois le remettre en
question par un retour en arrière.
-
C'est une réalisation de la résolution linéaire dans le cas restreint
où
- toutes les clauses sont des clauses de Horn,
- et où on travaille avec un seule clause négative, la liste
de buts.
Or la résolution linéaire à partir de cette clause
négative
donne à chaque pas
une résolvante courante qui reste
négative (c'est la liste de buts courante).
Ainsi dans notre processus il y a à chaque pas une
seule clause négative à gérer,
qui est connue par sa localisation.
Le seul degré de liberté est le choix de la construction de
la
résolvante,
qui doit réaliser la réunion des listes d'atomes (littéraux
négatifs) SButs
et de la queue de
clause Q
.
La stratégie Prolog de recherche en profondeur (la résolvante étant
gérée comme une pile)
se traduit par union
= append
et elle
entraîne des bouclages intempestifs.
La méthode correcte est de faire une union
sans duplication.
-
L'interprète Prolog gère la résolvante comme une pile, et
ne mémorise pas les résolvantes précédentes,
d'où un programme beaucoup plus simple, mais qui a une forte
tendance a boucler,