Postscript réduit compressé | (original compressé) |
Ocaml
Évaluation des programmes |
Cours | Exercices | |
|
||
let f = fun x -> x
est la syntaxe concrète
d'un (bout) de programme. La syntaxe abstraite associé sera, par exemple,
l'arbre
Liaison ("f", Fonction ("x", Variable "x)) |
a ::= | Expression | |||
c | Constante entière | |||
a + a | Somme | |||
a * a | Produit |
type exp = | Const of int | Somme of exp * exp | Produit of exp * exp;; |
2 * (3 + 4)
est représentée par:
let e = Produit (Const 2, Somme (Const 3, Const 4));; |
eval : exp -> int
qui prend une
expression arithmétique et retourne sa valeur.
a ::= | ... | |||
x | Variable |
type exp = ... | Var of string |
let ex = Somme (Const 2, Produit (Var "x", Const 3));; |
variables : exp -> string Set.t
qui calcule l'ensemble des variables d'une expression arthmétique.
eval : (string * int) list -> exp -> int
qui prend un environnement, une expression et retourne le résultat de cette
expression dans l'environnement.
a ::= | Expression | |||
c | Const | |||
f a | Primitive | |||
x | Variable | |||
a a | Application | |||
fun x ® a | Fonction | |||
let x = a1 in a2 | Liaison |
type prim = {name : string; arity : int} let succ = {name ="succ"; arity = 1} let plus = {name = "plus"; arity = 2} type exp = | Const of int | Prim of prim * exp list | Var of var | App of exp * exp | Fonction of var * exp | Liaison of var * exp * exp and var = string;; |
let e1 = Liaison ("f", Fonction ("y", Prim (plus, [ Var "y"; Const 3 ])), App (Var "f", Const 2));; |
e1
doit valoir 3?
Quels sont les autres formes de valeurs possibles?
Liaison ("f", Liaison ("x", Const 1, Fonction ("y", Prim (plus, [Var "x"; Var "y"]))) Liaison ("x", Const 2, App (Var "f", Var "x")));; |
Liaison ("x", Const 2, App (Fonction ("y", Prim (plus, [Var "x"; Var "y"])), Var "x"));; |
Var "f"
par
Fonction ("y", Prim (plus, [Var "x"; Var "y"])))
.
v ::= | Valeurs | |||
c | Constante entière | |||
á fun x ® a, rñ | Fermeture |
type valeur = | Vconst of int | Vfonction of var * exp * env and env = (var * valeur) list;; |
r ::= | Résultats | |||
v | Valeur | |||
Err | Erreur |
type error = | Libre of string | Delta of prim * valeur list | Beta of exp exception Error of error let error e = raise (Error e);; |
let delta_succ [Vconst x] = Vconst (x + 1) let delta_plus [Vconst x; Vconst y] = Vconst (x + y) let delta = [ "succ", delta_succ; "plus", delta_plus; ] ;; |
|
|
|
|
|
|
|
|
|
|
|
· |
Deux conclusions de formes différentes sont deux cas différents dans la
fonction eval .
|
· | Deux conclusions de la même forme (cas de l'application) corresponde à un même cas, les sous-expressions sont évaluées puis selon la forme de résultat l'une ou l'autre règle s'applique. |
let find x env = try List.assoc x env with Not_found -> error (Libre x);; let rec eval env = function | Const c -> Vconst c | Var x as vx -> find x env | Fonction (x, a) as f -> Vfonction (x, a, env) | App (a1, a2) as e -> let f = eval env a1 in let v = eval env a2 in begin match f with | Vfonction (x, a, env0) -> eval ((x, v) :: env0) a | Vconst _ -> error (Beta e) end | Prim (f, args) as e -> let vargs = List.map (eval env) args in begin try (List.assoc f.name delta) vargs with x -> error (Delta (f, vargs)) end | Liaison (x, e1, e2) as e -> eval env (App (Fonction (x, e2), e1)) ;; |
let v1 = eval [] e1;; |
· | Dans le cas idéal, l'évaluation retourne une valeur. |
· | L'évaluation produit une erreur. |
· |
L'évaluation peut aussi ``ne pas terminer''. Formellement, la seule chose que l'on peut dire est que pour un environnement r et un programme certain a il n'existe pas de réponse r telle que a r |- a Þ r. On note alors r |- a . Toutefois, la divergence ne correspond à la non terminaison au sens habituel que si les règles d'erreurs sont correctement définie (et comportent sufissement de cas). En effet, supprimer une règle d'erreur revient à chacun une erreur en une divergence. |
a ::= | Expression | |||
... | comme avant, sauf | |||
ck a k | Const | |||
c0 ::= | 0, 1, 2, ... | Entiers | ||
c2 ::= | (·, ·) | Paires |
type constr = Int of int | Constr of string type const = {constr : constr; carity : int} ... | Const of constructeur * exp list |
v ::= | Valeurs | |||
... | comme avant, sauf | |||
ck vk | Const | |||
c0 ::= | 0, 1, 2, ... | Entiers | ||
c2 ::= | (_, _) | Paires |
|
a ::= | Expression | |||
... | comme avant, plus | |||
ifz a0 then a1 else a2 | Conditionnelle |
|
|
a ::= | Expression | |||
... | comme avant, sauf | |||
ref a | Référence | |||
!a | Référence | |||
a := a | Référence |
type exp = ... | Ref of exp | Deref of exp | Assign of exp * exp |
v ::= | Valeurs | |||
... | comme avant, sauf | |||
loc m | Location mémoire |
|
|
|
|
type valeur = ... | Loc of valeur ref;; let loc v = Loc (ref v);; |
type error = ... | Loc of exp let rec eval = ... | Ref a -> loc (eval env a) | Deref a as e -> let v = eval env a in begin match v with Loc l -> !l | _ -> error (Loc e) end | Assign (a1, a2) -> let v1 = eval env a1 in begin match v with Loc l -> l := eval env a2 | _ -> error (Loc e) end ;; |
· | Directement, en ajoutant une construction pour cela. |
· | Indirectement, en utilisant des fonctions. |
· |
Indirectement, en utilisant des références. |
|
|
|
This document was translated from LATEX by HEVEA and HACHA.