@@ -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,123 @@ 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+ module POE = struct
573+ let mk (main : form ) (exnmap : form Mp.t * form option ) =
574+ { main; exnmap; }
572575
573- let is_empty_poe poe =
574- match poe with
575- | (_ ,m ,None) when Mp. is_empty m-> true
576- | _ -> false
576+ let destruct (poe : exnpost ) =
577+ (poe.main, poe.exnmap)
577578
578- let lift_f f = {hsi_m= f.m;hsi_inv= empty_poe f.inv}
579+ let empty (f : form ) : exnpost =
580+ { main = f; exnmap = (Mp. empty, None ); }
579581
580- let lower_f f =
581- let (post, _,_) = f.hsi_inv in
582- {m= f.hsi_m;inv= post}
582+ let is_empty ({ exnmap = (m , dfl ) } : exnpost ) =
583+ Option. is_none dfl && Mp. is_empty m
583584
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)}
585+ let lift (f : ss_inv ) =
586+ { hsi_m = f.m; hsi_inv = empty f.inv; }
588587
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)
588+ let lower (f : hs_inv ) =
589+ { m = f.hsi_m; inv = f.hsi_inv.main; }
594590
595- let map_hs_inv1 f inv1 = {inv1 with hsi_inv = map_poe f inv1.hsi_inv}
591+ let map (f : form -> form ) ({ main; exnmap = (m , d ) } : exnpost ) : exnpost =
592+ { main = f main; exnmap = (Mp. map f m, omap f d)}
596593
597- let map2_poe f (p1 ,m1 ,d1 ) (p2 ,m2 ,d2 ) =
598- let p = f p1 p2 in
599- let aux _ a b =
600- match a, b with
601- | Some a , Some b -> Some (f a b)
602- | _ , _ -> failwith " missing entry in exception map"
603- 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"
594+ let map2_pre (f : 'a -> 'b -> 'c ) (poe1 : 'a prepoe ) (poe2 : 'b prepoe ) : 'c prepoe =
595+ let (main1, (map1, d1)) = poe1 in
596+ let (main2, (map2, d2)) = poe2 in
609597
610- let map_hs_inv2
611- (fn : form -> form -> form ) (inv1 : hs_inv ) (inv2 : hs_inv ): hs_inv =
612- 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' }
598+ let merge (a : 'a option ) (b : 'b option ) =
599+ match a, b with
600+ | None , None -> None
601+ | Some a , Some b -> Some (f a b)
602+ | _ -> assert false
603+ in
615604
616- let exists_poe f (p ,m ,d ) =
617- f p || Mp. exists (fun _ -> f) m || omap_dfl f false d
605+ let main = f main1 main2 in
606+ let map = Mp. merge (fun _ -> merge) map1 map2 in
607+ let dfl = merge d1 d2 in
608+
609+ (main, (map, dfl))
610+
611+ let map2 (f : form -> form -> form ) (poe1 : exnpost ) (poe2 : exnpost ) =
612+ let main, exnmap =
613+ map2_pre f (destruct poe1) (destruct poe2) in
614+
615+ mk main exnmap
616+
617+ let exists (f : form -> bool ) (poe : exnpost ) =
618+ f poe.main
619+ || Mp. exists (fun _ -> f) (fst poe.exnmap)
620+ || omap_dfl f false (snd poe.exnmap)
621+
622+ let forall (f : form -> bool ) (poe : exnpost ) =
623+ f poe.main
624+ && Mp. for_all (fun _ -> f) (fst poe.exnmap)
625+ && omap_dfl f true (snd poe.exnmap)
626+
627+ let forall2 (f : form -> form -> bool ) (poe1 : exnpost ) (poe2 : exnpost ) =
628+ f poe1.main poe2.main
629+ && Mp. equal f (fst poe1.exnmap) (fst poe2.exnmap)
630+ && oeq f (snd poe1.exnmap) (snd poe2.exnmap)
631+
632+ let to_list_pre ((main , (map , d )) : 'a prepoe ) =
633+ let l =
634+ Mp. fold
635+ (fun _ p1 a -> p1 :: a)
636+ map
637+ [main]
638+ in otolist d @ l
639+
640+ let to_list (poe : exnpost ) =
641+ to_list_pre (destruct poe)
642+
643+ let iter (f : form -> unit ) (poe : exnpost ) =
644+ f poe.main;
645+ Mp. iter (fun _ -> f) (fst poe.exnmap);
646+ oiter f (snd poe.exnmap)
647+
648+ let iter2 (f : form -> form -> unit ) (poe1 : exnpost ) (poe2 : exnpost ) =
649+ let merge (a : form option ) (b : form option ) =
650+ match a, b with
651+ | None , None -> None
652+ | Some a , Some b -> Some (a, b)
653+ | _ , _ -> assert false in
654+
655+ f poe1.main poe2.main;
656+ Mp. iter
657+ (fun _ (a , b ) -> f a b)
658+ (Mp. merge (fun _ -> merge) (fst poe1.exnmap) (fst poe2.exnmap));
659+ begin
660+ match snd poe1.exnmap, snd poe2.exnmap with
661+ | None , None -> ()
662+ | Some a , Some b -> f a b
663+ | _ , _ -> assert false
664+ end
665+ end
618666
619- let forall_poe f (p ,m ,d ) =
620- f p && Mp. for_all (fun _ -> f) m && omap_dfl f true d
667+ (* ----------------------------------------------------------------- *)
668+ let empty_hs (f : ss_inv ) =
669+ { hsi_m = f.m; hsi_inv = POE. empty f.inv; }
621670
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
671+ let update_hs_ss (f : ss_inv ) (p : hs_inv ) : hs_inv =
672+ assert (f.m == (* phy*) p.hsi_m);
673+ { p with hsi_inv = { main = f.inv; exnmap = p.hsi_inv.exnmap; } }
626674
627- let poe_to_list (post ,poe ,d ) =
628- let l =
629- Mp. fold
630- (fun _ p1 a -> p1 :: a)
631- poe
632- [post]
633- in
634- otolist d @ l
635-
636- let iter_poe f (p , m ,d ) =
637- f p;
638- Mp. iter (fun _ -> f) m;
639- oiter f d
640-
641- let iter2_poe f (p1 ,m1 ,d1 ) (p2 ,m2 ,d2 ) =
642- f p1 p2;
643- let aux _ a b =
644- 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"
675+ let map_hs_inv1 (f : form ->form ) (inv1 : hs_inv ) =
676+ { inv1 with hsi_inv = POE. map f inv1.hsi_inv; }
677+
678+ let map_hs_inv2
679+ (fn : form -> form -> form )
680+ (inv1 : hs_inv )
681+ (inv2 : hs_inv )
682+ : hs_inv
683+ =
684+ assert (inv1.hsi_m = inv2.hsi_m);
685+ let inv = POE. map2 fn inv1.hsi_inv inv2.hsi_inv in
686+ { hsi_m = inv1.hsi_m; hsi_inv = inv }
654687
655688(* ----------------------------------------------------------------- *)
656689(* Accessors for program logic *)
@@ -665,8 +698,8 @@ let ef_po ef = {ml=ef.ef_ml; mr=ef.ef_mr; inv=ef.ef_po}
665698let es_pr es = {ml= fst es.es_ml; mr= fst es.es_mr; inv= es.es_pr}
666699let es_po es = {ml= fst es.es_ml; mr= fst es.es_mr; inv= es.es_po}
667700
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}
701+ let hf_pr hf = {m= hf.hf_m; inv= hf.hf_pr}
702+ let hf_po hf = {hsi_m= hf.hf_m; hsi_inv= hf.hf_po}
670703
671704let hs_pr hs = {m= fst hs.hs_m; inv= hs.hs_pr}
672705let hs_po hs = {hsi_m= fst hs.hs_m; hsi_inv= hs.hs_po}
@@ -1022,18 +1055,12 @@ let b_hash (bs : bindings) =
10221055 Why3.Hashcons. combine_list b1_hash 0 bs
10231056
10241057(* -------------------------------------------------------------------- *)
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
1058+ let posts_equal (poe1 : exnpost ) (poe2 : exnpost ) =
1059+ f_equal poe1.main poe2.main
1060+ && Mp. equal f_equal (fst poe1.exnmap) (fst poe2.exnmap)
1061+ && oeq f_equal (snd poe1.exnmap) (snd poe2.exnmap)
10341062
10351063(* -------------------------------------------------------------------- *)
1036-
10371064let hf_equal hf1 hf2 =
10381065 f_equal hf1.hf_pr hf2.hf_pr
10391066 && posts_equal hf1.hf_po hf2.hf_po
@@ -1108,14 +1135,17 @@ let pr_equal pr1 pr2 =
11081135 && mem_equal pr1.pr_event.m pr2.pr_event.m
11091136
11101137(* -------------------------------------------------------------------- *)
1138+ let post_hash (p : path ) (f : form ) =
1139+ Why3.Hashcons. combine (EcPath. p_hash p) (f_hash f)
11111140
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
1141+ let posts_hash (poe : exnpost ) =
1142+ let h =
1143+ Why3.Hashcons. combine
1144+ (f_hash poe.main) (omap_dfl f_hash 0 (snd poe.exnmap))
1145+ in
1146+ Mp. fold
1147+ (fun e f a -> Why3.Hashcons. combine a (post_hash e f))
1148+ (fst poe.exnmap) h
11191149
11201150(* -------------------------------------------------------------------- *)
11211151let hf_hash hf =
@@ -1476,12 +1506,12 @@ module Hsform = Why3.Hashcons.Make (struct
14761506
14771507 let fv_mlr ml mr = Sid. add ml (Sid. singleton mr)
14781508
1479- let posts_fv (post , posts , d ) =
1480- let fv = f_fv post in
1481- let fv = d |> omap f_fv |> odfl fv in
1509+ let posts_fv (poe : exnpost ) =
1510+ let fv = f_fv poe.main in
1511+ let fv = snd poe.exnmap |> omap f_fv |> odfl fv in
14821512 Mp. fold
14831513 (fun _ f acc -> fv_union (f_fv f) acc)
1484- posts fv
1514+ (fst poe.exnmap) fv
14851515
14861516 let fv_node f =
14871517 let union ex nodes =
0 commit comments