Adloun

Logique propositionnelle

Cours complet · informatique (MP2I/MPI), chapitre 20 · MP2I et MPI

Travailler ce chapitre sur Adloun Exercices corrigés de ce chapitre

20.1 Séparer ce qu'on écrit de ce que cela veut dire

Le programme assigne à ce chapitre un objectif qu'il faut prendre au mot : « familiariser progressivement les étudiants avec la différence entre syntaxe et sémantique ». Cette distinction est l'une des plus fécondes de l'informatique, et elle sera reprise telle quelle au chapitre chap:automates — où une expression régulière (syntaxe) dénotera un langage (sémantique) — et au chapitre chap:deduction, où l'on opposera à .

SyntaxeSémantique
Ce que c'estune suite de symbolesune valeur de vérité
Ce qu'on manipuleun arbreune fonction des valuations
Deux formules égales simêmes arbresmêmes tables de vérité

Le second usage de ce chapitre est plus concret : le programme veut « donner le vocabulaire permettant de modéliser une grande variété de situations (satisfaction de contraintes, planification, diagnostic, vérification de modèles) ». Une formule logique est un format d'entrée universel — et sat, le problème de sa satisfiabilité, sera au cœur du chapitre chap:decidabilite.

20.2 Syntaxe

Définition 20.1Formule propositionnelle

On se donne un ensemble de variables propositionnelles L'ensemble des formules est le plus petit ensemble tel que :

et de même pour . Les notations sont celles que le programme fixe : . L'arité d'un connecteur est son nombre d'arguments : pour , pour les autres.

ImportantUne formule est une donnée informatique, et c'est un arbre

Le programme est explicite deux fois : « les formules sont des données informatiques », et « on implémente uniquement les formules propositionnelles sous forme d'arbres ».


type formule =
  | Var of string
  | Non of formule
  | Et of formule * formule
  | Ou of formule * formule
  | Implique of formule * formule

C'est le type inductif du chapitre chap:induction, et tout ce qui y a été démontré s'applique : les fonctions sur les formules terminent par l'ordre induit, et se prouvent par induction structurelle. Rien n'est à réapprendre.

Définition 20.2Sous-formule, taille, hauteur

Les sous-formules de sont elle-même et, récursivement, celles de ses arguments — ce sont exactement les sous-arbres. La taille est le nombre de nœuds, la hauteur celle de l'arbre.


let rec taille = function
  | Var _ -> 1
  | Non f -> 1 + taille f
  | Et (a, b) | Ou (a, b) | Implique (a, b) -> 1 + taille a + taille b
iRemarqueLe parenthésage n'est pas dans l'arbre

Écrire est ambigu ; l'arbre, lui, ne l'est jamais. Les parenthèses ne servent qu'à écrire une formule en une ligne — et le programme demande de « faire le lien entre les écritures d'une formule comme mot et les parcours d'arbres » : l'écriture infixe parenthésée est le parcours infixe, la notation polonaise le parcours préfixe. C'est exactement le chapitre chap:arbres, et l'analyse syntaxique du chapitre chap:grammaires fera le trajet inverse.

20.2.1 Quantificateurs, variables libres et liées

Définition 20.3Portée, variables libres et liées

Les quantificateurs et introduisent une notion de portée : dans , la portée de est . Une occurrence de dans cette portée est liée ; une occurrence hors de toute portée d'un quantificateur sur est libre.

ImportantC'est exactement la portée des variables d'un programme

Le programme le dit : ce sont des « notions que l'on retrouve dans la pratique de la programmation ». Dans let f x = x + a, le est lié par fun, le est libre et va chercher sa valeur ailleurs. Renommer un lié ne change rien ; renommer un libre change tout. C'est le même phénomène, et le même piège.

iRemarqueCe que le programme écarte

