Le langage LISP - LibreTlemcen.org

publicité
Le langage
LISP
Université AbouBakr Belkaid -Tlemcen
Ecole doctorale STIC option SIC - Module : Intelligence Artificielle
Amine Brikci-Nigassa
05/06/2007
Plan
Introduction
Historique
Particularités
Utilisation en IA
Petit exemple : Morpion
Conclusion
Introduction
Le plus ancien des langages de haut niveau
actuels, après FORTRAN
Souvent associé à l'IA
Regain d'intérêt depuis quelques années
Sort du commun : différent des langages
dérivés d'ALGOL (Pascal, C, Java...)
Ses concepts simples et puissants =>
Apprentissage enrichissant
Introduction
Capacités puissantes. Nombreuses
améliorations => Applications multiples.
Simplicité, Faible nombre de mots-clés,
Interactivité => Permet l'initiation à la
programmation pour les non-informaticiens.
Historique
1958 : Pr John Mac Carthy (MIT), inventeur du
terme «intelligence artificielle» crée le LISt
Processing language : application du
Lambda-calcul de A. Church.
=> Nouveau paradigme: programmation
fonctionnelle
Nombreuses nouveautés, dont:
structure si-alors-sinon
ramasse-miettes (garbage collector)
=> influence sur ses successeurs, dont les futurs
langages objet (Smalltalk, Java...)
Historique
Inconvénient de la programmation
fonctionnelle : trop gourmand en ressources
pour les machines de l'époque
Evolution => les dialectes de Lisp :
Common Lisp : riche, complexe, normes ANSI
Scheme : épuré, normes IEEE
=> de nombreuses implémentations
(interpréteurs et/ou compilateurs)
multiplateformes et Libres/Open Source
Emacs Lisp : intégré dans GNU Emacs
...
Le langage pour enfants Logo est dérivé de
Lisp
Particularités de Lisp
Programmation fonctionnelle :
Programmation impérative (Fortran, C...):
changements successifs de l'état de la machine
(variables)
Programmation fonctionnelle: les valeurs
manipulées passent d'une fonction à l'autre
(paramètres/retour)
Une fonction appelée avec les mêmes valeurs
plusieurs fois retourne toujours le même résultat:
pas d'effets de bord
Lisp n'est pas un langage fonctionnel pur (aussi
un langage impératif => effets de bord
possibles)
Particularités de Lisp
Langage "fortement" récursif :
Nature fonctionnelle => facilite l'usage de la
récursivité. Les structures de boucles sont peu
utilisées
Problème : risques de débordements de pile
valeurs intermédiaires empilées à chaque appel:
Programme :
(define (fact n)
(if (zero? n)
1
(* n (fact (- n 1)))
)
)
L'appel à fact est "enveloppé"
dans l'appel à la fonction *
Trace des calculs :
(fact 4)
(* 4 (fact 3))
(* 4 (* 3 (fact 2)))
(* 4 (* 3 (* 2 (fact 1))))
(* 4 (* 3 (* 2 (* 1 (fact 0)))))
(* 4 (* 3 (* 2 (* 1 1))))
(* 4 (* 3 (* 2 1)))
(* 4 (* 3 2))
(* 4 6)
24
Particularités de Lisp
Solution : récursion terminale
Programme :
Trace des calculs :
(define (iterer n a)
(if (<= n 1)
a
(iterer (- n 1) (* a n))
)
)
(define (fact n)
(iterer n 1))
(fact 4)
(iterer 4
(iterer 3
(iterer 2
(iterer 1
24
1)
4)
12)
24)
Les résultats intermédiaires sont
passés en argument
L'appel récursif doit être terminal, ne doit pas
laisser une fonction attendre le résultat pour finir
L'interpréteur/compilateur peut aisément convertir
la récursion terminale en itération
Particularités de Lisp
Principale structure de données : la Liste
Liste = chaîne de doublets de pointeurs
1ère implémentation (IBM 704): doublets
accessibles dans les registres CPU par 2 macros
ASM:
car (contents of address register) donne l'adresse
d'un élément de la liste
cdr (contents of decrement register) donne
l'adresse du doublet suivant
Cette liste est notée (1 2 3)
1
2
Le dernier cdr contient
l'adresse "NIL" notée ()
3
Particularités de Lisp
Les élements d'une liste peuvent être des
atomes ou des listes (=> arborescence)
A
1
2/7
"foo"
3.14
liste L : (1 (2/7 3.14) A "foo")
Le 2ème élément, noté (car (cdr L)) ou (cadr L) est la liste (2/7 3.14)
Particularités de Lisp
Un doublet n'est pas toujours un élément d'une
liste:
1
2
cette "paire" (ou "cons") est notée (1 . 2), elle est
construite avec l'appel de fonction (cons 1 2)
ce n'est pas une liste
Particularités de Lisp
Les expressions arithmétiques et les appels de
fonctions sont des listes: notation préfixée
parenthésée (=> pas de priorité des opérateurs)
+
exp
1
e 
x
x
x
/
1
s'écrit (+ (exp x) (/ 1 (sqrt x)))
+ exp / et sqrt sont des fonctions
sqrt
x
Particularités de Lisp
Nature d'un programme Lisp
Les programmes sont des ensembles de
fonctions, dont l'appel se fait par des listes :
(fonct param1 param2 ...)
L'exécution d'un programme revient à
l'évaluation d'une fonction principale.
Le programme source étant lui-même une liste,
il est facilement manipulable
(métaprogrammation)
Particularités de Lisp
Exécution d'un programme Lisp :
La boucle read-eval-print
read : programme source --> structure de liste
(compilateur --> byte code ou langage machine)
eval : la structure est évaluée (retourne une
structure en résultat):
chaque argument du cdr est d'abord évalué
(peut être lui-même une fonction)
la fonction désignée par le car leur est appliquée
print :
l'affichage du résultat peut être simple (atome)
si c'est une liste, il faudra d'abord la parcourir.
Particularités de Lisp
Garbage Collecting (ou Glanage de
Cellules)
Les structures de données occupent de la
mémoire, qui n'est pas manipulée explicitement
par l'utilisateur
Pour éliminer les données inutilisées de la
mémoire, Mc Carthy invente le Garbage
Collector (ramasse-miettes): processus
automatique qui libère la régulièrement les
cases mémoire non référencées
Pas de souci de "désallocation" => moins de
bugs
L'idée est reprise dans de nombreux langages
(Smalltalk, Java...)
Utilisation en IA
Nature fonctionnelle
+ Manipulation des listes/arbres
=> programmation exploratoire utile en IA
Particulièrement adapté pour programmer:
les analyseurs syntaxiques (comme celui du 1er
compilateur Lisp !),
les systèmes experts,
réseaux de neurones,
algorithmes génétiques,
agents intelligents,
systèmes de gestion des connaissances, etc...
Utilisation en dehors de l'IA
Lisp est adapté à bien d'autres domaines:
l'animation et les graphismes, la
bioinformatique, le e-commerce, le data mining,
les applications pour EDA/Semiconducteurs, les
finances, la CAO mécanique, la modélisation et
la simulation, le langage naturel, l'optimisation,
l'analyse des risques, l'ordonnancement, les
télécommunications, et le Web Authoring...
Petit exemple : Morpion
(define (morpion) (boucle '((- - -) (- - -) (- - -)) 'X 'O))
(define (boucle matrice joueur1 joueur2)
(print "position pour le " joueur1 " ?")
(let ((ligne (saisie "ligne: ")))
(if (eqv? ligne 'q) 'abandon
(let* ((colonne (saisie "colonne: "))
(new-matrice (nouveau matrice ligne colonne joueur1)))
(newline)
(affiche-matrice new-matrice) (newline)
(cond ((gagne? new-matrice) (display "le gagnant est : ") joueur1)
((partie-nulle? new-matrice) (display "partie nulle !!! ") 'Fin)
(else (boucle new-matrice joueur2 joueur1)))))))
(define (saisie message) (display message) (read))
(define (gagne? m)
(or (identiques?
(identiques?
(identiques?
(identiques?
(identiques?
(identiques?
(identiques?
(identiques?
(car (car m)) (cadr (car m)) (caddr (car m)))
(car (cadr m)) (cadr (cadr m)) (caddr (cadr m)))
(car (caddr m)) (cadr (caddr m)) (caddr (caddr m)))
(car (car m)) (car (cadr m)) (car (caddr m)))
(cadr (car m)) (cadr (cadr m)) (cadr (caddr m)))
(caddr (car m)) (caddr (cadr m)) (caddr (caddr m)))
(car (car m)) (cadr (cadr m)) (caddr (caddr m)))
(car (caddr m)) (cadr (cadr m)) (caddr (car m)))))
Petit exemple : Morpion
(define (identiques? a b c)
(and (equal? a b) (equal? b c) (not (equal? A '-))))
(define (partie-nulle?
(and (not (member '(not (member '(not (member '-
m)
(car m)))
(cadr m)))
(caddr m)))))
(define (nouveau m i j joueur)
(new-ligne m i (new-ligne (nieme m i) j joueur)))
(define (new-ligne l i val)
(cond ((null? l) '())
((= i 1) (cons val (cdr l)))
(else (cons (car l) (new-ligne (cdr l) (- i 1) val)))))
(define (nieme l i)
(if (= i 1) (car l) (nieme (cdr l) (- i 1))))
(define (affiche-matrice m)
(print " " (caar m) " | " (cadar m) " | " (caddar m))
(print "---+---+---")
(print " " (car (cadr m)) " | " (cadr (cadr m)) " | " (caddr (cadr m)))
(print "---+---+---")
(print " " (car (caddr m)) " | " (cadr (caddr m)) " | " (caddr (caddr m))))
Petit exemple : Morpion
nh2@debian:~$ bigloo
-----------------------------------------------------------------------------Bigloo (2.6e)
,--^,
`a practical Scheme compiler'
_ ___/ /|/
Tue Oct 19 12:13:41 CEST 2004
,;'( )__, ) '
Inria -- Sophia Antipolis
;; //
L__.
email: [email protected]
'
\
/ '
url: http://www.inria.fr/mimosa/fp/Bigloo
^
^
-----------------------------------------------------------------------------Welcome to the interpreter
1:=> (load "morpion.scm")
morpion
boucle
saisie
gagne?
identiques?
partie-nulle?
nouveau
new-ligne
nieme
affiche-matrice
morpion.scm
1:=>
Petit exemple : Morpion
1:=> (morpion)
position pour le X ?
ligne: 2
colonne: 2
- | - | ---+---+--- | X | ---+---+--- | - | position pour le O ?
ligne: 1
colonne: 1
O | - | ---+---+--- | X | ---+---+--- | - | position pour le X ?
ligne:
Petit exemple : Morpion
position pour le X ?
ligne: 2
colonne: 3
O | - | X
---+---+--- | X | X
---+---+--O | - | position pour le O ?
ligne: 2
colonne: 1
O | - | X
---+---+--O | X | X
---+---+--O | - | le gagnant est : O
1:=>
Petit exemple : Morpion
1:=> (gagne? ((O O O) (X - X) (- - -)))
*** ERROR:bigloo:eval:
Unbound variable -- O
#unspecified
1:=> (gagne? '((O - X) (- O X) (X X O)) )
#t
1:=> (affiche-matrice '((O - X) (- O X) (X X O)) )
O | - | X
---+---+--- | O | X
---+---+--X | X | O
O
1:=> (nouveau '((O - X) (- O X) (X X -)) 3 3 'O)
((O - X) (- O X) (X X O))
1:=> (nieme '((O - X) (- O X) (X X -)) 2)
(- O X)
Conclusion
Lisp is worth learning for the profound
enlightenment experience you will have when
you finally get it; that experience will make you
a better programmer for the rest of your days,
even if you never actually use Lisp itself a lot.
Eric S. Raymond, "How to Become a Hacker"
Lisp vaut la peine d'être appris pour l'expérience profondément
enrichissante que l'on obtient quand on finit par l'assimiler. Cette
expérience là fera de vous un meilleur programmeur pour le
restant de vos jours, même si vous n'utilisez jamais vraiment Lisp
lui-même énormément.
Téléchargement