diff --git a/plutus-conformance/agda/Spec.hs b/plutus-conformance/agda/Spec.hs index ce8d1776dcd..b1a2d2ab3fa 100644 --- a/plutus-conformance/agda/Spec.hs +++ b/plutus-conformance/agda/Spec.hs @@ -147,9 +147,8 @@ failingEvaluationTests = -} failingBudgetTests :: [FilePath] failingBudgetTests = - -- These currently fail because (a) the Agda code doesn't know about the - -- IntegerCostedLiterally size measure used by `replicateByte`, and (b) - -- GHC 8.0 can't deal with `dropList`. + -- These currently fail because the Agda code doesn't know about the + -- IntegerCostedLiterally size measure used by `replicateByte` and `dropList`. [ "test-cases/uplc/evaluation/builtin/semantics/replicateByte/case-07" , "test-cases/uplc/evaluation/builtin/semantics/replicateByte/case-09" , "test-cases/uplc/evaluation/builtin/semantics/dropList/dropList-01" diff --git a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-01/expMod-01.uplc.budget.expected b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-01/expMod-01.uplc.budget.expected index 8331e319f3a..e933b9f34e0 100644 --- a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-01/expMod-01.uplc.budget.expected +++ b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-01/expMod-01.uplc.budget.expected @@ -1,2 +1,2 @@ -({cpu: 100000112100 -| mem: 100000000800}) \ No newline at end of file +({cpu: 1004094 +| mem: 801}) \ No newline at end of file diff --git a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-02/expMod-02.uplc.budget.expected b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-02/expMod-02.uplc.budget.expected index 8331e319f3a..e933b9f34e0 100644 --- a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-02/expMod-02.uplc.budget.expected +++ b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-02/expMod-02.uplc.budget.expected @@ -1,2 +1,2 @@ -({cpu: 100000112100 -| mem: 100000000800}) \ No newline at end of file +({cpu: 1004094 +| mem: 801}) \ No newline at end of file diff --git a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-03/expMod-03.uplc.budget.expected b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-03/expMod-03.uplc.budget.expected index 8331e319f3a..e933b9f34e0 100644 --- a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-03/expMod-03.uplc.budget.expected +++ b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-03/expMod-03.uplc.budget.expected @@ -1,2 +1,2 @@ -({cpu: 100000112100 -| mem: 100000000800}) \ No newline at end of file +({cpu: 1004094 +| mem: 801}) \ No newline at end of file diff --git a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-04/expMod-04.uplc.budget.expected b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-04/expMod-04.uplc.budget.expected index 8331e319f3a..e933b9f34e0 100644 --- a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-04/expMod-04.uplc.budget.expected +++ b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-04/expMod-04.uplc.budget.expected @@ -1,2 +1,2 @@ -({cpu: 100000112100 -| mem: 100000000800}) \ No newline at end of file +({cpu: 1004094 +| mem: 801}) \ No newline at end of file diff --git a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-05/expMod-05.uplc.budget.expected b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-05/expMod-05.uplc.budget.expected index 8331e319f3a..e933b9f34e0 100644 --- a/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-05/expMod-05.uplc.budget.expected +++ b/plutus-conformance/test-cases/uplc/evaluation/builtin/semantics/expModInteger/expMod-05/expMod-05.uplc.budget.expected @@ -1,2 +1,2 @@ -({cpu: 100000112100 -| mem: 100000000800}) \ No newline at end of file +({cpu: 1004094 +| mem: 801}) \ No newline at end of file diff --git a/plutus-core/cost-model/budgeting-bench/Benchmarks/Integers.hs b/plutus-core/cost-model/budgeting-bench/Benchmarks/Integers.hs index c2843f95540..2873f0e200a 100644 --- a/plutus-core/cost-model/budgeting-bench/Benchmarks/Integers.hs +++ b/plutus-core/cost-model/budgeting-bench/Benchmarks/Integers.hs @@ -2,10 +2,10 @@ module Benchmarks.Integers (makeBenchmarks) where import Common import Generators - import PlutusCore import Criterion.Main +import GHC.Num.Integer import System.Random (StdGen) ---------------- Integer builtins ---------------- @@ -43,6 +43,47 @@ benchSameTwoIntegers gen builtinName = createTwoTermBuiltinBenchElementwise builtinName [] $ pairWith copyInteger numbers where (numbers,_) = makeBiggerIntegerArgs gen +{- `expModInteger a e m` calculates `a^e` modulo `m`; if `e` is negative then the +function fails unless gcd(a,m) = 1, in which case there is an integer `a'` such +that `a*a'` is congruent to 1 modulo `m`, and then `expModInteger a e m` is +defined to be `expModInteger a' (-e) m`. If `0 <= a <= m-1` and `e>=0` then the +time taken by expModInteger varies linearly with the size of `e` (and the worst +case is when `e` is one less than a power of two) and quadratically with the +size of `m`. A good model can be obtained by fitting a function of the form A + +Byz + Cyz^2 (y=size(e), z=size(m)) to the results of the benchmarks. For most +values of `a` (except for things like 0 and 1), the time taken for +exponentiation is independent of the size of `a` because many intermediate +powers have to be calculated, and these quickly grow so that their size is +similar to that of `m`. In the benchmarks we use `a = m div 3` to start with a +value of reasonable size. + +For exponents `e<0` a little extra time is required to perform an initial +modular inversion, but this only adds a percent or two to the execution time so +for simplicity we benchmark only with positive values of `e`. For values of `a` +with `size(a)>size(m)` an extra modular reduction has to be performed before +starting the main calculation. It is difficult to model the effect of this +precisely, so we impose an extra charge by increasing the cost of +`expModInteger` by 50% for values of `a` with large sizes; to avoid the penalty, +call `modInteger` before calling `expModInteger`. +-} +benchExpModInteger :: StdGen -> Benchmark +benchExpModInteger _gen = + let fun = ExpModInteger + pow (a::Integer) (b::Integer) = a^b + moduli = fmap (\n -> pow 2 (32*n) - 11) [1, 3..31] + -- ^ 16 entries, sizes = 4, 12, ..., 124 bytes (memoryUsage = 1,2,...,16) + es = fmap (\n -> pow 2 (fromIntegral $ integerLog2 n) - 1) moduli + -- ^ Largest number less than modulus with binary expansion 1111...1. + -- This is the worst case. + + in bgroup (show fun) + [bgroup (showMemoryUsage (m `div` 3)) + [bgroup (showMemoryUsage e) + [mkBM a e m | a <- [m `div` 3] ] | e <- es ] | m <- moduli ] + where mkBM a e m = + benchDefault (showMemoryUsage m) $ + mkApp3 ExpModInteger [] a e m + makeBenchmarks :: StdGen -> [Benchmark] makeBenchmarks gen = [benchTwoIntegers gen makeLargeIntegerArgs AddInteger]-- SubtractInteger behaves identically. @@ -52,3 +93,5 @@ makeBenchmarks gen = , LessThanInteger , LessThanEqualsInteger ]) + <> [-- benchExpModInteger gen, + benchExpModInteger gen] diff --git a/plutus-core/cost-model/budgeting-bench/Common.hs b/plutus-core/cost-model/budgeting-bench/Common.hs index e1dcfc6c56a..1812fe78731 100644 --- a/plutus-core/cost-model/budgeting-bench/Common.hs +++ b/plutus-core/cost-model/budgeting-bench/Common.hs @@ -277,6 +277,29 @@ createTwoTermBuiltinBenchWithFlag fun tys flag ys zs = [bgroup (showMemoryUsage y) [mkBM y z | z <- zs] | y <- ys]] where mkBM y z = benchDefault (showMemoryUsage z) $ mkApp3 fun tys flag y z +{- | Given a builtin function f of type a * b -> _ together with lists xs::[a] and + ys::[b], create a collection of benchmarks which run f on all pairs in + {(x,y}: x in xs, y in ys}. -} +createTwoTermBuiltinBenchWithWrappers + :: ( fun ~ DefaultFun + , uni ~ DefaultUni + , uni `HasTermLevel` a + , uni `HasTermLevel` b + , ExMemoryUsage a' + , ExMemoryUsage b' + , NFData a + , NFData b + ) + => (a -> a', b-> b') + -> fun + -> [Type tyname uni ()] + -> [a] + -> [b] + -> Benchmark +createTwoTermBuiltinBenchWithWrappers (wrapX, wrapY) fun tys xs ys = + bgroup (show fun) [bgroup (showMemoryUsage (wrapX x)) [mkBM x y | y <- ys] | x <- xs] + where mkBM x y = benchDefault (showMemoryUsage (wrapY y)) $ mkApp2 fun tys x y + {- | Given a builtin function f of type a * b -> _ together with a list of (a,b) pairs, create a collection of benchmarks which run f on all of the pairs in the list. This can be used when the worst-case execution time of a @@ -379,3 +402,32 @@ createThreeTermBuiltinBenchElementwiseWithWrappers (wrapX, wrapY, wrapZ) fun tys ) inputs where mkBM x y z = benchDefault (showMemoryUsage $ wrapZ z) $ mkApp3 fun tys x y z + + +createThreeTermBuiltinBenchWithWrappers + :: ( fun ~ DefaultFun + , uni ~ DefaultUni + , uni `HasTermLevel` a + , uni `HasTermLevel` b + , uni `HasTermLevel` c + , ExMemoryUsage a' + , ExMemoryUsage b' + , ExMemoryUsage c' + , NFData a + , NFData b + , NFData c + ) + => (a -> a', b-> b', c -> c') + -> fun + -> [Type tyname uni ()] + -> [a] + -> [b] + -> [c] + -> Benchmark +createThreeTermBuiltinBenchWithWrappers (wrapX, wrapY, wrapZ) fun tys xs ys zs = + bgroup (show fun) + [bgroup (showMemoryUsage (wrapX x)) + [bgroup (showMemoryUsage (wrapY y)) + [mkBM x y z | z <- zs] | y <- ys] | x <- xs] + where mkBM x y z = benchDefault (showMemoryUsage (wrapZ z)) $ mkApp3 fun tys x y z + diff --git a/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs b/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs index 327f6558fdf..22b28d928a1 100644 --- a/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs +++ b/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs @@ -160,7 +160,7 @@ builtinMemoryModels = BuiltinCostModelBase , paramWriteBits = Id $ ModelThreeArgumentsLinearInX identityFunction -- The empty bytestring has memory usage 1, so we add an extra memory unit here to make sure that -- the memory cost of `replicateByte` is always nonzero. That means that we're charging one unit - -- ore than we perhaps should for nonempty bytestrings, but that's negligible (plus there's some + -- more than we perhaps should for nonempty bytestrings, but that's negligible (plus there's some -- overhead for bytesrings anyway). Note also that `replicateByte`'s argument is costed as a -- literal size. , paramReplicateByte = Id $ ModelTwoArgumentsLinearInX $ OneVariableLinearFunction 1 1 @@ -169,7 +169,7 @@ builtinMemoryModels = BuiltinCostModelBase , paramCountSetBits = Id $ ModelOneArgumentConstantCost 1 , paramFindFirstSetBit = Id $ ModelOneArgumentConstantCost 1 , paramRipemd_160 = Id $ hashMemModel Hash.ripemd_160 - , paramExpModInteger = Id $ ModelThreeArgumentsConstantCost 100000000000 -- FIXME: stub + , paramExpModInteger = Id $ ModelThreeArgumentsLinearInZ identityFunction -- paramCaseList -- paramCaseData , paramDropList = Id $ ModelTwoArgumentsConstantCost 4 diff --git a/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs b/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs index 5a61ab26d42..c59a516ff88 100644 --- a/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs +++ b/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs @@ -361,6 +361,14 @@ readTwoVariableQuadraticFunction var1 var2 e = do c02 <- Coefficient02 <$> getCoeff (printf "I(%s^2)" var2) e pure $ TwoVariableQuadraticFunction minVal c00 c10 c01 c20 c11 c02 +-- Specialised version of readTwoVariableQuadraticFunction for a*YZ^2 + b*YZ +readExpModCostingFunction :: MonadR m => String -> String -> SomeSEXP (Region m) -> m ExpModCostingFunction +readExpModCostingFunction var1 var2 e = do + c00 <- Coefficient00 <$> getCoeff "(Intercept)" e + c11 <- Coefficient11 <$> getCoeff (printf "I(%s * %s)" var1 var2) e + c12 <- Coefficient12 <$> getCoeff (printf "I(%s * %s^2)" var1 var2) e + pure $ ExpModCostingFunction c00 c11 c12 + -- | A two-variable costing function which is constant on one region of the -- plane and something else elsewhere. readTwoVariableFunConstOr :: MonadR m => SomeSEXP (Region m) -> m ModelConstantOrTwoArguments @@ -429,6 +437,7 @@ readCF3 e = do "quadratic_in_z" -> ModelThreeArgumentsQuadraticInZ <$> readOneVariableQuadraticFunction "z_mem" e "linear_in_y_and_z" -> ModelThreeArgumentsLinearInYAndZ <$> readTwoVariableLinearFunction "y_mem" "z_mem" e "literal_in_y_or_linear_in_z" -> ModelThreeArgumentsLiteralInYOrLinearInZ <$> error "literal" + "exp_mod_cost" -> ModelThreeArgumentsExpModCost <$> readExpModCostingFunction "y_mem" "z_mem" e _ -> error $ "Unknown three-variable model type: " ++ ty readCF6 :: MonadR m => SomeSEXP (Region m) -> m ModelSixArguments diff --git a/plutus-core/cost-model/data/benching-conway.csv b/plutus-core/cost-model/data/benching-conway.csv index 2b04e7a32cd..7147c0618ed 100644 --- a/plutus-core/cost-model/data/benching-conway.csv +++ b/plutus-core/cost-model/data/benching-conway.csv @@ -11536,9 +11536,264 @@ DropList/1128/25015001,3.162749453267043e-6,3.162068091550841e-6,3.1636924811762 DropList/207/25015001,1.3677632818657246e-6,1.366063566784575e-6,1.3702712053968081e-6,6.903273581765479e-9,4.89508668884939e-9,8.508124258033017e-9 DropList/3959/25015001,8.706556596368919e-6,8.705731665456883e-6,8.707361328964902e-6,2.9039371832642988e-9,2.4578524757690477e-9,3.6454321543776463e-9 DropList/1105/25015001,3.118675136929967e-6,3.118069043124161e-6,3.119277340025128e-6,2.124797971472072e-9,1.8136965951328366e-9,2.5336313519274434e-9 -## Temporary fake data to allow us to cost some missing builtins -ExpModInteger/1/1/1,8.706556596368919e-6,8.705731665456883e-6,8.707361328964902e-6,2.9039371832642988e-9,2.4578524757690477e-9,3.6454321543776463e-9 -ExpModInteger/2/2/2,3.118675136929967e-6,3.118069043124161e-6,3.119277340025128e-6,2.124797971472072e-9,1.8136965951328366e-9,2.533631351 +# Plutus Core cost model benchmark results +# Started at 2025-05-08 01:42:23.24298218 UTC +ExpModInteger/1/1/1,1.8228347336231008e-6,1.8216099990570763e-6,1.8241455856342669e-6,4.5106762968613095e-9,3.8488062703711975e-9,5.74343275841329e-9 +ExpModInteger/1/2/1,2.112784034263829e-6,2.1099554823638784e-6,2.1150170149379668e-6,8.057084882846323e-9,6.585037859849818e-9,9.737299133209436e-9 +ExpModInteger/1/3/1,2.384123285442966e-6,2.3827381377385376e-6,2.385753823487332e-6,4.98258710307916e-9,4.2486706418933535e-9,6.190011072521371e-9 +ExpModInteger/1/4/1,2.6717319226158177e-6,2.6700190160674774e-6,2.6730613456606753e-6,5.250121443057067e-9,4.16833837600759e-9,6.684820048102213e-9 +ExpModInteger/1/5/1,2.9310891057736214e-6,2.929715488212664e-6,2.932642787374779e-6,4.922066710753882e-9,3.9960493234812876e-9,6.122803258900307e-9 +ExpModInteger/1/6/1,3.224442502970443e-6,3.2233300427140403e-6,3.22562139196516e-6,3.75518602420052e-9,3.214978615400047e-9,4.596163067428863e-9 +ExpModInteger/1/7/1,3.482487960594203e-6,3.4815950076868955e-6,3.483530329141199e-6,3.330239415209867e-9,2.701020951022132e-9,4.417938659158721e-9 +ExpModInteger/1/8/1,3.7528871227616823e-6,3.750657273670732e-6,3.7555338222032963e-6,8.292760633495276e-9,6.865468946878213e-9,1.0344021722303524e-8 +ExpModInteger/1/9/1,4.014891044861363e-6,4.012986888046596e-6,4.017110862449987e-6,7.043834890735326e-9,6.084742367048627e-9,8.691503345055315e-9 +ExpModInteger/1/10/1,4.304419472941634e-6,4.302977245949014e-6,4.305945850970387e-6,4.992756693499465e-9,4.143421989543066e-9,6.010134838513561e-9 +ExpModInteger/1/11/1,4.566992939346832e-6,4.565723580121979e-6,4.568143595677946e-6,4.260212236261381e-9,3.321443548483328e-9,5.459767833682065e-9 +ExpModInteger/1/12/1,4.777755643188292e-6,4.776515569159774e-6,4.779387459252239e-6,4.7053681486651436e-9,3.877314010505423e-9,6.208817480381897e-9 +ExpModInteger/1/13/1,5.044295941790186e-6,5.042566299254209e-6,5.046194792401175e-6,5.932561354756071e-9,4.848773030792141e-9,7.475387860734627e-9 +ExpModInteger/1/14/1,5.28848217392182e-6,5.286946514182878e-6,5.290125119637775e-6,5.435507613728878e-9,4.5949247705289246e-9,6.47399246885952e-9 +ExpModInteger/1/15/1,5.557479374482044e-6,5.5546116725311e-6,5.5600541516866165e-6,9.1476356602864e-9,8.024465874674394e-9,1.0717067461907429e-8 +ExpModInteger/1/16/1,5.818425539680444e-6,5.817367497954022e-6,5.819453545191856e-6,3.5246351037639196e-9,2.965459820992827e-9,4.215454109376715e-9 +ExpModInteger/2/1/2,2.2680993125161467e-6,2.265665241333137e-6,2.2710280766373717e-6,8.751251212546197e-9,7.482450570771835e-9,1.0562388391444885e-8 +ExpModInteger/2/2/2,3.309103195096071e-6,3.3073292573597e-6,3.310856921038963e-6,5.958832466919273e-9,5.020289336658316e-9,7.1114626129196225e-9 +ExpModInteger/2/3/2,4.347502176149748e-6,4.345669728818631e-6,4.349097727209344e-6,5.665524196779548e-9,4.883258437162053e-9,6.607265855493308e-9 +ExpModInteger/2/4/2,5.389597494930722e-6,5.3878040745842084e-6,5.391866636947685e-6,7.0630399846752165e-9,6.046152039705542e-9,8.748710617995053e-9 +ExpModInteger/2/5/2,6.345432925769315e-6,6.34381547157087e-6,6.34695458681011e-6,5.200405484638413e-9,4.387774165967074e-9,6.3004281874878354e-9 +ExpModInteger/2/6/2,7.348109684709076e-6,7.346473811102091e-6,7.350443872587395e-6,6.122985203162702e-9,4.662269360188356e-9,8.248284585219194e-9 +ExpModInteger/2/7/2,8.341192360735874e-6,8.339124609426233e-6,8.343596256808667e-6,7.47888946181899e-9,6.115475912661752e-9,9.452403697828936e-9 +ExpModInteger/2/8/2,9.329485787752864e-6,9.326964307227145e-6,9.33191724383462e-6,8.430803626229866e-9,6.987940242402612e-9,1.0444304584899787e-8 +ExpModInteger/2/9/2,1.0321335759434707e-5,1.0319392579433385e-5,1.0325106863416155e-5,9.001204991398607e-9,5.726579483031475e-9,1.6304017315789494e-8 +ExpModInteger/2/10/2,1.1311374955088455e-5,1.1308733165797366e-5,1.1314103458350536e-5,9.234472870008716e-9,7.57019190565939e-9,1.1495247925614817e-8 +ExpModInteger/2/11/2,1.2304913399129565e-5,1.2302862498604126e-5,1.2306998934361635e-5,7.081200614016967e-9,6.0016783925196525e-9,9.095227227686993e-9 +ExpModInteger/2/12/2,1.3386525851589674e-5,1.3384488105473855e-5,1.3388652273447853e-5,7.184517091950643e-9,5.950735508009213e-9,9.125994093491463e-9 +ExpModInteger/2/13/2,1.4459672249794707e-5,1.4456648998003195e-5,1.4463392848045285e-5,1.1065719738828394e-8,8.752630065340206e-9,1.4586150454783038e-8 +ExpModInteger/2/14/2,1.5450182859367455e-5,1.544800421494046e-5,1.5452596379531856e-5,7.820794849860752e-9,6.69157048645155e-9,9.375576726785741e-9 +ExpModInteger/2/15/2,1.6440598970655896e-5,1.6438158093326002e-5,1.644783202681469e-5,1.3318081969826572e-8,5.248123427244661e-9,2.6758683877402963e-8 +ExpModInteger/2/16/2,1.7441414945617147e-5,1.743536559277403e-5,1.745409064518748e-5,2.76071316062091e-8,1.4574644911078341e-8,4.787059137479141e-8 +ExpModInteger/3/1/3,2.5756410259130634e-6,2.5742500010840852e-6,2.577171913015196e-6,5.065578700340993e-9,4.4101841635516365e-9,5.978437908083546e-9 +ExpModInteger/3/2/3,4.093212285213128e-6,4.091419966908669e-6,4.094800245456685e-6,5.31983139138428e-9,4.177604307988527e-9,6.771796908651741e-9 +ExpModInteger/3/3/3,5.59513515734787e-6,5.594157329724353e-6,5.596203594769434e-6,3.364138076818459e-9,2.785679509437291e-9,4.522904921361532e-9 +ExpModInteger/3/4/3,7.091819400565278e-6,7.090264992221281e-6,7.093556042669519e-6,5.287898873061789e-9,4.469944256590456e-9,6.320633076647911e-9 +ExpModInteger/3/5/3,8.630197251078525e-6,8.627712049547206e-6,8.632960486807098e-6,8.491909769925818e-9,6.799547793647671e-9,1.1272801528472037e-8 +ExpModInteger/3/6/3,1.0119857451081906e-5,1.0117618110663129e-5,1.0121783510914308e-5,6.658959893649321e-9,5.530821651081087e-9,8.490286981999517e-9 +ExpModInteger/3/7/3,1.1583454554338135e-5,1.1580490413248533e-5,1.1586655433608904e-5,1.0462793794567805e-8,8.436254743273532e-9,1.387648332626546e-8 +ExpModInteger/3/8/3,1.314200461844344e-5,1.312761353106079e-5,1.3152714010759724e-5,3.994097580090048e-8,3.260364089072532e-8,4.645737465239668e-8 +ExpModInteger/3/9/3,1.462664380647528e-5,1.462058292958196e-5,1.4631350881535317e-5,1.767129935307953e-8,1.4340974867270373e-8,2.3822253177202596e-8 +ExpModInteger/3/10/3,1.6122195589782288e-5,1.6115991395266395e-5,1.61306849912132e-5,2.4774114163646948e-8,1.6426977698605764e-8,3.617606333618645e-8 +ExpModInteger/3/11/3,1.7594703358195635e-5,1.7590687244036598e-5,1.760012014563211e-5,1.4992761945592646e-8,1.175440054945857e-8,2.056166353947142e-8 +ExpModInteger/3/12/3,1.879972824294208e-5,1.879767456083704e-5,1.8801560858609936e-5,6.814369539843547e-9,5.654624795417815e-9,8.439449104448713e-9 +ExpModInteger/3/13/3,2.0231060749598724e-5,2.022474213434344e-5,2.0255317104061083e-5,3.804228855912211e-8,6.848021640194112e-9,8.027250844614031e-8 +ExpModInteger/3/14/3,2.1662103452720718e-5,2.1658730234992298e-5,2.166576839200423e-5,1.1950817771420637e-8,9.3399428145896e-9,1.7632728956512425e-8 +ExpModInteger/3/15/3,2.3102273159604392e-5,2.309769875018025e-5,2.3110480983917832e-5,1.942924085339274e-8,1.271331617213178e-8,3.4537342152885586e-8 +ExpModInteger/3/16/3,2.4520108594618834e-5,2.4516236484378162e-5,2.4524898491952813e-5,1.4256807862061776e-8,1.1198596045853915e-8,1.875466471928537e-8 +ExpModInteger/4/1/4,2.9409071872033726e-6,2.939369738463045e-6,2.94244387546413e-6,5.2670493373690845e-9,4.3649080950092945e-9,6.839004608259683e-9 +ExpModInteger/4/2/4,5.225644194668169e-6,5.223863731158886e-6,5.227590103161111e-6,6.089939033614845e-9,4.863246847595974e-9,7.741553804857344e-9 +ExpModInteger/4/3/4,7.517907160044657e-6,7.511556428930104e-6,7.53231657238332e-6,3.075794069937893e-8,1.4333757361139343e-8,4.776255462759552e-8 +ExpModInteger/4/4/4,9.77334059733028e-6,9.770843247384106e-6,9.776386361201574e-6,9.346676052466247e-9,7.354382914819846e-9,1.3749740321791333e-8 +ExpModInteger/4/5/4,1.1887974123676518e-5,1.1886158570526175e-5,1.189010798295999e-5,6.888982241321927e-9,5.327384185789607e-9,9.851687748737309e-9 +ExpModInteger/4/6/4,1.4067344573817297e-5,1.406479191153085e-5,1.4072833587295573e-5,1.1875421634417906e-8,6.217663894013208e-9,2.163055814712524e-8 +ExpModInteger/4/7/4,1.6245664254319644e-5,1.6242850728753937e-5,1.6249201757995493e-5,1.0852124014521091e-8,8.3830101379296e-9,1.4519802701056432e-8 +ExpModInteger/4/8/4,1.8414372180694667e-5,1.8410575170933147e-5,1.84276206244817e-5,2.1065801989407318e-8,9.119553319973346e-9,4.189620429336517e-8 +ExpModInteger/4/9/4,2.0654207253172492e-5,2.0632597144518588e-5,2.068369743457412e-5,8.375157885936123e-8,6.178393760016727e-8,1.0000836036079593e-7 +ExpModInteger/4/10/4,2.2797495415106554e-5,2.2793594641568865e-5,2.2801659415081113e-5,1.3176095792744297e-8,1.0848984358255009e-8,1.6783721074271505e-8 +ExpModInteger/4/11/4,2.495127257151414e-5,2.4947638639609366e-5,2.495657712582876e-5,1.444170007022046e-8,1.104262308033242e-8,2.1586093215501092e-8 +ExpModInteger/4/12/4,2.6787019490752368e-5,2.6783304319845207e-5,2.6790859189586217e-5,1.288574115295364e-8,1.0384466250126982e-8,1.6735467755046728e-8 +ExpModInteger/4/13/4,2.8907110209553295e-5,2.890179293411642e-5,2.8913238561298817e-5,1.888493136233226e-8,1.4017616459694591e-8,2.703003329765554e-8 +ExpModInteger/4/14/4,3.098107803559441e-5,3.097664657693207e-5,3.098806201045569e-5,1.755545921970251e-8,1.268137713650454e-8,2.808174538342654e-8 +ExpModInteger/4/15/4,3.311425232930764e-5,3.310972682213549e-5,3.31190349576487e-5,1.588182966193269e-8,1.3531468279315326e-8,1.9816130135242232e-8 +ExpModInteger/4/16/4,3.520294469170209e-5,3.51962170499305e-5,3.520803307943844e-5,1.8561759098722934e-8,1.4671092078625508e-8,2.6953379158826428e-8 +ExpModInteger/5/1/5,3.354724828666543e-6,3.35287770532147e-6,3.356619302535707e-6,6.465375907268581e-9,5.573165250869173e-9,7.699395345240103e-9 +ExpModInteger/5/2/5,6.431170442089721e-6,6.42953581399996e-6,6.4329036494698e-6,5.6566620697348085e-9,4.6338189171555684e-9,7.1843282142230096e-9 +ExpModInteger/5/3/5,9.516656463868377e-6,9.514998993896443e-6,9.518221972342777e-6,5.3721224757328256e-9,4.406195060813882e-9,7.147195585900385e-9 +ExpModInteger/5/4/5,1.2584262087166136e-5,1.2581520902606458e-5,1.2590489633774257e-5,1.3341424407488641e-8,6.531768895582546e-9,2.7106613065327742e-8 +ExpModInteger/5/5/5,1.5242170393328718e-5,1.523748370142456e-5,1.5257425413857703e-5,2.5528471793845843e-8,8.112693106633675e-9,5.232260582411289e-8 +ExpModInteger/5/6/5,1.814281195734368e-5,1.8138482592188235e-5,1.8160300034094892e-5,2.4767909088057917e-8,7.94591703438611e-9,5.4798544636123993e-8 +ExpModInteger/5/7/5,2.1000199966971677e-5,2.0996565124108347e-5,2.1003518814132567e-5,1.2134893469084242e-8,9.046695459153038e-9,1.9034008939028083e-8 +ExpModInteger/5/8/5,2.393602091554451e-5,2.3930331131561054e-5,2.3943019905815295e-5,2.084833628539155e-8,1.5828613880534948e-8,2.9391492885384713e-8 +ExpModInteger/5/9/5,2.6827212880685606e-5,2.6822049567590448e-5,2.6832396214501837e-5,1.7680946969498252e-8,1.4708858468382233e-8,2.1984535242312994e-8 +ExpModInteger/5/10/5,2.9674768293949918e-5,2.966870278120055e-5,2.9683278242314843e-5,2.460573932482932e-8,1.9665512321565694e-8,3.403995168067655e-8 +ExpModInteger/5/11/5,3.253850211180827e-5,3.2533194359860436e-5,3.2544929773798824e-5,2.0241312032882755e-8,1.5067786399639665e-8,2.9197840051381343e-8 +ExpModInteger/5/12/5,3.501657200004189e-5,3.500895709037963e-5,3.50233432047258e-5,2.444058467200746e-8,2.0129853140380165e-8,3.13293019856511e-8 +ExpModInteger/5/13/5,3.776935307108384e-5,3.77616377331353e-5,3.778631981270041e-5,3.586368655480029e-8,2.1734900458866117e-8,5.9334401083584125e-8 +ExpModInteger/5/14/5,4.054641140099823e-5,4.053756057993754e-5,4.055548063357066e-5,3.045551321025548e-8,2.399737237256369e-8,3.862399478156736e-8 +ExpModInteger/5/15/5,4.3416205670735995e-5,4.34054145842546e-5,4.344014002626813e-5,4.9025262961994404e-8,2.6939231650736435e-8,8.79425800660528e-8 +ExpModInteger/5/16/5,4.6186179926836635e-5,4.6169359630559366e-5,4.620385076609294e-5,5.9299616171239924e-8,4.487639349827058e-8,8.749778160490382e-8 +ExpModInteger/6/1/6,3.9666021137434965e-6,3.96443831012144e-6,3.968378270460624e-6,6.7378232065018625e-9,5.948277038216584e-9,8.032529718634988e-9 +ExpModInteger/6/2/6,7.997391270499395e-6,7.995599609457676e-6,7.999640482431627e-6,6.840007804942249e-9,5.538506314281946e-9,9.781162728678546e-9 +ExpModInteger/6/3/6,1.2019117714591882e-5,1.2016460384607508e-5,1.2021607725879027e-5,8.072346420811863e-9,6.68352028430364e-9,9.984531188500708e-9 +ExpModInteger/6/4/6,1.609344151405771e-5,1.608969750346763e-5,1.6099513064266097e-5,1.6064508009447075e-8,1.0551136868465316e-8,2.59231786746605e-8 +ExpModInteger/6/5/6,1.975788089933164e-5,1.975513846166324e-5,1.9762307355290604e-5,1.1381021972996235e-8,7.415039075136974e-9,1.8940995123395587e-8 +ExpModInteger/6/6/6,2.362657695638066e-5,2.362200889698117e-5,2.364035872617079e-5,2.3994484654680115e-8,9.700155397771197e-9,5.6819334415925776e-8 +ExpModInteger/6/7/6,2.7450983488751718e-5,2.7446946279761554e-5,2.7457688559401084e-5,1.6354474977079035e-8,1.1682013799049129e-8,2.5841745816758338e-8 +ExpModInteger/6/8/6,3.129114066095493e-5,3.128644207907487e-5,3.129648690379516e-5,1.753467451125736e-8,1.4182377956862495e-8,2.1694901266512265e-8 +ExpModInteger/6/9/6,3.521609290708864e-5,3.5210889556807776e-5,3.522462787204329e-5,2.175594653687702e-8,1.4957291074768716e-8,3.5661128705445175e-8 +ExpModInteger/6/10/6,3.910630599532741e-5,3.909988821442929e-5,3.911329194781671e-5,2.215687469211568e-8,1.815230627261498e-8,2.6670120340480992e-8 +ExpModInteger/6/11/6,4.296364840025001e-5,4.2955925788370225e-5,4.2974413807046245e-5,3.030988931551078e-8,2.173359436911435e-8,4.983404861367728e-8 +ExpModInteger/6/12/6,4.617266746831716e-5,4.616610593218925e-5,4.618073604931968e-5,2.4123759289740055e-8,1.8680163326129256e-8,3.5491531353192315e-8 +ExpModInteger/6/13/6,4.992934391782583e-5,4.9920431406528376e-5,4.994679338357509e-5,3.884506533349136e-8,2.375946982178444e-8,6.917793771843583e-8 +ExpModInteger/6/14/6,5.3627339888285045e-5,5.3619859758050956e-5,5.363942960975076e-5,3.156646132016108e-8,2.2043489520881013e-8,5.151283456737684e-8 +ExpModInteger/6/15/6,5.734922395322597e-5,5.73384890916479e-5,5.736010346470369e-5,3.5605440055823066e-8,2.9220459367199937e-8,4.406273752598194e-8 +ExpModInteger/6/16/6,6.113193400110475e-5,6.11223493087583e-5,6.114208574068398e-5,3.454519659195044e-8,2.801617882471184e-8,4.7953562608368146e-8 +ExpModInteger/7/1/7,4.404135044210333e-6,4.402489602154339e-6,4.405673978444305e-6,5.79023736330969e-9,4.902112994159961e-9,6.8911887298848684e-9 +ExpModInteger/7/2/7,9.25037753768417e-6,9.24842347448124e-6,9.252931818006831e-6,7.48128489857998e-9,5.6516133532250365e-9,1.2114257193328432e-8 +ExpModInteger/7/3/7,1.4006119198038278e-5,1.398879915705424e-5,1.4025956833029465e-5,6.474770519368117e-8,6.066307808102816e-8,6.891474655906865e-8 +ExpModInteger/7/4/7,1.877578789840769e-5,1.8772025234951054e-5,1.8779485015657534e-5,1.2434711746267354e-8,9.56323314338521e-9,1.65736598467092e-8 +ExpModInteger/7/5/7,2.312747579966873e-5,2.3124903868768613e-5,2.3130328836166522e-5,9.516607774126172e-9,8.111920806918753e-9,1.1864651563261576e-8 +ExpModInteger/7/6/7,2.7721475160519222e-5,2.7717628713973863e-5,2.7725096529456872e-5,1.2396550375752932e-8,1.0503560801555607e-8,1.542495992445418e-8 +ExpModInteger/7/7/7,3.227559043268124e-5,3.227019141149339e-5,3.228080409030234e-5,1.8294414142927798e-8,1.492638346137865e-8,2.2496396083636902e-8 +ExpModInteger/7/8/7,3.691086135490302e-5,3.690421031867372e-5,3.6918289433821976e-5,2.3125680587332135e-8,1.811534065620299e-8,3.3797137198462283e-8 +ExpModInteger/7/9/7,4.1483750617151316e-5,4.146401411500448e-5,4.1492926713235624e-5,4.273399310102451e-8,2.5823319298748482e-8,7.328261529791483e-8 +ExpModInteger/7/10/7,4.5945506823669026e-5,4.5913459948255846e-5,4.5975263316646326e-5,1.067004419322991e-7,9.707936579801019e-8,1.2220384752055066e-7 +ExpModInteger/7/11/7,5.065110829400596e-5,5.064472928799211e-5,5.065751205726778e-5,2.113371982508892e-8,1.5725897987075063e-8,2.9224981813891446e-8 +ExpModInteger/7/12/7,5.432759652831777e-5,5.432271443092315e-5,5.433362854820845e-5,1.7548167169392352e-8,1.3951971070985883e-8,2.4229931560624708e-8 +ExpModInteger/7/13/7,5.8740578859914304e-5,5.873249465558387e-5,5.874727284993408e-5,2.5400675977470194e-8,2.072179250101458e-8,3.171865667999478e-8 +ExpModInteger/7/14/7,6.314959329867474e-5,6.314136424832558e-5,6.315832545769517e-5,2.9657076418108674e-8,2.4189801347474266e-8,3.6740667267982266e-8 +ExpModInteger/7/15/7,6.758803807309831e-5,6.757912987790433e-5,6.759868180562288e-5,3.215973181295778e-8,2.5238330034030118e-8,4.224745613182336e-8 +ExpModInteger/7/16/7,7.207147666729457e-5,7.206075652997437e-5,7.208031390964395e-5,3.438726928378177e-8,2.7956295157435983e-8,4.8886891873257274e-8 +ExpModInteger/8/1/8,4.808061616453617e-6,4.803974355898818e-6,4.811327543492992e-6,1.21590383522786e-8,1.0458899039614117e-8,1.4975451659266914e-8 +ExpModInteger/8/2/8,1.0265201675160051e-5,1.0263263640395471e-5,1.0267536990815509e-5,7.24355427551853e-9,5.840982098432887e-9,1.02091321375496e-8 +ExpModInteger/8/3/8,1.5792426833524865e-5,1.578921042795707e-5,1.5799218518131428e-5,1.5792703098177153e-8,9.04367514373978e-9,2.814750177809488e-8 +ExpModInteger/8/4/8,2.133847262918044e-5,2.133395076196166e-5,2.1343123729535114e-5,1.5950011178957585e-8,1.3546364154641011e-8,2.2389071027935768e-8 +ExpModInteger/8/5/8,2.626524623277942e-5,2.6260175358535248e-5,2.627081652432357e-5,1.8125595050382796e-8,1.5254406527622526e-8,2.292941402227316e-8 +ExpModInteger/8/6/8,3.150336959459355e-5,3.1497370353080506e-5,3.1514385830742305e-5,2.608066124653199e-8,1.7571008330909443e-8,4.451470635740249e-8 +ExpModInteger/8/7/8,3.6803910174834786e-5,3.6773763369089256e-5,3.683659677760924e-5,1.1124149040769378e-7,1.0050692392678389e-7,1.2056724182034622e-7 +ExpModInteger/8/8/8,4.2042584843966043e-5,4.201707856380073e-5,4.207456865292948e-5,9.804575172705172e-8,8.438102485966198e-8,1.1518852969830177e-7 +ExpModInteger/8/9/8,4.739412327758673e-5,4.736095766068893e-5,4.7425668332511716e-5,1.0473083772336462e-7,9.102003856614127e-8,1.196687193770203e-7 +ExpModInteger/8/10/8,5.283489212543426e-5,5.2811192069755845e-5,5.2853024472560585e-5,7.27253652728828e-8,4.96778391632828e-8,1.0316286761937602e-7 +ExpModInteger/8/11/8,5.820915286559177e-5,5.820265913508803e-5,5.821768893090438e-5,2.5269073672593082e-8,1.8335798355624316e-8,3.9614272702503405e-8 +ExpModInteger/8/12/8,6.25928814029172e-5,6.258001926277238e-5,6.261245107483046e-5,5.318300137677904e-8,3.4539778300716124e-8,8.163434194034459e-8 +ExpModInteger/8/13/8,6.796825848096456e-5,6.791669662564468e-5,6.802184828931372e-5,1.818110098098088e-7,1.598395297364508e-7,2.0628718930529505e-7 +ExpModInteger/8/14/8,7.296788465715265e-5,7.28915213253347e-5,7.30429245911866e-5,2.3876805834362576e-7,2.174380957258505e-7,2.668834752401007e-7 +ExpModInteger/8/15/8,7.792995729934702e-5,7.791676520064202e-5,7.794362777244847e-5,4.455364629478478e-8,3.5188695616999747e-8,5.7520950846340935e-8 +ExpModInteger/8/16/8,8.311696400387245e-5,8.305744582169805e-5,8.320049257510294e-5,2.2700862156212793e-7,1.6980468475444756e-7,2.778925178677765e-7 +ExpModInteger/9/1/9,5.557348164081282e-6,5.554367413416164e-6,5.56003615829561e-6,9.971566741788156e-9,8.729909102653877e-9,1.1660128933068664e-8 +ExpModInteger/9/2/9,1.2477208924805884e-5,1.2474973565981453e-5,1.2479238478614835e-5,7.320039988205116e-9,6.419568244110487e-9,8.826909040124734e-9 +ExpModInteger/9/3/9,1.937698264478513e-5,1.9374455831906452e-5,1.937976468993649e-5,9.053096891593917e-9,7.436093089051592e-9,1.1382936359421285e-8 +ExpModInteger/9/4/9,2.6198084124379133e-5,2.619332549218408e-5,2.6204702021996516e-5,1.8561665260857392e-8,1.3060175056804053e-8,3.115954107546139e-8 +ExpModInteger/9/5/9,3.2248656207020546e-5,3.224393399524583e-5,3.2253090406344375e-5,1.4954759697236557e-8,1.1473244446412229e-8,1.8801132617700312e-8 +ExpModInteger/9/6/9,3.8787746820054684e-5,3.878108454047955e-5,3.879445744169735e-5,2.262906911741196e-8,1.860014301091847e-8,2.7830029697157794e-8 +ExpModInteger/9/7/9,4.525420043192851e-5,4.524611970435131e-5,4.5262259657672365e-5,2.691939524397686e-8,2.2995851440569022e-8,3.29043337416413e-8 +ExpModInteger/9/8/9,5.1777002786069636e-5,5.176560108820014e-5,5.179579887577009e-5,4.682515239486012e-8,3.030666728674578e-8,8.336956244940366e-8 +ExpModInteger/9/9/9,5.831210207171097e-5,5.829913078635798e-5,5.83230286106763e-5,4.03226956185193e-8,3.341627844885689e-8,4.9780206022444294e-8 +ExpModInteger/9/10/9,6.495503529164381e-5,6.493976358981648e-5,6.497871188311188e-5,6.703139962673079e-8,4.867541325386717e-8,1.1121186417539247e-7 +ExpModInteger/9/11/9,7.13693195949542e-5,7.136075737402749e-5,7.137949070640152e-5,3.32965515214686e-8,2.6903630778783193e-8,4.542740323566911e-8 +ExpModInteger/9/12/9,7.63187606334608e-5,7.630187801742694e-5,7.63416285981018e-5,6.67625289389205e-8,5.197047090481216e-8,8.419837691133111e-8 +ExpModInteger/9/13/9,8.26756470758758e-5,8.265961923448351e-5,8.269837402319215e-5,5.979823603209361e-8,4.9289981188129357e-8,7.353435551260478e-8 +ExpModInteger/9/14/9,8.889165621644655e-5,8.884399663018756e-5,8.897056221954154e-5,1.976523776710191e-7,1.2138524344458494e-7,2.7050210622207707e-7 +ExpModInteger/9/15/9,9.574210622452697e-5,9.572314149189733e-5,9.576426938308191e-5,6.83651939479545e-8,5.3772208656921504e-8,9.21544473167988e-8 +ExpModInteger/9/16/9,1.021016609216632e-4,1.0207832122677433e-4,1.0212866726659047e-4,8.632220300303518e-8,7.184073357605977e-8,1.0813121892639277e-7 +ExpModInteger/10/1/10,6.330841626856171e-6,6.328736695167464e-6,6.333609216642832e-6,8.126913613054205e-9,6.13368013386624e-9,1.2720067079102523e-8 +ExpModInteger/10/2/10,1.4618257216408086e-5,1.4615391168982917e-5,1.4621190807357122e-5,9.754754896535855e-9,7.87602885900466e-9,1.257617300120145e-8 +ExpModInteger/10/3/10,2.30341903609561e-5,2.3027892880628475e-5,2.3048203701274148e-5,3.1168656885694154e-8,1.447745970204764e-8,6.029826931505578e-8 +ExpModInteger/10/4/10,3.114662868420776e-5,3.113924219486244e-5,3.115535952178272e-5,2.7215328152716233e-8,2.186398326405432e-8,3.6992942242376195e-8 +ExpModInteger/10/5/10,3.873759178986647e-5,3.873183310356525e-5,3.8744360737158454e-5,2.0964844465776204e-8,1.696814878925177e-8,2.675056340397168e-8 +ExpModInteger/10/6/10,4.6671604125758744e-5,4.66637618652697e-5,4.668172690797592e-5,3.0710257395949304e-8,2.280719740392531e-8,4.4496548164292e-8 +ExpModInteger/10/7/10,5.447690167112361e-5,5.446666464931763e-5,5.4488890709367656e-5,3.725305777246177e-8,2.7652587667091948e-8,5.255809646464993e-8 +ExpModInteger/10/8/10,6.243440164410324e-5,6.242433559212323e-5,6.245388334895231e-5,4.545597031323702e-8,2.6958985929839946e-8,8.109938002499166e-8 +ExpModInteger/10/9/10,7.042753827746608e-5,7.041104032567611e-5,7.044254842849806e-5,5.051297710407002e-8,4.287575160555214e-8,6.092466122195036e-8 +ExpModInteger/10/10/10,7.84115632792411e-5,7.83877908075643e-5,7.843215813550238e-5,7.600307618432201e-8,6.202814685638719e-8,9.885297032647746e-8 +ExpModInteger/10/11/10,8.629456959919471e-5,8.627313852004933e-5,8.631983160562954e-5,7.607702231994159e-8,6.228477408889633e-8,1.003128058244321e-7 +ExpModInteger/10/12/10,9.269336615632357e-5,9.267908303278884e-5,9.27092397429507e-5,5.083093422823379e-8,4.200198511091432e-8,6.320006282998549e-8 +ExpModInteger/10/13/10,1.0042606434394635e-4,1.004087908747131e-4,1.0044506908736435e-4,6.366929111734517e-8,5.0736755335037196e-8,7.947339912063996e-8 +ExpModInteger/10/14/10,1.0794577220771692e-4,1.0792612591130768e-4,1.0796229962391587e-4,5.739290832198841e-8,4.6565590497551544e-8,7.44176203280156e-8 +ExpModInteger/10/15/10,1.1556027122493899e-4,1.155305336616789e-4,1.1559446843060651e-4,1.0734130378676647e-7,8.982290272305042e-8,1.3640119818818222e-7 +ExpModInteger/10/16/10,1.2330591534811484e-4,1.2327877321573883e-4,1.2333745946698182e-4,1.0668108023044361e-7,8.945183367936947e-8,1.3190934567107154e-7 +ExpModInteger/11/1/11,7.094912548000572e-6,7.093058682296796e-6,7.096832318740756e-6,6.4396916943214335e-9,5.394850599172593e-9,8.411566164001557e-9 +ExpModInteger/11/2/11,1.667097951512822e-5,1.6668542576485646e-5,1.667289065837578e-5,7.49858780830058e-9,6.141257839208523e-9,9.571729042931209e-9 +ExpModInteger/11/3/11,2.625574717524446e-5,2.625206665542026e-5,2.6260262491652e-5,1.4684894068847566e-8,1.1612681668373202e-8,1.8691113813779146e-8 +ExpModInteger/11/4/11,3.586279700327909e-5,3.585686576534303e-5,3.5869527523055245e-5,2.0602688444587605e-8,1.750233048286152e-8,2.426030451367832e-8 +ExpModInteger/11/5/11,4.438804354248495e-5,4.4337444668045135e-5,4.4422162063429946e-5,1.4111968927941964e-7,1.0250403078288168e-7,1.7608915475134823e-7 +ExpModInteger/11/6/11,5.3636224609157295e-5,5.362849234262356e-5,5.3645728993738685e-5,3.15626698522815e-8,2.535673399278939e-8,4.1282356469286004e-8 +ExpModInteger/11/7/11,6.271690459936261e-5,6.270911989481552e-5,6.272629402363814e-5,2.865704108442172e-8,2.2481380499269217e-8,3.843825916273379e-8 +ExpModInteger/11/8/11,7.191518265437033e-5,7.190263979992505e-5,7.19276112367033e-5,4.281923397548542e-8,3.569444286689075e-8,5.351349297995101e-8 +ExpModInteger/11/9/11,8.10362101527235e-5,8.10154001949901e-5,8.106182413544404e-5,7.298166696684939e-8,5.777017865362471e-8,9.180924232254655e-8 +ExpModInteger/11/10/11,9.015341712739247e-5,9.013281122183536e-5,9.017530196409996e-5,7.150364800904244e-8,5.926122937133503e-8,8.785527895858926e-8 +ExpModInteger/11/11/11,9.936382919113472e-5,9.934343623132817e-5,9.938360137250435e-5,6.817691684365973e-8,5.25047218800941e-8,9.732540972757757e-8 +ExpModInteger/11/12/11,1.0742610072434129e-4,1.0741358660876994e-4,1.074405610360015e-4,4.6113058606517455e-8,3.854730306866156e-8,5.4448896992621334e-8 +ExpModInteger/11/13/11,1.162921744560175e-4,1.1627465595080607e-4,1.163126847532074e-4,6.373475769981372e-8,5.225340940262495e-8,8.122083034233562e-8 +ExpModInteger/11/14/11,1.2523220883590424e-4,1.2520705087915328e-4,1.252563588050517e-4,8.197933941778347e-8,6.427212397794446e-8,1.0929027004409998e-7 +ExpModInteger/11/15/11,1.3399410788362715e-4,1.3395548515980144e-4,1.3401832863595053e-4,9.654706624627156e-8,7.116149868693854e-8,1.4585736135631917e-7 +ExpModInteger/11/16/11,1.4317268841544312e-4,1.4315556921324412e-4,1.4319228224960793e-4,6.17801908175214e-8,4.759375114670648e-8,8.423786416717777e-8 +ExpModInteger/12/1/12,7.584995760765328e-6,7.583650995076819e-6,7.586173451855598e-6,4.103685518917369e-9,3.4400452274797564e-9,5.055848127688786e-9 +ExpModInteger/12/2/12,1.8073605927399375e-5,1.80709996350089e-5,1.8075990445231068e-5,8.456275694299126e-9,6.896498853366896e-9,1.0907897378421402e-8 +ExpModInteger/12/3/12,2.8554751389065508e-5,2.8548973398135602e-5,2.855977236585441e-5,1.763404388055871e-8,1.4304827381598662e-8,2.199712692629053e-8 +ExpModInteger/12/4/12,3.900977632283192e-5,3.9004261173982555e-5,3.901581479869624e-5,1.9400492128250598e-8,1.4891131165202283e-8,2.6546230667760994e-8 +ExpModInteger/12/5/12,4.8406129008055077e-5,4.839943538766397e-5,4.841222199681151e-5,2.1884887718741143e-8,1.7725144770334807e-8,2.671545873593495e-8 +ExpModInteger/12/6/12,5.8427036586064915e-5,5.841935801022089e-5,5.843727412106568e-5,2.903607858201201e-8,2.1804696194671175e-8,4.5135320708302585e-8 +ExpModInteger/12/7/12,6.828451798629368e-5,6.82756118611376e-5,6.830008618726066e-5,4.018658931380847e-8,2.532991157577082e-8,6.800991487252379e-8 +ExpModInteger/12/8/12,7.829786269880242e-5,7.828638996506994e-5,7.830912282095462e-5,4.087750374725565e-8,3.408684546896344e-8,4.920041105203371e-8 +ExpModInteger/12/9/12,8.82569024014228e-5,8.824413334551846e-5,8.827493993417166e-5,5.024302006887289e-8,3.902068546199477e-8,6.728310482229351e-8 +ExpModInteger/12/10/12,9.82874003479927e-5,9.827547309800697e-5,9.830032881121692e-5,4.3608517999872113e-8,3.4903828746527734e-8,5.619847015695058e-8 +ExpModInteger/12/11/12,1.0827948778198182e-4,1.0825935964220845e-4,1.0830063107381684e-4,7.220740940951275e-8,6.130088015743451e-8,9.576406761835019e-8 +ExpModInteger/12/12/12,1.1663659475830977e-4,1.166216602409079e-4,1.1665344347851313e-4,5.6070449337380806e-8,4.402315611341415e-8,7.460715097110545e-8 +ExpModInteger/12/13/12,1.2644366694273477e-4,1.2641912805966672e-4,1.2646585799773097e-4,7.985555722877466e-8,6.782315631842856e-8,9.833615727458051e-8 +ExpModInteger/12/14/12,1.3583230873046818e-4,1.3580343460339032e-4,1.3586218416014945e-4,9.930725878735298e-8,7.500732643212742e-8,1.34797615227025e-7 +ExpModInteger/12/15/12,1.4556092361458464e-4,1.4554042438512044e-4,1.4558062529070496e-4,7.042966264713551e-8,6.040341509575988e-8,8.946388047706149e-8 +ExpModInteger/12/16/12,1.554132030349591e-4,1.5539094021586942e-4,1.554331523269001e-4,7.339950878010969e-8,6.11556698577812e-8,9.358692635000181e-8 +ExpModInteger/13/1/13,8.675613765208785e-6,8.67333487275384e-6,8.677714140029025e-6,7.195617929705148e-9,5.725825455502738e-9,9.598102684940787e-9 +ExpModInteger/13/2/13,2.115206987256636e-5,2.114744198871675e-5,2.1157261707065166e-5,1.6874893404889312e-8,1.395022319872379e-8,2.1115733002987862e-8 +ExpModInteger/13/3/13,3.360669506262951e-5,3.3602363933018556e-5,3.361245735344574e-5,1.6310810116893947e-8,1.294974312623603e-8,2.035441974934788e-8 +ExpModInteger/13/4/13,4.606393090982372e-5,4.6054259290181655e-5,4.6075782852019384e-5,3.652039588368384e-8,2.8161652002228966e-8,4.7084112490255314e-8 +ExpModInteger/13/5/13,5.7174861290143886e-5,5.7159794062993764e-5,5.719203343088456e-5,5.2550763413657956e-8,4.382683525844031e-8,6.714454059515994e-8 +ExpModInteger/13/6/13,6.909546190859961e-5,6.907891986845532e-5,6.911003654652126e-5,5.204976466552813e-8,4.228468284542662e-8,6.757011029337106e-8 +ExpModInteger/13/7/13,8.093541584640342e-5,8.091831523473979e-5,8.095822521091515e-5,6.553634642879221e-8,5.3247701175216324e-8,8.413142681149426e-8 +ExpModInteger/13/8/13,9.199708225343214e-5,9.197442417973239e-5,9.202303019636396e-5,8.12307260680086e-8,6.652214031546477e-8,1.183484449926037e-7 +ExpModInteger/13/9/13,1.0373183798800248e-4,1.0369840317833849e-4,1.0376007533193807e-4,1.018831197434604e-7,8.012721585519318e-8,1.3710243670887798e-7 +ExpModInteger/13/10/13,1.153694628391741e-4,1.1533764893753974e-4,1.1541286806194084e-4,1.2767300394278514e-7,1.0666525270313094e-7,1.601295594400592e-7 +ExpModInteger/13/11/13,1.2697588642864878e-4,1.2691604886241553e-4,1.2704637944414412e-4,2.218863635608597e-7,1.515204518306281e-7,3.906351078547308e-7 +ExpModInteger/13/12/13,1.3685997720083113e-4,1.3682469157014063e-4,1.3689727460656438e-4,1.2462852325179707e-7,9.834252712706926e-8,1.6157033765814837e-7 +ExpModInteger/13/13/13,1.483459912720506e-4,1.4831371992503803e-4,1.4838078328889854e-4,1.1563256264132264e-7,9.498345387277959e-8,1.4219127986568095e-7 +ExpModInteger/13/14/13,1.606719254620353e-4,1.6046009936108123e-4,1.6083877710127927e-4,6.661161967811831e-7,5.449843637040805e-7,7.77627349509844e-7 +ExpModInteger/13/15/13,1.7273735367368773e-4,1.726575939754591e-4,1.7279935495424022e-4,2.345503538442312e-7,1.9000119298523565e-7,3.058557990851887e-7 +ExpModInteger/13/16/13,1.8439266463990685e-4,1.8433629180658414e-4,1.8445565588048174e-4,2.1116957432420008e-7,1.7627610991288085e-7,2.701302825357101e-7 +ExpModInteger/14/1/14,9.951056237480015e-6,9.948033466450873e-6,9.956462020771082e-6,1.3370741583041727e-8,8.50299090463598e-9,2.181782054705998e-8 +ExpModInteger/14/2/14,2.4705215199196094e-5,2.4700413544102568e-5,2.471014708562772e-5,1.6807918520191432e-8,1.3075569136176493e-8,2.2218156494564036e-8 +ExpModInteger/14/3/14,3.954336919716509e-5,3.9535022305160614e-5,3.9551365616245485e-5,2.87778272519454e-8,2.302116012662396e-8,3.610418215812323e-8 +ExpModInteger/14/4/14,5.4328850397986823e-5,5.431583512152312e-5,5.435580756852238e-5,5.717965402397878e-8,3.833351572835512e-8,9.879748686687572e-8 +ExpModInteger/14/5/14,6.76278010034262e-5,6.761636675992345e-5,6.764022975964895e-5,4.029085810887434e-8,3.3344100058211435e-8,4.942932029237036e-8 +ExpModInteger/14/6/14,8.177177679335273e-5,8.175406753844835e-5,8.179531200933877e-5,6.894639574392936e-8,5.340163335675383e-8,1.0849327266880632e-7 +ExpModInteger/14/7/14,9.574438541029677e-5,9.572348634592907e-5,9.576559827138434e-5,7.42035648658304e-8,5.767939965914786e-8,1.0079583761606921e-7 +ExpModInteger/14/8/14,1.0976238563723872e-4,1.0972892104544653e-4,1.0979214316606307e-4,1.087686218621153e-7,8.44521443321014e-8,1.506216618240728e-7 +ExpModInteger/14/9/14,1.240556981994965e-4,1.2402790934675786e-4,1.2408870485769894e-4,1.0247854407096352e-7,8.389022580252244e-8,1.3160658872029173e-7 +ExpModInteger/14/10/14,1.3791110418556372e-4,1.378591454612792e-4,1.3797081045925516e-4,1.8390467303396346e-7,1.3511705811252465e-7,3.1199805893723823e-7 +ExpModInteger/14/11/14,1.5233820152188107e-4,1.522982706649204e-4,1.523892657074702e-4,1.4898902768950655e-7,1.1863398201195004e-7,2.1944082699126976e-7 +ExpModInteger/14/12/14,1.6922298082789805e-4,1.6911305278627126e-4,1.6933484060750693e-4,3.834031657261469e-7,3.3151850482013803e-7,4.588178918745307e-7 +ExpModInteger/14/13/14,1.8304871215588754e-4,1.8296529332526002e-4,1.831496915918868e-4,3.017096922050457e-7,2.3696718267702357e-7,4.104443154855704e-7 +ExpModInteger/14/14/14,1.971069591478436e-4,1.970011904275354e-4,1.9721744658885484e-4,3.4888864589368403e-7,3.005192115090387e-7,4.3438704039619307e-7 +ExpModInteger/14/15/14,2.1138922896677228e-4,2.1120937665261154e-4,2.1154236204329595e-4,5.314253107773795e-7,4.2081357233119063e-7,6.50351952748344e-7 +ExpModInteger/14/16/14,2.251812875475446e-4,2.2507469222760325e-4,2.252903636965395e-4,3.617829726858701e-7,2.9364835105544777e-7,4.4353435612255924e-7 +ExpModInteger/15/1/15,1.1273697227114287e-5,1.1271367248126365e-5,1.1275787453408613e-5,7.154272743376132e-9,5.833793345235429e-9,9.160870367802043e-9 +ExpModInteger/15/2/15,2.841561925942456e-5,2.8411889888770883e-5,2.8419076526092067e-5,1.1833567879199696e-8,9.76614674071919e-9,1.5436977836788928e-8 +ExpModInteger/15/3/15,4.5512195801591616e-5,4.5507151169223294e-5,4.551607257154748e-5,1.4803651061062614e-8,1.1714894343690825e-8,2.02374583127178e-8 +ExpModInteger/15/4/15,6.26224194711051e-5,6.261793679954142e-5,6.262816270011828e-5,1.7527702377161045e-8,1.4767225743510957e-8,2.205418572847276e-8 +ExpModInteger/15/5/15,7.790790117574278e-5,7.790032688157896e-5,7.791576728267055e-5,2.499632849403607e-8,2.01377629793383e-8,3.198532635289637e-8 +ExpModInteger/15/6/15,9.4240516535788e-5,9.423018385194605e-5,9.425554518998128e-5,3.952259854467787e-8,3.110968760535828e-8,5.876992790742165e-8 +ExpModInteger/15/7/15,1.1036939206430512e-4,1.1035387374218293e-4,1.103852132606125e-4,5.461876141641734e-8,4.4164053811768753e-8,6.974820227914136e-8 +ExpModInteger/15/8/15,1.2669022889865873e-4,1.2667526213376056e-4,1.2670569555524604e-4,5.0845637460252416e-8,4.3048812753902935e-8,6.20655592155357e-8 +ExpModInteger/15/9/15,1.4304296825640197e-4,1.430229490737854e-4,1.4306079201237878e-4,6.239545440469538e-8,5.0685979621979726e-8,7.95358467513407e-8 +ExpModInteger/15/10/15,1.5937035483230925e-4,1.5935486238686242e-4,1.5938686347992203e-4,5.468201215393395e-8,4.3123938264147274e-8,8.200763177069874e-8 +ExpModInteger/15/11/15,1.7581166139748536e-4,1.7578532861259663e-4,1.7584057361336468e-4,9.332772702054191e-8,7.657423594844107e-8,1.1887138773690565e-7 +ExpModInteger/15/12/15,1.905297514621247e-4,1.904871669899428e-4,1.9056654802579264e-4,1.3667968716376618e-7,1.1580712915998842e-7,1.818694026076108e-7 +ExpModInteger/15/13/15,2.0648433493848162e-4,2.0644090749794323e-4,2.0652673245254974e-4,1.423631622127055e-7,1.0971972029972059e-7,1.986061902691625e-7 +ExpModInteger/15/14/15,2.2190560477453674e-4,2.2187433090642308e-4,2.219346073018668e-4,1.0411205838478457e-7,8.88329688911352e-8,1.2624181609475278e-7 +ExpModInteger/15/15/15,2.3801462021396898e-4,2.3797939211177215e-4,2.3804856088428038e-4,1.2623993646240993e-7,1.0317409474316626e-7,1.6368631085933672e-7 +ExpModInteger/15/16/15,2.538658311689463e-4,2.5382231485116604e-4,2.5390555490361174e-4,1.4955770943529224e-7,1.1643899189945805e-7,2.1291059051851338e-7 +ExpModInteger/16/1/16,1.2808002750818758e-5,1.28056721951513e-5,1.281023586027121e-5,7.498145088031575e-9,6.094372119489489e-9,9.455736467060183e-9 +ExpModInteger/16/2/16,3.297706285518407e-5,3.2971239007279584e-5,3.2981872121914455e-5,1.831481350642411e-8,1.3471178743876594e-8,2.5314249504176467e-8 +ExpModInteger/16/3/16,5.2958688936626826e-5,5.295159762567635e-5,5.2966592662430485e-5,2.5540371567616992e-8,2.0733851092054112e-8,3.2631263506567204e-8 +ExpModInteger/16/4/16,7.290658730158392e-5,7.28970702380898e-5,7.291710584371708e-5,3.300049686625137e-8,2.6278460940067496e-8,4.350069964270314e-8 +ExpModInteger/16/5/16,8.89091852898939e-5,8.889743746224611e-5,8.892132800090333e-5,3.7902761612172574e-8,3.1127700887521773e-8,4.63853743373874e-8 +ExpModInteger/16/6/16,1.0751343101873489e-4,1.0748768061214337e-4,1.0754282836758694e-4,8.676380541189747e-8,7.264510972980667e-8,1.05727888786601e-7 +ExpModInteger/16/7/16,1.2586754948387406e-4,1.2584526670903403e-4,1.2589266784318923e-4,7.962760354402093e-8,6.906248073839288e-8,9.465099327727434e-8 +ExpModInteger/16/8/16,1.445396955341208e-4,1.4451697346151666e-4,1.445645281753492e-4,7.857660079320155e-8,6.124580818580115e-8,1.0622580538013587e-7 +ExpModInteger/16/9/16,1.6335042006652967e-4,1.6332889006767922e-4,1.6337315878637687e-4,7.181487646129237e-8,5.8963057736837804e-8,9.117298096207363e-8 +ExpModInteger/16/10/16,1.8196361311464737e-4,1.81925299110639e-4,1.8200461025085364e-4,1.391865940301332e-7,1.1522871115874067e-7,1.69282104746966e-7 +ExpModInteger/16/11/16,2.0050379887314856e-4,2.0046392356928668e-4,2.0054319233063581e-4,1.3358086433417315e-7,1.0309483549178051e-7,1.984705052871704e-7 +ExpModInteger/16/12/16,2.1563115718858673e-4,2.1558919030104405e-4,2.1568339223741417e-4,1.533742176411032e-7,1.2191309733650467e-7,1.9241732961610924e-7 +ExpModInteger/16/13/16,2.3360802372195388e-4,2.3356882712972094e-4,2.336925983434257e-4,1.9374975804812425e-7,1.222587039879038e-7,3.321515024358083e-7 +ExpModInteger/16/14/16,2.5137520215880036e-4,2.513388530283794e-4,2.5141555088185966e-4,1.3339661111937381e-7,1.1238506729804821e-7,1.640653298532583e-7 +ExpModInteger/16/15/16,2.691845711277e-4,2.6911092789858184e-4,2.692774932752897e-4,2.656772213628854e-7,2.0827505516706554e-7,3.75206595562311e-7 +ExpModInteger/16/16/16,2.876084006340796e-4,2.8755898622897033e-4,2.87654054194647e-4,1.5901856205738667e-7,1.2976610875350057e-7,1.8971943002467932e-7 LengthOfArray/51,8.985717190895481e-7,8.98062978514804e-7,8.989441775253596e-7,1.4501066562593545e-9,1.1433891448989778e-9,1.8813129346001226e-9 LengthOfArray/8,9.11080496714245e-7,9.099175321252998e-7,9.120359048659579e-7,3.375496580311786e-9,2.6806515379143436e-9,4.477623673651683e-9 LengthOfArray/66,9.058863526218426e-7,9.05112216313436e-7,9.067024379787379e-7,2.557157058172265e-9,2.214345453381487e-9,3.0246451435728182e-9 diff --git a/plutus-core/cost-model/data/builtinCostModelA.json b/plutus-core/cost-model/data/builtinCostModelA.json index 0bca5dfd01d..bcd553ae65d 100644 --- a/plutus-core/cost-model/data/builtinCostModelA.json +++ b/plutus-core/cost-model/data/builtinCostModelA.json @@ -1152,12 +1152,19 @@ }, "expModInteger": { "cpu": { - "arguments": 100000000000, - "type": "constant_cost" + "arguments": { + "coefficient00": 607153, + "coefficient11": 231697, + "coefficient12": 53144 + }, + "type": "exp_mod_cost" }, "memory": { - "arguments": 100000000000, - "type": "constant_cost" + "arguments": { + "intercept": 0, + "slope": 1 + }, + "type": "linear_in_z" } }, "dropList": { diff --git a/plutus-core/cost-model/data/builtinCostModelB.json b/plutus-core/cost-model/data/builtinCostModelB.json index 08a1fb56670..af7a1cd2d1e 100644 --- a/plutus-core/cost-model/data/builtinCostModelB.json +++ b/plutus-core/cost-model/data/builtinCostModelB.json @@ -1152,12 +1152,19 @@ }, "expModInteger": { "cpu": { - "arguments": 100000000000, - "type": "constant_cost" + "arguments": { + "coefficient00": 607153, + "coefficient11": 231697, + "coefficient12": 53144 + }, + "type": "exp_mod_cost" }, "memory": { - "arguments": 100000000000, - "type": "constant_cost" + "arguments": { + "intercept": 0, + "slope": 1 + }, + "type": "linear_in_z" } }, "dropList": { diff --git a/plutus-core/cost-model/data/builtinCostModelC.json b/plutus-core/cost-model/data/builtinCostModelC.json index 71fbef18252..6c48ab042c3 100644 --- a/plutus-core/cost-model/data/builtinCostModelC.json +++ b/plutus-core/cost-model/data/builtinCostModelC.json @@ -1170,12 +1170,19 @@ }, "expModInteger": { "cpu": { - "arguments": 100000000000, - "type": "constant_cost" + "arguments": { + "coefficient00": 607153, + "coefficient11": 231697, + "coefficient12": 53144 + }, + "type": "exp_mod_cost" }, "memory": { - "arguments": 100000000000, - "type": "constant_cost" + "arguments": { + "intercept": 0, + "slope": 1 + }, + "type": "linear_in_z" } }, "dropList": { diff --git a/plutus-core/cost-model/data/models.R b/plutus-core/cost-model/data/models.R index 3625091be9d..df3caa1e1a2 100644 --- a/plutus-core/cost-model/data/models.R +++ b/plutus-core/cost-model/data/models.R @@ -56,6 +56,7 @@ discard.upper.outliers <- function(fr) { } arity <- function(name) { + ## cat (sprintf ("Arity: %s\n", name)) # Useful to see how far we get switch (name, "AddInteger" = 2, "SubtractInteger" = 2, @@ -148,7 +149,8 @@ arity <- function(name) { "DropList" = 2, "LengthOfArray" = 1, "ListToArray" = 1, - "IndexArray" = 2 + "IndexArray" = 2, + -1 ## Default for missing values ) } @@ -365,7 +367,11 @@ modelFun <- function(path) { ## average cost of a CEK step. discard.overhead <- function(frame) { fname <- frame$name[1] - args.overhead <- overhead[arity(fname)] + ar <- arity (fname) + if(ar < 0) { + stop(sprintf("ERROR: no arity information for %s\n", fname)) + } + args.overhead <- overhead[ar] mean.time <- mean(frame$t) if (mean.time > args.overhead) { f <- mutate(frame,across(c("t", "t.mean.lb", "t.mean.ub"), function(x) { x - args.overhead })) @@ -475,8 +481,6 @@ modelFun <- function(path) { quotientIntegerModel <- divideIntegerModel remainderIntegerModel <- divideIntegerModel modIntegerModel <- divideIntegerModel - expModIntegerModel <- constantModel ("ExpModInteger") # FIXME: stub - ## This could possibly be made constant away from the diagonal; it's harmless ## to make it linear everywhere, but may overprice some comparisons a bit. @@ -757,7 +761,7 @@ modelFun <- function(path) { fname <- "ByteStringToInteger" filtered <- data %>% filter.and.check.nonempty(fname) - m <- lm(t ~ I(y_mem) + I(y_mem^2), filtered) + m <- lm(t ~ I(y_mem) + I(y_mem^2), filtered) mk.result(m, "quadratic_in_y") } @@ -783,6 +787,17 @@ modelFun <- function(path) { countSetBitsModel <- linearInX ("CountSetBits") findFirstSetBitModel <- linearInX ("FindFirstSetBit") + + expModIntegerModel <- { + fname <- "ExpModInteger" + filtered <- data %>% + filter.and.check.nonempty(fname) %>% + filter(x_mem > 0 & y_mem > 0) %>% + discard.overhead () + m <- lm(t ~ I(y_mem*z_mem) + I(y_mem*z_mem^2), filtered) + mk.result(m, "exp_mod_cost") + } + dropListModel <- linearInX ("DropList") ## Arrays @@ -790,8 +805,7 @@ modelFun <- function(path) { listToArrayModel <- linearInX ("ListToArray") indexArrayModel <- constantModel ("IndexArray") - -##### Models to be returned to Haskell ##### + ##### Models to be returned to Haskell ##### models.for.adjustment <- list ( diff --git a/plutus-core/cost-model/print-cost-model/Main.hs b/plutus-core/cost-model/print-cost-model/Main.hs index 33c4a35dff9..51193a784ab 100644 --- a/plutus-core/cost-model/print-cost-model/Main.hs +++ b/plutus-core/cost-model/print-cost-model/Main.hs @@ -69,6 +69,16 @@ renderTwoVariableQuadraticFunction printf "max(%d, %d + %d*%s + %d*%s + %d*%s^2 + %d*%s*%s + %d*%s^2)" minVal c00 c10 var1 c01 var2 c20 var1 c11 var1 var2 c02 var2 +renderExpModCostingFunction + :: ExpModCostingFunction + -> String + -> String + -> String +renderExpModCostingFunction + (ExpModCostingFunction c00 c11 c12) var1 var2 = + printf "%d + %d*%s*%s + %d*%s*%s^2" + c00 c11 var1 var2 c12 var1 var2 + -- FIXME. This is arguably slightly incorrect because some of the arguments are -- wrapped in newtypes that change the memory usage instance of their content -- and this isn't reflected in the output. We're able to fix this for @@ -93,6 +103,7 @@ renderModel = QuadraticInY f -> [ renderOneVariableQuadraticFunction f "y" ] QuadraticInZ f -> [ renderOneVariableQuadraticFunction f "z" ] QuadraticInXAndY f -> [ renderTwoVariableQuadraticFunction f "x" "y" ] + ExpModCost f -> [ renderExpModCostingFunction f "y" "z" ] LinearInMaxYZ f -> [ renderLinearFunction f "max(y,z)" ] LinearInYAndZ f -> [ renderTwoVariableLinearFunction f "y" "z" ] LiteralInYOrLinearInZ f -> [ "if y==0" diff --git a/plutus-core/cost-model/test/TestCostModels.hs b/plutus-core/cost-model/test/TestCostModels.hs index ef82af61e3f..e202ce228d7 100644 --- a/plutus-core/cost-model/test/TestCostModels.hs +++ b/plutus-core/cost-model/test/TestCostModels.hs @@ -334,6 +334,8 @@ main = , $(genTest 2 "lessThanInteger") Everywhere , $(genTest 2 "lessThanEqualsInteger") Everywhere , $(genTest 2 "equalsInteger") Everywhere + -- , $(genTest 3 "expModInteger") + -- ^ Doesn't work because of the penalty for initial modular reduction. -- Bytestrings , $(genTest 2 "appendByteString") Everywhere @@ -378,6 +380,7 @@ main = , $(genTest 1 "headList") , $(genTest 1 "tailList") , $(genTest 1 "nullList") + , $(genTest 2 "dropList") Everywhere -- Arrays , $(genTest 1 "lengthOfArray") diff --git a/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs b/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs index 8ca636aaac5..33ecb4dd03a 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs @@ -49,6 +49,7 @@ import Data.Vector.Strict qualified as Vector import Flat hiding (from, to) import Flat.Decoder (Get, dBEBits8) import Flat.Encoder as Flat (Encoding, NumBits, eBits) +import GHC.Natural (naturalFromInteger) import GHC.Num.Integer (Integer (..)) import GHC.Types (Int (..)) import NoThunks.Class (NoThunks) @@ -2020,8 +2021,15 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where -- Batch 6 toBuiltinMeaning _semvar ExpModInteger = - let expModIntegerDenotation :: Integer -> Integer -> Natural -> BuiltinResult Natural - expModIntegerDenotation = ExpMod.expMod + let expModIntegerDenotation + :: Integer + -> Integer + -> Integer + -> BuiltinResult Natural + expModIntegerDenotation a b m = + if m < 0 + then fail "expModInteger: negative modulus" + else ExpMod.expMod a b (naturalFromInteger m) {-# INLINE expModIntegerDenotation #-} in makeBuiltinMeaning expModIntegerDenotation diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs index 768e95e37c7..b5209120c32 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs @@ -26,10 +26,12 @@ module PlutusCore.Evaluation.Machine.BuiltinCostModel , Coefficient20(..) , Coefficient11(..) , Coefficient02(..) + , Coefficient12(..) , OneVariableLinearFunction(..) , OneVariableQuadraticFunction(..) , TwoVariableLinearFunction(..) , TwoVariableQuadraticFunction(..) + , ExpModCostingFunction(..) , ModelSubtractedSizes(..) , ModelConstantOrOneArgument(..) , ModelConstantOrTwoArguments(..) diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/Core.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/Core.hs index d0133bba1cc..0b9ede4c10a 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/Core.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/Core.hs @@ -23,10 +23,12 @@ module PlutusCore.Evaluation.Machine.CostingFun.Core , Coefficient20(..) , Coefficient11(..) , Coefficient02(..) + , Coefficient12(..) , OneVariableLinearFunction(..) , OneVariableQuadraticFunction(..) , TwoVariableLinearFunction(..) , TwoVariableQuadraticFunction(..) + , ExpModCostingFunction(..) , ModelSubtractedSizes(..) , ModelConstantOrLinear(..) -- Deprecated: see below. , ModelConstantOrOneArgument(..) @@ -199,6 +201,13 @@ newtype Coefficient02 = Coefficient02 } deriving stock (Generic, Lift) deriving newtype (Show, Eq, Num, NFData) +-- | A wrapped 'CostingInteger' that is supposed to be used as the degree (1,2) +-- coefficient of a two-variable polynomial. +newtype Coefficient12 = Coefficient12 + { unCoefficient12 :: CostingInteger + } deriving stock (Generic, Lift) + deriving newtype (Show, Eq, Num, NFData) + ---------------- One-argument costing functions ---------------- data ModelOneArgument = @@ -383,12 +392,43 @@ evaluateTwoVariableQuadraticFunction -- here: see Note [Minimum values for two-variable quadratic costing functions] {-# INLINE evaluateTwoVariableQuadraticFunction #-} --- FIXME: we could use ModelConstantOrOneArgument for --- ModelTwoArgumentsSubtractedSizes instead, but that would change the order of --- the cost model parameters since the minimum value would come first instead of --- last. --- Tracked by https://github.com/IntersectMBO/plutus-private/issues/1554. +-- | c00 + c01x*y + c12x*y^2 +-- This is used only for `expModInteger`, whose costing is quite complex. +data ExpModCostingFunction = ExpModCostingFunction + { coefficient00 :: Coefficient00 + , coefficient11 :: Coefficient11 + , coefficient12 :: Coefficient12 + } deriving stock (Show, Eq, Generic, Lift) + deriving anyclass (NFData) + +{- | Calculate the cost of calling `expModInteger a e m` where a is of size aa, e +is of size ee, and m is of size mm. If aa>mm then the cost is increased by +50% to impose a penalty for the extra cost of initially reducing `a` modulo `m`. +If large values of `a` really are required then the penalty can be avoided by +calling `modInteger` before `expModInteger`. +-} +evaluateExpModCostingFunction + :: ExpModCostingFunction + -> CostingInteger + -> CostingInteger + -> CostingInteger + -> CostingInteger +evaluateExpModCostingFunction + (ExpModCostingFunction + (Coefficient00 c00) (Coefficient11 c11) (Coefficient12 c12)) + aa ee mm = if aa <= mm + then cost0 + else cost0 + (cost0 `dividedBy` 2) + where cost0 = c00 + c11*ee*mm + c12*ee*mm*mm +{-# INLINE evaluateExpModCostingFunction #-} + -- | s * (x - y) + I +{- In principle we could use ModelConstantOrOneArgument here, but that would +change the order of the cost model parameters since the minimum value would come +first instead of last, so for the time being we use a special type. We may be +able to change this later if we move to a self-describing cost model format +where the cost model parameters include the type of the costing function. See +Note [Backward compatibility for costing functions]. -} data ModelSubtractedSizes = ModelSubtractedSizes { modelSubtractedSizesIntercept :: Intercept , modelSubtractedSizesSlope :: Slope @@ -396,9 +436,9 @@ data ModelSubtractedSizes = ModelSubtractedSizes } deriving stock (Show, Eq, Generic, Lift) deriving anyclass (NFData) --- | NB: this is subsumed by ModelConstantOrOneArgument, but we have to keep it --- for the time being. See Note [Backward compatibility for costing functions]. -- | if p then s*x else c; p depends on usage +{- NB: this is subsumed by ModelConstantOrOneArgument, but we have to keep it +-- for the time being. See Note [Backward compatibility for costing functions]. -} data ModelConstantOrLinear = ModelConstantOrLinear { modelConstantOrLinearConstant :: CostingInteger , modelConstantOrLinearIntercept :: Intercept @@ -593,14 +633,16 @@ runTwoArgumentModel ---------------- Three-argument costing functions ---------------- data ModelThreeArguments = - ModelThreeArgumentsConstantCost CostingInteger - | ModelThreeArgumentsLinearInX OneVariableLinearFunction - | ModelThreeArgumentsLinearInY OneVariableLinearFunction - | ModelThreeArgumentsLinearInZ OneVariableLinearFunction - | ModelThreeArgumentsQuadraticInZ OneVariableQuadraticFunction - | ModelThreeArgumentsLiteralInYOrLinearInZ OneVariableLinearFunction - | ModelThreeArgumentsLinearInMaxYZ OneVariableLinearFunction - | ModelThreeArgumentsLinearInYAndZ TwoVariableLinearFunction + ModelThreeArgumentsConstantCost CostingInteger + | ModelThreeArgumentsLinearInX OneVariableLinearFunction + | ModelThreeArgumentsLinearInY OneVariableLinearFunction + | ModelThreeArgumentsLinearInZ OneVariableLinearFunction + | ModelThreeArgumentsQuadraticInZ OneVariableQuadraticFunction + | ModelThreeArgumentsLiteralInYOrLinearInZ OneVariableLinearFunction + | ModelThreeArgumentsLinearInMaxYZ OneVariableLinearFunction + | ModelThreeArgumentsLinearInYAndZ TwoVariableLinearFunction + | ModelThreeArgumentsQuadraticInYAndZ TwoVariableQuadraticFunction + | ModelThreeArgumentsExpModCost ExpModCostingFunction deriving stock (Show, Eq, Generic, Lift) deriving anyclass (NFData) @@ -658,6 +700,20 @@ runThreeArgumentModel (ModelThreeArgumentsLinearInYAndZ (TwoVariableLinearFunction intercept slope2 slope3)) = lazy $ \_costs1 costs2 costs3 -> scaleLinearlyTwoVariables intercept slope2 costs2 slope3 costs3 + +runThreeArgumentModel + (ModelThreeArgumentsQuadraticInYAndZ f) = + lazy $ \_ costs2 costs3 -> + let !size2 = sumCostStream costs2 + !size3 = sumCostStream costs3 + in CostLast $ evaluateTwoVariableQuadraticFunction f size2 size3 + +runThreeArgumentModel (ModelThreeArgumentsExpModCost f) = + lazy $ \costs1 costs2 costs3 -> + let !size1 = sumCostStream costs1 + !size2 = sumCostStream costs2 + !size3 = sumCostStream costs3 + in CostLast $ evaluateExpModCostingFunction f size1 size2 size3 {-# OPAQUE runThreeArgumentModel #-} -- See Note [runCostingFun* API]. diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/JSON.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/JSON.hs index 0ce9d157ba1..abf72d19736 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/JSON.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/JSON.hs @@ -55,6 +55,8 @@ deriving newtype instance FromJSON Coefficient11 deriving newtype instance ToJSON Coefficient11 deriving newtype instance FromJSON Coefficient02 deriving newtype instance ToJSON Coefficient02 +deriving newtype instance FromJSON Coefficient12 +deriving newtype instance ToJSON Coefficient12 deriving via ModelArgumentJSON "ModelOneArgument" ModelOneArgument instance FromJSON ModelOneArgument @@ -101,6 +103,10 @@ deriving via ModelJSON "twoVariableQuadraticFunction" TwoVariableQuadraticFuncti instance FromJSON TwoVariableQuadraticFunction deriving via ModelJSON "twoVariableQuadraticFunction" TwoVariableQuadraticFunction instance ToJSON TwoVariableQuadraticFunction +deriving via ModelJSON "expModCostingFunction" ExpModCostingFunction + instance FromJSON ExpModCostingFunction +deriving via ModelJSON "expModCostingFunction" ExpModCostingFunction + instance ToJSON ExpModCostingFunction deriving via ModelJSON "modelConstantOrOneArgument" ModelConstantOrOneArgument instance FromJSON ModelConstantOrOneArgument deriving via ModelJSON "modelConstantOrOneArgument" ModelConstantOrOneArgument diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/SimpleJSON.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/SimpleJSON.hs index f12cd9bac55..2c26e33f4c9 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/SimpleJSON.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/CostingFun/SimpleJSON.hs @@ -58,6 +58,21 @@ instance FromJSON TwoVariableQuadraticFunction where obj .: "c00" <*> obj .: "c10" <*> obj .: "c01" <*> obj .: "c20" <*> obj .: "c11" <*> obj .: "c02" +data ExpModCostingFunction = + ExpModCostingFunction + { emcfcoeff00_ :: Integer + , emcfcoeff11_ :: Integer + , emcfcoeff12_ :: Integer + } + deriving stock (Show, Lift) + +instance FromJSON ExpModCostingFunction where + parseJSON = withObject "ExpMod costing function" $ \obj -> + ExpModCostingFunction <$> + obj .: "coefficient00" <*> + obj .: "coefficient11" <*> + obj .: "coefficient12" + {- | This type reflects what is actually in the JSON. The stuff in CostingFun.Core and CostingFun.JSON is much more rigid, allowing parsing only for the model types applicable to the various ModelNArguments types; it also @@ -85,6 +100,7 @@ data Model | ConstAboveDiagonal Integer Model | ConstBelowDiagonal Integer Model | ConstOffDiagonal Integer Model + | ExpModCost ExpModCostingFunction deriving stock (Show, Lift) {- The JSON representation consists of a list of pairs of (type, arguments) @@ -122,6 +138,7 @@ instance FromJSON Model where "quadratic_in_y" -> QuadraticInY <$> parseJSON args "quadratic_in_z" -> QuadraticInZ <$> parseJSON args "quadratic_in_x_and_y" -> QuadraticInXAndY <$> parseJSON args + "exp_mod_cost" -> ExpModCost <$> parseJSON args "literal_in_y_or_linear_in_z" -> LiteralInYOrLinearInZ <$> parseJSON args "linear_in_max_yz" -> LinearInMaxYZ <$> parseJSON args "linear_in_y_and_z" -> LinearInYAndZ <$> parseJSON args diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemory.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemory.hs index 64825637f6a..3690db632b9 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemory.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemory.hs @@ -8,6 +8,7 @@ module PlutusCore.Evaluation.Machine.ExMemory ( CostingInteger , ExMemory(..) , ExCPU(..) + , dividedBy ) where import Codec.Serialise (Serialise) diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemoryUsage.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemoryUsage.hs index e1820fd1555..07f3bf9026a 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemoryUsage.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExMemoryUsage.hs @@ -226,6 +226,33 @@ instance ExMemoryUsage () where memoryUsage () = singletonRose 1 {-# INLINE memoryUsage #-} +{- | Calculate a 'CostingInteger' for the size of the given 'Integer', measured in +64-bit words. This is the default size measure for `Integer`s. +-} +memoryUsageInteger :: Integer -> CostingInteger +-- integerLog2# is unspecified for 0 (but in practice returns -1) +-- ^ This changed with GHC 9.2: it now returns 0. It's probably safest if we +-- keep this special case for the time being though. +memoryUsageInteger 0 = 1 +-- Assume 64 Int +memoryUsageInteger i = fromIntegral $ I# (integerLog2# (abs i) `quotInt#` integerToInt 64) + 1 +-- So that the produced GHC Core doesn't explode in size, we don't win anything by inlining this +-- function anyway. +{-# OPAQUE memoryUsageInteger #-} + +instance ExMemoryUsage Integer where + memoryUsage i = singletonRose $ memoryUsageInteger i + {-# INLINE memoryUsage #-} + +instance ExMemoryUsage Natural where + -- Same as Integer since we are going via Integer + memoryUsage n = memoryUsage $ toInteger n + {-# INLINE memoryUsage #-} + +instance ExMemoryUsage Word8 where + memoryUsage _ = singletonRose 1 + {-# INLINE memoryUsage #-} + {- | When invoking a built-in function, a value of type `NumBytesCostedAsNumWords` can be used transparently as a built-in Integer but with a different size measure: see Note [Integral types as Integer]. This is required by the @@ -264,31 +291,6 @@ instance ExMemoryUsage IntegerCostedLiterally where -- realistic input should be that large; however if you're going to use this then be -- sure to convince yourself that it's safe. --- | Calculate a 'CostingInteger' for the given 'Integer'. -memoryUsageInteger :: Integer -> CostingInteger --- integerLog2# is unspecified for 0 (but in practice returns -1) --- ^ This changed with GHC 9.2: it now returns 0. It's probably safest if we --- keep this special case for the time being though. -memoryUsageInteger 0 = 1 --- Assume 64 Int -memoryUsageInteger i = fromIntegral $ I# (integerLog2# (abs i) `quotInt#` integerToInt 64) + 1 --- So that the produced GHC Core doesn't explode in size, we don't win anything by inlining this --- function anyway. -{-# OPAQUE memoryUsageInteger #-} - -instance ExMemoryUsage Integer where - memoryUsage i = singletonRose $ memoryUsageInteger i - {-# INLINE memoryUsage #-} - -instance ExMemoryUsage Natural where - -- Same as Integer since we are going via Integer - memoryUsage n = memoryUsage $ toInteger n - {-# INLINE memoryUsage #-} - -instance ExMemoryUsage Word8 where - memoryUsage _ = singletonRose 1 - {-# INLINE memoryUsage #-} - {- Bytestrings: we want the empty bytestring and bytestrings of length 1-8 to have size 1, bytestrings of length 9-16 to have size 2, etc. Note that (-1) `quot` 8 == 0, so the code below gives the correct answer for the empty diff --git a/plutus-core/plutus-core/test/TypeSynthesis/Golden/Signatures/DefaultFun/ExpModInteger.sig.golden b/plutus-core/plutus-core/test/TypeSynthesis/Golden/Signatures/DefaultFun/ExpModInteger.sig.golden index bd41d4c56f3..70d4f9586ed 100644 --- a/plutus-core/plutus-core/test/TypeSynthesis/Golden/Signatures/DefaultFun/ExpModInteger.sig.golden +++ b/plutus-core/plutus-core/test/TypeSynthesis/Golden/Signatures/DefaultFun/ExpModInteger.sig.golden @@ -1 +1 @@ -Integer -> Integer -> Natural -> BuiltinResult Natural \ No newline at end of file +Integer -> Integer -> Integer -> BuiltinResult Natural \ No newline at end of file diff --git a/plutus-core/satint/src/Data/SatInt.hs b/plutus-core/satint/src/Data/SatInt.hs index 4b21ae4e527..49dc2791159 100644 --- a/plutus-core/satint/src/Data/SatInt.hs +++ b/plutus-core/satint/src/Data/SatInt.hs @@ -8,12 +8,14 @@ This is not quite as fast as using 'Int' or 'Int64' directly, but we need the sa {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE ViewPatterns #-} module Data.SatInt ( -- Not exporting the constructor, so that 'coerce' doesn't work, see 'unsafeToSatInt'. SatInt (unSatInt) , unsafeToSatInt , fromSatInt + , dividedBy ) where import Codec.Serialise (Serialise) @@ -24,6 +26,7 @@ import Data.Csv import Data.Primitive (Prim) import GHC.Base import GHC.Generics +import GHC.Natural import GHC.Real import Language.Haskell.TH.Syntax (Lift) import NoThunks.Class @@ -78,6 +81,17 @@ instance Num SatInt where | x < minBoundInteger = minBound | otherwise = SI (fromInteger x) +-- | Divide a `SatInt` by a natural number. If the natural number is zero, +-- return `maxBound`; if we're at the maximum or minimum value then leave the +-- input unaltered. This should never throw. +dividedBy :: SatInt -> Natural -> SatInt +dividedBy _ 0 = maxBound +dividedBy x@(SI n) d = + if n == maxBound || n == minBound + then x + else SI (n `div` (fromIntegral d)) +{-# INLINE dividedBy #-} + maxBoundInteger :: Integer maxBoundInteger = toInteger maxInt {-# INLINABLE maxBoundInteger #-} diff --git a/plutus-core/satint/test/TestSatInt.hs b/plutus-core/satint/test/TestSatInt.hs index 67518e13062..0d39684875a 100644 --- a/plutus-core/satint/test/TestSatInt.hs +++ b/plutus-core/satint/test/TestSatInt.hs @@ -60,9 +60,12 @@ tests = unitTest "max+min" ((maxBound :: SatInt) + (minBound :: SatInt) == -1), unitTest "max+*" (saturatesPos ((2 :: SatInt) ^ (wordSize `div` 2) * 2 ^ (wordSize `div` 2 - 1))), unitTest "min-*" (saturatesNeg (negate ((2 :: SatInt) ^ (wordSize `div` 2)) * 2 ^ (wordSize `div` 2 - 1))), + unitTest "max/2" (saturatesPos ((maxBound :: SatInt) `dividedBy` 2)), + unitTest "min/2" (saturatesNeg ((minBound :: SatInt) `dividedBy` 2)), testProperty "*" (propBinOp (*)), testProperty "+" (propBinOp (+)), - testProperty "-" (propBinOp (-)) + testProperty "-" (propBinOp (-)), + testProperty "/0" propDividedBy0 -- lcm and gcd do *not* pass `behavesOk` since they *internally* use `abs` (which will give the wrong/saturated -- answer for minBound), and hence go astray after that. But we can't easily detect that this is the "correct" -- saturated thing to do as we do for other operations (where we can just see if the saturating version is @@ -79,3 +82,7 @@ propBinOp (!) = withMaxSuccess 10000 $ forAll intWithSpecialCases $ \ x -> forAll intWithSpecialCases $ \ y -> ioProperty $ behavesOk (fromIntegral x ! fromIntegral y) + +propDividedBy0 :: Property +propDividedBy0 = withMaxSuccess 1000 $ + forAll intWithSpecialCases $ \n -> saturatesPos ((fromIntegral n) `dividedBy` 0) diff --git a/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Golden/Integer/ExpMod/mod-neg.err.golden b/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Golden/Integer/ExpMod/mod-neg.err.golden index 917d2d185d6..e0967b8a797 100644 --- a/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Golden/Integer/ExpMod/mod-neg.err.golden +++ b/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Golden/Integer/ExpMod/mod-neg.err.golden @@ -2,4 +2,4 @@ An error has occurred: The machine terminated because of an error, either from a built-in function or from an explicit use of 'error'. Caused by: expModInteger 1 1 -3 Logs were: --3 is not within the bounds of Natural \ No newline at end of file +expModInteger: negative modulus \ No newline at end of file diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs index ff16eb1d068..c4af4f460c1 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs @@ -314,18 +314,18 @@ data ParamName = | Ripemd_160'cpu'arguments'slope | Ripemd_160'memory'arguments -- not enabled yet: --- ExpModInteger'cpu'arguments --- ExpModInteger'memory'arguments --- DropList'cpu'arguments'intercept --- DropList'cpu'arguments'slope --- DropList'memory'arguments'intercept --- DropList'memory'arguments'slope --- LengthOfArray'cpu'arguments --- LengthOfArray'memory'arguments --- ListToArray'cpu'arguments --- ListToArray'memory'arguments --- IndexArray'cpu'arguments --- IndexArray'memory'arguments +-- | ExpModInteger'cpu'arguments +-- | ExpModInteger'memory'arguments +-- | DropList'cpu'arguments'intercept +-- | DropList'cpu'arguments'slope +-- | DropList'memory'arguments'intercept +-- | DropList'memory'arguments'slope +-- | LengthOfArray'cpu'arguments +-- | LengthOfArray'memory'arguments +-- | ListToArray'cpu'arguments +-- | ListToArray'memory'arguments +-- | IndexArray'cpu'arguments +-- | IndexArray'memory'arguments deriving stock (Eq, Ord, Enum, Ix, Bounded, Generic) deriving IsParamName via (GenericParamName ParamName) diff --git a/plutus-metatheory/src/Cost/Model.lagda.md b/plutus-metatheory/src/Cost/Model.lagda.md index c255d8f4641..a938b45b609 100644 --- a/plutus-metatheory/src/Cost/Model.lagda.md +++ b/plutus-metatheory/src/Cost/Model.lagda.md @@ -81,6 +81,7 @@ data CostingModel : ℕ → Set where -- exactly 3 arguments twoArgumentsLinearInYAndZ : Intercept → Slope → Slope → CostingModel 3 twoArgumentsLinearInMaxYZ : Intercept → Slope → CostingModel 3 + threeArgumentsExpModCost : CostingNat → CostingNat → CostingNat -> CostingModel 3 ``` A model of a builtin consists of a pair of costing models, one for CPU and one for memory. @@ -152,6 +153,17 @@ runModel (twoArgumentsConstOffDiagonal c m) (x ∷ y ∷ []) = in if not (a ≡ᵇ b) then c else runModel m (x ∷ y ∷ []) +runModel (threeArgumentsExpModCost c00 c11 c12) (x ∷ y ∷ z ∷ []) = + let aa = sizeOf x + ee = sizeOf y + mm = sizeOf z + cost0 = c00 + c11 * ee * mm + c12 * ee * mm * mm + in if mm <ᵇ aa + then cost0 + (cost0 / 2) + else cost0 + + -- ^ THIS IS INCOMPLETE: the real costing function branches if a > 5*c; however we measure + -- sizes in bytes instead of words for expModInteger, so it gives incorrect results anyway. runModel (literalCostIn n m) xs with lookup xs n ... | V-con (atomic aInteger) (pos (suc n)) = (n / 8) + 1 --only uses the literal size if positive integer. @@ -185,6 +197,7 @@ convertRawModel {2} (SubtractedSizes (mkLF intercept slope) c) = just (twoArgume convertRawModel {2} (ConstAboveDiagonal c m) = mapMaybe (twoArgumentsConstAboveDiagonal c) (convertRawModel m) convertRawModel {2} (ConstBelowDiagonal c m) = mapMaybe (twoArgumentsConstBelowDiagonal c) (convertRawModel m) convertRawModel {2} (ConstOffDiagonal c m) = mapMaybe (twoArgumentsConstOffDiagonal c) (convertRawModel m) +convertRawModel {3} (ExpModCost (mkExpModCostingFunction c00 c11 c12)) = just (threeArgumentsExpModCost c00 c11 c12) convertRawModel _ = nothing convertCpuAndMemoryModel : ∀{n} → CpuAndMemoryModel → Maybe (BuiltinModel n) diff --git a/plutus-metatheory/src/Cost/Raw.lagda.md b/plutus-metatheory/src/Cost/Raw.lagda.md index d2c9f673da8..a619355eb06 100644 --- a/plutus-metatheory/src/Cost/Raw.lagda.md +++ b/plutus-metatheory/src/Cost/Raw.lagda.md @@ -109,6 +109,15 @@ record TwoVariableQuadraticFunction : Set where {-# COMPILE GHC TwoVariableQuadraticFunction = data TwoVariableQuadraticFunction(TwoVariableQuadraticFunction) #-} +record ExpModCostingFunction : Set where + constructor mkExpModCostingFunction + field + coeff00 : CostingNat + coeff11 : CostingNat + coeff12 : CostingNat + +{-# COMPILE GHC ExpModCostingFunction = data ExpModCostingFunction(ExpModCostingFunction) #-} + data RawModel : Set where ConstantCost : CostingNat → RawModel AddedSizes : LinearFunction → RawModel @@ -128,12 +137,13 @@ data RawModel : Set where ConstAboveDiagonal : CostingNat → RawModel → RawModel ConstBelowDiagonal : CostingNat → RawModel → RawModel ConstOffDiagonal : CostingNat → RawModel → RawModel + ExpModCost : ExpModCostingFunction → RawModel {-# COMPILE GHC RawModel = data Model (ConstantCost | AddedSizes | MultipliedSizes | MinSize | MaxSize | LinearInX | LinearInY | LinearInZ | LiteralInYOrLinearInZ | LinearInMaxYZ | LinearInYAndZ |QuadraticInY | QuadraticInZ | QuadraticInXAndY | SubtractedSizes | ConstAboveDiagonal | - ConstBelowDiagonal | ConstOffDiagonal) #-} + ConstBelowDiagonal | ConstOffDiagonal | ExpModCost) #-} record CpuAndMemoryModel : Set where constructor mkCpuAndMemoryModel