-
Notifications
You must be signed in to change notification settings - Fork 1
/
dyn.v
185 lines (149 loc) · 4.23 KB
/
dyn.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
(*
** Dynamization of LIR terms: Type erasure for Lir expressions
*)
Require Import Coq.Logic.Decidable.
Require Import PeanoNat.
Require Import Coq.Strings.String.
Require Import Ascii.
Require Import Bool.
Require Import Nat.
Require Import LIR.maps.
Require Import LIR.lir.
(*
** 'dyn' transformation
*)
Fixpoint dyn (e : IRE) : IRE :=
match e with
| IRENil => IREBox TgNil IRENil
| IRENum n => IREBox TgInt (IRENum n)
| IREPlus e1 e2 => IREBox TgInt (IREPlus (IREUnbox TgInt (dyn e1))
(IREUnbox TgInt (dyn e2)))
| IRENew => IREBox TgTbl IRENew
| IRETAddr a => IREBox TgTbl (IRETAddr a)
| IREFAddr a => IREBox TgFun (IREFAddr a)
| IREGet e1 e2 => IREGet (IREUnbox TgTbl (dyn e1)) (dyn e2)
| IRESet e1 e2 e3 => IREBox TgNil (IRESet (IREUnbox TgTbl (dyn e1))
(dyn e2)
(dyn e3))
| IREVar var => IREVar var
| IRELet var t e body => IRELet var IRTStar (dyn e) (dyn body)
| IREFun var exp => IREBox TgFun (IREFun var (dyn exp))
| IREApp e1 e2 => IREApp (IREUnbox TgFun (dyn e1)) (dyn e2)
| IREBox _ e => dyn e
| IREUnbox _ e => dyn e
end.
(* 'dyn' is idempotent *)
Theorem dynIdempotent : forall e, dyn e = dyn (dyn e).
Proof. induction e; simpl; congruence. Qed.
(*
** 'dyn' for environments: all variables have type '*'
*)
Fixpoint dynGamma (Γ : IREnvironment) : IREnvironment :=
match Γ with
| MEmpty => MEmpty
| MCons var t Γ' => MCons var IRTStar (dynGamma Γ')
end.
(* Correctness of dynGamma *)
Lemma TP2TGammaIn : forall Γ var T,
In Γ var = Some T -> In (dynGamma Γ) var = Some IRTStar.
Proof.
induction Γ; intros; breakStrDec; try easy; eauto.
Qed.
Lemma NTP2TGammaIn : forall Γ var,
In Γ var = None -> In (dynGamma Γ) var = None.
Proof.
intros. induction Γ; breakStrDec; subst; auto.
Qed.
(*
** 'dyn' preserves well-typeness
*)
Theorem dynTyping : forall Γ e T,
Γ |= e : T -> dynGamma Γ |= (dyn e) : IRTStar.
Proof with apply IRTyUnbox; trivial.
induction 1; eauto using IRTyping, TP2TGammaIn.
Qed.
(*
** 'dyn' preserves well-typeness in the empty environment
*)
Corollary dynTypingE : forall e,
MEmpty |= e : IRTStar -> MEmpty |= dyn e : IRTStar.
Proof.
replace MEmpty with (dynGamma MEmpty) by trivial.
eauto using dynTyping.
Qed.
(*
** 'dyn' preserves "valueness".
*)
Theorem dynValue : forall e, Value e -> Value (dyn e).
Proof.
induction 1; simpl; auto using Value.
Qed.
(*
** 'dyn' commutes with substitution
*)
Lemma dynSubst : forall var e1 e2,
([var := dyn e1](dyn e2)) = dyn ([var := e1]e2).
Proof.
induction e2;
simpl; breakStrDec;
simpl; congruence.
Qed.
(*
** Lift 'dyn' to memories
*)
Fixpoint dynMem (m : Mem) : Mem :=
match m with
| EmptyMem => EmptyMem
| UpdateT a n (EV e ve) m =>
UpdateT a n (EV (dyn e) (dynValue e ve)) (dynMem m)
| UpdateF a v b m => UpdateF a v (dyn b) (dynMem m)
end.
(*
** 'dynMem' preserves memory correctness
*)
Lemma dynMemCorrect : forall m, mem_correct m -> mem_correct (dynMem m).
Proof.
induction 1;
try match goal with
[V: ExpValue |- _] => destruct V
end; eauto using mem_correct, dynTypingE.
constructor; eauto.
replace (var |=> IRTStar; MEmpty) with
(dynGamma (var |=> IRTStar; MEmpty)) by trivial.
eauto using dynTyping.
Qed.
(* 'dyn' preserves indices *)
Lemma DynIndex : forall e, ToIndex e = ToIndex (dyn e).
Proof.
induction e; eauto.
Qed.
(*
** Two values have equal indices iff they are equal up to type erasure.
*)
Lemma DynIndexEq : forall e1 e2,
Value e1 ->
Value e2 ->
(ToIndex e1 = ToIndex e2 <-> dyn e1 = dyn e2).
Proof.
intros * HV1 HV2. split.
- induction e1; intros; induction e2; try easy; eauto using valBoxVal;
simpl in *; congruence.
- rewrite DynIndex. rewrite (DynIndex e2). congruence.
Qed.
(*
** For values with ground types, 'dyn' means boxing them.
*)
Lemma ValueTag : forall e tg,
Value e -> MEmpty |= e : Tag2Type tg -> dyn e = IREBox tg e.
Proof.
destruct tg; inversion 1; inversion 1; trivial.
Qed.
(*
** For values with type '*', 'dyn' does nothing.
*)
Lemma ValueStar : forall e,
Value e -> MEmpty |= e : IRTStar -> e = dyn e.
Proof.
induction 1; inversion 1; subst.
simpl. erewrite ValueTag; trivial.
Qed.