82
1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative ». Repose sur deux courants: la définition des langages de programmation (« W-grammaires ») et la démonstration automatique 1981 : programme Japonais de 5ème Génération. 1989 : Programmation Logique avec Contraintes (Prolog III) 1995 : Extension et introduction des

1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

Embed Size (px)

Citation preview

Page 1: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

1

1. HISTORIQUE

Origine

PROLOG : PROgrammation LOGique.

1967 : SIMULA 67

1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative ». Repose sur deux courants: la définition des langages de programmation (« W-grammaires ») et la démonstration automatique

1981 : programme Japonais de 5ème Génération.

1989 : Programmation Logique avec Contraintes (Prolog III)

1995 : Extension et introduction des contraintes sur intervalles (Prolog IV)

Page 2: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

2

HISTORIQUE (1)

Logiciels Prolog

Domaine du «  libre »

INRIA : GNU-Prolog

Sicstus, Eclipse

Domaine payant

PrologIA : Prolog 4

COSYTEC (Orsay) : CHIP (Constraint Handling in Prolog)

ILOG Solver

Page 3: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

3

HISTORIQUE(2)

Méthodologie de construction de programme

Spécification logique à partir de laquelle on dérive un programme à l’aide de « règles de dérivation ».

Aspects neufs:

Le langage dans lequel la spécification et le programme sont écrits est le « même ».

Les règles de dérivation conservent la «logique » : si le programme s’arrête le résultat est conforme à la spécification.

Page 4: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

4

HISTORIQUE (3)

Exemple PLC grand public

vc(L, C) : vrai si L est une liste de versements annuels qui rembourse le capital C avec un intérêt de 10 %.

Spécification (et aussi programme):

vc([], C) <= (C = 0).

vc ([V | Lp], C) <= vc(Lp, Cp) et Cp = C – V + (1/10) * C.

Une première question, typique d’un banquier typique:

V, vc([V, V, V], 1000) ?

Réponse: V = 133100/331 ou 402.11480362537765

Page 5: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

5

HISTORIQUE (5)

Aspect « déclaratif »

Autre question dans le même style (pas pour banquier ordinaire):

V, vc([V, 2*V, 3*V], 1000) ?V = 133100/641 ou 207.6443057722309

Ou encore (pas pour banquier du tout): C, vc([200, 400, 300], C) ? C = 982000/1331 ou 737.7911344853494

Page 6: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

6

2.CLAUSES DE HORN, MACHINE PROLOG

clause de Horn: P0 <= P1 … Pn avec n 0

Pi : formule atomique (plus petite formule qui peut être égale à vrai ou faux)

Pi = p (t1, …, tm) avec m 0

p : prédicat

t1, …, tm : termes:

- soit une constante : 123, theodore, …- soit une variable (ou inconnue) : X,X1,Mav….

Page 7: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

7

CLAUSES DE HORN, MACHINE PROLOG (1)

- soit un terme complexe : f (t1, …, tp), p 0

f : foncteur (une constante)

t1, …, tp : termes

Exemple: f (1, g (3, X))

Les variables des clause sont quantifiées universellement

Exemple :

X, biellecoulée(X) <= plusd huile(X) voyantrouge(X)

Page 8: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

8

CLAUSES DE HORN, MACHINE PROLOG (2)

Toute clause de Horn peut se mettre sous la forme:P0 ¬P1 … ¬Pn avec n 0Démonstration ?Un seul littéral (formule atomique ou formule atomique négativé) est positif

(P0)Une clause générale est de la forme:P0 Q1 … Qp ¬P1 … ¬Pn Qui possède éventuellement plusieurs littéraux positifs et qui peut se mettre sous

la forme:P0 Q1 … Qp <=P1 … Pnou encore: P0 <=P1 … Pn ¬ Q1 … ¬ Qp Attention: on ne peut utiliser de clauses générales en Prolog.

Page 9: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

9

Exemple initial type BDDes formules logiques

pere (jacques, pierre) <=

pere (pierre, isidore) <=

et des théorèmes à démontrer:

pere (jacques, pierre) et X pere (jacques, X),

on peut déduire les règles Prolog suivantes:

pere (jacques, pierre). /*regle 1*/

pere (pierre, isidore). /*regle 2*/

et les requêtes Prolog suivantes:

pere (jacques, pierre).

pere (jacques, X).

Page 10: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

10

Exemple initial type BD (1)

pere (jacques, X). fournit un succès:X = pierrepere (X, Y) fournit un succès et deux solutionsX = jacques, Y = pierre ;X = pierre, Y = isidore.

On trouve ici un exemple de la première de dérivation:

Les règles sont consultées par le démonstrateur prolog dans leur ordre d’apparition.

Page 11: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

11

Exemple initial type BD (2)

Le théorème à démontrer suivantZ, Y pere (jacques, Z) pere(Z, Y) peut se traduire par la requête:pere (jacques, Z), pere(Z, Y) démontrée par le processus:

{jacques = jacques,Z = pierre}pere (Z, Y)

{jacques = pierre,Z = isidore} Echec

{Z = jacques,Y = pierre}Echec

{Z = pierre,Y = isidore}Succès

Page 12: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

12

Exemple initial type BD (3)On trouve ici un exemple de la deuxième règle de dérivation:Les buts (formules atomiques) sont prouvés de gauche à droite.

La clause de Horn X, Y, Z grand_pere (X, Y) <= pere (Z, Y) pere (X, Z)peut se traduire par la règlegrand_pere (X, Y) :- pere (Z, Y), pere (X, Z).ou par la règlegrand_pere (X, Y) :- pere (X, Z), pere (Z, Y).

