diff --git a/src/ZkFold/Symbolic/Compiler.hs b/src/ZkFold/Symbolic/Compiler.hs index 8c405176b..20cdb2168 100644 --- a/src/ZkFold/Symbolic/Compiler.hs +++ b/src/ZkFold/Symbolic/Compiler.hs @@ -10,33 +10,37 @@ module ZkFold.Symbolic.Compiler ( solder, ) where -import Data.Aeson (ToJSON) -import Data.Eq (Eq) -import Data.Function (const, (.)) -import Data.Proxy (Proxy) -import Prelude (FilePath, IO, Monoid (mempty), Show (..), - putStrLn, type (~), ($), (++)) +import Data.Aeson (ToJSON) +import Data.Eq (Eq) +import Data.Function (const, (.)) +import Data.Functor (($>)) +import Data.Proxy (Proxy) +import Data.Traversable (for) +import Prelude (FilePath, IO, Monoid (mempty), Show (..), Traversable, + putStrLn, type (~), ($), (++)) import ZkFold.Base.Algebra.Basic.Class import ZkFold.Base.Algebra.Basic.Number -import ZkFold.Base.Data.Vector (Vector, unsafeToVector) -import ZkFold.Prelude (writeFileJSON) -import ZkFold.Symbolic.Class (Arithmetic) +import ZkFold.Base.Data.Vector (Vector, unsafeToVector) +import ZkFold.Prelude (writeFileJSON) +import ZkFold.Symbolic.Class (Arithmetic, Symbolic (..)) import ZkFold.Symbolic.Compiler.ArithmeticCircuit -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (forceOne) import ZkFold.Symbolic.Data.Class +import ZkFold.Symbolic.MonadCircuit (MonadCircuit (..)) {- ZkFold Symbolic compiler module dependency order: 1. ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal 2. ZkFold.Symbolic.Compiler.ArithmeticCircuit.Map - 3. ZkFold.Symbolic.Compiler.ArithmeticCircuit.MonadBlueprint - 4. ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators - 5. ZkFold.Symbolic.Compiler.ArithmeticCircuit.Instance - 6. ZkFold.Symbolic.Compiler.ArithmeticCircuit - 7. ZkFold.Symbolic.Compiler + 3. ZkFold.Symbolic.Compiler.ArithmeticCircuit.Instance + 4. ZkFold.Symbolic.Compiler.ArithmeticCircuit + 5. ZkFold.Symbolic.Compiler -} +forceOne :: (Symbolic c, Traversable f) => c f -> c f +forceOne r = fromCircuitF r (\fi -> for fi $ \i -> constraint (\x -> x i - one) $> i) + + -- | Arithmetizes an argument by feeding an appropriate amount of inputs. solder :: forall a c f . diff --git a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit.hs b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit.hs index eedb770f2..45cb5de51 100644 --- a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit.hs +++ b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit.hs @@ -33,26 +33,27 @@ module ZkFold.Symbolic.Compiler.ArithmeticCircuit ( checkClosedCircuit ) where -import Control.Monad.State (execState) -import Data.Map hiding (drop, foldl, foldr, map, null, splitAt, - take) -import GHC.Generics (U1 (..)) -import Numeric.Natural (Natural) -import Prelude hiding (Num (..), drop, length, product, - splitAt, sum, take, (!!), (^)) -import Test.QuickCheck (Arbitrary, Property, conjoin, property, vector, - withMaxSuccess, (===)) -import Text.Pretty.Simple (pPrint) +import Control.Monad (foldM) +import Control.Monad.State (execState) +import Data.Map hiding (drop, foldl, foldr, map, null, splitAt, + take) +import GHC.Generics (U1 (..)) +import Numeric.Natural (Natural) +import Prelude hiding (Num (..), drop, length, product, splitAt, + sum, take, (!!), (^)) +import Test.QuickCheck (Arbitrary, Property, conjoin, property, vector, + withMaxSuccess, (===)) +import Text.Pretty.Simple (pPrint) import ZkFold.Base.Algebra.Basic.Class -import ZkFold.Base.Algebra.Polynomials.Multivariate (evalMonomial, evalPolynomial) -import ZkFold.Prelude (length) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (desugarRange) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Instance () -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal (Arithmetic, ArithmeticCircuit (..), Constraint, - apply, eval, eval1, exec, exec1, - witnessGenerator) +import ZkFold.Base.Algebra.Polynomials.Multivariate (evalMonomial, evalPolynomial) +import ZkFold.Prelude (length) +import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Instance () +import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal (Arithmetic, ArithmeticCircuit (..), Constraint, + apply, eval, eval1, exec, exec1, witnessGenerator) import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Map +import ZkFold.Symbolic.Data.Combinators (expansion) +import ZkFold.Symbolic.MonadCircuit (MonadCircuit (..)) --------------------------------- High-level functions -------------------------------- @@ -67,6 +68,23 @@ applyArgs r args = optimize :: ArithmeticCircuit a f -> ArithmeticCircuit a f optimize = id + +desugarRange :: (Arithmetic a, MonadCircuit i a m) => i -> a -> m () +desugarRange i b + | b == negate one = return () + | otherwise = do + let bs = binaryExpansion b + is <- expansion (length bs) i + case dropWhile ((== one) . fst) (zip bs is) of + [] -> return () + ((_, k0):ds) -> do + z <- newAssigned (one - ($ k0)) + ge <- foldM (\j (c, k) -> newAssigned $ forceGE j c k) z ds + constraint (($ ge) - one) + where forceGE j c k + | c == zero = ($ j) * (one - ($ k)) + | otherwise = one + ($ k) * (($ j) - one) + -- | Desugars range constraints into polynomial constraints desugarRanges :: Arithmetic a => ArithmeticCircuit a f -> ArithmeticCircuit a f desugarRanges c = diff --git a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Combinators.hs b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Combinators.hs deleted file mode 100644 index 9e985e6ff..000000000 --- a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Combinators.hs +++ /dev/null @@ -1,152 +0,0 @@ -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeOperators #-} - -module ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators ( - boolCheckC, - embed, - embedV, - embedAll, - embedVar, - expansion, - splitExpansion, - horner, - desugarRange, - forceOne, - isZeroC, - invertC, - runInvert, - foldCircuit, - embedVarIndex, - embedVarIndexV, - getAllVars -) where - -import Control.Monad (foldM, replicateM) -import Data.Containers.ListUtils (nubOrd) -import Data.Eq ((==)) -import Data.Foldable (foldlM) -import Data.Functor (($>)) -import Data.List (sort) -import Data.Map (elems) -import Data.Traversable (for) -import qualified Data.Zip as Z -import GHC.Generics (Par1) -import GHC.IsList (IsList (..)) -import Prelude hiding (Bool, Eq (..), drop, length, negate, - splitAt, take, (!!), (*), (+), (-), (^)) - -import ZkFold.Base.Algebra.Basic.Class -import ZkFold.Base.Algebra.Basic.Number -import ZkFold.Base.Algebra.Polynomials.Multivariate (variables) -import qualified ZkFold.Base.Data.Vector as V -import ZkFold.Base.Data.Vector (Vector (..)) -import ZkFold.Prelude (drop, length, take, (!!)) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal (ArithmeticCircuit (..), acInput) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.MonadBlueprint -import ZkFold.Symbolic.MonadCircuit - -boolCheckC :: (Arithmetic a, Traversable f) => ArithmeticCircuit a f -> ArithmeticCircuit a f --- ^ @boolCheckC r@ computes @r (r - 1)@ in one PLONK constraint. -boolCheckC r = circuitF $ do - is <- runCircuit r - for is $ \i -> newAssigned (\x -> let xi = x i in xi * (xi - one)) - -foldCircuit :: forall n a. Arithmetic a => (forall i m . MonadBlueprint i a m => i -> i -> m i) -> ArithmeticCircuit a (Vector n) -> ArithmeticCircuit a Par1 -foldCircuit f c = circuit $ do - outputs <- runCircuit c - let (element, rest) = V.uncons outputs - foldlM f element rest - --- | TODO: Think about circuits with multiple outputs --- -embed :: Arithmetic a => a -> ArithmeticCircuit a Par1 -embed x = circuit $ newAssigned $ const (fromConstant x) - -embedV :: (Arithmetic a, Traversable f) => f a -> ArithmeticCircuit a f -embedV v = circuitF $ for v $ \x -> newAssigned $ const (fromConstant x) - -embedVar :: forall a . a -> (forall i m . MonadBlueprint i a m => m i) -embedVar x = newAssigned $ const (fromConstant x) - -embedAll :: forall a n . (Arithmetic a, KnownNat n) => a -> ArithmeticCircuit a (Vector n) -embedAll x = circuitF $ Vector <$> replicateM (fromIntegral $ value @n) (newAssigned $ const (fromConstant x)) - -expansion :: MonadCircuit i a m => Natural -> i -> m [i] --- ^ @expansion n k@ computes a binary expansion of @k@ if it fits in @n@ bits. -expansion n k = do - bits <- bitsOf n k - k' <- horner bits - constraint (\x -> x k - x k') - return bits - -splitExpansion :: (MonadCircuit i a m, Arithmetic a) => Natural -> Natural -> i -> m (i, i) --- ^ @splitExpansion n1 n2 k@ computes two values @(l, h)@ such that --- @k = 2^n1 h + l@, @l@ fits in @n1@ bits and @h@ fits in n2 bits (if such --- values exist). -splitExpansion n1 n2 k = do - let f x y = x + y + y - l <- newRanged (fromConstant $ (2 :: Natural) ^ n1 -! 1) $ foldr f zero . take n1 . repr . ($ k) - h <- newRanged (fromConstant $ (2 :: Natural) ^ n2 -! 1) $ foldr f zero . take n2 . drop n1 . repr . ($ k) - constraint (\x -> x k - x l - scale (2 ^ n1 :: Natural) (x h)) - return (l, h) - where - repr :: forall b . (BinaryExpansion b, Bits b ~ [b]) => b -> [b] - repr = padBits (n1 + n2) . binaryExpansion - -bitsOf :: MonadCircuit i a m => Natural -> i -> m [i] --- ^ @bitsOf n k@ creates @n@ bits and sets their witnesses equal to @n@ smaller --- bits of @k@. -bitsOf n k = for [0 .. n -! 1] $ \j -> - newConstrained (\x i -> let xi = x i in xi * (xi - one)) ((!! j) . repr . ($ k)) - where - repr :: forall b . (BinaryExpansion b, Bits b ~ [b], Finite b) => b -> [b] - repr = padBits (numberOfBits @b) . binaryExpansion - -horner :: MonadCircuit i a m => [i] -> m i --- ^ @horner [b0,...,bn]@ computes the sum @b0 + 2 b1 + ... + 2^n bn@ using --- Horner's scheme. -horner xs = case reverse xs of - [] -> newAssigned (const zero) - (b : bs) -> foldlM (\a i -> newAssigned (\x -> let xa = x a in x i + xa + xa)) b bs - -desugarRange :: (Arithmetic a, MonadBlueprint i a m) => i -> a -> m () -desugarRange i b - | b == negate one = return () - | otherwise = do - let bs = binaryExpansion b - is <- expansion (length bs) i - case dropWhile ((== one) . fst) (zip bs is) of - [] -> return () - ((_, k0):ds) -> do - z <- newAssigned (one - ($ k0)) - ge <- foldM (\j (c, k) -> newAssigned $ forceGE j c k) z ds - constraint (($ ge) - one) - where forceGE j c k - | c == zero = ($ j) * (one - ($ k)) - | otherwise = one + ($ k) * (($ j) - one) - -forceOne :: (Arithmetic a, Traversable f) => ArithmeticCircuit a f -> ArithmeticCircuit a f -forceOne r = circuitF $ do - is' <- runCircuit r - for is' $ \i -> constraint (\x -> x i - one) $> i - -isZeroC :: (Arithmetic a, Z.Zip f, Traversable f) => ArithmeticCircuit a f -> ArithmeticCircuit a f -isZeroC r = circuitF $ runCircuit r >>= fmap fst . runInvert - -invertC :: (Arithmetic a, Z.Zip f, Traversable f) => ArithmeticCircuit a f -> ArithmeticCircuit a f -invertC r = circuitF $ runCircuit r >>= fmap snd . runInvert - -runInvert :: (MonadCircuit i a m, Z.Zip f, Traversable f) => f i -> m (f i, f i) -runInvert is = do - js <- for is $ \i -> newConstrained (\x j -> x i * x j) (\x -> let xi = x i in one - xi // xi) - ks <- for (Z.zip is js) $ \(i, j) -> newConstrained (\x k -> x i * x k + x j - one) (finv . ($ i)) - return (js, ks) - -embedVarIndex :: Arithmetic a => Natural -> ArithmeticCircuit a Par1 -embedVarIndex n = mempty { acInput = [ n ], acOutput = pure n} - -embedVarIndexV :: (Arithmetic a, KnownNat n) => Natural -> ArithmeticCircuit a (Vector n) -embedVarIndexV n = mempty { acInput = [ n ], acOutput = pure n} - -getAllVars :: MultiplicativeMonoid a => ArithmeticCircuit a o -> [Natural] -getAllVars ac = nubOrd $ sort $ 0 : acInput ac ++ concatMap (toList . variables) (elems $ acSystem ac) diff --git a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Instance.hs b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Instance.hs index e97b60a12..0dc0c8ab0 100644 --- a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Instance.hs +++ b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Instance.hs @@ -6,24 +6,23 @@ module ZkFold.Symbolic.Compiler.ArithmeticCircuit.Instance where -import Data.Aeson hiding (Bool) -import Data.Map hiding (drop, foldl, foldl', foldr, map, null, - splitAt, take) -import GHC.Generics (Par1 (..)) -import GHC.Num (integerToNatural) -import Prelude (Show, mempty, pure, return, show, ($), (++), - (<$>)) -import qualified Prelude as Haskell -import System.Random (mkStdGen) -import Test.QuickCheck (Arbitrary (arbitrary), Gen, chooseInteger, - elements) +import Data.Aeson hiding (Bool) +import Data.Map hiding (drop, foldl, foldl', foldr, map, null, + splitAt, take, toList) +import GHC.Generics (Par1 (..)) +import GHC.Num (integerToNatural) +import Prelude (Show, mempty, pure, return, show, ($), (++), + (<$>)) +import qualified Prelude as Haskell +import System.Random (mkStdGen) +import Test.QuickCheck (Arbitrary (arbitrary), Gen, chooseInteger, + elements) import ZkFold.Base.Algebra.Basic.Class import ZkFold.Base.Algebra.Basic.Number -import ZkFold.Base.Data.Par1 () -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (getAllVars) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal hiding (constraint) -import ZkFold.Symbolic.Data.FieldElement (FieldElement (..)) +import ZkFold.Base.Data.Par1 () +import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal hiding (constraint) +import ZkFold.Symbolic.Data.FieldElement (FieldElement (..)) ------------------------------------- Instances ------------------------------------- diff --git a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Internal.hs b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Internal.hs index 2da40d38e..85a10e476 100644 --- a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Internal.hs +++ b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Internal.hs @@ -20,16 +20,21 @@ module ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal ( exec, exec1, apply, + getAllVars ) where import Control.DeepSeq (NFData, force) import Control.Monad.State (MonadState (..), State, gets, modify, runState) +import Data.Containers.ListUtils (nubOrd) import Data.Foldable (fold) -import Data.Map.Strict hiding (drop, foldl, foldr, map, null, splitAt, take) -import qualified Data.Map.Strict as M +import Data.List (sort) +import Data.Map.Strict hiding (drop, foldl, foldr, map, null, splitAt, take, + toList) +import qualified Data.Map.Strict as M hiding (toList) import Data.Semialign (unzipDefault) import qualified Data.Set as S import GHC.Generics (Generic, Par1 (..), U1 (..)) +import GHC.IsList (IsList (toList)) import Optics import Prelude hiding (Num (..), drop, length, product, splitAt, sum, take, (!!), (^)) @@ -41,7 +46,8 @@ import ZkFold.Base.Algebra.Basic.Field (Zp, fromZp, toZp) import ZkFold.Base.Algebra.Basic.Number import ZkFold.Base.Algebra.Basic.Sources import ZkFold.Base.Algebra.EllipticCurve.BLS12_381 (BLS12_381_Scalar) -import ZkFold.Base.Algebra.Polynomials.Multivariate (Mono, Poly, evalMonomial, evalPolynomial, mapCoeffs, var) +import ZkFold.Base.Algebra.Polynomials.Multivariate (Mono, Poly, evalMonomial, evalPolynomial, mapCoeffs, var, + variables) import ZkFold.Base.Control.HApplicative import ZkFold.Base.Data.HFunctor import ZkFold.Base.Data.Package @@ -49,6 +55,8 @@ import ZkFold.Prelude (drop, length) import ZkFold.Symbolic.Class import ZkFold.Symbolic.MonadCircuit + + -- | Arithmetic circuit in the form of a system of polynomial constraints. data ArithmeticCircuit a o = ArithmeticCircuit { @@ -241,6 +249,9 @@ apply xs = do zoom #acInput . put $ drop (length xs) inputs zoom #acWitness . modify . union . fromList $ zip inputs (map const xs) +getAllVars :: MultiplicativeMonoid a => ArithmeticCircuit a o -> [Natural] +getAllVars ac = nubOrd $ sort $ 0 : acInput ac ++ concatMap (toList . variables) (elems $ acSystem ac) + -- TODO: Add proper symbolic application functions -- applySymOne :: ArithmeticCircuit a -> State (ArithmeticCircuit a) () diff --git a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Map.hs b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Map.hs index b789cc352..fc4039a6d 100644 --- a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Map.hs +++ b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/Map.hs @@ -6,23 +6,22 @@ module ZkFold.Symbolic.Compiler.ArithmeticCircuit.Map ( ArithmeticCircuitTest(..) ) where -import Data.Map hiding (drop, foldl, foldr, fromList, map, null, - splitAt, take, toList) -import qualified Data.Map as Map -import GHC.Generics (Par1) -import GHC.IsList (IsList (..)) -import GHC.Natural (naturalToInteger) -import GHC.Num (integerToInt) -import Numeric.Natural (Natural) -import Prelude hiding (Num (..), drop, length, product, - splitAt, sum, take, (!!), (^)) -import Test.QuickCheck (Arbitrary (arbitrary), Gen, vector) - -import ZkFold.Base.Algebra.Basic.Class (MultiplicativeMonoid (..)) +import Data.Map hiding (drop, foldl, foldr, fromList, map, null, + splitAt, take, toList) +import qualified Data.Map as Map +import GHC.Generics (Par1) +import GHC.IsList (IsList (..)) +import GHC.Natural (naturalToInteger) +import GHC.Num (integerToInt) +import Numeric.Natural (Natural) +import Prelude hiding (Num (..), drop, length, product, splitAt, + sum, take, (!!), (^)) +import Test.QuickCheck (Arbitrary (arbitrary), Gen, vector) + +import ZkFold.Base.Algebra.Basic.Class (MultiplicativeMonoid (..)) import ZkFold.Base.Algebra.Polynomials.Multivariate -import ZkFold.Prelude (length) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (getAllVars) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal (Arithmetic, ArithmeticCircuit (..)) +import ZkFold.Prelude (length) +import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal (Arithmetic, ArithmeticCircuit (..), getAllVars) -- This module contains functions for mapping variables in arithmetic circuits. diff --git a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/MonadBlueprint.hs b/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/MonadBlueprint.hs deleted file mode 100644 index 577fd836b..000000000 --- a/src/ZkFold/Symbolic/Compiler/ArithmeticCircuit/MonadBlueprint.hs +++ /dev/null @@ -1,47 +0,0 @@ -module ZkFold.Symbolic.Compiler.ArithmeticCircuit.MonadBlueprint ( - ClosedPoly, - MonadBlueprint (..), - NewConstraint, - Witness, - WitnessField, - circuit, - circuitF, - circuits -) where - -import Control.Applicative (pure) -import Control.Monad.State (State, modify, runState) -import Data.Functor (Functor, fmap, ($>), (<$>)) -import Data.Monoid (mempty, (<>)) -import GHC.Generics (Par1, U1 (..)) -import Numeric.Natural (Natural) - -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal hiding (constraint) -import ZkFold.Symbolic.MonadCircuit - --- | A @'MonadCircuit'@ with an added capability --- of embedding another arithmetic circuit inside. -class MonadCircuit i a m => MonadBlueprint i a m where - -- | Adds the supplied circuit to the blueprint and returns its output variable. - runCircuit :: ArithmeticCircuit a f -> m (f i) - -instance Arithmetic a => MonadBlueprint Natural a (State (ArithmeticCircuit a U1)) where - runCircuit r = modify (<> r {acOutput = U1}) $> acOutput r - -circuit :: Arithmetic a => (forall i m . MonadBlueprint i a m => m i) -> ArithmeticCircuit a Par1 --- ^ Builds a circuit from blueprint. A blueprint is a function which, given an --- arbitrary type of variables @i@ and a monad @m@ supporting the 'MonadBlueprint' --- API, computes the output variable of a future circuit. -circuit b = circuitF (pure <$> b) - -circuitF :: forall a f . Arithmetic a => (forall i m . MonadBlueprint i a m => m (f i)) -> ArithmeticCircuit a f --- TODO: I should really rethink this... -circuitF b = let (os, r) = runState b mempty - in r { acOutput = os } - --- TODO: kept for compatibility with @binaryExpansion@ only. Perhaps remove it in the future? -circuits :: forall a f . (Arithmetic a, Functor f) => (forall i m . MonadBlueprint i a m => m (f i)) -> f (ArithmeticCircuit a Par1) --- ^ Builds a collection of circuits from one blueprint. A blueprint is a function --- which, given an arbitrary type of variables @i@ and a monad @m@ supporting the --- 'MonadBlueprint' API, computes the collection of output variables of future circuits. -circuits b = let (os, r) = runState (fmap pure <$> b) mempty in (\o -> r { acOutput = o }) <$> os diff --git a/src/ZkFold/Symbolic/Data/Combinators.hs b/src/ZkFold/Symbolic/Data/Combinators.hs index 1a33b5736..bc17f6f95 100644 --- a/src/ZkFold/Symbolic/Data/Combinators.hs +++ b/src/ZkFold/Symbolic/Data/Combinators.hs @@ -6,24 +6,30 @@ module ZkFold.Symbolic.Data.Combinators where -import Control.Monad (mapM) -import Data.Kind (Type) -import Data.List (find, splitAt) -import Data.List.Split (chunksOf) -import Data.Maybe (fromMaybe) -import Data.Proxy (Proxy (..)) -import Data.Ratio ((%)) -import Data.Type.Bool (If) +import Control.Monad (mapM) +import Data.Foldable (Foldable (..), foldlM) +import Data.Kind (Type) +import Data.List (find, splitAt) +import Data.List.Split (chunksOf) +import Data.Maybe (fromMaybe) +import Data.Proxy (Proxy (..)) +import Data.Ratio ((%)) +import Data.Traversable (Traversable, for) +import Data.Type.Bool (If) +import Data.Type.Equality (type (~)) import Data.Type.Ord +import qualified Data.Zip as Z +import GHC.Base (const, return) +import GHC.List (reverse) import GHC.TypeNats -import Prelude (error, head, pure, tail, ($), (.), (<$>), (<>)) -import qualified Prelude as Haskell +import Prelude (error, head, pure, tail, ($), (.), (<$>), (<>)) +import qualified Prelude as Haskell import Type.Errors import ZkFold.Base.Algebra.Basic.Class -import ZkFold.Base.Algebra.Basic.Number (value) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (expansion, horner) -import ZkFold.Symbolic.MonadCircuit (MonadCircuit) +import ZkFold.Base.Algebra.Basic.Number (value) +import ZkFold.Prelude (drop, take, (!!)) +import ZkFold.Symbolic.MonadCircuit -- | A class for isomorphic types. -- The @Iso b a@ context ensures that transformations in both directions are defined @@ -175,3 +181,50 @@ highRegisterBits = case getNatural @n `mod` maxBitsPerFieldElement @p of minNumberOfRegisters :: forall p n. (Finite p, KnownNat n) => Natural minNumberOfRegisters = (getNatural @n + maxBitsPerRegister @p @n -! 1) `div` maxBitsPerRegister @p @n + +--------------------------------------------------------------- + +expansion :: MonadCircuit i a m => Natural -> i -> m [i] +-- ^ @expansion n k@ computes a binary expansion of @k@ if it fits in @n@ bits. +expansion n k = do + bits <- bitsOf n k + k' <- horner bits + constraint (\x -> x k - x k') + return bits + +bitsOf :: MonadCircuit i a m => Natural -> i -> m [i] +-- ^ @bitsOf n k@ creates @n@ bits and sets their witnesses equal to @n@ smaller +-- bits of @k@. +bitsOf n k = for [0 .. n -! 1] $ \j -> + newConstrained (\x i -> let xi = x i in xi * (xi - one)) ((!! j) . repr . ($ k)) + where + repr :: forall b . (BinaryExpansion b, Bits b ~ [b], Finite b) => b -> [b] + repr = padBits (numberOfBits @b) . binaryExpansion + +horner :: MonadCircuit i a m => [i] -> m i +-- ^ @horner [b0,...,bn]@ computes the sum @b0 + 2 b1 + ... + 2^n bn@ using +-- Horner's scheme. +horner xs = case reverse xs of + [] -> newAssigned (const zero) + (b : bs) -> foldlM (\a i -> newAssigned (\x -> let xa = x a in x i + xa + xa)) b bs + +splitExpansion :: (MonadCircuit i a m, Arithmetic a) => Natural -> Natural -> i -> m (i, i) +-- ^ @splitExpansion n1 n2 k@ computes two values @(l, h)@ such that +-- @k = 2^n1 h + l@, @l@ fits in @n1@ bits and @h@ fits in n2 bits (if such +-- values exist). +splitExpansion n1 n2 k = do + let f x y = x + y + y + l <- newRanged (fromConstant $ (2 :: Natural) ^ n1 -! 1) $ foldr f zero . take n1 . repr . ($ k) + h <- newRanged (fromConstant $ (2 :: Natural) ^ n2 -! 1) $ foldr f zero . take n2 . drop n1 . repr . ($ k) + constraint (\x -> x k - x l - scale (2 ^ n1 :: Natural) (x h)) + return (l, h) + where + repr :: forall b . (BinaryExpansion b, Bits b ~ [b]) => b -> [b] + repr = padBits (n1 + n2) . binaryExpansion + + +runInvert :: (MonadCircuit i a m, Z.Zip f, Traversable f) => f i -> m (f i, f i) +runInvert is = do + js <- for is $ \i -> newConstrained (\x j -> x i * x j) (\x -> let xi = x i in one - xi // xi) + ks <- for (Z.zip is js) $ \(i, j) -> newConstrained (\x k -> x i * x k + x j - one) (finv . ($ i)) + return (js, ks) diff --git a/src/ZkFold/Symbolic/Data/Eq.hs b/src/ZkFold/Symbolic/Data/Eq.hs index 604280d74..320378128 100644 --- a/src/ZkFold/Symbolic/Data/Eq.hs +++ b/src/ZkFold/Symbolic/Data/Eq.hs @@ -5,17 +5,18 @@ module ZkFold.Symbolic.Data.Eq ( elem ) where -import Data.Bool (bool) -import qualified Data.Eq as Haskell -import Data.Foldable (Foldable) -import Data.Traversable (Traversable, for) -import qualified Data.Zip as Z -import Prelude (return, ($), (.)) +import Data.Bool (bool) +import qualified Data.Eq as Haskell +import Data.Foldable (Foldable) +import Data.Traversable (Traversable, for) +import qualified Data.Zip as Z +import Prelude (return, ($)) import ZkFold.Base.Algebra.Basic.Class import ZkFold.Base.Data.Package import ZkFold.Symbolic.Class -import ZkFold.Symbolic.Data.Bool (Bool (Bool), BoolType (..), all, any) +import ZkFold.Symbolic.Data.Bool (Bool (Bool), BoolType (..), all, any) +import ZkFold.Symbolic.Data.Combinators (runInvert) import ZkFold.Symbolic.MonadCircuit class Eq b a where @@ -33,7 +34,7 @@ instance (Symbolic c, Haskell.Eq (BaseField c), Z.Zip f, Traversable f) x == y = let result = symbolic2F x y - (\x' y' -> Z.zipWith (\i j -> bool zero one (i Haskell.== j)) x' y') + (Z.zipWith (\i j -> bool zero one (i Haskell.== j))) (\x' y' -> do difference <- for (Z.zip x' y') $ \(i, j) -> newAssigned (\w -> w i - w j) @@ -46,20 +47,14 @@ instance (Symbolic c, Haskell.Eq (BaseField c), Z.Zip f, Traversable f) x /= y = let result = symbolic2F x y - (\x' y' -> Z.zipWith (\i j -> bool zero one (i Haskell./= j)) x' y') + (Z.zipWith (\i j -> bool zero one (i Haskell./= j))) (\x' y' -> do difference <- for (Z.zip x' y') $ \(i, j) -> newAssigned (\w -> w i - w j) (isZeros, _) <- runInvert difference - notIsZeros <- for isZeros $ \isZ -> + for isZeros $ \isZ -> newAssigned (\w -> one - w isZ) - return notIsZeros ) in any Bool (unpacked result) -runInvert :: (MonadCircuit i a m, Z.Zip f, Traversable f) => f i -> m (f i, f i) -runInvert is = do - js <- for is $ \i -> newConstrained (\x j -> x i * x j) (\x -> let xi = x i in one - xi // xi) - ks <- for (Z.zip is js) $ \(i, j) -> newConstrained (\x k -> x i * x k + x j - one) (finv . ($ i)) - return (js, ks) diff --git a/src/ZkFold/Symbolic/Data/FFA.hs b/src/ZkFold/Symbolic/Data/FFA.hs index d85e4fd97..333fec461 100644 --- a/src/ZkFold/Symbolic/Data/FFA.hs +++ b/src/ZkFold/Symbolic/Data/FFA.hs @@ -4,31 +4,30 @@ module ZkFold.Symbolic.Data.FFA (FFA (..)) where -import Control.Applicative (pure) -import Control.Monad (Monad, return, (>>=)) -import Data.Foldable (any, foldlM) -import Data.Function (const, ($), (.)) -import Data.Functor (fmap, (<$>)) -import Data.List (dropWhile, (++)) -import Data.Ratio ((%)) -import Data.Traversable (for, traverse) -import Data.Tuple (fst, snd, uncurry) -import Data.Zip (zipWith) -import Prelude (Integer, error) -import qualified Prelude as Haskell +import Control.Applicative (pure) +import Control.Monad (Monad, return, (>>=)) +import Data.Foldable (any, foldlM) +import Data.Function (const, ($), (.)) +import Data.Functor (fmap, (<$>)) +import Data.List (dropWhile, (++)) +import Data.Ratio ((%)) +import Data.Traversable (for, traverse) +import Data.Tuple (fst, snd, uncurry) +import Data.Zip (zipWith) +import Prelude (Integer, error) +import qualified Prelude as Haskell import ZkFold.Base.Algebra.Basic.Class -import ZkFold.Base.Algebra.Basic.Field (Zp, inv) +import ZkFold.Base.Algebra.Basic.Field (Zp, inv) import ZkFold.Base.Algebra.Basic.Number import ZkFold.Base.Data.Vector -import ZkFold.Prelude (iterateM, length) +import ZkFold.Prelude (iterateM, length) import ZkFold.Symbolic.Class -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (expansion, splitExpansion) import ZkFold.Symbolic.Data.Class -import ZkFold.Symbolic.Data.Combinators (log2, maxBitsPerFieldElement) -import ZkFold.Symbolic.Data.Ord (blueprintGE) +import ZkFold.Symbolic.Data.Combinators (expansion, log2, maxBitsPerFieldElement, splitExpansion) +import ZkFold.Symbolic.Data.Ord (blueprintGE) import ZkFold.Symbolic.Interpreter -import ZkFold.Symbolic.MonadCircuit (MonadCircuit, newAssigned) +import ZkFold.Symbolic.MonadCircuit (MonadCircuit, newAssigned) type Size = 7 diff --git a/src/ZkFold/Symbolic/Data/FieldElement.hs b/src/ZkFold/Symbolic/Data/FieldElement.hs index 1d19452a4..597fbab32 100644 --- a/src/ZkFold/Symbolic/Data/FieldElement.hs +++ b/src/ZkFold/Symbolic/Data/FieldElement.hs @@ -4,31 +4,31 @@ module ZkFold.Symbolic.Data.FieldElement where -import Data.Bool (bool) -import Data.Foldable (foldlM, foldr) -import Data.Function (($), (.)) -import Data.Functor (fmap, (<$>)) -import Data.Ord (Ordering (..), compare) -import Data.Traversable (for) -import Data.Tuple (fst, snd) -import Data.Zip (zip) -import GHC.Generics (Par1 (..)) -import Prelude (Integer) -import qualified Prelude as Haskell +import Data.Bool (bool) +import Data.Foldable (foldlM, foldr) +import Data.Function (($), (.)) +import Data.Functor (fmap, (<$>)) +import Data.Ord (Ordering (..), compare) +import Data.Traversable (for) +import Data.Tuple (fst, snd) +import Data.Zip (zip) +import GHC.Generics (Par1 (..)) +import Prelude (Integer) +import qualified Prelude as Haskell import ZkFold.Base.Algebra.Basic.Class import ZkFold.Base.Algebra.Basic.Number -import ZkFold.Base.Data.HFunctor (HFunctor, hmap) -import ZkFold.Base.Data.Par1 () -import ZkFold.Base.Data.Vector (Vector, fromVector, unsafeToVector) +import ZkFold.Base.Data.HFunctor (HFunctor, hmap) +import ZkFold.Base.Data.Par1 () +import ZkFold.Base.Data.Vector (Vector, fromVector, unsafeToVector) import ZkFold.Symbolic.Class -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (expansion, horner, runInvert) -import ZkFold.Symbolic.Data.Bool (Bool (Bool)) +import ZkFold.Symbolic.Data.Bool (Bool (Bool)) import ZkFold.Symbolic.Data.Class +import ZkFold.Symbolic.Data.Combinators (expansion, horner, runInvert) import ZkFold.Symbolic.Data.DiscreteField -import ZkFold.Symbolic.Data.Eq (Eq) +import ZkFold.Symbolic.Data.Eq (Eq) import ZkFold.Symbolic.Data.Ord -import ZkFold.Symbolic.MonadCircuit (newAssigned) +import ZkFold.Symbolic.MonadCircuit (newAssigned) newtype FieldElement c = FieldElement { fromFieldElement :: c Par1 } diff --git a/src/ZkFold/Symbolic/Data/Ord.hs b/src/ZkFold/Symbolic/Data/Ord.hs index bff05594d..2fcfabd8d 100644 --- a/src/ZkFold/Symbolic/Data/Ord.hs +++ b/src/ZkFold/Symbolic/Data/Ord.hs @@ -5,27 +5,27 @@ module ZkFold.Symbolic.Data.Ord (Ord (..), Lexicographical (..), blueprintGE, bitwiseGE, bitwiseGT, getBitsBE) where -import Control.Monad (foldM) -import qualified Data.Bool as Haskell -import Data.Data (Proxy (..)) -import Data.Foldable (Foldable, toList) -import Data.Function ((.)) -import Data.Functor ((<$>)) -import qualified Data.Zip as Z -import GHC.Generics (Par1 (..)) -import Prelude (type (~), ($)) -import qualified Prelude as Haskell +import Control.Monad (foldM) +import qualified Data.Bool as Haskell +import Data.Data (Proxy (..)) +import Data.Foldable (Foldable, toList) +import Data.Function ((.)) +import Data.Functor ((<$>)) +import qualified Data.Zip as Z +import GHC.Generics (Par1 (..)) +import Prelude (type (~), ($)) +import qualified Prelude as Haskell import ZkFold.Base.Algebra.Basic.Class -import ZkFold.Base.Data.HFunctor (hmap) -import qualified ZkFold.Base.Data.Vector as V -import ZkFold.Base.Data.Vector (unsafeToVector) -import ZkFold.Symbolic.Class (Symbolic (BaseField, symbolicF), symbolic2F) -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (expansion) -import ZkFold.Symbolic.Data.Bool (Bool (..)) +import ZkFold.Base.Data.HFunctor (hmap) +import qualified ZkFold.Base.Data.Vector as V +import ZkFold.Base.Data.Vector (unsafeToVector) +import ZkFold.Symbolic.Class (Symbolic (BaseField, symbolicF), symbolic2F) +import ZkFold.Symbolic.Data.Bool (Bool (..)) import ZkFold.Symbolic.Data.Class -import ZkFold.Symbolic.Data.Conditional (Conditional (..)) -import ZkFold.Symbolic.MonadCircuit (MonadCircuit, newAssigned) +import ZkFold.Symbolic.Data.Combinators (expansion) +import ZkFold.Symbolic.Data.Conditional (Conditional (..)) +import ZkFold.Symbolic.MonadCircuit (MonadCircuit, newAssigned) -- TODO (Issue #23): add `compare` class Ord b a where diff --git a/src/ZkFold/Symbolic/Data/UInt.hs b/src/ZkFold/Symbolic/Data/UInt.hs index 472ac0100..27b3758da 100644 --- a/src/ZkFold/Symbolic/Data/UInt.hs +++ b/src/ZkFold/Symbolic/Data/UInt.hs @@ -16,40 +16,39 @@ module ZkFold.Symbolic.Data.UInt ( ) where import Control.DeepSeq -import Control.Monad.State (StateT (..)) -import Data.Foldable (foldr, foldrM, for_) -import Data.Functor ((<$>)) -import Data.Kind (Type) -import Data.List (unfoldr, zip) -import Data.Map (fromList, (!)) -import Data.Traversable (for, traverse) -import Data.Tuple (swap) -import qualified Data.Zip as Z -import GHC.Generics (Generic, Par1 (..)) -import GHC.Natural (naturalFromInteger) -import Prelude (Integer, error, flip, otherwise, return, - type (~), ($), (++), (.), (<>), (>>=)) -import qualified Prelude as Haskell -import Test.QuickCheck (Arbitrary (..), chooseInteger) +import Control.Monad.State (StateT (..)) +import Data.Foldable (foldr, foldrM, for_) +import Data.Functor ((<$>)) +import Data.Kind (Type) +import Data.List (unfoldr, zip) +import Data.Map (fromList, (!)) +import Data.Traversable (for, traverse) +import Data.Tuple (swap) +import qualified Data.Zip as Z +import GHC.Generics (Generic, Par1 (..)) +import GHC.Natural (naturalFromInteger) +import Prelude (Integer, error, flip, otherwise, return, type (~), ($), (++), (.), + (<>), (>>=)) +import qualified Prelude as Haskell +import Test.QuickCheck (Arbitrary (..), chooseInteger) import ZkFold.Base.Algebra.Basic.Class -import ZkFold.Base.Algebra.Basic.Field (Zp) +import ZkFold.Base.Algebra.Basic.Field (Zp) import ZkFold.Base.Algebra.Basic.Number -import qualified ZkFold.Base.Data.Vector as V -import ZkFold.Base.Data.Vector (Vector (..)) -import ZkFold.Prelude (drop, length, replicate, replicateA) +import qualified ZkFold.Base.Data.Vector as V +import ZkFold.Base.Data.Vector (Vector (..)) +import ZkFold.Prelude (drop, length, replicate, replicateA) import ZkFold.Symbolic.Class -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (expansion, splitExpansion) import ZkFold.Symbolic.Data.Bool import ZkFold.Symbolic.Data.ByteString -import ZkFold.Symbolic.Data.Class (SymbolicData) +import ZkFold.Symbolic.Data.Class (SymbolicData) import ZkFold.Symbolic.Data.Combinators import ZkFold.Symbolic.Data.Conditional import ZkFold.Symbolic.Data.Eq import ZkFold.Symbolic.Data.Eq.Structural import ZkFold.Symbolic.Data.Ord -import ZkFold.Symbolic.Interpreter (Interpreter (..)) -import ZkFold.Symbolic.MonadCircuit (MonadCircuit, constraint, newAssigned) +import ZkFold.Symbolic.Interpreter (Interpreter (..)) +import ZkFold.Symbolic.MonadCircuit (MonadCircuit, constraint, newAssigned) -- TODO (Issue #18): hide this constructor newtype UInt (n :: Natural) (r :: RegisterSize) (context :: (Type -> Type) -> Type) = UInt (context (Vector (NumberOfRegisters (BaseField context) n r))) diff --git a/tests/Tests/ArithmeticCircuit.hs b/tests/Tests/ArithmeticCircuit.hs index 52d74ea5b..21bca5c3a 100644 --- a/tests/Tests/ArithmeticCircuit.hs +++ b/tests/Tests/ArithmeticCircuit.hs @@ -4,39 +4,40 @@ module Tests.ArithmeticCircuit (exec1, it, specArithmeticCircuit) where -import Data.Bool (bool) -import GHC.Generics (Par1) -import Prelude (IO, Show, String, id, ($)) -import qualified Prelude as Haskell +import Data.Bool (bool) +import GHC.Generics (Par1 (..)) +import Prelude (IO, Show, String, id, ($)) +import qualified Prelude as Haskell import qualified Test.Hspec -import Test.Hspec (Spec, describe, hspec) +import Test.Hspec (Spec, describe, hspec) import Test.QuickCheck import ZkFold.Base.Algebra.Basic.Class -import ZkFold.Base.Algebra.Basic.Field (Zp) +import ZkFold.Base.Algebra.Basic.Field (Zp) import ZkFold.Base.Algebra.EllipticCurve.BLS12_381 -import qualified ZkFold.Base.Data.Vector as V +import ZkFold.Base.Data.Par1 () +import qualified ZkFold.Base.Data.Vector as V +import ZkFold.Symbolic.Class import ZkFold.Symbolic.Compiler -import ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators (embed) import ZkFold.Symbolic.Data.Bool import ZkFold.Symbolic.Data.DiscreteField import ZkFold.Symbolic.Data.Eq import ZkFold.Symbolic.Data.FieldElement -import ZkFold.Symbolic.MonadCircuit (Arithmetic) correctHom0 :: forall a . (Arithmetic a, Scale a a, Show a) => (forall b . Field b => b) -> Property correctHom0 f = let r = fromFieldElement f in withMaxSuccess 1 $ checkClosedCircuit r .&&. exec1 r === f @a -correctHom1 :: forall a . (Arithmetic a, Scale a a, Show a) => (forall b . Field b => b -> b) -> a -> Property -correctHom1 f x = let r = fromFieldElement $ f (FieldElement $ embed x) in checkClosedCircuit r .&&. exec1 r === f x +correctHom1 :: forall a . (Arithmetic a, Scale a a, Show a, FromConstant a (FieldElement (ArithmeticCircuit a))) => (forall b . Field b => b -> b) -> a -> Property +correctHom1 f x = let r = fromFieldElement $ f (fromConstant x) in checkClosedCircuit r .&&. exec1 r === f x -correctHom2 :: forall a . (Arithmetic a, Scale a a, Show a) => (forall b . Field b => b -> b -> b) -> a -> a -> Property -correctHom2 f x y = let r = fromFieldElement $ f (FieldElement $ embed x) (FieldElement $ embed y) in checkClosedCircuit r .&&. exec1 r === f x y +correctHom2 :: forall a . (Arithmetic a, Scale a a, Show a, FromConstant a (FieldElement (ArithmeticCircuit a))) => (forall b . Field b => b -> b -> b) -> a -> a -> Property +correctHom2 f x y = let r = fromFieldElement $ f (fromConstant x) (fromConstant y) + in checkClosedCircuit r .&&. exec1 r === f x y it :: Testable prop => String -> prop -> Spec it desc prop = Test.Hspec.it desc (property prop) -specArithmeticCircuit' :: forall a . (Arbitrary a, Arithmetic a, Scale a a, Show a) => IO () +specArithmeticCircuit' :: forall a . (Arbitrary a, Arithmetic a, Scale a a, Show a, FromConstant a (FieldElement (ArithmeticCircuit a))) => IO () specArithmeticCircuit' = hspec $ do describe "ArithmeticCircuit specification" $ do it "embeds constants" $ correctHom1 @a id @@ -48,19 +49,19 @@ specArithmeticCircuit' = hspec $ do it "inverts nonzero correctly" $ correctHom1 @a finv it "inverts zero correctly" $ correctHom0 @a (finv zero) it "checks isZero(nonzero)" $ \(x :: a) -> - let Bool (r :: ArithmeticCircuit a Par1) = isZero $ FieldElement (embed x) + let Bool (r :: ArithmeticCircuit a Par1) = isZero (fromConstant x :: FieldElement (ArithmeticCircuit a)) in checkClosedCircuit r .&&. exec1 r === bool zero one (x Haskell.== zero) it "checks isZero(0)" $ let Bool (r :: ArithmeticCircuit a Par1) = isZero (zero :: FieldElement (ArithmeticCircuit a)) in withMaxSuccess 1 $ checkClosedCircuit r .&&. exec1 r === one it "computes binary expansion" $ \(x :: a) -> - let rs = binaryExpansion $ FieldElement (embed x) + let rs = binaryExpansion (fromConstant x :: FieldElement (ArithmeticCircuit a)) in checkClosedCircuit rs .&&. V.fromVector (exec rs) === padBits (numberOfBits @a) (binaryExpansion x) it "internalizes equality" $ \(x :: a) (y :: a) -> - let Bool (r :: ArithmeticCircuit a Par1) = embed x == embed y + let Bool (r :: ArithmeticCircuit a Par1) = fromFieldElement (fromConstant x :: FieldElement (ArithmeticCircuit a)) == fromFieldElement (fromConstant y) in checkClosedCircuit r .&&. exec1 r === bool zero one (x Haskell.== y) it "internal equality is reflexive" $ \(x :: a) -> - let Bool (r :: ArithmeticCircuit a Par1) = embed x == embed x + let Bool (r :: ArithmeticCircuit a Par1) = fromFieldElement (fromConstant x :: FieldElement (ArithmeticCircuit a)) == fromFieldElement (fromConstant x) in checkClosedCircuit r .&&. exec1 r === one specArithmeticCircuit :: IO () diff --git a/zkfold-base.cabal b/zkfold-base.cabal index ac28bc986..aaa09a56f 100644 --- a/zkfold-base.cabal +++ b/zkfold-base.cabal @@ -163,11 +163,9 @@ library ZkFold.Symbolic.Class ZkFold.Symbolic.Compiler ZkFold.Symbolic.Compiler.ArithmeticCircuit - ZkFold.Symbolic.Compiler.ArithmeticCircuit.Combinators ZkFold.Symbolic.Compiler.ArithmeticCircuit.Instance ZkFold.Symbolic.Compiler.ArithmeticCircuit.Internal ZkFold.Symbolic.Compiler.ArithmeticCircuit.Map - ZkFold.Symbolic.Compiler.ArithmeticCircuit.MonadBlueprint ZkFold.Symbolic.Data.Bool ZkFold.Symbolic.Data.ByteString ZkFold.Symbolic.Data.Class