module SMT.Derived where
open import Cubical.Data.Bool.Base using (true; false)
open import Cubical.Data.Int.Base using (ℤ; pos)
open import Cubical.Data.List.Base using (List; []; _∷_)
open import SMT.Core
z0 z1 z2 z3 : ℤ
z0 = pos 0
z1 = pos 1
z2 = pos 2
z3 = pos 3
int0 int1 int2 int3 : ∀ {Γ} → Expr Γ sInt
int0 = int z0
int1 = int z1
int2 = int z2
int3 = int z3
allBool : ∀ {Γ} → List (Expr Γ sBool) → Expr Γ sBool
allBool [] = bool true
allBool (p ∷ ps) = bAnd p (allBool ps)
anyBool : ∀ {Γ} → List (Expr Γ sBool) → Expr Γ sBool
anyBool [] = bool false
anyBool (p ∷ ps) = bOr p (anyBool ps)
between : ∀ {Γ} → Expr Γ sInt → Expr Γ sInt → Expr Γ sInt → Expr Γ sBool
between lo x hi = bAnd (iLe lo x) (iLe x hi)
iMin : ∀ {Γ} → Expr Γ sInt → Expr Γ sInt → Expr Γ sInt
iMin x y = ite (iLe x y) x y
iMax : ∀ {Γ} → Expr Γ sInt → Expr Γ sInt → Expr Γ sInt
iMax x y = ite (iLe x y) y x
iAbs : ∀ {Γ} → Expr Γ sInt → Expr Γ sInt
iAbs x = ite (iGe x int0) x (iNeg x)
iClamp : ∀ {Γ} → Expr Γ sInt → Expr Γ sInt → Expr Γ sInt → Expr Γ sInt
iClamp lo hi x = iMin hi (iMax lo x)
indicator : ∀ {Γ} → Expr Γ sBool → Expr Γ sInt
indicator p = ite p int1 int0
countTrue : ∀ {Γ} → List (Expr Γ sBool) → Expr Γ sInt
countTrue [] = int0
countTrue (p ∷ ps) = iAdd (indicator p) (countTrue ps)
atLeast : ∀ {Γ} → Expr Γ sInt → List (Expr Γ sBool) → Expr Γ sBool
atLeast n ps = iGe (countTrue ps) n
atMost : ∀ {Γ} → Expr Γ sInt → List (Expr Γ sBool) → Expr Γ sBool
atMost n ps = iLe (countTrue ps) n