Page 13: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

13

Exemple initial type BD (4)

Exercice: donner les deux démonstrations différentes suivant ces deux règles de la requête:grand-pere(jacques,Y).

Exercice: montrer que la clause de HornX, Y, Z grand_pere(X, Y) <= pere(Z, Y) pere(X, Z)est équivalente à la formuleX, Y grand_pere(X, Y) <= pere(Z, Y) pere(X, Z))

Page 14: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

14

Machine Prolog

-état courant: (W, L-b, R) où

W : ensemble des variables de la question initiale

L-b : séquence des "buts«  (formules atomiques) à prouver.

R : système d’équation courant (supposé « satisfiable » plus ou moins « fortement »)

-état initial : (W, [Q0], )

Q0 = requête initiale.

Page 15: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

15

Machine Prolog (1)

-état final = (W, [ ], Rf)

Rf satisfaisable.

Résultat: Système d’équation "le plus petit" extrait de Rf portant sur les variables de W.

-règle d’inférence:

(W, [B0, B1, …, Bm], R), P0 :– P1, …, Pn

-------------------------------------------------------------

(W, [ P1, …, Pn, B1, …, Bm], {B0 = P0} R)

R et {B0 = P0} R doivent être statisfaisables

Page 16: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

16

Machine Prolog (2)

Exemple:

état initial : ({U}, [grand_pere (jacques, U)], )

Application de la règle d’inférence:

({U}, [grand_pere (jacques, U)], ),

grand_pere (X, Y) :- pere (X, Z), pere (Z, Y).

-----------------------------------------------------

({U}, [pere (X1, Z1), pere (Z1, Y1)],

{grand_pere (jacques, U) = grand_pere (X1, Y1)} )

Page 17: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

17

3. Contraintes sur les arbres

Équation sur les arbres: satisfaisable si les étiquettes des sommets sont égales et si leurs fils sont égaux deux à deux. On dit qu’il y a « unification » des deux arbres.

Exemple:

{ f (1,Y) = f (X,4) }

ou f

Y

f

X 4=

a une solution: {1 = X, Y = 4}

Page 18: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

18

Unification

f (1,Y) et f (X,4) s’»unifient » en f(1, 4).

Exemple:

{ f (Y, 2, 1) = f (1,Y,Y) }

n’a pas de solution.

Exemple:

{ X = f (1,X) } a pour solution un arbre infini rationnel (voir chap. 7).

Page 19: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

19

Listes- liste vide : constante, soit :nil

- liste non vide : terme complexe soit: cons(E, L)

où E est le premier élément de liste et L la liste restante.

Exemple: cons(1, cons(2, cons(3, nil)))

Exemple d’unification:

{cons(X, cons(2, cons(3, nil))) = cons(1, L)} a pour solution:

{ X = 1, L = cons(2, cons(3, nil)) }

Page 20: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

20

Construction de programmes

1) Spécification logique

2) Dérivation depuis la spécification d’un programme qui se termine pour la question considérée.

Page 21: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

21

Terminaison et « réversibilité »

Définition:

concat(X, Y, Z) : vrai si X, Y, Z sont des listes et si Z est la concaténation de X et Y.

Spécification: X, Y concat (nil, Y, Z) <= Z = Y. E, L, Y, L1 concat (cons(E,L), Y, cons(E, L1)) <=

concat (L, Y, L1).

Un programme:

concat (nil, Y, Y).

concat (cons(E,L), Y, cons(E, L1)) :-concat (L, Y, L1).

Page 22: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

22

Terminaison(1)Est-ce que la démonstration de concat(X, Y, Z)se termine pour les cas suivants ?X Y Z où * signifie connu et ? inconnu* * ** * ?* ? *? * ** ? ?? * ?? ? *? ? ?

Page 23: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

23

Terminaison(cont. 1)

Théorème à retenir

« toute suite entière ui, tq i ui 0 et ui > ui+1, est finie »

Exemple non trivial :proc pgcd = (ent a, b) ent :casa = b alors a,a > b alors pgcd (a-b, b),a < b alors pgcd (a, b-a)fcas

Avec pré-condition a>0, et b>0 et entiers

Page 24: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

24

Terminaison(cont. 2)

Pour montrer que pgcd (a0, b0) termine (a0>0, b0>0):

pgcd (a0, b0) -> pgcd (a1, b1) -> pgcd (a2, b2)…

Il s’agit de « découvrir » une fonction f entière respectant le théorème précédent et tq:

u0 = f (a0, b0), u1 = f (a1, b1), u2= f (a2, b2)…

f(a, b) = a-b ne convient pas

f(a, b) = | a-b | ne convient pas

f(a, b) = a + b et f(a, b) = a * b conviennent.

Page 25: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

25

Terminaison (cont. 3)En programmation logique, il faut prendre soin de montrer que la fonction f est évaluable

Soit Z connu comme dans la requête:

concat (X, cons(2, nil), cons(1, cons(2, nil)))

La fonction f = |Z| convient: |cons(E, L1)) |> |cons(L1)|

On montre par réccurence qu’elle est évaluable.

Idem si X est connu. Les seuls cas de non terminaison sont ceux où ni la taille de X ni celle de Z ne sont connues.

Question: quel est le résultat de la requête suivante ?

concat (cons(1, nil), Y, Z)

Page 26: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

26

Notation usuelle de listes

Notations de base: [], [E | L]

Contractions:

[E1 | [E2…[En | L]…]] = [E1, E2, …, En|L]

