Skip to content

Commit 4a5529b

Browse files
committed
it compiles
1 parent 50a3039 commit 4a5529b

79 files changed

Lines changed: 3224 additions & 2059 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/ecAst.ml

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ and f_node =
207207
| Fpr of pr (* hr *)
208208

209209
and eagerF = {
210+
eg_ml : memory;
211+
eg_mr : memory;
210212
eg_pr : form;
211213
eg_sl : stmt; (* No local program variables *)
212214
eg_fl : EcPath.xpath;
@@ -216,6 +218,8 @@ and eagerF = {
216218
}
217219

218220
and equivF = {
221+
ef_ml : memory;
222+
ef_mr : memory;
219223
ef_pr : form;
220224
ef_fl : EcPath.xpath;
221225
ef_fr : EcPath.xpath;
@@ -231,6 +235,7 @@ and equivS = {
231235
es_po : form; }
232236

233237
and sHoareF = {
238+
hf_m : memory;
234239
hf_pr : form;
235240
hf_f : EcPath.xpath;
236241
hf_po : form;
@@ -244,6 +249,7 @@ and sHoareS = {
244249

245250

246251
and eHoareF = {
252+
ehf_m : memory;
247253
ehf_pr : form;
248254
ehf_f : EcPath.xpath;
249255
ehf_po : form;
@@ -257,6 +263,7 @@ and eHoareS = {
257263
}
258264

259265
and bdHoareF = {
266+
bhf_m : memory;
260267
bhf_pr : form;
261268
bhf_f : EcPath.xpath;
262269
bhf_po : form;
@@ -280,6 +287,309 @@ and pr = {
280287
pr_event : form;
281288
}
282289

290+
type ss_inv = {
291+
m : memory;
292+
inv : form;
293+
}
294+
295+
let map_ss_inv (fn: form list -> form) (invs: ss_inv list): ss_inv =
296+
assert (List.length invs > 0);
297+
let m' = (List.hd invs).m in
298+
let inv = fn (List.map (fun {inv;m} -> assert (m = m'); inv) invs) in
299+
{ m = m'; inv = inv }
300+
301+
let map_ss_inv1 (fn: form -> form) (inv: ss_inv): ss_inv =
302+
let inv' = fn inv.inv in
303+
{ m = inv.m; inv = inv' }
304+
305+
let map_ss_inv2 (fn: form -> form -> form) (inv1: ss_inv) (inv2: ss_inv): ss_inv =
306+
assert (inv1.m = inv2.m);
307+
let inv' = fn inv1.inv inv2.inv in
308+
{ m = inv1.m; inv = inv' }
309+
310+
let map_ss_inv3 (fn: form -> form -> form -> form)
311+
(inv1: ss_inv) (inv2: ss_inv) (inv3: ss_inv): ss_inv =
312+
assert (inv1.m = inv2.m && inv2.m = inv3.m);
313+
let inv' = fn inv1.inv inv2.inv inv3.inv in
314+
{ m = inv1.m; inv = inv' }
315+
316+
let map_ss_inv_destr2 (fn: form -> form * form) (inv: ss_inv): ss_inv * ss_inv =
317+
let inv1, inv2 = fn inv.inv in
318+
let m = inv.m in
319+
(* Everything should be boolean *)
320+
assert (inv1.f_ty = inv2.f_ty && inv1.f_ty = inv.inv.f_ty);
321+
{m;inv=inv1}, {m;inv=inv2}
322+
323+
let map_ss_inv_destr3 (fn: form -> form * form * form) (inv: ss_inv): ss_inv * ss_inv * ss_inv =
324+
let inv1, inv2, inv3 = fn inv.inv in
325+
let m = inv.m in
326+
(* Everything should be boolean *)
327+
assert (inv1.f_ty = inv2.f_ty && inv2.f_ty = inv3.f_ty && inv1.f_ty = inv.inv.f_ty);
328+
{m;inv=inv1}, {m;inv=inv2}, {m;inv=inv3}
329+
330+
type ts_inv = {
331+
ml : memory;
332+
mr : memory;
333+
inv : form;
334+
}
335+
336+
let map_ts_inv (fn: form list -> form) (invs: ts_inv list): ts_inv =
337+
assert (List.length invs > 0);
338+
let ml' = (List.hd invs).ml in
339+
let mr' = (List.hd invs).mr in
340+
let inv = fn (List.map (fun {inv;ml;mr} -> assert (ml = ml' && mr = mr'); inv) invs) in
341+
{ ml = ml'; mr = mr'; inv = inv }
342+
343+
let map_ts_inv1 (fn: form -> form) (inv: ts_inv): ts_inv =
344+
let inv' = fn inv.inv in
345+
{ ml = inv.ml; mr = inv.mr; inv = inv' }
346+
347+
let map_ts_inv2 (fn: form -> form -> form) (inv1: ts_inv) (inv2: ts_inv): ts_inv =
348+
assert (inv1.ml = inv2.ml && inv1.mr = inv2.mr);
349+
let inv' = fn inv1.inv inv2.inv in
350+
{ ml = inv1.ml; mr = inv1.mr; inv = inv' }
351+
352+
let map_ts_inv3 (fn: form -> form -> form -> form)
353+
(inv1: ts_inv) (inv2: ts_inv) (inv3: ts_inv): ts_inv =
354+
assert (inv1.ml = inv2.ml && inv2.ml = inv3.ml &&
355+
inv1.mr = inv2.mr && inv2.mr = inv3.mr);
356+
let inv' = fn inv1.inv inv2.inv inv3.inv in
357+
{ ml = inv1.ml; mr = inv1.mr; inv = inv' }
358+
359+
let map_ts_inv_left (fn: ss_inv list -> ss_inv) (invs: ts_inv list): ts_inv =
360+
assert (List.length invs > 0);
361+
let mr' = (List.hd invs).mr in
362+
let inv = fn (List.map (fun {inv;ml;mr} -> assert (mr = mr'); {m=ml;inv}) invs) in
363+
{ ml=inv.m; mr = mr'; inv = inv.inv }
364+
365+
let map_ts_inv_left1 (fn: ss_inv -> ss_inv) (inv: ts_inv): ts_inv =
366+
let inv' = fn {m=inv.ml; inv=inv.inv} in
367+
{ ml = inv.ml; mr = inv.mr; inv = inv'.inv }
368+
369+
let map_ts_inv_left2 (fn: ss_inv -> ss_inv -> ss_inv) (inv1: ts_inv) (inv2: ts_inv): ts_inv =
370+
assert (inv1.mr = inv2.mr);
371+
let inv' = fn {m=inv1.ml; inv=inv1.inv} {m=inv2.ml; inv=inv2.inv} in
372+
{ ml = inv1.ml; mr = inv1.mr; inv = inv'.inv }
373+
374+
let map_ts_inv_left3 (fn: ss_inv -> ss_inv -> ss_inv -> ss_inv)
375+
(inv1: ts_inv) (inv2: ts_inv) (inv3: ts_inv): ts_inv =
376+
assert (inv1.mr = inv2.mr && inv2.mr = inv3.mr);
377+
let inv' = fn {m=inv1.ml; inv=inv1.inv} {m=inv2.ml; inv=inv2.inv} {m=inv3.ml; inv=inv3.inv} in
378+
{ ml = inv1.ml; mr = inv1.mr; inv = inv'.inv }
379+
380+
let map_ts_inv_right (fn: ss_inv list -> ss_inv) (invs: ts_inv list): ts_inv =
381+
assert (List.length invs > 0);
382+
let ml' = (List.hd invs).ml in
383+
let inv = fn (List.map (fun {inv;ml;mr} -> assert (ml = ml'); {m=mr;inv}) invs) in
384+
{ ml = ml'; mr = inv.m; inv = inv.inv }
385+
386+
let map_ts_inv_right1 (fn: ss_inv -> ss_inv) (inv: ts_inv): ts_inv =
387+
let inv' = fn {m=inv.mr; inv=inv.inv} in
388+
{ ml = inv.ml; mr = inv.mr; inv = inv'.inv }
389+
390+
let map_ts_inv_right2 (fn: ss_inv -> ss_inv -> ss_inv) (inv1: ts_inv) (inv2: ts_inv): ts_inv =
391+
assert (inv1.ml = inv2.ml);
392+
let inv' = fn {m=inv1.mr; inv=inv1.inv} {m=inv2.mr; inv=inv2.inv} in
393+
{ ml = inv1.ml; mr = inv1.mr; inv = inv'.inv }
394+
395+
let map_ts_inv_right3 (fn: ss_inv -> ss_inv -> ss_inv -> ss_inv)
396+
(inv1: ts_inv) (inv2: ts_inv) (inv3: ts_inv): ts_inv =
397+
assert (inv1.ml = inv2.ml && inv2.ml = inv3.ml);
398+
let inv' = fn {m=inv1.mr; inv=inv1.inv} {m=inv2.mr; inv=inv2.inv} {m=inv3.mr; inv=inv3.inv} in
399+
{ ml = inv1.ml; mr = inv1.mr; inv = inv'.inv }
400+
401+
let map_ts_inv_destr2 (fn: form -> form * form) (inv: ts_inv): ts_inv * ts_inv =
402+
let inv1, inv2 = fn inv.inv in
403+
let ml = inv.ml in
404+
let mr = inv.mr in
405+
(* Everything should be boolean *)
406+
assert (inv1.f_ty = inv2.f_ty && inv1.f_ty = inv.inv.f_ty);
407+
{ml;mr;inv=inv1}, {ml;mr;inv=inv2}
408+
409+
let map_ts_inv_destr3 (fn: form -> form * form * form) (inv: ts_inv) =
410+
let inv1, inv2, inv3 = fn inv.inv in
411+
let ml = inv.ml in
412+
let mr = inv.mr in
413+
(* Everything should be boolean *)
414+
assert (inv1.f_ty = inv2.f_ty && inv2.f_ty = inv3.f_ty && inv1.f_ty = inv.inv.f_ty);
415+
{ml;mr;inv=inv1}, {ml;mr;inv=inv2}, {ml;mr;inv=inv3}
416+
417+
let ts_inv_lower_left (fn: ss_inv list -> form) (invs: ts_inv list): ss_inv =
418+
assert (List.length invs > 0);
419+
let mr' = (List.hd invs).mr in
420+
let inv = fn (List.map (fun {inv;ml;mr} -> assert (mr = mr'); {m=ml; inv}) invs) in
421+
{ m = mr'; inv = inv }
422+
423+
let ts_inv_lower_left1 (fn: ss_inv -> form) (inv: ts_inv): ss_inv =
424+
let inv' = fn {m=inv.ml; inv=inv.inv} in
425+
{ m = inv.mr; inv = inv' }
426+
427+
let ts_inv_lower_left2 (fn: ss_inv -> ss_inv -> form) (inv1: ts_inv) inv2 =
428+
assert (inv1.mr = inv2.mr);
429+
let inv' = fn {m=inv1.ml; inv=inv1.inv} {m=inv2.ml; inv=inv2.inv} in
430+
{ m = inv1.mr; inv = inv' }
431+
432+
let ts_inv_lower_left3 (fn: ss_inv -> ss_inv -> ss_inv -> form)
433+
(inv1: ts_inv) (inv2: ts_inv) (inv3: ts_inv): ss_inv =
434+
assert (inv1.mr = inv2.mr && inv2.mr = inv3.mr);
435+
let inv' = fn {m=inv1.ml; inv=inv1.inv} {m=inv2.ml; inv=inv2.inv} {m=inv3.ml; inv=inv3.inv} in
436+
{ m = inv1.mr; inv = inv' }
437+
438+
let ts_inv_lower_right (fn: ss_inv list -> form) (invs: ts_inv list): ss_inv =
439+
assert (List.length invs > 0);
440+
let ml' = (List.hd invs).ml in
441+
let inv = fn (List.map (fun {inv;ml;mr} -> assert (ml = ml'); {m=mr; inv}) invs) in
442+
{ m = ml'; inv = inv }
443+
444+
let ts_inv_lower_right1 (fn: ss_inv -> form) (inv: ts_inv): ss_inv =
445+
let inv' = fn {m=inv.mr; inv=inv.inv} in
446+
{ m = inv.ml; inv = inv' }
447+
448+
let ts_inv_lower_right2 (fn: ss_inv -> ss_inv -> form) (inv1: ts_inv) inv2 =
449+
assert (inv1.ml = inv2.ml);
450+
let inv' = fn {m=inv1.mr; inv=inv1.inv} {m=inv2.mr; inv=inv2.inv} in
451+
{ m = inv1.ml; inv = inv' }
452+
453+
let ts_inv_lower_right3 (fn: ss_inv -> ss_inv -> ss_inv -> form)
454+
(inv1: ts_inv) (inv2: ts_inv) (inv3: ts_inv): ss_inv =
455+
assert (inv1.ml = inv2.ml && inv2.ml = inv3.ml);
456+
let inv' = fn {m=inv1.mr; inv=inv1.inv} {m=inv2.mr; inv=inv2.inv} {m=inv3.mr; inv=inv3.inv} in
457+
{ m = inv1.ml; inv = inv' }
458+
459+
(* ----------------------------------------------------------------- *)
460+
461+
type inv =
462+
| Inv_ss of ss_inv
463+
| Inv_ts of ts_inv
464+
465+
(* TODO: Get rid of this after refactor *)
466+
let inv_of_inv (inv: inv) : form =
467+
match inv with
468+
| Inv_ss ss -> ss.inv
469+
| Inv_ts ts -> ts.inv
470+
471+
let lift_ss_inv (f: ss_inv -> 'a) : inv -> 'a =
472+
let f inv = match inv with
473+
| Inv_ss ss -> f ss
474+
| Inv_ts _ -> failwith "expected single sided invariant" in
475+
f
476+
477+
let lift_ss_inv2 (f: ss_inv -> ss_inv -> 'a) : inv -> inv -> 'a =
478+
let f inv1 inv2 = match inv1, inv2 with
479+
| Inv_ss ss1, Inv_ss ss2 -> f ss1 ss2
480+
| _ -> failwith "expected only single sided invariants" in
481+
f
482+
483+
let lift_ss_inv3 (f: ss_inv -> ss_inv -> ss_inv -> 'a) : inv -> inv -> inv -> 'a =
484+
let f inv1 inv2 inv3 = match inv1, inv2, inv3 with
485+
| Inv_ss ss1, Inv_ss ss2, Inv_ss ss3 -> f ss1 ss2 ss3
486+
| _ -> failwith "expected only single sided invariants" in
487+
f
488+
489+
let lift_ts_inv (f: ts_inv -> 'a) : inv -> 'a =
490+
let f inv = match inv with
491+
| Inv_ts ss -> f ss
492+
| Inv_ss _ -> failwith "expected two sided invariant" in
493+
f
494+
495+
let lift_ts_inv2 (f: ts_inv -> ts_inv -> 'a) : inv -> inv -> 'a =
496+
let f inv1 inv2 = match inv1, inv2 with
497+
| Inv_ts ss1, Inv_ts ss2 -> f ss1 ss2
498+
| _ -> failwith "expected only two sided invariants" in
499+
f
500+
501+
(* TODO: This should be removed after refactor is done *)
502+
let lift_inv_adapter (f: form -> 'a) : inv -> 'a =
503+
let f inv = match inv with
504+
| Inv_ss ss -> f ss.inv
505+
| Inv_ts ts -> f ts.inv in
506+
f
507+
508+
let lift_inv_adapter2 (f: form -> form -> 'a) : inv -> inv -> 'a =
509+
let f inv1 inv2 = match inv1, inv2 with
510+
| Inv_ss ss1, Inv_ss ss2 -> f ss1.inv ss2.inv
511+
| Inv_ts ts1, Inv_ts ts2 -> f ts1.inv ts2.inv
512+
| _ -> failwith "expected compatible invariants" in
513+
f
514+
515+
let ss_inv_generalize_left (inv: ss_inv) (m: memory) : ts_inv =
516+
{ ml = m; mr = inv.m; inv = inv.inv }
517+
518+
let ss_inv_generalize_right (inv: ss_inv) (m: memory) : ts_inv =
519+
{ ml = inv.m; mr = m; inv = inv.inv }
520+
521+
(* ----------------------------------------------------------------- *)
522+
let map_inv (fn: form list -> form) (inv: inv list): inv =
523+
assert (List.length inv > 0);
524+
match List.hd inv with
525+
| Inv_ss ss' ->
526+
Inv_ss (map_ss_inv fn (List.map (function
527+
Inv_ss ss -> assert (ss.m = ss'.m); ss
528+
| _ -> failwith "expected all invariants to have same kind") inv))
529+
| Inv_ts ts' ->
530+
Inv_ts (map_ts_inv fn (List.map (function
531+
Inv_ts ts -> assert (ts.ml = ts'.ml && ts.mr = ts'.mr); ts
532+
| _ -> failwith "expected all invariants to have same kind") inv))
533+
534+
let map_inv1 (fn: form -> form) (inv: inv): inv =
535+
match inv with
536+
| Inv_ss ss ->
537+
Inv_ss (map_ss_inv1 fn ss)
538+
| Inv_ts ts ->
539+
Inv_ts (map_ts_inv1 fn ts)
540+
541+
let map_inv2 (fn: form -> form -> form) (inv1: inv) (inv2: inv): inv =
542+
match inv1, inv2 with
543+
| Inv_ss ss1, Inv_ss ss2 ->
544+
Inv_ss (map_ss_inv2 fn ss1 ss2)
545+
| Inv_ts ts1, Inv_ts ts2 ->
546+
Inv_ts (map_ts_inv2 fn ts1 ts2)
547+
| _ ->
548+
failwith "incompatible invariants for map_inv2"
549+
550+
let map_inv3 (fn: form -> form -> form -> form)
551+
(inv1: inv) (inv2: inv) (inv3: inv): inv =
552+
match inv1, inv2, inv3 with
553+
| Inv_ss ss1, Inv_ss ss2, Inv_ss ss3 ->
554+
Inv_ss (map_ss_inv3 fn ss1 ss2 ss3)
555+
| Inv_ts ts1, Inv_ts ts2, Inv_ts ts3 ->
556+
Inv_ts (map_ts_inv3 fn ts1 ts2 ts3)
557+
| _ ->
558+
failwith "incompatible invariants for map_inv3"
559+
560+
(* ----------------------------------------------------------------- *)
561+
(* Accessors for program logic *)
562+
(* ----------------------------------------------------------------- *)
563+
564+
let eg_pr eg = {ml=eg.eg_ml; mr=eg.eg_mr; inv=eg.eg_pr}
565+
let eg_po eg = {ml=eg.eg_ml; mr=eg.eg_mr; inv=eg.eg_po}
566+
567+
let ef_pr ef = {ml=ef.ef_ml; mr=ef.ef_mr; inv=ef.ef_pr}
568+
let ef_po ef = {ml=ef.ef_ml; mr=ef.ef_mr; inv=ef.ef_po}
569+
570+
let es_pr es = {ml=fst es.es_ml; mr=fst es.es_mr; inv=es.es_pr}
571+
let es_po es = {ml=fst es.es_ml; mr=fst es.es_mr; inv=es.es_po}
572+
573+
let hf_pr hf = {m=hf.hf_m; inv=hf.hf_pr}
574+
let hf_po hf = {m=hf.hf_m; inv=hf.hf_po}
575+
576+
let hs_pr hs = {m=fst hs.hs_m; inv=hs.hs_pr}
577+
let hs_po hs = {m=fst hs.hs_m; inv=hs.hs_po}
578+
579+
let ehf_pr ehf = {m=ehf.ehf_m; inv=ehf.ehf_pr}
580+
let ehf_po ehf = {m=ehf.ehf_m; inv=ehf.ehf_po}
581+
582+
let ehs_pr ehs = {m=fst ehs.ehs_m; inv=ehs.ehs_pr}
583+
let ehs_po ehs = {m=fst ehs.ehs_m; inv=ehs.ehs_po}
584+
585+
let bhf_pr bhf = {m=bhf.bhf_m; inv=bhf.bhf_pr}
586+
let bhf_po bhf = {m=bhf.bhf_m; inv=bhf.bhf_po}
587+
let bhf_bd bhf = {m=bhf.bhf_m; inv=bhf.bhf_bd}
588+
589+
let bhs_pr bhs = {m=fst bhs.bhs_m; inv=bhs.bhs_pr}
590+
let bhs_po bhs = {m=fst bhs.bhs_m; inv=bhs.bhs_po}
591+
let bhs_bd bhs = {m=fst bhs.bhs_m; inv=bhs.bhs_bd}
592+
283593
(* ----------------------------------------------------------------- *)
284594
(* Equality, hash, and fv *)
285595
(* ----------------------------------------------------------------- *)

0 commit comments

Comments
 (0)