• Aucun résultat trouvé

Types existentiels

N/A
N/A
Protected

Academic year: 2022

Partager "Types existentiels"

Copied!
11
0
0

Texte intégral

(1)

Types existentiels

Types abstraits de données

Manipulation de domaines complexes.

La manipulation est indépendante de lareprésentation particulière du domaine.

On se donne :

Un nom pour domaine abstrait

Des opérations de construction d'une représentation concrète vers le domaine abstrait

Des opérations de test pour les diérents constructions.

Des opérations d'accèsd'un objet abstrait vers les composantes d'une représentation concrète.

1

Exemple : jour Domaine :

jour (jours vus comme des entiers de 1 à 31) Opérations de construction :

cons_jour : {x:entier|1≤x≤31} →jour Opérations de construction étendue :

entier_to_jour : entier→jour Opérations d'accès :

numéro_jour : jour→ {x:entier|1≤x≤31}

Exemple : exemplaire Domaine :

exemplaire

Opérations de construction :

cons_livre : livre→exemplaire cons_video : video→exemplaire Opérations de test :

est_livre,est_video : exemplaire→bool Opérations d'accès :

ex_livre : {x:exemplaire|est_livre(x)} →livre ex_video : {x:exemplaire|est_video(x)} →video

(2)

Exemple : argent Domaine :

argent

Opérations de construction : francs : entier→argent euros : entier→argent Opérations de test :

est_francs,est_euros : argent→bool Opérations d'accès :

val_argent : argent→entier

4

Exemple : Les cartes de couleur Domaine :

couleur Constantes :

pique,coeur,carreau,trèfle : couleur

Domaine : figure Constantes :

as,roi,dame,valet, dix,neuf,huit,sept : figure

5

Domaine : carte

Opérations de construction :

cons_carte : couleur×figure→carte Opérations d'accès :

figure_carte : carte→figure couleur_carte : carte→couleur

Domaine : main

Opérations de construction :

cons_main : {~n∈carte5|Diff(~n)} →main Opérations de construction étendue :

carte5_to_main : carte5→main Opérations d'accès :

carte1 :main→carte ...

carte5 :main→carte

(3)

Domaine : carte_tarot Constantes :

excuse : carte_tarot Opérations de construction :

cons_tarot_simple : carte→carte_tarot

cons_atout : {n :entier|1≤n≤21} →carte_tarot Opérations de construction étendue :

entier_to_carte_tarot : entier→carte_tarot Opérations de test :

est_carte_simple,est_atout : carte_tarot→bool

8

Opérations d'accès :

couleur_de_tarot : {x:carte_tarot|est_carte_simple(x)}

→couleur

figure_de_tarot : {x:carte_tarot|est_carte_simple(x)}

→figure

atout_de_tarot : {x:carte_tarot|est_atout(x)} → {n :entier|1≤n≤21}

9

Forme générale d'un TDA Domaine :

dom

Constantes : c1, . . . , cn :dom

Opérations de construction :

cons_dom1 :{x:d1|P1(x)} →dom ...

cons_domm :{x:dm|Pm(x)} →dom

Opérations de construction étendue : dom1_to_dom :d1→dom

...

domm_to_dom :dm→dom Opérations de test :

est_c1, . . . , est_cn :dom→bool ...

est_op1, . . . , est_opm :dom→bool

(4)

Opérations d'accès :

acces1 :{x:dom|est_op1(x)} → {x:d1|P1(x)}

...

accesm :{x:dom|est_opm(x)} → {x:dm|Pm(x)}

Autres opérations : ...

12

Quelques variantes

On peut omettre ou rajouterquelques items selon les cas : Si la propriété Pi(x) est toujourstrue, alors on l'écrit pas.

Si le domaine est construit à partir d'une seule constante ou d'une seule opération de construction, alors inutiled'écrire l'opération de test car elle est équivalente àest(x) =true.

