Commit the start of the work on modular X before I worry about From.
This commit is contained in:
@@ -10,6 +10,7 @@ import CryptoNum(cryptoNum)
|
||||
import Control.Monad(forM_,unless)
|
||||
import Division(divisionOps)
|
||||
import File(File,Task(..),generateTasks)
|
||||
import ModOps(modulusOps)
|
||||
import Multiply(safeMultiplyOps, unsafeMultiplyOps)
|
||||
import Scale(safeScaleOps, unsafeScaleOps)
|
||||
import Shift(shiftOps)
|
||||
@@ -38,6 +39,7 @@ unsignedFiles = [
|
||||
, conversions
|
||||
, cryptoNum
|
||||
, divisionOps
|
||||
, modulusOps
|
||||
, safeAddOps
|
||||
, safeMultiplyOps
|
||||
, safeScaleOps
|
||||
|
||||
@@ -22,6 +22,7 @@ library
|
||||
containers,
|
||||
directory,
|
||||
filepath,
|
||||
integer-gmp,
|
||||
language-rust,
|
||||
largeword,
|
||||
mtl,
|
||||
@@ -40,6 +41,7 @@ library
|
||||
Gen,
|
||||
Generators,
|
||||
Karatsuba,
|
||||
ModOps,
|
||||
Multiply,
|
||||
Scale,
|
||||
Shift,
|
||||
|
||||
@@ -207,6 +207,6 @@ generateDivisionTests size g = go g numTestCases
|
||||
("z", showX (x `div` y)),
|
||||
("r", showX (x `mod` y))]
|
||||
in if y == 0
|
||||
then go g0 i
|
||||
then go g2 i
|
||||
else tcase : go g2 (i - 1)
|
||||
|
||||
|
||||
76
generation/src/ModOps.hs
Normal file
76
generation/src/ModOps.hs
Normal file
@@ -0,0 +1,76 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
module ModOps(modulusOps)
|
||||
where
|
||||
|
||||
import Data.Map.Strict(Map)
|
||||
import qualified Data.Map.Strict as Map
|
||||
import File
|
||||
import Gen(toLit)
|
||||
import Generators
|
||||
import GHC.Integer.GMP.Internals(powModInteger)
|
||||
import Language.Rust.Data.Ident
|
||||
import Language.Rust.Data.Position
|
||||
import Language.Rust.Quote
|
||||
import Language.Rust.Syntax
|
||||
import System.Random(RandomGen)
|
||||
|
||||
numTestCases :: Int
|
||||
numTestCases = 3000
|
||||
|
||||
modulusOps :: File
|
||||
modulusOps = File {
|
||||
predicate = \ me others -> (me * 2) `elem` others,
|
||||
outputName = "modops",
|
||||
isUnsigned = True,
|
||||
generator = declareModOps,
|
||||
testCase = Just generateModulusTests
|
||||
}
|
||||
|
||||
declareModOps :: Word -> SourceFile Span
|
||||
declareModOps bitsize =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
bname = mkIdent ("U" ++ show (bitsize * 2))
|
||||
in [sourceFile|
|
||||
use crate::unsigned::$$sname;
|
||||
use crate::{DivMod, ModularOperations};
|
||||
|
||||
impl ModularOperations for $$sname {
|
||||
fn reduce(&self, m: &$$sname) -> $$sname {
|
||||
let (_, res) = self.divmod(m);
|
||||
res
|
||||
}
|
||||
|
||||
fn modmul(&self, y: &$$sname, m: &$$sname) -> $$sname {
|
||||
panic!("modmul")
|
||||
}
|
||||
|
||||
fn modsq(&self, m: &$$sname) -> $$sname {
|
||||
panic!("reduce")
|
||||
}
|
||||
|
||||
fn modexp(&self, e: &$$sname, m: &$$sname) -> $$sname {
|
||||
panic!("reduce")
|
||||
}
|
||||
}
|
||||
|]
|
||||
|
||||
generateModulusTests :: RandomGen g => Word -> g -> [Map String String]
|
||||
generateModulusTests size g = go g numTestCases
|
||||
where
|
||||
go _ 0 = []
|
||||
go g0 i =
|
||||
let (x, g1) = generateNum g0 size
|
||||
(y, g2) = generateNum g1 size
|
||||
(m, g3) = generateNum g2 size
|
||||
tcase = Map.fromList [("x", showX x), ("y", showX y),
|
||||
("m", showX m),
|
||||
("r", showX (x `mod` m)),
|
||||
("t", showX ((x * y) `mod` m)),
|
||||
("s", showX ((x * x) `mod` m)),
|
||||
("e", showX (powModInteger x y m))
|
||||
]
|
||||
in if y < 2
|
||||
then go g3 i
|
||||
else tcase : go g3 (i - 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user