-
Notifications
You must be signed in to change notification settings - Fork 1
/
post-typecheck.sml
360 lines (326 loc) · 10.4 KB
/
post-typecheck.sml
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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
structure PostTypecheck = struct
open TypeCheckMain
infixr 0 $
fun str_vce vce =
case vce of
VcForall (name, ft) =>
let
val ft = case ft of
FtSorting _ => "s"
| FtModule _ => "m"
in
sprintf "(forall_$ $ " [ft, name]
end
| ImplyVC p => "(imply prop "
| PropVC _ => "prop"
| AdmitVC _ => "admit"
| OpenParen => "("
| CloseParen => ")"
exception ErrorEmpty
exception ErrorClose of vc_entry list
(* formulas transcribed from [vce]s *)
datatype formula =
ForallF of string * basic_sort forall_type * formula list
| ImplyF of prop * formula list
| AndF of formula list
| PropF of prop * region
| AdmitF of prop * region
fun str_ft ft =
case ft of
FtSorting bs => str_bs bs
| FtModule _ => "module"
fun str_f gctx ctx f =
case f of
ForallF (name, ft, fs) =>
let
val (gctx, ctx) =
case ft of
FtSorting _ => (gctx, name :: ctx)
| FtModule sctx => (curry insert' (name, (sctx_names sctx, [], [], [])) gctx, ctx)
in
sprintf "(forall ($ : $) ($))" [name, str_ft ft, str_fs gctx ctx fs]
end
| ImplyF (p, fs) =>
sprintf "($ => ($))" [str_p gctx ctx p, str_fs gctx ctx fs]
| AndF fs =>
sprintf "($)" [str_fs gctx ctx fs]
| PropF (p, _) => str_p empty ctx p
| AdmitF (p, _) => sprintf "(admit $)" [str_p gctx ctx p]
and str_fs gctx ctx fs = (join " " o map (str_f gctx ctx)) fs
fun consume_close (s : vc_entry list) : vc_entry list =
case s of
CloseParen :: s => s
| _ => raise Impossible "consume_close ()"
fun get_basic_sort_SUVar s =
let
val s = update_s s
in
case s of
SUVar (a, r) =>
let
val def = BSUnit
val () = is_eqv_sort dummy empty [] (s, SBasic (def, r))
in
def
end
| _ => get_base (fn _ => raise Impossible "get_basic_sort_SUVar()/get_base()") s
end
fun get_base_and_refinement s =
case s of
SSubset ((basic_sort, _), Bind (_, p), _) =>
(basic_sort, SOME p)
| SBasic (basic_sort, _) =>
(basic_sort, NONE)
| _ => (get_base refine_SUVar_to_SBasic s, NONE)
fun get_formula s(*vce sequence*) =
case s of
[] => raise ErrorEmpty
| vce :: s =>
case vce of
VcForall (name, ft) =>
let
val (fs, s) = get_formulas s
val s = consume_close s
val (ft, fs) =
case ft of
FtModule m =>
(FtModule m, fs)
| FtSorting s =>
let
val s = normalize_s s
val (b, p) = get_base_and_refinement s
in
case p of
SOME p =>
(FtSorting b, [ImplyF (p, fs)])
| NONE =>
(FtSorting b, fs)
end
in
(ForallF (name, ft, fs), s)
end
| ImplyVC p =>
let
val (fs, s) = get_formulas s
val s = consume_close s
in
(ImplyF (p, fs), s)
end
| OpenParen =>
let
val (fs, s) = get_formulas s
val s = consume_close s
in
(AndF fs, s)
end
| CloseParen => raise ErrorClose s
| PropVC (p, r) => (PropF (p, r), s)
| AdmitVC (p, r) => (AdmitF (p, r), s)
and get_formulas (s : vc_entry list) =
let
val (f, s) = get_formula s
val (fs, s) = get_formulas s
in
(f :: fs, s)
end
handle ErrorEmpty => ([], [])
| ErrorClose s => ([], CloseParen :: s)
fun get_admits f =
case f of
AdmitF (_, r) => ([f], PropF (PTrue r, r))
| PropF _ => ([], f)
| AndF fs => mapSnd AndF $ get_admits_fs fs
| ImplyF (p, fs) =>
let
fun wrap fs = ImplyF (p, fs)
in
mapPair (map (wrap o singleton), wrap) $ get_admits_fs fs
end
| ForallF (name, bs, fs) =>
let
fun wrap fs = ForallF (name, bs, fs)
in
mapPair (map (wrap o singleton), wrap) $ get_admits_fs fs
end
and get_admits_fs fs =
case fs of
[] => ([], [])
| f :: fs =>
let
val (admits1, f) = get_admits f
val (admits2, fs) = get_admits_fs fs
in
(admits1 @ admits2, f :: fs)
end
(* another formulation of formulas that won't talk about lists *)
datatype formula2 =
ForallF2 of string * basic_sort forall_type * formula2
| BinConnF2 of bin_conn * formula2 * formula2
| PropF2 of prop * region
fun str_f2 gctx ctx f =
case f of
ForallF2 (name, ft, f) =>
let
val (gctx, ctx) =
case ft of
FtSorting _ => (gctx, name :: ctx)
| FtModule sctx => (Gctx.add (name, (sctx_names sctx, [], [], [])) gctx, ctx)
in
sprintf "(forall ($ : $) ($))" [name, str_ft ft, str_f2 gctx ctx f]
end
| BinConnF2 (opr, f1, f2) =>
sprintf "($ $ $)" [str_f2 gctx ctx f1, str_bin_conn opr, str_f2 gctx ctx f2]
| PropF2 (p, _) => str_p gctx ctx p
fun f_to_f2 f =
case f of
ForallF (name, ft, fs) => ForallF2 (name, ft, fs_to_f2 fs)
| ImplyF (p, fs) => BinConnF2 (BCImply (), PropF2 (p, get_region_p p), fs_to_f2 fs)
| AndF fs => fs_to_f2 fs
| PropF p => PropF2 p
| AdmitF p => PropF2 p (* drop admit info *)
and fs_to_f2 fs =
case fs of
[] => PropF2 (PTrue dummy, dummy)
| f :: fs => BinConnF2 (BCAnd (), f_to_f2 f, fs_to_f2 fs)
(* remove all forall-module *)
fun unpackage_f m n f =
let
val unpackage_f = unpackage_f m
in
case f of
ForallF2 (name, ft, f) =>
(case ft of
FtModule _ => raise Impossible "unpackage(): FtModule"
| FtSorting bs => ForallF2 (name, ft, unpackage_f (n + 1) f)
)
| BinConnF2 (opr, f1, f2) => BinConnF2 (opr, unpackage_f n f1, unpackage_f n f2)
| PropF2 (p, r) => PropF2 (Unpackage.unpackage_i_p m n p, r)
end
fun unpackage_f2 f =
case f of
ForallF2 (name, ft, f) =>
let
val f = unpackage_f2 f
in
case ft of
FtModule m =>
let
val mod_name = name
val f = unpackage_f mod_name 0 f
fun iter ((name, s), f) =
let
val (b, p) = get_base_and_refinement s
val f =
case p of
SOME p => BinConnF2 (BCImply (), PropF2 (p, get_region_p p), f)
| NONE => f
in
ForallF2 (mod_name ^ "_" ^ name, FtSorting b, f)
end
val f = foldl iter f m
in
f
end
| FtSorting bs =>
ForallF2 (name, ft, f)
end
| BinConnF2 (opr, f1, f2) =>
BinConnF2 (opr, unpackage_f2 f1, unpackage_f2 f2)
| PropF2 _ => f
fun collect_uvar_i_f2 f =
case f of
ForallF2 (name, bs, f) => collect_uvar_i_f2 f
| BinConnF2 (_, f1, f2) => collect_uvar_i_f2 f1 @ collect_uvar_i_f2 f2
| PropF2 (p, r) => collect_uvar_i_p p
fun f2_to_prop f : prop =
case f of
ForallF2 (name, ft, f) =>
let
val bs = case ft of
FtSorting bs => bs
| FtModule _ => raise Impossible "f2_to_prop(): FtModule"
val p = f2_to_prop f
in
PQuan (Forall (), bs, Bind ((name, dummy), p), get_region_p p)
end
| BinConnF2 (opr, f1, f2) => PBinConn(opr, f2_to_prop f1, f2_to_prop f2)
| PropF2 (p, r) => set_region_p p r
fun vces_to_vcs vces =
let
open VC
(* val () = println "VCEs: " *)
(* val () = println $ join " " $ map str_vce vces *)
val (fs, vces) = get_formulas vces
val () = case vces of
[] => ()
| _ => raise Impossible "to_vcs (): remaining after get_formulas"
(* val () = println "Formulas: " *)
(* val () = app println $ map (str_f [] []) fs *)
val (admits, fs) = get_admits_fs fs
fun fs_to_prop fs =
let
val f = fs_to_f2 fs
(* val () = println $ "Formula2: \n" ^ str_f2 empty [] f *)
val f = unpackage_f2 f
(* val () = println $ "Formula2-after-unpackage: \n" ^ str_f2 empty [] f *)
val p = f2_to_prop f
(* val () = println "Props: " *)
(* val () = println $ Expr.str_p [] [] p *)
val p = Simp.simp_p p
in
p
end
val p = fs_to_prop fs
val p = simp_p p
val p = uniquefy [] p
val admits = map (fs_to_prop o singleton) admits
(* val admits = map Expr.Simp.simp_p admits *)
val vcs = prop2vcs p
val vcs = concatMap simp_vc_vcs vcs
(* val () = app println $ concatMap (str_vc false "") vcs *)
val vcs = map VC.simp_vc vcs
val vcs = TrivialSolver.simp_and_solve_vcs vcs
in
(vcs, admits)
end
fun runWriter m () =
let
val () = acc := []
val r = m ()
val vces = rev (!acc)
val vcs_admits = vces_to_vcs vces
in
(r, vcs_admits)
end
fun typecheck_expr gctx ctx_st e =
runWriter (fn () => get_mtype gctx ctx_st e) ()
fun typecheck_decls gctx (ctx, st) decls =
let
fun m () =
let
val skctxn_old = (sctx_names $ #1 ctx, names $ #2 ctx)
val (decls, ctxd, nps, ds, ctx, st) = check_decls gctx (ctx, st) decls
val () = close_n nps
val () = close_ctx ctxd
(* val () = app println $ str_typing_info (gctx_names gctx) skctxn_old (ctxd, ds) *)
in
(decls, ctxd, ds, ctx, st)
end
in
runWriter m ()
end
fun typecheck_top_bind gctx top_bind =
runWriter (fn () => check_top_bind gctx top_bind) ()
fun typecheck_prog gctx prog =
runWriter (fn () => check_prog gctx prog) ()
(* fun runError m _ = *)
(* OK (m ()) *)
(* handle *)
(* Error e => Failed e *)
(* fun typecheck_expr_opt ctx e = *)
(* runError (fn () => typecheck_expr ctx e) () *)
(* fun typecheck_decls_opt ctx decls = *)
(* runError (fn () => typecheck_decls ctx decls) () *)
type tc_result = typing_info * (VC.vc list * prop list)
(* exception Unimpl *)
end