@ -95,10 +95,21 @@ let equal_trm x y =
Int . equal i j
| _ -> equal_trm x y
let zero = Z Z . zero
let one = Z Z . one
let _ Neg x = Neg x
let _ Add x y = Add ( x , y )
let _ Add x y =
match ( x , y ) with
| _ , Q q when Q . sign q = 0 -> x
| Q q , _ when Q . sign q = 0 -> y
| _ -> Add ( x , y )
let _ Sub x y = Sub ( x , y )
let _ Mulq q x = Mulq ( q , x )
let _ Mulq q x =
if Q . equal Q . one q then x else if Q . sign q = 0 then zero else Mulq ( q , x )
let _ Splat x = Splat x
let _ Sized seq siz = Sized { seq ; siz }
let _ Extract seq off len = Extract { seq ; off ; len }
@ -108,8 +119,6 @@ let _Update rcd idx elt = Update {rcd; idx; elt}
let _ Tuple es = Tuple es
let _ Project ary idx tup = Project { ary ; idx ; tup }
let _ Apply f a = Apply ( f , a )
let zero = Z Z . zero
let one = Z Z . one
(*
* ( Uninterpreted ) Predicate Symbols
@ -161,6 +170,7 @@ module Fml : sig
val _ Ge0 : trm -> fml
val _ Lt0 : trm -> fml
val _ Le0 : trm -> fml
val _ Not : fml -> fml
val _ And : fml -> fml -> fml
val _ Or : fml -> fml -> fml
val _ Iff : fml -> fml -> fml
@ -197,34 +207,165 @@ end = struct
let _ Tt = Tt
let _ Ff = Ff
let _ Eq x y = if equal_trm x y then Tt else Eq ( x , y )
let _ Dq x y = Dq ( x , y )
let _ Eq0 x = Eq0 x
let _ Dq0 = function
type equal_or_separate = Equal | Separate | Unknown
let equal_or_separate d e : equal_or_separate =
match ( d , e ) with
| Z y , Z z -> if Z . equal y z then Equal else Separate
| Q q , Q r -> if Q . equal q r then Equal else Separate
| Z z , Q q | Q q , Z z ->
if Q . equal ( Q . of_z z ) q then Equal else Separate
| _ -> if equal_trm d e then Equal else Unknown
let _ Eq0 x =
match equal_or_separate zero x with
(* 0 = 0 ==> tt *)
| Equal -> Tt
(* 0 = N ==> ff for N ≢ 0 *)
| Separate -> Ff
| Unknown -> Eq0 x
let _ Dq0 x =
match equal_or_separate zero x with
(* 0 ≠ 0 ==> ff *)
| Z _ as z when z = = zero -> Ff
| Equal -> Ff
(* 0 ≠ N ==> tt for N ≢ 0 *)
| Z _ -> Tt
| t -> Dq0 t
let _ Gt0 x = Gt0 x
let _ Ge0 x = Ge0 x
let _ Lt0 x = Lt0 x
let _ Le0 x = Le0 x
let _ And p q = And ( p , q )
let _ Or p q = Or ( p , q )
let _ Iff p q = Iff ( p , q )
let _ Xor p q = Xor ( p , q )
let _ Cond cnd pos neg =
match ( pos , neg ) with
(* ( p ? tt : ff ) ==> p *)
| Tt , Ff -> cnd
| _ -> Cond { cnd ; pos ; neg }
| Separate -> Tt
| Unknown -> Dq0 x
let _ Eq x y =
if x = = zero then _ Eq0 y
else if y = = zero then _ Eq0 x
else
match equal_or_separate x y with
| Equal -> Tt
| Separate -> Ff
| Unknown -> Eq ( x , y )
let _ Dq x y =
if x = = zero then _ Dq0 y
else if y = = zero then _ Dq0 x
else
match equal_or_separate x y with
| Equal -> Ff
| Separate -> Tt
| Unknown -> Dq ( x , y )
let _ Gt0 = function
| Z z -> if Z . gt z Z . zero then Tt else Ff
| Q q -> if Q . gt q Q . zero then Tt else Ff
| x -> Gt0 x
let _ Ge0 = function
| Z z -> if Z . geq z Z . zero then Tt else Ff
| Q q -> if Q . geq q Q . zero then Tt else Ff
| x -> Ge0 x
let _ Lt0 = function
| Z z -> if Z . lt z Z . zero then Tt else Ff
| Q q -> if Q . lt q Q . zero then Tt else Ff
| x -> Lt0 x
let _ Le0 = function
| Z z -> if Z . leq z Z . zero then Tt else Ff
| Q q -> if Q . leq q Q . zero then Tt else Ff
| x -> Le0 x
let _ UPosLit p x = UPosLit ( p , x )
let _ UNegLit p x = UNegLit ( p , x )
type equal_or_opposite = Equal | Opposite | Unknown
let rec equal_or_opposite p q : equal_or_opposite =
if equal_fml p q then Equal
else if equal_fml p ( _ Not q ) then Opposite
else Unknown
and _ And p q =
match ( p , q ) with
| Tt , p | p , Tt -> p
| Ff , _ | _ , Ff -> Ff
| _ -> (
match equal_or_opposite p q with
| Equal -> p
| Opposite -> Ff
| Unknown -> And ( p , q ) )
and _ Or p q =
match ( p , q ) with
| Ff , p | p , Ff -> p
| Tt , _ | _ , Tt -> Tt
| _ -> (
match equal_or_opposite p q with
| Equal -> p
| Opposite -> Tt
| Unknown -> Or ( p , q ) )
and _ Iff p q =
match ( p , q ) with
| Tt , p | p , Tt -> p
| Ff , p | p , Ff -> _ Not p
| _ -> (
match equal_or_opposite p q with
| Equal -> Tt
| Opposite -> Ff
| Unknown -> Iff ( p , q ) )
and _ Xor p q =
match ( p , q ) with
| Tt , p | p , Tt -> _ Not p
| Ff , p | p , Ff -> p
| _ -> (
match equal_or_opposite p q with
| Equal -> Ff
| Opposite -> Tt
| Unknown -> Xor ( p , q ) )
and _ Not = function
| Tt -> _ Ff
| Ff -> _ Tt
| Eq ( x , y ) -> _ Dq x y
| Dq ( x , y ) -> _ Eq x y
| Eq0 x -> _ Dq0 x
| Dq0 x -> _ Eq0 x
| Gt0 x -> _ Le0 x
| Ge0 x -> _ Lt0 x
| Lt0 x -> _ Ge0 x
| Le0 x -> _ Gt0 x
| And ( x , y ) -> _ Or ( _ Not x ) ( _ Not y )
| Or ( x , y ) -> _ And ( _ Not x ) ( _ Not y )
| Iff ( x , y ) -> _ Xor x y
| Xor ( x , y ) -> _ Iff x y
| Cond { cnd ; pos ; neg } -> _ Cond cnd ( _ Not pos ) ( _ Not neg )
| UPosLit ( p , x ) -> _ UNegLit p x
| UNegLit ( p , x ) -> _ UPosLit p x
and _ Cond cnd pos neg =
match ( cnd , pos , neg ) with
(* ( tt ? p : n ) ==> p *)
| Tt , _ , _ -> pos
(* ( ff ? p : n ) ==> n *)
| Ff , _ , _ -> neg
(* ( c ? tt : ff ) ==> c *)
| _ , Tt , Ff -> cnd
(* ( c ? ff : tt ) ==> ¬c *)
| _ , Ff , Tt -> _ Not cnd
(* ( c ? p : ff ) ==> c ∧ p *)
| _ , _ , Ff -> _ And cnd pos
(* ( c ? ff : n ) ==> ¬c ∧ n *)
| _ , Ff , _ -> _ And ( _ Not cnd ) neg
(* ( c ? tt : n ) ==> c ∨ n *)
| _ , Tt , _ -> _ Or cnd neg
(* ( c ? p : tt ) ==> ¬c ∨ p *)
| _ , _ , Tt -> _ Or ( _ Not cnd ) pos
| _ -> (
match equal_or_opposite pos neg with
(* ( c ? p : p ) ==> c *)
| Equal -> cnd
(* ( c : p : ¬p ) ==> c <=> p *)
| Opposite -> _ Iff cnd pos
| Unknown -> Cond { cnd ; pos ; neg } )
end
open Fml
@ -1005,25 +1146,7 @@ module Formula = struct
let iff = _ Iff
let xor = _ Xor
let cond ~ cnd ~ pos ~ neg = _ Cond cnd pos neg
let rec not_ = function
| Tt -> _ Ff
| Ff -> _ Tt
| Eq ( x , y ) -> _ Dq x y
| Dq ( x , y ) -> _ Eq x y
| Eq0 x -> _ Dq0 x
| Dq0 x -> _ Eq0 x
| Gt0 x -> _ Le0 x
| Ge0 x -> _ Lt0 x
| Lt0 x -> _ Ge0 x
| Le0 x -> _ Gt0 x
| And ( x , y ) -> _ Or ( not_ x ) ( not_ y )
| Or ( x , y ) -> _ And ( not_ x ) ( not_ y )
| Iff ( x , y ) -> _ Xor x y
| Xor ( x , y ) -> _ Iff x y
| Cond { cnd ; pos ; neg } -> _ Cond cnd ( not_ pos ) ( not_ neg )
| UPosLit ( p , x ) -> _ UNegLit p x
| UNegLit ( p , x ) -> _ UPosLit p x
let not_ = _ Not
(* * Query *)