[sledge] Refactor: split Equality.diff_classes out of ppx_classes_diff

Summary:
Refactor `Equality.ppx_classes_diff` into `diff_classes` to construct
the difference between classes maps explicitly, and change
`ppx_classes` to accept such a difference instead of computing it
internally.

This more flexibly composable interface allows elimination of extra
calls to `Equality.entails` to check if the difference is empty.

Reviewed By: jvillard

Differential Revision: D22038488

fbshipit-source-id: c19c18fc8
master
Josh Berdine 5 years ago committed by Facebook GitHub Bot
parent 89f60156a9
commit d5de3f78a6

@ -339,6 +339,8 @@ type t =
'rep(resentative)' of [a] *) } 'rep(resentative)' of [a] *) }
[@@deriving compare, equal, sexp] [@@deriving compare, equal, sexp]
type classes = Term.t list Term.Map.t
let classes r = let classes r =
let add key data cls = let add key data cls =
if Term.equal key data then cls if Term.equal key data then cls
@ -382,14 +384,14 @@ let ppx_cls x = List.pp "@ = " (Term.ppx x)
let pp_cls = ppx_cls (fun _ -> None) let pp_cls = ppx_cls (fun _ -> None)
let pp_diff_cls = List.pp_diff ~compare:Term.compare "@ = " Term.pp let pp_diff_cls = List.pp_diff ~compare:Term.compare "@ = " Term.pp
let ppx_clss x fs cs = let ppx_classes x fs clss =
List.pp "@ @<2>∧ " List.pp "@ @<2>∧ "
(fun fs (key, data) -> (fun fs (rep, cls) ->
Format.fprintf fs "@[%a@ = %a@]" (Term.ppx x) key (ppx_cls x) Format.fprintf fs "@[%a@ = %a@]" (Term.ppx x) rep (ppx_cls x)
(List.sort ~compare:Term.compare data) ) (List.sort ~compare:Term.compare cls) )
fs (Term.Map.to_alist cs) fs (Term.Map.to_alist clss)
let pp_clss fs cs = ppx_clss (fun _ -> None) fs cs let pp_classes fs r = ppx_classes (fun _ -> None) fs (classes r)
let pp_diff_clss = let pp_diff_clss =
Term.Map.pp_diff ~data_equal:(List.equal Term.equal) Term.pp pp_cls Term.Map.pp_diff ~data_equal:(List.equal Term.equal) Term.pp pp_cls
@ -566,9 +568,6 @@ let entails_eq r d e =
|> |>
[%Trace.retn fun {pf} -> pf "%b"] [%Trace.retn fun {pf} -> pf "%b"]
let entails r s =
Subst.for_alli s.rep ~f:(fun ~key:e ~data:e' -> entails_eq r e e')
let normalize = canon let normalize = canon
let class_of r e = let class_of r e =
@ -710,25 +709,12 @@ let fold_vars r ~init ~f =
fold_terms r ~init ~f:(fun init -> Term.fold_vars ~f ~init) fold_terms r ~init ~f:(fun init -> Term.fold_vars ~f ~init)
let fv e = fold_vars e ~f:Var.Set.add ~init:Var.Set.empty let fv e = fold_vars e ~f:Var.Set.add ~init:Var.Set.empty
let pp_classes fs r = pp_clss fs (classes r)
let ppx_classes x fs r = ppx_clss x fs (classes r)
let ppx_classes_diff x fs (r, s) = let diff_classes r s =
let clss = classes s in Term.Map.filter_mapi (classes r) ~f:(fun ~key:rep ~data:cls ->
let clss = match List.filter cls ~f:(fun exp -> not (entails_eq s rep exp)) with
Term.Map.filter_mapi clss ~f:(fun ~key:rep ~data:cls ->
match
List.filter cls ~f:(fun exp -> not (entails_eq r rep exp))
with
| [] -> None | [] -> None
| cls -> Some cls ) | cls -> Some cls )
in
List.pp "@ @<2>∧ "
(fun fs (rep, cls) ->
Format.fprintf fs "@[%a@ = %a@]" (Term.ppx x) rep
(List.pp "@ = " (Term.ppx x))
(List.dedup_and_sort ~compare:Term.compare cls) )
fs (Term.Map.to_alist clss)
(** Existential Witnessing and Elimination *) (** Existential Witnessing and Elimination *)

@ -14,11 +14,19 @@
fresh, and the output set is the variables that have been generated. *) fresh, and the output set is the variables that have been generated. *)
type t [@@deriving compare, equal, sexp] type t [@@deriving compare, equal, sexp]
type classes = Term.t list Term.Map.t
val classes : t -> classes
(** [classes r] maps each equivalence class representative to the other
terms [r] proves equal to it. *)
val diff_classes : t -> t -> classes
(** [diff_classes r s] is the equality classes of [r] omitting equalities in
[s]. *)
val pp : t pp val pp : t pp
val pp_classes : t pp val pp_classes : t pp
val ppx_classes : Var.strength -> t pp val ppx_classes : Var.strength -> classes pp
val ppx_classes_diff : Var.strength -> (t * t) pp
include Invariant.S with type t := t include Invariant.S with type t := t
@ -55,9 +63,6 @@ val is_false : t -> bool
val entails_eq : t -> Term.t -> Term.t -> bool val entails_eq : t -> Term.t -> Term.t -> bool
(** Test if an equation is entailed by a relation. *) (** Test if an equation is entailed by a relation. *)
val entails : t -> t -> bool
(** Test if one relation entails another. *)
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
[e = f] is implied by the relation. *) [e = f] is implied by the relation. *)
@ -74,9 +79,6 @@ val difference : t -> Term.t -> Term.t -> Z.t option
val fold_terms : t -> init:'a -> f:('a -> Term.t -> 'a) -> 'a val fold_terms : t -> init:'a -> f:('a -> Term.t -> 'a) -> 'a
val classes : t -> Term.t list Term.Map.t
(** The equalities that make up the relation. *)
(** Solution Substitutions *) (** Solution Substitutions *)
module Subst : sig module Subst : sig
type t [@@deriving compare, equal, sexp] type t [@@deriving compare, equal, sexp]

@ -216,9 +216,10 @@ 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 first = Equality.entails parent_cong cong in let clss = Equality.diff_classes cong parent_cong 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_diff x fs (parent_cong, cong) ; Equality.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

Loading…
Cancel
Save