@@ -544,17 +544,37 @@ struct
544544 d
545545 end
546546
547- let invariant x =
547+ (* * Keep only box-representable constraints.
548+ Used for [diff-box] in {!invariant}. *)
549+ let boxify d =
550+ let {box1_env; interval_array}: A. box1 = A. to_box Man. mgr d in
551+ let ivs, fvs = Environment. vars box1_env in
552+ assert (Array. length fvs = 0 ); (* shouldn't ever contain floats *)
553+ A. of_box Man. mgr box1_env ivs interval_array
554+
555+ let to_lincons_set d =
556+ Lincons1Set. of_earray (A. to_lincons_array Man. mgr d)
557+
558+ let invariant d =
548559 (* Would like to minimize to get rid of multi-var constraints directly derived from one-var constraints,
549560 but not implemented in Apron at all: https://github.com/antoinemine/apron/issues/44 *)
550- (* let x = A.copy Man.mgr x in
551- A.minimize Man.mgr x; *)
552- let {lincons0_array; array_env}: Lincons1. earray = A. to_lincons_array Man. mgr x in
553- Array. to_seq lincons0_array
554- |> Seq. map (fun (lincons0 : Lincons0.t ) -> Lincons1. {lincons0; env = array_env})
555- |> Lincons1Set. of_seq
561+ (* let d = A.copy Man.mgr d in
562+ A.minimize Man.mgr d; *)
563+ let lcd = to_lincons_set d in
564+ if GobConfig. get_bool " ana.apron.invariant.diff-box" then (
565+ (* diff via lincons *)
566+ (* TODO: is there benefit to also Lincons1Set.simplify before diff? might make a difference if y=0 is represented as y>=0 && y<=0 or not *)
567+ let b = boxify d in (* convert back to same Apron domain (instead of box) to make lincons use the same format (e.g. oct doesn't return equalities, but box does) *)
568+ let lcb = to_lincons_set b in
569+ Lincons1Set. diff lcd lcb
570+ )
571+ else
572+ lcd
573+
574+ let invariant d =
575+ invariant d
556576 |> (if Oct. manager_is_oct Man. mgr then Lincons1Set. simplify else Fun. id)
557- |> Lincons1Set. elements
577+ |> Lincons1Set. elements (* TODO: remove list conversion? *)
558578end
559579
560580(* * With heterogeneous environments. *)
@@ -836,111 +856,3 @@ struct
836856
837857 let unmarshal (m : marshal ) = Oct.Abstract1. of_oct @@ OctagonD. unmarshal m
838858end
839-
840- (* * Lift [D] to a non-reduced product with box.
841- Both are updated in parallel, but [D] answers to queries.
842- Box domain is used to filter out non-relational invariants for output. *)
843- module BoxProd0 (D : S3 ) =
844- struct
845- module BoxD = D2 (IntervalManager )
846-
847- include Printable. Prod (BoxD ) (D )
848-
849- let equal (_ , d1 ) (_ , d2 ) = D. equal d1 d2
850- let hash (_ , d ) = D. hash d
851- let compare (_ , d1 ) (_ , d2 ) = D. compare d1 d2
852-
853- let leq (_ , d1 ) (_ , d2 ) = D. leq d1 d2
854- let join (b1 , d1 ) (b2 , d2 ) = (BoxD. join b1 b2, D. join d1 d2)
855- let meet (b1 , d1 ) (b2 , d2 ) = (BoxD. meet b1 b2, D. meet d1 d2)
856- let widen (b1 , d1 ) (b2 , d2 ) = (BoxD. widen b1 b2, D. widen d1 d2)
857- let narrow (b1 , d1 ) (b2 , d2 ) = (BoxD. narrow b1 b2, D. narrow d1 d2)
858-
859- let top () = (BoxD. top () , D. top () )
860- let bot () = (BoxD. bot () , D. bot () )
861- let is_top (_ , d ) = D. is_top d
862- let is_bot (_ , d ) = D. is_bot d
863- let top_env env = (BoxD. top_env env, D. top_env env)
864- let bot_env env = (BoxD. bot_env env, D. bot_env env)
865- let is_top_env (_ , d ) = D. is_top_env d
866- let is_bot_env (_ , d ) = D. is_bot_env d
867- let unify (b1 , d1 ) (b2 , d2 ) = (BoxD. unify b1 b2, D. unify d1 d2)
868- let copy (b , d ) = (BoxD. copy b, D. copy d)
869-
870- type marshal = BoxD .marshal * D .marshal
871-
872- let marshal (b , d ) = (BoxD. marshal b, D. marshal d)
873- let unmarshal (b , d ) = (BoxD. unmarshal b, D. unmarshal d)
874-
875- let mem_var (_ , d ) v = D. mem_var d v
876- let vars (_ , d ) = D. vars d
877-
878- let pretty_diff () ((_ , d1 ), (_ , d2 )) = D. pretty_diff () (d1, d2)
879-
880- let add_vars_with (b , d ) vs =
881- BoxD. add_vars_with b vs;
882- D. add_vars_with d vs
883- let remove_vars_with (b , d ) vs =
884- BoxD. remove_vars_with b vs;
885- D. remove_vars_with d vs
886- let remove_filter_with (b , d ) f =
887- BoxD. remove_filter_with b f;
888- D. remove_filter_with d f
889- let keep_filter_with (b , d ) f =
890- BoxD. keep_filter_with b f;
891- D. keep_filter_with d f
892- let keep_vars_with (b , d ) vs =
893- BoxD. keep_vars_with b vs;
894- D. keep_vars_with d vs
895- let forget_vars_with (b , d ) vs =
896- BoxD. forget_vars_with b vs;
897- D. forget_vars_with d vs
898- let assign_exp_with ask (b , d ) v e no_ov =
899- BoxD. assign_exp_with ask b v e no_ov;
900- D. assign_exp_with ask d v e no_ov
901- let assign_exp_parallel_with ask (b , d ) ves no_ov =
902- BoxD. assign_exp_parallel_with ask b ves no_ov;
903- D. assign_exp_parallel_with ask d ves no_ov
904- let assign_var_with (b , d ) v e =
905- BoxD. assign_var_with b v e;
906- D. assign_var_with d v e
907- let assign_var_parallel_with (b , d ) vvs =
908- BoxD. assign_var_parallel_with b vvs;
909- D. assign_var_parallel_with d vvs
910- let assign_var_parallel' (b , d ) vs v's =
911- (BoxD. assign_var_parallel' b vs v's, D. assign_var_parallel' d vs v's)
912- let substitute_exp_with ask (b , d ) v e no_ov =
913- BoxD. substitute_exp_with ask b v e no_ov;
914- D. substitute_exp_with ask d v e no_ov
915- let substitute_exp_parallel_with ask (b , d ) ves no_ov =
916- BoxD. substitute_exp_parallel_with ask b ves no_ov;
917- D. substitute_exp_parallel_with ask d ves no_ov
918- let substitute_var_with (b , d ) v1 v2 =
919- BoxD. substitute_var_with b v1 v2;
920- D. substitute_var_with d v1 v2
921- let meet_tcons ask (b , d ) c e = (BoxD. meet_tcons ask b c e, D. meet_tcons ask d c e)
922- let to_lincons_array (_ , d ) = D. to_lincons_array d
923- let of_lincons_array a = (BoxD. of_lincons_array a, D. of_lincons_array a)
924-
925- let cil_exp_of_lincons1 = D. cil_exp_of_lincons1
926- let assert_inv ask (b , d ) e n no_ov = (BoxD. assert_inv ask b e n no_ov, D. assert_inv ask d e n no_ov)
927- let eval_int ask (_ , d ) = D. eval_int ask d
928-
929- let invariant (b , d ) =
930- (* diff via lincons *)
931- let lcb = D. to_lincons_array (D. of_lincons_array (BoxD. to_lincons_array b)) in (* convert through D to make lincons use the same format *)
932- let lcd = D. to_lincons_array d in
933- Lincons1Set. (diff (of_earray lcd) (of_earray lcb))
934- |> (if Oct. manager_is_oct D.Man. mgr then Lincons1Set. simplify else Fun. id)
935- |> Lincons1Set. elements
936- end
937-
938- module BoxProd (D : S3 ): RD =
939- struct
940- module V = D. V
941- type var = V .t
942- module BP0 = BoxProd0 (D )
943- module Tracked = SharedFunctions .Tracked
944- include BP0
945- include AOpsPureOfImperative (BP0 )
946- end
0 commit comments