[E1, E2, …|[]] = [E1, E2,…]

Page 27: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

27

Dérivation de programme

Définition:

inverse(X, Y) : vrai si X est inverse de Y .

Spécification:

inverse([], []) <= E, L, Y, L1 inverse ([E| L], Y) <=

concat (L1, [E], Y) inverse(L, L1).

Un programme:inverse1([], []). inverse1 ([E| L], Y) :- concat (L1, [E], Y),

inverse1(L, L1).

Page 28: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

28

Dérivation de programme(1)

Méthodologie: dérivation d’un deuxième programme possédant la même spécification:

inverse2([], []). inverse2([E| L], Y) :-

inverse2(L, L1), concat (L1, [E], Y).

Mêmes questions concernant la terminaison de démonstrations du type inverse(X, Y) selon que la taille de X ou celle de Y est connue.

Page 29: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

29

CoupureTroisième règle de dérivation. Nécessitée par un besoin d’efficacité i toutes les démonstrations ne sont pas nécessaires.

Exemple:

membre_et_reste(X, L ,R): vrai si X a une occurrence dans L et si R est L amputée de cette occurence.

membre_et_reste(X, [X | L],L).

membre_et_reste(X, [E| L], [E | Rp]):- membre_et_reste(X, L, Rp).

Page 30: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

30

Coupure(1)

membre_et_reste(1, [2,1,3,1,4,1,5], R).

fournit:

R = [2,3,1,4,1,5];

R = [2,1,3,4,1,5];

R = [2,1,3,1, 4, 5].

Si on introduit la coupure

membre_et_reste(X, [X | L],L) :- !.

le seul résultat est:

R = [2,3,1,4,1,5].

Page 31: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

31

Coupure(2)La coupure ! est une formule atomique toujours vraie. De plus, tous les buts en suspens pour prouver le but qui est le sujet de la règle dans laquelle intervient la coupure sont abandonnés.

Exemple:Consigne: règle de dérivation à employer avec précaution pour ne pas « supprimer la complétude », ie supprimer toutes les démonstrations. Emploi « sur »: requête initiale, !.

Page 32: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

32

Coupure(3)

abandon

abandon

Page 33: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

33

Négation par échec

neg_par_echec(b) :- b, !, fail.

neg_par_echec(b).

« Fausse » négation à n’employer que sur des buts instanciés.

homme(pierre).

homme(jacques).fort(jacques).

homme(X), neg_par_echec(fort(X)) donne un succès.

neg_par_echec(fort(X)), homme(X) donne un échec.

Page 34: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

34

4. Contraintes sur les listes

Objets: les listes

Opérations: X o Y (concaténation)

Contraintes: =, #, size(N, X) (N est la taille de X).

Exemple:

{[U, 2]o Y = [1]o [V, W]} se réduit en:

{U = 1, 2 = V, Y = [W]}

Deux questions: décidabilité de la satisfaisabilité de telles contraintes et (si décidabilité)

complexité (en termes de nb de variables et nb d’équations).

Page 35: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

35

LinéaritéIci pour obtenir une bonne efficacité, on autorise seulement des concaténations « linéaires » tq dans Z = X oY , deux des tailles parmi celles de X, Y et Z sont connues.

Exemple:

X o [3] o Y = [1, 2, 3, 4] n’est pas accepté.

Mais

size(6, X), [1, 2, 3]o X = X o [1, 2, 3].

size(10000, X), [1]o X = X o [1].

le sont.

Page 36: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

36

Réversibilité. Pseudo-linéarité

Pour illustrer le fait que + de contraintes => + de « réversibilité », une nouvelle mouture:inverse([], []). inverse([E] o X, Y o [E]) :- inverse(X, Y).nécessite la vérification que les équations posées sont linéaires.inverse([1, 2], Y).termine mais pose des équations non linéaires. Cependant, elles sont conservées et elles deviennent linéaires par propagation (pseudo-linéarité).

Page 37: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

37

Réversibilité. Pseudo-linéarité(1)

Une solution sans équations pseudo-linéaires.

inverse(X, Y) :- sixe(N, X), size(N, Y), palindrome(X o Y).

palindrome([]). palindrome([E] o X o [E]):- palindrome(X).

Page 38: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

38

5. Analyse syntaxique et traduction

otivations

faire ressortir l’analogie entre la restriction que représente les clauses de Horn face aux contraintes générales et celle des grammaires hors contexte face aux grammaires générales (« context-sensitive »)

-appliquer le principe de composition dans un cadre rigoureux qui fait apparaître le besoin de valeurs sous la forme de fonctions

Analyse syntaxique

Exemple: le langage ancbn, n 0 défini par la gramaire G d’axiome S:

S -> c

S -> a S b

Page 39: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

39

Analyse syntaxique

Il s’agit de définir le prédicat analyse-G(M) : vrai si la liste M représente une chaîne du langage décrit par G:

Exemple: analyse_G([a, a, c, b, b]) est vrai

Deux clause sont dérivées à partir des deux règles de grammaires:

analyse_G(M) :- M= [c].

analyse_G(M) :- M = [a]o M1o[b], analyse_G(M1).

Mais à cause de la restriction sur la concaténation, cette dérivation ne peut être généralisée.

Page 40: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

40

Analyse syntaxique(cont. 1)

Exemple: la grammaire suivante d’axiome A

A -> X Y

X ->

X -> a X b

Y ->

Y -> c Y

La démonstration de analyse-G([a, b, c]) pose l’équation:

M = M1o M2 et demande les démonstrations de

analyse_X([M1]) et de analyse_Y(M2)

