{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
module What4.Expr.MATLAB
( MatlabSolverFn(..)
, matlabSolverArgTypes
, matlabSolverReturnType
, ppMatlabSolverFn
, evalMatlabSolverFn
, testSolverFnEq
, traverseMatlabSolverFn
, MatlabSymbolicArrayBuilder(..)
, clampedIntAdd
, clampedIntSub
, clampedIntMul
, clampedIntNeg
, clampedIntAbs
, clampedUIntAdd
, clampedUIntSub
, clampedUIntMul
) where
import Control.Monad (join)
import qualified Data.BitVector.Sized as BV
import Data.Kind (Type)
import Data.Hashable
import Data.Parameterized.Classes
import Data.Parameterized.Context as Ctx
import Data.Parameterized.TH.GADT
import Data.Parameterized.TraversableFC
import Text.PrettyPrint.ANSI.Leijen hiding ((<$>))
import What4.BaseTypes
import What4.Interface
import What4.Utils.Complex
import What4.Utils.OnlyNatRepr
clampedIntAdd :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> SymBV sym w
-> IO (SymBV sym w)
clampedIntAdd sym x y = do
let w = bvWidth x
withAddPrefixLeq w (knownNat :: NatRepr 1) $ do
let w' = incNat w
x' <- bvSext sym w' x
y' <- bvSext sym w' y
r' <- bvAdd sym x' y'
too_high <- bvSgt sym r' =<< bvLit sym w' (BV.maxSigned w')
max_int <- bvLit sym w (BV.maxSigned w)
too_low <- bvSlt sym r' =<< bvLit sym w' (BV.minSigned w')
min_int <- bvLit sym w (BV.minSigned w)
r <- bvTrunc sym w r'
r_low <- bvIte sym too_low min_int r
bvIte sym too_high max_int r_low
clampedIntSub :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> SymBV sym w
-> IO (SymBV sym w)
clampedIntSub sym x y = do
let w = bvWidth x
(ov, xy) <- subSignedOF sym x y
ysign <- bvIsNeg sym y
minint <- minSignedBV sym w
maxint <- maxSignedBV sym w
ov_val <- bvIte sym ysign maxint minint
bvIte sym ov ov_val xy
clampedIntMul :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> SymBV sym w
-> IO (SymBV sym w)
clampedIntMul sym x y = do
let w = bvWidth x
(hi,lo) <- signedWideMultiplyBV sym x y
zro <- bvLit sym w (BV.zero w)
ones <- maxUnsignedBV sym w
ok_pos <- join $ andPred sym <$> (notPred sym =<< bvIsNeg sym lo)
<*> bvEq sym hi zro
ok_neg <- join $ andPred sym <$> bvIsNeg sym lo
<*> bvEq sym hi ones
ov <- notPred sym =<< orPred sym ok_pos ok_neg
minint <- minSignedBV sym w
maxint <- maxSignedBV sym w
hisign <- bvIsNeg sym hi
ov_val <- bvIte sym hisign minint maxint
bvIte sym ov ov_val lo
clampedIntNeg :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> IO (SymBV sym w)
clampedIntNeg sym x = do
let w = bvWidth x
minint <- minSignedBV sym w
p <- bvEq sym x minint
iteM bvIte sym p (maxSignedBV sym w) (bvNeg sym x)
clampedIntAbs :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> IO (SymBV sym w)
clampedIntAbs sym x = do
isNeg <- bvIsNeg sym x
iteM bvIte sym isNeg (clampedIntNeg sym x) (pure x)
clampedUIntAdd :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> SymBV sym w
-> IO (SymBV sym w)
clampedUIntAdd sym x y = do
let w = bvWidth x
(ov, xy) <- addUnsignedOF sym x y
maxint <- maxUnsignedBV sym w
bvIte sym ov maxint xy
clampedUIntSub :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> SymBV sym w
-> IO (SymBV sym w)
clampedUIntSub sym x y = do
let w = bvWidth x
no_underflow <- bvUge sym x y
iteM bvIte
sym
no_underflow
(bvSub sym x y)
(bvLit sym w (BV.zero w))
clampedUIntMul :: (IsExprBuilder sym, 1 <= w)
=> sym
-> SymBV sym w
-> SymBV sym w
-> IO (SymBV sym w)
clampedUIntMul sym x y = do
let w = bvWidth x
(hi, lo) <- unsignedWideMultiplyBV sym x y
maxint <- maxUnsignedBV sym w
ov <- bvIsNonzero sym hi
bvIte sym ov maxint lo
data MatlabSolverFn (f :: BaseType -> Type) args ret where
BoolOrFn :: MatlabSolverFn f (EmptyCtx ::> BaseBoolType ::> BaseBoolType) BaseBoolType
IsIntegerFn :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseBoolType
NatLeFn :: MatlabSolverFn f (EmptyCtx ::> BaseNatType ::> BaseNatType) BaseBoolType
IntLeFn :: MatlabSolverFn f (EmptyCtx ::> BaseIntegerType ::> BaseIntegerType) BaseBoolType
BVToNatFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) BaseNatType
SBVToIntegerFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) BaseIntegerType
NatToIntegerFn :: MatlabSolverFn f (EmptyCtx ::> BaseNatType) BaseIntegerType
IntegerToNatFn :: MatlabSolverFn f (EmptyCtx ::> BaseIntegerType) BaseNatType
IntegerToRealFn :: MatlabSolverFn f (EmptyCtx ::> BaseIntegerType) BaseRealType
RealToIntegerFn :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseIntegerType
PredToIntegerFn :: MatlabSolverFn f (EmptyCtx ::> BaseBoolType) BaseIntegerType
NatSeqFn :: !(f BaseNatType)
-> !(f BaseNatType)
-> MatlabSolverFn f (EmptyCtx ::> BaseNatType ::> BaseNatType) BaseNatType
RealSeqFn :: !(f BaseRealType)
-> !(f BaseRealType)
-> MatlabSolverFn f (EmptyCtx ::> BaseNatType ::> BaseNatType) BaseRealType
IndicesInRange :: !(Assignment OnlyNatRepr (idx ::> itp))
-> !(Assignment f (idx ::> itp))
-> MatlabSolverFn f (idx ::> itp) BaseBoolType
IsEqFn :: !(BaseTypeRepr tp)
-> MatlabSolverFn f (EmptyCtx ::> tp ::> tp) BaseBoolType
BVIsNonZeroFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) BaseBoolType
ClampedIntNegFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) (BaseBVType w)
ClampedIntAbsFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) (BaseBVType w)
ClampedIntAddFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f
(EmptyCtx ::> BaseBVType w ::> BaseBVType w)
(BaseBVType w)
ClampedIntSubFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f
(EmptyCtx ::> BaseBVType w ::> BaseBVType w)
(BaseBVType w)
ClampedIntMulFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f
(EmptyCtx ::> BaseBVType w ::> BaseBVType w)
(BaseBVType w)
ClampedUIntAddFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f
(EmptyCtx ::> BaseBVType w ::> BaseBVType w)
(BaseBVType w)
ClampedUIntSubFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f
(EmptyCtx ::> BaseBVType w ::> BaseBVType w)
(BaseBVType w)
ClampedUIntMulFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f
(EmptyCtx ::> BaseBVType w ::> BaseBVType w)
(BaseBVType w)
IntSetWidthFn :: (1 <= m, 1 <= n)
=> !(NatRepr m)
-> !(NatRepr n)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
UIntSetWidthFn :: (1 <= m, 1 <= n)
=> !(NatRepr m)
-> !(NatRepr n)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
UIntToIntFn :: (1 <= m, 1 <= n)
=> !(NatRepr m)
-> !(NatRepr n)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
IntToUIntFn :: (1 <= m, 1 <= n)
=> !(NatRepr m)
-> !(NatRepr n)
-> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
RealIsNonZeroFn :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseBoolType
RealCosFn :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseRealType
RealSinFn :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseRealType
RealToSBVFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseRealType) (BaseBVType w)
RealToUBVFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseRealType) (BaseBVType w)
PredToBVFn :: (1 <= w)
=> !(NatRepr w)
-> MatlabSolverFn f (EmptyCtx ::> BaseBoolType) (BaseBVType w)
CplxIsNonZeroFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseBoolType
CplxIsRealFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseBoolType
RealToComplexFn :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseComplexType
RealPartOfCplxFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseRealType
ImagPartOfCplxFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseRealType
CplxNegFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
CplxAddFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType ::> BaseComplexType)
BaseComplexType
CplxSubFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType ::> BaseComplexType)
BaseComplexType
CplxMulFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType ::> BaseComplexType)
BaseComplexType
CplxRoundFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
CplxFloorFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
CplxCeilFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
CplxMagFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseRealType
CplxSqrtFn :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
CplxExpFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType)
BaseComplexType
CplxLogFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType)
BaseComplexType
CplxLogBaseFn :: !Integer
-> MatlabSolverFn f
(EmptyCtx ::> BaseComplexType)
BaseComplexType
CplxSinFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType)
BaseComplexType
CplxCosFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType)
BaseComplexType
CplxTanFn :: MatlabSolverFn f
(EmptyCtx ::> BaseComplexType)
BaseComplexType
$(return [])
traverseMatlabSolverFn :: Applicative m
=> (forall tp . e tp -> m (f tp))
-> MatlabSolverFn e a r
-> m (MatlabSolverFn f a r)
traverseMatlabSolverFn f fn_id =
case fn_id of
BoolOrFn -> pure $ BoolOrFn
IsIntegerFn -> pure $ IsIntegerFn
NatLeFn -> pure $ NatLeFn
IntLeFn -> pure $ IntLeFn
BVToNatFn w -> pure $ BVToNatFn w
SBVToIntegerFn w -> pure $ SBVToIntegerFn w
NatToIntegerFn -> pure $ NatToIntegerFn
IntegerToNatFn -> pure $ IntegerToNatFn
IntegerToRealFn -> pure $ IntegerToRealFn
RealToIntegerFn -> pure $ RealToIntegerFn
PredToIntegerFn -> pure $ PredToIntegerFn
NatSeqFn b i -> NatSeqFn <$> f b <*> f i
RealSeqFn b i -> RealSeqFn <$> f b <*> f i
IndicesInRange tps a -> IndicesInRange tps <$> traverseFC f a
IsEqFn tp -> pure $ IsEqFn tp
BVIsNonZeroFn w -> pure $ BVIsNonZeroFn w
ClampedIntNegFn w -> pure $ ClampedIntNegFn w
ClampedIntAbsFn w -> pure $ ClampedIntAbsFn w
ClampedIntAddFn w -> pure $ ClampedIntAddFn w
ClampedIntSubFn w -> pure $ ClampedIntSubFn w
ClampedIntMulFn w -> pure $ ClampedIntMulFn w
ClampedUIntAddFn w -> pure $ ClampedUIntAddFn w
ClampedUIntSubFn w -> pure $ ClampedUIntSubFn w
ClampedUIntMulFn w -> pure $ ClampedUIntMulFn w
IntSetWidthFn i o -> pure $ IntSetWidthFn i o
UIntSetWidthFn i o -> pure $ UIntSetWidthFn i o
UIntToIntFn i o -> pure $ UIntToIntFn i o
IntToUIntFn i o -> pure $ IntToUIntFn i o
RealCosFn -> pure $ RealCosFn
RealSinFn -> pure $ RealSinFn
RealIsNonZeroFn -> pure $ RealIsNonZeroFn
RealToSBVFn w -> pure $ RealToSBVFn w
RealToUBVFn w -> pure $ RealToUBVFn w
PredToBVFn w -> pure $ PredToBVFn w
CplxIsNonZeroFn -> pure $ CplxIsNonZeroFn
CplxIsRealFn -> pure $ CplxIsRealFn
RealToComplexFn -> pure $ RealToComplexFn
RealPartOfCplxFn -> pure $ RealPartOfCplxFn
ImagPartOfCplxFn -> pure $ ImagPartOfCplxFn
CplxNegFn -> pure $ CplxNegFn
CplxAddFn -> pure $ CplxAddFn
CplxSubFn -> pure $ CplxSubFn
CplxMulFn -> pure $ CplxMulFn
CplxRoundFn -> pure $ CplxRoundFn
CplxFloorFn -> pure $ CplxFloorFn
CplxCeilFn -> pure $ CplxCeilFn
CplxMagFn -> pure $ CplxMagFn
CplxSqrtFn -> pure $ CplxSqrtFn
CplxExpFn -> pure $ CplxExpFn
CplxLogFn -> pure $ CplxLogFn
CplxLogBaseFn b -> pure $ CplxLogBaseFn b
CplxSinFn -> pure $ CplxSinFn
CplxCosFn -> pure $ CplxCosFn
CplxTanFn -> pure $ CplxTanFn
binCtx :: BaseTypeRepr tp -> Ctx.Assignment BaseTypeRepr (EmptyCtx ::> tp ::> tp)
binCtx tp = Ctx.empty Ctx.:> tp Ctx.:> tp
matlabSolverArgTypes :: MatlabSolverFn f args ret -> Assignment BaseTypeRepr args
matlabSolverArgTypes f =
case f of
BoolOrFn -> knownRepr
IsIntegerFn -> knownRepr
NatLeFn -> knownRepr
IntLeFn -> knownRepr
BVToNatFn w -> Ctx.singleton (BaseBVRepr w)
SBVToIntegerFn w -> Ctx.singleton (BaseBVRepr w)
NatToIntegerFn -> knownRepr
IntegerToNatFn -> knownRepr
IntegerToRealFn -> knownRepr
RealToIntegerFn -> knownRepr
PredToIntegerFn -> knownRepr
NatSeqFn{} -> knownRepr
IndicesInRange tps _ -> fmapFC toBaseTypeRepr tps
RealSeqFn _ _ -> knownRepr
IsEqFn tp -> binCtx tp
BVIsNonZeroFn w -> Ctx.singleton (BaseBVRepr w)
ClampedIntNegFn w -> Ctx.singleton (BaseBVRepr w)
ClampedIntAbsFn w -> Ctx.singleton (BaseBVRepr w)
ClampedIntAddFn w -> binCtx (BaseBVRepr w)
ClampedIntSubFn w -> binCtx (BaseBVRepr w)
ClampedIntMulFn w -> binCtx (BaseBVRepr w)
ClampedUIntAddFn w -> binCtx (BaseBVRepr w)
ClampedUIntSubFn w -> binCtx (BaseBVRepr w)
ClampedUIntMulFn w -> binCtx (BaseBVRepr w)
IntSetWidthFn i _ -> Ctx.singleton (BaseBVRepr i)
UIntSetWidthFn i _ -> Ctx.singleton (BaseBVRepr i)
UIntToIntFn i _ -> Ctx.singleton (BaseBVRepr i)
IntToUIntFn i _ -> Ctx.singleton (BaseBVRepr i)
RealCosFn -> knownRepr
RealSinFn -> knownRepr
RealIsNonZeroFn -> knownRepr
RealToSBVFn _ -> knownRepr
RealToUBVFn _ -> knownRepr
PredToBVFn _ -> knownRepr
CplxIsNonZeroFn -> knownRepr
CplxIsRealFn -> knownRepr
RealToComplexFn -> knownRepr
RealPartOfCplxFn -> knownRepr
ImagPartOfCplxFn -> knownRepr
CplxNegFn -> knownRepr
CplxAddFn -> knownRepr
CplxSubFn -> knownRepr
CplxMulFn -> knownRepr
CplxRoundFn -> knownRepr
CplxFloorFn -> knownRepr
CplxCeilFn -> knownRepr
CplxMagFn -> knownRepr
CplxSqrtFn -> knownRepr
CplxExpFn -> knownRepr
CplxLogFn -> knownRepr
CplxLogBaseFn _ -> knownRepr
CplxSinFn -> knownRepr
CplxCosFn -> knownRepr
CplxTanFn -> knownRepr
matlabSolverReturnType :: MatlabSolverFn f args ret -> BaseTypeRepr ret
matlabSolverReturnType f =
case f of
BoolOrFn -> knownRepr
IsIntegerFn -> knownRepr
NatLeFn -> knownRepr
IntLeFn -> knownRepr
BVToNatFn{} -> knownRepr
SBVToIntegerFn{} -> knownRepr
NatToIntegerFn -> knownRepr
IntegerToNatFn -> knownRepr
IntegerToRealFn -> knownRepr
RealToIntegerFn -> knownRepr
PredToIntegerFn -> knownRepr
NatSeqFn{} -> knownRepr
IndicesInRange{} -> knownRepr
RealSeqFn _ _ -> knownRepr
IsEqFn{} -> knownRepr
BVIsNonZeroFn _ -> knownRepr
ClampedIntNegFn w -> BaseBVRepr w
ClampedIntAbsFn w -> BaseBVRepr w
ClampedIntAddFn w -> BaseBVRepr w
ClampedIntSubFn w -> BaseBVRepr w
ClampedIntMulFn w -> BaseBVRepr w
ClampedUIntAddFn w -> BaseBVRepr w
ClampedUIntSubFn w -> BaseBVRepr w
ClampedUIntMulFn w -> BaseBVRepr w
IntSetWidthFn _ o -> BaseBVRepr o
UIntSetWidthFn _ o -> BaseBVRepr o
UIntToIntFn _ o -> BaseBVRepr o
IntToUIntFn _ o -> BaseBVRepr o
RealCosFn -> knownRepr
RealSinFn -> knownRepr
RealIsNonZeroFn -> knownRepr
RealToSBVFn w -> BaseBVRepr w
RealToUBVFn w -> BaseBVRepr w
PredToBVFn w -> BaseBVRepr w
CplxIsNonZeroFn -> knownRepr
CplxIsRealFn -> knownRepr
RealToComplexFn -> knownRepr
RealPartOfCplxFn -> knownRepr
ImagPartOfCplxFn -> knownRepr
CplxNegFn -> knownRepr
CplxAddFn -> knownRepr
CplxSubFn -> knownRepr
CplxMulFn -> knownRepr
CplxRoundFn -> knownRepr
CplxFloorFn -> knownRepr
CplxCeilFn -> knownRepr
CplxMagFn -> knownRepr
CplxSqrtFn -> knownRepr
CplxExpFn -> knownRepr
CplxLogFn -> knownRepr
CplxLogBaseFn _ -> knownRepr
CplxSinFn -> knownRepr
CplxCosFn -> knownRepr
CplxTanFn -> knownRepr
ppMatlabSolverFn :: IsExpr f => MatlabSolverFn f a r -> Doc
ppMatlabSolverFn f =
case f of
BoolOrFn -> text "bool_or"
IsIntegerFn -> text "is_integer"
NatLeFn -> text "nat_le"
IntLeFn -> text "int_le"
BVToNatFn w -> parens $ text "bv_to_nat" <+> text (show w)
SBVToIntegerFn w -> parens $ text "sbv_to_int" <+> text (show w)
NatToIntegerFn -> text "nat_to_integer"
IntegerToNatFn -> text "integer_to_nat"
IntegerToRealFn -> text "integer_to_real"
RealToIntegerFn -> text "real_to_integer"
PredToIntegerFn -> text "pred_to_integer"
NatSeqFn b i -> parens $ text "nat_seq" <+> printSymExpr b <+> printSymExpr i
RealSeqFn b i -> parens $ text "real_seq" <+> printSymExpr b <+> printSymExpr i
IndicesInRange _ bnds ->
parens (text "indices_in_range" <+> sep (toListFC printSymExpr bnds))
IsEqFn{} -> text "is_eq"
BVIsNonZeroFn w -> parens $ text "bv_is_nonzero" <+> text (show w)
ClampedIntNegFn w -> parens $ text "clamped_int_neg" <+> text (show w)
ClampedIntAbsFn w -> parens $ text "clamped_neg_abs" <+> text (show w)
ClampedIntAddFn w -> parens $ text "clamped_int_add" <+> text (show w)
ClampedIntSubFn w -> parens $ text "clamped_int_sub" <+> text (show w)
ClampedIntMulFn w -> parens $ text "clamped_int_mul" <+> text (show w)
ClampedUIntAddFn w -> parens $ text "clamped_uint_add" <+> text (show w)
ClampedUIntSubFn w -> parens $ text "clamped_uint_sub" <+> text (show w)
ClampedUIntMulFn w -> parens $ text "clamped_uint_mul" <+> text (show w)
IntSetWidthFn i o -> parens $ text "int_set_width" <+> text (show i) <+> text (show o)
UIntSetWidthFn i o -> parens $ text "uint_set_width" <+> text (show i) <+> text (show o)
UIntToIntFn i o -> parens $ text "uint_to_int" <+> text (show i) <+> text (show o)
IntToUIntFn i o -> parens $ text "int_to_uint" <+> text (show i) <+> text (show o)
RealCosFn -> text "real_cos"
RealSinFn -> text "real_sin"
RealIsNonZeroFn -> text "real_is_nonzero"
RealToSBVFn w -> parens $ text "real_to_sbv" <+> text (show w)
RealToUBVFn w -> parens $ text "real_to_sbv" <+> text (show w)
PredToBVFn w -> parens $ text "pred_to_bv" <+> text (show w)
CplxIsNonZeroFn -> text "cplx_is_nonzero"
CplxIsRealFn -> text "cplx_is_real"
RealToComplexFn -> text "real_to_complex"
RealPartOfCplxFn -> text "real_part_of_complex"
ImagPartOfCplxFn -> text "imag_part_of_complex"
CplxNegFn -> text "cplx_neg"
CplxAddFn -> text "cplx_add"
CplxSubFn -> text "cplx_sub"
CplxMulFn -> text "cplx_mul"
CplxRoundFn -> text "cplx_round"
CplxFloorFn -> text "cplx_floor"
CplxCeilFn -> text "cplx_ceil"
CplxMagFn -> text "cplx_mag"
CplxSqrtFn -> text "cplx_sqrt"
CplxExpFn -> text "cplx_exp"
CplxLogFn -> text "cplx_log"
CplxLogBaseFn b -> parens $ text "cplx_log_base" <+> text (show b)
CplxSinFn -> text "cplx_sin"
CplxCosFn -> text "cplx_cos"
CplxTanFn -> text "cplx_tan"
testSolverFnEq :: TestEquality f
=> MatlabSolverFn f ax rx
-> MatlabSolverFn f ay ry
-> Maybe ((ax ::> rx) :~: (ay ::> ry))
testSolverFnEq = $(structuralTypeEquality [t|MatlabSolverFn|]
[ ( DataArg 0 `TypeApp` AnyType
, [|testEquality|]
)
, ( ConType [t|NatRepr|] `TypeApp` AnyType
, [|testEquality|]
)
, ( ConType [t|Assignment|] `TypeApp` AnyType `TypeApp` AnyType
, [|testEquality|]
)
, ( ConType [t|BaseTypeRepr|] `TypeApp` AnyType
, [|testEquality|]
)
]
)
instance ( Hashable (f BaseNatType)
, Hashable (f BaseRealType)
, HashableF f
)
=> Hashable (MatlabSolverFn f args tp) where
hashWithSalt = $(structuralHashWithSalt [t|MatlabSolverFn|] [])
realIsNonZero :: IsExprBuilder sym => sym -> SymReal sym -> IO (Pred sym)
realIsNonZero sym = realNe sym (realZero sym)
evalMatlabSolverFn :: forall sym args ret
. IsExprBuilder sym
=> MatlabSolverFn (SymExpr sym) args ret
-> sym
-> Assignment (SymExpr sym) args
-> IO (SymExpr sym ret)
evalMatlabSolverFn f sym =
case f of
BoolOrFn -> uncurryAssignment $ orPred sym
IsIntegerFn -> uncurryAssignment $ isInteger sym
NatLeFn -> uncurryAssignment $ natLe sym
IntLeFn -> uncurryAssignment $ intLe sym
BVToNatFn{} -> uncurryAssignment $ bvToNat sym
SBVToIntegerFn{} -> uncurryAssignment $ sbvToInteger sym
NatToIntegerFn -> uncurryAssignment $ natToInteger sym
IntegerToNatFn -> uncurryAssignment $ integerToNat sym
IntegerToRealFn -> uncurryAssignment $ integerToReal sym
RealToIntegerFn -> uncurryAssignment $ realToInteger sym
PredToIntegerFn -> uncurryAssignment $ \p ->
iteM intIte sym p (intLit sym 1) (intLit sym 0)
NatSeqFn b inc -> uncurryAssignment $ \idx _ -> do
natAdd sym b =<< natMul sym inc idx
RealSeqFn b inc -> uncurryAssignment $ \_ idx -> do
realAdd sym b =<< realMul sym inc =<< natToReal sym idx
IndicesInRange tps0 bnds0 -> \args ->
Ctx.forIndex (Ctx.size tps0) (g tps0 bnds0 args) (pure (truePred sym))
where g :: Assignment OnlyNatRepr ctx
-> Assignment (SymExpr sym) ctx
-> Assignment (SymExpr sym) ctx
-> IO (Pred sym)
-> Index ctx tp
-> IO (Pred sym)
g tps bnds args m i = do
case tps Ctx.! i of
OnlyNatRepr -> do
let v = args ! i
let bnd = bnds ! i
one <- natLit sym 1
p <- join $ andPred sym <$> natLe sym one v <*> natLe sym v bnd
andPred sym p =<< m
IsEqFn{} -> Ctx.uncurryAssignment $ \x y -> do
isEq sym x y
BVIsNonZeroFn _ -> Ctx.uncurryAssignment $ bvIsNonzero sym
ClampedIntNegFn _ -> Ctx.uncurryAssignment $ clampedIntNeg sym
ClampedIntAbsFn _ -> Ctx.uncurryAssignment $ clampedIntAbs sym
ClampedIntAddFn _ -> Ctx.uncurryAssignment $ clampedIntAdd sym
ClampedIntSubFn _ -> Ctx.uncurryAssignment $ clampedIntSub sym
ClampedIntMulFn _ -> Ctx.uncurryAssignment $ clampedIntMul sym
ClampedUIntAddFn _ -> Ctx.uncurryAssignment $ clampedUIntAdd sym
ClampedUIntSubFn _ -> Ctx.uncurryAssignment $ clampedUIntSub sym
ClampedUIntMulFn _ -> Ctx.uncurryAssignment $ clampedUIntMul sym
IntSetWidthFn _ o -> Ctx.uncurryAssignment $ \v -> intSetWidth sym v o
UIntSetWidthFn _ o -> Ctx.uncurryAssignment $ \v -> uintSetWidth sym v o
UIntToIntFn _ o -> Ctx.uncurryAssignment $ \v -> uintToInt sym v o
IntToUIntFn _ o -> Ctx.uncurryAssignment $ \v -> intToUInt sym v o
RealIsNonZeroFn -> Ctx.uncurryAssignment $ realIsNonZero sym
RealCosFn -> Ctx.uncurryAssignment $ realCos sym
RealSinFn -> Ctx.uncurryAssignment $ realSin sym
RealToSBVFn w -> Ctx.uncurryAssignment $ \v -> realToSBV sym v w
RealToUBVFn w -> Ctx.uncurryAssignment $ \v -> realToBV sym v w
PredToBVFn w -> Ctx.uncurryAssignment $ \v -> predToBV sym v w
CplxIsNonZeroFn -> Ctx.uncurryAssignment $ \x -> do
(real_x :+ imag_x) <- cplxGetParts sym x
join $ orPred sym <$> realIsNonZero sym real_x <*> realIsNonZero sym imag_x
CplxIsRealFn -> Ctx.uncurryAssignment $ isReal sym
RealToComplexFn -> Ctx.uncurryAssignment $ cplxFromReal sym
RealPartOfCplxFn -> Ctx.uncurryAssignment $ getRealPart sym
ImagPartOfCplxFn -> Ctx.uncurryAssignment $ getImagPart sym
CplxNegFn -> Ctx.uncurryAssignment $ cplxNeg sym
CplxAddFn -> Ctx.uncurryAssignment $ cplxAdd sym
CplxSubFn -> Ctx.uncurryAssignment $ cplxSub sym
CplxMulFn -> Ctx.uncurryAssignment $ cplxMul sym
CplxRoundFn -> Ctx.uncurryAssignment $ cplxRound sym
CplxFloorFn -> Ctx.uncurryAssignment $ cplxFloor sym
CplxCeilFn -> Ctx.uncurryAssignment $ cplxCeil sym
CplxMagFn -> Ctx.uncurryAssignment $ cplxMag sym
CplxSqrtFn -> Ctx.uncurryAssignment $ cplxSqrt sym
CplxExpFn -> Ctx.uncurryAssignment $ cplxExp sym
CplxLogFn -> Ctx.uncurryAssignment $ cplxLog sym
CplxLogBaseFn b -> Ctx.uncurryAssignment $ cplxLogBase (toRational b) sym
CplxSinFn -> Ctx.uncurryAssignment $ cplxSin sym
CplxCosFn -> Ctx.uncurryAssignment $ cplxCos sym
CplxTanFn -> Ctx.uncurryAssignment $ cplxTan sym
class IsSymExprBuilder sym => MatlabSymbolicArrayBuilder sym where
mkMatlabSolverFn :: sym
-> MatlabSolverFn (SymExpr sym) args ret
-> IO (SymFn sym args ret)