Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
COURS DE
Programmation
logique et
contrainte
Enseignant : Dr. AOUN Oussama
Langages fonctionnels
tout est fonction
– syntaxe dépouillée
– base mathématique forte : λ-calcul
contrôle délégué à l’interprète
– utilisation intensive de la récursivité
exemples : Lisp, Scheme, Haskell, …
Une nouvelle classe : PROgrammation en LOGique
PROgrammation en LOGique
tout est logique
syntaxe simple et dépouillée
base théorique : calcul des prédicats
encore plus de contrôle donné à la machine
récursion
non déterminisme
exemple : Prolog
Objectifs
Utiliser PROLOG
On définit :
Les propositions : a, b, c, …
Les constantes : V et F
Les connecteurs :
∧ (conjonction)
∨ (disjonction)
¬ (négation)
⊃ (implication)
7
CONSTRUCTION D’UNE FORMULE
Si
a et b sont des formules, alors ¬a,
a∨b, a∧b, a⊃b sont des formules
8
LOGIQUE DES PROPOSITIONS
SÉMANTIQUE
Les formules sont interprétées dans {V,F}
On définit l’interprétation associée à chaque
connecteur grâce aux tables de vérité
9
TABLES DE VÉRITÉ DES CONNECTEURS
V V F V V V
V F F F V F
F V V F V V
F F V F F V
10
PROPRIÉTÉS DES FORMULES
11
DRESSONS LA TABLE DE VÉRITÉ
12
RÈGLES DE TRANSFORMATION (1)
13
RÈGLES DE TRANSFORMATION (2)
Lois de De Morgan :
• ¬(a∨b) ⇔ ¬a ∧ ¬b
• ¬(a∧b) ⇔ ¬a ∨ ¬b
Commutativité et associativité de ∨ et ∧
Distributivité de ∨ par rapport à ∧ et de ∧ par
rapport à ∨
X∧(X∨Y) = X, X∨(X∧Y) = X (absorption)
X∨(¬X∧Y) = X∨Y
14
UNE ÉNIGME POLICIÈRE
16
DÉFINITIONS
Terme :
Une variable est un terme
Une constante est un terme
Si t1, t2, …, tn sont des termes,
alors f(t1,t2,…,tn) est un terme
Exemple : fils(x)
Atome :
Si t1, t2, …, tn sont des termes, et p un prédicat,
alors p(t1,t2,…,tn) est un atome
Exemple : pere(x,y)
17
CONSTRUCTION D’UNE FORMULE
∀ x¬A ⇔ ¬ ∃xA
∀ xA ⇔¬ ∃x¬A
Comment déterminer qu’une formule
est valide ?
19
DÉFINITIONS
Littéral
Un atome est un littéral (positif)
La négation d’un atome est un littéral (négatif)
Une clause est une formule qui a la forme d’une
disjonction de littéraux
Exemple : P(x,y) ∨ ¬Q(z)
Une clause concrète est une clause sans
variable
Une clause de Horn est une clause comportant
au plus un littéral positif
On peut toujours transformer une formule en un
ensemble (conjonction) de clauses
20
PRINCIPE DE RÉSOLUTION
21
JUSTIFICATION
(P∨A)∧(¬P∨B)
= (P∧B)∨(A∧¬P) ∨(A∧B)
(P∨A)∧(¬P∨B) ∧(A∨B)
= ((P∧B)∨(A∧¬P) ∨(A∧B))∧(A∨B)
= (A∧P∧B)∨(A∧¬P)∨(A∧B)∨(P∧B)∨(A∧¬P∧B)∨(A∧B)
= (A∧B) ∨(A∧¬P) ∨(P∧B)
22
CAS PARTICULIERS
23
UTILISATION
24
UNIFICATION
25
RÉFUTATION PAR RÉSOLUTION
26
ENSEM
COURS DE
Programmation
logique et
contrainte
Enseignant : Dr. AOUN Oussama
Bibliographie
L. Sterling, E. Shapiro, L’art de Prolog, Masson
Clocksin, Mellish, Programmer en Prolog, Eyrolles
LE LANGAGE PROLOG
Programmation déclarative :
L’utilisateur définit une base de connaissances
L’interpréteur Prolog utilise cette base de
connaissances pour répondre à des questions
4
CONSTANTES ET VARIABLES
Constantes
Nombres : 12, 3.5
Atomes
Chaînes de caractères commençant par une minuscule
Chaînes de caractères entre " "
Liste vide []
Variables
Chaînes de caractères commençant par une majuscule
Chaînes de caractères commençant par _
La variable « indéterminée » : _
5
TROIS SORTES DE CONNAISSANCES :
FAITS, RÈGLES, QUESTIONS
Univers PROLOG
Syntaxe de PROLOG
Considérons l’énoncé
Socrate est un homme
Tout homme est mortel
Socrate est-il mortel ?
?- mortel(socrate).
Le langage
La famille
masculin(tom). % tom est de sexe masculin
masculin(tim).
masculin(bob).
masculin(jim). % «paquet» de clauses
feminin(pam).
feminin(liz).
feminin(ann).
feminin(pat).
enfant(bob,pam).
enfant(bob,tom).
enfant(liz,tom).
enfant(ann,bob).
enfant(pat,bob).
enfant(tim,liz).
enfant(jim,pat).
Le langage
masculin(tom).
masculin(tim).
masculin(bob).
masculin(jim).
enfant(bob,pam).
enfant(bob,tom).
enfant(liz,tom).
Est-ce que pat est un enfant de bob ? enfant(ann,bob).
enfant(pat,bob).
enfant(tim,liz).
enfant(jim,pat).
?- enfant(pat,bob).
Yes
?- enfant(X,tom).
X = bob ;
X = liz ;
Règles Prolog
1
Constantes vs Variables
1
Variables
1
Variable anonyme
Programme P
P1 : Père (charlie, david).
P2 : pere(henri, charlie).
P3 : gpere(X,Y) :- pere(X,Z), pere(Z,Y).
Appel du programme P
A: gpere(X,Y).
Réponse : X=henri, Y=david
1
7
GRAPHE DE RÉSOLUTION
A : ¬gpere(X,Y) P3 :
¬pere(X1,Z1)¬pere(Z1,Y1)gpere(X1,Y1)
X|X1
Y|Y1
P1 : pere(charlie, david)
david|Y
¬pere(david, Y)
échec : retour arrière succès de la réfutation
1
8
INTERPRÉTATION PROCÉDURALE : ARBRE ET-OU
gpere(X,Y)
P3
et
pere(X,Z) pere(Z,Y)
ou pere(david,Y) pere(charlie,Y)
P1 P2
ou ou
P1 P2 P1 P2
X=charlie X=henri
Z=david Z=charlie
échec échec Y=david
succès
1
9
MON PROGRAMME (1)
pere(charlie,david).
pere(henri,charlie).
gpere(X,Y) :- pere(X,Z), pere(Z,Y).
lirispc1$ swiprolog
Welcome to SWI-Prolog (Version 3.3.0)
Copyright (c) 1993-1999 University of Amsterdam.
All rights reserved.
For help, use ?- help(Topic). or ?-apropos(Word).
?- [pere].
% pere compiled 0.00 sec, 824 bytes
true.
?- listing.
pere(charlie, david).
pere(henri, charlie).
gpere(A, B) :-
pere(A, C),
pere(C, B).
true. 2
0
MON PROGRAMME (2)
?- pere(charlie,david). ?- gpere(x,y).
true. false.
?- pere(charlie,henri). ?- gpere(X,Y).
false. X = henri
?- pere(X,Y). Y = david
X = charlie
Y = david ?- gpere(henri,X).
true. X = david
?- pere(X,Y). true.
X = charlie ?- halt.
Y = david ; lirispc1$
X = henri
Y = charlie
21
ORDRE DES RÉPONSES
23
L’ÉNIGME POLICIÈRE EN PROLOG
24
L’ÉNIGME POLICIÈRE EN PROLOG
Hypothèse
secretaire_dit_vrai.
Pour la démonstration, on pose la requête :
ingenieur_ment.
26
Commentaires dans un programme
Prolog
2
7
Structures de données
2
8
Chaines de caractères
2
9
ENSEM
COURS DE
Programmation
logique et
contrainte
Enseignant : Dr. AOUN Oussama
2
Les expressions arithmétiques
3
Expressions arithmétiques
Opérations habituelles :
addition (+), soustraction (-),
multiplication (*), division entière (//),
division flottante (/), modulo (mod), puissance(^)
Fonctions mathématiques prédéfinies :
abs(X), log(X), sqrt(X), exp(X), sign(X), random(X), sin(X),
cos(X), tan(X), min(X,Y), max(X,Y), pi, etc.
Exemples :
?- X is 2^20, Y is exp(1) ?- X is sin(pi/2), Y is cos(pi).
X = 1048576, X = 1.0,
Y = 2.718281828459045, Y = -1.0.
?- Z is random(100)+100. ?- S1 is sign(20), S2 is sign(-12).
Z = 151. S1 = 1, 7
S2 = -1.
Expressions arithmétiques
X Y
8
X
Les expressions arithmétiques
6
Les prédicats de comparaison
var, nonvar
?- var(X). ?- var(X), nonvar(3).
true. true.
?- X=2,var(X). ?- nonvar(X).
false. false.
11
Les opérations d’Entrée / Sortie
12
Les entrées-sorties
13
Affichage de termes
write(1+2)
affiche 1+2
write(X)
Si X n’est pas instanciée, affiche X sous la forme _2451 qui
est le nom interne de la variable.
Affiche la valeur de X si X est instanciée.
nl permet de passer à la ligne (nl/0)
tab(N) affiche N espaces (tab/1)
Exemple :
?- write(3+4), nl, tab(10), write("hello !").
3+4
hello !
true. 14
Affichage de termes
16
Affichage d’un caractère
Lecture de termes :
read/1 admet n’importe quel terme en argument.
read lit un terme au clavier et l’unifie avec son argument. Le
terme lu doit être obligatoirement suivi d’un point. Certains
interprètes Prolog affichent un signe d’invite lorsque le
prédicat read/1 est utilisé, c’est le cas de Swi-Prolog.
Exemple :
?- read(X).
|: a(1,2).
X = a(1,2).
?- read(A).
|: toto.
A = toto.
?- read(A).
|: "toto".
A = "toto". 19
Saisie de données
20
Fichiers
ecrire(T) :-
open('a.pl', append, Flux), /* ouverture du fichier a.pl */
write(Flux, T), nl(Flux), /* enregistrement de T */
close(Flux). /* fermeture du fichier */
23
SYMBOLES FONCTIONNELS
25
PROGRAMMATION RÉCURSIVE
Exemple : factorielle
factorielle(1) = 1 (Cas d’arrêt)
factorielle(n) = n * factorielle(n-1) si n≠1
Appel récursif
En Prolog, un prédicat est récursif si au moins une de
26
ses règles associées réfère à lui-même.
Intérêt de la récursion
?- p.
?- descend(marie,paul).
39
ERROR: Stack limit (1.0Gb) exceeded
Exercice
Il faut :
Choisir sur quoi faire l’appel récursif
Choisir comment passer du résultat de l’appel récursif
au résultat que l’on cherche (relation de récurrence)
Choisir le(s) cas d’arrêt
30
BOUCLAGE
maries(jean, sophie). maries(jean, sophie).
maries(philippe, maries(philippe,
stephanie). stephanie).
maries(A, B) :- sont_maries(A, B) :-
maries(B, A). maries(A, B).
sont_maries(A, B) :-
?- maries(jean,sophie). maries(B, A).
true.
?- maries(sophie,jean).
true.
?- maries(X,Y).
?- sont_maries(X,Y).
X = jean
X = jean
Y = sophie ;
Y = sophie ;
X = philippe
X = philippe
Y = stephanie ;
Y = stephanie ;
X = sophie
X = sophie
Y = jean ;
Y = jean ;
X = stephanie
X = stephanie
Y = philippe ;
Y = philippe ;
false.
X = jean
?-
Y = sophie ;
19
...
UN EXEMPLE : FACTORIELLE (1)
?- trace, fact(3,R).
fact(1, 1). Call: (8) fact(3, _G237) ? creep
^ Call: (9) _G308 is 3-1 ? creep
fact(N, R) :- ^ Exit: (9) 2 is 3-1 ? creep
Nm1 is N-1, Call: (9) fact(2, _G306) ? creep
^ Call: (10) _G311 is 2-1 ? creep
fact(Nm1, Rnm1), ^ Exit: (10) 1is 2-1 ? creep
R is Rnm1*N. Call: (10) fact(1, _G309) ? creep
Exit: (10) fact(1, 1) ? creep
^ Call: (10) _G314 is 2*1 ? creep
^ Exit: (10)2is 2*1 ? creep
Exit: (9) fact(2, 2) ? creep
^ Call: (9) _G237 is 3*2 ? creep
?- fact(5,R). ^ Exit: (9) 6 is 3*2 ? creep
R = 120 ; Exit: (8) fact(3, 6) ? creep
R = 6 ;
ERROR: Out of local Redo: (10) fact(1, _G309) ? creep
stack ^ Call: (11) _G314 is 1-1 ? creep
^ Exit: (11) 0 is 1-1 ? creep
Exception: (36,276) Call: (11) fact(0, _G312) ? creep
_G4661 is-36263-1 ? ^ Call: (12) _G317 is 0-1 ? creep
^ Exit: (12) -1 is 0-1 ? creep
abort Call: (12) fact(-1, _G315) ? creep
% Execution Aborted ^ Call: (13) _G320 is-1-1 ? creep
^ Exit: (13) -2 is-1-1 ? creep
21
Il faut faire des cas exclusifs
UN EXEMPLE : FACTORIELLE (2)
fact(1, 1).
fact(N, R) :- ?- 5 is X-1.
fact(Nm1, Rnm1), ERROR: Arguments
are not
Nm1 is N-1, sufficiently
R is Rnm1*N. instantiated
% Execution
Aborted
?- fact(3,R).
?- plus(3,2,5).
ERROR: Arguments are not
sufficiently instantiated true.
^ Exception: (9) 1 is ?- plus(X,2,5).
_G241-1 ? creep X = 3
Exception: (8) true.
fact(_G241, _G255) ? creep
Exception: (7) fact(3,
_G195) ? creep
% Execution Aborted
33
UNE FACTORIELLE AVEC ACCUMULATEUR
^ Call: (9) _G308 is 3-1 ? creep
fact(N,R) :- fact(N,1,R).
^ Exit: (9) 2 is 3-1 ? creep
Call: (9) fact(2, 3, _G234) ?
fact(1,R,R). creep
fact(N,I,R) :- N>1, Call: (10) 2>1 ? creep
Nm1 is N-1, Exit: (10) 2>1 ? creep
NewI is N*I, ^ Call: (10) _G311 is 3*2 ?
fact(Nm1,NewI,R). creep
^ Exit: (10) 6 is 3*2 ? creep
^ Call: (10) _G314 is 2-1 ?
?- trace, fact(3,N). creep
Call: (7) fact(3, _G234) ? ^ Exit: (10) 1 is 2-1 ? creep
creep Call: (10) fact(1, 6, _G234) ?
Call: (8) fact(3, 1, _G234) creep
? creep Call: (11) 1>1 ? creep
Call: (9) 3>1 ? creep Fail: (11) 1>1 ? creep
Exit: (9) 3>1 ? creep Redo: (10) fact(1, 6, _G234) ?
^ Call: (9) _G305 is 1*3 ? creep
creep Exit: (10) fact(1, 6, 6) ?
^ Exit: (9) 3 is 1*3 ? creep creep
34
N = 6
ENSEM
COURS DE
Programmation
logique et
contrainte
Enseignant : Prof. AOUN Oussama
2
Les Listes
4
Découpage Tête Queue
6
Listes et sous-listes
Liste vide : [ ]
8
EXEMPLES
9
Exercice
10
Elément d'une liste (1)
11
Elément d'une liste (2)
12
Elément d'une liste (3)
13
Accès aux éléments (1)
element_de(X, [X|_]).
element_de(X, [_|Q]) :- element_de(X, Q).
element_de(X, [X|_]).
element_de(X, [_|Q]) :- element_de(X, Q).
?- element_de(X,[artichauts, crevettes, oeufs]).
X = artichauts ;
X = crevettes ;
X = oeufs ;
false.
18
LE PRÉDICAT MEMBER
19
Parcours d’une liste
Cas de base :
parcours([],v). v = valeur associée à la liste vide
Cas général :
parcours([T|Q],R):- parcours(Q,RI), R is f(RI,T).
R est calculé à partir de RI et de T
20
SOMME DES D’UNE LISTE DE NOMBRES
ÉLÉMENTS
?- somme([1,2,3,5],N).
N = 11
Exercice
22
Solution de l'exercice
nbpairs([], 0).
nbpairs([T|Q], N) :- T mod 2 =:= 0, nbpairs(Q, N1), N is N1+1.
nbpairs([T|Q], N) :- T mod 2 =:= 1, nbpairs(Q, N).
23
UTILISATION DU PRÉDICAT APPEND
24
append : autres utilisations possibles
25
Construction d’une liste au moyen d’une
liste auxiliaire appelée « accumulateur »(2)
16
Construction d’une liste au moyen d’une liste auxiliaire
« accumulateur » (4)
17
Prédicats prédéfinis sur les listes
Quelques prédicats prédéfinis
sur les listes
Dans la documentation Prolog :
- les arguments consultés sont précédés d'un +
- les arguments élaborés sont précédés d'un -
-les arguments qui peuvent être soit consultés,
soit élaborés (suivant le sens de l'unification)
sont précédées d'un ?
Exemple : numlist(+Min, +Max, -List).
?- numlist(2,8,L).
L = [2, 3, 4, 5, 6, 7, 8]
30
Prédicats simplifiant la manipulation des listes (1)
is_list(+Terme) réussit si Terme est une liste
?- is_list([a,b,c]).
true.
length/2 permet d’obtenir la longueur d’une liste :
?- length([a,b,c],L). ?- length([a,b,c],4).
L = 3. false.
?- length(L,3).
L = [_3648, _3654, _3660].
member(?Element, ?Liste) réussit si Element s’unifie avec un élément de Liste. Prédicat
utilisé principalement pour énumérer les membres de la liste :
?- member(E,[a,b,c]). ?- member(d,[a,b,c]).
E = a ; false
E = b ; ?- member(b,[a,b,c]).
E = c. true
memberchk(?Element, ?Liste) permet de vérifier si Element appartient à Liste:
?- memberchk(d,[a,b,c]). ?- memberchk(X,[a,b,c]).
false. X = a.
?- memberchk(b,[a,b,c]).
true.
31
Prédicats simplifiant la manipulation des listes (2)
last(?Liste, ?Last) permet de sélectionner le dernier élément d’une liste.
?- last([a,b,c],X).
X = c.
nth0(?I, ?Liste, ?Elem) permet de sélectionner Elem l’élément d’indice I de Liste, lepremier
élément ayant l’indice 0 :
?- nth0(3,[a,b,c,d,e],E).
E = d.
nth0 permet aussi d’obtenir le ou les indice(s) d’un élément donné dans une liste :
?- nth0(I,[a,b,c,b,d,e],b).
I = 1 ;
I = 3
nth1(?I, ?Liste, ?Elem) fonctionne exactement comme nth0, mais l’indice du premier élément
de la liste est 1 :
?- nth1(3,[a,b,c,d,e],E). ?- nth1(I,[a,b,c,b,d,e],b).
E = c. I = 2 ;
I = 4
select(?Elem,?Liste,?Reste) fonctionne comme member mais en plus unifie Reste avec Liste
privée de Elem (permet de sélectionner un élément et le supprimer de la liste) :
?- select(b,[a,b,c,d,b,a],L). ?- select(E,[a,b,c],R).
L = [a, c, d, b, a] ; E = a, R = [b, c] ;
L = [a, b, c, d, a] ; E = b, R = [a, c] ; 21
false. E = c, R = [a, b].
Prédicats simplifiant la manipulation des listes (3)
flatten(+Liste1, -Liste2) applanit Liste1 et unifie le résultat dans Liste2 :
?- flatten([a,[[],b],[[c],d,e]],L).
L = [a, b, c, d, e].
reverse(+Liste1, -Liste2) inverse l'ordre des éléments de Liste1 et unifie le résultat dans Liste2 :
?- reverse([a, b, c, d, e],L).
L = [e, d, c, b, a].
sumlist(+Liste, -Somme) unifie Somme avec la somme de tous les éléments de Liste (numériques):
?- sumlist([3.4,12,17.2,3],S).
S = 35.6
permutation(?Liste1, ?Liste2) vrai si Liste2 est une permutation de Liste1 ; permet également d'énumérer
toutes les permutations possibles de Liste1 ou Liste2.
?- permutation([a,b,c],P). ?- permutation([a,b,c],[c,a,b]).
P = [a, b, c] ; true
P = [a, c, b] ;
P = [b, a, c] ;
P = [b, c, a] ;
P = [c, a, b] ;
P = [c, b, a] ;
false.
msort(+Liste, -Triee) trie les éléments de Liste pour créer Triée :
?- msort([12,3,-7,9,-3,17,11,10,3,9,6,18],L),writeln(L).
[-7,-3,3,3,6,9,9,10,11,12,17,18]
L = [-7, -3, 3, 3, 6, 9, 9, 10, 11|...].
33
Conversions entre atomes chaines
et listes
atom_chars(?Atom, ?Liste) unifie un atome avec la liste des atomes caractères qui le composent :
?- atom_chars(bonjour,L). ?- atom_chars(X,[b, o, n, j, o, u, r]).
L = [b, o, n, j, o, u, r]. X = bonjour.
string_chars(?String, ?Liste) unifie une chaine avec la liste des atomes caractères qui le
composent :
?- string_chars("hello",L). ?- string_chars(C,[h, e, l, l, o]).
L = [h, e, l, l, o]. C = "hello".
atom_string(?Atom, ?String) unifie un atome avec la chaine des caractères qui le composent :
?- atom_string(foo, Z). ?- atom_string(A,"hello world!").
Z = "foo". A = 'hello world!'.
number_string(?Number, ?String) unifie un nombre avec la chaine des caractères qui le composent:
?- number_string(3.14159265,S). ?- number_string(N,"3.14159265").
S = "3.14159265". N = 3.14159265.
string_codes(?String, ?Codes) unifie une chaine avec la liste des codes des caractères de la chaine:
?- string_codes("hello",L). ?- string_codes(S,[104, 101, 108, 108, 111]).
L = [104, 101, 108, 108, 111]. S = "hello".
atomics_to_string(+List, -String) convertit une liste d’éléments atomiques en une chaine :
?- atomics_to_string([hello, ' ', "world ", 33],S).
25
S = "hello world 33".
ENSEM
COURS DE
Programmation
logique et
contrainte
Enseignant : Dr. AOUN Oussama
2
Les graphes en Prolog
Graphe
Ensemble de sommets (ou nœuds) reliés par des arcs
(graphe orienté) ou des arêtes (graphe non orienté).
Permet de modéliser de nombreuses situations concrètes
comme par exemple : des liaisons routières, des flux, des
tâches à ordonner, etc.
B B
A C A C
D D
Graphe orienté Graphe non orienté
3
Représentation des graphes
B arc(a,b,5).
2 arc(b,c,2).
5
arc(a,d,3).
A C arc(c,d,2).
3 3 arc(d,c,3).
2 sommet(a).
D sommet(b).
sommet(c).
Graphe orienté sommet(d).
4
Exemple : des figures à colorier
Problème posé :
On veut colorier les zones des
figures, de sorte que deux zones
adjacentes n’aient pas la même
couleur. Figure 1
adjacentes
5
Exemple : des figures à colorier
Les sommets représentent les
zones de la figure
B C
Les arêtes relient deux zones
A
adjacentes
D E F
B Figure 2
B
A C
A
C
E D
Figure 1
F D
E
6
Exemple : des figures à colorier
réalisation en Prolog
B
Représentation des 2 figures en Prolog
zones(figure1,[a,b,c,d,e]).
zones(figure2,[a,b,c,d,e,f]). A C
arete(figure1,a,b).
arete(figure1,a,c).
arete(figure1,a,d). E D
arete(figure1,a,e).
arete(figure1,b,c). Figure 1
arete(figure1,b,d).
arete(figure1,c,d).
arete(figure1,d,e).
B
arete(figure2,a,b). A
arete(figure2,a,c).
arete(figure2,a,d).
arete(figure2,a,e).
C
arete(figure2,a,f).
arete(figure2,b,c).
arete(figure2,b,d).
arete(figure2,c,f).
arete(figure2,d,e).
F D
arete(figure2,e,f).
E
8
aretes(Fig,L):- findall([X,Y], arete(Fig,X,Y), L). Figure 2
Exemple : des figures à colorier
réalisation en Prolog
On veut écrire le prédicat coloriage/2 B
qui, à partir du nom de la figure,
donne un coloriage possible à l’aide A C
des couleurs disponibles
E D
Le résultat est une liste de couples Figure 1
[zone, couleur]
?- coloriage(figure1,L).
L = [[e, vert], [d, rouge], [c, bleu], [b, vert], [a, jaune]]
8
Exemple : des figures à colorier
réalisation en Prolog
Programme de coloriage :
adjacent/3 : prédicat indiquant si 2 sommets (zones) sont
adjacent(e)s dans la figure donnée.
adjacent(Fig,X,Y):- arete(Fig,X,Y); arete(Fig,Y,X).
dans la figure Fig, X adjacent à Y si une arête les relie.
conflit/3 : prédicat indiquant s’il y a conflit de coloriage
entre les zones Z1 et Z2 d’une figure.
conflit(Fig,[Z1,C1],[Z2,C2]):- adjacent(Fig,Z1,Z2), C1==C2.
ou plus simplement :
conflit(Fig,[Z1,C],[Z2,C]):- adjacent(Fig,Z1,Z2).
9
Exemple : des figures à colorier
réalisation en Prolog
noconflit/3 : prédicat indiquant si la couleur d’une zone n’est
pas en conflit avec les couleurs déjà sélectionnées pour les
autres zones (liste de doublets)
noconflit(Fig,X,[]).
noconflit(Fig,X,[P|F]):- \+conflit(Fig,X,P)), noconflit(Fig,X,F).
coloriage : coloriage de la figure Fig
coloriage(Fig,L):- zones(Fig,Zones), colorier(Fig,Zones,[],L).
L est une liste de doublets [zone, couleur].
colorier : trouve la liste des couleurs de chaque zone de la
figure
colorier(_,[],L,L).
colorier(Fig,[Z|F],L,R):- couleur(C), noconflit(Fig,[Z,C],L),
colorier(Fig,F,[[Z,C]|L],R).
10
Les Arbres en Prolog
Eléments abordés :
Arbres n-aires et arbres binaires
Parcours d’arbres
14
Les Arbres
Les arbres sont des graphes particuliers.
Les arbres, comme les listes, permettent de
représenter un nombre variable de données
Le principal avantage des arbres est qu’ils
permettent d’organiser les données selon un
ordre partiel.
Exemples d’arbres :
Arbre généalogique
Sommaire d’un livre, hiérarchie de répertoires
Arbre de dérivation d’une phrase d’un langage défini
15
par une grammaire
Exemples d’arbres
+
A
*
B -
H
C +
E A 7
L
5
F X
G
14
Représentations graphiques d’un
arbre
Racine A
B D H
C E K L
F G J
15
Représentations graphiques d’un
arbre
Racine A
B D H
C E K L
F G J
Feuilles
16
Définition d’un Arbre
Un Arbre est un ensemble non vide structuré comme suit :
un des éléments est désigné comme étant la « racine » de l’arbre
il existe une partition sur les éléments restants, et chaque classe de cette
partition est elle-même un arbre : on parle des sous-arbres de la racine.
Si le nombre de sous-arbres est variable, l’arbre est dit n-aire.
L’ensemble représenté par un arbre est la réunion d’un élément (la
racine) et des sous-arbres qui lui sont directement associés.
Chaque élément de l’ensemble structuré en arbre est appelé un nœud.
A tout nœud est associée une information élémentaire.
Pour décrire les relations entre les nœuds on utilise la terminologie de la
généalogie, un nœud est donc le père de ses fils.
Le degré d’un nœud est le nombre de ses fils. On distingue :
les nœuds non terminaux de degré non nul
les nœuds terminaux ou feuilles, de degré nul.
17
Arbre binaire
Un arbre binaire est un arbre pour lequel tout
nœud a au plus deux fils.
Un arbre binaire est un ensemble fini qui est
soit vide, soit composé d’une racine et de deux
sous-arbres binaires appelés sous-arbre
gauche et sous-arbre droit.
On peut donc dire qu’un arbre binaire est :
soit l’arbre vide
soit un nœud qui a exactement deux sous-arbres
éventuellement vides 18
Représentation des arbres
binaires en Prolog
Nous choisissons d’utiliser les listes pour
représenter les arbres binaires
Un arbre vide sera représenté par la liste vide []
Un nœud sera représenté par une liste de 3 éléments :
le premier est la valeur portée par le nœud,
le deuxième son sous-arbre gauche,
le troisième son sous-arbre droit.
19
Exemple de représentation d’un
arbre binaire en Prolog
6
4 12
1 8 14
20
Parcours d’arbres
Un arbre contient un ensemble de données.
Pour utiliser ces données, on peut parcourir l’arbre
en largeur
6
On parcourt l’arbre
par niveaux : d’abord 4 12
la racine, puis les
nœuds de niveau
inférieur, et ainsi de 1 8 14
suite
7
21
Parcours d’arbres
Un arbre contient un ensemble de données.
Pour utiliser ces données, il faut parcourir l’arbre
en profondeur
6
On visite d’abord le
sous-arbre gauche,
4 12
ensuite la racine, puis
le sous-arbre droit
1 8 14
7
22
Exemples de parcours en
profondeur
Calcul de la somme des nœuds d’un arbre
binaire de nombres
somme([],0).
somme([N, G, D], S) :- somme(G, N1), somme(D,N2),
S is N+N1+N2.
23
Exemples de parcours d’un arbre
binaire
Affichage des nœuds d’un arbre binaire
Dans l’ordre du parcours en profondeur (infixé)
afficher([]).
afficher([N, G, D]) :- afficher(G), write(N), afficher(D).
Dans l’ordre préfixé : racine puis les sous-arbres
afficher([]).
afficher([N, G, D]) :- write(N), afficher(G), afficher(D).
Dans l’ordre postfixé : les sous-arbres puis la racine
afficher([]).
afficher([N, G, D]) :- afficher(G), afficher(D), write(N).
24
Exemples de construction d’un
arbre binaire
A partir d’un arbre, créer un arbre qui représente
la somme des valeurs des sous-arbres
6 52
4 12 20 26
1 8 14
1 15 14
7 7
25
Arbre représentant la somme des
valeurs des sous-arbres : analyse
Cas possibles Arbre construit
R
R
g G
d D
27
Une autre manière de représenter
les arbres binaires en Prolog
Un arbre binaire peut être représenté par le terme
de suivant: t(SousArbreG, Racine, SousArbreD).
9
4 12
1 8 14
t( t( t(nil, 1, nil), 4, t( t(nil, 7, nil), 8, nil) ), 9, t(nil, 12, t(nil, 14, nil) ) )
Arbre vide : nil 28
ENSEM
COURS DE
Programmation
logique et
contrainte
Enseignant : Dr. AOUN Oussama
Les intégrammes
Les intégrammes
Les intégrammes appelés parfois logigrammes
sont un type de casse-tête logique.
On donne un certain nombre d'indices, desquels
il faudra déduire l'intégralité des relations entre
tous les éléments.
3
Exemple d’intégramme simple
4
Modélisation : les faits
% les maisons :
maison(studio).
maison(pavillon).
maison(château).
% les animaux :
animal(chat).
animal(cheval).
animal(poisson).
5
Modélisation : les règles
% le prédicat habitation représente la relation
% entre une personne, sa maison et son animal :
% Max a un chat :
habitation(max,M,chat) :- maison(M).
% Eric n’habite pas en pavillon :
habitation(eric,M,A) :- maison(M), M\==pavillon, animal(A).
% Luc habite un studio, il n’a pas le cheval :
habitation(luc,studio,A):-animal(A),A\==cheval.
6
Résolution du problème :
prédicat résoudre
% avec ses 4 éléments inconnus resoudre :-
habitation(max,MM,chat),
Astuce : habitation(eric,ME,AE),
habitation(luc,studio,AL),
% le prédicat resoudre décrit l’ensemble du problème à résoudre
et affiche la solution :
7
Interrogeons Prolog
?- resoudre.
max pavillon chat
eric chateau cheval
luc studio poisson
true ;
false.
8
On souhaite maintenant résoudre
l’intégramme suivant
Dans une rue 3 maisons voisines sont de couleurs différentes :
rouge, bleue et verte. Des personnes de nationalités différentes
vivent dans ces maisons et elles ont chacune un animal de
compagnie différent.
Les données du problème sont :
l'anglais vit dans la maison rouge.
le jaguar est l'animal de l'espagnol.
le japonais vit à droite de la maison du possesseur de l'escargot.
le possesseur de l'escargot vit à gauche de la maison bleue.
La problématique à résoudre est :
Qui possède le serpent ?
9
Modélisation du problème
On va représenter la solution par une liste de 3
termes, chaque terme aura la forme suivante :
maison(couleur,nationalité,animal)
Le programme Prolog ne contient qu’un prédicat :
serpent(N, Rue) :- …
N représente la nationalité du possesseur du serpent
Rue représente la solution complète, c’est-à-dire la liste
de 3 termes maison(couleur,nationalité,animal)
10
Solution
serpent(N, Rue) :-
% Rue est représentée par une liste de 3 maisons :
length(Rue,3),
% il y a une maison rouge, une maison bleue et une maison verte :
member(maison(rouge,_,_),Rue),
member(maison(bleue,_,_),Rue),
member(maison(verte,_,_),Rue),
% l'anglais vit dans la maison rouge :
member(maison(rouge,anglais,_),Rue),
% le jaguar est l'animal de l'espanol :
member(maison(_,espagnol,jaguar),Rue),
% le japonais vit à droite de la maison du possesseur de l'escargot :
nextto(maison(_,_,escargot),maison(_,japonais,_),Rue),
% le possesseur de l'escargot vit à gauche de la maison bleue :
nextto(maison(_,_,escargot),maison(bleue,_,_),Rue),
% le troisième animal est un serpent :
member(maison(_,N,serpent),Rue).
11
Interrogeons Prolog
?- serpent(N,Rue).
N = japonais,
Rue = [maison(rouge, anglais, escargot),
maison(bleue, japonais, serpent),
maison(verte, espagnol, jaguar)]
Utilisons cette modélisation pour le
problème précédent
resoudre2(S):-
% il y a 3 habitations: studio, chateau, pavillon (non ordonnés)
S = [habitation(_,studio,_), habitation(_,chateau,_),
habitation(_,pavillon,_)],
% il y a un poisson
member(habitation(_,_,poisson),S),
% il y a un cheval
member(habitation(_,_,cheval),S),
% Max a un chat
member(habitation(max,_,chat),S),
% Eric n’habite pas en pavillon :
member(habitation(eric,HE,_),S), HE \== pavillon,
% Luc habite un studio, il n’a pas le cheval :
member(habitation(luc,studio,AL),S), AL \== cheval.
61
Interrogeons Prolog
?- resoudre2(S).
S = [habitation(luc, studio, poisson),
habitation(eric, chateau, cheval),
habitation(max, pavillon, chat)]
ENSEM
COURS DE
Programmation
logique et
contrainte
Enseignant : Dr. AOUN Oussama
Le code source (il charge le module clpfd puis définit les contraintes sur la
variable X) :
:-use_module(library(clpfd)).
solution(L):-
L=[X],
X in 1..5,
X#>2,
labeling([],L).
La programmation logique avec
contraintes
Le module clpfd de SWI-Prolog permet de programmer avec
contraintes.
Appelons le prédicat solution dans l'interpréteur Prolog :
?- solution(L).
L = [3] ;
L = [4] ;
L = [5].