• Aucun résultat trouvé

Option Informatique MP/MP*, TP 2 Judicaël Courant 2 novembre 2015

N/A
N/A
Protected

Academic year: 2022

Partager "Option Informatique MP/MP*, TP 2 Judicaël Courant 2 novembre 2015"

Copied!
4
0
0

Texte intégral

(1)

1

Option Informatique MP/MP*, TP 2

Judicaël Courant 2 novembre 2015

Le but de cet exercice est de réaliser un outil permettant de tester la satisfiabilité de formules en forme normale conjonctive.

À permutation près et suppression des clauses en doublon, une formule en forme normale conjonc- tive peut être représentée comme un simple ensemble de clauses. Dans la suite, on s’intéressera donc à des ensembles de clauses qu’on représentera en Caml par des listes (tout en s’autorisant à tout moment à réordonner les listes, l’ordre relatif des éléments ne nous intéressant pas). On dira qu’un ensemble ou une liste de clauses est satisfiable si leur conjonction l’est.

Étant donné un atome𝑎et une clause 𝐶 = l1∨ … ∨ lu�, on dit que 𝑎apparaît positivementdans 𝐶 si 𝑎 est l’un des lu� et que 𝑎 apparaît négativement dans 𝐶 si ¬𝑎 est l’un des lu�. On notera pos(C) l’ensemble des atomes apparaissant positivement dans 𝐶 et neg(C)l’ensemble de ceux y apparaissant négativement.

On généralise cette notion aux ensembles de clauses (ou aux formes normales conjonctives si l’on préfère) : on dit qu’un atome apparaît positivement (négativement) dans un ensemble de clauses𝐸 s’il apparaît positivement (resp. négativement) dans l’une de ces clauses et on notepos(E) (resp.

neg(E)) l’ensemble des atomes apparaissant positivement (resp. négativement) dans𝐸.

À permutation près des littéraux et suppression des éventuels doublons, une clause𝐶est déterminée de façon unique par la donnée du couple(pos(C), neg(C)). Plus précisément, si 𝑎1, …,𝑎u� sont les éléments depos(C)et𝑏1,…,𝑏u� sont ceux deneg(C), on a

𝐶 ≡ 𝑏1∧ … ∧ 𝑏u� ⇒ 𝑎1∨ … ∨ 𝑎u�

Cela nous conduit à représenter les clauses comme des couples d’ensembles d’atomes.

⟨resolution.ml⟩≡

type atome == string;;

type clause = {

p: atome list; (* atomes apparaissant positivement *) n: atome list; (* atomes apparaissant négativement *) };;

type clauses = { liste: clause list; };;

(2)

2

On rappelle qu’on peut utiliser la bibliothèque Caml et notamment le modulelist.

Pour éviter les doublons, on mettra toujours les atomes dans le même ordre dans les clauses et on supprimera tout doublon. Pour cela, on utilisera les fonctions suivantes :

⟨resolution.ml⟩+≡

let trie l = sort__sort (fun x y -> x <= y) l;;

(* enleve les valeurs identiques successives d'une liste Précondition: l est triée (peu importe pour quel ordre).

*)let rec enleve_doublons l = match l with

| [] -> []

| [x] -> [x]

| x:: y:: r -> if x = y then enleve_doublons (y::r) else x::enleve_doublons (y::r)

;;

(* met sous forme canonique un ensemble. Pour cela, le trie puis enlève les doublons: *)

let ensemble l = enleve_doublons (trie l);;

