[sledge] Strengthen Equality.close to handle rep being sparse on constants

Reviewed By: jvillard

Differential Revision: D20831350

fbshipit-source-id: 3ba2d14d0
master
Josh Berdine 5 years ago committed by Facebook GitHub Bot
parent 2f4f9801ed
commit ee595f2ebf

@ -407,11 +407,12 @@ let pp_diff_clss =
(** test membership in carrier *) (** test membership in carrier *)
let in_car r e = Subst.mem r.rep e let in_car r e = Subst.mem r.rep e
(** congruent specialized to assume subterms of [a'] are [Subst.norm]alized
wrt [r] (or canonized) *)
let semi_congruent r a' b = Term.equal a' (Term.map ~f:(Subst.norm r.rep) b)
(** terms are congruent if equal after normalizing subterms *) (** terms are congruent if equal after normalizing subterms *)
let congruent r a b = let congruent r a b = semi_congruent r (Term.map ~f:(Subst.norm r.rep) a) b
Term.equal
(Term.map ~f:(Subst.norm r.rep) a)
(Term.map ~f:(Subst.norm r.rep) b)
(** Invariant *) (** Invariant *)
@ -454,12 +455,8 @@ let lookup r a =
; ;
( with_return ( with_return
@@ fun {return} -> @@ fun {return} ->
(* congruent specialized to assume [a] canonized and [b] non-interpreted *) Subst.iteri r.rep ~f:(fun ~key:b ~data:b' ->
let semi_congruent r a b = if semi_congruent r a b then return b' ) ;
Term.equal a (Term.map ~f:(Subst.norm r.rep) b)
in
Subst.iteri r.rep ~f:(fun ~key ~data ->
if semi_congruent r a key then return data ) ;
a ) a )
|> |>
[%Trace.retn fun {pf} -> pf "%a" Term.pp] [%Trace.retn fun {pf} -> pf "%a" Term.pp]
@ -482,10 +479,16 @@ let rec canon r a =
[%Trace.retn fun {pf} -> pf "%a" Term.pp] [%Trace.retn fun {pf} -> pf "%a" Term.pp]
let rec extend_ a r = let rec extend_ a r =
(* omit identity mappings for constants *)
if Term.is_constant a then r
else
match classify a with match classify a with
(* omit interpreted terms, but consider their subterms *)
| Interpreted | Simplified -> Term.fold ~f:extend_ a ~init:r | Interpreted | Simplified -> Term.fold ~f:extend_ a ~init:r
(* add uninterpreted terms *)
| Uninterpreted -> ( | Uninterpreted -> (
match Subst.extend a r with match Subst.extend a r with
(* and their subterms if newly added *)
| Some r -> Term.fold ~f:extend_ a ~init:r | Some r -> Term.fold ~f:extend_ a ~init:r
| None -> r ) | None -> r )
| Atomic -> r | Atomic -> r
@ -512,12 +515,27 @@ let find_missing r =
with_return with_return
@@ fun {return} -> @@ fun {return} ->
Subst.iteri r.rep ~f:(fun ~key:a ~data:a' -> Subst.iteri r.rep ~f:(fun ~key:a ~data:a' ->
let a_subnorm = Term.map ~f:(Subst.norm r.rep) a in
(* rep omits identity mappings for constants, so check for them *)
if
(* a normalizes to a constant *)
Term.is_constant a_subnorm
(* distinct from its representative *)
&& not (Term.equal a' a_subnorm)
then
(* need to equate current representative and constant *)
return (Some (a', a_subnorm))
else
Subst.iteri r.rep ~f:(fun ~key:b ~data:b' -> Subst.iteri r.rep ~f:(fun ~key:b ~data:b' ->
if if
(* optimize: do not consider both a = b and b = a *)
Term.compare a b < 0 Term.compare a b < 0
(* a and b are not already equal *)
&& (not (Term.equal a' b')) && (not (Term.equal a' b'))
&& congruent r a b (* a and b are congruent *)
then return (Some (a', b')) ) ) ; && semi_congruent r a_subnorm b
then (* need to equate a' and b' *)
return (Some (a', b')) ) ) ;
None None
let rec close us r = let rec close us r =

Loading…
Cancel
Save