qui ne terminent pas

Page 41: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

41

Analyse syntaxique(cont. 2)

Une solution correcte mais très inefficace: remplacer les contraintes sur les listes par des contraintes sur les arbres. Exemple:

analyse_G(M) :- concat(M1, M2, M), analyse_X(M1), analyse_Y(M2).

Autre solution. Idée: « préparer » la concaténation à droite. Formellement: faire abstraction du suffixe d’une chaîne , ie au lieu de considérer qu’il s’agit de la chaîne vide, on l’ »abstrait » (on le considère comme inconnu). En lambda-calcul, la représentation serait l’abstraction S.M o S où M est la chaîne et S le suffixe.

Pratiquement, en Prolog qui est basé sur la logique du 1er ordre (sans lambda-expression): une chaîne est représentée par [C, S ] comme le préfixe de la chaîne C dont le suffixe est S (« difference list »).

Exemple: [[a, b, c| S], S] est la représentation de la chaîne abc.

Page 42: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

42

Analyse syntaxique(cont. 3)

Pratiquement, la représentation que nous adoptons en Prolog ne permet qu’une seule application pour une -expression.

D’un point de vue mathématique, la concaténation des listes

X = S.M1 o S et Y = S.M2 o S est

Z = S.M2 o S

Z est le résultat de l’application de X sur Y.

Page 43: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

43

Analyse syntaxique(cont. 4)

La concaténation devient:concat1([C1, S1], [C2, S2], [C, S]) :- C = C1, S1 = C2, S = S2. et d’une façon générale (n 0):concatn([C, S1], [S1, S2], … [Si-1 , Si], [Si , Si+1], …[Sn, S], [C, S]).

Exemple:analyse_A([C, S]) :- analyse_X([C, S1]), analyse_Y([S1, S]).

analyse_X([S, S]).analyse_X([C, S]) :- mot(C, a, S1), analyse_X([S1, S2]),

mot(S2, b, S).analyse_Y([S, S]).analyse_Y([C, S]) :- mot(C, c, S1), analyse_Y([S1, S]).où: mot([X|S], X, S).

Page 44: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

44

Analyse syntaxique(cont. 5)

analyse_A([C, S]) se lit: vrai si C débute par une dérivation du non-terminal A et se termine par S.

Remarque: analyse_A([[a, b, c], []]) est vrai si abc est une dérivation de A.

Note: la chaîne vide est représentée formellement par la fonction identité, soit S.S.

Page 45: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

45

Analyse syntaxique(cont. 6)

Dans le cas général, pour la règle hors contexte:

X0 X1 … Xn, n 0

on obtient la clause:

analyse_ X0([C, S]) :- p1(C1,S1), …, pn(Cn,Sn).

avec C1 = C, Sn = S

Et

si Xi est non terminal, alors pi(Ci, Si) est:

analyse_ Xi([Ci, Si]) avec Ci = Si-1 et S0= C

si Xi est terminal, alors pi(Ci, Si) est:

mot(Ci, Xi, Si) avec Ci = Si-1

Page 46: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

46

Traduction

Principe de composition (dit aussi de FREGE): la valeur d’un tout est une fonction de la valeur de ses composants.

Peut sembler trivial. En fait une méthode de construction de définitions (et du coup de programmes) très utile.

Exemple: on considère les expressions décrites par la grammaire G suivante d’axiome E:E TE T + ET FT F * TF aF bF cF ( E )

Page 47: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

47

Traduction(cont. 1)

Il s’agit de définir la traduction d’une telle expression dans le langage des termes A suivants: a, b, c, plus2(A1, A2), mul2(A1, A2) où A1 et A2 sont de type A. Donc de définir le prédicat tradE_A([C, S ], A) : vrai si C débute par une dérivation de E dont la traduction est A et se termine par S.

tradE_A([C, S ], A) :- tradT_A([C, S ], A) .

tradE_A([C, S ], A) :- tradT_A([C, S1 ], A1), mot(S1, +, S2),

tradE_A([S2, S ], A2), A=plus2(A1, A2).

tradT_A([C, S ], A) :- tradF_A([C, S ], A) .

tradT_A([C, S ], A) :- tradF_A([C, S1 ], A1), mot(S1, *, S2),

tradT_A([S2, S ], A2), A=mul2(A1, A2).

tradF_A([C, S ], a) :- mot(C, a, S). …

tradF_A([C, S ], A):- mot(C, ‘(, S1). tradE_A([S1, S2], A),

mot(S2, ‘), S).

Page 48: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

48

Traduction(cont. 2)

Le principe de composition s’applique sans difficulté. La décomposition est donnée par les règles de grammaire. Les valeurs des expressions termes et facteurs sont des arbres. La recomposition des valeurs est donné par construction de nouveaux arbres.

Un programme se déduit aisément de cette spécification pour une requête où la taille de la chaîne C est donnée. En effet, la démonstration termine car la taille de C diminue strictement pour des démonstrations successives portant sur un même prédicat.

Nous procédons dans ce qui suit à une étude montrant la nécessité de revenir sur la décomposition (ie déterminer de nouvelles grammaires pour le même langage) et sur la notion de valeur à associer à un composant (abstraction comme dans les grammaires de Montague)

Page 49: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

49

Traduction(cont. 3)Les opérateurs que nous avons considérés (+ et *) sont associatifs ((a + b) + c = a + (b+ c)). Introduisons l’opérateur - qui ne l’est pas et le terme moins2(A1, A2) dans le langage des termes.

Une idée immédiate consiste à remplacer + par - (et plus2 par moins2).

