Commit the start of the work on modular X before I worry about From.

This commit is contained in:
2020-01-08 15:19:34 -10:00
parent 3e82008189
commit 8c5f18cb7c
5 changed files with 99 additions and 1 deletions

76
generation/src/ModOps.hs Normal file
View 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)