[sledge] Change: Generalize entails_eq to implies

Summary:
Generalize Fol interface to allow checking if a context implies any
formula, rather than restricting to only equalities.

Reviewed By: jvillard

Differential Revision: D22571144

fbshipit-source-id: 726bd87fd
master
Josh Berdine 4 years ago committed by Facebook GitHub Bot
parent c9fa894a31
commit 867131e964

@ -1212,7 +1212,7 @@ module Context = struct
let fv x = vs_of_ses (Ses.Equality.fv x) let fv x = vs_of_ses (Ses.Equality.fv x)
let is_true x = Ses.Equality.is_true x let is_true x = Ses.Equality.is_true x
let is_false x = Ses.Equality.is_false x let is_false x = Ses.Equality.is_false x
let entails_eq x e f = Ses.Equality.entails_eq x (to_ses e) (to_ses f) let implies x b = Ses.Equality.implies x (f_to_ses b)
let normalize x e = ses_map (Ses.Equality.normalize x) e let normalize x e = ses_map (Ses.Equality.normalize x) e
let normalizef x e = f_ses_map (Ses.Equality.normalize x) e let normalizef x e = f_ses_map (Ses.Equality.normalize x) e
let difference x e f = Term.d_int (normalize x (Term.sub e f)) let difference x e f = Term.d_int (normalize x (Term.sub e f))
@ -1238,7 +1238,8 @@ module Context = struct
let diff_classes r s = let diff_classes r s =
Term.Map.filter_mapi (classes r) ~f:(fun ~key:rep ~data:cls -> Term.Map.filter_mapi (classes r) ~f:(fun ~key:rep ~data:cls ->
match match
List.filter cls ~f:(fun exp -> not (entails_eq s rep exp)) List.filter cls ~f:(fun exp ->
not (implies s (Formula.eq rep exp)) )
with with
| [] -> None | [] -> None
| cls -> Some cls ) | cls -> Some cls )