E T

E T - E

avec

tradE_A([C, S ], A) :- tradT_A([C, S ], A) .

tradE_A([C, S ], moins2(A1, A2)) :- tradT_A([C, S1 ], A1), mot(S1, -, S2), tradE_A([S2, S ], A2).

Ce n’est pas bonne idée. En effet

tradE_A([[a, -, b, - , c], []], A) donne A = moins2(a, moins2(b, c)) qui n’est pas la bonne traduction, mais celle de a – (b – c).

Rappel: C’est opérateur le plus à gauche qui a la plus forte priorité.

Page 50: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

50

Traduction(cont. 4)La méthode consiste à reprendre le principe de composition et à rechercher une nouvelle décomposition, c’est-à-dire une grammaire différente, mais toujours pour le même langage.

Un bonne décomposition est la suivante:

E T

E E - T

avec

tradE_A([C, S ], A) :- tradT_A([C, S ], A) .

tradE_A([C, S ], moins2(A1, A2)) :- tradE_A([C, S1 ], A1),

mot(S1, -, S2), tradT_A([S2, S ], A2).

Malheureusement, cette fois, c’est le démonstrateur (+ notre représentation pour les chaînes) qui flanche:

tradE_A([[a, -, b, - , c], []], A) ne termine pas, comme c’est la cas pour les analyseurs descendants, à cause de la récursivité à gauche (sur E).

Page 51: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

51

Traduction(cont. 5)Une autre grammaire doit donc être construite avec les caractéristiques suivantes: non récursive à gauche, mettant en évidence l’opérateur – et son opérande droit. La grammaire suivante (où RT, pour « reste de terme », est un nouveau non-terminal) convient:

E -> T RT

RT ->

RT -> - T RT

Le traducteur qui s’en déduit pour E:

tradE_A([C, S ], A) :- tradT_A([C, S1 ], A1), tradRT_V([S1, S ], V),

composition(A, A1, V).

pose naturellement:

- la question de la nature de la valeur V d’un reste de terme et

- celle la composition des valeurs A1 et V qui doit donner celle d’une expression, c’est-à-dire A.

Page 52: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

52

Traduction(cont. 6)Un exemple dans un autre domaine permet d’éclairer la démarche pour déterminer V et la composition recherchée.

En linguistique, on se pose typiquement le problème de la traduction de groupe nominaux du type:

La maison qui est belle

dans un langage logique, en l’occurrence ici en la formule atomique: belle(maison).

Le problème rencontré est similaire au nôtre dans la mesure où la décomposition fait apparaître la proposition relative (le sujet est inconnu comme le premier opérande du premier – dans un reste de terme).

La solution est de donner à une subordonnée la valeur d’une principale dans laquelle le référent (ici maison) est « abstrait » (ie inconnu): X. belle (X). La composition est alors l’application de cette fonction sur le référent, soit:

(X. belle (X))(maison) =belle(maison)

Page 53: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

53

Traduction(cont. 7)

Comme dans le cas des « difference lists », une lambda-expression X.F.est représentée en Prolog par un couple : nous le notons ici lambada[X, F]. L’application, comme on l’a vu, ne peut avoir lieu qu’une fois (ici, comme dans le cas des « difference lists » ce n’est pas gênant). On obtien,

tradE_A([C, S ], A) :- tradE_A([C, S1 ], A1),

tradRT_V([S1, S ], lambada(X, A2)),

A = A2, X = A1.

De la même façon:

tradRT_A ([C, S ], lambada(X, X)).

tradRT_A ([C, S ], lambada(Z, A)) :- mot(C, -, S1),

tradE_A([S1, S2], A1),

tradRT_V([S2, S ], lambada(X, A2)),

A = A2, X = moins(Z, A1).

Page 54: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

54

Traduction(cont. 7)Remarque1: dans cette dernière règle la valeur de Z. A est le résultat de l’application de X. A2 à la valeur du reste de terme - T, c’est-à-dire Y. A1. Exercice:

Soit X. A2 = X. moins(X, c), Y. A1= Y. moins(Y, b). Déterminer Z. A.

Remarque2: la règle définissant tradE_A s’écrit aussi

tradE_A([C, S ], A2) :- tradE_A([C, S1 ], A1),

tradRT_V([S2, S ], lambada(A1, A2)).

qui fait apparaître une exécution qui n’est pas celle naturellement issue du principe de composition. Il n’y a pas contradiction: celui-ci est utilisé à des fins de spécification.

Page 55: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

55

6. Contraintes numériquesContraintes linéaires:

relations: =, >, dif(X, Y)

opérations: +, -, *, /

Restriction: dans un produit X*Y, X ou Y doit être connu.

Exemple:

nbpattestêtes(Chats, Oiseaux, Np, Nt):-

Np = 4* Chats + 2* Oiseaux, Nt =Chats + Oiseaux,.

Exercice: réponses aux requêtes:

nbpattestêtes(Chats, Oiseaux, 16, 5).

nbpattestêtes(Chats, Oiseaux, 3, 1).

Page 56: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

56

Contraintes + heuristique d’énumération

Illustration de la méthodologie contraintes + heuristiques d’énumération: le cas de la recherche des solutions entières.

Exemple ( cryptogramme):

Déterminer S, E, N, D, M O, R, Y entiers de 0 à 9 tels que l’addition:

S E N D+ MORE------------- M O N E Y

soit vérifiée.Il s’agit de définir solution_crypt([S, E, N, D, M, O, R, Y]) vrai si les variables S, E, N, D, M, O, R et Y répondent aux conditions précédentes.

