@@ -396,6 +396,10 @@ struct
396396 (* * is_top returns true for top_of array and empty array; precondition: t.env and t.d are of same size *)
397397 let is_top t = GobOption. exists EConj. is_top_con t.d
398398
399+ let is_top_env t = (not @@ Environment. equal empty_env t.env) && GobOption. exists EConj. is_top_con t.d
400+
401+ (* * is_bot_env returns true for empty env and empty d *)
402+
399403 let to_subscript i =
400404 let transl = [|" ₀" ;" ₁" ;" ₂" ;" ₃" ;" ₄" ;" ₅" ;" ₆" ;" ₇" ;" ₈" ;" ₉" |] in
401405 let rec subscr i =
@@ -466,8 +470,8 @@ struct
466470 | Some (coeffj ,j ) -> tuple_cmp (EConj. get_rhs ts i) @@ Rhs. subst (EConj. get_rhs ts j) j (var, offs, divi)
467471 in
468472 if env_comp = - 2 || env_comp > 0 then false else
469- if is_bot_env t1 || is_top t2 then true
470- else if is_bot_env t2 || is_top t1 then false else
473+ if is_bot_env t1 || is_top_env t2 then true
474+ else if is_bot_env t2 || is_top_env t1 then false else
471475 let m1, m2 = Option. get t1.d, Option. get t2.d in
472476 let m1' = if env_comp = 0 then m1 else VarManagement. dim_add (Environment. dimchange t1.env t2.env) m1 in
473477 EConj.IntMap. for_all (implies m1') (snd m2) (* even on sparse m2, it suffices to check the non-trivial equalities, still present in sparse m2 *)
@@ -534,19 +538,24 @@ struct
534538
535539 in
536540 (* Normalize the two domains a and b such that both talk about the same variables*)
537- match a .d , b .d with
538- | None, _ -> b
539- | _ , None -> a
540- | Some x , Some y when is_top a || is_top b ->
541- let new_env = Environment. lce a.env b.env in
542- top_of new_env
543- | Some x , Some y when (Environment. cmp a.env b.env <> 0 ) ->
544- let sup_env = Environment. lce a.env b.env in
545- let mod_x = dim_add (Environment. dimchange a.env sup_env) x in
546- let mod_y = dim_add (Environment. dimchange b.env sup_env) y in
547- {d = join_d mod_x mod_y; env = sup_env}
548- | Some x , Some y when EConj. equal x y -> {d = Some x; env = a.env}
549- | Some x , Some y -> {d = join_d x y; env = a.env}
541+ if is_bot a then
542+ b
543+ else if is_bot b then
544+ a
545+ else
546+ match a .d , b .d with
547+ | None, _ -> b
548+ | _ , None -> a
549+ | Some x , Some y when is_top_env a || is_top_env b ->
550+ let new_env = Environment. lce a.env b.env in
551+ top_of new_env
552+ | Some x , Some y when (Environment. cmp a.env b.env <> 0 ) ->
553+ let sup_env = Environment. lce a.env b.env in
554+ let mod_x = dim_add (Environment. dimchange a.env sup_env) x in
555+ let mod_y = dim_add (Environment. dimchange b.env sup_env) y in
556+ {d = join_d mod_x mod_y; env = sup_env}
557+ | Some x , Some y when EConj. equal x y -> {d = Some x; env = a.env}
558+ | Some x , Some y -> {d = join_d x y; env = a.env}
550559
551560 let join a b = Timing. wrap " join" (join a) b
552561
@@ -574,12 +583,12 @@ struct
574583 dprintf " %s: %a not leq %a" (name () ) pretty x pretty y
575584
576585 let forget_var t var =
577- if is_bot_env t || is_top t then t
586+ if is_bot_env t || is_top_env t then t
578587 else
579588 {d = Some (EConj. forget_variable (Option. get t.d) (Environment. dim_of_var t.env var)); env = t.env}
580589
581590 let forget_vars t vars =
582- if is_bot_env t || is_top t || List. is_empty vars then
591+ if is_bot_env t || is_top_env t || List. is_empty vars then
583592 t
584593 else
585594 let newm = List. fold (fun map i -> EConj. forget_variable map (Environment. dim_of_var t.env i)) (Option. get t.d) vars in
@@ -651,7 +660,7 @@ struct
651660 let t_primed = add_vars t primed_vars in
652661 let multi_t = List. fold_left2 (fun t' v_prime (_ ,v' ) -> assign_var t' v_prime v') t_primed primed_vars vv's in
653662 match multi_t.d with
654- | Some arr when not @@ is_top multi_t ->
663+ | Some arr when not @@ is_top_env multi_t ->
655664 let switched_arr = List. fold_left2 (fun multi_t assigned_var primed_var -> assign_var multi_t assigned_var primed_var) multi_t assigned_vars primed_vars in
656665 remove_vars switched_arr primed_vars
657666 | _ -> t
0 commit comments