Add some comments

This commit is contained in:
Iavor Diatchki 2017-10-03 10:53:40 -07:00
parent a233084db8
commit 234615e7b2

View File

@ -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.