zkFold / zkfold-base

ZkFold's Base library
https://zkfold.io
MIT License
11 stars 6 forks source link

Refactor Symbolic & SymbolicData #102

Open echatav opened 2 months ago

echatav commented 2 months ago
echatav commented 2 months ago

@TurtlePU

Arithmetization looks like this then:


class Arithmetizable a f where
type InputRep a f :: Type
type OutputRep a f :: Type
arithmetize :: f -> (InputRep a f -> ArithmeticCircuit a) -> OutputRep a f -> ArithmeticCircuit a

instance SymbolicData a u => Arithmetizable a (u (ArithmeticCircuit a)) where type InputRep a (u (ArithmeticCircuit a)) = Void type OutputRep a (u (ArithmeticCircuit a)) = Rep a u arithmetize c _ = index c

instance (SymbolicData a x, Arithmetizable a f) => Arithmetizable a (x (ArithmeticCircuit a) -> f) where type InputRep a (x (ArithmeticCircuit a) -> f) = Either (Rep a x) (InputRep a f) type OutputRep a (x (ArithmeticCircuit a) -> f) = OutputRep a f arithmetize f i = arithmetize (f $ tabulate (i . Left)) (i . Right)

vlasin commented 2 months ago

@TurtlePU

Arithmetization looks like this then:

class Arithmetizable a f where
  type InputRep a f :: Type
  type OutputRep a f :: Type
  arithmetize :: f -> (InputRep a f -> ArithmeticCircuit a) -> OutputRep a f -> ArithmeticCircuit a

instance SymbolicData a u => Arithmetizable a (u (ArithmeticCircuit a)) where
  type InputRep a (u (ArithmeticCircuit a)) = Void
  type OutputRep a (u (ArithmeticCircuit a)) = Rep a u
  arithmetize c _ = index c

instance (SymbolicData a x, Arithmetizable a f) => Arithmetizable a (x (ArithmeticCircuit a) -> f) where
  type InputRep a (x (ArithmeticCircuit a) -> f) = Either (Rep a x) (InputRep a f)
  type OutputRep a (x (ArithmeticCircuit a) -> f) = OutputRep a f
  arithmetize f i = arithmetize (f $ tabulate (i . Left)) (i . Right)

Why does arithmetize have this signature?

TurtlePU commented 2 months ago

@vlasin InputRep is an indexing type for function inputs, OutputRep is an indexing type for function outputs To arithmetize a function of type f, we need to have prepared inputs in a mapping of type InputRep a f -> ArithmeticCircuit a and generate outputs in form of a mapping OutputRep a f -> ArithmeticCircuit a

vlasin commented 2 months ago

@vlasin InputRep is an indexing type for function inputs, OutputRep is an indexing type for function outputs To arithmetize a function of type f, we need to have prepared inputs in a mapping of type InputRep a f -> ArithmeticCircuit a and generate outputs in form of a mapping OutputRep a f -> ArithmeticCircuit a

Got you, makes sense.

echatav commented 2 months ago

@TurtlePU here's a variant I got past GHC.

class Arithmetizable a f where
  arithmetize :: f -> (Inputs a f -> ArithmeticCircuit a) -> Outputs a f -> ArithmeticCircuit a

type family Inputs a f where
  Inputs a (x (ArithmeticCircuit a) -> f) =
    Either (Basis (ArithmeticCircuit a) x) (Inputs a f)
  Inputs a (u (ArithmeticCircuit a)) = Void

type family Outputs a f where
  Outputs a (x (ArithmeticCircuit a) -> f) = Outputs a f
  Outputs a (u (ArithmeticCircuit a)) = Basis (ArithmeticCircuit a) u

instance {-# OVERLAPPABLE #-}
  ( SymbolicData (ArithmeticCircuit a) u
  , Basis (ArithmeticCircuit a) u ~ Outputs a (u (ArithmeticCircuit a))
  ) => Arithmetizable a (u (ArithmeticCircuit a)) where
    arithmetize c _ = indexV c

instance {-# OVERLAPPING #-}
  ( SymbolicData (ArithmeticCircuit a) x
  , Arithmetizable a f
  ) => Arithmetizable a (x (ArithmeticCircuit a) -> f) where
    arithmetize f i = arithmetize (f $ tabulateV (i . Left)) (i . Right)