TD/TP n°3 : Inside list world
1. cons, car, cdr et list
Une expression du langage Lisp est soit un atome, soit une liste d'expressions.
Une liste d'expressions est faite de 0, 1 ou plusieurs expressions entre
parenthèses.
La liste la plus élémentaire est la liste vide, notée
( ) ou encore nil.
> ( )
NIL
Toute autre liste peut être représentée comme
une paire de deux cellules, la première cellule s'appelle le car
et la deuxième le cdr. La fonction cons permet de
construire une paire : ses deux paramètres correspondent alors
au car et cdr de la paire ainsi construite.
> (cons 'a 'b)
(A . B)
> (setq L1 (cons 'a 'b))
(A . B)
> L1
(A . B)
> (car L1)
A
> (cdr L1)
B
La liste (a . (b . c)) est notée plus simplement (a b . c).
Cette règle de simplification est récurrente, ainsi (a .
(b . (c . d))) est notée (a b c . d). Par contre elle n'est pas
symétrique (sinon elle serait ambigüe) et (((a . b) . c) .
d) ne sera pas simplifiée.
Par ailleurs, une paire dont le cdr est nil sera simplifiée
de la manière suivante : (a . nil) s'écrit (a).
La fonction list correspond à la création d'une
liste contenant dans l'ordre ses arguments, suivis de nil.
(list 'a 'b 'c) correspond donc à (cons 'a (cons 'b (cons
'c nil))) et vaut (a b c).
Des fonctions composées existent et permettent d'invoquer
car ou cdr jusqu'à 4 fois successivement.
Exemple : (cdddr L1) correspond à (cdr (cdr (cdr L1))).
Exercice 1 :
Evaluer les expressions suivantes et comprendre le résultat
obtenu.
> (setq l2 (cons 'a (cons "bonjour" (cons
2 (cons 'd nil))))) ; faire la même construction avec la fonction list
uniquement
> (car (cdr (cdr l2)))
Faire la construction d'une liste L2 telle que l'évaluation
de (caaaar L2) renvoie (a), en n'utilisant que setq et cons,
puis en n'utilisant que setq et list.
Il existe d'autres fonctions de base sur les listes appelées
first, last et rest. Ces fonctions s'utilisent avec
un argument de type liste. Comparer les avec les fonctions car et
cdr, en évaluant des constructions qui les font intervenir.
2. Fonctions supplémentaires
- La fonction append permet de fusionner les listes données
en argument.
Exercice 2 :
Fusionner des listes crées précédemment. Tester
la fonction append avec des listes dont le dernier élément
n'est pas nil. Que ce passe-t-il dans ce cas ?
- La fonction length renvoie le nombre d'éléments
d'une liste.
Exercice 3 :
Calculer la longueur de listes précédemment construites.
On fera des évaluations pour des listes dont le dernier élément
est nil et d'autres pour lesquelles le dernier élément
ne vaut pas nil. Que remarque-t-on ?
- La fonction nth renvoie un élément situé
à une place donnée dans une liste.
Exemple : (nth 3 L3) renvoie le 3ème élément
de la liste L3.
- La fonction last renvoie le dernier élément
de la liste donnée en paramètre.
Exercice 4 :
Tester nth et last sur des listes crées précédemment.
Tester avec des listes dont le dernier élément est nil
et d'autres dont le dernier élément n'est pas nil.
- La fonction member recherche une expression dans une liste
et retourne comme valeur la partie de la liste commençant à
l'expression trouvée. Dans le cas où l'expression n'existe
pas, la fonction member retourne nill.
> (member 'a '(b c a d e))
(a d e)
Mapping
Les fonctions suivantes ont un premier argument qui est une fonction f
et un deuxième argument qui est une liste. Eventuellement elles ont
également d'autres arguments qui sont des listes si f est une fonction
à plusieurs arguments.
- Les fonctions mapc, mapcar et mapcan appliquent
f sur les différents "car" successifs de ses autres arguments.
- mapc a pour valeur une liste qui est le premier argument
qui suit f
- mapcar a pour valeur la liste des valeurs retournées
par chaque application de f
- mapcan a pour valeur la fusion des listes retournées
par chaque application de fonction
- Les fonctions mapl, maplist et mapcon appliquent
f sur les différents "cdr" successifs de ses autres arguments.
- mapl a pour valeur une liste qui est le premier argument
qui suit f
- maplist a pour valeur la liste des valeurs retournées
par chaque application de f
- mapcon a pour valeur la fusion des listes retournées
par chaque application de fonction
Pour plus d'information sur ces fonctions, vous pouvez consulter le chapitre
sur les fonctions
d'application du Traité
de programmation en Common Lisp de R. Strandh et I. Durand.
Exercice 5 :
Tester ces 6 fonctions pour f prenant les valeurs car puis cdr
et sur l'argument liste '((a b) (c d) (e f)).
Fonctions de remplacement physique dans des listes
- La fonction rplaca remplace physiquement la première
cellule (car) de la liste donnée en premier argument par la valeur
du second argument.
- La fonction rplacd remplace physiquement la deuxième
cellule (cdr) de la liste donnée en premier argument par la valeur
du second argument.
Exercice 6 :
Evaluer les expressions suivantes et comprendre les résultats
retournés
> (setq a '(a b c))
> (setq b a)
> (rplaca b '(c d))
> a
> (rplacd b '(e f))
> a
Que fait la fonction reverse qui possède un seul argument
de type list ?
3. Exercices d'application
Exercice 7 :
Ecrire une fonction
qui calcule la concaténation de deux listes.
Exercice 8 :
Ecrire une fonction
qui calcule le nombre d'éléments d'une liste.
Exercice 9 :
Ecrire une fonction
qui effectue le tri d'une liste par insertion.
Exercice 10 :
Ecrire une fonction
qui renvoie le dernier élément d'une liste.
Exercice 11 :
Ecrire une fonction
qui ajoute 1 à chaque élément d'une liste d'entiers.
Exercice 12 :
Ecrire une fonction qui calcule la somme des éléments
d'une liste d'entiers.
Exercice 13 :
Ecrire une fonction qui calcule le nombre d'occurence d'un symbole
dans une liste.
Exercice 14 :
Ecrire une fonction
qui remplace toutes les occurences d'un élément d'une liste
par un autre élément.
Exercice 15 :
Ecrire une fonction
qui extrait tous les éléments de rang pair d'une liste.
Exercice 16 :
Ecrire une fonction qui fusionne 2 listes ordonnées en une liste
ordonnée.
Exercice 17 :
Ecrire une fonction qui fusionne 2 listes non ordonnées en une
liste ordonnée.
Exercice 18 :
Ecrire une fonction qui a pour argument une liste et qui renvoie une
liste de paires telles que ces dernières associent chaque symbole
apparaissant dans la liste originale et son nombre d'occurence.