Page 57: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

57

Contraintes + heuristique d’énumération (cont. 1)

solution_crypt([S, E, N, D, M, O, R, Y]) :-

tous_differents([S, E, N, D, M, O, R, Y]),

K1 = 1000*S + 100*E + 10*N + D,

K2 = 1000*M + 100*O + 10*R + E,

K3 = 10000*M + 1000*O + 100*N + 10*E + Y,

K3 = K1 + K2, dif(S, 0), dif(M,0),

/* fin de la partie contraintes, suit l’énumération*/

enumeration([S, E, N, D, M, O, R, Y]).

Exercice: trouver un « bon » (efficace) ordre dans lequel énumérer (voir ci-après) les variables (qui n’est pas forcément S, E, N, D, M, O, R, Y). C’est tout l’art de déterminer une heuristique (méta-connaissance). Par exemple, en énumérant d’abord les variables intervenant dans le plus grand nombre de contraintes.

Page 58: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

58

Contraintes + heuristique d’énumération (cont. 2)

tous_differents([]).

tous_differents([X | L]) :- 0 X, X 9, different(X, L), tous_differents(L)

different(X, []).

different(X, [Y | L]):- dif(X, Y), different(X, L).

enumeration([]).

enumeration([X | L]) :- enum0_9(X), enumeration(L).

enum0_9(0).

enum0_9(1).

enum0_9(9).

Page 59: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

59

Démonstration automatiqueIllustrations de l’utilisation d’un résolveur pour la démonstration automatique (en particulier de formules universelles). A noter: le démonstrateur Prolog permet de faire de la démonstration, mais, comme on l’a vu, elle n’est pas vraiment automatique, il faut quelquefois l’aider pour que la démonstration termine.

Méthode pour démontrer X P(X) => Q(X): montrer que ¬(X P(X) => Q(X)) n’est pas satisfaisable. Soit montrer que X ¬( P(X) => Q(X)) ou encore X P(X) ¬ Q(X) n’est pas satisfaisable.

Exemple: le théorème de Varigon: « pour tout quadrilatère ABCD, le quadrilatère des milieux M1 M2 M3 M4 (M1 (resp. M2, M3, M4) milieu de AB(resp. BC, CD, DA)) est un parallélogramme ».

Il s’agit de montrer que la proposition »il existe un quadrilatère ABCD pour lequel le quadrilatère des milieux n’est pas un parallélogramme » n’ est pas satisfaisable.

Page 60: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

60

A

B

C

D

M4

M2

M1

M3

IJ

Démonstration automatique. Fig.

Page 61: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

61

Démonstration automatique (cont. 1)Sachant qu’un parallélogramme est caractérisé par le fait que ses deux digaonales se coupent en leur mieux, il vient:

varignon :- neg_par_echec(non_varignon_possible).

non_varignon_possible: - milieu(A, B, M1), milieu(B, C, M2),

milieu(C, D, M3), milieu(D, A, M4),

milieu(M2, M4, J), milieu(M1, M3, I),

dif(I, J) /* négation de la conclusion*/.

milieu([X1, YI], [X2, Y2], [X, Y]) :- X = (X1 + X2) / 2,

Y = (Y1 + Y2) / 2.

Bien noter la nécessité que les équations posées soient linéaires (c’est le cas ici).

Page 62: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

62

Démonstration automatique (cont. 2)

Autre exemple: montrer que toute suite entière telle que ui+2= |ui+1 | - ui a une période de 9.

periode9 :- neg_par_echec(periode9_non_possible).

periode9_non_possible :- size(11, S), bonne_suite(S),

size(2, S1), size(7, S2), size(2, S3), S = S1 o S2 o S3,

dif(S1, S3) /* négation de la conclusion*/.

bonne_suite([X1, X0]).

bonne_suite(S o [X2, X1, X0]) :-

val_abs(X1, X1p), X2 = X1p – X0,

bonne_suite(S o [X2, X1]).

val_abs(X, X) :- X 0.

val_abs(X, -X):- X < 0.

Page 63: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

63

7. Arbres infinis rationnelsIntroduits naturellement par des équations au point fixe sur les arbres.

Exemple: X = f(1, X)

Deux approches sont possibles:

-on admet que ces systèmes ont des solutions: des arbres infinis dits rationnels dans la mesure où ils possèdent un nombre fini de sous-arbres.

-Exemple: dans le cas précédent X admet deux sous-arbres : 1 et X.

--on rejette ces systèmes pour des raisons théoriques (intuitivement, il devient possible qu’un système cohérent sur les arbres ne le soit pas si on donne des significations aux foncteurs: f(X, 4) = f(3, Y) est cohérent si f est interprété par + ou par *, ce n’est pas le cas pour X = f(1, X)). Ce rejet est coûteux: il faut vérifier que chaque unification ne donne pas lieu à de telles équations.

Page 64: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

64

f

f

1

1

1 …

f

1

f

Grâce aux arbres infinis on dispose en Prolog IV des graphes finis comme des « valeurs à part entière », c’est-à-dire manipulable comme des touts

X =

Arbres infinis rationnels. Fig.

Page 65: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

65

Arbres infinis rationnels (cont. 1)

f

f

1

1

f

g

gg

… ….

Il existe bien sur des arbres infinis non rationnels.

Exemple:

Page 66: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

66

Arbres infinis rationnels (cont. 2)

Illustrations:

- d’une part, de représentation à l’aide de graphe fini et d’utilisation (grammaire et analyse syntaxique)

