c 2006 Marc Feeley IFT2030 page 220
Définition de macros (1)
•
Les macros en Lisp et Scheme tirent avantage de la similitude des données et expressions (la syntaxe des expressions est un sous-ensemble de la syntaxe des données)•
Ainsi l’expression (and x y) se représente avec la liste (and x y)•
Une macro sera vue comme une fonction de transformation qui prend en paramètre lareprésentation des paramètres actuels de l’appel de macro, et qui retourne comme résultat la
représentation de l’expression qui est l’expansion de la macro
c 2006 Marc Feeley IFT2030 page 221
Définition de macros (2)
•
Exemple: définition d’une macro “and”Il faut transformer (and X Y ) en (if X Y #f) (define-macro and
(lambda (x y)
(list ’if x y #f)))
•
Cette fonction de transformation est appelée à lacompilation sur l’ASA qui est justement représenté sous forme de liste
c 2006 Marc Feeley IFT2030 page 222
Définition de macros (3)
•
Ainsi le programme(define-macro and (lambda (x y)
(list ’if x y #f))) (define f
(lambda (x)
(if (and (<= 0 x) (<= x 9)) (g x)
’erreur)))
sera expansé en
(define f
(lambda (x)
(if (if (<= 0 x) (<= x 9) #f) (g x)
’erreur)))
c 2006 Marc Feeley IFT2030 page 223
Définition de macros (4)
•
Puisque les formes spéciales prédéfinies et les macros utilisent la même syntaxe préfixe parenthésée, il n’y a pas de distinction d’utilisation entre elles et l’usagerpeut ainsi intégrer naturellement ses propres extensions au langage de base
•
On parle de langage à domaine spécifique (“domain specific language”)c 2006 Marc Feeley IFT2030 page 224
Définition de macros (5)
•
Par exemple, pour écrire des “boucles” dans le style de Pascal on aimerait une macro “for” avec la syntaxe(for hvariablei := hexpr1i to hexpr2i do hexpr3i)
•
Cela permet de faire(for i := 1 to 10 do (write i))
c 2006 Marc Feeley IFT2030 page 225
Définition de macros (6)
•
(for hvariablei := hexpr1i to hexpr2i do hexpr3i)doit donc s’expandre à
(let ((debut hexpr1i) (fin hexpr2i)) (define boucle
(lambda (hvariablei)
(if (<= hvariablei fin) (begin hexpr3i
(boucle (+ hvariablei 1)))))) (boucle debut))
c 2006 Marc Feeley IFT2030 page 226
Définition de macros (7)
•
Définition basée sur “list”(define-macro for
(lambda (variable _1 expr1 _2 expr2 _3 expr3) (list ’let
(list (list ’debut expr1) (list ’fin expr2)) (list ’define
’boucle
(list ’lambda
(list variable) (list ’if
(list ’<= variable ’fin) (list ’begin
expr3
(list ’boucle
(list ’+ variable 1))))))
’(boucle debut))))
c 2006 Marc Feeley IFT2030 page 227
Définition de macros (8)
•
L’utilisation de “list” pour cette macro donne une définition difficile à lire; il est mieux de construire des listes “quasi-constantes” à l’aide de la forme spéciale“quasiquote”:
`(a b ,X c (,Y d))
=
(list ’a ’b X ’c (list Y ’d))
•
La donnée construite correspond au patron avec desvaleurs calculées insérées aux endroits précédés d’une virgule
c 2006 Marc Feeley IFT2030 page 228
Définition de macros (9)
•
Définition basée sur “quasiquote”(define-macro for
(lambda (variable _1 expr1 _2 expr2 _3 expr3)
`(let ((debut ,expr1) (fin ,expr2)) (define boucle
(lambda (,variable)
(if (<= ,variable fin)
(begin ,expr3 (boucle (+ ,variable 1)))))) (boucle debut))))
•
Ces définitions engendrent malheureusement un conflit de nom dans certains cas (par exemple, si la variable se nomme “fin” ou le corps fait référence à unevariable “fin”)
c 2006 Marc Feeley IFT2030 page 229
Définition de macros (10)
•
Solution 1: utilisation de fonctions d’O.S.(define-macro for
(lambda (variable _1 expr1 _2 expr2 _3 expr3)
`((let ()
(define boucle
(lambda (i fin corps) (if (<= i fin)
(begin (corps i) (boucle (+ i 1) fin corps))))) boucle)
,expr1 ,expr2
(lambda (,variable) ,expr3))))
c 2006 Marc Feeley IFT2030 page 230
Définition de macros (11)
•
Solution 2: utilisation de “gensym” qui crée dessymboles qui sont garantis d’être différent de tout autre symbole
(define-macro for
(lambda (variable _1 expr1 _2 expr2 _3 expr3)
(let ((debut (gensym)) (fin (gensym)) (boucle (gensym)))
`(let ((,debut ,expr1) (,fin ,expr2)) (define ,boucle
(lambda (,variable)
(if (<= ,variable ,fin)
(begin ,expr3 (,boucle (+ ,variable 1)))))) (,boucle ,debut)))))
c 2006 Marc Feeley IFT2030 page 231
Définition de macros (12)
•
Solution 3: utilisation de “syntax-rules” (propre à R5RS) un mécanisme de définition de macros“hygiéniques” définis par des règles de transformation à base de patrons
(define-syntax for
(syntax-rules (:= to do)
((for variable := expr1 to expr2 do expr3) (let ((debut expr1) (fin expr2))
(define boucle
(lambda (variable)
(if (<= variable fin) (begin expr3
(boucle (+ variable 1)))))) (boucle debut)))))
c 2006 Marc Feeley IFT2030 page 232
Interprètes et compilateurs (1)
•
Une machine est capable d’exécuter un programme exprimé dans son langage source Ls•
Un interprète est un programme exprimé en langage hôte Lh capable d’exécuter un programme exprimé dans le langage source Ls•
Un compilateur est un programme exprimé en langage hôte Lh capable de traduire un programme en langage source Ls en un programme en langage cible Lcc 2006 Marc Feeley IFT2030 page 233
Interprètes et compilateurs (2)
•
La notation graphique suivante permet de spécifier les langages impliqués dans chaque cas:Ls Lc
Lh Ls
Lh Ls
interprète
machine compilateur
•
Exempleslang.
ass.
MIPS Scheme
MIPS L.M.
i386
L.M.
MIPS JVM
C MIPS
L.M.
C
MIPS
L.M.
MIPS MIPS
L.M. L.M. L.M.
c 2006 Marc Feeley IFT2030 page 234
Interprètes et compilateurs (3)
•
Un interprète ou compilateur exécutable peut êtreobtenu en combinant des machine(s), interprète(s) et compilateur(s)
C
MIPS
L.M.
MIPS
L.M.
L.M.
MIPS
L.M.
MIPS JVM
C
L.M.
MIPS Scheme
MIPS L.M.
L.M.
MIPS
Scheme
C
MIPS L.M.
C
JVM
L.M.
MIPS Java JVM
C
Java C
Java
Java
JVM C
L.M.
MIPS C
L.M.
MIPS
JVM
L.M.
MIPS L.M.
MIPS
c 2006 Marc Feeley IFT2030 page 235
Interprètes et compilateurs (4)
•
Problème du “bootstrap” d’un compilateur: comment créer un nouveau compilateur pour un langage Ls?•
Le compilateur peut être écrit dans n’importe quel langage hôte Lh•
Évidemment c’est mieux si Lh est un langage de haut niveau (par exemple Scheme ou C) car si Lh est lelangage machine/assembleur cela prendra beaucoup d’efforts de développement (mais c’est ce qui a été fait pour FORTRAN!)
c 2006 Marc Feeley IFT2030 page 236
Interprètes et compilateurs (5)
•
S’il existe déjà un interprète ou compilateur pour Ls il est pratique d’écrire un compilateur autogènec’est-à-dire où Ls = Lh
•
Gambit:Scheme
L.M.
M68K
Scheme GAMBIT V1
Scheme
L.M.
M68K
Scheme GAMBIT V1
L.M.
Scheme
M68K MIT-SCH.
L.M.
M68K
L.M.
M68K Scheme
L.M.
M68K GAMBIT V1
L.M.
M68K
L.M.
M68K Scheme
L.M.
M68K
L.M.
M68K GAMBIT V2 Scheme
L.M.
M68K
Scheme GAMBIT V2
L.M.
M68K Scheme
L.M.
M68K
Scheme GAMBIT V2
Scheme
L.M.
M68K
L.M.
M68K GAMBIT V2
c 2006 Marc Feeley IFT2030 page 237
Interprètes et compilateurs (6)
•
Avantages1. autosuffisance (pas besoin d’un autre compilateur ou interprète pour la maintenance et extensions)
2. amélioration de la qualité du code généré a un impact sur la performance du compilateur (p.e. réduction du temps de compilation)
c 2006 Marc Feeley IFT2030 page 238
Interprètes et compilateurs (7)
•
Le cas analogue pour les interprètes, c’est-à-dire Ls = Lh, se nomme interprète méta-circulaire•
La compilation d’un interprète méta-circulaire permet d’obtenir un interprète exécutable•
Exemple de l’interprète Gambit:L.M.
M68K
L.M.
Scheme
M68K GSI Scheme
GSI
Scheme Scheme
L.M.
M68K
L.M.
M68K GSC
c 2006 Marc Feeley IFT2030 page 239
Interprètes et compilateurs (8)
•
De plus, un interprète méta-circulaire peut servir à décrire et éclaircir la sémantique d’un langage de programmation et le fonctionnement des interprètes (méta-circulaires ou non)c 2006 Marc Feeley IFT2030 page 240
Interprète méta-circulaire (1)
•
L’implantation d’un interprète méta-circulaire pour Scheme est simplifiée par le fait que la syntaxe dulangage source est un sous-ensemble de la syntaxe des données
•
Ainsi la liste (set! x (cdr x)) peut servir de représentation pourl’expression (set! x (cdr x))
•
De plus, il est possible de représenter les données manipulées par le programme interprété parelles-mêmes (par exemple si le programme interprété exécute (cons 1 2) l’interprète construira la paire (1 . 2) directement)
c 2006 Marc Feeley IFT2030 page 241
Interprète méta-circulaire (2)
•
Nous allons écrire un interprète pour unsous-ensemble de Scheme (petit nombre de fonctions et seulement les formes spéciales quote, set!,
lambda, begin, cond, define et define-macro)
•
Problèmes principaux1. représentation de l’environnement d’évaluation 2. représentation des fonctions
c 2006 Marc Feeley IFT2030 page 242
Interprète méta-circulaire (3)
•
Commençons par un interprète simple qui traite seulement les constantes et l’appel de fonction•
L’interprète prend la représentation d’une expression en paramètre et calcule sa valeur(eval ’(+ (* 2 3) 4)) => 10
•
Implantation de l’interprète:(define eval (lambda (e)
(cond ((pair? e)
(let ((op (car e))
(a1 (eval (cadr e))) (a2 (eval (caddr e))))
(cond ((eq? op ’+) (+ a1 a2)) ((eq? op ’-) (- a1 a2)) ((eq? op ’*) (* a1 a2))
(else (error "erreur"))))) (else
e))))
c 2006 Marc Feeley IFT2030 page 243
Interprète méta-circulaire (4)
•
Voici une version plus extensible:(define eval (lambda (e)
(cond ((pair? e)
(let ((fn (lookup (car e) table)) (a1 (eval (cadr e)))
(a2 (eval (caddr e)))) (fn a1 a2)))
(else e)))) (define lookup
(lambda (sym env)
(let ((x (assoc sym env)))
(if x (cdr x) (error "erreur"))))) (define table
(list (cons ’+ +) (cons ’- -) (cons ’* *) (cons ’/ /)
(cons ’expt expt)))
c 2006 Marc Feeley IFT2030 page 244
Interprète méta-circulaire (5)
•
Et encore plus extensible:(define eval (lambda (e)
(cond ((pair? e)
(let ((fn (lookup (car e) table))) (apply fn (map eval (cdr e))))) (else
e))))
; note: (apply f ’(1 2 3)) = (f 1 2 3) (define table
(list (cons ’+ +) (cons ’- -) (cons ’* *) (cons ’/ /)
(cons ’expt expt) (cons ’log log) (cons ’cos cos)))
(eval ’(+ (log 1) (cos 0) 5)) => 6
c 2006 Marc Feeley IFT2030 page 245
Interprète méta-circulaire (6)
•
Pour traiter les variables on ajoute un paramètre environnement à eval:(define eval
(lambda (e env)
(cond ((symbol? e)
(lookup e env)) ((pair? e)
(let ((ev (lambda (x) (eval x env)))) (apply (ev (car e))
(map ev (cdr e))))) (else
e)))) (define table
(list (cons ’x 5) (cons ’+ +) (cons ’- -) (cons ’* *) (cons ’/ /)))
(eval ’(+ 1 x x) table) => 11
c 2006 Marc Feeley IFT2030 page 246
Interprète méta-circulaire (7)
•
L’environnement d’évaluation est donc représenté par une liste d’association (qui associe la valeur d’une variable avec le symbole qui est le nom de la variable)•
Par exemple si l’environnement contient uniquement les variables x, y et z et que ces variables ontrespectivement les valeurs 1, 2 et 3:
((x . 1) (y . 2) (z . 3))
qui a la forme suivante en mémoire:
()
z 3
y 2
x 1
c 2006 Marc Feeley IFT2030 page 247
Interprète méta-circulaire (8)
•
L’accès aux variables se fait avec assoc:(define env-read
(lambda (env var)
(cdr (assoc var env))))
(define env-set! ; supporte ´egalement "define"
(lambda (env var val)
(cond ((eq? (car (car env)) var) (set-cdr! (car env) val)) ((null? (cdr env))
(set-cdr! env (list (cons var val)))) (#t
(env-set! (cdr env) var val)))))
c 2006 Marc Feeley IFT2030 page 248
Interprète méta-circulaire (9)
•
Le traitement correct des formes spéciales lambda et define demande d’ajouter des nouvelles variables à l’environnement•
Pour lambda on peut simplement ajouter des nouvelles associations à l’avant de l’environnement; ainsil’environnement construit pendant l’évaluation de
((lambda (a y) (list a y z)) 123 999) est
y 2
y
a 123 999 x 1
()
z 3
c 2006 Marc Feeley IFT2030 page 249
Interprète méta-circulaire (10)
•
Extension de l’environnement(define env-extend
(lambda (env parms vals) (cond ((null? parms)
env) (#t
(cons (cons (car parms) (car vals)) (env-extend env
(cdr parms)
(cdr vals)))))))
•
Note: l’ancienne association pour y est cachée (aux yeux de env-read et env-set!) ce qui implante correctement la portée lexicalec 2006 Marc Feeley IFT2030 page 250
Interprète méta-circulaire (11)
•
Pour define, si la variable existe déjà on change sa valeur comme pour un set!•
Sinon on doit ajouter une nouvelle association à l’arrière de l’environnement destructivementAinsi l’environnement sera modifié comme suit pendant l’évaluation de (define b 555)
y 2
x 1
() ()
z 3 b 555
c 2006 Marc Feeley IFT2030 page 251
Interprète méta-circulaire (12)
•
L’environnement doit être étendu destructivement pour implanter correctement les références “vers l’avant”:(define f (lambda (a) (list a b))) (define b 555)
•
Le même mécanisme est utilisé pour implanter define-macroc 2006 Marc Feeley IFT2030 page 252
Interprète méta-circulaire (13)
•
Il y a 2 types de fonctions: les primitives (les fonctions prédéfinies) et les fermetures (créées par l’évaluation de lambda-expressions)•
Pour simplifier, les fonctions sont représentées par des paires• si le car est le symbole prim, la paire représente la fonction primitive dont le nom est le champ cdr,
p.ex. (prim . write)
• sinon, la paire représente une fermeture, le champ car donne les paramètres et le corps de la
lambda-expression qui a engendré cette fermeture et le champ cdr est l’environnement dans lequel cette lambda-expression fut évaluée
c 2006 Marc Feeley IFT2030 page 253
Interprète méta-circulaire (14)
•
Par exemple, si(lambda (a y) (list a y z)) est évaluée dans l’environnement
((x . 1) (y . 2) (z . 3)) le résultat est
(((a y) (list a y z)) . ((x . 1)(y . 2)(z . 3)))
•
Cette fermeture sera scrutée par l’interprète lors de son appelc 2006 Marc Feeley IFT2030 page 254
Interprète méta-circulaire (15)
•
La fonction principale de l’interprète est la fonction eval:(eval hrepr d’une expressioni henvironnementi)
=> hvaleur de l’expressioni Par exemple:
(eval ’(cons 1 2) global-env) => (1 . 2)
•
La boucle d’interaction “read-eval-print” de l’interprète s’implante simplement avec:(define repl (lambda ()
(begin
(write ’>)
(write (eval (read) global-env)) (newline)
(repl))))
c 2006 Marc Feeley IFT2030 page 255
Interprète méta-circulaire (16)
1. (define global-env
2. (list ’(read . (prim . read )) ’(newline . (prim . newline))
3. ’(write . (prim . write )) ’(symbol? . (prim . symbol?))
4. ’(null? . (prim . null? )) ’(pair? . (prim . pair? ))
5. ’(car . (prim . car )) ’(cdr . (prim . cdr ))
6. ’(cadr . (prim . cadr )) ’(cons . (prim . cons ))
7. ’(set-cdr! . (prim . set-cdr!)) ’(assoc . (prim . assoc ))
8. ’(eq? . (prim . eq? )) ’(list . (prim . list ))))
9.
10. (define env-read
11. (lambda (env var)
12. (cdr (assoc var env))))
13.
14. (define env-set!
15. (lambda (env var val)
16. (cond ((eq? (car (car env)) var) (set-cdr! (car env) val))
17. ((null? (cdr env)) (set-cdr! env (list (cons var val))))
18. (#t (env-set! (cdr env) var val)))))
19.
20. (define env-extend
21. (lambda (env parms vals)
22. (cond ((null? parms) env)
23. (#t (cons (cons (car parms) (car vals))
24. (env-extend env (cdr parms) (cdr vals)))))))
c 2006 Marc Feeley IFT2030 page 256
Interprète méta-circulaire (17)
25. (define eval
26. (lambda (expr env)
27. (cond ((symbol? expr) (env-read env expr))
28. ((pair? expr) (eval-composite (car expr) (cdr expr) env))
29. (#t expr))))
30.
31. (define eval-composite
32. (lambda (x lst env)
33. (cond ((assoc x macros) (eval (apply (env-read macros x) lst) env))
34. ((eq? x ’defmacro) (env-set! macros (car lst) (eval (cadr lst) env)))
35. ((eq? x ’set!) (env-set! env (car lst) (eval (cadr lst) env)))
36. ((eq? x ’quote) (car lst))
37. ((eq? x ’lambda) (eval-lambda lst env))
38. ((eq? x ’begin) (eval-begin #f lst env))
39. ((eq? x ’cond) (eval-cond lst env))
40. (#t (eval-call x lst env)))))
41.
42. (define eval-lambda
43. (lambda (parms-and-body def-env)
44. (cons parms-and-body def-env)))
45.
46. (define eval-begin
47. (lambda (val lst env)
48. (cond ((null? lst) val)
49. (#t (eval-begin (eval (car lst) env) (cdr lst) env)))))
50.
51. (define eval-cond
52. (lambda (lst env)
53. (cond ((eval (car (car lst)) env) (eval (cadr (car lst)) env))
54. ((pair? (cdr lst)) (eval-cond (cdr lst) env)))))
55.
56. (define eval-call
57. (lambda (fn-expr arg-exprs env)
58. (apply (eval fn-expr env) (eval-list arg-exprs env))))
59.
60. (define eval-list
61. (lambda (lst env)
62. (cond ((null? lst) ’())
63. (#t (cons (eval (car lst) env)
64. (eval-list (cdr lst) env))))))
c 2006 Marc Feeley IFT2030 page 257
Interprète méta-circulaire (18)
65. (define apply
66. (lambda (fn lst)
67. (cond ((eq? (car fn) ’prim)
68. (cond ((eq? (cdr fn) ’read) (read))
69. ((eq? (cdr fn) ’newline) (newline))
70. ((eq? (cdr fn) ’write) (write (car lst)))
71. ((eq? (cdr fn) ’symbol?) (symbol? (car lst)))
72. ((eq? (cdr fn) ’null?) (null? (car lst)))
73. ((eq? (cdr fn) ’pair?) (pair? (car lst)))
74. ((eq? (cdr fn) ’car) (car (car lst)))
75. ((eq? (cdr fn) ’cdr) (cdr (car lst)))
76. ((eq? (cdr fn) ’cadr) (cadr (car lst)))
77. ((eq? (cdr fn) ’cons) (cons (car lst) (cadr lst)))
78. ((eq? (cdr fn) ’set-cdr!) (set-cdr! (car lst) (cadr lst)))
79. ((eq? (cdr fn) ’assoc) (assoc (car lst) (cadr lst)))
80. ((eq? (cdr fn) ’eq?) (eq? (car lst) (cadr lst)))
81. ((eq? (cdr fn) ’list) lst)))
82. (#t
83. (eval (cadr (car fn))
84. (env-extend (cdr fn) (car (car fn)) lst))))))
85.
86. (define macros
87. (list (cons ’define
88. (eval-lambda ’((var expr) (list ’set! var expr)) global-env))))
89.
90. (define repl
91. (lambda ()
92. (begin (write ’>)
93. (write (eval (read) global-env))
94. (newline)
95. (repl))))
c 2006 Marc Feeley IFT2030 page 258
Interprète méta-circulaire (19)
Exemple 1: trace de l’évaluation de list
| > (eval ’list ’((read prim . read) ...))
| > (env-read ’((read prim . read) ...) ’list)
| (prim . list)
Exemple 2: trace de l’évaluation de
(set! read (list 1 2))
| > (eval ’(set! read (list 1 2)) ’((read prim . read) ...))
| > (eval-composite ’set! ’(read (list 1 2)) ’((read ...)))
| | > (eval ’(list 1 2) ’((read prim . read) ...))
| | > (eval-composite ’list ’(1 2) ’((read prim . read) ...))
| | > (eval-call ’list ’(1 2) ’((read prim . read) ...))
| | | > (eval ’list ’((read prim . read) ...))
| | | > (env-read ’((read prim . read) ...) ’list)
| | | (prim . list)
| | | > (eval-list ’(1 2) ’((read prim . read) ...))
| | | | > (eval 1 ’((read prim . read) ...))
| | | | 1
| | | | > (eval-list ’(2) ’((read prim . read) ...))
| | | | | > (eval 2 ’((read prim . read) ...))
| | | | | 2
| | | | | > (eval-list ’() ’((read prim . read) ...))
| | | | | ()
| | | | (2)
| | | (1 2)
| | > (apply ’(prim . list) ’(1 2))
| | (1 2)
| > (env-set! ’((read prim . read) ...) ’read ’(1 2))
| #<void>
c 2006 Marc Feeley IFT2030 page 259
Interprète méta-circulaire (20)
Exemple 3: ((lambda (write) (write read)) car)
| > (eval ’((lambda (write) (write read)) car) ’((read 1 2) ...))
| > (eval-composite ’(lambda (write) (write read)) ’(car) ’(...))
| > (eval-call ’(lambda (write) (write read)) ’(car) ’((read 1 2) ...))
| | > (eval ’(lambda (write) (write read)) ’((read 1 2) ...))
| | > (eval-composite ’lambda ’((write) (write read)) ’((read 1 2) ...))
| | > (eval-lambda ’((write) (write read)) ’((read 1 2) ...))
| | (((write) (write read)) . ((read 1 2) ...))
| | > (eval-list ’(car) ’((read 1 2) ...))
| | | > (eval ’car ’((read 1 2) ...))
| | | > (env-read ’((read 1 2) ...) ’car)
| | | (prim . car)
| | | > (eval-list ’() ’((read 1 2) ...))
| | | ()
| | ((prim . car))
| > (apply ’(((write) (write read)) . ((read 1 2) ...)) ’((prim . car)))
| | > (env-extend ’((read 1 2) ...) ’(write) ’((prim . car)))
| | | > (env-extend ’((read 1 2) ...) ’() ’())
| | | ((read 1 2) ...)
| | ((write prim . car) (read 1 2) ...)
| > (eval ’(write read) ’((write prim . car) (read 1 2) ...))
| > (eval-composite ’write ’(read) ’((write prim . car) (read 1 2) ...))
| > (eval-call ’write ’(read) ’((write prim . car) (read 1 2) ...))
| | > (eval ’write ’((write prim . car) (read 1 2) ...))
| | > (env-read ’((write prim . car) (read 1 2) ...) ’write)
| | (prim . car)
| | > (eval-list ’(read) ’((write prim . car) (read 1 2) ...))
| | | > (eval ’read ’((write prim . car) (read 1 2) ...))
| | | > (env-read ’((write prim . car) (read 1 2) ...) ’read)
| | | (1 2)
| | | > (eval-list ’() ’((write prim . car) (read 1 2) ...))
| | | ()
| | ((1 2))
| > (apply ’(prim . car) ’((1 2)))
| 1
c 2006 Marc Feeley IFT2030 page 260
Programmation logique
•
Prolog est le langage principal qui offre ce style•
Inventé en 1972 par Alain Colmerauer•
Applications principales:• Traitement de la langue naturelle
• Traitement symbolique et I.A.
•
Particularités:• Unification et filtrage (“pattern matching”)
• Retour arrière (“backtracking”)
• Interactif
• Déclaratif (un programme exprime des relations entre objets)
c 2006 Marc Feeley IFT2030 page 261
Relations (1)
•
Déf: une relation binaire sur les ensembles X1 et X2 est un ensemble de couples de la forme hx1,x2i, où x1 est élément de X1 et x2 est élément de X2•
Exemple2
5 4 3 1
2
5 4 3 1
X1 X2
soit X1 = {1..5} et X2 = {1..5}
relation R sur X1 et X2: "x1 est un facteur de x2"
<2,2>, <2,4>, <3,3>, <4,4>, <5,5> } R = { <1,1>, <1,2>, <1,3>, <1,4>, <1,5>,
1 1 1 1 1 2 2 3 4 5
1 2 3 4 5 2 4 3 4 5
X2 X1
c 2006 Marc Feeley IFT2030 page 262
Relations (2)
•
Déf: une relation N-aire sur les ensembles X1...Xn est un ensemble de tuples de la forme hx1,x2,...,xni, où xi est élément de Xi•
Exemple: relation sur les 3 ensembles “Nom”, “Code” et“Note”
Nom Code Note
"Luc Dubuc" "DUBL123456" 76
"Julie Roy" "ROYJ123456" 57
"Jean Coutu" "COUJ123456" 89
c 2006 Marc Feeley IFT2030 page 263
Relations (3)
•
Déf: une fonction de X1 (domaine) vers X2 (l’image) est une relation binaire qui met en relation au plus un élément de X2 avec chaque élément de X1•
Exemplerelation: relation:
age de x1 est x2 x1 plus vieux que x2
X1 X2 X1 X2
"Luc Dubuc" 45 "Jean Coutu" "Luc Dubuc"
"Julie Roy" 18 "Jean Coutu" "Julie Roy"
"Jean Coutu" 60 "Luc Dubuc" "Julie Roy"
est une fonction n’est pas une fonction
c 2006 Marc Feeley IFT2030 page 264
Relations (4)
•
Les langages fonctionnels permettent de manipuler aisément les relations binaires qui sont des fonctions•
Les langages logiques permettent de manipuler n’importe quelles relations•
Avantage: permet de faire des calculs “dans les 2 sens”(passer de X1 à X2, ou l’inverse)
•
Exemple 1relation: le genre de x1 est x2
X1 X2
"Luc Dubuc" homme
"Julie Roy" femme
"Jean Coutu" homme
c 2006 Marc Feeley IFT2030 page 265
Relations (5)
•
En programmation fonctionnelle il serait natureld’implanter une fonction “genre” qui retourne le genre étant donné le nom
•
Cela permettrait de répondre facilement à la question:quel est le genre de “Julie Roy”?
•
Cependant cette fonction ne permet pas de répondre à la question: quels sont tous les hommes?•
En programmation logique il sera tout aussi facile de spécifier x2 pour obtenir le ou les x1 qui sont enrelation, que l’inverse
c 2006 Marc Feeley IFT2030 page 266
Relations (6)
•
Exemple 2: concaténation de chaînesrelation: la concat´enation de x1 et x2 donne x3
X1 X2 X3
"" "" ""
"" "a" "a"
"a" "" "a"
"" "ab" "ab"
"a" "b" "ab"
"ab" "" "ab"
"" "abc" "abc"
"a" "bc" "abc"
"ab" "c" "abc"
"abc" "" "abc"
... et ainsi de suite pour toutes les chaines