|
|
|
@ -5,7 +5,6 @@
|
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
|
|
|
|
*)
|
|
|
|
|
|
|
|
|
|
open Trm
|
|
|
|
|
open Fml
|
|
|
|
|
|
|
|
|
|
type var = Var.t
|
|
|
|
@ -70,7 +69,7 @@ let rec map_cnd : (fml -> 'a -> 'a -> 'a) -> (trm -> 'a) -> cnd -> 'a =
|
|
|
|
|
let embed_into_cnd : exp -> cnd = function
|
|
|
|
|
| #cnd as c -> c
|
|
|
|
|
(* p ==> (p ? 1 : 0) *)
|
|
|
|
|
| `Fml fml -> `Ite (fml, `Trm one, `Trm zero)
|
|
|
|
|
| `Fml fml -> `Ite (fml, `Trm Trm.one, `Trm Trm.zero)
|
|
|
|
|
|
|
|
|
|
(** Project out a formula that is embedded into a conditional term.
|
|
|
|
|
|
|
|
|
@ -78,7 +77,8 @@ let embed_into_cnd : exp -> cnd = function
|
|
|
|
|
that [project_out_fml (embed_into_cnd (`Fml f)) = Some f]. *)
|
|
|
|
|
let project_out_fml : cnd -> fml option = function
|
|
|
|
|
(* (p ? 1 : 0) ==> p *)
|
|
|
|
|
| `Ite (cnd, `Trm one', `Trm zero') when one == one' && zero == zero' ->
|
|
|
|
|
| `Ite (cnd, `Trm one', `Trm zero')
|
|
|
|
|
when Trm.one == one' && Trm.zero == zero' ->
|
|
|
|
|
Some cnd
|
|
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
|
@ -215,35 +215,41 @@ module Term = struct
|
|
|
|
|
|
|
|
|
|
(* arithmetic *)
|
|
|
|
|
|
|
|
|
|
let zero = `Trm zero
|
|
|
|
|
let one = `Trm one
|
|
|
|
|
let integer z = `Trm (_Z z)
|
|
|
|
|
let rational q = `Trm (_Q q)
|
|
|
|
|
let neg = ap1t @@ fun x -> _Arith Arith.(neg (trm x))
|
|
|
|
|
let zero = `Trm Trm.zero
|
|
|
|
|
let one = `Trm Trm.one
|
|
|
|
|
let integer z = `Trm (Trm.integer z)
|
|
|
|
|
let rational q = `Trm (Trm.rational q)
|
|
|
|
|
let neg = ap1t Trm.neg
|
|
|
|
|
let add = ap2t Trm.add
|
|
|
|
|
let sub = ap2t Trm.sub
|
|
|
|
|
let mulq q = ap1t @@ fun x -> _Arith Arith.(mulc q (trm x))
|
|
|
|
|
let mul = ap2t @@ fun x y -> _Arith (Arith.mul x y)
|
|
|
|
|
let div = ap2t @@ fun x y -> _Arith (Arith.div x y)
|
|
|
|
|
let pow x i = (ap1t @@ fun x -> _Arith (Arith.pow x i)) x
|
|
|
|
|
let mulq q = ap1t (Trm.mulq q)
|
|
|
|
|
let mul = ap2t Trm.mul
|
|
|
|
|
let div = ap2t Trm.div
|
|
|
|
|
let pow x i = (ap1t @@ fun x -> Trm.pow x i) x
|
|
|
|
|
|
|
|
|
|
(* sequences *)
|
|
|
|
|
|
|
|
|
|
let splat = ap1t _Splat
|
|
|
|
|
let sized ~seq ~siz = ap2t _Sized seq siz
|
|
|
|
|
let extract ~seq ~off ~len = ap3t _Extract seq off len
|
|
|
|
|
let concat elts = apNt _Concat elts
|
|
|
|
|
let splat = ap1t Trm.splat
|
|
|
|
|
let sized ~seq ~siz = ap2t (fun seq siz -> Trm.sized ~seq ~siz) seq siz
|
|
|
|
|
|
|
|
|
|
let extract ~seq ~off ~len =
|
|
|
|
|
ap3t (fun seq off len -> Trm.extract ~seq ~off ~len) seq off len
|
|
|
|
|
|
|
|
|
|
let concat elts = apNt Trm.concat elts
|
|
|
|
|
|
|
|
|
|
(* records *)
|
|
|
|
|
|
|
|
|
|
let select ~rcd ~idx = ap1t (_Select idx) rcd
|
|
|
|
|
let update ~rcd ~idx ~elt = ap2t (_Update idx) rcd elt
|
|
|
|
|
let record elts = apNt _Record elts
|
|
|
|
|
let ancestor i = `Trm (_Ancestor i)
|
|
|
|
|
let select ~rcd ~idx = ap1t (fun rcd -> Trm.select ~rcd ~idx) rcd
|
|
|
|
|
|
|
|
|
|
let update ~rcd ~idx ~elt =
|
|
|
|
|
ap2t (fun rcd elt -> Trm.update ~rcd ~idx ~elt) rcd elt
|
|
|
|
|
|
|
|
|
|
let record elts = apNt Trm.record elts
|
|
|
|
|
let ancestor i = `Trm (Trm.ancestor i)
|
|
|
|
|
|
|
|
|
|
(* uninterpreted *)
|
|
|
|
|
|
|
|
|
|
let apply sym args = apNt (_Apply sym) args
|
|
|
|
|
let apply sym args = apNt (Trm.apply sym) args
|
|
|
|
|
|
|
|
|
|
(* if-then-else *)
|
|
|
|
|
|
|
|
|
@ -251,21 +257,23 @@ module Term = struct
|
|
|
|
|
|
|
|
|
|
(** Destruct *)
|
|
|
|
|
|
|
|
|
|
let d_int = function `Trm (Z z) -> Some z | _ -> None
|
|
|
|
|
let d_int e = match (e : t) with `Trm (Z z) -> Some z | _ -> None
|
|
|
|
|
|
|
|
|
|
let get_const = function
|
|
|
|
|
let get_const e =
|
|
|
|
|
match (e : t) with
|
|
|
|
|
| `Trm (Z z) -> Some (Q.of_z z)
|
|
|
|
|
| `Trm (Q q) -> Some q
|
|
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
|
|
(** Access *)
|
|
|
|
|
|
|
|
|
|
let split_const = function
|
|
|
|
|
let split_const e =
|
|
|
|
|
match (e : t) with
|
|
|
|
|
| `Trm (Z z) -> (zero, Q.of_z z)
|
|
|
|
|
| `Trm (Q q) -> (zero, q)
|
|
|
|
|
| `Trm (Arith a) ->
|
|
|
|
|
let a_c, c = Arith.split_const a in
|
|
|
|
|
(`Trm (_Arith a_c), c)
|
|
|
|
|
let a_c, c = Trm.Arith.split_const a in
|
|
|
|
|
(`Trm (Trm.arith a_c), c)
|
|
|
|
|
| e -> (e, Q.zero)
|
|
|
|
|
|
|
|
|
|
(** Traverse *)
|
|
|
|
@ -464,10 +472,10 @@ let vs_to_ses : Var.Set.t -> Ses.Var.Set.t =
|
|
|
|
|
fun vs -> Ses.Var.Set.of_iter (Iter.map ~f:v_to_ses (Var.Set.to_iter vs))
|
|
|
|
|
|
|
|
|
|
let rec arith_to_ses poly =
|
|
|
|
|
Arith.fold_monomials poly Ses.Term.zero ~f:(fun mono coeff e ->
|
|
|
|
|
Trm.Arith.fold_monomials poly Ses.Term.zero ~f:(fun mono coeff e ->
|
|
|
|
|
Ses.Term.add e
|
|
|
|
|
(Ses.Term.mulq coeff
|
|
|
|
|
(Arith.fold_factors mono Ses.Term.one ~f:(fun trm pow f ->
|
|
|
|
|
(Trm.Arith.fold_factors mono Ses.Term.one ~f:(fun trm pow f ->
|
|
|
|
|
let rec exp b i =
|
|
|
|
|
assert (i > 0) ;
|
|
|
|
|
if i = 1 then b else Ses.Term.mul b (exp f (i - 1))
|
|
|
|
@ -544,8 +552,8 @@ let v_of_ses : Ses.Var.t -> var =
|
|
|
|
|
let vs_of_ses : Ses.Var.Set.t -> Var.Set.t =
|
|
|
|
|
fun vs -> Var.Set.of_iter (Iter.map ~f:v_of_ses (Ses.Var.Set.to_iter vs))
|
|
|
|
|
|
|
|
|
|
let uap1 f = ap1t (fun x -> _Apply f [|x|])
|
|
|
|
|
let uap2 f = ap2t (fun x y -> _Apply f [|x; y|])
|
|
|
|
|
let uap1 f = ap1t (fun x -> Trm.apply f [|x|])
|
|
|
|
|
let uap2 f = ap2t (fun x y -> Trm.apply f [|x; y|])
|
|
|
|
|
let litN p = apNf (_Lit p)
|
|
|
|
|
|
|
|
|
|
let rec uap_tt f a = uap1 f (of_ses a)
|
|
|
|
|