@@ -234,20 +234,18 @@ and equivS = {
234234 es_sr : stmt ;
235235 es_po : form ; }
236236
237- and post = (form * form Mp. t * form option )
238-
239237and sHoareF = {
240238 hf_m : memory ;
241239 hf_pr : form ;
242240 hf_f : EcPath .xpath ;
243- hf_po : post ;
241+ hf_po : exnpost ;
244242}
245243
246244and sHoareS = {
247245 hs_m : memenv ;
248246 hs_pr : form ;
249247 hs_s : stmt ;
250- hs_po : post ;
248+ hs_po : exnpost ;
251249}
252250
253251and eHoareF = {
@@ -294,6 +292,11 @@ and pr = {
294292 pr_event : ss_inv ;
295293}
296294
295+ and exnpost = {
296+ main : form ;
297+ exnmap : form Mp .t * form option ;
298+ }
299+
297300let map_ss_inv ?m (fn : form list -> form ) (invs : ss_inv list ): ss_inv =
298301 let m' = match m with
299302 | Some m -> m
@@ -463,10 +466,9 @@ let ts_inv_lower_right3 (fn: ss_inv -> ss_inv -> ss_inv -> form)
463466 { m = inv1.ml; inv = inv' }
464467
465468(* ----------------------------------------------------------------- *)
466-
467469type hs_inv = {
468- hsi_m : memory ;
469- hsi_inv : post ;
470+ hsi_m : memory ;
471+ hsi_inv : exnpost ;
470472}
471473
472474type inv =
@@ -508,7 +510,7 @@ let lift_ss_inv3 (f: ss_inv -> ss_inv -> ss_inv -> 'a) : inv -> inv -> inv -> 'a
508510let lift_ts_inv (f : ts_inv -> 'a ) : inv -> 'a =
509511 let f inv = match inv with
510512 | Inv_ts ss -> f ss
511- | _ -> failwith " expected two sided invariant" in
513+ | _ -> failwith " expected two sided invariant" in
512514 f
513515
514516let lift_ts_inv2 (f : ts_inv -> ts_inv -> 'a ) : inv -> inv -> 'a =
@@ -535,15 +537,15 @@ let map_inv (fn: form list -> form) (inv: inv list): inv =
535537 Inv_ts (map_ts_inv fn (List. map (function
536538 Inv_ts ts -> assert (ts.ml = ts'.ml && ts.mr = ts'.mr); ts
537539 | _ -> failwith " expected all invariants to have same kind" ) inv))
538- | _ -> failwith " Exceptions are not supported"
540+ | Inv_hs _ -> failwith " Exceptions are not supported"
539541
540542let map_inv1 (fn : form -> form ) (inv : inv ): inv =
541543 match inv with
542544 | Inv_ss ss ->
543545 Inv_ss (map_ss_inv1 fn ss)
544546 | Inv_ts ts ->
545547 Inv_ts (map_ts_inv1 fn ts)
546- | _ -> failwith " Exceptions are not supported"
548+ | Inv_hs _ -> failwith " Exceptions are not supported"
547549
548550let map_inv2 (fn : form -> form -> form ) (inv1 : inv ) (inv2 : inv ): inv =
549551 match inv1, inv2 with
@@ -565,92 +567,121 @@ let map_inv3 (fn: form -> form -> form -> form)
565567 failwith " incompatible invariants for map_inv3"
566568
567569(* ----------------------------------------------------------------- *)
568- let empty_poe f = (f, Mp. empty, None )
570+ type 'a prepoe = 'a * ( 'a Mp .t * 'a option )
569571
570- let empty_hs f =
571- {hsi_m = f.m;hsi_inv = empty_poe f.inv }
572+ let mk_poe ( main : form ) ( exnmap : form Mp.t * form option ) =
573+ { main; exnmap; }
572574
573- let is_empty_poe poe =
574- match poe with
575- | (_ ,m ,None) when Mp. is_empty m-> true
576- | _ -> false
575+ let destruct_poe (poe : exnpost ) =
576+ (poe.main, poe.exnmap)
577+
578+ let empty_poe (f : form ) : exnpost =
579+ { main = f; exnmap = (Mp. empty, None ); }
577580
578- let lift_f f = {hsi_m= f.m;hsi_inv= empty_poe f.inv}
581+ let empty_hs (f : ss_inv ) =
582+ { hsi_m = f.m; hsi_inv = empty_poe f.inv; }
579583
580- let lower_f f =
581- let (post, _,_) = f.hsi_inv in
582- {m= f.hsi_m;inv= post}
584+ let is_empty_poe ({ exnmap = (m , dfl ) } : exnpost ) =
585+ Option. is_none dfl && Mp. is_empty m
583586
584- let update_hs_ss f p =
585- assert (f.m == p.hsi_m);
586- let (_,m,d) = p.hsi_inv in
587- {p with hsi_inv= (f.inv,m,d)}
587+ let lift_f (f : ss_inv ) =
588+ { hsi_m = f.m; hsi_inv = empty_poe f.inv; }
588589
589- let map_poe f (p ,m ,d ) =
590- let p = f p in
591- let m = Mp. map f m in
592- let d = omap f d in
593- (p, m, d)
590+ let lower_f (f : hs_inv ) =
591+ { m = f.hsi_m; inv = f.hsi_inv.main; }
594592
595- let map_hs_inv1 f inv1 = {inv1 with hsi_inv = map_poe f inv1.hsi_inv}
593+ let update_hs_ss (f : ss_inv ) (p : hs_inv ) : hs_inv =
594+ assert (f.m == (* phy*) p.hsi_m);
595+ { p with hsi_inv = { main = f.inv; exnmap = p.hsi_inv.exnmap; } }
596596
597- let map2_poe f (p1 ,m1 ,d1 ) (p2 ,m2 ,d2 ) =
598- let p = f p1 p2 in
599- let aux _ a b =
597+ let map_poe (f : form -> form ) ({ main; exnmap = (m , d ) } : exnpost ) : exnpost =
598+ { main = f main; exnmap = (Mp. map f m, omap f d)}
599+
600+ let map_hs_inv1 (f : form ->form ) (inv1 : hs_inv ) =
601+ { inv1 with hsi_inv = map_poe f inv1.hsi_inv; }
602+
603+ let map2_prepoe (f : 'a -> 'b -> 'c ) (poe1 : 'a prepoe ) (poe2 : 'b prepoe ) : 'c prepoe =
604+ let (main1, (map1, d1)) = poe1 in
605+ let (main2, (map2, d2)) = poe2 in
606+
607+ let merge (a : 'a option ) (b : 'b option ) =
600608 match a, b with
601- | Some a , Some b -> Some (f a b)
602- | _ , _ -> failwith " missing entry in exception map"
609+ | None , None -> None
610+ | Some a , Some b -> Some (f a b)
611+ | _ -> assert false
603612 in
604- let m = Mp. merge aux m1 m2 in
605- match d1, d2 with
606- | None , None -> (p, m, None )
607- | Some d1 , Some d2 -> (p, m, Some (f d1 d2))
608- | _ , _ -> failwith " missing default exception"
613+
614+ let main = f main1 main2 in
615+ let map = Mp. merge (fun _ -> merge) map1 map2 in
616+ let dfl = merge d1 d2 in
617+
618+ (main, (map, dfl))
619+
620+ let map2_poe (f : form -> form -> form ) (poe1 : exnpost ) (poe2 : exnpost ) =
621+ let main, exnmap =
622+ map2_prepoe f (destruct_poe poe1) (destruct_poe poe2) in
623+
624+ mk_poe main exnmap
609625
610626let map_hs_inv2
611- (fn : form -> form -> form ) (inv1 : hs_inv ) (inv2 : hs_inv ): hs_inv =
627+ (fn : form -> form -> form )
628+ (inv1 : hs_inv )
629+ (inv2 : hs_inv )
630+ : hs_inv
631+ =
612632 assert (inv1.hsi_m = inv2.hsi_m);
613- let inv' = map2_poe fn inv1.hsi_inv inv2.hsi_inv in
614- { hsi_m = inv1.hsi_m; hsi_inv = inv' }
633+ let inv = map2_poe fn inv1.hsi_inv inv2.hsi_inv in
634+ { hsi_m = inv1.hsi_m; hsi_inv = inv }
615635
616- let exists_poe f (p ,m ,d ) =
617- f p || Mp. exists (fun _ -> f) m || omap_dfl f false d
636+ let exists_poe (f : form -> bool ) (poe : exnpost ) =
637+ f poe.main
638+ || Mp. exists (fun _ -> f) (fst poe.exnmap)
639+ || omap_dfl f false (snd poe.exnmap)
618640
619- let forall_poe f (p ,m ,d ) =
620- f p && Mp. for_all (fun _ -> f) m && omap_dfl f true d
641+ let forall_poe (f : form -> bool ) (poe : exnpost ) =
642+ f poe.main
643+ && Mp. for_all (fun _ -> f) (fst poe.exnmap)
644+ && omap_dfl f true (snd poe.exnmap)
621645
622- let forall2_poe f ( p1 , m1 , d1 ) (p2 , m2 , d2 ) =
623- let b1 = f p1 p2 in
624- let b2 = Mp. equal f m1 m2 in
625- b1 && b2 && oeq f d1 d2
646+ let forall2_poe ( f : form -> form -> bool ) ( poe1 : exnpost ) (poe2 : exnpost ) =
647+ f poe1.main poe2.main
648+ && Mp. equal f (fst poe1.exnmap) (fst poe2.exnmap)
649+ && oeq f (snd poe1.exnmap) (snd poe2.exnmap)
626650
627- let poe_to_list ( post , poe , d ) =
651+ let prepoe_to_list (( main , ( map , d )) : ' a prepoe ) =
628652 let l =
629653 Mp. fold
630654 (fun _ p1 a -> p1 :: a)
631- poe
632- [post ]
655+ map
656+ [main ]
633657 in
634658 otolist d @ l
635659
636- let iter_poe f (p , m ,d ) =
637- f p;
638- Mp. iter (fun _ -> f) m;
639- oiter f d
660+ let poe_to_list (poe : exnpost ) =
661+ prepoe_to_list (destruct_poe poe)
662+
663+ let iter_poe (f : form -> unit ) (poe : exnpost ) =
664+ f poe.main;
665+ Mp. iter (fun _ -> f) (fst poe.exnmap);
666+ oiter f (snd poe.exnmap)
640667
641- let iter2_poe f (p1 ,m1 ,d1 ) (p2 ,m2 ,d2 ) =
642- f p1 p2;
643- let aux _ a b =
668+ let iter2_poe (f : form -> form -> unit ) (poe1 : exnpost ) (poe2 : exnpost ) =
669+ let merge (a : form option ) (b : form option ) =
644670 match a, b with
645- | Some a , Some b -> Some (a,b)
646- | _ , _ -> failwith " missing entry in exception map"
647- in
648- let m = Mp. merge aux m1 m2 in
649- Mp. iter (fun _ (p1 ,p2 ) -> f p1 p2) m;
650- match d2, d1 with
651- | None , None -> ()
652- | Some d1 , Some d2 -> f d1 d2
653- | _ , _ -> failwith " missing default exception"
671+ | None , None -> None
672+ | Some a , Some b -> Some (a, b)
673+ | _ , _ -> assert false in
674+
675+ f poe1.main poe2.main;
676+ Mp. iter
677+ (fun _ (a , b ) -> f a b)
678+ (Mp. merge (fun _ -> merge) (fst poe1.exnmap) (fst poe2.exnmap));
679+ begin
680+ match snd poe1.exnmap, snd poe2.exnmap with
681+ | None , None -> ()
682+ | Some a , Some b -> f a b
683+ | _ , _ -> assert false
684+ end
654685
655686(* ----------------------------------------------------------------- *)
656687(* Accessors for program logic *)
@@ -665,8 +696,8 @@ let ef_po ef = {ml=ef.ef_ml; mr=ef.ef_mr; inv=ef.ef_po}
665696let es_pr es = {ml= fst es.es_ml; mr= fst es.es_mr; inv= es.es_pr}
666697let es_po es = {ml= fst es.es_ml; mr= fst es.es_mr; inv= es.es_po}
667698
668- let hf_pr hf = {m= hf.hf_m; inv= hf.hf_pr}
669- let hf_po hf = {hsi_m= hf.hf_m; hsi_inv= hf.hf_po}
699+ let hf_pr hf = {m= hf.hf_m; inv= hf.hf_pr}
700+ let hf_po hf = {hsi_m= hf.hf_m; hsi_inv= hf.hf_po}
670701
671702let hs_pr hs = {m= fst hs.hs_m; inv= hs.hs_pr}
672703let hs_po hs = {hsi_m= fst hs.hs_m; hsi_inv= hs.hs_po}
@@ -1022,18 +1053,12 @@ let b_hash (bs : bindings) =
10221053 Why3.Hashcons. combine_list b1_hash 0 bs
10231054
10241055(* -------------------------------------------------------------------- *)
1025-
1026- let posts_equal (post1 , eposts1 , d1 ) (post2 , eposts2 , d2 ) =
1027- let b = f_equal post1 post2 in
1028- let b = b && Mp. equal f_equal eposts1 eposts2 in
1029- b &&
1030- match d1, d2 with
1031- | Some f1 , Some f2 -> f_equal f1 f2
1032- | None , None -> true
1033- | _ , _ -> false
1056+ let posts_equal (poe1 : exnpost ) (poe2 : exnpost ) =
1057+ f_equal poe1.main poe2.main
1058+ && Mp. equal f_equal (fst poe1.exnmap) (fst poe2.exnmap)
1059+ && oeq f_equal (snd poe1.exnmap) (snd poe2.exnmap)
10341060
10351061(* -------------------------------------------------------------------- *)
1036-
10371062let hf_equal hf1 hf2 =
10381063 f_equal hf1.hf_pr hf2.hf_pr
10391064 && posts_equal hf1.hf_po hf2.hf_po
@@ -1108,14 +1133,17 @@ let pr_equal pr1 pr2 =
11081133 && mem_equal pr1.pr_event.m pr2.pr_event.m
11091134
11101135(* -------------------------------------------------------------------- *)
1136+ let post_hash (p : path ) (f : form ) =
1137+ Why3.Hashcons. combine (EcPath. p_hash p) (f_hash f)
11111138
1112- let post_hash e f = Why3.Hashcons. combine (EcPath. p_hash e) (f_hash f)
1113-
1114- let posts_hash (post , posts ,d ) =
1115- let h = Why3.Hashcons. combine (f_hash post) (omap_dfl f_hash 0 d) in
1116- Mp. fold
1117- (fun e f a -> Why3.Hashcons. combine a (post_hash e f))
1118- posts h
1139+ let posts_hash (poe : exnpost ) =
1140+ let h =
1141+ Why3.Hashcons. combine
1142+ (f_hash poe.main) (omap_dfl f_hash 0 (snd poe.exnmap))
1143+ in
1144+ Mp. fold
1145+ (fun e f a -> Why3.Hashcons. combine a (post_hash e f))
1146+ (fst poe.exnmap) h
11191147
11201148(* -------------------------------------------------------------------- *)
11211149let hf_hash hf =
@@ -1476,12 +1504,12 @@ module Hsform = Why3.Hashcons.Make (struct
14761504
14771505 let fv_mlr ml mr = Sid. add ml (Sid. singleton mr)
14781506
1479- let posts_fv (post , posts , d ) =
1480- let fv = f_fv post in
1481- let fv = d |> omap f_fv |> odfl fv in
1507+ let posts_fv (poe : exnpost ) =
1508+ let fv = f_fv poe.main in
1509+ let fv = snd poe.exnmap |> omap f_fv |> odfl fv in
14821510 Mp. fold
14831511 (fun _ f acc -> fv_union (f_fv f) acc)
1484- posts fv
1512+ (fst poe.exnmap) fv
14851513
14861514 let fv_node f =
14871515 let union ex nodes =
0 commit comments