@ -218,8 +218,10 @@ module Context : sig
val is_false : t -> bool val is_false : t -> bool
(** Test if the relation is empty / inconsistent. *) (** Test if the relation is empty / inconsistent. *)
val entails_eq : t -> Term.t -> Term.t -> bool val implies : t -> Formula.t -> bool
(** Test if an equation is entailed by a relation. *) (** [implies x f] holds only if [f] is a logical consequence of [x]. This
only checks if [f] is valid in the current state of [x], without doing
any further logical reasoning or propagation. *)
val class_of : t -> Term.t -> Term.t list val class_of : t -> Term.t -> Term.t list
(** Equivalence class of [e]: all the terms [f] in the relation such that (** Equivalence class of [e]: all the terms [f] in the relation such that

@ -561,10 +561,10 @@ let is_true {sat; rep} =
let is_false {sat} = not sat let is_false {sat} = not sat
let entails_eq r d e = let implies r b =
[%Trace.call fun {pf} -> pf "%a = %a@ %a" Term.pp d Term.pp e pp r] [%Trace.call fun {pf} -> pf "%a@ %a" Term.pp b pp r]
; ;
Term.is_true (Term.eq (canon r d) (canon r e)) Term.is_true (canon r b)
|> |>
[%Trace.retn fun {pf} -> pf "%b"] [%Trace.retn fun {pf} -> pf "%b"]
@ -630,7 +630,9 @@ let or_ us r s =
List.fold cls List.fold cls
~init:([rep], rs) ~init:([rep], rs)
~f:(fun (reps, rs) exp -> ~f:(fun (reps, rs) exp ->
match List.find ~f:(entails_eq r exp) reps with match
List.find ~f:(fun rep -> implies r (Term.eq exp rep)) reps
with
| Some rep -> (reps, and_eq_ us exp rep rs) | Some rep -> (reps, and_eq_ us exp rep rs)
| None -> (exp :: reps, rs) ) | None -> (exp :: reps, rs) )
|> snd ) |> snd )
@ -934,7 +936,7 @@ let solve_concat_extracts_eq r x =
let find_extracts_at_off off = let find_extracts_at_off off =
List.filter uses ~f:(fun use -> List.filter uses ~f:(fun use ->
match (use : Term.t) with match (use : Term.t) with
| Ap3 (Extract, _, o, _) -> entails_eq r o off | Ap3 (Extract, _, o, _) -> implies r (Term.eq o off)
| _ -> false ) | _ -> false )
in in
let rec find_extracts full_rev_extracts rev_prefix off = let rec find_extracts full_rev_extracts rev_prefix off =
@ -943,7 +945,7 @@ let solve_concat_extracts_eq r x =
match e with match e with
| Ap3 (Extract, Ap2 (Sized, n, _), o, l) -> | Ap3 (Extract, Ap2 (Sized, n, _), o, l) ->
let o_l = Term.add o l in let o_l = Term.add o l in
if entails_eq r n o_l then if implies r (Term.eq n o_l) then
(e :: rev_prefix) :: full_rev_extracts (e :: rev_prefix) :: full_rev_extracts
else find_extracts full_rev_extracts (e :: rev_prefix) o_l else find_extracts full_rev_extracts (e :: rev_prefix) o_l
| _ -> full_rev_extracts ) | _ -> full_rev_extracts )
@ -1029,7 +1031,7 @@ let solve_for_vars vss r =
pf "%a" Subst.pp subst ; pf "%a" Subst.pp subst ;
Subst.iteri subst ~f:(fun ~key ~data -> Subst.iteri subst ~f:(fun ~key ~data ->
assert ( assert (
entails_eq r key data implies r (Term.eq key data)
|| fail "@[%a@ = %a@ not entailed by@ @[%a@]@]" Term.pp key || fail "@[%a@ = %a@ not entailed by@ @[%a@]@]" Term.pp key
Term.pp data pp_classes r () ) ; Term.pp data pp_classes r () ) ;
assert ( assert (

@ -56,8 +56,8 @@ val is_true : t -> bool
val is_false : t -> bool val is_false : t -> bool
(** Test if the relation is empty / inconsistent. *) (** Test if the relation is empty / inconsistent. *)
val entails_eq : t -> Term.t -> Term.t -> bool val implies : t -> Term.t -> bool
(** Test if an equation is entailed by a relation. *) (** Test if a term is implied by a relation. *)
val class_of : t -> Term.t -> Term.t list val class_of : t -> Term.t -> Term.t list
(** Equivalence class of [e]: all the terms [f] in the relation such that (** Equivalence class of [e]: all the terms [f] in the relation such that

@ -49,6 +49,7 @@ let%test_module _ =
l l
|> snd |> snd
let implies_eq r a b = implies r (Term.eq a b)
let and_eq a b r = and_eq wrt a b r |> snd let and_eq a b r = and_eq wrt a b r |> snd
let and_ r s = and_ wrt r s |> snd let and_ r s = and_ wrt r s |> snd
let or_ r s = or_ wrt r s |> snd let or_ r s = or_ wrt r s |> snd
@ -122,7 +123,7 @@ let%test_module _ =
{sat= true; rep= [[%x_5 ]; [%y_6 %x_5]; [-1 ]; [0 ]]} |}] {sat= true; rep= [[%x_5 ]; [%y_6 %x_5]; [-1 ]; [0 ]]} |}]
let%test _ = entails_eq r1 x y let%test _ = implies_eq r1 x y
let r2 = of_eqs [(x, y); (f x, y); (f y, z)] let r2 = of_eqs [(x, y); (f x, y); (f y, z)]
@ -141,14 +142,14 @@ let%test_module _ =
[-1 ]; [-1 ];
[0 ]]} |}] [0 ]]} |}]
let%test _ = entails_eq r2 x z let%test _ = implies_eq r2 x z
let%test _ = entails_eq (or_ r1 r2) x y let%test _ = implies_eq (or_ r1 r2) x y
let%test _ = not (entails_eq (or_ r1 r2) x z) let%test _ = not (implies_eq (or_ r1 r2) x z)
let%test _ = entails_eq (or_ f1 r2) x z let%test _ = implies_eq (or_ f1 r2) x z
let%test _ = entails_eq (or_ r2 f3) x z let%test _ = implies_eq (or_ r2 f3) x z
let%test _ = entails_eq r2 (f y) y let%test _ = implies_eq r2 (f y) y
let%test _ = entails_eq r2 (f x) (f z) let%test _ = implies_eq r2 (f x) (f z)
let%test _ = entails_eq r2 (g x y) (g z y) let%test _ = implies_eq r2 (g x y) (g z y)
let%expect_test _ = let%expect_test _ =
let r = of_eqs [(w, y); (y, z)] in let r = of_eqs [(w, y); (y, z)] in
@ -171,7 +172,7 @@ let%test_module _ =
let r = of_eqs [(w, y); (y, z)] in let r = of_eqs [(w, y); (y, z)] in
let s = of_eqs [(x, y); (y, z)] in let s = of_eqs [(x, y); (y, z)] in
let rs = or_ r s in let rs = or_ r s in
entails_eq rs y z implies_eq rs y z
let r3 = of_eqs [(g y z, w); (v, w); (g y w, t); (x, v); (x, u); (u, z)] let r3 = of_eqs [(g y z, w); (v, w); (g y w, t); (x, v); (x, u); (u, z)]
@ -196,9 +197,9 @@ let%test_module _ =
[-1 ]; [-1 ];
[0 ]]} |}] [0 ]]} |}]
let%test _ = entails_eq r3 t z let%test _ = implies_eq r3 t z
let%test _ = entails_eq r3 x z let%test _ = implies_eq r3 x z
let%test _ = entails_eq (and_ r2 r3) x z let%test _ = implies_eq (and_ r2 r3) x z
let r4 = of_eqs [(w + !2, x - !3); (x - !5, y + !7); (y, z - !4)] let r4 = of_eqs [(w + !2, x - !3); (x - !5, y + !7); (y, z - !4)]
@ -217,7 +218,7 @@ let%test_module _ =
[-1 ]; [-1 ];
[0 ]]} |}] [0 ]]} |}]
let%test _ = entails_eq r4 x (w + !5) let%test _ = implies_eq r4 x (w + !5)
let r5 = of_eqs [(x, y); (g w x, y); (g w y, f z)] let r5 = of_eqs [(x, y); (g w x, y); (g w y, f z)]
@ -234,7 +235,7 @@ let%test_module _ =
{sat= true; rep= [[%x_5 1]; [%y_6 1]; [-1 ]; [0 ]]} |}] {sat= true; rep= [[%x_5 1]; [%y_6 1]; [-1 ]; [0 ]]} |}]
let%test _ = entails_eq r6 x y let%test _ = implies_eq r6 x y
let r7 = of_eqs [(v, x); (w, z); (y, z)] let r7 = of_eqs [(v, x); (w, z); (y, z)]
@ -300,10 +301,10 @@ let%test_module _ =
let%test _ = normalize r7' w |> Term.equal v let%test _ = normalize r7' w |> Term.equal v
let%test _ = let%test _ =
entails_eq (of_eqs [(g w x, g y z); (x, z)]) (g w x) (g w z) implies_eq (of_eqs [(g w x, g y z); (x, z)]) (g w x) (g w z)
let%test _ = let%test _ =
entails_eq (of_eqs [(g w x, g y w); (x, z)]) (g w x) (g w z) implies_eq (of_eqs [(g w x, g y w); (x, z)]) (g w x) (g w z)
let r8 = of_eqs [(x + !42, (3 * y) + (13 * z)); (13 * z, x)] let r8 = of_eqs [(x + !42, (3 * y) + (13 * z)); (13 * z, x)]
@ -317,7 +318,7 @@ let%test_module _ =
{sat= true; {sat= true;
rep= [[%x_5 (13 × %z_7)]; [%y_6 14]; [%z_7 ]; [-1 ]; [0 ]]} |}] rep= [[%x_5 (13 × %z_7)]; [%y_6 14]; [%z_7 ]; [-1 ]; [0 ]]} |}]
let%test _ = entails_eq r8 y !14 let%test _ = implies_eq r8 y !14
let r11 = of_eqs [(!16, z - x); (x + !8 - z, z - !16 + !8 - z)] let r11 = of_eqs [(!16, z - x); (x + !8 - z, z - !16 + !8 - z)]
@ -357,7 +358,7 @@ let%test_module _ =
{| {|
{sat= true; rep= [[%x_5 1]; [(%x_5 0) -1]; [-1 ]; [0 ]]} |}] {sat= true; rep= [[%x_5 1]; [(%x_5 0) -1]; [-1 ]; [0 ]]} |}]
let%test _ = entails_eq r14 a Term.true_ let%test _ = implies_eq r14 a Term.true_
let b = Term.dq y !0 let b = Term.dq y !0
let r14 = of_eqs [(a, b); (x, !1)] let r14 = of_eqs [(a, b); (x, !1)]
@ -374,8 +375,8 @@ let%test_module _ =
[-1 ]; [-1 ];
[0 ]]} |}] [0 ]]} |}]
let%test _ = entails_eq r14 a Term.true_ let%test _ = implies_eq r14 a Term.true_
let%test _ = entails_eq r14 b Term.true_ let%test _ = implies_eq r14 b Term.true_
let b = Term.dq x !0 let b = Term.dq x !0
let r15 = of_eqs [(b, b); (x, !1)] let r15 = of_eqs [(b, b); (x, !1)]
@ -386,8 +387,8 @@ let%test_module _ =
{| {|
{sat= true; rep= [[%x_5 1]; [(%x_5 0) -1]; [-1 ]; [0 ]]} |}] {sat= true; rep= [[%x_5 1]; [(%x_5 0) -1]; [-1 ]; [0 ]]} |}]
let%test _ = entails_eq r15 b (Term.signed 1 !1) let%test _ = implies_eq r15 b (Term.signed 1 !1)
let%test _ = entails_eq r15 (Term.unsigned 1 b) !1 let%test _ = implies_eq r15 (Term.unsigned 1 b) !1
(* f(x1)1=x+1, f(y)+1=y1, y+1=x ⊢ false *) (* f(x1)1=x+1, f(y)+1=y1, y+1=x ⊢ false *)
let r16 = let r16 =
@ -449,5 +450,5 @@ let%test_module _ =
{sat= true; {sat= true;
rep= [[%x_5 0]; [%y_6 0]; [%z_7 0]; [-1 ]; [0 ]]} |}] rep= [[%x_5 0]; [%y_6 0]; [%z_7 0]; [-1 ]; [0 ]]} |}]
let%test _ = entails_eq r19 z !0 let%test _ = implies_eq r19 z !0
end ) end )

