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

Reviewed By: ngorogiannis

Differential Revision: D22170521

fbshipit-source-id: e791739b7
master
Josh Berdine 5 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 = let term_eq_class_has_only_vars_in fvs cong term =
[%Trace.call fun {pf} -> [%Trace.call fun {pf} ->
pf "@[<v> fvs: @[%a@] @,cong: @[%a@] @,term: @[%a@]@]" Var.Set.pp fvs 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 = let term_has_only_vars_in fvs term =
Var.Set.is_subset (Term.fv term) ~of_:fvs Var.Set.is_subset (Term.fv term) ~of_:fvs
in 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 List.exists ~f:(term_has_only_vars_in fvs) term_eq_class
|> |>
[%Trace.retn fun {pf} -> pf "%b"] [%Trace.retn fun {pf} -> pf "%b"]
@ -107,7 +107,7 @@ let garbage_collect (q : t) ~wrt =
let new_set = let new_set =
List.fold ~init:current q.heap ~f:(fun current seg -> List.fold ~init:current q.heap ~f:(fun current seg ->
if term_eq_class_has_only_vars_in current q.cong seg.loc then 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)) ~f:(fun c e -> Var.Set.union c (Term.fv e))
else current ) else current )
in in

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

@ -7,4 +7,4 @@
module Var = Ses.Var module Var = Ses.Var
module Term = Ses.Term 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 = type starjunction =
{ us: Var.Set.t { us: Var.Set.t
; xs: Var.Set.t ; xs: Var.Set.t
; cong: Equality.t ; cong: Context.t
; pure: Term.t ; pure: Term.t
; heap: seg list ; heap: seg list
; djns: disjunction list } ; djns: disjunction list }
@ -32,7 +32,7 @@ type t = starjunction [@@deriving compare, equal, sexp]
let emp = let emp =
{ us= Var.Set.empty { us= Var.Set.empty
; xs= Var.Set.empty ; xs= Var.Set.empty
; cong= Equality.true_ ; cong= Context.true_
; pure= Term.true_ ; pure= Term.true_
; heap= [] ; heap= []
; djns= [] } ; djns= [] }
@ -82,7 +82,7 @@ let fold_vars_stem ?ignore_cong {us= _; xs= _; cong; pure; heap; djns= _}
|> fun init -> |> fun init ->
if Option.is_some ignore_cong then init if Option.is_some ignore_cong then init
else 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 = let fold_vars ?ignore_cong fold_vars q ~init ~f =
fold_vars_stem ?ignore_cong ~init ~f q 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 pp_seg_norm cong fs seg =
let x _ = None in 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 pp_block x fs segs =
let is_full_alloc segs = let is_full_alloc segs =
@ -179,17 +179,17 @@ let pp_heap x ?pre cong fs heap =
in in
let compare s1 s2 = let compare s1 s2 =
[%compare: Term.t * (Term.t * Q.t)] [%compare: Term.t * (Term.t * Q.t)]
( Equality.normalize cong s1.bas ( Context.normalize cong s1.bas
, bas_off (Equality.normalize cong s1.loc) ) , bas_off (Context.normalize cong s1.loc) )
( Equality.normalize cong s2.bas ( Context.normalize cong s2.bas
, bas_off (Equality.normalize cong s2.loc) ) , bas_off (Context.normalize cong s2.loc) )
in in
let break s1 s2 = let break s1 s2 =
(not (Term.equal s1.bas s2.bas)) (not (Term.equal s1.bas s2.bas))
|| (not (Term.equal s1.len s2.len)) || (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 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 let blocks = List.group ~break (List.sort ~compare heap) in
List.pp ?pre "@ * " (pp_block x) fs blocks 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 "@ " ) ;
if not (Var.Set.is_empty xs_d_vs) then if not (Var.Set.is_empty xs_d_vs) then
Format.fprintf fs "@<2>∃ @[%a@] .@ " (Var.Set.ppx x) xs_d_vs ; 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 let first = Term.Map.is_empty clss in
if not first then Format.fprintf fs " " ; if not first then Format.fprintf fs " " ;
Equality.ppx_classes x fs clss ; Context.ppx_classes x fs clss ;
let pure = let pure =
if Option.is_none var_strength then [pure] if Option.is_none var_strength then [pure]
else else
let pure' = Equality.normalize cong pure in let pure' = Context.normalize cong pure in
if Term.is_true pure' then [] else [pure'] if Term.is_true pure' then [] else [pure']
in in
List.pp 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 = 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 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 fs q = pp_diff_eq Context.true_ fs q
let pp_djn fs d = pp_djn Var.Set.empty Var.Set.empty Equality.true_ fs d 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 Equality.true_ fs q 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_seg seg = fold_vars_seg seg ~f:Var.Set.add ~init:Var.Set.empty
let fv ?ignore_cong q = let fv ?ignore_cong q =
@ -297,13 +297,13 @@ let rec invariant q =
Var.Set.is_subset (fv q) ~of_:us Var.Set.is_subset (fv q) ~of_:us
|| fail "unbound but free: %a" Var.Set.pp (Var.Set.diff (fv q) us) () || fail "unbound but free: %a" Var.Set.pp (Var.Set.diff (fv q) us) ()
) ; ) ;
Equality.invariant cong ; Context.invariant cong ;
( match djns with ( match djns with
| [[]] -> | [[]] ->
assert (Equality.is_true cong) ; assert (Context.is_true cong) ;
assert (Term.is_true pure) ; assert (Term.is_true pure) ;
assert (List.is_empty heap) assert (List.is_empty heap)
| _ -> assert (not (Equality.is_false cong)) ) ; | _ -> assert (not (Context.is_false cong)) ) ;
invariant_pure pure ; invariant_pure pure ;
List.iter heap ~f:invariant_seg ; List.iter heap ~f:invariant_seg ;
List.iter djns ~f:(fun djn -> List.iter djns ~f:(fun djn ->
@ -320,7 +320,7 @@ let rec invariant q =
invariant *) invariant *)
let rec apply_subst sub q = let rec apply_subst sub q =
map q ~f_sjn:(rename sub) 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) ~f_trm:(Term.rename sub)
|> check (fun q' -> |> check (fun q' ->
assert (Var.Set.disjoint (fv q') (Var.Subst.domain sub)) ) 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 *) (** conjoin an equality relation assuming vocabulary is compatible *)
let and_cong_ cong q = let and_cong_ cong q =
assert (Var.Set.is_subset (Equality.fv cong) ~of_:q.us) ; assert (Var.Set.is_subset (Context.fv cong) ~of_:q.us) ;
let xs, cong = Equality.and_ (Var.Set.union q.us q.xs) q.cong cong in let xs, cong = Context.and_ (Var.Set.union q.us q.xs) q.cong cong in
if Equality.is_false cong then false_ q.us if Context.is_false cong then false_ q.us
else exists_fresh xs {q with cong} else exists_fresh xs {q with cong}
let and_cong cong q = 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 ( match q.djns with
| [[]] -> q | [[]] -> q
| _ -> and_cong_ cong (extend_us (Equality.fv cong) q) ) | _ -> and_cong_ cong (extend_us (Context.fv cong) q) )
|> |>
[%Trace.retn fun {pf} q -> [%Trace.retn fun {pf} q ->
pf "%a" pp q ; pf "%a" pp q ;
@ -460,11 +460,11 @@ let star q1 q2 =
| {djns= [[]]; _}, _ | _, {djns= [[]]; _} -> | {djns= [[]]; _}, _ | _, {djns= [[]]; _} ->
false_ (Var.Set.union q1.us q2.us) false_ (Var.Set.union q1.us q2.us)
| {us= _; xs= _; cong; pure; heap= []; djns= []}, _ | {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 let us = Var.Set.union q1.us q2.us in
if us == q2.us then q2 else {q2 with us} if us == q2.us then q2 else {q2 with us}
| _, {us= _; xs= _; cong; pure; heap= []; djns= []} | _, {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 let us = Var.Set.union q1.us q2.us in
if us == q1.us then q1 else {q1 with us} 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 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)) ; assert (Var.Set.equal us (Var.Set.union us1 us2)) ;
let xs, cong = 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 in
if Equality.is_false cong then false_ us if Context.is_false cong then false_ us
else else
exists_fresh xs exists_fresh xs
{ us { us
@ -514,7 +514,7 @@ let or_ q1 q2 =
| _ -> | _ ->
{ us= Var.Set.union q1.us q2.us { us= Var.Set.union q1.us q2.us
; xs= Var.Set.empty ; xs= Var.Set.empty
; cong= Equality.true_ ; cong= Context.true_
; pure= Term.true_ ; pure= Term.true_
; heap= [] ; heap= []
; djns= [[q1; q2]] } ) ; 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 -> List.fold (Term.disjuncts e) ~init:(false_ Var.Set.empty) ~f:(fun q b ->
let us = Term.fv b in let us = Term.fv b in
let xs, cong = Equality.(and_term us b true_) in let xs, cong = Context.(and_term us b true_) in
if Equality.is_false cong then false_ us if Context.is_false cong then false_ us
else or_ q (exists_fresh xs {emp with us; cong; pure= b}) ) else or_ q (exists_fresh xs {emp with us; cong; pure= b}) )
|> |>
[%Trace.retn fun {pf} q -> [%Trace.retn fun {pf} q ->
@ -545,9 +545,9 @@ let pure (e : Term.t) =
let and_ e q = star (pure e) q let and_ e q = star (pure e) q
let and_subst subst 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)) ~f:(fun ~key ~data -> and_ (Term.eq key data))
subst ~init:q subst ~init:q
|> |>
@ -595,9 +595,9 @@ let is_emp = function
let is_false = function let is_false = function
| {djns= [[]]; _} -> true | {djns= [[]]; _} -> true
| {cong; pure; heap; _} -> | {cong; pure; heap; _} ->
Term.is_false (Equality.normalize cong pure) Term.is_false (Context.normalize cong pure)
|| List.exists heap ~f:(fun seg -> || 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 rec pure_approx ({us; xs; cong; pure; heap= _; djns} as q) =
let heap = emp.heap in let heap = emp.heap in
@ -647,12 +647,12 @@ let dnf q =
(** Simplify *) (** Simplify *)
let rec norm_ s q = 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 = 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 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} exists_fresh xs {q with cong}
|> |>
[%Trace.retn fun {pf} q' -> [%Trace.retn fun {pf} q' ->
@ -660,9 +660,9 @@ let rec norm_ s q =
invariant q'] invariant q']
let norm s 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' -> [%Trace.retn fun {pf} q' ->
pf "%a" pp_raw 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 = let rec propagate_equality_ ancestor_vs ancestor_cong q =
[%Trace.call fun {pf} -> [%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 *) (* extend vocabulary with variables in scope above *)
let ancestor_vs = Var.Set.union ancestor_vs (Var.Set.union q.us q.xs) in 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 let dj = propagate_equality_ ancestor_vs ancestor_cong dj in
(dj.cong, dj) ) (dj.cong, dj) )
in 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 *) (* 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 djn = List.map ~f:(elim_exists djn_xs) djn in
let cong_djn = and_cong_ djn_cong (orN 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) ; 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 = let propagate_equality ancestor_vs ancestor_cong q =
[%Trace.call fun {pf} -> [%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 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 if Var.Set.is_empty ks then q
else else
let xs = Var.Set.diff q.xs ks in 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 djns =
let rec trim_ks ks djns = let rec trim_ks ks djns =
List.map djns ~f:(fun djn -> List.map djns ~f:(fun djn ->
List.map djn ~f:(fun sjn -> List.map djn ~f:(fun sjn ->
{ sjn with { sjn with
us= Var.Set.diff sjn.us ks 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 } ) ) ; djns= trim_ks ks sjn.djns } ) )
in in
trim_ks ks q.djns trim_ks ks q.djns
@ -773,10 +773,10 @@ let rec simplify_ us rev_xss q =
)) ))
in in
(* try to solve equations in cong for variables in xss *) (* 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 *) (* simplification can reveal inconsistency *)
( if is_false q then false_ q.us ( 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 else
(* normalize wrt solutions *) (* normalize wrt solutions *)
let q = norm subst q in let q = norm subst q in
@ -786,20 +786,20 @@ let rec simplify_ us rev_xss q =
(Var.Set.union_list rev_xss) (Var.Set.union_list rev_xss)
(fv ~ignore_cong:() (elim_exists q.xs q)) (fv ~ignore_cong:() (elim_exists q.xs q))
in 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 let q = and_subst keep q in
(* remove the eliminated variables from xs and subformulas' us *) (* remove the eliminated variables from xs and subformulas' us *)
remove_absent_xs removed q ) remove_absent_xs removed q )
|> |>
[%Trace.retn fun {pf} 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'] invariant q']
let simplify q = let simplify q =
[%Trace.call fun {pf} -> pf "%a" pp_raw q] [%Trace.call fun {pf} -> pf "%a" pp_raw q]
; ;
let q = freshen_nested_xs q in 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 let q = simplify_ q.us [] q in
q 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 type starjunction = private
{ us: Var.Set.t (** vocabulary / variable context of formula *) { us: Var.Set.t (** vocabulary / variable context of formula *)
; xs: Var.Set.t (** existentially-bound variables *) ; 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 *) ; pure: Term.t (** pure boolean constraints *)
; heap: seg list (** star-conjunction of segment atomic formulas *) ; heap: seg list (** star-conjunction of segment atomic formulas *)
; djns: disjunction list (** star-conjunction of disjunctions *) } ; djns: disjunction list (** star-conjunction of disjunctions *) }
@ -26,11 +26,11 @@ and disjunction = starjunction list
type t = starjunction [@@deriving compare, equal, sexp] 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_us : ?pre:('a, 'a) fmt -> ?vs:Var.Set.t -> unit -> Var.Set.t pp
val pp : t pp val pp : t pp
val pp_raw : 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 pp_djn : disjunction pp
val simplify : t -> t val simplify : t -> t
@ -61,11 +61,11 @@ val pure : Term.t -> t
val and_ : Term.t -> t -> t val and_ : Term.t -> t -> t
(** Conjoin a boolean constraint to a formula. *) (** 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 (** Conjoin constraints of a congruence to a formula, extending to a common
vocabulary, and avoiding capturing existentials. *) 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 (** Conjoin constraints of a solution substitution to a formula, extending
to a common vocabulary, and avoiding capturing existentials. *) 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 val filter_heap : f:(seg -> bool) -> t -> t
(** [filter_heap q f] Remove all segments in [q] for which [f] returns false *) (** [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 (** [norm s q] is [q] where subterms have been normalized with a
substitution. *) substitution. *)

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

Loading…
Cancel
Save