Library Demos.compile_ml
Variable OP : Set.
Definition Pat := nat.
Inductive MLexp : Set :=
| Bool : bool -> MLexp
| Num : nat -> MLexp
| op : OP -> MLexp
| id : Pat -> MLexp
| appl : MLexp -> MLexp -> MLexp
| mlpair : MLexp -> MLexp -> MLexp
| lambda : Pat -> MLexp -> MLexp
| let' : Pat -> MLexp -> MLexp -> MLexp
| letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
| ite : MLexp -> MLexp -> MLexp -> MLexp.
Inductive Value : Set :=
| null : Value
| elem : bool -> Value
| int : nat -> Value
| def_op : OP -> Value.
Inductive Commande : Set :=
| quote : Value -> Commande
| car : Commande
| cdr : Commande
| cons : Commande
| push : Commande
| swap : Commande
| branch : Commande -> Commande -> Commande
| cur : Commande -> Commande
| cur_rec : Commande -> Commande
| app : Commande
| o : Commande -> Commande -> Commande.
Inductive Squelette : Set :=
| nil_squelette : Squelette
| cons_squelette : Pat -> Squelette -> Squelette.
Inductive Access : Pat -> Squelette -> Commande -> Prop :=
| Rule1 :
forall (P : Pat) (s : Squelette), Access P (cons_squelette P s) cdr
| Rule2 :
forall (P T : Pat) (s : Squelette) (C : Commande),
P <> T :>Pat -> Access P s C -> Access P (cons_squelette T s) (o car C).
Inductive Traduction : Squelette -> MLexp -> Commande -> Prop :=
| Bool_Trad :
forall (b : bool) (S : Squelette),
Traduction S (Bool b) (quote (elem b))
| Trad_num :
forall (n : nat) (S : Squelette), Traduction S (Num n) (quote (int n))
| Trad_clos :
forall (c : OP) (S : Squelette), Traduction S (op c) (quote (def_op c))
| Trad_var :
forall (p : Pat) (S : Squelette) (C : Commande),
Access p S C -> Traduction S (id p) C
| Trad_ite :
forall (S : Squelette) (E1 E2 E3 : MLexp) (C1 C2 C3 : Commande),
Traduction S E1 C1 ->
Traduction S E2 C2 ->
Traduction S E3 C3 ->
Traduction S (ite E1 E2 E3) (o push (o C1 (branch C2 C3)))
| Trad_pair :
forall (S : Squelette) (E1 E2 : MLexp) (C1 C2 : Commande),
Traduction S E1 C1 ->
Traduction S E2 C2 ->
Traduction S (mlpair E1 E2) (o push (o C1 (o swap (o C2 cons))))
| Trad_app :
forall (S : Squelette) (E1 E2 : MLexp) (C1 C2 : Commande),
Traduction S E1 C1 ->
Traduction S E2 C2 ->
Traduction S (appl E1 E2) (o push (o C1 (o swap (o C2 (o cons app)))))
| Trad_let :
forall (p : Pat) (S : Squelette) (E1 E2 : MLexp) (C1 C2 : Commande),
Traduction S E1 C1 ->
Traduction (cons_squelette p S) E2 C2 ->
Traduction S (let' p E1 E2) (o push (o C1 (o cons C2)))
| Trad_let_rec :
forall (p x : Pat) (S : Squelette) (E E2 : MLexp) (C C2 : Commande),
Traduction (cons_squelette x (cons_squelette p S)) E C ->
Traduction (cons_squelette p S) E2 C2 ->
Traduction S (letrec p x E E2) (o push (o (cur_rec C) (o cons C2)))
| Trad_lambda :
forall (S : Squelette) (p : Pat) (E : MLexp) (C : Commande),
Traduction (cons_squelette p S) E C ->
Traduction S (lambda p E) (cur C).
Definition two := lambda 0 (lambda 1 (appl (id 1) (appl (id 1) (id 0)))).
Definition compile_two : {c : Commande | Traduction nil_squelette two c}.
Proof.
unfold two in |- *.
eapply exist.
prolog
[ Bool_Trad Trad_num Trad_clos Trad_var Trad_ite Trad_pair Trad_app Trad_let
Trad_let_rec Trad_lambda Rule1 Rule2 cons_squelette nil_squelette O_S ] 10.
Defined.
Eval compute in match compile_two with
| exist c _ => c
end.