@ -185,7 +185,8 @@ let pp_heap x ?pre ctx fs heap =
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 (Context.entails_eq ctx (Term.add s1.loc s1.siz) s2.loc) || not
(Context.implies ctx (Formula.eq (Term.add s1.loc s1.siz) s2.loc))
in in
let heap = List.map heap ~f:(map_seg ~f:(Context.normalize ctx)) in let heap = List.map heap ~f:(map_seg ~f:(Context.normalize ctx)) in
let blocks = List.group ~break (List.sort ~compare heap) in let blocks = List.group ~break (List.sort ~compare heap) in
@ -591,7 +592,7 @@ let is_false = function
| {ctx; pure; heap; _} -> | {ctx; pure; heap; _} ->
Formula.is_false (Context.normalizef ctx pure) Formula.is_false (Context.normalizef ctx pure)
|| List.exists heap ~f:(fun seg -> || List.exists heap ~f:(fun seg ->
Context.entails_eq ctx seg.loc Term.zero ) Context.implies ctx (Formula.eq seg.loc Term.zero) )
let rec pure_approx ({us; xs; ctx; pure; heap= _; djns} as q) = let rec pure_approx ({us; xs; ctx; pure; heap= _; djns} as q) =
let heap = emp.heap in let heap = emp.heap in

@ -563,8 +563,8 @@ let excise_seg ({sub} as goal) msg ssg =
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 = Context.difference sub.ctx k l in let* k_l = Context.difference sub.ctx k l in
if if
(not (Context.entails_eq sub.ctx b b')) (not (Context.implies sub.ctx (Formula.eq b b')))
|| not (Context.entails_eq sub.ctx m m') || not (Context.implies sub.ctx (Formula.eq m m'))
then then
Some Some
( goal ( goal

Loading…
Cancel
Save