[sledge] Move Formula.fold_dnf to Fml

Summary: As well as fold_pos_neg and map_pos_neg

Reviewed By: jvillard

Differential Revision: D24532349

fbshipit-source-id: 610b34153
master
Josh Berdine 4 years ago committed by Facebook GitHub Bot
parent cc3f76b0ad
commit 4473c6a193

@ -170,4 +170,27 @@ let map_vars b ~f = map_trms ~f:(Trm.map_vars ~f) b
(** Traverse *) (** Traverse *)
let fold_pos_neg ~pos ~neg s ~f =
let f_not p s = f (not_ p) s in
Set.fold ~f:f_not neg (Set.fold ~f pos s)
let fold_dnf ~meet1 ~join1 ~top ~bot fml =
let rec add_conjunct fml (cjn, splits) =
match fml with
| Tt | Eq _ | Eq0 _ | Pos _ | Iff _ | Lit _ | Not _ ->
(meet1 fml cjn, splits)
| And {pos; neg} -> fold_pos_neg ~f:add_conjunct ~pos ~neg (cjn, splits)
| Or {pos; neg} -> (cjn, (pos, neg) :: splits)
| Cond {cnd; pos; neg} ->
add_conjunct (or_ (and_ cnd pos) (and_ (not_ cnd) neg)) (cjn, splits)
in
let rec add_disjunct (cjn, splits) fml djn =
let cjn, splits = add_conjunct fml (cjn, splits) in
match splits with
| (pos, neg) :: splits ->
fold_pos_neg ~f:(add_disjunct (cjn, splits)) ~pos ~neg djn
| [] -> join1 cjn djn
in
add_disjunct (top, []) fml bot
let vars p = Iter.flat_map ~f:Trm.vars (trms p) let vars p = Iter.flat_map ~f:Trm.vars (trms p)

@ -67,8 +67,21 @@ val lit : Ses.Predsym.t -> Trm.t array -> t
val map_vars : t -> f:(Var.t -> Var.t) -> t val map_vars : t -> f:(Var.t -> Var.t) -> t
val map_trms : t -> f:(Trm.t -> Trm.t) -> t val map_trms : t -> f:(Trm.t -> Trm.t) -> t
val map_pos_neg :
(t -> t) -> 'a -> (pos:set -> neg:set -> 'a) -> pos:set -> neg:set -> 'a
(** Traverse *) (** Traverse *)
val fold_pos_neg : pos:set -> neg:set -> 'a -> f:(t -> 'a -> 'a) -> 'a
val fold_dnf :
meet1:(t -> 'conjunction -> 'conjunction)
-> join1:('conjunction -> 'disjunction -> 'disjunction)
-> top:'conjunction
-> bot:'disjunction
-> t
-> 'disjunction
val vars : t -> Var.t iter val vars : t -> Var.t iter
(** Query *) (** Query *)

@ -9,9 +9,6 @@ type var = Var.t
type trm = Trm.t [@@deriving compare, equal, sexp] type trm = Trm.t [@@deriving compare, equal, sexp]
type fml = Fml.t [@@deriving compare, equal, sexp] type fml = Fml.t [@@deriving compare, equal, sexp]
let map_pos_neg f e cons ~pos ~neg =
map2 (Fml.Set.map ~f) e (fun pos neg -> cons ~pos ~neg) pos neg
(** Conditional terms, denoting functions from structures to values, taking (** Conditional terms, denoting functions from structures to values, taking
the form of trees with internal nodes labeled with formulas and leaves the form of trees with internal nodes labeled with formulas and leaves
labeled with terms. *) labeled with terms. *)
@ -410,8 +407,8 @@ module Formula = struct
| Eq0 x -> lift_map1 f b Fml.eq0 x | Eq0 x -> lift_map1 f b Fml.eq0 x
| Pos x -> lift_map1 f b Fml.pos x | Pos x -> lift_map1 f b Fml.pos x
| Not x -> map1 (map_terms ~f) b Fml.not_ x | Not x -> map1 (map_terms ~f) b Fml.not_ x
| And {pos; neg} -> map_pos_neg (map_terms ~f) b Fml.andN ~pos ~neg | And {pos; neg} -> Fml.map_pos_neg (map_terms ~f) b Fml.andN ~pos ~neg
| Or {pos; neg} -> map_pos_neg (map_terms ~f) b Fml.orN ~pos ~neg | Or {pos; neg} -> Fml.map_pos_neg (map_terms ~f) b Fml.orN ~pos ~neg
| Iff (x, y) -> map2 (map_terms ~f) b Fml.iff x y | Iff (x, y) -> map2 (map_terms ~f) b Fml.iff x y
| Cond {cnd; pos; neg} -> | Cond {cnd; pos; neg} ->
map3 (map_terms ~f) b map3 (map_terms ~f) b
@ -430,39 +427,6 @@ module Formula = struct
(e', !s) (e', !s)
let rename s e = map_vars ~f:(Var.Subst.apply s) e let rename s e = map_vars ~f:(Var.Subst.apply s) e
let fold_pos_neg ~pos ~neg s ~f =
let f_not p s = f (Fml.not_ p) s in
Fml.Set.fold ~f:f_not neg (Fml.Set.fold ~f pos s)
let fold_dnf :
meet1:('literal -> 'conjunction -> 'conjunction)
-> join1:('conjunction -> 'disjunction -> 'disjunction)
-> top:'conjunction
-> bot:'disjunction
-> 'formula
-> 'disjunction =
fun ~meet1 ~join1 ~top ~bot fml ->
let rec add_conjunct fml (cjn, splits) =
match fml with
| Tt | Eq _ | Eq0 _ | Pos _ | Iff _ | Lit _ | Not _ ->
(meet1 fml cjn, splits)
| And {pos; neg} ->
fold_pos_neg ~f:add_conjunct ~pos ~neg (cjn, splits)
| Or {pos; neg} -> (cjn, (pos, neg) :: splits)
| Cond {cnd; pos; neg} ->
add_conjunct
(or_ (and_ cnd pos) (and_ (not_ cnd) neg))
(cjn, splits)
in
let rec add_disjunct (cjn, splits) fml djn =
let cjn, splits = add_conjunct fml (cjn, splits) in
match splits with
| (pos, neg) :: splits ->
fold_pos_neg ~f:(add_disjunct (cjn, splits)) ~pos ~neg djn
| [] -> join1 cjn djn
in
add_disjunct (top, []) fml bot
end end
(* (*

Loading…
Cancel
Save