1         Mercredi 3 Octobre 1984





 INRIA
 Domaine de Voluceau
 Rocquencourt
 78153 Le Chesnay Cedex






                      Ceyx: Une Initiation



                        Ceyx - Version 15




                        Jean-Marie Hullot

                            Ete' 1984






Re'sume': ←C←e←y←x ←e←s←t ←u←n ←e←n←s←e←m←b←l←e ←d'←o←u←t←i←l←s ←p←e←r←m←e←t←t←a←n←t ←d←e ←f←a←c←i←l←i←t←e←r  ←l←a
←t←a↑←c←h←e  ←d←e←s  ←p←r←o←g←r←a←m←m←e←u←r←s  ←L←i←s←p  ←p←o←u←r  ←d←e'←f←i←n←i←r  ←e←t  ←m←a←n←i←p←u←l←e←r  ←d←e←s
←s←t←r←u←c←t←u←r←e←s ←a←r←b←i←t←r←a←i←r←e←s. ←A←u←x  ←s←t←r←u←c←t←u←r←e←s  ←d←e'←f←i←n←i←e←s  ←e←n  ←C←e←y←x  ←s←o←n←t
←a←s←s←o←c←i←e'←e←s  ←d←e←s  ←e←s←p←a←c←e←s  ←s←e'←m←a←n←t←i←q←u←e←s, ←o←r←g←a←n←i←s←e'←s ←h←i←e'←r←a←r←c←h←i←q←u←e←m←e←n←t,
←d←a←n←s ←l←e←s←q←u←e←l←s ←s←o←n←t ←r←a←n←g←e'←e←s ←l←e←s ←f←o←n←c←t←i←o←n←s ←d←e ←m←a←n←i←p←u←l←a←t←i←o←n  ←p←r←o←p←r←e←s
←a`  ←c←e←s ←s←t←r←u←c←t←u←r←e←s. ←U←n ←s←t←y←l←e ←d←e ←p←r←o←g←r←a←m←m←a←t←i←o←n ←o←r←i←e←n←t←e'←e ←o←b←j←e←t←s ←a` ←l←a
←S←m←a←l←l←T←a←l←k ←e←s←t ←a←i←n←s←i ←r←e←n←d←u ←p←o←s←s←i←b←l←e.

←N←o←u←s ←p←r←e'←s←e←n←t←o←n←s ←d←a←n←s ←c←e ←d←o←c←u←m←e←n←t, ←l←e←s ←c←o←n←s←t←r←u←c←t←i←o←n←s  ←e'←l←e'←m←e←n←t←a←i←r←e←s
←d←u ←s←y←s←t←e`←m←e.




                                2         Mercredi 3 Octobre 1984















































                                3         Mercredi 3 Octobre 1984




















                            ←C←e←y←x ←e'←t←a←i←t ←f←i←l←s ←d←e ←L←u←c←i←f←e←r,
             ←l←e ←c←o←n←d←u←c←t←e←u←r ←d←e←s ←A←s←t←r←e←s ←e←t ←d←e ←l←a ←L←u←m←i←e`←r←e,
                      ←l'←e'←t←o←i←l←e ←q←u←i ←f←a←i←t ←n←a←i↑←t←r←e ←l←e ←j←o←u←r,
←e←t ←l←a ←j←o←i←e ←b←r←i←l←l←a←n←t←e ←d←e ←s←o←n ←p←e`←r←e ←i←l←l←u←m←i←n←a←i←t ←s←o←n ←v←i←s←a←g←e.

                                                  Ovide





















                                4         Mercredi 3 Octobre 1984















































                                5         Mercredi 3 Octobre 1984








                          Avertissement

Ce document constitue une introduction a` Ceyx.  Une  connaissance
minimum  de  Lisp  est  requise.  Ceyx  est e'crit en Le←Lisp, qui
posse`de un excellent manuel disponible aupre`s de l'INRIA:

o+ ←L←e←←L←i←s←p ←d←e ←l'←I←N←R←I←A, ←L←e ←M←a←n←u←e←l ←d←e ←R←e'←f←e'←r←e←n←c←e (J. Chailloux).

