[sledge] Refactor: Rename Fol.Equality to Fol.Context

Reviewed By: ngorogiannis

Differential Revision: D22170521

fbshipit-source-id: e791739b7
master
Josh Berdine 4 years ago committed by Facebook GitHub Bot
parent dd2e7b4782
commit a629486c9f

@ -86,12 +86,12 @@ let exec_intrinsic ~skip_throw q r i es =
let term_eq_class_has_only_vars_in fvs cong term =
[%Trace.call fun {pf} ->
pf "@[<v> fvs: @[%a@] @,cong: @[%a@] @,term: @[%a@]@]" Var.Set.pp fvs
Equality.pp cong Term.pp term]
Context.pp cong Term.pp term]
;
let term_has_only_vars_in fvs term =
Var.Set.is_subset (Term.fv term) ~of_:fvs
in
let term_eq_class = Equality.class_of cong term in
let term_eq_class = Context.class_of cong term in
List.exists ~f:(term_has_only_vars_in fvs) term_eq_class
|>
[%Trace.retn fun {pf} -> pf "%b"]
@ -107,7 +107,7 @@ let garbage_collect (q : t) ~wrt =
let new_set =
List.fold ~init:current q.heap ~f:(fun current seg ->
if term_eq_class_has_only_vars_in current q.cong seg.loc then
List.fold (Equality.class_of q.cong seg.seq) ~init:current
List.fold (Context.class_of q.cong seg.seq) ~init:current
~f:(fun c e -> Var.Set.union c (Term.fv e))
else current )
in

@ -7,4 +7,4 @@
module Var = Ses.Var
module Term = Ses.Term
module Equality = Ses.Equality
module Context = Ses.Equality

@ -7,4 +7,4 @@
module Var = Ses.Var
module Term = Ses.Term
module Equality = Ses.Equality
module Context = Ses.Equality

