Professional Documents
Culture Documents
8cours#4 (Part 1) Paradigme Logique
8cours#4 (Part 1) Paradigme Logique
com
1
Ordre du jour
1. Introduction
2. Faits
3. Prédicats (termes structurés)
4. Opérations logiques et prédicats composites
5. Règles d'inférence
6. Quelques analogies
Course content available at: coronet.iicm.tugraz.at/sa/scripts/lesson06.doc
2
La programmation logique propose un formalisme pour spécifier un calcul en
termes de relations logiques entre entités. Un programme logique consiste
en un ensemble d'instructions logiques décrivant un certain état de choses.
Pour écrire un programme dans un tel langage, le programmeur doit d'abord
décrire toutes les relations logiques pertinentes entre les différentes entités.
Un calcul revient essentiellement à déterminer si une conclusion particulière
découle de ces énoncés logiques.
L'implémentation d'un langage de programmation logique fournit des
démonstrations automatisées de théorèmes (Automatic Theorem Proof -
ATP) - utilisées pour établir la validité de la conclusion.
Un point important pour écrire des programmes logiques est de modéliser le
domaine (ou l'état des choses) en termes de relations logiques. La facilité
relative avec laquelle cela peut être fait dépend du domaine lui-même.
3
Un modèle de données logiques fonctionne avec ce qu'on appelle
des faits.
D'une manière générale, un fait est une expression qui peut être
interprétée comme Vrai ou Faux.
Examples:
◦ ‘Alex is a nice guy’.
◦ 25 > 36
◦ 25 + 41 = 66
◦ ‘Smith est étudiant et a il obtenu "2" à l'examen sur la programmation SQL’
Les faits sont présentés comme des termes dits structurés qui sont
constitués de plusieurs composants.
4
Structure générale
◦ Un terme structuré est formé syntaxiquement par un foncteur (operateur,
également appelé symbole de prédicat) et une liste d'arguments.
La liste d’arguments apparaît entre parenthèses
Chaque argument est séparé du suivant argument par une virgule
Examples:
Alex is a nice guy. = = niceGuy (Alex)
Foncteur argument
Smith est étudiant et il a obtenu "2" à l'examen sur la programmation SQL.= = exam(‘Smith’,SQL Programming’,2)
Foncteur arguments
5
Chaque argument d'un prédicat est un soi-disant terme, par exemple, il peut
s'agir d'un autre prédicat (terme structuré).
Le nombre d'arguments d'un terme structuré est appelé son arité (arity).
Exemples:
greaterThan(9, 6) exam(a, b, h(c,d)) plus(2, 3, 5)
Un point important à mentionner est qu'une structure est simplement un
mécanisme pour combiner des termes ensemble, en formant ainsi des
termes plus complexes mais sans effectuer aucune évaluation implicite.
Ainsi, dans le dernier exemple ci-dessus, les entiers 2, 3 et 5 sont combinés
avec le foncteur plus. Une combinaison tout aussi valable, quoique
légèrement trompeuse, pourrait être plus(2, 3, 7).
Si évalué,
plus(2,3,5) est Vrai (True)
plus(2,3,7) est Faux (False)
Définition de l'arité
Le nombre d'arguments pris par une fonction ou un opérateur. Dans certains langages,
les fonctions peuvent avoir une arité variable, ce qui signifie parfois que leur dernier ou
unique argument est en fait une liste d'arguments.
6
Il existe trois types d'objets de données simples :
◦ atomes,
◦ Nombres,
◦ variables
Les atomes peuvent se former de trois manières :
1. Une lettre, éventuellement suivie par d'autres lettres (dans les deux cas), de chiffres, et d'un trait
de soulignement
Examples:
a greaterThan two_B_or_not_2_b
2. Une chaîne de caractères spéciaux tels que: + - * / \ = ^ < > : . ~ @ # $ &
Examples:
<> ##&& ::=
3. Une chaîne de caractères entre guillemets simples.
Examples:
'ABC' '1234' 'a<>b'
Dans le troisième cas ci-dessus, si ce qui apparaît entre guillemets simples est un atome valide tel que spécifié par
l'un des deux premiers cas, alors les guillemets sont facultatifs. Ainsi, 'abc' et abc représentent le même atome.
7
Les applications impliquant des calculs numériques intenses sont rarement écrites
en langages de programmation logique. En fait, le paradigme logique n'est pas
particulièrement bien adapté pour écrire de telles applications. Néanmoins, le
paradigme fournit une représentation pour les nombres entiers et les nombres réels.
Les exemples suivants illustrent la représentation des nombres entièrs:
0 -16 33 +100
Les nombres réels peuvent être écrits en notation standard ou scientifique, comme
illustré ci-dessous:
0.5 -3.1416 6.23e+23 11.0e-3 -2.6e-2
Un point décimal doit apparaître dans tous les nombres réels et il doit y avoir au
moins un chiffre de chaque côté. Plusieurs aspects concernant la représentation des
nombres dépendent de l'implémentation. Une brève liste de certains de ces points
suit la gamme réelle de nombres (réels et entiers) qui peuvent être représentés.
8
Variable - nom d'une valeur qui peut changer pendant l'exécution d'une évaluation
Examples:
StudentName peut être ‘Johns’, ‘Mayer’ , ‘Ivanov’, etc.
ExaminationMark peut être 1, 2, 3, 4 and 5
GoodGuy peut être ‘Vrai’ ou ‘Faux’
L'ensemble de toutes les valeurs possibles qui peuvent avoir une variable
particulière est appelé une portée de variable ou une plage de variable.
Un prédicat (terme structuré) dont tous les arguments sont des constantes est
appelé un fait. Un fait particulier peut être vrai ou faux (true/false).
Formellement parlant, un paradigme de programmation logique repose fortement
sur une base de données. Cette structure contient des objets de données
persistants qui répertorient tous les faits de base valides. Si un fait de base
particulier ne peut pas être trouvé dans une telle base de données, il est considéré
comme faux.
9
greaterThan (25,36) est Faux
plus (25,41,66) est Vrai
Pourquoi? Parce que nous connaissons des règles formelles pour valider
les faits et pouvons communiquer ces règles aux ordinateurs, c'est-à-dire
un algorithme peut être défini. Ces termes sont appelés termes de calcul.
niceGuy(Alex) est Vrai
exam(‘Smith’,SQL Programming’) est Faux
Pourquoi? Parce que nous savons leur valeur de vérité selon notre propre
expérience qui ne peut pas être formalisée comme un algorithme.
Nous pouvons simplement mettre ces connaissances dans la mémoire d'un ordinateur
en énumérant tous les faits valables. Par exemple, on peut lister tous les mecs qui se
considèrent comme gentils ou lister tous les étudiants qui réussissent un examen sur
les paradigmes logiciels.
10
Un prédicat (terme structuré) ayant au moins un argument
variable est appelé fonction logique ou simplement prédicat.
Toutes les variables utilisées pour la définition d'un tel prédicat
sont appelées variables libres.
Une fonction logique particulière mappe chaque combinaison de
valeurs de variables libres sur une valeur booléenne Vrai/Faux.
En d'autres termes, le prédicat peut être vrai ou faux en fonction
d'une combinaison particulière de valeurs de variables libres.
11
greaterThan (X,25) est une fonction de variable “X”, F(X)
greaterThan(X,25) est Vrai si X = 26, 27, etc. le même prédicat est faux si X = 25,
24, etc.
plus (X,Y,66)
◦ plus(X,Y,66) est Vrai si {X,Y} = {1,65}, {2,64}, {3,63}, etc.
◦ le même prédicat est faux si, par exemple, {X,Y} = {30,45} or {X,Y} = {55,55}.
niceGuy(X)
◦ niceGuy(X) est vrai si X = “Alex” et “Alex” peut être trouvé parmi les objets de base de
données persistants “niceGuy”,
exam(StudentName,VO) est faux si StudentName = “Alex”, VO = “Software
Paradigm” et (“Alex”,”Software Paradigms”) ne peuvent être trouvé parmi les objets
de base de données persistants de type “exam”.
12
Syntaxiquement, un prédicat peut être composé d'un ou plusieurs
prédicats simples utilisant une opération logique et parentheses.
◦ “&” – “and” logique,
◦ “|” – “or” logique,
◦ “°” – “not” logique
Example:
greaterThan(36,25) & plus(55,11,66) est Vrai parce’que
greaterThan(36,25) est Vrai & plus(55,11,66) est Vrai
13
La priorité des opérateurs pour les opérateurs '&' et '|' suit les
règles de priorité standard, c'est-à-dire '&' lie plus fort que '|'.
Ainsi,
F1 & F2 | F3 == ( F1 & F2 ) | F3
L'utilisation explicite de parenthèses, comme dans le prédicat
ci-dessus, est nécessaire pour remplacer cette priorité par
défaut. Ainsi, si l'intention est pour le '|' opérateur pour lier
plus fort dans l'expression ci-dessus, il doit être écrit comme
F1 & (F2 | F3)
14
niceGuy(‘Alex’) & niceGuy(‘Tom’) | exam(‘Tom’, ‘Software Paradigm’,1)
est vrai si les deux faits de base: niceGuy(‘Alex’) & niceGuy(‘Tom’) sont
Vrai ou l'autre fait exam(‘Tom’,’Software Paradigms’,1) est vrai.
Autrement dit, si le fait exam(‘Tom’,’Software Paradigms’,1) est vrai, il
suffit déjà que l'expression entière soit valide (vraie).
15
Les prédicats peuvent également inclure des quantificateurs variables, en particulier
◦ Le quantificateur existentiel, désigné par le symbole ‘’, et
◦ Le quantificateur universel, désigné par le symbole ‘’
◦ Ces quantificateurs quantifient des variables. Une variable existentiellement
quantifiée, disons X, s'écrit « X» et se lit comme "il existe un X tel que ...".
Une variable universellement quantifiée s'écrit « X » et se lit comme «pour
tout X … ».
◦ La quantification est appliquée à une formule et est écrite avant celle-ci
Example:
x (greaterThan(Y,X) & greaterThan(12,Y))
serait lu comme "il existe un X tel que X est inférieur à Y et Y est inférieur à 12"
16
La formule à laquelle la quantification est appliquée est appelée la
portée de la quantification (scope)
17
De manière informelle, la formule « X (<expr>)» affirme que:
◦ Il existe au moins une valeur de X (parmi son intervalle de valeurs) tel que
<expr> est vrai.
Cette assertion n'est fausse que lorsque aucune valeur de X ne
peut être trouvée pour le satisfaire
Par contre, si l'assertion est vraie, il peut y avoir plus d'une telle
valeur de X, mais peu importe laquelle
En d'autres termes, la vérité d'une expression quantifiée
existentiellement n'est pas fonction des variables quantifiées.
18
A titre d'exemple, considérons l'expression non quantifiée
greaterThan(Y,X) & greaterThan(12,Y)
19
Considérons maintenant la même expression mais avec X quantifié
existentiellement :
20
Passons maintenant au quantificateur universel
21
Considérons, par exemple, l'expression non quantifiée
greaterThan(Y,X) | greaterThan(12,Y)
et supposons que X s'étend sur {4,15} et Y sur {7,14}.
La table de vérité de l'expression est:
X Y greaterThan(Y,X) | greaterThan(12,Y)
4 7 Vrai
15 7 Vrai
4 14 Vrai
15 14 Faux
22
Considérons maintenant la même expression mais avec X universellement
quantifié:
X (greaterThan(Y,X) | greaterThan(12,Y))
Dans un sens, comme la variable existentiellement quantifiée, nous ne nous
soucions pas des valeurs de X, tant que chacune d'elles rend l'expression
vraie pour un Y donné. Ainsi, sa table de vérité est:
Y X (greaterThan(Y,X) | greaterThan(12,Y))
7 Vrai
14 Faux
Notez que les différents types de quantificateurs peuvent être mélangés. Mais notez
aussi que leur ordre est important, i.e. x y ( <expr> ) n'est pas le même que
y x ( <expr> )
23
Supposons, par exemple, le prédicat is_a_mother(M,Ch) qui
définit un ensemble de faits de base de données
“M is the mother of Ch”.
Ch M (is_a_mother(M,Ch))
affirme que tout le monde a une mère. Tandis que,
M Ch (is_a_mother(M,Ch))
affirme qu'il y a un seul individu (M) qui est la mère de tout le
monde!
24
Précisons maintenant les formes valides des prédicats impliquant
des variables. Ces formes valides sont appelées formules bien
formées (FBF) et sont définies comme suit :
1. F (X1, ... Xn) est un FBF où X1, X2, .. sont appelées variables libres
2. F1 & F2 et F1 | F2 sont des FBF si F1 et F2 sont des FBF
3. (F) est un FBF si F est un FBF
4. x (F(X)) et x (F(X)) sont FBF si F(X) est une FBF avec une
occurrence libre de la variable X.
Dans ce cas, X est appelé une variable liée dans la portée de F (x).
25
Tête et corps
La forme générale des clauses est la suivante :
<tête> : - <corps>.
Notez que ces deux composants (tête et corps) peuvent
également être appelés respectivement conclusion et
prémisse.
<conclusion> : - <prémisse>
où
« corps » est un FBF (expression logique)
« tête » est un prédicat
Inférence
a) L'acte ou le processus de tirer des conclusions logiques à partir de prémisses
connues ou supposées vraies.
b) L'acte de raisonner à partir de connaissances factuelles ou de preuves.
26
Si nous n'utilisons pas de variables, les deux composants (c'est-à-dire
la tête et le corps) sont des faits. La règle est interprétée comme suit :
« Si un corps est valide (vrai) alors la tête est également valide (vrai)
par définition »
Examples:
humanBeing(‘Alex’):-goodGuy(‘Alex’)
si Alex est un bon gars, alors c'est un être humain.
Si on prend le fait,
enrollVO(‘Alex’, ‘Programming’)
il est vrai si un étudiant « Alex » est inscrit au cours «Programmation»
27
Supposons également que le fait locVO(‘Programming’, ‘Thursady, ‘Room 22’) est
vrai si les cours de programmation ont lieu dans la salle 22, le jeudi.
On peut définir la règle d'inférence suivante
mustGo(‘Alex’, ‘Thursday’,’Room 22’) :-
enrollVO(‘Alex’, ‘Programming’) & locVO(‘Programming’, ‘Thursday’, ‘Room 22’)
signifiant que le fait
mustGo(‘Alex’, ‘Thursday’, ‘Room 22’)
est vrai si les deux faits
enrollVO(‘Alex’, ‘Programming’) et locVO(‘Programming’, ‘Thursday’, ‘Room 22’)
sont vrai.
28
En fait, tous les exemples ci-dessus ne sont pas très illustratifs
car les règles d'inférence ne sont presque jamais définies sans
variables.
Si nous utilisons des variables, les deux composants (c'est-à-
dire la tête et le corps) sont des prédicats. La règle est
interprétée comme suit :
"Si un corps est valide (vrai) pour une combinaison particulière
de valeurs de variables libres alors la tête est également valide
(vrai) pour la même combinaison de valeurs de variables libres"
29
humanBeing(X):-goodGuy(X) tout (!) bon gars est un être humain.
Supposons que le prédicat enrollVO(Student, Subject) est vrai si un
étudiant est inscrit à un cours sur ce sujet particulier.
Supposons également que le prédicat locVO(Subject, Day, Room)
est vrai si les cours sur ce sujet particulier ont lieu dans cette salle
et ce jour.
On peut définir la règle d'inférence suivante
mustGo(Student, Room, Day, Subject) :-enrollVO(Student, Subject) & locVO(Subject, Day, Room)
ce qui signifie qu'un étudiant particulier doit être dans une salle
particulière un jour stipulé, s'il s'est inscrit à un cours et que ces
cours ont lieu dans cette salle ce jour-là.
30
Les prédicats enrollVO et locVO fonctionnent définitivement sur les
faits de la base de données, c'est-à-dire le système doit rechercher
dans une base de données interne pour savoir si, par exemple, le
fait enrollVO ("Alex", "Programmation") est vrai ou faux.
Supposons que la base de données se présente comme suit :
locVO Subject Day Room
31
Par analogie, les faits de base enrollVO peuvent être vus comme le
tableau suivant :
enrollVO Student Subject
Palina Hypermedia
Palina Programming
Alex Programming
Alex Databases
Le résultat de l'application de la règle d'inférence suivante
mustGo(Student, Room, Day, Subject) :-enrollVO(Student, Subject) & locVO(Subject, Day, Room)
32
Tous les faits inférés sont vrais par définition et peuvent être
vus comme dans le tableau suivant:
mustGo Student Room Day Subject
33
Le dernier exemple suggère que nous devrions peut-être simplifier la
règle en supprimant la variable Sujet de la tête :
mustGo(Student, Room, Day) :- enrollVO(Student, Subject) & locVO(Subject, Day, Room)
En fait, cette règle est erronée car les variables libres dans l'en-tête
de la règle ne sont pas identiques aux variables dans le corps.
34
Ainsi, pour vérifier un fait mustGo(‘Alex’,’Room 22’, ‘Thursday’), le
système doit évaluer l'expression suivante:
35
Suite à la définition formelle d'une règle d'inférence :
"Si un corps est valide (vrai) pour une combinaison particulière de valeurs de
variables libres alors la tête est également valide (vrai) pour la même
combinaison de valeurs de variables libres"
le système ne peut tout simplement pas conclure si l'expression
36
Ainsi, nous pouvons définir la règle comme suit:
mustGo(Student, Room, Day) :-
Subject (enrollVO(Student, Subject) & locVO(Subject, Day, Room))
Le prédicat (corps) ci-dessus est vrai s'il existe au moins un sujet tel
que la condition
enrollVO(Student, Subject) & locVO(Subject, Day, Room)
est Vrai
Autrement dit, le fait mustGo(‘Alex’,’Room 22’, ‘Thursday’) est
certainement vrai puisqu'il existe un sujet, par exemple,
"Programmation" tel que
enrollVO(‘Alex’, ‘Programming’) & locVO(‘Programming’, ‘Room 22’, ‘Thursday’) est vrai
37
La définition récursive des règles d'inférence est une méthode de
programmation logique très puissante et couramment utilisée.
Supposons que nous ayons un prédicat
parent (G, D)
le prédicat identifie si une personne D est un enfant de la personne G
descendant (G, D)
qui identifie si une personne D est un descendant de la personne G comme
38
Notez que des règles comme celle-ci, peuvent être définies plus
clairement en utilisant un certain nombre de règles d'inférence
avec une seule et même tête.
descendent(G,D):-parent(G,D)
descendent(G,D):- X (parent(G,X) & descendent(X,D))
La première règle pour trouver un descendant direct: il suffit de copier tous les
faits "parent" en tant que faits "descendant"
la deuxième règle utilise le même prédicat principal (c'est-à-dire la récursivité)
pour trouver un descendant indirect.
Ici, si le fait inféré est vrai conformément à l'une des règles, il est
considéré comme vrai, généralement.
39
Considérez l'arbre généalogique suivant, qui pourrait être
décrit comme les faits suivants:
parent G D
Nick Pauline
Pauline Alex
Pauline Paul
Alex Tom
40
L’application de la règle:
descendent(G,D):- X (parent(G,X) & descendent(X,D))
aboutit aux faits inférés suivants:
descendent G D X parent(G,X) & descendent(X,D))
Nick Alex Pauline parent(‘Nick’,’Pauline’) & descendent(‘Pauline’,’Alex’)
41
Dans la programmation logique, les calculs sont effectués au
moyen de termes de calcul ressemblant par exemple, à ce qui
suit :
plus(V1,V2,R) le prédicat est vrai si R = V1 + V2;
mult(V1,V2,R) le prédicat est vrai si R = V1 * V2;
etc.
Considérons, par exemple, un caz bien connu d'une soi-disant
nomenclature des matériaux qui identifie quels composants et
en quelle quantité sont nécessaires pour assembler un produit
particulier / un autre composant.
42
Il peut être décrit comme les faits suivants: need(P,C,Q)
need P C Q
D_A D_B 5
D_B D_D 3
D_B D_C 8
D_D D_E 4
43
Application de la règle:
need+(P,C,Q):-need(P,C,Q)
aboutit aux faits inférés suivants:
Need+ P C Q
D_A D_B 5
D_B D_D 3
D_B D_C 8
D_D D_E 4
44
Application de la règle:
need+( P,C,Q):- X Q1 Q2(need(P,X,Q1) & need+(X,C,Q2) & mult(Q1,Q2,Q))
45
Définir les calculs comme des prédicats de calcul impliquant
plusieurs variables liées comme, par exemple,
need+( P,C,Q):- X Q1 Q2(need(P,X,Q1) & need+(X,C,Q2) & mult(Q1,Q2,Q))
peut constituer un grave problème.
Les fonctions offrent un moyen beaucoup plus direct et simple de
définir des calculs. Une fonction particulière peut être appliquée à un
certain nombre de variables libres et être réutilisée ultérieurement
comme variable.
Par exemple, la règle d'inférence précédemment définie need+
peut être définie de manière beaucoup plus claire comme :
need+( P,C,(Q1 * Q2)):- X (need(P,X,Q1) & need+(X,C,Q2))
où notation (Q1 * Q2) est utilisée de manière mathématique normale
46
L'application de cette règle aboutit à la même liste de faits
inférés, mais la procédure d'inférence est beaucoup plus simple
need+ P C Q1*Q2 X need(P,X,Q1) & need+(X,C,Q2)
47
On pourrait penser aux prédicats et aux faits de plusieurs manières.
◦ Une manière naturelle (peut-être particulièrement pour les non-programmeurs) d'examiner
les règles d'inférence est de les considérer comme des phrases déclaratives en langage
naturel.
◦ Comme indiqué précédemment, les prédicats décrivent les relations entre les entités (par
exemple, la grand- paternité, la paternité, etc.).
◦ Certaines relations peuvent être énoncées dans une phrase, d'autres relations nécessitent
plus d'une phrase (règle d'inférence) afin de spécifier pleinement la relation.
Les programmeurs peuvent trouver des similitudes entre un prédicat et une
procédure.
◦ En ce sens, un prédicat spécifie comment "calculer" quelque chose;
◦ Dans ce contexte, les règles correspondraient à une procédure d'appel et les directives
générales correspondraient à des appels impliquant des procédures intégrées (cette
dernière analogie est plus faible que les autres).
◦ Considérer les prédicats et les requêtes de cette manière est certainement exact,
cependant, cela constitue une vision restreinte.
48
Query languages
Langages before
de requête SQL
avant ( a,
SQL b )vsvsSQL
(a,b) SQL(c) ( c )
49