parse JSON input files (in Haskell)

This commit is contained in:
Balazs Komuves 2025-03-14 17:05:39 +01:00
parent 60b4d8d8f4
commit b7f036848d
No known key found for this signature in database
GPG Key ID: F63B7AEF18435562
3 changed files with 71 additions and 10 deletions

View File

@ -6,27 +6,31 @@ The original idea behind this small project was to take the "computation graph"
files generated by [`circom-witnesscalc`](https://github.com/iden3/circom-witnesscalc),
and either interprets or compiles them to various algebra backends.
While this is quite straightforward in principle, and seems to work on small
examples, it turns out that `circom-witnesscalc` itself is completely broken,
in the sense that it doesn't seem to be able to handle nontrivial circuits using any
kind of meaningful metaprogramming (that being the only thing which makes `circom`
borderline useful).
While this is quite straightforward in principle, and seems to work on particular
examples, it turns out that `circom-witnesscalc` itself has some serious limitations.
And this doesn't look fixable without something like a full rewrite of `circom-witnesscalc` (?).
The biggest one is that it doesn't support any kind of dynamic computation (which should
be obvious from the fact that it produces a static graph). But even if one uses only
static computations, there are further very annoying things which just don't work.
However at the end this is still a useful thing.
### Implementation status
Compiler (in Haskell):
- [x] parsing the graph file
- [x] parsing json input
- [x] naive interpreter
- [ ] exporting the witness
- [ ] constantine backend
- [ ] zikkurat backend
- [ ] arkworks backend
Nim witness generator:
Nim witness generator (to be used with [`nim-groth16`](https://github.com/codex-storage/nim-groth16))
- [x] parsing the graph file
- [ ] parsing json input
- [ ] generating the witness
- [ ] proper error handling

52
haskell/src/JSON.hs Normal file
View File

@ -0,0 +1,52 @@
-- | Parse JSON input files
module JSON where
--------------------------------------------------------------------------------
import Data.List
import Data.Foldable as F
import Data.Foldable.WithIndex as FI
import Data.Map (Map)
import qualified Data.Map as Map
import qualified Data.Text as T
import qualified Data.ByteString as B
import Data.Aeson
import Data.Aeson.Key as Key
import Data.Scientific
--------------------------------------------------------------------------------
parseInputJsonValue :: Value -> Map String [Integer]
parseInputJsonValue val =
case val of
Object obj -> Map.fromList (map worker (FI.itoList obj))
_ -> error "parseInputJsonValue: expecting a JSON object"
where
worker (key,value) = (Key.toString key, flatten value)
flatten :: Value -> [Integer]
flatten val = case val of
Number num -> numberToInteger num
Array arr -> F.concatMap flatten arr
String txt -> [read (T.unpack txt)]
_ -> error "parseInputJsonValue/flatten: expecting a number or an array"
numberToInteger x = case floatingOrInteger x of
Right y -> [y]
Left _ -> error "parseInputJsonValue/numberToInteger: expecting an integer"
--------------------------------------------------------------------------------
loadInputJsonFile :: FilePath -> IO (Map String [Integer])
loadInputJsonFile fpath = do
text <- B.readFile fpath
let Just value = decodeStrict text
return $ parseInputJsonValue value
--------------------------------------------------------------------------------

View File

@ -8,8 +8,11 @@ import qualified Data.Map as Map
import Witness
import Parser
import Graph
import JSON
--------------------------------------------------------------------------------
{-
(~>) :: String -> a -> (String, a)
(~>) = (,)
@ -22,13 +25,15 @@ testInputs = Map.fromList
, "b" ~> [0xff02]
]
-}
--------------------------------------------------------------------------------
main :: IO ()
main = do
Right graph <- parseGraphFile "../tmp/graph2.bin"
Right graph <- parseGraphFile "../../tmp/graph4.bin"
putStrLn ""
print graph
let wtns = witnessCalc testInputs graph
inputs <- loadInputJsonFile "../../tmp/input4.json"
print (inputSignals $ graphMeta graph)
let wtns = witnessCalc inputs graph
putStrLn ""
print wtns