@ -17,7 +17,7 @@ type seg = {loc: Term.t; bas: Term.t; len: Term.t; siz: Term.t; seq: Term.t}
type starjunction =
{ us: Var.Set.t
; xs: Var.Set.t
; cong: Equality.t
; cong: Context.t
; pure: Term.t
; heap: seg list
; djns: disjunction list }
@ -32,7 +32,7 @@ type t = starjunction [@@deriving compare, equal, sexp]
let emp =
{ us= Var.Set.empty
; xs= Var.Set.empty
; cong= Equality.true_
; cong= Context.true_
; pure= Term.true_
; heap= []
; djns= [] }
@ -82,7 +82,7 @@ let fold_vars_stem ?ignore_cong {us= _; xs= _; cong; pure; heap; djns= _}
|> fun init ->
if Option.is_some ignore_cong then init
else
Equality.fold_terms ~init cong ~f:(fun init -> Term.fold_vars ~f ~init)
Context.fold_terms ~init cong ~f:(fun init -> Term.fold_vars ~f ~init)
let fold_vars ?ignore_cong fold_vars q ~init ~f =
fold_vars_stem ?ignore_cong ~init ~f q
@ -137,7 +137,7 @@ let pp_seg x fs {loc; bas; len; siz; seq} =
let pp_seg_norm cong fs seg =
let x _ = None in
pp_seg x fs (map_seg seg ~f:(Equality.normalize cong))
pp_seg x fs (map_seg seg ~f:(Context.normalize cong))
let pp_block x fs segs =
let is_full_alloc segs =
@ -179,17 +179,17 @@ let pp_heap x ?pre cong fs heap =
in
let compare s1 s2 =
[%compare: Term.t * (Term.t * Q.t)]
( Equality.normalize cong s1.bas
, bas_off (Equality.normalize cong s1.loc) )
( Equality.normalize cong s2.bas
, bas_off (Equality.normalize cong s2.loc) )
( Context.normalize cong s1.bas
, bas_off (Context.normalize cong s1.loc) )
( Context.normalize cong s2.bas
, bas_off (Context.normalize cong s2.loc) )
in
let break s1 s2 =
(not (Term.equal s1.bas s2.bas))
|| (not (Term.equal s1.len s2.len))
|| not (Equality.entails_eq cong (Term.add s1.loc s1.siz) s2.loc)
|| not (Context.entails_eq cong (Term.add s1.loc s1.siz) s2.loc)
in
let heap = List.map heap ~f:(map_seg ~f:(Equality.normalize cong)) in
let heap = List.map heap ~f:(map_seg ~f:(Context.normalize cong)) in
let blocks = List.group ~break (List.sort ~compare heap) in
List.pp ?pre "@ * " (pp_block x) fs blocks
@ -218,14 +218,14 @@ let rec pp_ ?var_strength vs parent_xs parent_cong fs
if not (Var.Set.is_empty xs_d_vs) then Format.fprintf fs "@ " ) ;
if not (Var.Set.is_empty xs_d_vs) then
Format.fprintf fs "@<2>∃ @[%a@] .@ " (Var.Set.ppx x) xs_d_vs ;
let clss = Equality.diff_classes cong parent_cong in
let clss = Context.diff_classes cong parent_cong in
let first = Term.Map.is_empty clss in
if not first then Format.fprintf fs " " ;
Equality.ppx_classes x fs clss ;
Context.ppx_classes x fs clss ;
let pure =
if Option.is_none var_strength then [pure]
else
let pure' = Equality.normalize cong pure in
let pure' = Context.normalize cong pure in
if Term.is_true pure' then [] else [pure']
in
List.pp
@ -265,9 +265,9 @@ and pp_djn ?var_strength vs xs cong fs = function
let pp_diff_eq ?(us = Var.Set.empty) ?(xs = Var.Set.empty) cong fs q =
pp_ ~var_strength:(var_strength ~xs q) us xs cong fs q
let pp fs q = pp_diff_eq Equality.true_ fs q
let pp_djn fs d = pp_djn Var.Set.empty Var.Set.empty Equality.true_ fs d
let pp_raw fs q = pp_ Var.Set.empty Var.Set.empty Equality.true_ fs q
let pp fs q = pp_diff_eq Context.true_ fs q
let pp_djn fs d = pp_djn Var.Set.empty Var.Set.empty Context.true_ fs d
let pp_raw fs q = pp_ Var.Set.empty Var.Set.empty Context.true_ fs q
let fv_seg seg = fold_vars_seg seg ~f:Var.Set.add ~init:Var.Set.empty
let fv ?ignore_cong q =
@ -297,13 +297,13 @@ let rec invariant q =
Var.Set.is_subset (fv q) ~of_:us
|| fail "unbound but free: %a" Var.Set.pp (Var.Set.diff (fv q) us) ()
) ;
Equality.invariant cong ;
Context.invariant cong ;
( match djns with
| [[]] ->
assert (Equality.is_true cong) ;
assert (Context.is_true cong) ;
assert (Term.is_true pure) ;
assert (List.is_empty heap)
| _ -> assert (not (Equality.is_false cong)) ) ;
| _ -> assert (not (Context.is_false cong)) ) ;
invariant_pure pure ;
List.iter heap ~f:invariant_seg ;
List.iter djns ~f:(fun djn ->
@ -320,7 +320,7 @@ let rec invariant q =
invariant *)
let rec apply_subst sub q =
map q ~f_sjn:(rename sub)
~f_cong:(fun r -> Equality.rename r sub)
~f_cong:(fun r -> Context.rename r sub)
~f_trm:(Term.rename sub)
|> check (fun q' ->
assert (Var.Set.disjoint (fv q') (Var.Subst.domain sub)) )
@ -437,17 +437,17 @@ let elim_exists xs q =
(** conjoin an equality relation assuming vocabulary is compatible *)
let and_cong_ cong q =
assert (Var.Set.is_subset (Equality.fv cong) ~of_:q.us) ;
let xs, cong = Equality.and_ (Var.Set.union q.us q.xs) q.cong cong in
if Equality.is_false cong then false_ q.us
assert (Var.Set.is_subset (Context.fv cong) ~of_:q.us) ;
let xs, cong = Context.and_ (Var.Set.union q.us q.xs) q.cong cong in
if Context.is_false cong then false_ q.us
else exists_fresh xs {q with cong}
let and_cong cong q =
[%Trace.call fun {pf} -> pf "%a@ %a" Equality.pp cong pp q]
[%Trace.call fun {pf} -> pf "%a@ %a" Context.pp cong pp q]
;
( match q.djns with
| [[]] -> q
| _ -> and_cong_ cong (extend_us (Equality.fv cong) q) )
| _ -> and_cong_ cong (extend_us (Context.fv cong) q) )
|>
[%Trace.retn fun {pf} q ->
pf "%a" pp q ;
@ -460,11 +460,11 @@ let star q1 q2 =
| {djns= [[]]; _}, _ | _, {djns= [[]]; _} ->
false_ (Var.Set.union q1.us q2.us)
| {us= _; xs= _; cong; pure; heap= []; djns= []}, _
when Equality.is_true cong && Term.is_true pure ->
when Context.is_true cong && Term.is_true pure ->
let us = Var.Set.union q1.us q2.us in
if us == q2.us then q2 else {q2 with us}
| _, {us= _; xs= _; cong; pure; heap= []; djns= []}
when Equality.is_true cong && Term.is_true pure ->
when Context.is_true cong && Term.is_true pure ->
let us = Var.Set.union q1.us q2.us in
if us == q1.us then q1 else {q1 with us}
| _ ->
@ -475,9 +475,9 @@ let star q1 q2 =
let {us= us2; xs= xs2; cong= c2; pure= p2; heap= h2; djns= d2} = q2 in
assert (Var.Set.equal us (Var.Set.union us1 us2)) ;
let xs, cong =
Equality.and_ (Var.Set.union us (Var.Set.union xs1 xs2)) c1 c2
Context.and_ (Var.Set.union us (Var.Set.union xs1 xs2)) c1 c2
in
if Equality.is_false cong then false_ us
if Context.is_false cong then false_ us
else
exists_fresh xs
{ us
@ -514,7 +514,7 @@ let or_ q1 q2 =
| _ ->
{ us= Var.Set.union q1.us q2.us
; xs= Var.Set.empty
; cong= Equality.true_
; cong= Context.true_
; pure= Term.true_
; heap= []
; djns= [[q1; q2]] } )
@ -534,8 +534,8 @@ let pure (e : Term.t) =
;
List.fold (Term.disjuncts e) ~init:(false_ Var.Set.empty) ~f:(fun q b ->
let us = Term.fv b in
let xs, cong = Equality.(and_term us b true_) in
if Equality.is_false cong then false_ us
let xs, cong = Context.(and_term us b true_) in
if Context.is_false cong then false_ us
else or_ q (exists_fresh xs {emp with us; cong; pure= b}) )
|>
[%Trace.retn fun {pf} q ->
@ -545,9 +545,9 @@ let pure (e : Term.t) =
let and_ e q = star (pure e) q
let and_subst subst q =
[%Trace.call fun {pf} -> pf "%a@ %a" Equality.Subst.pp subst pp q]
[%Trace.call fun {pf} -> pf "%a@ %a" Context.Subst.pp subst pp q]
;
Equality.Subst.fold
Context.Subst.fold
~f:(fun ~key ~data -> and_ (Term.eq key data))
subst ~init:q
|>
@ -595,9 +595,9 @@ let is_emp = function
let is_false = function
| {djns= [[]]; _} -> true
| {cong; pure; heap; _} ->
Term.is_false (Equality.normalize cong pure)
Term.is_false (Context.normalize cong pure)
|| List.exists heap ~f:(fun seg ->
Equality.entails_eq cong seg.loc Term.zero )
Context.entails_eq cong seg.loc Term.zero )
let rec pure_approx ({us; xs; cong; pure; heap= _; djns} as q) =
let heap = emp.heap in
@ -647,12 +647,12 @@ let dnf q =
(** Simplify *)
let rec norm_ s q =
[%Trace.call fun {pf} -> pf "@[%a@]@ %a" Equality.Subst.pp s pp_raw q]
[%Trace.call fun {pf} -> pf "@[%a@]@ %a" Context.Subst.pp s pp_raw q]
;
let q =
map q ~f_sjn:(norm_ s) ~f_cong:Fn.id ~f_trm:(Equality.Subst.subst s)
map q ~f_sjn:(norm_ s) ~f_cong:Fn.id ~f_trm:(Context.Subst.subst s)
in
let xs, cong = Equality.apply_subst (Var.Set.union q.us q.xs) s q.cong in
let xs, cong = Context.apply_subst (Var.Set.union q.us q.xs) s q.cong in
exists_fresh xs {q with cong}
|>
[%Trace.retn fun {pf} q' ->
@ -660,9 +660,9 @@ let rec norm_ s q =
invariant q']
let norm s q =
[%Trace.call fun {pf} -> pf "@[%a@]@ %a" Equality.Subst.pp s pp_raw q]
[%Trace.call fun {pf} -> pf "@[%a@]@ %a" Context.Subst.pp s pp_raw q]
;
(if Equality.Subst.is_empty s then q else norm_ s q)
(if Context.Subst.is_empty s then q else norm_ s q)
|>
[%Trace.retn fun {pf} q' ->
pf "%a" pp_raw q' ;
@ -695,7 +695,7 @@ let rec freshen_nested_xs q =
let rec propagate_equality_ ancestor_vs ancestor_cong q =
[%Trace.call fun {pf} ->
pf "(%a)@ %a" Equality.pp_classes ancestor_cong pp q]
pf "(%a)@ %a" Context.pp_classes ancestor_cong pp q]
;
(* extend vocabulary with variables in scope above *)
let ancestor_vs = Var.Set.union ancestor_vs (Var.Set.union q.us q.xs) in
@ -713,9 +713,9 @@ let rec propagate_equality_ ancestor_vs ancestor_cong q =
let dj = propagate_equality_ ancestor_vs ancestor_cong dj in
(dj.cong, dj) )
in
let new_xs, djn_cong = Equality.orN ancestor_vs dj_congs in
let new_xs, djn_cong = Context.orN ancestor_vs dj_congs in
(* hoist xs appearing in disjunction's equality relation *)
let djn_xs = Var.Set.diff (Equality.fv djn_cong) q'.us in
let djn_xs = Var.Set.diff (Context.fv djn_cong) q'.us in
let djn = List.map ~f:(elim_exists djn_xs) djn in
let cong_djn = and_cong_ djn_cong (orN djn) in
assert (is_false cong_djn || Var.Set.is_subset new_xs ~of_:djn_xs) ;
@ -727,7 +727,7 @@ let rec propagate_equality_ ancestor_vs ancestor_cong q =
let propagate_equality ancestor_vs ancestor_cong q =
[%Trace.call fun {pf} ->
pf "(%a)@ %a" Equality.pp_classes ancestor_cong pp q]
pf "(%a)@ %a" Context.pp_classes ancestor_cong pp q]
;
propagate_equality_ ancestor_vs ancestor_cong q
|>
@ -745,14 +745,14 @@ let remove_absent_xs ks q =
if Var.Set.is_empty ks then q
else
let xs = Var.Set.diff q.xs ks in
let cong = Equality.elim ks q.cong in
let cong = Context.elim ks q.cong in
let djns =
let rec trim_ks ks djns =
List.map djns ~f:(fun djn ->
List.map djn ~f:(fun sjn ->
{ sjn with
us= Var.Set.diff sjn.us ks
; cong= Equality.elim ks sjn.cong
; cong= Context.elim ks sjn.cong
; djns= trim_ks ks sjn.djns } ) )
in
trim_ks ks q.djns
@ -773,10 +773,10 @@ let rec simplify_ us rev_xss q =
))
in
(* try to solve equations in cong for variables in xss *)
let subst = Equality.solve_for_vars (us :: List.rev rev_xss) q.cong in
let subst = Context.solve_for_vars (us :: List.rev rev_xss) q.cong in
(* simplification can reveal inconsistency *)
( if is_false q then false_ q.us
else if Equality.Subst.is_empty subst then q
else if Context.Subst.is_empty subst then q
else
(* normalize wrt solutions *)
let q = norm subst q in
@ -786,20 +786,20 @@ let rec simplify_ us rev_xss q =
(Var.Set.union_list rev_xss)
(fv ~ignore_cong:() (elim_exists q.xs q))
in
let keep, removed, _ = Equality.Subst.partition_valid removed subst in
let keep, removed, _ = Context.Subst.partition_valid removed subst in
let q = and_subst keep q in
(* remove the eliminated variables from xs and subformulas' us *)
remove_absent_xs removed q )
|>
[%Trace.retn fun {pf} q' ->
pf "%a@ %a" Equality.Subst.pp subst pp_raw q' ;
pf "%a@ %a" Context.Subst.pp subst pp_raw q' ;
invariant q']
let simplify q =
[%Trace.call fun {pf} -> pf "%a" pp_raw q]
;
let q = freshen_nested_xs q in
let q = propagate_equality Var.Set.empty Equality.true_ q in
let q = propagate_equality Var.Set.empty Context.true_ q in
let q = simplify_ q.us [] q in
q
|>

@ -17,7 +17,7 @@ type seg = {loc: Term.t; bas: Term.t; len: Term.t; siz: Term.t; seq: Term.t}
type starjunction = private
{ us: Var.Set.t (** vocabulary / variable context of formula *)
; xs: Var.Set.t (** existentially-bound variables *)
; cong: Equality.t (** congruence induced by rest of formula *)
; cong: Context.t (** congruence induced by rest of formula *)
; pure: Term.t (** pure boolean constraints *)
; heap: seg list (** star-conjunction of segment atomic formulas *)
; djns: disjunction list (** star-conjunction of disjunctions *) }
@ -26,11 +26,11 @@ and disjunction = starjunction list
type t = starjunction [@@deriving compare, equal, sexp]
val pp_seg_norm : Equality.t -> seg pp
val pp_seg_norm : Context.t -> seg pp
val pp_us : ?pre:('a, 'a) fmt -> ?vs:Var.Set.t -> unit -> Var.Set.t pp
val pp : t pp
val pp_raw : t pp
val pp_diff_eq : ?us:Var.Set.t -> ?xs:Var.Set.t -> Equality.t -> t pp
val pp_diff_eq : ?us:Var.Set.t -> ?xs:Var.Set.t -> Context.t -> t pp
val pp_djn : disjunction pp
val simplify : t -> t
@ -61,11 +61,11 @@ val pure : Term.t -> t
val and_ : Term.t -> t -> t
(** Conjoin a boolean constraint to a formula. *)
val and_cong : Equality.t -> t -> t
val and_cong : Context.t -> t -> t
(** Conjoin constraints of a congruence to a formula, extending to a common
vocabulary, and avoiding capturing existentials. *)
val and_subst : Equality.Subst.t -> t -> t
val and_subst : Context.Subst.t -> t -> t
(** Conjoin constraints of a solution substitution to a formula, extending
to a common vocabulary, and avoiding capturing existentials. *)
@ -85,7 +85,7 @@ val rem_seg : seg -> t -> t
val filter_heap : f:(seg -> bool) -> t -> t
(** [filter_heap q f] Remove all segments in [q] for which [f] returns false *)
val norm : Equality.Subst.t -> t -> t
val norm : Context.Subst.t -> t -> t
(** [norm s q] is [q] where subterms have been normalized with a
substitution. *)

@ -158,9 +158,9 @@ let excise_exists goal =
Var.Set.diff goal.xs
(Sh.fv ~ignore_cong:() (Sh.with_pure Term.true_ goal.sub))
in
Equality.solve_for_vars [Var.Set.empty; goal.us; xs] goal.sub.cong
Context.solve_for_vars [Var.Set.empty; goal.us; xs] goal.sub.cong
in
if Equality.Subst.is_empty solutions_for_xs then goal
if Context.Subst.is_empty solutions_for_xs then goal
else
let removed =
Var.Set.diff goal.xs
@ -169,13 +169,13 @@ let excise_exists goal =
if Var.Set.is_empty removed then goal
else
let _, removed, witnesses =
Equality.Subst.partition_valid removed solutions_for_xs
Context.Subst.partition_valid removed solutions_for_xs
in
if Equality.Subst.is_empty witnesses then goal
if Context.Subst.is_empty witnesses then goal
else (
excise (fun {pf} ->
pf "@[<2>excise_exists @[%a%a@]@]" Var.Set.pp_xs removed
Equality.Subst.pp witnesses ) ;
Context.Subst.pp witnesses ) ;
let us = Var.Set.union goal.us removed in
let xs = Var.Set.diff goal.xs removed in
let min = Sh.and_subst witnesses goal.min in
@ -183,7 +183,7 @@ let excise_exists goal =
let excise_pure ({min; sub} as goal) =
trace (fun {pf} -> pf "@[<2>excise_pure@ %a@]" pp goal) ;
let pure' = Equality.normalize min.cong sub.pure in
let pure' = Context.normalize min.cong sub.pure in
if Term.is_false pure' then None
else Some (goal |> with_ ~sub:(Sh.with_pure pure' sub))
@ -562,10 +562,10 @@ let excise_seg ({sub} as goal) msg ssg =
(Sh.pp_seg_norm sub.cong) ssg ) ;
let {Sh.loc= k; bas= b; len= m; siz= o} = msg in
let {Sh.loc= l; bas= b'; len= m'; siz= n} = ssg in
let* k_l = Equality.difference sub.cong k l in
let* k_l = Context.difference sub.cong k l in
if
(not (Equality.entails_eq sub.cong b b'))
|| not (Equality.entails_eq sub.cong m m')
(not (Context.entails_eq sub.cong b b'))
|| not (Context.entails_eq sub.cong m m')
then
Some
( goal
@ -578,11 +578,11 @@ let excise_seg ({sub} as goal) msg ssg =
| Neg -> (
let ko = Term.add k o in
let ln = Term.add l n in
let* ko_ln = Equality.difference sub.cong ko ln in
let* ko_ln = Context.difference sub.cong ko ln in
match Int.sign (Z.sign ko_ln) with
(* k+o-(l+n) < 0 so k+o < l+n *)
| Neg -> (
let* l_ko = Equality.difference sub.cong l ko in
let* l_ko = Context.difference sub.cong l ko in
match Int.sign (Z.sign l_ko) with
(* l-(k+o) < 0 [k; o)
* so l < k+o [l; n) *)
@ -600,7 +600,7 @@ let excise_seg ({sub} as goal) msg ssg =
)
(* k-l = 0 so k = l *)
| Zero -> (
let* o_n = Equality.difference sub.cong o n in
let* o_n = Context.difference sub.cong o n in
match Int.sign (Z.sign o_n) with
(* o-n < 0 [k; o)
* so o < n [l; n) *)
@ -615,7 +615,7 @@ let excise_seg ({sub} as goal) msg ssg =
| Pos -> (
let ko = Term.add k o in
let ln = Term.add l n in
let* ko_ln = Equality.difference sub.cong ko ln in
let* ko_ln = Context.difference sub.cong ko ln in
match Int.sign (Z.sign ko_ln) with
(* k+o-(l+n) < 0 [k; o)
* so k+o < l+n [l; n) *)
@ -625,7 +625,7 @@ let excise_seg ({sub} as goal) msg ssg =
| Zero -> Some (excise_seg_min_suffix goal msg ssg k_l)
(* k+o-(l+n) > 0 so k+o > l+n *)
| Pos -> (
let* k_ln = Equality.difference sub.cong k ln in
let* k_ln = Context.difference sub.cong k ln in
match Int.sign (Z.sign k_ln) with
(* k-(l+n) < 0 [k; o)
* so k < l+n [l; n) *)

Loading…
Cancel
Save