mirror of
https://github.com/GaloisInc/cryptol.git
synced 2024-12-17 04:44:39 +03:00
Add some comments
This commit is contained in:
parent
a233084db8
commit
234615e7b2
@ -16,7 +16,16 @@ import Cryptol.TypeCheck.Solver.InfNat
|
|||||||
import Cryptol.TypeCheck.Solver.Numeric.Interval
|
import Cryptol.TypeCheck.Solver.Numeric.Interval
|
||||||
import Cryptol.TypeCheck.SimpType
|
import Cryptol.TypeCheck.SimpType
|
||||||
|
|
||||||
|
{- Convention for comments:
|
||||||
|
|
||||||
|
K1, K2 ... Concrete constants
|
||||||
|
s1, s2, t1, t2 ... Arbitrary type expressions
|
||||||
|
a, b, c ... Type variables
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
|
-- | Try to solve @t1 = t2@
|
||||||
cryIsEqual :: Ctxt -> Type -> Type -> Solved
|
cryIsEqual :: Ctxt -> Type -> Type -> Solved
|
||||||
cryIsEqual ctxt t1 t2 =
|
cryIsEqual ctxt t1 t2 =
|
||||||
matchDefault Unsolved $
|
matchDefault Unsolved $
|
||||||
@ -34,9 +43,11 @@ cryIsEqual ctxt t1 t2 =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- | Try to solve @t1 /= t2@
|
||||||
cryIsNotEqual :: Ctxt -> Type -> Type -> Solved
|
cryIsNotEqual :: Ctxt -> Type -> Type -> Solved
|
||||||
cryIsNotEqual _i t1 t2 = matchDefault Unsolved (pBin PNeq (/=) t1 t2)
|
cryIsNotEqual _i t1 t2 = matchDefault Unsolved (pBin PNeq (/=) t1 t2)
|
||||||
|
|
||||||
|
-- | Try to solve @t1 >= t2@
|
||||||
cryIsGeq :: Ctxt -> Type -> Type -> Solved
|
cryIsGeq :: Ctxt -> Type -> Type -> Solved
|
||||||
cryIsGeq i t1 t2 =
|
cryIsGeq i t1 t2 =
|
||||||
matchDefault Unsolved $
|
matchDefault Unsolved $
|
||||||
@ -53,10 +64,10 @@ cryIsGeq i t1 t2 =
|
|||||||
-- XXX: width e >= k
|
-- XXX: width e >= k
|
||||||
|
|
||||||
|
|
||||||
-- XXX: max a 10 >= 2 --> True
|
-- XXX: max t 10 >= 2 --> True
|
||||||
-- XXX: max a 2 >= 10 --> a >= 10
|
-- XXX: max t 2 >= 10 --> a >= 10
|
||||||
|
|
||||||
|
|
||||||
|
-- | Try to solve something by evalutaion.
|
||||||
pBin :: PC -> (Nat' -> Nat' -> Bool) -> Type -> Type -> Match Solved
|
pBin :: PC -> (Nat' -> Nat' -> Bool) -> Type -> Type -> Match Solved
|
||||||
pBin tf p t1 t2 =
|
pBin tf p t1 t2 =
|
||||||
Unsolvable <$> anError KNum t1
|
Unsolvable <$> anError KNum t1
|
||||||
@ -73,9 +84,12 @@ pBin tf p t1 t2 =
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- GEQ
|
-- GEQ
|
||||||
|
|
||||||
|
-- | Try to solve @K >= t@
|
||||||
tryGeqKThan :: Ctxt -> Type -> Nat' -> Match Solved
|
tryGeqKThan :: Ctxt -> Type -> Nat' -> Match Solved
|
||||||
tryGeqKThan _ _ Inf = return (SolvedIf [])
|
tryGeqKThan _ _ Inf = return (SolvedIf [])
|
||||||
tryGeqKThan _ ty (Nat n) =
|
tryGeqKThan _ ty (Nat n) =
|
||||||
|
|
||||||
|
-- K1 >= K2 * t
|
||||||
do (a,b) <- aMul ty
|
do (a,b) <- aMul ty
|
||||||
m <- aNat' a
|
m <- aNat' a
|
||||||
return $ SolvedIf
|
return $ SolvedIf
|
||||||
@ -84,9 +98,12 @@ tryGeqKThan _ ty (Nat n) =
|
|||||||
Nat 0 -> []
|
Nat 0 -> []
|
||||||
Nat k -> [ tNum (div n k) >== b ]
|
Nat k -> [ tNum (div n k) >== b ]
|
||||||
|
|
||||||
|
-- | Try to solve @t >= K@
|
||||||
tryGeqThanK :: Ctxt -> Type -> Nat' -> Match Solved
|
tryGeqThanK :: Ctxt -> Type -> Nat' -> Match Solved
|
||||||
tryGeqThanK _ t Inf = return (SolvedIf [ t =#= tInf ])
|
tryGeqThanK _ t Inf = return (SolvedIf [ t =#= tInf ])
|
||||||
tryGeqThanK _ t (Nat k) =
|
tryGeqThanK _ t (Nat k) =
|
||||||
|
|
||||||
|
-- K1 + t >= K2
|
||||||
do (a,b) <- anAdd t
|
do (a,b) <- anAdd t
|
||||||
n <- aNat a
|
n <- aNat a
|
||||||
return $ SolvedIf $ if n >= k
|
return $ SolvedIf $ if n >= k
|
||||||
@ -94,21 +111,24 @@ tryGeqThanK _ t (Nat k) =
|
|||||||
else [ b >== tNum (k - n) ]
|
else [ b >== tNum (k - n) ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tryGeqThanSub :: Ctxt -> Type -> Type -> Match Solved
|
tryGeqThanSub :: Ctxt -> Type -> Type -> Match Solved
|
||||||
tryGeqThanSub _ x y =
|
tryGeqThanSub _ x y =
|
||||||
|
|
||||||
|
-- t1 >= t1 - t2
|
||||||
do (a,_) <- (|-|) y
|
do (a,_) <- (|-|) y
|
||||||
guard (x == a)
|
guard (x == a)
|
||||||
return (SolvedIf [])
|
return (SolvedIf [])
|
||||||
|
|
||||||
tryGeqThanVar :: Ctxt -> Type -> TVar -> Match Solved
|
tryGeqThanVar :: Ctxt -> Type -> TVar -> Match Solved
|
||||||
tryGeqThanVar _ctxt ty x =
|
tryGeqThanVar _ctxt ty x =
|
||||||
|
-- (t + a) >= a
|
||||||
do (a,b) <- anAdd ty
|
do (a,b) <- anAdd ty
|
||||||
let check y = do x' <- aTVar y
|
let check y = do x' <- aTVar y
|
||||||
guard (x == x')
|
guard (x == x')
|
||||||
return (SolvedIf [])
|
return (SolvedIf [])
|
||||||
check a <|> check b
|
check a <|> check b
|
||||||
|
|
||||||
|
-- | Try to prove GEQ by considering the known intervals for the given types.
|
||||||
geqByInterval :: Ctxt -> Type -> Type -> Match Solved
|
geqByInterval :: Ctxt -> Type -> Type -> Match Solved
|
||||||
geqByInterval ctxt x y =
|
geqByInterval ctxt x y =
|
||||||
let ix = typeInterval ctxt x
|
let ix = typeInterval ctxt x
|
||||||
@ -117,7 +137,7 @@ geqByInterval ctxt x y =
|
|||||||
(l,Just n) | l >= n -> return (SolvedIf [])
|
(l,Just n) | l >= n -> return (SolvedIf [])
|
||||||
_ -> mzero
|
_ -> mzero
|
||||||
|
|
||||||
|
-- min K1 t >= K2 ~~> t >= K2, if K1 >= K2; Err otherwise
|
||||||
tryMinIsGeq :: Type -> Type -> Match Solved
|
tryMinIsGeq :: Type -> Type -> Match Solved
|
||||||
tryMinIsGeq t1 t2 =
|
tryMinIsGeq t1 t2 =
|
||||||
do (a,b) <- aMin t1
|
do (a,b) <- aMin t1
|
||||||
@ -131,7 +151,7 @@ tryMinIsGeq t1 t2 =
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
-- min a b = a ~> a <= b
|
-- min t1 t2 = t1 ~> t1 <= t2
|
||||||
tryEqMin :: Type -> Type -> Match Solved
|
tryEqMin :: Type -> Type -> Match Solved
|
||||||
tryEqMin x y =
|
tryEqMin x y =
|
||||||
do (a,b) <- aMin x
|
do (a,b) <- aMin x
|
||||||
@ -143,7 +163,7 @@ tryEqMin x y =
|
|||||||
tryEqVar :: Type -> TVar -> Match Solved
|
tryEqVar :: Type -> TVar -> Match Solved
|
||||||
tryEqVar ty x =
|
tryEqVar ty x =
|
||||||
|
|
||||||
-- x = K + x --> x = inf
|
-- a = K + a --> x = inf
|
||||||
(do (k,tv) <- matches ty (anAdd, aNat, aTVar)
|
(do (k,tv) <- matches ty (anAdd, aNat, aTVar)
|
||||||
guard (tv == x && k >= 1)
|
guard (tv == x && k >= 1)
|
||||||
|
|
||||||
@ -151,7 +171,7 @@ tryEqVar ty x =
|
|||||||
)
|
)
|
||||||
<|>
|
<|>
|
||||||
|
|
||||||
-- x = min (K + x) y --> x = y
|
-- a = min (K + a) t --> a = t
|
||||||
(do (l,r) <- aMin ty
|
(do (l,r) <- aMin ty
|
||||||
let check this other =
|
let check this other =
|
||||||
do (k,x') <- matches this (anAdd, aNat', aTVar)
|
do (k,x') <- matches this (anAdd, aNat', aTVar)
|
||||||
@ -160,7 +180,7 @@ tryEqVar ty x =
|
|||||||
check l r <|> check r l
|
check l r <|> check r l
|
||||||
)
|
)
|
||||||
<|>
|
<|>
|
||||||
-- x = K + min a x
|
-- a = K + min t a
|
||||||
(do (k,(l,r)) <- matches ty (anAdd, aNat, aMin)
|
(do (k,(l,r)) <- matches ty (anAdd, aNat, aMin)
|
||||||
guard (k >= 1)
|
guard (k >= 1)
|
||||||
let check a b = do x' <- aTVar a
|
let check a b = do x' <- aTVar a
|
||||||
@ -178,12 +198,16 @@ tryEqVar ty x =
|
|||||||
-- e.g., 10 = t
|
-- e.g., 10 = t
|
||||||
tryEqK :: Ctxt -> Type -> Nat' -> Match Solved
|
tryEqK :: Ctxt -> Type -> Nat' -> Match Solved
|
||||||
tryEqK ctxt ty lk =
|
tryEqK ctxt ty lk =
|
||||||
|
|
||||||
|
-- (t1 + t2 = inf, fin t1) ~~~> t2 = inf
|
||||||
do guard (lk == Inf)
|
do guard (lk == Inf)
|
||||||
(a,b) <- anAdd ty
|
(a,b) <- anAdd ty
|
||||||
let check x y = do guard (iIsFin (typeInterval ctxt x))
|
let check x y = do guard (iIsFin (typeInterval ctxt x))
|
||||||
return $ SolvedIf [ y =#= tInf ]
|
return $ SolvedIf [ y =#= tInf ]
|
||||||
check a b <|> check b a
|
check a b <|> check b a
|
||||||
<|>
|
<|>
|
||||||
|
|
||||||
|
-- (K1 + t = K2, K2 >= K1) ~~~> t = (K2 - K1)
|
||||||
do (rk, b) <- matches ty (anAdd, aNat', __)
|
do (rk, b) <- matches ty (anAdd, aNat', __)
|
||||||
return $
|
return $
|
||||||
case nSub lk rk of
|
case nSub lk rk of
|
||||||
@ -195,18 +219,30 @@ tryEqK ctxt ty lk =
|
|||||||
|
|
||||||
Just r -> SolvedIf [ b =#= tNat' r ]
|
Just r -> SolvedIf [ b =#= tNat' r ]
|
||||||
<|>
|
<|>
|
||||||
|
|
||||||
do (rk, b) <- matches ty (aMul, aNat', __)
|
do (rk, b) <- matches ty (aMul, aNat', __)
|
||||||
return $
|
return $
|
||||||
case (lk,rk) of
|
case (lk,rk) of
|
||||||
|
-- Inf * t = Inf ~~~> t >= 1
|
||||||
(Inf,Inf) -> SolvedIf [ b >== tOne ]
|
(Inf,Inf) -> SolvedIf [ b >== tOne ]
|
||||||
|
|
||||||
|
-- K * t = Inf ~~~> t = Inf
|
||||||
(Inf,Nat _) -> SolvedIf [ b =#= tInf ]
|
(Inf,Nat _) -> SolvedIf [ b =#= tInf ]
|
||||||
|
|
||||||
|
-- Inf * t = 0 ~~~> t = 0
|
||||||
(Nat 0, Inf) -> SolvedIf [ b =#= tZero ]
|
(Nat 0, Inf) -> SolvedIf [ b =#= tZero ]
|
||||||
|
|
||||||
|
-- Inf * t = K ~~~> ERR (K /= 0)
|
||||||
(Nat k, Inf) -> Unsolvable
|
(Nat k, Inf) -> Unsolvable
|
||||||
$ TCErrorMessage
|
$ TCErrorMessage
|
||||||
$ show k ++ " /= inf * anything"
|
$ show k ++ " /= inf * anything"
|
||||||
|
|
||||||
(Nat lk', Nat rk')
|
(Nat lk', Nat rk')
|
||||||
|
-- 0 * t = K2 ~~> K2 = 0
|
||||||
| rk' == 0 -> SolvedIf [ tNat' lk =#= tZero ]
|
| rk' == 0 -> SolvedIf [ tNat' lk =#= tZero ]
|
||||||
-- shouldn't happen, as `0 * x = x`
|
-- shouldn't happen, as `0 * t = t` should have been simplified
|
||||||
|
|
||||||
|
-- K1 * t = K2 ~~> t = K2/K1
|
||||||
| (q,0) <- divMod lk' rk' -> SolvedIf [ b =#= tNum q ]
|
| (q,0) <- divMod lk' rk' -> SolvedIf [ b =#= tNum q ]
|
||||||
| otherwise ->
|
| otherwise ->
|
||||||
Unsolvable
|
Unsolvable
|
||||||
@ -219,7 +255,7 @@ tryEqK ctxt ty lk =
|
|||||||
-- 10 = min (2,y) --> impossible
|
-- 10 = min (2,y) --> impossible
|
||||||
|
|
||||||
|
|
||||||
|
-- | K1 * t1 = K2 * t2
|
||||||
tryEqMulConst :: Type -> Type -> Match Solved
|
tryEqMulConst :: Type -> Type -> Match Solved
|
||||||
tryEqMulConst l r =
|
tryEqMulConst l r =
|
||||||
do (l1,l2) <- aMul l
|
do (l1,l2) <- aMul l
|
||||||
@ -254,6 +290,7 @@ tryEqMulConst l r =
|
|||||||
else (SolvedIf [ tMul (tNum lk') l' =#= tMul (tNum rk') r' ])
|
else (SolvedIf [ tMul (tNum lk') l' =#= tMul (tNum rk') r' ])
|
||||||
|
|
||||||
|
|
||||||
|
-- | @(t1 + t2 = Inf, fin t1) ~~> t2 = Inf@
|
||||||
tryEqAddInf :: Ctxt -> Type -> Type -> Match Solved
|
tryEqAddInf :: Ctxt -> Type -> Type -> Match Solved
|
||||||
tryEqAddInf ctxt l r = check l r <|> check r l
|
tryEqAddInf ctxt l r = check l r <|> check r l
|
||||||
where
|
where
|
||||||
@ -279,6 +316,7 @@ tryEqAddInf ctxt l r = check l r <|> check r l
|
|||||||
|
|
||||||
|
|
||||||
-- | Check for addition of constants to both sides of a relation.
|
-- | Check for addition of constants to both sides of a relation.
|
||||||
|
-- @((K1 + K2) + t1) `R` (K1 + t2) ~~> (K2 + t1) `R` t2@
|
||||||
--
|
--
|
||||||
-- This relies on the fact that constants are floated left during
|
-- This relies on the fact that constants are floated left during
|
||||||
-- simplification.
|
-- simplification.
|
||||||
|
Loading…
Reference in New Issue
Block a user