On trouvera une  description  comple`te  de  Ceyx  dans  un  autre
rapport INRIA:

o+ ←P←r←o←g←r←a←m←m←e←r ←e←n ←C←e←y←x (J.-M. Hullot),

et la documentation de processeurs spe'cialise's dans:

o+ ←V←p←r←i←n←t, ←L←e ←C←o←m←p←o←s←e←u←r ←C←e←y←x (G. Berry, J.-M. Hullot),

o+ ←C←X←Y←A←C←C ←e←t ←L←E←X-←K←I←T (G. Berry, B. Serlet).





















                                6         Mercredi 3 Octobre 1984















































                                7         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp



                       C H A P I T R E  1


                        Les Records Lisp





Nous introduisons dans ce chapitre des  constructions  permettant
de  de'finir de nouvelles structures de donne'es en Lisp. Il s'agit
essentiellement  de  constructions  simples  qui  devraient  e↑tre
comprises  sans difficulte's par un lecteur un peu habitue' a` Lisp.
Ce chapitre peut e↑tre conside're' comme une initiation a` Ceyx  dans
la  mesure  ou`  il  introduit a` un style de programmation et a` un
ensemble de notations qui sont de mise en Ceyx.




1.1  Introduction


Nous proposons une construction permettant de manipuler  en  Lisp
des structures de donne'es a` e'le'ments nomme's analogues aux records
de Pascal. Cherchons par exemple a` mode'liser la notion  de  point
mate'riel  en mouvement dans un plan carte'sien. Il s'agit d'objets
posse'dant les deux champs x et y, qui  sont  les  coordonne'es  du
point,  et  les  deux  champs  vx et vy qui sont les vitesses par
rapport aux axes de coordonne'es. Pour manipuler de tels objets en
Lisp,  on  commencera  par  de'finir  une fonction Point cre'ant un
objet  Lisp  composite  me'morisant  ces  valeurs.  Une   solution
minimale  en  utilisation  me'moire et en rapidite' moyenne d'acce`s
aux champs est:


? (de Point (x y vx vy)
      (cons (cons x y) (cons vx vy)))
= Point

                                8         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

? (setq point1 (Point 0 0 0 0))
= ((0 . 0) 0 . 0)

Il nous  est  alors  possible  d'inspecter  et  de  modifier  les
composantes x,y, vx et vy d'une instance de Point par les chaines
de car, cdr, rplaca, rplacd idoines. Une bonne solution  consiste
a`  de'finir  des  fonctions  d'acce`s  aux  champs en lecture et en
e'criture et de ne plus acce'der aux instances de  Points  que  par
ces fonctions.


? (de get-Point-x (point) (caar point))
= get-Point-x
? (de put-Point-x (point val) (rplaca (car point) val)))
= put-Point-x
? (put-Point-x point1 1)
= (1 . 0)
? point1
= ((1 . 0) . (0 . 0))
? (get-Point-x point1)
= 1

et de la me↑me fac,on des fonctions pour les champs y,  vx  et  vy.
Le  proble`me  de  la  manipulation  des  Points semble ainsi bien
re'solu au prix de l'e'criture d'un certain  nombre  de  fonctions.
Ceci  nous  permet de faire nos premiers pas dans l'e'criture d'un
programme sur les Points.  Malheureusement, nous nous  apercevons
au bout d'un certain temps que nous voulons en fait manipuler des
points nomme's et qu'ainsi un nouveau  champ  appele'  nom  devient
ne'cessaire.  Il  nous  faut  alors  rede'finir  la  fonction Point
prenant cette fois-ci cinq  arguments  et  toutes  les  fonctions
d'acce`s puisque la structure de repre'sentation des Points en tant
qu'arbre de cons a e'te' modifie'e. On notera que tous les appels  a`
la  fonction  Point  dans le code devront e↑tre e'galement modifie's
puisque   cette   fonction   prend   maintenant    un    argument
supple'mentaire.  Le but de la construction que nous proposons est
de faciliter  ce  genre  de  manipulations,  en  introduisant  de
nouvelles constructions dans Lisp.

Pour de'finir la structure Point sous Ceyx, il suffit d'invoquer:


                                9         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp


? (defrecord Point x y vx vy)
= Point

Une instance de Point sera alors cre'e'e par:


? (setq point1 (omakeq Point x 0 y 0 vx 0 vy 0))
= ((0 . 0) 0 . 0)

De plus a` l'invocation  de  la  forme  defrecord,  les  fonctions
d'acce`s  {Point}:x,  {Point}:y,  {Point}:vx  et  {Point}:vy  sont
automatiquement cre'e'es qui permettent  d'acce'der  aux  points  en
lecture  et  en  e'criture  suivant  qu'on  leur  donne un ou deux
arguments.


