forked from TiarkRompf/minidot
-
Notifications
You must be signed in to change notification settings - Fork 1
/
dot_exs.v
322 lines (290 loc) · 10.6 KB
/
dot_exs.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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
Require Import dot.
(* ############################################################ *)
(* Examples *)
(* ############################################################ *)
(*# Infrastructure #*)
Hint Constructors dms_has_type.
Definition dm_compute (d: dm) (l: lb) :=
match d with
| dty T11 => TTyp l T11 T11
| dfun (Some T11) (Some T12) t12 => TFun l T11 T12
| dfun _ _ t12 => TFun l TBot TTop (* tactic not supported *)
end.
Fixpoint dms_compute (ds: dms) :=
match ds with
| dnil => TTop
| dcons d ds => TAnd (dm_compute d (length (dms_to_list ds))) (dms_compute ds)
end.
Ltac apply_dfun := match goal with
| [ |- dms_has_type ?GH ?G1 (dcons (dfun (Some ?T11) (Some ?T12) ?t12) ?ds) ?T ?n ] =>
eapply (D_Fun GH G1 (length (dms_to_list ds)) (Some T11) T11 (Some T12) T12 (open 0 (TVar false (length GH)) T12) t12 ds (dms_compute ds) (TAnd (TFun (length (dms_to_list ds)) T11 T12) (dms_compute ds)))
end.
Ltac apply_tobj := match goal with
| [ |- has_type ?GH ?G1 (tobj ?ds) ?T ?n ] =>
eapply (T_Obj GH G1 ds) with (T':=(dms_compute ds)); try solve [simpl; reflexivity]
end.
Ltac pick_stp_and c :=
match goal with
| [ |- stp ?GH ?G1 (TAnd ?T _) ?T ?n ] =>
eapply stp_and11; c
| [ |- stp ?GH ?G1 (TAnd _ ?T) ?T ?n ] =>
eapply stp_and12; c
| [ |- stp ?GH ?G1 (TAnd _ _) (TAnd _ _) ?n ] =>
idtac
| [ |- stp ?GH ?G1 (TAnd (TFun ?l _ _) _) (TFun ?l _ _) ?n ] =>
eapply stp_and11; c
| [ |- stp ?GH ?G1 (TAnd (TFun ?l _ _) _) _ ?n ] =>
eapply stp_and12; c
| [ |- stp ?GH ?G1 (TAnd (TTyp ?l _ _) _) (TTyp ?l _ _) ?n ] =>
eapply stp_and11; c
| [ |- stp ?GH ?G1 (TAnd (TTyp ?l _ _) _) _ ?n ] =>
eapply stp_and12; c
| [ |- stp ?GH ?G1 (TAnd _ (TTyp ?l _ _)) (TTyp ?l _ _) ?n ] =>
eapply stp_and12; [eapply stp_typ; c | c]
| _ => idtac
end.
Fixpoint compute_split_aux {X} (G: list X) (r: nat) :=
match G with
| [] => ([],[])
| x::G => match r with
| 0 => ([],x::G)
| S r => match compute_split_aux G r with
| (GU,GL) => (x::GU,GL)
end
end
end.
Definition compute_split {X} (G: list X) (n: nat) :=
compute_split_aux G ((length G)-(S n)).
Definition compute_GU {X} (G: list X) (n: nat) :=
match (compute_split G n) with
| (GU,GL) => GU
end.
Definition compute_GL {X} (G: list X) (n: nat) :=
match (compute_split G n) with
| (GU,GL) => GL
end.
Fixpoint rev_open (k: nat) (u: id) (T: ty) { struct T }: ty :=
match T with
| TTop => TTop
| TBot => TBot
| TSel (TVar false x) l => TSel (if beq_nat x u then TVarB k else TVar false x) l
| TSel p l => TSel p l
| TFun l T1 T2 => TFun l (rev_open k u T1) (rev_open (S k) u T2)
| TTyp l T1 T2 => TTyp l (rev_open k u T1) (rev_open k u T2)
| TBind T1 => TBind (rev_open (S k) u T1)
| TAnd T1 T2 => TAnd (rev_open k u T1) (rev_open k u T2)
| TOr T1 T2 => TOr (rev_open k u T1) (rev_open k u T2)
end.
Ltac apply_htp_sub :=
match goal with
| [ |- htp ?GH ?G1 ?x ?T ?n ] =>
eapply (htp_sub GH (compute_GU GH x) (compute_GL GH x))
end.
Ltac apply_rev_open :=
match goal with
| [ |- ?T1 = open ?k (TVar false ?u) ?T2 ] =>
try instantiate (1:=rev_open k u T1); simpl; reflexivity
end.
Ltac apply_refl c d :=
match goal with
| [ |- stp ?GH ?G1 ?T1 ?T2 ?n ] =>
assert (T1 = T2) as Eq by solve [simpl; reflexivity];
assert (stpd GH G1 T1 T2) as A by solve [eapply stpd_refl; d];
simpl in Eq; inversion Eq; clear A; clear Eq;
c
end.
Ltac apply_stp_bot :=
match goal with
| [ |- stp ?GH ?G1 TBot ?T2 ?n ] =>
eapply stp_bot
end.
Ltac apply_stp_top :=
match goal with
| [ |- stp ?GH ?G1 ?T1 TTop ?n ] =>
eapply stp_top
end.
Ltac apply_stp_selx :=
match goal with
| [ |- stp ?GH ?G1 (TSel ?X1 ?l1) (TSel ?X2 ?l2) ?n ] =>
eapply stp_selx
end.
Ltac apply_refl_typ c :=
match goal with
| [ |- stp ?GH ?G1 (TTyp ?l ?TS ?TU) (TTyp _ _ _) _ ] =>
assert (closed (length GH) (length G1) 0 (TTyp l TS TU)) as C by solve [c];
inversion C; subst; eapply stp_typ;
try solve [apply_refl idtac eassumption; c]; solve [c]
end.
Ltac apply_stp_sel2 c :=
eapply stp_trans;
[idtac |
eapply stp_sel2; try solve [simpl; reflexivity]; c];
c.
Ltac crush := simpl;
try solve [eapply T_Sub; [(apply_tobj; crush) | (crush)]];
try solve [apply_dfun; crush];
try solve [apply_stp_bot; crush];
try solve [apply_stp_top; crush];
try solve [apply_stp_selx; crush];
try solve [apply_refl_typ crush];
try solve [eapply stp_and2; crush];
try solve [pick_stp_and crush];
try solve [apply_stp_sel2 crush];
try solve [eapply stp_sel1; try solve [simpl; reflexivity]; crush];
try solve [eapply stp_bindx; try solve [simpl; reflexivity]; crush];
try solve [eapply stp_bind1; try solve [simpl; reflexivity]; crush];
try solve [apply_rev_open];
try solve [simpl; erewrite <- closed_no_open; try reflexivity; crush];
try solve [apply_htp_sub; try solve [simpl; reflexivity];
[eapply htp_var; crush | compute; repeat pick_stp_and; crush]];
try solve [eapply T_App; try solve [simpl; reflexivity]; [idtac | crush | crush]; crush];
try solve [econstructor; try solve [simpl; reflexivity]; crush];
try solve [eapply T_Sub; crush];
try solve [unfold eq_some; eauto 3].
Definition tfun TS TU t := dfun (Some TS) (Some TU) t.
Definition nfun t := dfun None None t.
Fixpoint list_to_dms (xs: list dm) : dms :=
match xs with
| nil => dnil
| cons d xs => dcons d (list_to_dms xs)
end.
Definition lobj ds := tobj (list_to_dms ds).
(*# Sanity Check #*)
Example ex0: has_typed [] [] (tobj dnil) TTop.
eexists. crush.
Grab Existential Variables.
apply 0. apply 0.
Qed.
(*# Polymorphic Identity Function #*)
Definition polyId := TFun 0 (TTyp 0 TBot TTop) (TFun 0 (TSel (TVarB 0) 0) (TSel (TVarB 1) 0)).
Example ex1: has_typed
[] []
(tobj (dcons (tfun (TTyp 0 TBot TTop) (TFun 0 (TSel (TVarB 0) 0) (TSel (TVarB 1) 0))
(tobj (dcons (tfun (TSel (TVar false 1) 0) (TSel (TVar false 1) 0) (tvar false 3)) dnil))) dnil)) polyId.
Proof.
compute. eexists. crush.
Grab Existential Variables.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
Qed.
(* instantiate it to TTop *)
Example ex2: has_typed [polyId] [] (tapp (tvar false 0) 0 (tobj (dcons (dty TTop) dnil))) (TFun 0 TTop TTop).
Proof.
unfold polyId.
eexists.
eapply T_App.
eapply T_Sub.
eapply T_Varz. compute. reflexivity.
crush.
instantiate (2:=TTyp 0 TTop TTop). crush.
crush.
crush.
Grab Existential Variables.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0.
Qed.
(*# List Module Example from Paper #*)
(*
-- module implementation
val listModule = new { m =>
type List = { this =>
type Elem
def head(): this.Elem
def tail(): m.List & { type Elem <: this.Elem }
}
def nil() = new { this =>
type Elem = Bot
def head() = bot()
def tail() = bot()
}
def cons[T](hd: T)(tl: m.List & { type Elem <: T }) = new { this =>
type Elem = T
def head() = hd
def tail() = tl
}
}
-- module type
type ListAPI = { m =>
type List <: { this =>
type Elem
def head(): this.Elem
def tail(): m.List & { type Elem <: this.Elem }
}
def nil(): List & { type Elem = Bot }
def cons[T]: T =>
m.List & { type Elem <: T } =>
m.List & { type Elem <: T }
}
-- desugaring of cons type parameter
def cons(t: { type T }) = new {
def apply(hd: t.T) = new {
def apply(tl: m.List & { type Elem <: t.T }) = new { this =>
type Elem = t.T
def head() = hd
def tail() = tl
}}}
*)
Definition TLst m EL EU :=
(TBind (TAnd
(*def head(_:Top):this.Elem*)
(TFun 2 TTop (TSel (TVarB 1) 0)) (TAnd
(*def tail(_:Top): m.List & { type Elem <: this.Elem } *)
(TFun 1 TTop (TAnd (TSel m 0) (TTyp 0 TBot (TSel (TVarB 1) 0))))
(*type Elem*)
(TTyp 0 EL EU)
))).
Definition mList := (TSel (TVar false 0) 0).
Definition pT := (TSel (TVar false 1) 0).
Example paper_lst:
has_typed [] []
(* list module impl. *)
(lobj
[(*def nil*)
(tfun TTop (TAnd mList (TTyp 0 TBot TBot))
(lobj [(*def head*)(tfun TTop TBot (*error*)(tapp (tvar false 2) 2 (tvar false 3)));
(*def tail*)(tfun TTop TBot (*error*)(tapp (tvar false 2) 1 (tvar false 3)));
(*def Elem*)(dty TBot)]));
(*def cons*)
(tfun
(*T*)(TTyp 0 TBot TTop)
(TFun 0 (*hd*)(*:T*)(TSel (TVarB 0) 0)
(TFun 0 (*tl*)(TAnd mList (TTyp 0 TBot (TSel (TVarB 1) 0)))
(TAnd mList (TTyp 0 (TSel (TVarB 2) 0) (TSel (TVarB 2) 0)))))
(lobj [(tfun pT
(TFun 0 (TAnd mList (TTyp 0 TBot pT))
(TAnd mList (TTyp 0 pT pT)))
(lobj [(tfun (TAnd mList (TTyp 0 TBot pT))
(TAnd mList (TTyp 0 pT pT))
(lobj [(*def head*)(tfun TTop pT (tvar false 3));
(*def tail*)(tfun TTop
(TAnd mList (TTyp 0 TBot pT))
(tvar false 5));
(*def Elem*)(dty pT)]))]))]));
(*type List*)
(dty (TLst (TVar false 0) TBot TTop))])
(* list module type *)
(TBind (TAnd
(*def nil *)
(TFun 2 TTop (TAnd (TSel (TVarB 1) 0) (TTyp 0 TBot TBot))) (TAnd
(*def cons *)
(TFun 1
(TTyp 0 TBot TTop)
(TFun 0 (TSel (TVarB 0) 0)
(TFun 0 (TAnd (TSel (TVarB 2) 0) (TTyp 0 TBot (TSel (TVarB 1) 0)))
(TAnd (TSel (TVarB 3) 0) (TTyp 0 TBot (TSel (TVarB 2) 0))))))
(*type List *)
(TTyp 0 TBot (TLst (TVarB 2) TBot TTop))))).
Proof.
compute. eexists. crush.
Grab Existential Variables.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0. apply 0.
apply 0. apply 0. apply 0. apply 0.
Qed.