{-# Language FlexibleContexts #-}
{-# Language TypeFamilies #-}
module Cryptol.Backend
( Backend(..)
, sDelay
, invalidIndex
, cryUserError
, cryNoPrimError
, FPArith2
, SRational(..)
, intToRational
, ratio
, rationalAdd
, rationalSub
, rationalNegate
, rationalMul
, rationalRecip
, rationalDivide
, rationalFloor
, rationalCeiling
, rationalTrunc
, rationalRoundAway
, rationalRoundToEven
, rationalEq
, rationalLessThan
, rationalGreaterThan
, iteRational
, ppRational
) where
import Control.Monad.IO.Class
import Data.Kind (Type)
import Data.Ratio ( (%), numerator, denominator )
import Cryptol.Backend.FloatHelpers (BF)
import Cryptol.Backend.Monad ( PPOpts(..), EvalError(..) )
import Cryptol.TypeCheck.AST(Name)
import Cryptol.Utils.PP
invalidIndex :: Backend sym => sym -> Integer -> SEval sym a
invalidIndex :: sym -> Integer -> SEval sym a
invalidIndex sym
sym = sym -> EvalError -> SEval sym a
forall sym a. Backend sym => sym -> EvalError -> SEval sym a
raiseError sym
sym (EvalError -> SEval sym a)
-> (Integer -> EvalError) -> Integer -> SEval sym a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Integer -> EvalError
InvalidIndex (Maybe Integer -> EvalError)
-> (Integer -> Maybe Integer) -> Integer -> EvalError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Maybe Integer
forall a. a -> Maybe a
Just
cryUserError :: Backend sym => sym -> String -> SEval sym a
cryUserError :: sym -> String -> SEval sym a
cryUserError sym
sym = sym -> EvalError -> SEval sym a
forall sym a. Backend sym => sym -> EvalError -> SEval sym a
raiseError sym
sym (EvalError -> SEval sym a)
-> (String -> EvalError) -> String -> SEval sym a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> EvalError
UserError
cryNoPrimError :: Backend sym => sym -> Name -> SEval sym a
cryNoPrimError :: sym -> Name -> SEval sym a
cryNoPrimError sym
sym = sym -> EvalError -> SEval sym a
forall sym a. Backend sym => sym -> EvalError -> SEval sym a
raiseError sym
sym (EvalError -> SEval sym a)
-> (Name -> EvalError) -> Name -> SEval sym a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> EvalError
NoPrim
{-# INLINE sDelay #-}
sDelay :: Backend sym => sym -> Maybe String -> SEval sym a -> SEval sym (SEval sym a)
sDelay :: sym -> Maybe String -> SEval sym a -> SEval sym (SEval sym a)
sDelay sym
sym Maybe String
msg SEval sym a
m =
let msg' :: String
msg' = String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" (String
"while evaluating "String -> String -> String
forall a. [a] -> [a] -> [a]
++) Maybe String
msg
retry :: SEval sym a
retry = sym -> EvalError -> SEval sym a
forall sym a. Backend sym => sym -> EvalError -> SEval sym a
raiseError sym
sym (String -> EvalError
LoopError String
msg')
in sym -> SEval sym a -> SEval sym a -> SEval sym (SEval sym a)
forall sym a.
Backend sym =>
sym -> SEval sym a -> SEval sym a -> SEval sym (SEval sym a)
sDelayFill sym
sym SEval sym a
m SEval sym a
retry
data SRational sym =
SRational
{ SRational sym -> SInteger sym
sNum :: SInteger sym
, SRational sym -> SInteger sym
sDenom :: SInteger sym
}
intToRational :: Backend sym => sym -> SInteger sym -> SEval sym (SRational sym)
intToRational :: sym -> SInteger sym -> SEval sym (SRational sym)
intToRational sym
sym SInteger sym
x = SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
x (SInteger sym -> SRational sym)
-> SEval sym (SInteger sym) -> SEval sym (SRational sym)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
1)
ratio :: Backend sym => sym -> SInteger sym -> SInteger sym -> SEval sym (SRational sym)
ratio :: sym -> SInteger sym -> SInteger sym -> SEval sym (SRational sym)
ratio sym
sym SInteger sym
n SInteger sym
d =
do SBit sym
pz <- sym -> SBit sym -> SEval sym (SBit sym)
forall sym. Backend sym => sym -> SBit sym -> SEval sym (SBit sym)
bitComplement sym
sym (SBit sym -> SEval sym (SBit sym))
-> SEval sym (SBit sym) -> SEval sym (SBit sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
intEq sym
sym SInteger sym
d (SInteger sym -> SEval sym (SBit sym))
-> SEval sym (SInteger sym) -> SEval sym (SBit sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
0
sym -> SBit sym -> EvalError -> SEval sym ()
forall sym.
Backend sym =>
sym -> SBit sym -> EvalError -> SEval sym ()
assertSideCondition sym
sym SBit sym
pz EvalError
DivideByZero
SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
n SInteger sym
d)
rationalRecip :: Backend sym => sym -> SRational sym -> SEval sym (SRational sym)
rationalRecip :: sym -> SRational sym -> SEval sym (SRational sym)
rationalRecip sym
sym (SRational SInteger sym
a SInteger sym
b) = sym -> SInteger sym -> SInteger sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SRational sym)
ratio sym
sym SInteger sym
b SInteger sym
a
rationalDivide :: Backend sym => sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalDivide :: sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalDivide sym
sym SRational sym
x SRational sym
y = sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalMul sym
sym SRational sym
x (SRational sym -> SEval sym (SRational sym))
-> SEval sym (SRational sym) -> SEval sym (SRational sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SRational sym)
rationalRecip sym
sym SRational sym
y
rationalFloor :: Backend sym => sym -> SRational sym -> SEval sym (SInteger sym)
rationalFloor :: sym -> SRational sym -> SEval sym (SInteger sym)
rationalFloor sym
sym (SRational SInteger sym
n SInteger sym
d) = sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intDiv sym
sym SInteger sym
n SInteger sym
d
rationalCeiling :: Backend sym => sym -> SRational sym -> SEval sym (SInteger sym)
rationalCeiling :: sym -> SRational sym -> SEval sym (SInteger sym)
rationalCeiling sym
sym SRational sym
r = sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SInteger sym)
intNegate sym
sym (SInteger sym -> SEval sym (SInteger sym))
-> SEval sym (SInteger sym) -> SEval sym (SInteger sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SRational sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SInteger sym)
rationalFloor sym
sym (SRational sym -> SEval sym (SInteger sym))
-> SEval sym (SRational sym) -> SEval sym (SInteger sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SRational sym)
rationalNegate sym
sym SRational sym
r
rationalTrunc :: Backend sym => sym -> SRational sym -> SEval sym (SInteger sym)
rationalTrunc :: sym -> SRational sym -> SEval sym (SInteger sym)
rationalTrunc sym
sym SRational sym
r =
do SBit sym
p <- sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalLessThan sym
sym SRational sym
r (SRational sym -> SEval sym (SBit sym))
-> SEval sym (SRational sym) -> SEval sym (SBit sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SInteger sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SRational sym)
intToRational sym
sym (SInteger sym -> SEval sym (SRational sym))
-> SEval sym (SInteger sym) -> SEval sym (SRational sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
0
SInteger sym
cr <- sym -> SRational sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SInteger sym)
rationalCeiling sym
sym SRational sym
r
SInteger sym
fr <- sym -> SRational sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SInteger sym)
rationalFloor sym
sym SRational sym
r
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
iteInteger sym
sym SBit sym
p SInteger sym
cr SInteger sym
fr
rationalRoundAway :: Backend sym => sym -> SRational sym -> SEval sym (SInteger sym)
rationalRoundAway :: sym -> SRational sym -> SEval sym (SInteger sym)
rationalRoundAway sym
sym SRational sym
r =
do SBit sym
p <- sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalLessThan sym
sym SRational sym
r (SRational sym -> SEval sym (SBit sym))
-> SEval sym (SRational sym) -> SEval sym (SBit sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SInteger sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SRational sym)
intToRational sym
sym (SInteger sym -> SEval sym (SRational sym))
-> SEval sym (SInteger sym) -> SEval sym (SRational sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
0
SRational sym
half <- SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational (SInteger sym -> SInteger sym -> SRational sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym -> SRational sym)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
1 SEval sym (SInteger sym -> SRational sym)
-> SEval sym (SInteger sym) -> SEval sym (SRational sym)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
2
SInteger sym
cr <- sym -> SRational sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SInteger sym)
rationalCeiling sym
sym (SRational sym -> SEval sym (SInteger sym))
-> SEval sym (SRational sym) -> SEval sym (SInteger sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalSub sym
sym SRational sym
r SRational sym
half
SInteger sym
fr <- sym -> SRational sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SInteger sym)
rationalFloor sym
sym (SRational sym -> SEval sym (SInteger sym))
-> SEval sym (SRational sym) -> SEval sym (SInteger sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalAdd sym
sym SRational sym
r SRational sym
half
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
iteInteger sym
sym SBit sym
p SInteger sym
cr SInteger sym
fr
rationalRoundToEven :: Backend sym => sym -> SRational sym -> SEval sym (SInteger sym)
rationalRoundToEven :: sym -> SRational sym -> SEval sym (SInteger sym)
rationalRoundToEven sym
sym SRational sym
r =
do SInteger sym
lo <- sym -> SRational sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SInteger sym)
rationalFloor sym
sym SRational sym
r
SInteger sym
hi <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intPlus sym
sym SInteger sym
lo (SInteger sym -> SEval sym (SInteger sym))
-> SEval sym (SInteger sym) -> SEval sym (SInteger sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
1
SRational sym
diff <- sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalSub sym
sym SRational sym
r (SRational sym -> SEval sym (SRational sym))
-> SEval sym (SRational sym) -> SEval sym (SRational sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> SInteger sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SRational sym)
intToRational sym
sym SInteger sym
lo
SRational sym
half <- SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational (SInteger sym -> SInteger sym -> SRational sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym -> SRational sym)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
1 SEval sym (SInteger sym -> SRational sym)
-> SEval sym (SInteger sym) -> SEval sym (SRational sym)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
2
SEval sym (SBit sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
ite (sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalLessThan sym
sym SRational sym
diff SRational sym
half) (SInteger sym -> SEval sym (SInteger sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure SInteger sym
lo) (SEval sym (SInteger sym) -> SEval sym (SInteger sym))
-> SEval sym (SInteger sym) -> SEval sym (SInteger sym)
forall a b. (a -> b) -> a -> b
$
SEval sym (SBit sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
ite (sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalGreaterThan sym
sym SRational sym
diff SRational sym
half) (SInteger sym -> SEval sym (SInteger sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure SInteger sym
hi) (SEval sym (SInteger sym) -> SEval sym (SInteger sym))
-> SEval sym (SInteger sym) -> SEval sym (SInteger sym)
forall a b. (a -> b) -> a -> b
$
SEval sym (SBit sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
ite (SInteger sym -> SEval sym (SBit sym)
isEven SInteger sym
lo) (SInteger sym -> SEval sym (SInteger sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure SInteger sym
lo) (SInteger sym -> SEval sym (SInteger sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure SInteger sym
hi)
where
isEven :: SInteger sym -> SEval sym (SBit sym)
isEven SInteger sym
x =
do SInteger sym
parity <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMod sym
sym SInteger sym
x (SInteger sym -> SEval sym (SInteger sym))
-> SEval sym (SInteger sym) -> SEval sym (SInteger sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
2
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
intEq sym
sym SInteger sym
parity (SInteger sym -> SEval sym (SBit sym))
-> SEval sym (SInteger sym) -> SEval sym (SBit sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
0
ite :: SEval sym (SBit sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym)
ite SEval sym (SBit sym)
x SEval sym (SInteger sym)
t SEval sym (SInteger sym)
e =
do SBit sym
x' <- SEval sym (SBit sym)
x
case sym -> SBit sym -> Maybe Bool
forall sym. Backend sym => sym -> SBit sym -> Maybe Bool
bitAsLit sym
sym SBit sym
x' of
Just Bool
True -> SEval sym (SInteger sym)
t
Just Bool
False -> SEval sym (SInteger sym)
e
Maybe Bool
Nothing ->
do SInteger sym
t' <- SEval sym (SInteger sym)
t
SInteger sym
e' <- SEval sym (SInteger sym)
e
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
iteInteger sym
sym SBit sym
x' SInteger sym
t' SInteger sym
e'
rationalAdd :: Backend sym => sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalAdd :: sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalAdd sym
sym (SRational SInteger sym
a SInteger sym
b) (SRational SInteger sym
c SInteger sym
d) =
do SInteger sym
ad <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
a SInteger sym
d
SInteger sym
bc <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
b SInteger sym
c
SInteger sym
bd <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
b SInteger sym
d
SInteger sym
ad_bc <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intPlus sym
sym SInteger sym
ad SInteger sym
bc
SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
ad_bc SInteger sym
bd)
rationalSub :: Backend sym => sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalSub :: sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalSub sym
sym (SRational SInteger sym
a SInteger sym
b) (SRational SInteger sym
c SInteger sym
d) =
do SInteger sym
ad <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
a SInteger sym
d
SInteger sym
bc <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
b SInteger sym
c
SInteger sym
bd <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
b SInteger sym
d
SInteger sym
ad_bc <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMinus sym
sym SInteger sym
ad SInteger sym
bc
SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
ad_bc SInteger sym
bd)
rationalNegate :: Backend sym => sym -> SRational sym -> SEval sym (SRational sym)
rationalNegate :: sym -> SRational sym -> SEval sym (SRational sym)
rationalNegate sym
sym (SRational SInteger sym
a SInteger sym
b) =
do SInteger sym
aneg <- sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SInteger sym)
intNegate sym
sym SInteger sym
a
SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
aneg SInteger sym
b)
rationalMul :: Backend sym => sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalMul :: sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
rationalMul sym
sym (SRational SInteger sym
a SInteger sym
b) (SRational SInteger sym
c SInteger sym
d) =
do SInteger sym
ac <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
a SInteger sym
c
SInteger sym
bd <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
b SInteger sym
d
SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
ac SInteger sym
bd)
rationalEq :: Backend sym => sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalEq :: sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalEq sym
sym (SRational SInteger sym
a SInteger sym
b) (SRational SInteger sym
c SInteger sym
d) =
do SInteger sym
ad <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
a SInteger sym
d
SInteger sym
bc <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
b SInteger sym
c
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
intEq sym
sym SInteger sym
ad SInteger sym
bc
normalizeSign :: Backend sym => sym -> SRational sym -> SEval sym (SRational sym)
normalizeSign :: sym -> SRational sym -> SEval sym (SRational sym)
normalizeSign sym
sym (SRational SInteger sym
a SInteger sym
b) =
do SBit sym
p <- sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
intLessThan sym
sym SInteger sym
b (SInteger sym -> SEval sym (SBit sym))
-> SEval sym (SInteger sym) -> SEval sym (SBit sym)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< sym -> Integer -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> Integer -> SEval sym (SInteger sym)
integerLit sym
sym Integer
0
case sym -> SBit sym -> Maybe Bool
forall sym. Backend sym => sym -> SBit sym -> Maybe Bool
bitAsLit sym
sym SBit sym
p of
Just Bool
False -> SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
a SInteger sym
b)
Just Bool
True ->
do SInteger sym
aneg <- sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SInteger sym)
intNegate sym
sym SInteger sym
a
SInteger sym
bneg <- sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SInteger sym)
intNegate sym
sym SInteger sym
b
SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
aneg SInteger sym
bneg)
Maybe Bool
Nothing ->
do SInteger sym
aneg <- sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SInteger sym)
intNegate sym
sym SInteger sym
a
SInteger sym
bneg <- sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SEval sym (SInteger sym)
intNegate sym
sym SInteger sym
b
SInteger sym
a' <- sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
iteInteger sym
sym SBit sym
p SInteger sym
aneg SInteger sym
a
SInteger sym
b' <- sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
iteInteger sym
sym SBit sym
p SInteger sym
bneg SInteger sym
b
SRational sym -> SEval sym (SRational sym)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational SInteger sym
a' SInteger sym
b')
rationalLessThan:: Backend sym => sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalLessThan :: sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalLessThan sym
sym SRational sym
x SRational sym
y =
do SRational SInteger sym
a SInteger sym
b <- sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SRational sym)
normalizeSign sym
sym SRational sym
x
SRational SInteger sym
c SInteger sym
d <- sym -> SRational sym -> SEval sym (SRational sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SEval sym (SRational sym)
normalizeSign sym
sym SRational sym
y
SInteger sym
ad <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
a SInteger sym
d
SInteger sym
bc <- sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
intMult sym
sym SInteger sym
b SInteger sym
c
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SInteger sym -> SInteger sym -> SEval sym (SBit sym)
intLessThan sym
sym SInteger sym
ad SInteger sym
bc
rationalGreaterThan:: Backend sym => sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalGreaterThan :: sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalGreaterThan sym
sym = (SRational sym -> SRational sym -> SEval sym (SBit sym))
-> SRational sym -> SRational sym -> SEval sym (SBit sym)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
forall sym.
Backend sym =>
sym -> SRational sym -> SRational sym -> SEval sym (SBit sym)
rationalLessThan sym
sym)
iteRational :: Backend sym => sym -> SBit sym -> SRational sym -> SRational sym -> SEval sym (SRational sym)
iteRational :: sym
-> SBit sym
-> SRational sym
-> SRational sym
-> SEval sym (SRational sym)
iteRational sym
sym SBit sym
p (SRational SInteger sym
a SInteger sym
b) (SRational SInteger sym
c SInteger sym
d) =
SInteger sym -> SInteger sym -> SRational sym
forall sym. SInteger sym -> SInteger sym -> SRational sym
SRational (SInteger sym -> SInteger sym -> SRational sym)
-> SEval sym (SInteger sym)
-> SEval sym (SInteger sym -> SRational sym)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
iteInteger sym
sym SBit sym
p SInteger sym
a SInteger sym
c SEval sym (SInteger sym -> SRational sym)
-> SEval sym (SInteger sym) -> SEval sym (SRational sym)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
forall sym.
Backend sym =>
sym
-> SBit sym
-> SInteger sym
-> SInteger sym
-> SEval sym (SInteger sym)
iteInteger sym
sym SBit sym
p SInteger sym
b SInteger sym
d
ppRational :: Backend sym => sym -> PPOpts -> SRational sym -> Doc
ppRational :: sym -> PPOpts -> SRational sym -> Doc
ppRational sym
sym PPOpts
opts (SRational SInteger sym
n SInteger sym
d)
| Just Integer
ni <- sym -> SInteger sym -> Maybe Integer
forall sym. Backend sym => sym -> SInteger sym -> Maybe Integer
integerAsLit sym
sym SInteger sym
n
, Just Integer
di <- sym -> SInteger sym -> Maybe Integer
forall sym. Backend sym => sym -> SInteger sym -> Maybe Integer
integerAsLit sym
sym SInteger sym
d
= let q :: Ratio Integer
q = Integer
ni Integer -> Integer -> Ratio Integer
forall a. Integral a => a -> a -> Ratio a
% Integer
di in
String -> Doc
text String
"(ratio" Doc -> Doc -> Doc
<+> Integer -> Doc
integer (Ratio Integer -> Integer
forall a. Ratio a -> a
numerator Ratio Integer
q) Doc -> Doc -> Doc
<+> (Integer -> Doc
integer (Ratio Integer -> Integer
forall a. Ratio a -> a
denominator Ratio Integer
q) Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
")")
| Bool
otherwise
= String -> Doc
text String
"(ratio" Doc -> Doc -> Doc
<+> sym -> PPOpts -> SInteger sym -> Doc
forall sym. Backend sym => sym -> PPOpts -> SInteger sym -> Doc
ppInteger sym
sym PPOpts
opts SInteger sym
n Doc -> Doc -> Doc
<+> (sym -> PPOpts -> SInteger sym -> Doc
forall sym. Backend sym => sym -> PPOpts -> SInteger sym -> Doc
ppInteger sym
sym PPOpts
opts SInteger sym
d Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
")")
class MonadIO (SEval sym) => Backend sym where
type SBit sym :: Type
type SWord sym :: Type
type SInteger sym :: Type
type SFloat sym :: Type
type SEval sym :: Type -> Type
isReady :: sym -> SEval sym a -> Bool
sDeclareHole :: sym -> String -> SEval sym (SEval sym a, SEval sym a -> SEval sym ())
sDelayFill :: sym -> SEval sym a -> SEval sym a -> SEval sym (SEval sym a)
sSpark :: sym -> SEval sym a -> SEval sym (SEval sym a)
mergeEval ::
sym ->
(SBit sym -> a -> a -> SEval sym a) ->
SBit sym ->
SEval sym a ->
SEval sym a ->
SEval sym a
assertSideCondition :: sym -> SBit sym -> EvalError -> SEval sym ()
raiseError :: sym -> EvalError -> SEval sym a
ppBit :: sym -> SBit sym -> Doc
ppWord :: sym -> PPOpts -> SWord sym -> Doc
ppInteger :: sym -> PPOpts -> SInteger sym -> Doc
ppFloat :: sym -> PPOpts -> SFloat sym -> Doc
bitAsLit :: sym -> SBit sym -> Maybe Bool
wordLen :: sym -> SWord sym -> Integer
wordAsLit :: sym -> SWord sym -> Maybe (Integer, Integer)
wordAsChar :: sym -> SWord sym -> Maybe Char
integerAsLit :: sym -> SInteger sym -> Maybe Integer
bitLit :: sym -> Bool -> SBit sym
wordLit ::
sym ->
Integer ->
Integer ->
SEval sym (SWord sym)
integerLit ::
sym ->
Integer ->
SEval sym (SInteger sym)
fpLit ::
sym ->
Integer ->
Integer ->
Rational ->
SEval sym (SFloat sym)
fpExactLit :: sym -> BF -> SEval sym (SFloat sym)
iteBit :: sym -> SBit sym -> SBit sym -> SBit sym -> SEval sym (SBit sym)
iteWord :: sym -> SBit sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
iteInteger :: sym -> SBit sym -> SInteger sym -> SInteger sym -> SEval sym (SInteger sym)
bitEq :: sym -> SBit sym -> SBit sym -> SEval sym (SBit sym)
bitOr :: sym -> SBit sym -> SBit sym -> SEval sym (SBit sym)
bitAnd :: sym -> SBit sym -> SBit sym -> SEval sym (SBit sym)
bitXor :: sym -> SBit sym -> SBit sym -> SEval sym (SBit sym)
bitComplement :: sym -> SBit sym -> SEval sym (SBit sym)
wordBit ::
sym ->
SWord sym ->
Integer ->
SEval sym (SBit sym)
wordUpdate ::
sym ->
SWord sym ->
Integer ->
SBit sym ->
SEval sym (SWord sym)
packWord ::
sym ->
[SBit sym] ->
SEval sym (SWord sym)
unpackWord ::
sym ->
SWord sym ->
SEval sym [SBit sym]
wordFromInt ::
sym ->
Integer ->
SInteger sym ->
SEval sym (SWord sym)
joinWord ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
splitWord ::
sym ->
Integer ->
Integer ->
SWord sym ->
SEval sym (SWord sym, SWord sym)
::
sym ->
Integer ->
Integer ->
SWord sym ->
SEval sym (SWord sym)
wordOr ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordAnd ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordXor ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordComplement ::
sym ->
SWord sym ->
SEval sym (SWord sym)
wordPlus ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordMinus ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordMult ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordDiv ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordMod ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordSignedDiv ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordSignedMod ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SWord sym)
wordNegate ::
sym ->
SWord sym ->
SEval sym (SWord sym)
wordLg2 ::
sym ->
SWord sym ->
SEval sym (SWord sym)
wordEq ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SBit sym)
wordSignedLessThan ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SBit sym)
wordLessThan ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SBit sym)
wordGreaterThan ::
sym ->
SWord sym ->
SWord sym ->
SEval sym (SBit sym)
wordToInt ::
sym ->
SWord sym ->
SEval sym (SInteger sym)
intPlus ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
intNegate ::
sym ->
SInteger sym ->
SEval sym (SInteger sym)
intMinus ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
intMult ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
intDiv ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
intMod ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
intEq ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SBit sym)
intLessThan ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SBit sym)
intGreaterThan ::
sym ->
SInteger sym ->
SInteger sym ->
SEval sym (SBit sym)
intToZn ::
sym ->
Integer ->
SInteger sym ->
SEval sym (SInteger sym)
znToInt ::
sym ->
Integer ->
SInteger sym ->
SEval sym (SInteger sym)
znPlus ::
sym ->
Integer ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
znNegate ::
sym ->
Integer ->
SInteger sym ->
SEval sym (SInteger sym)
znMinus ::
sym ->
Integer ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
znMult ::
sym ->
Integer ->
SInteger sym ->
SInteger sym ->
SEval sym (SInteger sym)
znEq ::
sym ->
Integer ->
SInteger sym ->
SInteger sym ->
SEval sym (SBit sym)
znRecip ::
sym ->
Integer ->
SInteger sym ->
SEval sym (SInteger sym)
fpEq :: sym -> SFloat sym -> SFloat sym -> SEval sym (SBit sym)
fpLessThan :: sym -> SFloat sym -> SFloat sym -> SEval sym (SBit sym)
fpGreaterThan :: sym -> SFloat sym -> SFloat sym -> SEval sym (SBit sym)
fpLogicalEq :: sym -> SFloat sym -> SFloat sym -> SEval sym (SBit sym)
fpPlus, fpMinus, fpMult, fpDiv :: FPArith2 sym
fpNeg :: sym -> SFloat sym -> SEval sym (SFloat sym)
fpToInteger ::
sym ->
String ->
SWord sym ->
SFloat sym -> SEval sym (SInteger sym)
fpFromInteger ::
sym ->
Integer ->
Integer ->
SWord sym ->
SInteger sym ->
SEval sym (SFloat sym)
type FPArith2 sym =
sym ->
SWord sym ->
SFloat sym ->
SFloat sym ->
SEval sym (SFloat sym)