? ({Point}:x point1)
= 0
? ({Point}:y point1 1)
= (0 . 1)
? ({Point}:y point1)
= 1

Cette fois-ci, l'effort  pour  rajouter  un  champ  nom  dans  la
structure  sera  minime  puiqu'il suffira de remplacer l'appel de
defrecord pre'ce'dent par:


(defrecord Point nom x y vx vy)

Aucune autre modification ne sera  ne'cessaire  dans  le  code  de
l'utilisateur.









                               10         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

1.2  De'finition d'un Record Lisp

Un Record Lisp est de'fini a` l'aide de la forme defrecord:

(defrecord <name> <field>1 ... <field>n)

   <name> est un symbole qui devient le nom de la structure ainsi
   de'finie  et  les  <field>i  sont  de  la  forme  <symbol>i  ou
   (<symbol>i <init>i), ou` <symbol>i  est  le  nom  du  champ  et
   <init>i,  qui  est  e'value'e  est la valeur d'initialisation du
   champ (voir fonction omakeq).  Les  champs  pour  lesquels  la
   valeur  d'initialisation  n'est  pas donne'e sont initialise's a`
   nil.

   Cette construction associe au symbole <name> la de'finition  de
   Lrecord  a`  n champs de noms <symbol>i. De plus n fonctions de
   nom   {<name>}:<symbol>i  sont   engendre'es   pour   permettre
   d'acce'der  aux  instances  de cette structure en lecture et en
   e'criture.


? (defrecord Point nom (x 0) (y 0) (vx 0) (vy 0))
= Point




1.3  Fonctions de Manipulation des Instances de Record


1.3.1  Cre'ation d'Instances

(omakeq <name> <fieldname>1 <val>1 ... <fieldname>n <val>n)

   <name> et les <fieldname>i ne sont pas e'value's, les <val>i  le
   sont.   <name>  doit  avoir  une de'finition de record, c'est a`
   dire  avoir  e'te'  de'fini  par  (defrecord  <name>  ...).   Les
   <fieldname>i   sont  des  noms  de  champ  du  record  de  nom
   <recordname>. Cette fonction renvoie en valeur une instance de
   ce  record  dont  le champ de nom <fieldname> a pour valeur sa
   valeur  initiale   si   <fieldname>   n'appartient   pas   aux

                               11         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

   <fieldname>i, <val>i autrement.