Si le domaine est construit à partir de m opérations de construction, alors m−1 opérations de test susent.

Si un domaine di est un produit cartésien a1×. . .×ak, alors on peut remplacer l'opération d'accès

accesi :{x:dom|est_opi(x)} → {x:di |Pi(x)}

par k opérations de la forme

13

accesi1 :{x:dom| est_opi(x)} →

{y:a1|y =proj1(x) etx:di et Pi(x)}

...

accesik :{x:dom| est_opi(x)} →

{y:ak |y =projk(x)etx:di etPi(x)}

Le Tarot en OCAML

(* type couleur *)

#type couleur = Pique | Coeur | Carreau | Trefle;;

(* Constructeurs pour les constantes de couleur *)

#let pique = Pique;;

#let coeur = Coeur;;

#let carreau = Carreau;;

#let trefle = Trefle;;

(5)

(* type figure *)

#type figure =

As | Roi | Dame | Cavalier | Valet | Dix | Neuf | Huit | Sept;;

(* Constructeurs pour les constantes de figure *)

#let as =As;;

#let roi =Roi;;

#let dame =Dame;;

#let cavalier=Cavalier;;

#let valet =Valet;;

#let dix =Dix;;

#let neuf =Neuf;;

16

#let huit =Huit;;

#let sept =Sept;;

(* type carte *)

#type carte = Carte of figure * couleur;;

(* opération de construction du type carte *)

#let cons_carte(f,c) = Carte(f,c);;

17

