diff --git a/sledge/lib/import/qset.ml b/sledge/lib/import/qset.ml index b598b9983..e2e89423b 100644 --- a/sledge/lib/import/qset.ml +++ b/sledge/lib/import/qset.ml @@ -80,6 +80,13 @@ struct let pop = M.pop let min_elt = M.min_elt let pop_min_elt = M.pop_min_elt + + let classify s = + match pop s with + | None -> `Zero + | Some (elt, q, s') when is_empty s' -> `One (elt, q) + | _ -> `Many + let to_list m = M.to_alist m let iter m ~f = M.iteri ~f:(fun ~key ~data -> f key data) m let exists m ~f = M.existsi ~f:(fun ~key ~data -> f key data) m diff --git a/sledge/lib/import/qset_intf.ml b/sledge/lib/import/qset_intf.ml index 9aeaf218a..cf0067b61 100644 --- a/sledge/lib/import/qset_intf.ml +++ b/sledge/lib/import/qset_intf.ml @@ -65,6 +65,9 @@ module type S = sig val pop_min_elt : t -> (elt * Q.t * t) option (** Find and remove minimum element. [O(log n)]. *) + val classify : t -> [`Zero | `One of elt * Q.t | `Many] + (** Classify a set as either empty, singleton, or otherwise. *) + val find_and_remove : t -> elt -> (Q.t * t) option (** Find and remove an element. *) diff --git a/sledge/lib/term.ml b/sledge/lib/term.ml index 26b90ffa4..271395968 100644 --- a/sledge/lib/term.ml +++ b/sledge/lib/term.ml @@ -480,16 +480,16 @@ module Sum = struct else Qset.map_counts ~f:(fun _ -> Q.mul const) sum let to_term sum = - match Qset.pop sum with - | None -> zero - | Some (arg, q, sum') when Qset.is_empty sum' -> ( + match Qset.classify sum with + | `Zero -> zero + | `One (arg, q) -> ( match arg with | Integer {data} -> assert (Z.equal Z.one data) ; rational q | _ when Q.equal Q.one q -> arg | _ -> Add sum ) - | _ -> Add sum + | `Many -> Add sum end (* Products of indeterminants represented by multisets. A product ∏ᵢ xᵢ^nᵢ