{-# LANGUAGE PatternGuards #-}
module Cryptol.TypeCheck.Solver.Class
( solveZeroInst
, solveLogicInst
, solveRingInst
, solveFieldInst
, solveIntegralInst
, solveRoundInst
, solveEqInst
, solveCmpInst
, solveSignedCmpInst
, solveLiteralInst
, solveFLiteralInst
, solveValidFloat
) where
import qualified LibBF as FP
import Cryptol.TypeCheck.Type
import Cryptol.TypeCheck.SimpType (tAdd,tWidth)
import Cryptol.TypeCheck.Solver.Types
import Cryptol.Utils.RecordMap
solveValidFloat :: Type -> Type -> Solved
solveValidFloat :: Type -> Type -> Solved
solveValidFloat Type
e Type
p
| Just BFOpts
_ <- Type -> Type -> Maybe BFOpts
knownSupportedFloat Type
e Type
p = [Type] -> Solved
SolvedIf []
| Bool
otherwise = Solved
Unsolved
knownSupportedFloat :: Type -> Type -> Maybe FP.BFOpts
knownSupportedFloat :: Type -> Type -> Maybe BFOpts
knownSupportedFloat Type
et Type
pt
| Just Integer
e <- Type -> Maybe Integer
tIsNum Type
et, Just Integer
p <- Type -> Maybe Integer
tIsNum Type
pt
, Integer
minExp Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
e Bool -> Bool -> Bool
&& Integer
e Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
maxExp Bool -> Bool -> Bool
&& Integer
minPrec Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
p Bool -> Bool -> Bool
&& Integer
p Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
maxPrec =
BFOpts -> Maybe BFOpts
forall a. a -> Maybe a
Just (Int -> BFOpts
FP.expBits (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
e) BFOpts -> BFOpts -> BFOpts
forall a. Semigroup a => a -> a -> a
<> Int -> BFOpts
FP.precBits (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
p)
BFOpts -> BFOpts -> BFOpts
forall a. Semigroup a => a -> a -> a
<> BFOpts
FP.allowSubnormal)
| Bool
otherwise = Maybe BFOpts
forall a. Maybe a
Nothing
where
minExp :: Integer
minExp = Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
max Integer
2 (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
FP.expBitsMin)
maxExp :: Integer
maxExp = Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
FP.expBitsMax
minPrec :: Integer
minPrec = Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
max Integer
2 (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
FP.precBitsMin)
maxPrec :: Integer
maxPrec = Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
FP.precBitsMax
solveZeroInst :: Type -> Solved
solveZeroInst :: Type -> Solved
solveZeroInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCInteger) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCIntMod) [Type
n] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n, Type
n Type -> Type -> Type
>== Type
tOne ]
TCon (TC TC
TCRational) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCFloat) [Type
e,Type
p] -> [Type] -> Solved
SolvedIf [ Type -> Type -> Type
pValidFloat Type
e Type
p ]
TCon (TC TC
TCSeq) [Type
_, Type
a] -> [Type] -> Solved
SolvedIf [ Type -> Type
pZero Type
a ]
TCon (TC TC
TCFun) [Type
_, Type
b] -> [Type] -> Solved
SolvedIf [ Type -> Type
pZero Type
b ]
TCon (TC (TCTuple Int
_)) [Type]
es -> [Type] -> Solved
SolvedIf [ Type -> Type
pZero Type
e | Type
e <- [Type]
es ]
TRec RecordMap Ident Type
fs -> [Type] -> Solved
SolvedIf [ Type -> Type
pZero Type
ety | Type
ety <- RecordMap Ident Type -> [Type]
forall a b. RecordMap a b -> [b]
recordElements RecordMap Ident Type
fs ]
Type
_ -> Solved
Unsolved
solveLogicInst :: Type -> Solved
solveLogicInst :: Type -> Solved
solveLogicInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCInteger) [] -> Solved
Unsolvable
TCon (TC TC
TCIntMod) [Type
_] -> Solved
Unsolvable
TCon (TC TC
TCRational) [] -> Solved
Unsolvable
TCon (TC TC
TCFloat) [Type
_, Type
_] -> Solved
Unsolvable
TCon (TC TC
TCSeq) [Type
_, Type
a] -> [Type] -> Solved
SolvedIf [ Type -> Type
pLogic Type
a ]
TCon (TC TC
TCFun) [Type
_, Type
b] -> [Type] -> Solved
SolvedIf [ Type -> Type
pLogic Type
b ]
TCon (TC (TCTuple Int
_)) [Type]
es -> [Type] -> Solved
SolvedIf [ Type -> Type
pLogic Type
e | Type
e <- [Type]
es ]
TRec RecordMap Ident Type
fs -> [Type] -> Solved
SolvedIf [ Type -> Type
pLogic Type
ety | Type
ety <- RecordMap Ident Type -> [Type]
forall a b. RecordMap a b -> [b]
recordElements RecordMap Ident Type
fs ]
Type
_ -> Solved
Unsolved
solveRingInst :: Type -> Solved
solveRingInst :: Type -> Solved
solveRingInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCSeq) [Type
n, Type
e] -> Type -> Type -> Solved
solveRingSeq Type
n Type
e
TCon (TC TC
TCFun) [Type
_,Type
b] -> [Type] -> Solved
SolvedIf [ Type -> Type
pRing Type
b ]
TCon (TC (TCTuple Int
_)) [Type]
es -> [Type] -> Solved
SolvedIf [ Type -> Type
pRing Type
e | Type
e <- [Type]
es ]
TCon (TC TC
TCBit) [] -> Solved
Unsolvable
TCon (TC TC
TCInteger) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCIntMod) [Type
n] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n, Type
n Type -> Type -> Type
>== Type
tOne ]
TCon (TC TC
TCRational) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCFloat) [Type
e,Type
p] -> [Type] -> Solved
SolvedIf [ Type -> Type -> Type
pValidFloat Type
e Type
p ]
TRec RecordMap Ident Type
fs -> [Type] -> Solved
SolvedIf [ Type -> Type
pRing Type
ety | Type
ety <- RecordMap Ident Type -> [Type]
forall a b. RecordMap a b -> [b]
recordElements RecordMap Ident Type
fs ]
Type
_ -> Solved
Unsolved
solveRingSeq :: Type -> Type -> Solved
solveRingSeq :: Type -> Type -> Solved
solveRingSeq Type
n Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n ]
TVar {} -> case Type -> Type
tNoUser Type
n of
TCon (TC TC
TCInf) [] -> [Type] -> Solved
SolvedIf [ Type -> Type
pRing Type
ty ]
Type
_ -> Solved
Unsolved
Type
_ -> [Type] -> Solved
SolvedIf [ Type -> Type
pRing Type
ty ]
solveIntegralInst :: Type -> Solved
solveIntegralInst :: Type -> Solved
solveIntegralInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> Solved
Unsolvable
TCon (TC TC
TCInteger) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCSeq) [Type
n, Type
elTy] ->
case Type -> Type
tNoUser Type
elTy of
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n ]
TVar TVar
_ -> Solved
Unsolved
Type
_ -> Solved
Unsolvable
TVar TVar
_ -> Solved
Unsolved
Type
_ -> Solved
Unsolvable
solveFieldInst :: Type -> Solved
solveFieldInst :: Type -> Solved
solveFieldInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> Solved
Unsolvable
TCon (TC TC
TCInteger) [] -> Solved
Unsolvable
TCon (TC TC
TCRational) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCFloat) [Type
e,Type
p] -> [Type] -> Solved
SolvedIf [ Type -> Type -> Type
pValidFloat Type
e Type
p ]
TCon (TC TC
TCIntMod) [Type
n] -> [Type] -> Solved
SolvedIf [ Type -> Type
pPrime Type
n ]
TCon (TC TC
TCSeq) [Type
_, Type
_] -> Solved
Unsolvable
TCon (TC TC
TCFun) [Type
_, Type
_] -> Solved
Unsolvable
TCon (TC (TCTuple Int
_)) [Type]
_ -> Solved
Unsolvable
TRec RecordMap Ident Type
_ -> Solved
Unsolvable
Type
_ -> Solved
Unsolved
solveRoundInst :: Type -> Solved
solveRoundInst :: Type -> Solved
solveRoundInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> Solved
Unsolvable
TCon (TC TC
TCInteger) [] -> Solved
Unsolvable
TCon (TC TC
TCIntMod) [Type
_] -> Solved
Unsolvable
TCon (TC TC
TCRational) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCFloat) [Type
e,Type
p] -> [Type] -> Solved
SolvedIf [ Type -> Type -> Type
pValidFloat Type
e Type
p ]
TCon (TC TC
TCSeq) [Type
_, Type
_] -> Solved
Unsolvable
TCon (TC TC
TCFun) [Type
_, Type
_] -> Solved
Unsolvable
TCon (TC (TCTuple Int
_)) [Type]
_ -> Solved
Unsolvable
TRec RecordMap Ident Type
_ -> Solved
Unsolvable
Type
_ -> Solved
Unsolved
solveEqInst :: Type -> Solved
solveEqInst :: Type -> Solved
solveEqInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCInteger) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCRational) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCFloat) [Type
e,Type
p] -> [Type] -> Solved
SolvedIf [ Type -> Type -> Type
pValidFloat Type
e Type
p ]
TCon (TC TC
TCIntMod) [Type
n] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n, Type
n Type -> Type -> Type
>== Type
tOne ]
TCon (TC TC
TCSeq) [Type
n,Type
a] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n, Type -> Type
pEq Type
a ]
TCon (TC (TCTuple Int
_)) [Type]
es -> [Type] -> Solved
SolvedIf ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
pEq [Type]
es)
TCon (TC TC
TCFun) [Type
_,Type
_] -> Solved
Unsolvable
TRec RecordMap Ident Type
fs -> [Type] -> Solved
SolvedIf [ Type -> Type
pEq Type
e | Type
e <- RecordMap Ident Type -> [Type]
forall a b. RecordMap a b -> [b]
recordElements RecordMap Ident Type
fs ]
Type
_ -> Solved
Unsolved
solveCmpInst :: Type -> Solved
solveCmpInst :: Type -> Solved
solveCmpInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCInteger) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCRational) [] -> [Type] -> Solved
SolvedIf []
TCon (TC TC
TCIntMod) [Type
_] -> Solved
Unsolvable
TCon (TC TC
TCFloat) [Type
e,Type
p] -> [Type] -> Solved
SolvedIf [ Type -> Type -> Type
pValidFloat Type
e Type
p ]
TCon (TC TC
TCSeq) [Type
n,Type
a] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n, Type -> Type
pCmp Type
a ]
TCon (TC (TCTuple Int
_)) [Type]
es -> [Type] -> Solved
SolvedIf ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
pCmp [Type]
es)
TCon (TC TC
TCFun) [Type
_,Type
_] -> Solved
Unsolvable
TRec RecordMap Ident Type
fs -> [Type] -> Solved
SolvedIf [ Type -> Type
pCmp Type
e | Type
e <- RecordMap Ident Type -> [Type]
forall a b. RecordMap a b -> [b]
recordElements RecordMap Ident Type
fs ]
Type
_ -> Solved
Unsolved
solveSignedCmpSeq :: Type -> Type -> Solved
solveSignedCmpSeq :: Type -> Type -> Solved
solveSignedCmpSeq Type
n Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n, Type
n Type -> Type -> Type
>== Integer -> Type
forall a. Integral a => a -> Type
tNum (Integer
1 :: Integer) ]
TVar {} -> Solved
Unsolved
Type
_ -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
n, Type -> Type
pSignedCmp Type
ty ]
solveSignedCmpInst :: Type -> Solved
solveSignedCmpInst :: Type -> Solved
solveSignedCmpInst Type
ty = case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> Solved
Unsolvable
TCon (TC TC
TCInteger) [] -> Solved
Unsolvable
TCon (TC TC
TCIntMod) [Type
_] -> Solved
Unsolvable
TCon (TC TC
TCRational) [] -> Solved
Unsolvable
TCon (TC TC
TCFloat) [Type
_, Type
_] -> Solved
Unsolvable
TCon (TC TC
TCSeq) [Type
n,Type
a] -> Type -> Type -> Solved
solveSignedCmpSeq Type
n Type
a
TCon (TC (TCTuple Int
_)) [Type]
es -> [Type] -> Solved
SolvedIf ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
pSignedCmp [Type]
es)
TCon (TC TC
TCFun) [Type
_,Type
_] -> Solved
Unsolvable
TRec RecordMap Ident Type
fs -> [Type] -> Solved
SolvedIf [ Type -> Type
pSignedCmp Type
e | Type
e <- RecordMap Ident Type -> [Type]
forall a b. RecordMap a b -> [b]
recordElements RecordMap Ident Type
fs ]
Type
_ -> Solved
Unsolved
solveFLiteralInst :: Type -> Type -> Type -> Type -> Solved
solveFLiteralInst :: Type -> Type -> Type -> Type -> Solved
solveFLiteralInst Type
numT Type
denT Type
rndT Type
ty
| TCon (TError {}) [Type]
_ <- Type -> Type
tNoUser Type
numT = Solved
Unsolvable
| TCon (TError {}) [Type]
_ <- Type -> Type
tNoUser Type
denT = Solved
Unsolvable
| Type -> Bool
tIsInf Type
numT Bool -> Bool -> Bool
|| Type -> Bool
tIsInf Type
denT Bool -> Bool -> Bool
|| Type -> Bool
tIsInf Type
rndT = Solved
Unsolvable
| Just Integer
0 <- Type -> Maybe Integer
tIsNum Type
denT = Solved
Unsolvable
| Bool
otherwise =
case Type -> Type
tNoUser Type
ty of
TVar {} -> Solved
Unsolved
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCRational) [] ->
[Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
numT, Type -> Type
pFin Type
denT, Type
denT Type -> Type -> Type
>== Type
tOne ]
TCon (TC TC
TCFloat) [Type
e,Type
p]
| Just Integer
0 <- Type -> Maybe Integer
tIsNum Type
rndT ->
[Type] -> Solved
SolvedIf [ Type -> Type -> Type
pValidFloat Type
e Type
p
, Type -> Type
pFin Type
numT, Type -> Type
pFin Type
denT, Type
denT Type -> Type -> Type
>== Type
tOne ]
| Just Integer
_ <- Type -> Maybe Integer
tIsNum Type
rndT
, Just BFOpts
opts <- Type -> Type -> Maybe BFOpts
knownSupportedFloat Type
e Type
p
, Just Integer
n <- Type -> Maybe Integer
tIsNum Type
numT
, Just Integer
d <- Type -> Maybe Integer
tIsNum Type
denT
-> case BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
FP.bfDiv BFOpts
opts (Integer -> BigFloat
FP.bfFromInteger Integer
n) (Integer -> BigFloat
FP.bfFromInteger Integer
d) of
(BigFloat
_, Status
FP.Ok) -> [Type] -> Solved
SolvedIf []
(BigFloat, Status)
_ -> Solved
Unsolvable
| Bool
otherwise -> Solved
Unsolved
Type
_ -> Solved
Unsolvable
solveLiteralInst :: Type -> Type -> Solved
solveLiteralInst :: Type -> Type -> Solved
solveLiteralInst Type
val Type
ty
| TCon (TError {}) [Type]
_ <- Type -> Type
tNoUser Type
val = Solved
Unsolvable
| Bool
otherwise =
case Type -> Type
tNoUser Type
ty of
TCon (TError {}) [Type]
_ -> Solved
Unsolvable
TCon (TC TC
TCBit) [] -> [Type] -> Solved
SolvedIf [ Type
tOne Type -> Type -> Type
>== Type
val ]
TCon (TC TC
TCInteger) [] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
val ]
TCon (TC TC
TCRational) [] -> [Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
val ]
TCon (TC TC
TCFloat) [Type
e,Type
p]
| Just Integer
n <- Type -> Maybe Integer
tIsNum Type
val
, Just BFOpts
opts <- Type -> Type -> Maybe BFOpts
knownSupportedFloat Type
e Type
p ->
let bf :: BigFloat
bf = Integer -> BigFloat
FP.bfFromInteger Integer
n
in case BFOpts -> BigFloat -> (BigFloat, Status)
FP.bfRoundFloat BFOpts
opts BigFloat
bf of
(BigFloat
bf1,Status
FP.Ok) | BigFloat
bf BigFloat -> BigFloat -> Bool
forall a. Eq a => a -> a -> Bool
== BigFloat
bf1 -> [Type] -> Solved
SolvedIf []
(BigFloat, Status)
_ -> Solved
Unsolvable
| Bool
otherwise -> Solved
Unsolved
TCon (TC TC
TCIntMod) [Type
modulus] ->
[Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
val, Type -> Type
pFin Type
modulus, Type
modulus Type -> Type -> Type
>== Type -> Type -> Type
tAdd Type
val Type
tOne ]
TCon (TC TC
TCSeq) [Type
bits, Type
elTy]
| TCon (TC TC
TCBit) [] <- Type
ety ->
[Type] -> Solved
SolvedIf [ Type -> Type
pFin Type
val, Type -> Type
pFin Type
bits, Type
bits Type -> Type -> Type
>== Type -> Type
tWidth Type
val ]
| TVar TVar
_ <- Type
ety -> Solved
Unsolved
where ety :: Type
ety = Type -> Type
tNoUser Type
elTy
TVar TVar
_ -> Solved
Unsolved
Type
_ -> Solved
Unsolvable