« On ne soulève aucune difficulté technique sur la substitution. L'unification est hors programme. » Et la sémantique n'est présentée que pour des formules sans quantificateurs — « par souci d'éviter trop de technicité ». Les quantificateurs reviendront au chapitre chap:deduction, par leurs règles d'inférence seulement.

20.3 Sémantique

Définition 20.4Valuation, valeur de vérité

Une valuation affecte à chaque variable une valeur de vérité, notée ou . La valeur se calcule alors par induction sur la structure :


(* Valeur de f sous la valuation v. Précondition : v est définie sur toutes
   les variables de f. La structure de la fonction EST celle du type. *)
let rec evalue v = function
  | Var p -> v p
  | Non f -> not (evalue v f)
  | Et (a, b) -> evalue v a && evalue v b
  | Ou (a, b) -> evalue v a || evalue v b
  | Implique (a, b) -> (not (evalue v a)) || evalue v b
Attention vaut , et ce n'est pas une bizarrerie

Les deux dernières lignes de la colonne déconcertent : une implication de prémisse fausse est vraie. C'est pourtant le seul choix cohérent. « Si est divisible par , alors est pair » doit être vraie pour tout , y compris , où prémisse et conclusion sont toutes deux fausses.

Retenez la lecture opérationnelle : n'est fausse que dans un seul cas, celui où l'on a promis en ayant , et où n'est pas là.

Définition 20.5Modèle, satisfiabilité, tautologie, antilogie
  • est un modèle de si ;
  • est satisfiable si elle admet au moins un modèle ;
  • est une tautologie si toute valuation en est un modèle ; on écrit ;
  • est une antilogie si aucune valuation n'en est un modèle.

Le programme autorise à noter une formule tautologique et une antilogie.

Proposition 20.6Le lien entre les trois

est une tautologie est une antilogie n'est pas satisfiable.

ImportantCette équivalence est la porte d'entrée de sat

Elle transforme « prouver que est toujours vraie » en « montrer que n'a aucun modèle ». Autrement dit : tout problème de validité se ramène à sat. C'est ce qui donne à sat son statut, et c'est aussi ce qui rend le chapitre chap:deduction nécessaire — car chercher un modèle coûte .

Définition 20.7Équivalence et conséquence logique
  • si les deux ont la même valeur sous toute valuation ;
  • (conséquence logique) si tout modèle de est modèle de . Plus généralement, pour un ensemble de formules.

Le programme précise : « la compacité est hors programme ».

Attention est sémantique, est syntaxique

et sont équivalentes et ne sont pas égales : leurs arbres diffèrent. Un programme qui teste l'égalité structurelle de deux formules ne teste pas leur équivalence — et tester l'équivalence coûte, dans l'état des connaissances, un temps exponentiel.

Proposition 20.8Les équivalences que le programme nomme

Démonstration (Pour la première loi de De Morgan)

Table de vérité, quatre lignes.

Les deux dernières colonnes coïncident : les formules sont équivalentes.

20.4 Formes normales

Définition 20.9Littéral, clause, formes normales

Un littéral est une variable ou sa négation. Une formule est en :

  • forme normale conjonctive (fnc) si elle est une conjonction de clauses, chacune étant une disjonction de littéraux : ;
  • forme normale disjonctive (fnd) si c'est une disjonction de conjonctions de littéraux.

Le programme suggère de les représenter « comme des listes de listes de littéraux » — ce qui donne, en OCaml, le type (int * bool) list list.

Méthode : Mettre sous forme normale

Trois étapes, dans cet ordre :

  • éliminer et par ;
  • pousser les négations vers les variables par De Morgan et ;
  • distribuer — sur pour la fnc, sur pour la fnd.
ImportantLe lien entre fnd complète et table de vérité

Le programme demande ce lien, et il est direct : chaque ligne de la table de vérité où la formule vaut donne une conjonction de la fnd. Pour , les lignes vraies sont et :