(* opérations d'accès du type carte *)

#let figure_carte(e) = match e with Carte(f,c)->f;;

#let couleur_carte(e) = match e with Carte(f,c)->c;;

(* type carte_tarot *)

#type carte_tarot =

Excuse | Simple of carte | Atout of int;;

(* opérations de construction étendue du type carte_tarot *)

#let excuse = Excuse;;

#let cons_tarot_simple(c) = Simple(c);;

#let cons_atout (n) = Atout(n);;

(* opérations de construction du type carte_tarot *)

#let int_to_carte_tarot (n) = if 1 <= n & n <= 21

then cons_atout (n)

else failwith"numéro d'atout invalide";;

(* opérations de test du type carte_tarot *)

#let est_carte_simple (c) =

match c with Simple(_) -> true | _ -> false;;

(6)

#let est_atout (c) =

match c with Atout(_) -> true | _ -> false;;

(* opérations d'accès du type carte_tarot *)

#let couleur_de_tarot (e) = match e with

Simple(Carte(_,c)) -> c

| _ -> failwith "Pas une carte simple";;

20

#let figure_de_tarot (e) = match e with

Simple(Carte(f,_)) -> f

| _ -> failwith "Pas une carte simple";;

#let atout_de_tarot (e) = match e with

Atout(x) -> x

| _ -> failwith "Pas un atout";;

21

Les prols de symboles de la signature

pique: -> couleur

coeur: -> couleur

carreau: -> couleur

trefle: -> couleur

as: -> figure

roi: -> figure

dame: -> figure

cavalier: -> figure

valet: -> figure

dix: -> figure

neuf: -> figure

huit: -> figure

sept: -> figure

cons_carte: figure * couleur -> carte = <fun>

figure_carte: carte -> figure = <fun>

couleur_carte: carte -> couleur = <fun>

excuse: -> carte_tarot

cons_tarot_simple: carte -> carte_tarot = <fun>

cons_atout: int -> carte_tarot = <fun>

int_to_carte_tarot:int -> carte_tarot = <fun>

est_carte_simple: carte_tarot -> bool = <fun>

est_atout: carte_tarot -> bool = <fun>

figure_de_tarot: carte_tarot -> figure = <fun>

couleur_de_tarot: carte_tarot -> couleur = <fun>

atout_de_tarot: carte_tarot -> int = <fun>

(7)

Codage d'autres opérations d'un TDA

Abstrait :on utilise uniquement les opérations abstraites dénies dans le TDA.

Concret :on utilise les primitives du langage de programmation associées au domaines concrets utilisés dans le TDA.

24

Codage abstrait

#let points (c) = if c = excuse then 4.5

else if est_carte_simple (c)

then let f = figure_de_tarot(c) in if f = roi

then 4.5

else if f = dame then 3.5

else if f = cavalier then 2.5

else if f = valet

25

then 1.5 else 0.5 else let n = atout_de_tarot(c) in

if n=1 or n=21 then 4.5 else 0.5;;

val points : carte_tarot -> float = <fun>

Codage concret

#let points(c) = match c with

Excuse -> 4.5

| Simple(Carte(f,_)) -> (match f with Roi -> 4.5

| Dame -> 3.5

| Cavalier -> 2.5

| Valet -> 1.5

| _ -> 0.5)

| Atout(1) -> 4.5

| Atout(21) -> 4.5

| _ -> 0.5;;

val points : carte_tarot -> float = <fun>

(8)

Types existentiels Types : A::=. . .| ∃α.A

Expressions :M ::=. . .| pack M withA as∃α.A Règle de typage pour l'introduction de ∃α.A :

Γ`M :A{α/B}

Γ` pack M withB as∃α.A:∃α.A

Le terme M donne une implémentation d'un TDA ayantsignature A. Le typeB utilisé dans l'implémentation du TDA est caché si α a des occurrences libres dans le type A.

28

Exemples simples

p1= pack 0 with int as∃α.α

p2= pack (0, λx:int.x+ 0)with int as∃α.(α×(α→α)) p3= pack (0, λx:int.x+ 0)with int as∃α.(α×(α→int)) p4= pack (true, λx:bool.1)with bool as∃α.(α×(α→int)) p5= pack (0, λx:int.x+ 0)with int as∃α.(int×(int→int)) p1 ne sert à rien, p2 etp3 ont la même implémentation mais

diérente signature, p3 etp4 ont la même signature mais diérente implémentation, p5 ne cache rien.

29

On peut aussi écrire : let a= 0; ;

let f =λx:int.x+ 0; ;

let p= pack (a, f)with intas ∃α.(a:α×(f :α→α)); ; Ou bien

let z={a= 0;f =λx:int.x+ 0}; ;

let p= pack z with int as∃α.(a:α×(f :α→α)); ; z.a etz.f sont les composantes dez.

Exemple : un TDA

(9)

Domaine : type_pile Constantes :

pile_vide : type_pile Opération de construction :

cons_pile : entier×type_pile→type_pile Opération de test :

est_pile_nv : type_pile→bool Opérations d'accès

premier_pile : {x:type_pile|est_pile_nv(x)} →entier reste_pile : {x:type_pile|est_pile_nv(x)} →type_pile

32

Exemple : une première implémentation

#type pile = intlist;;

#let pile_vide = [];;

val pile_vide : intlist

#let cons_pile(a,p) = a::p;;

val cons_pile : int * intlist -> intlist = <fun>

#let est_pile_nv(p) =

match p with a::l -> true | _ -> false;;

val est_pile_nv : intlist -> bool = <fun>

33

#let premier_pile(p) = match p with a::l -> a;;

val premier_pile : intlist -> int = <fun>

#let reste_pile(p) = match p with a::l -> l;;

val reste_pile : intlist -> intlist = <fun>

type_pile=

α×(int×α→α)×(α→bool)×(α→int)×(α→α) M = (pile_vide,cons_pile,est_pile_nv,

premier_pile,reste_pile)

type_pile{α/intlist}=intlist×(int×intlist→intlist)×

(intlist→bool)×(intlist→int)×(intlist→intlist) Γ`M :type_pile{α/intlist}

Γ` packM with intlist as∃α.type_pile:∃α.type_pile

(10)

Exemple : une autre implémentation

#type pile_nv = {tete:int; reste:ma_pile} and ma_pile = Pile_Vide | P of pile_nv;;

type pile_nv = { tete : int; reste : ma_pile; } and ma_pile = Pile_Vide | P of pile_nv

# let cons_pile_nv(t,r) = { tete=t ; reste = r};;

val cons_pile_nv : int * ma_pile -> pile_nv = <fun>

# let tete_pile_nv(p) = p.tete;;

val tete_pile_nv : pile_nv -> int = <fun>

36

# let reste_pile_nv(p) = p.reste;;

val reste_pile_nv : pile_nv -> ma_pile = <fun>

# let pile_vide =Pile_Vide;;

val pile_vide : ma_pile = Pile_Vide

# let cons_pile(a,p) = P(cons_pile_nv(a,p));;

val cons_pile : int * ma_pile -> ma_pile = <fun>

# let est_pile_nv(p) =

match p with Pile_Vide -> false | _ -> true ;;

val est_pile_nv : ma_pile -> bool = <fun>

37

# let premier_pile(p) = match p with Pile_Vide -> failwith"Pile Vide"

| P(x) -> x.tete;;

val premier_pile : ma_pile -> int = <fun>

# let reste_pile(p) = match p with Pile_Vide -> failwith"Pile Vide"

| P(x) -> x.reste;;

val reste_pile : ma_pile -> ma_pile = <fun>

type_pile=

α×(int×α→α)×(α→bool)×(α→int)×(α→α) M = (pile_vide,cons_pile,est_pile_nv,

premier_pile,reste_pile)

type_pile{α/ma_pile}=ma_pile×(int×ma_pile→ma_pile)×

(ma_pile→bool)×(ma_pile→int)×(ma_pile→ma_pile) Γ`M :type_pile{α/ma_pile}

Γ` packM with ma_pileas∃α.type_pile:∃α.type_pile

(11)

Règle de typage pour l'élimination de ∃α.A :

Γ`M :∃α.A Γ, z :A`N :C Γ`unpack M asβ with z:A inN :C où la variableβ n'est pas dans C

On ouvre l'implémentation M dans leprogramme N en lui donnant un nom z et en supposant que le typecaché est β.

40

Exemples simples

Soit pune implémentation du type ∃α.(a:α, f :α→int) unpackpasβ with z:Ainz.f(z.a) + 2

unpackpasβ with z:Ainz.a+ 2 (mal typé) (unpackp asβ with z:A inz.a) + 2 (mal typé)

41

Sémantique

Si p= packM with B as∃α.A, alors

unpackpasβ withy :A inN se réduit dans N{y/M}{α/β} qui se comporte comme lety :A=M inN

Références

Documents relatifs

CONSIGNE : à l'aide du diaporama, trouve les définitions des différents types de gouvernements grecs.. TYPE DE RÉGIME ÉTYMOLOGIE

Quand je recherche dans mon livre une page `a partir de la table des mati`eres :b. je prononce le num´ero de la page `a

Pas de nouvelle cr´ eation de point dans la table pour (1,2,3) En deux comparaisons avec un autre point (au lieu de potentiellement 4).. Points

Il appara•t plus que jamais que les risques de fortes pr•cipitations sont bien le propre de la vall•e du Rhƒne de Lyon ‚ la M•diterran•e, avec une

Prévu pour rouler sur des terrains très accidentés, sur la terre, les cailloux ou dans la boue, il est équipé d'un cadre renforcé traité anti- corrosion, de pneus larges aux dessins

print (&#34;Vous n ' avez pas donné de nombre correct, nous ne pouvons donc pas donner le carré&#34;) print (&#34;Le carré de&#34;, nombre, &#34;est égale à&#34;, nombre * nombre).

Extrait du livre Enfants-Poètes de l'Ecole Freinet.. de la Table

Un autre point a été envisagé ce soir, celui de la représentativité du vieillard et de sa fonction dans un groupe social, ce qui ne nécessite nullement que,