[sledge] Detect unsat symbolic heaps earlier during simplification

Summary:
Simplifying a symbolic heap can reveal inconsistencies, either of
individual disjuncts or (therefore) of toplevel formulas. This is due
to the first-order contexts being propagated from a formula to its
descendents, and for the intersection of the contexts of disjunctions
being propagated to their parent. The later stages of eliminating
redundant quantifiers, etc. do not reveal further
inconsistencies. Therefore this diff moves the inconsistency detection
earlier, to just after the contexts are strengthened. This is clearer,
and also a minor optimization.

Reviewed By: jvillard

Differential Revision: D25756564

fbshipit-source-id: d3acf875b
master
Josh Berdine 4 years ago committed by Facebook GitHub Bot
parent 69a979612b
commit df37767a93

@ -703,8 +703,8 @@ let rec propagate_context_ ancestor_vs ancestor_ctx q =
(* strengthen context with that from above *) (* strengthen context with that from above *)
let ancestor_stem = and_ctx_ ancestor_ctx stem in let ancestor_stem = and_ctx_ ancestor_ctx stem in
let ancestor_ctx = ancestor_stem.ctx in let ancestor_ctx = ancestor_stem.ctx in
exists xs let q' =
(List.fold djns ancestor_stem ~f:(fun djn q' -> List.fold djns ancestor_stem ~f:(fun djn q' ->
let dj_ctxs, djn = let dj_ctxs, djn =
List.rev_map_split djn ~f:(fun dj -> List.rev_map_split djn ~f:(fun dj ->
let dj = propagate_context_ ancestor_vs ancestor_ctx dj in let dj = propagate_context_ ancestor_vs ancestor_ctx dj in
@ -715,8 +715,13 @@ let rec propagate_context_ ancestor_vs ancestor_ctx q =
let djn_xs = Var.Set.diff (Context.fv djn_ctx) q'.us in let djn_xs = Var.Set.diff (Context.fv djn_ctx) q'.us in
let djn = List.map ~f:(elim_exists djn_xs) djn in let djn = List.map ~f:(elim_exists djn_xs) djn in
let ctx_djn = and_ctx_ djn_ctx (orN djn) in let ctx_djn = and_ctx_ djn_ctx (orN djn) in
assert (is_unsat ctx_djn || Var.Set.subset new_xs ~of_:djn_xs) ; assert (is_false ctx_djn || Var.Set.subset new_xs ~of_:djn_xs) ;
star (exists djn_xs ctx_djn) q' )) star (exists djn_xs ctx_djn) q' )
in
(* requantify existentials *)
let q' = exists xs q' in
(* strengthening contexts can reveal inconsistency *)
(if is_false q' then false_ q'.us else q')
|> |>
[%Trace.retn fun {pf} q' -> [%Trace.retn fun {pf} q' ->
pf "%a" pp q' ; pf "%a" pp q' ;
@ -776,9 +781,7 @@ let rec simplify_ us rev_xss q =
(* try to solve equations in ctx for variables in xss *) (* try to solve equations in ctx for variables in xss *)
let subst = Context.solve_for_vars (us :: List.rev rev_xss) q.ctx in let subst = Context.solve_for_vars (us :: List.rev rev_xss) q.ctx in
let removed, q = let removed, q =
(* simplification can reveal inconsistency *) if Context.Subst.is_empty subst then (Var.Set.empty, q)
if is_unsat q then (Var.Set.empty, false_ q.us)
else if Context.Subst.is_empty subst then (Var.Set.empty, q)
else else
(* normalize wrt solutions *) (* normalize wrt solutions *)
let q = norm subst q in let q = norm subst q in

Loading…
Cancel
Save