mirror of
https://github.com/GaloisInc/cryptol.git
synced 2024-12-16 20:03:27 +03:00
Add a rule for multiplication
When the constraint is of the form, `k1 * x = k2 * y`, and `gcd k1 k2 /= 1`, simplify the constraint to `(k1 / gcd k1 k2) * x = (k2 / gcd k1 k2) * y`. (NOTE: this doesn't produce a new constraint that uses division, but evaluates the two two constants.)
This commit is contained in:
parent
d498212684
commit
1e723d5265
@ -5,10 +5,11 @@ module Cryptol.TypeCheck.Solver.Numeric
|
||||
|
||||
import Control.Applicative(Alternative(..))
|
||||
import Control.Monad (guard,mzero)
|
||||
import Data.Foldable (asum)
|
||||
|
||||
import Cryptol.Utils.Patterns
|
||||
import Cryptol.TypeCheck.PP
|
||||
import Cryptol.TypeCheck.Type
|
||||
import Cryptol.TypeCheck.Type hiding (tMul)
|
||||
import Cryptol.TypeCheck.TypePat
|
||||
import Cryptol.TypeCheck.Solver.Types
|
||||
import Cryptol.TypeCheck.Solver.InfNat
|
||||
@ -27,6 +28,7 @@ cryIsEqual ctxt t1 t2 =
|
||||
<|> ( guard (t1 == t2) >> return (SolvedIf []))
|
||||
<|> tryEqMin t1 t2
|
||||
<|> tryEqMin t2 t1
|
||||
<|> tryEqMulConst t1 t2
|
||||
|
||||
|
||||
|
||||
@ -200,4 +202,35 @@ tryEqK ctxt ty lk =
|
||||
|
||||
|
||||
|
||||
tryEqMulConst :: Type -> Type -> Match Solved
|
||||
tryEqMulConst l r =
|
||||
do (l1,l2) <- aMul l
|
||||
(r1,r2) <- aMul r
|
||||
|
||||
asum [ do l1' <- aNat l1
|
||||
r1' <- aNat r1
|
||||
return (build l1' l2 r1' r2)
|
||||
|
||||
, do l2' <- aNat l2
|
||||
r1' <- aNat r1
|
||||
return (build l2' l1 r1' r2)
|
||||
|
||||
, do l1' <- aNat l1
|
||||
r2' <- aNat r2
|
||||
return (build l1' l2 r2' r1)
|
||||
|
||||
, do l2' <- aNat l2
|
||||
r2' <- aNat r2
|
||||
return (build l2' l1 r2' r1)
|
||||
|
||||
]
|
||||
|
||||
where
|
||||
|
||||
build lk l' rk r' =
|
||||
let d = gcd lk rk
|
||||
lk' = lk `div` d
|
||||
rk' = rk `div` d
|
||||
in if d == 1
|
||||
then Unsolved
|
||||
else (SolvedIf [ tMul (tNum lk') l' =#= tMul (tNum rk') r' ])
|
||||
|
Loading…
Reference in New Issue
Block a user