Logique des prédicats 2011-2012 1 Pourquoi les prédicats Limitations de la logique des propositions. Exemple : on veut modéliser le problème suivant : Si un étudiant a les UEs PROG001 et PROG002, il a le module PROG. S’il a aussi l’UE Stage, il a le CP PROGRAMMEUR. On peut le faire en logique des propositions : prog001 ∧ prog002 → prog prog ∧ stage → cp Mais ce système ne permet pas de gérer des informations sur plusieurs étudiants. Par exemple, si Aragorn et Bilbo sont deux étudiants d’informatique, il faudrait écrire les formules : aragornAprog001 ∧ aragornAprog002 → aragornAprog aragornAprog ∧ aragornAstage → aragornAcp bilboAprog001 ∧ bilboAprog002 → bilboAprog bilboAprog ∧ bilboAstage → bilboAcp Pour éviter de dupliquer les règles pour chaque cas particulier, on introduit la notion de variables, qui nous permettra de raisonner de manière plus générale : ∀X(prog001(X) ∧ prog002(X) → prog(X)) ∀X(prog(X) ∧ stage(X) → cp(X)) On ajoute donc des arguments aux propositions. La nouvelle construction, qui est vraie ou fausse pour certaines valeurs, est appelée un prédicat. 1 2 Syntaxe de la logique des prédicats (sans symbole fonctionnel) Dans un premier temps, nous allons décrire un sous ensemble simplifié de la logique des prédicats, que nous complèterons par la suite. On définit une logique du premier ordre sans symboles fonctionnel par la donnée : – d’un ensemble de de symboles de prédicats P ; chaque prédicat a une arité, qui est son nombre d’arguments. – d’un ensemble de constantes C ; – d’un ensemble de variables X. On définit les formules du premier ordre pour P et C inductivement : Base : si p/n ∈ P alors p(a1 , ..., an ) est une formule, pour tout ai dans C ∪ X (c’est aussi un atome). exemple : si X est une variable, et aragorn une constante, et que prog est un prédicat d’arité 1, alors prog(X) et prog(aragorn) sont des formules (et des atomes). Cas particulier : les prédicats d’arité 0 correspondent aux propositions. induction : Si A et B sont des formules et X une variable, alors – ¬A est une formule ; – (A ∧ B) est une formule ; – (A ∨ B) est une formule ; – (A → B) est une formule (on peut éventuellement ajouter ← et ↔) ; – ∀XA est une formule ; – ∃XA est une formule ; Les parenthèses servent à éviter les ambiguı̈tés. fermeture : les seules formules du premier ordre sur P et C sans symboles fonctionnels sont celles obtenues par induction. Grammaire formelle (en utilisant les DCG) : /* grammaire de la logique des prédicats en DCG */ terme --> foncteur,"(",termes, ")". terme --> constante. terme --> variable. termes --> terme. termes --> terme, ",", termes. atome --> predicat, "(", termes, ")". formule formule formule formule formule formule --> --> --> --> --> --> atome. "non", esp, formule. "(", formule, esp, "ou", esp, formule, ")". "(", formule, esp, "et", esp, formule, ")". "(", formule, esp, "->", esp, formule, ")". "pourtout", esp, variable, esp, formule. 2 formule --> "existe", esp, variable, esp, formule. esp --> " ". esp --> " ", esp. /* Lexique */ non --> "non". foncteur --> "fonc". foncteur --> "f". constante --> "a". constante --> "b". constante --> "c". variable --> "x". variable --> "y". variable --> "z". predicat --> "p". 3 Quantification et variables ∀Xp(X) : pour tout X, p(X) , quantification universelle. ∃Xp(X) : il existe un X (au moins) pour lequel p(X) , quantification existentielle. 3.1 Quelques particularités des quantificateurs – Dans une quantification, ∀XA, la formule A est dite dans la portée de la quantification. En effet, si on écrit (p(X) ∧ ∀Xq(X)), le premier X n’est pas concerné par la quantification, et le second, si. Les deux X sont donc à considérer comme des variables différentes. – ¬(∀XA(X)) équivaut à ∃X(¬A(X)) – ¬(∃XA(X)) équivaut à ∀X(¬A(X)) 3.2 Variables quantifiées, liées et libres – Une variable est quantifiée quand elle apparaı̂t juste derrière un quantificateur. Par exemple, dans ∀Xp(X), le premier X est dit quantifié, le second non. – une variable est dite liée quand elle est dans la portée d’une quantification. Dans la formule précédente, X est liée. – une variable X est libre si elle n’est dans la portée d’aucune quantification la concernant. Par exemple, dans ∀X∃Y q(X, Y, Z), X et Y sont liées, et Z est libre. Une formule est dite fermée (ou close) ssi elle n’a pas de variable libre. Un terme est dit clos s’il ne contient pas de variable. Une formule est terminale (grounded en anglais) si elle ne contient pas de variable. 3 3.3 Notion d’ordre La notion d’ordre explique sur quoi portent les quantifications, et donc quelles sont les variables possibles. Dans la logique du premier ordre, elles portent uniquement sur les termes. Dans la logique du second ordre, les quantifications peuvent aussi porter sur les prédicats. Exemple de formule du second ordre : ∀P ∃Y P (Y ) 4 Sémantique logique Comme pour la logique des proposition, un langage du premier ordre peut se voir associer des interprétations. Certaines propriétés dépendront de l’interprétation choisie, d’autre seront vraie dans toutes les interprétations. Une interprétation donne un sens aux constantes et aux prédicats. Les constantes sont associées à des valeurs prises dans un ensemble D qui dépendra de l’interprétation, et les prédicats prendront les valeurs vrai ou faux . Comme les prédicats prennent des arguments, on considèrera un prédicat p/n comme une fonction de Dn dans {vrai, faux}. Exemples : Soit le langage du premier ordre de signature : – P = r/1 – F = a, b Voici quelques interprétations possibles : – D = {1, 2} et j’interprète a comme 1 , et b comme 2 . En interprétant r(X) comme signifiant mon argument est pair, on voir que r(a) s’interprète comme faux et r(b) comme vrai . – D = {java, lisp}, avec a interprété comme java et b comme lisp , et r/1 comme signifiant le langage est un langage impératif . On aurait alors r(a) faux et r(b) vrai. Cependant, comme avec les propositions, certaines propriétés seront vraies dans toutes les interprétations : on aura toujours r(a) ∨ ¬r(a), par exemple. Pour interpréter correctement une formule comme r(X), où X est une variable, il faut, de plus, connaı̂tre la valeur de X. On interprètera donc une formule par rapport à une interprétation et à une assignation donnée. L’interprétation sera définie inductivement sur les formules : on définira d’abord la sémantique des termes, puis celle des atome et des expressions complexes. Nous donnerons une description formelle de la sémantique quand nous aurons introduit l’intégralité de la logique des prédicats. 5 Exemples et exercices Nous allons voir des modélisations qui permettent de gérer des bases de données déductives (datalog). On veut modéliser à partir de la logique des prédicats l’organisation des cours dans un iut. On a, dans une base de données, les tables suivantes : 4 Enseignant nom prénom Baggins Bilbo Baggins Frodo Gamgee Samwise Etudiant id Nom Prénom Classe 01 Turing Alan I2 02 Lovelace Ada I2 03 Babbage Charles I2 04 Meyer Bertrand I1 05 Wirth Niklaus I1 Module ID-mod Intitule Classe id-prof 01 Math I1 01 02 Math I2 01 03 Logique I2 03 04 Programmation I1 03 05 Programmation I2 02 On va interpréter chacune de ces tables comme un prédicat. On a ainsi le prédicat enseignant/3, tel que enseignant(1,Baggins,Frodo) est vrai (etc...). Écrire une formule avec une variable libre X, qui sera vraie uniquement si... – X est le nom d’un enseignant ; – X est le nom d’un enseignant de programmation ; – X est le nom d’un étudiant qui suit au moins un cours. – X est l’intitulé d’une matière suivie par tous les étudiants Exprimer en logique du premier ordre : – il n’y a pas d’enseignant qui enseigne la programmation (on peut aussi écrire des formules fausses !) – tous les étudiants suivent au moins un cours. – il existe un enseignant qui donne des cours à tous les étudiants. id 01 02 03 6 Logique des prédicats du premier ordre En fait, les prédicats peuvent avoir pour argument non seulement des variables et des constantes, mais des structures créées à l’aide de symboles fonctionnels. Ces symboles vont servir à modéliser non seulement des fonctions au sens classique du terme, mais aussi à représenter des structures comme par exemple les listes. Il ne faut pas les confondre avec les prédicats ! exemple : dans ∀XestPair(plus(X, X)) est une formule dans laquelle estPair/1 est un prédicat d’arité 1, et plus/2 est un symbole fonctionnel d’arité 2. Le premier, quand on définira une sémantique, s’interprètera comme vrai ou faux, et le second sera compris comme une valeur. On considère généralement les constantes comme étant des symboles fonctionnels d’arité 0. 5 autre exemple : définition des listes. On décrit généralement les listes en définissant une constante, vide, qui représente la liste vide, et un opérateur cons (un symbole fonctionnel), qui prend deux arguments : le premier est le premier élément de la liste, et le second est la queue de la liste, qui est elle-même une liste. Une liste à un seul élément a pour queue la liste vide. Ainsi cons(4,cons(2, cons(8, vide))) représente la liste [4,2,8] ; et, si pour le prédicat membre/2, membre(X,L) signifie que X est un élément de la liste Y, alors on peut dire que dans cette interprétation, la formule membre(2, cons(4, cons(2, cons(8, vide)))) sera vraie. 6.1 Syntaxe de la logique du premier ordre On définit les termes par induction comme : – une variable est un terme ; – une constante est un terme ; – si f/n est un symbole fonctionnel d’arité n, et que t1 , ...tn sont des termes, alors f(t1 , ...tn ) est un terme. Une fois les termes définis, on reprend la définition précédente des formules, en modifiant simplement la base : Si p/n est un symbole de prédicat d’arité n, et que t1 , ...tn sont des termes, alors p(t1 , ...tn ) est une formule. 6.2 Sémantique de la logique du premier ordre Par rapport à la version sans symboles fonctionnels , la difficulté sera justement d’interpréter ces symboles. Un exemple simple (sur l’arithmétique). On considère le symbole fonctionnel s/1 (successeur), la constante z , et le prédicat p/1. On peut en donner l’interprétation suivante. On prend comme domaine D l’ensemble des entiers, et – JzKI = 0 – Js(z)KI = 1 – et en général, si t est un terme, Js(t)KI = 1 + JtKI – Jp(T )KI = vrai si JT KI est pair, faux sinon. Formellement : Définition : une interprétation I est la donnée d’un ensemble ID , et d’une fonction qui : – à toute constante associe une valeur dans ID ; n – à tout symbole fonctionnel d’arité n associe une fonction de ID dans ID ; n – à tout prédicat d’arité n associe une fonction de ID dans {vrai, faux} Définition : une assignation a est une application de l’ensemble V des variables dans ID . Si a est une assignation, a[x ← v] est une assignation dans laquelle toutes les variables prennent la valeur que leur donne a, sauf x, qui prend la valeur v. 6 On évalue une formule par rapport à une interprétation I et à une assignation a. On peut considérer une interprétation comme une fonction qui à une assignation a donnée fera correspondre une valeur vraie ou faux. Dans la définition ci-dessous, on notera ¬b , ∨b , ... les opérateurs usuels de l’algèbre booléenne, qui s’appliquent à des booléens, pour bien les différencier de ceux que nous sommes en train de définir. On définit par induction : – l’interprétation des termes : – pour une constante c, JcKI (a) = JcKI – pour une variable x, JxKI (a) = a(x) – pour un terme de la forme f (t1 , ...tn ), on a Jf (t1 , ...tn )KI (a) = Jf KI (Jt1 KI (a), ..., Jtn KI (a)) – Si A et B sont des formules : – pour un atome p(t1 , ..., tn ) : Jp(t1 , ...tn )KI (a) = JpKI (Jt1 KI (a), ..., Jtn KI (a)) – J¬AKI (a) = ¬b JAKI (a) – J(A ∧ B)KI (a) = JAKI (a) ∧b JBKI (a) – J(A ∨ B)KI (a) = JAKI (a) ∨b JBKI (a) – J(A → B)KI (a) = (¬b JAKI (a)) ∨b JBKI (a) – J∀XAKI (a) est vraie si et seulement si, pour toute élément v dans ID , JAKI (a[X ← v]) est vraie (i.e. la formule est vraie en remplaçant X par toutes les valeurs possibles). – J∃XAKI (a) est vraie si et seulement si il existe v dans ID tel que JAKI (a[X ← v]) soit vraie. 7 Modèles, formules consistante, formules valides Une interprétation I est un modèle de la formule F si F est vraie dans I pour toute assignation. On note |=I F On remarquera que cela revient à supposer une quantification universelle (quel que soit) devant chacune des variables libres de F. Une formule est consistante si elle a au moins un modèle. Une formule inconsistante est une formule qui n’a aucun modèle (comme p(X) ∧ ¬p(X)). Une formule est valide si elle est vraie dans toutes les interprétations et toutes les assignations. Par exemple : ∀X(p(X) ∨ ¬p(X)) est valide. On note : |= ∀X(p(X) ∨ ¬p(X)) En d’autre termes, une formule est valide si toute interprétation est un modèle de cette formule. Une formule F est la conséquence logique des formules F 1, F 2...Fn si tout modèle de F 1, F 2...Fn est aussi un modèle de F . 7 7.1 Interprétation de Herbrand Les interprétations de Herbrand donnent une version complètement syntaxique de l’interprétation. Dans une interprétation I de Herbrand, l’ensemble ID est l’ensemble des termes clos, qu’on appelle domaine de Herbrand. Ceux-ci sont leur propre image : Js(s(a))KI (a) = s(s(a)). La base de Herbrand est l’ensemble des formules atomiques closes (obtenues en utilisant toutes les combinaisons possibles d’éléments du domaine de Herbrand). Une interprétation de Herbrand est obtenue en partitionnant la base de Herbrand en deux ensembles, et en attribuant la valeur V au premier et F au second. On peut identifier l’interprétation de Herbrand à l’ensemble des atomes interprétés comme vrais. Dès qu’on introduit des symboles fonctionnels d’arité non nulle, le domaine de Herbrand devient infini. 7.1.1 Exemple 1 On considère F = {sethy, ramses} et P = {pere/2} Alors, – le domaine de Herbrand est DH = {sethy, ramses} – la base de Herbrand est {pere(sethy, ramses), pere(sethy, sethy), pere(ramses, sethy), pere(ramses, ramses)} – Une interprétation de Hebrand possible est {pere(sethy, ramses)}. Cette interprétation est, par exemple, un modèle de ∃X∃Y, pere(Y, X) 7.1.2 Exemple 2 On considère F = {z/0, s/1} et P = {p/1} Alors, – le domaine de Herbrand est DH = {z, s(z), s(s(z)), s(s(s(z))), ...} (infini). – la base de Herbrand est {p(z), p(s(z)), p(s(s(z))), ...} (infini aussi) Tout sous ensemble de la base de Herbrand définit une interprétation. On peut considérer I1 = la base en entier, ou I2 = les éléments de la base contenant un nombre pair de s. I1 et I2 sont tous deux des modèles de : ∀X(p(X) → p(s(s(X)))). 8 Manipulation des variables Lorsqu’il sera question de démonstration automatique (et de prolog), il faudra souvent remplacer des variables par des termes (et non plus par des valeurs). Par exemple, quand nous essaierons, en prolog, de montrer que la liste [3,5,8] contient la valeur 5, on tentera d’identifier cons(A,L) et cons(3,cons(5, cons(8,vide))). Il faudra donc remplacer A par 3, ce qui correspond à une assignation, mais L par cons(5,cons(8, vide)), ce qui est complètement différent. Dans ce cas, on ne parle plus d’assignation, mais de substitution. 8 8.1 Substitution de variables Définition : une substitution est une fonction qui, à des variables libres associe des termes. Exemple : σ = [X ← Y, Z ← s(X)] est une substitution qui remplace les occurrences libres de X par Y, et celles de Z par s(X). On applique la substitution sur une terme en remplaçant simultanément toutes les occurrences des variables concernées dans le terme d’origine par la valeur à substituer. Ainsi, ((e(X, Y, Z))σ = e(Y, Y, s(X)). Quand on veut définir la notion de substitution sur des formules, on ne substitue que les variables libres. Le cas échéant, il est toujours possible de renommer les variables. Si A est une formule, on note Aσ la formule obtenue en appliquant la substitution σ aux variables de A. Exemple de problème : soit la formule ∃Y different(X, Y ). La substitution X → Y donnera la formule ∃Y different(Y, Y ), qui a visiblement un sens très différent de la précédente. Pour éviter ce problème, on ne n’autorise pas de variables liées dans les valeurs données par les substitutions. En revanche, (∃Y different(X, Y ))[X ← p(X, Q)] donne (∃Y different(p(X, Q), Y )). Si σ et φ sont des substitutions, σφ note la substitution obtenue en appliquant d’abord σ et ensuite φ (notation différente de celle de la composition des fonctions). 8.2 Unification de variables Un unificateur est une substitution qui permettra de rendre deux formules égales. Cette opération sera utilisée dans les démonstrations, et en particulier pour le langage prolog. Si nous savons que – contient(X, cons(X, L)) – et (contient(X, L) → contient(X, cons(A, L)))) Et que nous voulons prouver que contient(5, cons(2, cons(5, vide))) est vraie, il nous faut identifier X à 5 et L à cons(2, cons(5, vide))) Définition : σ est un unificateur des formules A et B si Aσ et Bσ sont égales (à un renommage des variables liées près). Par exemple, si A = ∃Y p(Z, W, Y ) et B = ∃Kp(A, A, K), alors – σ1 = [Z ← f (m), W ← f (m), A ← f (m)] est un unificateur. – σ2 = [Z ← A, W ← A] en est un autre. On voit bien que σ2 est meilleur que le premier ; en effet, il est plus général. On peut le formaliser en disant qu’il existe une substitution φ telle que σ1 = σ2 φ (en l’occurrence, φ = [A ← f (m)]). On peut démontrer l’existence de l’unificateur le plus général de deux formules. Il n’est pas unique, mais il est plus général que tous les autres unificateurs, au sens donné ci-dessus. On décrira par la suite des algorithmes permettant d’unifier deux formules. 9 9 Exercices Pour raisonner sur des programmes concernant les tableaux, on se dote d’une fonction case/2, dont le premier argument est le nom d’un tableau (t, par exemple), et le second est l’indice de la case. En supposant que le tableau t est de taille n, et en utilisant la logique des prédicats (et les symboles mathématiques usuels, comme <, >, =, qu’on supposera définis), exprimer les propriétés suivantes : – le tableau t contient la valeur a ; – m est le maximum des élément du tableau t ; – le tableau t est trié. Un exemple en prolog : le prédicat contient. contient(X, cons(X,L)). contient(X, cons(A,L)):- contient(X,L). Traduction de chacune des règles en logique des prédicats : – ∀X∀Lcontient(X, cons(X, L)) – ∀X∀A∀L(contient(X, L) → contient(X, cons(A, L)))) – (en réalité, le programme prolog correspond à ∀X∀L contient(X, L) ↔(∃L0(L = cons(X, L0))) ∨ (∃A∃L0(L = cons(A, L0) ∧ contient(X, L0))) 10