- d’autre part, de la construction de graphes finis et de la terminaison de parcours (substitution appliquée à un arbres infini rationnel)

Page 67: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

67

Grammaire et analyse syntaxique

Exemple de graphe fini: à un non terminal est associé un arbre ou et à une règle un arbre et:

E T

E T + E

T F

T F * T

F a

F b

F c

F ( E )

ou

et

ou

et

ou

et et et

et

et

a

et

b c ( )

+

*

Page 68: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

68

Grammaire et analyse syntaxique(1)

Cet arbre est E, solution du système suivant:

E = ou (et(T), et(T, +, E)),

T = ou (et(F), et(F, *, T)),

F= ou(et(a), et(b), et(c), et(‘(‘, E, ‘)’)).

L’objectif consiste à construire:

analyse_G(G, [C, S]): vrai si C commence par la dérivation du nom terminal G (représenté par un arbre infini) et se termine par S.

Exemple:

analyse_G(E, [[a, +, b, * , c], []]) est vrai.

Page 69: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

69

Grammaire et analyse syntaxique(2)

Les sous-arbres sont soit une feuille, soit de la forme ou(…) , soit de la forme et(…).

On utilise la contrainte =.. telle que: f(X1, …, Xn) =.. [f, X1, …, Xn]

analyse_G(G,[C, S]) :- leaf(G), mot(C, G, S), dif(G, et).

analyse_G(G,[C, S]) :- G =.. [ou | [R|L_r]], analyse_G(R, [C, S]).

analyse_G(G,[C, S]) :- G =.. [ou | [R|L_r]], Gp =..[ou | L_r], analyse_G(Gp, [C, S]).

analyse_G(G,[S, S]):- G =.. [et | []].

analyse_G(G,[C, S]) :- G =.. [et | [E|L_e]], analyse_G(E, [C, S1]),

Gp =..[et| L_e], analyse_G(Gp, [ S1, S]).

NB: il y a terminaison si la taille de C est connue

Page 70: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

70

SubstitutionIl s’agit de donner une méthode assurant la terminaison dans le cas où le graphe est parcouru et contient des cycles.

Exemple:

subst(A1, A2, X, Y): vrai si l’arbre A2 est l’arbre A1 dans lequel les feuilles X sont remplacées par Y. On suppose que les arbres sont de la classe A qui sont des feuilles ou de la forme f(A1, A2) où A1et A2 sont des arbres de la classe A.

Exemple: subst(f(a, b), f(b, b), a, b) est vrai.

En supposant que A1 et A2 sont finis, on obtient:

subst(A1, A2, X, Y):- leaf(A1), leaf(A2), A1= X, A2 = Y.

subst(A1, A2, X, Y):-l eaf(A1), leaf(A2), dif(A1, X), A2 = A1.

subst(A1, A2, X, Y):- A1 = f(A11, A12), A2 = f(A21, A22),

subst(A11, A21, X, Y), subst(A12, A22, X, Y).

Page 71: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

71

f

f

a

f

f

aab

A1 = f(a, f(A1, b)), subst(A1, A2, b, a).

Substitution (cont. 1)

Page 72: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

72

Substitution (cont.2)Si A1 et A2 peuvent être infinis, il est nécessaire d’introduire une liste d’ancêtres L_a pour obtenir des chemins finis: la décomposition d’un arbre n’est considérée que si cet arbre n’appartient pas à L_a.

subst(A1, A2, X, Y):- substp(A1, A2, X, Y, []).

substp(A1, A2, X, Y, L_a):- leaf(A1), leaf(A2), A1= X, A2 = Y.

subspt(A1, A2, X, Y, L_a):- leaf(A1), leaf(A2), dif(A1, X), A2 = A1.

substp(A1, A2, X, Y, L_a):- membre([A1, A2], L_a).

substp(A1, A2, X, Y, L_a):- non_membre([A1, A2], L_a),

A1 = f(A11, A12), A2 = f(A21, A22),

substp(A11, A21, X, Y, [[A1, A2] | L_a]),

substp(A21, A22, X, Y, [[A1, A2] | L_a]).

NB: On remarque qu’il y a terminaison si la profondeur de A1 où celle de A2 est connue.

Page 73: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

73

Unification et arbres infinis rationnels

L’unification de deux arbres infinis nécessite un algorithme étendu.

Exemple: il faut détecter la satisfiabilité du système:

X = f(1, X), Y = f(1, f(1, Y)), X = Y

Un algorithme possible conserve les associations des sous-arbres (gauches et droits) déjà considérés comme des couples (arbre-g, arbre-d). Chaque fois qu’un sous-arbre gauche est considéré à nouveau, c’est son arbre droit dans l’association qui est considéré pour l’unification.

Exemple: pour le système précédent, on donne les couples successifs (arbre-g, arbre-d) mis en jeu successivement.

Page 74: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

74

f

1f

fY =

X =

1

1

1

1

2

23

3

4

4

5

5

Unification et arbres infinis rationnels(cont.1)

Page 75: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

75

8. Suspension de processus

Il s’agit de la quatrième règle de dérivation pour produire un programme à partir d’une spécification. L’idée consiste à permettre un « cadencement » entre des démonstrations pour les terminer plus rapidement.

La nouvelle structure de contrôle est:

freeze(X, B):

-vrai si B est vrai

-retarde la démonstration de B si X n’est pas « connu ». X est dit connu  si: l’étiquette (ie le foncteur) de X est connu et si on sait si les nombre de feuilles de X est nul ou non.

Exemples: dans les cas suivants X est connu: X = 1, X = [], X = [E| L]