(* construit une clause en s'assurant que celle-ci est bien sous forme canonique. *)

let cons_clause p n = { p = ensemble p; n = ensemble n; };;

(* met sous forme canonique une clause qui aurait été mal construite *) let canonise_clause { p = p; n = n; } = cons_clause p n;;

(* construit un ensemble de clauses en s'assurant que chaque clause est bien sous forme canonique et que l'ensemble est bien lui-même trié, sans doublon. *)

let cons_clauses cl = { liste = (ensemble (map canonise_clause cl)) };;

Par la suite, on s’interdit de construire directement (avec la syntaxe{ liste = … }) des éléments de typeclauses: on utilisera la fonctioncons_clauses : clause list -> clausespour cela.

De même, on s’interdit de construire directement des éléments de type clause: on utilisera la fonctioncons_clause : atome list -> atome list -> clausepour cela.

On utilisera les fonctions suivantes pour afficher des clauses :

⟨resolution.ml⟩+≡

let print_atomes l =

do_list (fun a -> print_string " "; print_string a) l;;

let print_clause c = print_string "(conj";

print_atomes c.p;

print_string ") => (disj";

print_atomes c.n;

print_string ")\n"

;;

let print_clauses cl =

do_list (fun c -> print_clause c) cl.liste;

print_string "\n"

;;

(3)

3 Méthode

Q1 Écrire une fonctionest_tautologie : clause -> bool disant si une clause est une tautologie (on commencera par voir à quelle condition c’est le cas).

Q2 Écrire une fonction supprime_clauses_tautologiques : clauses -> clauses supprimant les clauses tautologiques d’une forme normale conjonctive. Après application de cette opération à une fnc𝜙, obtient-on une fnc équisatisfiable à𝜙?

Étant donné deux clauses𝐶1 et𝐶2 et un atome𝑎apparaissant positivement dans𝐶1et négative- ment dans𝐶2, on appellerésolvant de𝐶1 et𝐶2 par coupure avec𝑎la clause𝐶3 définie par

pos(C3) = (pos(C1) ∖ {a}) ∪ pos(C2) neg(C3) = (neg(C2) ∖ {a}) ∪ neg(C1)

Q3 Montrer que si une interprétation satisfait𝐶1et𝐶2, alors elle satisfait son résolvantres(C1, C2, a).

Étant donné un atome𝑎et un ensemble𝐸 de clauses ne comportant aucune tautologie, on peut partitionner cet ensemble en trois ensembles 𝑃, 𝑁 et 𝑂 respectivement celui des clauses où 𝑎 apparaît de façon positive, celui des clauses où𝑎apparaît de façon négative et celui des clauses où 𝑎n’apparaît pas.

L’ensembleobtenu à partir de𝐸 par un pas de résolution sur𝑎est l’ensemble𝐸 défini par 𝐸= 𝑂 ∪ {res(C1, C2, a)|(C1, C2) ∈ P × N}

Q4 Montrer que l’atome𝑎n’apparaît pas dans𝐸.

Q5 Montrer que𝐸est équisatisfiable à𝐸. On pourra montrer tout d’abord que la satisfiabilité de𝐸 entraîne celle de𝐸, puis que si on dispose d’une interprétation𝜌des variables de𝐸la satisfaisant, l’une des deux interprétations 𝜌u� et 𝜌u� obtenues en étendant 𝜌 à la variable 𝑎 en lui donnant respectivement la valeur𝟎et la valeur𝟏doit satisfaire𝐸.

Q6 Écrire une fonctionpartionne_clauses : atome -> clauses -> clauses * clauses * clauses dont l’application à un atome𝑎et à l’ensemble𝐸 retourne le triplet(𝑃 , 𝑁, 𝑂).

Q7 Écrire une fonctionresolution : atome -> clauses -> clausescalculant l’ensemble des clauses obtenu à partir d’un ensemble de clauses𝐸 par un pas de résolution sur un atome𝑎.

Q8 Écrire une fonctionsatisfiable : clauses -> booltestant la satisfiabilité d’un ensemble de clauses𝐸en suivant l’algorithme suivant :

− supprimer les clauses tautologiques de𝐸;

− si l’ensemble restant est vide, c’est terminé : l’ensemble des clauses est satisfiable ;

− s’il n’est pas vide, considérer sa première clause ; s’il s’agit de la clause vide, alors c’est terminé : 𝐸 est insatisfiable ;

− sinon, prendre un atome apparaissant dans cette clause et effectuer un pas de résolution sur cet atome ;

− recommencer.

Q9 Justifier que cet algorithme termine.

Q10 Justifier brièvement sa correction.

(4)

4 Application

On considère un club privé écossais possédant des règles très strictes : 1. Tout membre non écossais porte des chaussettes rouges ;

2. Tout membre porte un kilt ou ne porte pas des chaussettes rouges ; 3. Les membres mariés ne sortent pas le dimanche ;

4. Un membre sort le dimanche si et seulement si il est écossais.

5. Tout membre qui porte un kilt est marié et écossais.

6. Tout membre écossais porte un kilt.

Q11 Représenter chacune des règles par une formule du calcul propositionnel, en utilisant une variable 𝐸 pour le fait qu’un membre est écossais, 𝑅 le fait qu’il porte des chaussettes rouges, 𝐾 le fait qu’il porte un kilt,𝑀 le fait qu’il est marié, 𝐷le fait qu’il sort le dimanche.

Q12 Donnez, pour chacune de ces règles, une formule en forme normale conjonctive qui lui est équiva- lente.

Q13 Utilisez le programme que vous avez écrit précédemment pour tester si les conditions données sont satisfiables.

Références

Documents relatifs

I Beaucoup de problèmes concernent la satisfaisabilité d'une formule en CNF (ou facilement transformée en CNF):.. I Problème de

On généralise cette notion aux ensembles de clauses (ou aux formes normales conjonctives si l’on préfère) : on dit qu’un atome apparaît positivement (négativement) dans un

(ii) ⇒ (i) Si G est connexe d’ensemble d’arêtes minimal, alors il ne peut posséder de cycle : sinon en enlevant une arête d’un cycle, on obtient un graphe avec un

Écrire une fonction coaccessibles : afd -&gt; int list retournant la liste des états coaccessibles de l’automate qui lui est passé en argument. Q14 On dit qu’un automate est

Écrire une fonction inverse(s) prenant en argument la représentation d’une

Écrire une fonction fusion(t1, t2) prenant en argument deux tableaux t1 et t2 de nombres supposés triés 1 de longueurs

Vous trouverez dans le fichier lance_tests.py les commandes permettant de générer les douze combinaisons possibles (quatre méthodes pour générer un tableau, trois fonctions de

Écrire une fonction size : 'a abr -&gt; int de complexité constante retournant la