? (setq point1 (omakeq Point))
= ((nil . 0) 0 0 . 0)
? ({Point}:nom point1)
= nil
? ({Point}:nom point1 'Le←Point)
= Le←Point
? ({Point}:nom point1)
= Le←Point
? (setq point2 (omakeq Point nom 'Autre←Point x 10 y 10))))
= ((Autre←Point . 10) 10 0 . 0)
? ({Point}:nom point2)
= Autre←Point
? ({Point}:x point2)
= 10
? ({Point}:vx point2)
= 0


1.3.2  Discrimination

(omatchq <name> <object>)

   <name> n'est pas e'value', <object> l'est. <name> doit  posse'der
   une  de'finition  de  Record.  Cette fonction rame`ne une valeur
   diffe'rente de nil si et seulement si <object> a pu  e↑tre  cre'e'
   par (omakeq <name> ... ).



? (omatchq Point point1)
= t
? (omatchq Point 1)
= nil





                               12         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

1.3.3  Acce`s aux Champs

A co↑te' des fonctions d'acce`s en lecture et en e'criture  engendre's
automatiquement   lors   de   la  de'finition  d'un  record,  nous
introduisons des constructions ge'ne'rales d'acce`s aux champs.  Ces
constructions  seront  surtout utilise'es lors de la de'finition de
macros.

(ogetq <name> <fieldname> <object>

   L'argument <name>, qui n'est pas e'value', doit e↑tre un  symbole
   posse'dant  une de'finition de record. Si <fieldname>, qui n'est
   pas e'value', n'est pas un nom de champ pour le  record  de  nom
   <name>,  une  erreur  est de'clenche'e. Sinon <object> doit e↑tre
   une instance de <name> et cette fonction rame`ne en  valeur  la
   valeur de son champ <fieldname>.

(oputq <name> <fieldname> <object> <object>1)

   L'argument <name>, qui n'est pas e'value', doit e↑tre un  symbole
   posse'dant  une de'finition de record. Si <fieldname>, qui n'est
   pas e'value', n'est pas un nom de champ pour le  record  de  nom
   <name>,  une  erreur  est de'clenche'e. Sinon <object> doit e↑tre
   une instance de <name> et cette fonction remplace physiquement
   la valeur du champ <fieldname> par <object>1.



? (ogetq Point nom point1)
= Le←Point
? (oputq Point x point1 20)
= (Le←Point . 20)
? (ogetq Point x point1)
= 20








                               13         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

1.4  Les Records Extensibles ou Classes

De'finissons maintenant une structure d'individu:


(defrecord Individu nom prenom adresse telephone)
= Individu

et supposons que nous voulions cre'e'er deux  nouvelles  structures
posse'dant  les  quatre  champs du record Individu plus un nouveau
champ  "pointure"  pour  la  premie`re   et   un   nouveau   champ
"condamnations"  pour la seconde.  Une premie`re solution consiste
a` de'finir deux nouveaux records a` cinq  champs.  Pour  simplifier
ces  ope'rations  Ceyx introduit la notion de record extensible ou
classe. Pour notre exemple, il suffira d'e'crire:


? (defclass Individu nom prenom adresse telephone)
= #:Class:Individu
? (defclass {Individu}:Client pointure)
= #:Class:Individu:Client
? (defclass {Individu}:Suspect condamnations)
= #:Class:Individu:Suspect

Une classe Lisp ou Classe est de'finie a` l'aide de la forme:

(defclass <name>/{<superclass>}:name <field>1 ... <field>n)

   Dans le premier cas, cette forme est e'quivalente au defrecord,
   sinon  qu'on  de'finit cette fois-ci un record extensible. Dans
   le second cas <superclass> doit avoir une de'finition de classe
   et  <name>  devient  le  nom  d'une nouvelle classe ayant pour
   champs tous ceux de <superclass> accessibles par les  fonction
   {<superclass>}:<fieldname>  et  pour  nouveaux champs tous les
   <field>i accessibles par {<name>}:<fieldname>i.   Nous  dirons
   que   <name>  est  une  sous-classe  de  <superclass>  et  que
   <superclass> est la  superclasse  de  <name>.   On  remarquera
   eenfin que les instances de classes sont imple'mente'es avec des
   ←v←e←c←t←o←r←s Le←Lisp et non plus avec des cons.



                               14         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp


? (setq client (omakeq Client nom 'Jacquemart prenom 'Marcel pointure 48))
= #[Jacquemart Marcel () () 48]
? (setq suspect
?       (omakeq Suspect nom 'Jacquemart
?                       prenom 'Marcel
?                       condamnations "Vol de chaussures"))
= #[Jacquemart Marcel () () Vol de chaussures]
? ({Individu}:nom client)
= Jacquemart
? ({Individu}:nom suspect)
= Jacquemart
? ({Client}:pointure client)
= 48
? ({Suspect}:condamnations suspect)
= Vol de chaussures

   On notera de plus que  si  <class>1  est  une  sous-classe  de
   <class> on a (omatchq <class> (omakeq <class>1 ...)) = t

   Exemple:

   ? (omatchq Individu client)
   = t





1.5  Proprie'te's Se'mantiques des Records et des Classes

Nous sommes maintenant capables  de  de'finir  des  structures  de
donne'es,  nous  aimerions  de'finir  des ope'rations, ou proprie'te's
se'mantiques,  s'appliquant  spe'cifiquement  aux  instances  d'une
telle  structure. Reprenons l'exemple de la structure Point. Pour
de'finir l'ope'ration v**2 qui calcule la vitesse de  ce  point  au
carre', il suffit de faire sous Ceyx:


? (de {Point}:v**2 (point)
      (+ (* ({Point}:vx point) ({Point}:vx point))

                               15         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

         (* ({Point}:vy point) ({Point}:vy point))))
= Point:v**2
? ({Point}:v**2 point2)
= 100

A ce point on peut conside'rer qu'on de'finit  juste  une  fonction
Lisp  ordinaire de nom {Point}:v**2. Nous allons un peu plus loin
en de'finissant la construction semcall:

(semcall <structname> <sem> <arg>1 ... <arg>n)

   Tous les arguments sont e'value's. <structname> est  un  nom  de
   classe  ou  de  record,  <sem> est un symbole. Si la proprie'te'
   se'mantique de nom <sem> a e'te' de'finie pour <structname>,  elle
   est  applique'e aux arguments <arg>i. Sinon si <structname> n'a
   pas une de'finition de classe une erreur est de'clenche'e.  Sinon
   si  <structname>  a  une de'finition de classe et est extension
   d'une autre classe  <superclass>  on  s'appelle  re'cursivement
   avec   <structname>  =  <superclass>.  Sinon  une  erreur  est
   de'clenche'e.



? (de {Individu}:print (individu)
?      (print "Nom: " ({Individu}:nom individu))
?      (print "Prenom: " ({Individu}:prenom individu))
?      t)
= #:Class:Individu:print
? ({Individu}:print client)
Nom: Jacquemart
Prenom: Marcel
= t
? (semcall 'Client 'print client)
Nom: Jacquemart
Prenom: Marcel
= t

Nous pouvons raffiner cette proprie'te' se'mantique sur la structure
Client en de'finissant:



                               16         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

? (de {Client}:print (client)
?     ({Individu}:print client)
?     (print "Pointure: " ({Client}:pointure client))
?     t)
= #:Class:Individu:Client:print
? (semcall 'Client 'print client)
Nom: Jacquemart
Prenom: Marcel
Pointure: 47
= t
? (semcall 'Suspect 'print suspect)
Nom: Jacquemart
Prenom: Marcel
= t

Cette  construction  permet   donc   d'e'tablir   une   hie'rarchie
se'mantique calquant la hie'rarchie structurelle introduite avec la
structure classe.  Si les objets e'taient a` me↑me de reconnaitre de
quelle structure ils sont instance, il n'y aurait me↑me plus a` lui
passer l'argument donnant cette information et elle prendrait  sa
pleine  puissance. Nous reviendrons sur ce point dans le prochain
chapitre.




1.6  Un Exemple De'veloppe'

Nous donnons un exemple de programmes manipulant des positions et
des  re'gions rectangulaires dans un plan carte'sien dont l'axe des
x est vertical dirige' vers le  bas  et  l'axe  des  y  horizontal
dirige' vers la droite (syste`me de coordonne'es de style e'cran).

Tout d'abord, nous de'finissons le record Position par:


(defrecord Position (x 0) (y 0))

Pour cre'er des instances de position, nous de'finissons:



                               17         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

(de Position (xpos ypos) (omakeq Position x xpos y ypos))

Pour effectuer une translation sur une position, nous de'finissons
la proprie'te' se'mantique translate:


(de {Position}:translate (pos dx dy)
    ({Position}:x pos (+ dx ({Position}:x pos)))
    ({Position}:y pos (+ dy ({Position}:y pos)))
    pos)

Ceci e'tant, nous introduisons la structure Region pour  mode'liser
les  re'gions  rectangulaires.  Une  re'gion est de'termine'e par son
coin supe'rieur gauche et son coin infe'rieur droit  qui  sont  des
positions:


(defrecord Region upper-left bottom-right)

Et pour cre'er des instances de re'gion a` partir de deux positions:


(de Region (pos1 pos2)
    (let ((x1 ({Position}:x pos1))
          (y1 ({Position}:y pos1))
          (x2 ({Position}:x pos2))
          (y2 ({Position}:y pos2)))
         (omakeq Region
                 upper-left (Position (min x1 x2) (min y1 y2))
                 bottom-right (Position (max x1 x2) (max y1 y2)))))


Nous de'finissons un  certain  nombre  de  proprie'te's  se'mantiques
calculant des caracte'ristiques ge'ome'triques des re'gions:


(de {Region}:xmin (region)
    ({Position}:x ({Region}:upper-left region)))

(de {Region}:ymin (region)
    ({Position}:y ({Region}:upper-left region)))

                               18         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp


(de {Region}:xmax (region)
    ({Position}:x ({Region}:bottom-right region)))

(de {Region}:ymax (region)
    ({Position}:y ({Region}:bottom-right region)))

(de {Region}:width (region)
    (1- (- ({Region}:xmax region) ({Region}:xmin region))))

(de {Region}:height (region)
    (1- (- ({Region}:ymax region) ({Region}:ymin region))))

Nous de'finissons maintenant une proprie'te' se'mantique des  re'gions
permattant de de'terminer si une position donne'e est a` l'inte'rieur
d'une re'gion:


(de {Region}:contains-position (region pos)
    (not
      (or (< ({Position}:x pos) ({Region}:xmin region))
          (> ({Position}:x pos) ({Region}:xmax region))
          (< ({Position}:y pos) ({Region}:xmin region))
          (> ({Position}:y pos) ({Region}:ymin region)))))

Etant donne'es deux re'gions, nous aimerions savoir  si  elles  ont
une  intersection.  Pour  ce  faire nous de'finissons la proprie'te'
se'mantique intersects pour les re'gions, qui renvoie nil en valeur
s'il n'y a pas intersection, la re'gion d'intersection autrement.


(de {Region}:intersects (region1 region2)
    (let ((xmin1 ({Region}:xmin region1))
          (ymin1 ({Region}:ymin region1))
          (xmax1 ({Region}:xmax region1))
          (ymax1 ({Region}:ymax region1))
          (xmin2 ({Region}:xmin region2))
          (ymin2 ({Region}:ymin region2))
          (xmax2 ({Region}:xmax region2))
          (ymax2 ({Region}:ymax region2)))
         (setq xmin1 (max xmin1 xmin2)

                               19         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp

               ymin1 (max ymin1 ymin2))
         (if (and (> (- (min xmax1 xmax2) xmin1) 0)
                  (> (- (min ymax1 ymax2) ymin1) 0))
             (Region (Position xmin1 ymin1)
                     (Position (min xmax1 xmax2) (min ymax1 ymax2)))
             nil)))

Enfin, nous pouvons de'finir des transformations sur  les  re'gions
comme la translation:


(de {Region}:translate (region dx dy)
    ({Position}:translate ({Region}:upper-left region) dx dy)
    ({Position}:translate ({Region}:bottom-right region) dx dy)
    region)

et la transformation qui  met  le  coin  supe'rieur  gauche  d'une
re'gion sur une position donne'e:


(de {Region}:move-to (region pos)
    ({Region}:translate region
             (- ({Position}:x pos) ({Region}:xmin region))
             (- ({Position}:y pos) ({Region}:ymin region))))


















                               20         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                          1: Les Records Lisp











































                               21         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                     2: Les Records Autotype's



                       C H A P I T R E  2


                      Les Records Autotype's





Ce chapitre suit un plan similaire a` celui du chapitre pre'ce'dent.
Nous  y de'finissons de nouvelles notions de records et de classes
qui diffe`rent des pre'ce'dentes en ce que leurs  instances  portent
toujours  l'information  du  nom  du record ou de la classe qui a
permis  de  les  engendrer.  La  seule  construction   re'ellement
nouvelle de ce chapi↑tre est la construction send qui joue un ro↑le
majeur dans Ceyx.




2.1  Introduction


Reprenons l'exemple du chapi↑tre pre'ce'dent sur  les  individus  en
de'finissant cette fois-ci la classe des individus par la nouvelle
construction deftclass:


? (deftclass Individu nom prenom adresse telephone)
= #:Tclass:Individu

et cre'ons maintenant une instance d'Individu par la  construction
omakeq:


? (setq individu (omakeq Individu nom 'Jacquemart prenom 'Marcel))
= #(#:Tclass:Individu . #[Jacquemart Marcel () ()])



                               22         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                     2: Les Records Autotype's

Comme pre'ce'demment, nous avons acce`s  aux  divers  champs  de  la
structure Individu:


? ({Individu}:nom individu)
= Jacquemart
? ({Individu}:adresse individu)
= ()

La seule diffe'rence avec le chapi↑tre pre'ce'dent est que maintenant
les  instances  produites  par omakeq portent l'information de la
classe qui  les  a  cre'e'es,  information  qui  est  accessible  a`
l'utilisateur par la fonction model:


? (model individu)
= #:Tclass:Individu

Nous pouvons rede'finir les sous-classes Client et Suspect par:


? (deftclass {Individu}:Client pointure)
= #:Tclass:Individu:Client
? (deftclass {Individu}:Suspect condamnations)
= #:Tclass:Individu:Suspect

et cre'er des instances de ces classes:


? (setq client (omakeq Client nom 'Jacquemart prenom 'Marcel pointure 48))
= #(#:Tclass:Individu:Client . #[Jacquemart Marcel () () 48])
? (setq suspect
?       (omakeq Suspect
?               nom 'Jacquemart
?               prenom 'Marcel
?               condamnations "Vol de chaussures"))
= #(#:Tclass:Individu:Suspect . #[Jacquemart Marcel () () Vol de chaussures])


et ve'rifier  que  ces  instances  portent  bien  leur  marque  de
fabrique:

                               23         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                     2: Les Records Autotype's


? (model client)
= #:Tclass:Individu:Client
? (model suspect)
= #:Tclass:Individu:Suspect

et que client est bien un Individu:


? (omatchq Individu client)
= t

Comme pre'ce'demment, nous  de'finissons  une  proprie'te'  se'mantique
d'impression pour les Individus:


? (de {Individu}:print (individu)
?     (print "Nom: " ({Individu}:nom individu))
?     (print "Prenom: " ({Individu}:prenom individu))
?     t)
= #:Tclass:Individu:print

Nous  avons  vu  que  cette  proprie'te'   se'mantique   peut   e↑tre
de'clenche'e:

- soit par appel de la  fonction  Lisp  {Individu}:print  sur  un
individu ({Individu}:print client),

-  soit  par  invocation  de  semcall,  (semcall  'Client  'print
client),  auquel  cas  la  proprie'te'  se'mantique  sera recherche'e
d'abord dans celles de Client puis,  en  cas  d'e'chec,  dans  les
proprie'te's   se'mantiques   des   superclasses   de   Client,   en
l'occurrence Individu.

Compte tenu que les instances portent maintenant l'information du
record  ou  de  la  classe  qui  a  permis de les engendrer, nous
pouvons, dans le cas des proprie'te's se'mantiques qui prennent pour
premier argument un objet qui est une instance du record ou de la
classe   associe'e,   donner   une   nouvelle   construction    de
de'clenchement   de  proprie'te's  se'mantiques  qui  ne  prend  plus
l'argument nom  de  record  ou  de  classe.   Cette  construction

                               24         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                     2: Les Records Autotype's

appele'e  send  prend  en  argument un nom de proprie'te' se'mantique
<sem> et un  nombre  arbitraire  d'autres  arguments  <arg>1  ...
<arg>n et est e'quivalente a`:


(semcall <sem> (model <arg>1) <arg>2 ... <arg>n)

Nous aurons ainsi:


? (send 'print client)
Nom: Jacquemart
Prenom: Marcel
= t
? (send 'print suspect)
Nom: Jacquemart
Prenom: Marcel
= t

On notera au passage que la proprie'te'  print  des  Individus  est
ge'ne'rique  pour  tous  les Individus compte tenu de la de'pendance
hie'rarchique  des  classes.  Comme  pre'ce'demment,  nous   pouvons
raffiner la proprie'te' print pour les Clients:


? (de {Client}:print (client)
?     ({Individu}:print client)
?     (print "Pointure: " ({Client}:pointure client))
?     t)
= #:Tclass:Individu:Client:print

et cette fois-ci nous aurons:


? (send 'print client)
Nom: Jacquemart
Prenom: Marcel
Pointure: 48
= t



                               25         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                     2: Les Records Autotype's

De'finissons maintenant une proprie'te' se'mantique d'impression pour
les Suspects:


? (de {Suspect}:print (suspect)
?     (print "Le denomme " ({Individu}:nom suspect)
?            " " ({Individu}:prenom suspect)
?            " a ete condamne pour " ({Suspect}:condamnations suspect))
?     t)
= #:Tclass:Individu:Suspect:print
? (send 'print suspect)
Le denomme Jacquemart Marcel a ete condamne pour Vol de chaussures
= t

L'un des inte're↑ts  majeurs  de  la  construction  send  est  donc
qu'elle  se  substitue  e'le'gamment  a`  des  constructions de type
selectq quand on veut effectuer des actions  diffe'rentes  suivant
le type de l'objet qu'on manipule.





2.2  De'finition d'un Record Autotype' ou Trecord


Un record tagge' est de'fini a` l'aide de la forme deftrecord:

(deftrecord <name> <field>1 ... <field>n)

   <name> est un symbole qui devient le nom de la structure ainsi
   de'finie  et  les  <field>i  sont  de  la  forme  <symbol>i  ou
   (<symbol>i <init>i), ou` <symbol>i  est  le  nom  du  champ  et
   <init>i,  qui  est  e'value'e  est la valeur d'initialisation du
   champ.  Les champs pour lesquels  la  valeur  d'initialisation
   n'est pas donne'e sont initialise's a` nil.

   Cette construction associe au symbole <name> la de'finition  de
   Trecord  a`  n champs de noms <symbol>i. De plus n fonctions de
   nom   {<symbol>}:<symbol>i  sont  engendre'es  pour   permettre
   d'acce'der  aux  instances  de cette structure en lecture et en

                               26         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                     2: Les Records Autotype's

   e'criture.

   La seule diffe'rence  entre  Record  et  Trecord  est  que  les
   instances  des  seconds  (obtenues par appel de (omakeq <name>
   ...)) portent l'information du  Trecord  qui  a  servi  a  les
   engendrer.  Les  fonctions  omakeq,  omatchq,  oputq  et ogetq
   fonctionnent sur ces nouveaux objets,





2.3  De'finition d'une Classe Autotype'e ou Tclasse


Une classe tagge'e est de'finie a` l'aide de la forme deftclass:

(deftclass <name>/{<superclass>}:<name> <field>1 ... <field>n)

   Dans  le  premier  cas,  cette  forme   est   e'quivalente   au
   deftrecord,  sinon  qu'on  de'finit  cette  fois-ci  un Trecord
   extensible. Dans le second cas  <superclass>  doit  avoir  une
   de'finition  de Tclasse et <name> devient le nom d'une nouvelle
   classe ayant pour champs tous ceux de <superclass> accessibles
   par  les  fonction {<superclass>}:<fieldname> et pour nouveaux
   champs     tous     les     <field>i      accessibles      par
   {<name>}:<fieldname>i.   Nous  dirons que <name> est une sous-
   classe de <superclass> et que <superclass> est la  superclasse
   de <name>.

   De me↑me que pour les Trecords la seule diffe'rence entre Classe
   et  Tclasse  est  que  les instances des seconds (obtenues par
   appel de (omakeq <name>  ...))  portent  l'information  de  la
   Tclasse qui a servi a les engendrer.








                               27         Mercredi 3 Octobre 1984



Ceyx: Une Initiation                     2: Les Records Autotype's

2.4  La Construction send


Les proprie'te's se'mantiques des  Trecords  et  des  Tclasses  sont
de'finies  de la me↑me manie`re que pour les Records et les Classes.
La construction semcall fonctionne e'galement sur les Trecords  et
les Tclasses.


(send <sem> <object> <arg>1 ... <arg>n)


   Tous les  arguments  sont  e'value's,  <object>  doit  e↑tre  une
   instance  de  Trecord  ou  de  Tclasse.  Cette construction ne
   fonctionne que pour les proprie'te's se'mantiques dont le premier
   argument  est  une  instance  de la structure pour laquelle on
   de'finit cette proprie'te' se'mantique. Elle est e'quivalente a`:


   (semcall <sem> (model <object>) <object> <arg>1 ... <arg>n)



On trouvera de nombreux exemples  d'application  dans  le  manuel
programmeur Ceyx: "Programmer en Ceyx".

















                               28         Mercredi 3 Octobre 1984



                       Table des matie`res











































                                1         Mercredi 3 Octobre 1984



                       Table des matie`res

                       Table des matie`res



1 Les Records Lisp
1.1 Introduction.........................................8
1.2 De'finition d'un Record Lisp.........................11
1.3 Fonctions de Manipulation des Instances de Record...11
1.3.1 Cre'ation d'Instances..............................11
1.3.2 Discrimination....................................12
1.3.3 Acce`s aux Champs..................................13
1.4 Les Records Extensibles ou Classes..................14
1.5 Proprie'te's Se'mantiques des Records et des Classes...15
1.6 Un Exemple De'veloppe'................................17

2 Les Records Autotype's
2.1 Introduction........................................22
2.2 De'finition d'un Record Autotype' ou Trecord..........26
2.3 De'finition d'une Classe Autotype'e ou Tclasse........27
2.4 La Construction send................................28






















                                2         Mercredi 3 Octobre 1984



                    Index des fonctions Lisp











































                                1         Mercredi 3 Octobre 1984



                    Index des fonctions Lisp


                    Index des fonctions Lisp


(defclass <name>/{<superclass>}:name <field>1 ... <field>n) 14
(defrecord <name> <field>1 ... <field>n) ...............11
(deftclass <name>/{<superclass>}:<name> <field>1 ... <field>n) 27
(deftrecord <name> <field>1 ... <field>n) ..............26
(ogetq <name> <fieldname> <object> .....................13
(omakeq <name> <fieldname>1 <val>1 ... <fieldname>n <val>n) 11
(omatchq <name> <object>) ..............................12
(oputq <name> <fieldname> <object> <object>1) ..........13
(semcall <structname> <sem> <arg>1 ... <arg>n) .........16
(send <sem> <object> <arg>1 ... <arg>n) ................28




























                                2         Mercredi 3 Octobre 1984