| 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.