Toute formule admet donc une fnd — et le procédé le montre — mais cette fnd a autant de termes que la table a de lignes vraies, donc jusqu'à .

AttentionLa mise en forme normale peut faire exploser la taille

Le programme demande un « exemple de formule dont la taille des formes normales est exponentiellement plus grande ». En voici un, et il est bref :

Elle est déjà en fnd et sa taille est linéaire. Sa fnc, en revanche, s'obtient en distribuant : il faut choisir un littéral dans chacun des groupes, ce qui donne

Pour : une formule de variables devient un million de clauses. Une transformation qui préserve la sémantique peut détruire l'efficacité, et c'est pourquoi les solveurs réels emploient des transformations qui ajoutent des variables au lieu de distribuer.

20.5 Le problème sat

Définition 20.10sat et -sat

sat : étant donné une formule en fnc, admet-elle un modèle ? -sat : même question quand chaque clause a au plus littéraux.

-sat se résout en temps linéaire — le chapitre chap:graphes-avances le montrera, par les composantes fortement connexes. -sat est np-complet (chapitre chap:decidabilite). Le saut se fait donc entre et .

Méthode : L'algorithme de Quine

C'est un retour sur trace (chapitre chap:exploration) sur les valuations : on choisit une variable, on essaie , on simplifie, on recommence ; en cas d'échec, on essaie .


(* Vrai si f est satisfiable. Précondition : aucune. Complexité : O(2^n · |f|). *)
let rec quine f =
  match variables f with
  | [] -> evalue (fun _ -> false) f          (* plus de variable : on évalue *)
  | p :: _ ->
      quine (substituer f p true) || quine (substituer f p false)

Ce qui fait toute son efficacité pratique : la simplification. Substituer dans une fnc supprime toutes les clauses contenant , et retire des autres. Une clause devenue vide est fausse : on remonte immédiatement, sans explorer les valuations restantes. C'est exactement l'élagage du chapitre chap:exploration, et c'est ce qui rend l'algorithme utilisable là où serait rédhibitoire.

Exemple 20.11Modéliser la coloration d'un graphe en sat

Le programme demande d'« incarner sat par la modélisation d'un problème (par exemple la coloration des sommets d'un graphe) ». Colorier avec couleurs sans que deux voisins partagent la leur :

Variables : pour « le sommet porte la couleur », soit variables.

Clauses :

  • chaque sommet a au moins une couleur : pour chaque ;
  • chaque sommet a au plus une couleur : pour ;
  • deux voisins diffèrent : pour chaque arête et chaque .

La formule est satisfiable si et seulement si le graphe est -coloriable, et un modèle donne la coloration. C'est le schéma de toute modélisation par sat : on encode les choix en variables, les contraintes en clauses, et l'on délègue la recherche.

ImportantPourquoi sat plutôt qu'un algorithme sur mesure

Parce que les solveurs sat modernes traitent couramment des instances à des millions de clauses, et que l'on gagne à écrire des contraintes plutôt qu'un algorithme. C'est le paradigme déclaratif du chapitre chap:algo-prog : on dit ce qu'on veut, un moteur cherche. Le prix à payer est le pire cas exponentiel — que le chapitre chap:decidabilite justifiera.

20.6 Ce qu'il faut retenir

ImportantLogique propositionnelle : cinq points
  • Une formule est un arbre — un type inductif —, et tout le chapitre chap:induction s'y applique.
  • Syntaxe (, les arbres) et sémantique (, les tables) ne se confondent jamais.
  • Tautologie, satisfiabilité et antilogie se ramènent l'une à l'autre par la négation — et donc à sat.
  • Toute formule a une fnd lisible dans sa table de vérité, mais la mise en forme normale peut faire passer une taille linéaire à .
  • Quine est un retour sur trace, et c'est la simplification qui le rend utilisable. -sat est linéaire, -sat est np-complet.

Continuer sur Adloun : animation, QCM, fiches, exercices