Les démonstrations dépendantes de X sont prioritaires si X devient connu.

Exemple: freeze(X, B), B1, X = 3, B2. La démonstration de B est prioritaire par rapport à celle deB2.

Entre deux démonstrations dépendantes de X, la priorité n’est pas définie.

Page 76: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

76

Suspension de processus (cont. 1)

Exemple:

même_mot_feuilles(A1, A2): - mot_feuilles(A1, M), mot_feuilles(A2, M).

mot_feuilles(A2, M): vrai si M est le mot des feuilles (liste des feuilles de gauche à droite) de l’arbre A. On suppose que les arbres sont de laclasse A qui sont des feuilles ou de la forme f(A1, A2) où A1et A2 sont des arbres de la classe A.

mot_feuilles(A, [A]) :- leaf(A).

mot_feuilles(f(A1, A2), [A1| M]) :- leaf(A1), mot_feuilles(A2, M).

mot_feuilles(f(f(A11, A12), A2), M) :-

mot_feuilles(f(A11, f(A12, A2)), M) .

Page 77: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

77

Suspension de processus (cont. 2)

Une démonstration de même_mot_feuilles(A1, A2) où A1 et A2 sont connus procède par production et vérification (« generate and test ») de M. Elle peut être très coûteuse si par exemple, M est très grand et si les deux arbres diffèrent dès la première feuille.

Exemple:

même_mot_feuilles(f(a, f(b, c)), f(f(b, b), c))

La démonstration échoue seulement après que le mot des feuilles de f(a, f(b, c)) (soit [a, b, c]) ait été totalement produit alors que celui-ci diffère du mot des feuilles du second arbre (soit [b, b, c]) par son premier élément. Il serait plus efficace de considérer ces deux mots de feuilles de façon symétrique en comparant leurs deux premiers éléments, puis les deux suivants…etc, c’est-à-dire en cadençant les démonstrations des formules mot_feuilles(f(a, f(b, c)), ) et mot_feuilles(f(f(b, b), c))).

Page 78: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

78

Suspension de processus (cont. 3)

La méthode de dérivation est basée d’une part sur l’identification d’un producteur et d’un ou plusieurs consommateurs, d’autre part sur l’activation du (ou des) consommateur(s) une fois la production d’un élément (notion à préciser par le concepteur) faite et la reprise du producteur après ces consommations.

Cette méthode est illustrée sur un exemple artificiel trivial. Soit prod(D, T) le producteur (produisant une liste T à partir d’une liste donnée D et conso(T, R) le consommateur de T fournissant en résultat la liste R. Si p(D1, T1) et c(T1, R1) modélisent respectivement les productions et consommations élémentaires, on obtient:

programme :- prod(D, T), conso(T, R).

prod([],[]).

prod([D1 | D], [T1| T]) :- p(D1, T1), prod(D, T).

conso([],[]).

conso([T1 | T], [R1| R]) :- c(T1, R1), conso(T, R).

Page 79: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

79

Suspension de processus (cont. 4)La transformation vise simplement mettre en attente de T le consommateur (et à le déclencher d’abord) et à laisser le producteur le reprendre.

Concernant l’exemple précédent, pour montrer que c’est au concepteur de décider ce qu’est une production élémentaire, on décide que la production élémentaire est accomplie après la démonstration de p(D1, T1) . On obtient (les transformations sont indiquées en rouge).

programmep :- consop(T, R), prodp (D, T).

consop(T, R) : - freeze(T, conso(T, R)).

prodp([],[]).

prodp([D1 | D], M) :- p(D1, T1), M = [T1|T], prodp(D, T).

conso([],[]).

conso([T1 | T], [R1| R]) :- c(T1, R1), consop (T, R).

Page 80: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

80

Suspension de processus (cont. 5)L’application de la méthode à meme_mot_feuilles, en choisissant mot_feuilles(A1, M) comme producteur donne:

même_mot_feuillesp(A1, A2): - mot_feuillesp (A2, M), mot_feuillespp(A1, M).

mot_feuillesp(A2, M) :- freeze(M, mot_feuilles(A2, M))

mot_feuilles(A, [A]) :- leaf(A).

mot_feuilles(f(A1, A2), [A1| M]) :- leaf(A1), mot_feuillesp(A2, M).

mot_feuilles(f(f(A11, A12), A2), M) :-

mot_feuilles(f(A11, f(A12, A2), M) .

NB. On note que dans la troisième règle, il n’est pas nécessaire de placer le consommateur en attente.

Page 81: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

81

Suspension de processus (cont. 6)

La production élémentaire demande que la première feuille du mot des feuilles du producteur soit connue:

mot_feuillespp(A, [A]) :- leaf(A).

mot_feuillespp (f(A1, A2), Mp) :- leaf(A1),

Mp = [A1|M], mot_feuillespp (A2, M).

mot_feuillespp (f(f(A11, A12), A2), M) :-

mot_feuillespp (f(A11, f(A12, A2), M) .

Page 82: 1 1. HISTORIQUE Origine PROLOG : PROgrammation LOGique. 1967 : SIMULA 67 1972 : introduit par Alain COLMERAUER. Ce langage permet une programmation « déclarative

82

Suspension de processus (cont. 7)

On peut aussi concevoir un producteur artificiel, dont le rôle est de cadencer les consommateurs.

Exemple: un producteur fournit successivement les éléments du mot du feuille.

même_mot_feuilles(A1, A2): - mot_feuillesp (A1, M), mot_feuillesp (A2, M),

liste(M).

liste ([]).

liste([E|M]):- liste(M).