diff --git a/benches/end2end.rs b/benches/end2end.rs index 13fe31dfba..b6b16ccf28 100644 --- a/benches/end2end.rs +++ b/benches/end2end.rs @@ -5,14 +5,15 @@ use criterion::{ }; use lurk::{ + circuit::circuit_frame::MultiFrame, eval::{ empty_sym_env, lang::{Coproc, Lang}, Evaluator, }, field::LurkField, - proof::nova::NovaProver, proof::Prover, + proof::{nova::NovaProver, MultiFrameTrait}, ptr::Ptr, public_parameters, state::State, @@ -70,7 +71,7 @@ fn end2end_benchmark(c: &mut Criterion) { let prover = NovaProver::new(reduction_count, lang_pallas); // use cached public params - let pp = public_parameters::public_params( + let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, Coproc>>( reduction_count, true, lang_pallas_rc.clone(), @@ -87,7 +88,7 @@ fn end2end_benchmark(c: &mut Criterion) { b.iter(|| { let ptr = go_base::(&mut store, state.clone(), s.0, s.1); let _result = prover - .evaluate_and_prove(&pp, ptr, env, &mut store, limit, lang_pallas_rc.clone()) + .evaluate_and_prove(&pp, ptr, env, &mut store, limit, &lang_pallas_rc) .unwrap(); }) }); @@ -290,27 +291,26 @@ fn prove_benchmark(c: &mut Criterion) { group.bench_with_input(benchmark_id, &size, |b, &s| { let ptr = go_base::(&mut store, state.clone(), s.0, s.1); let prover = NovaProver::new(reduction_count, lang_pallas.clone()); - let pp = public_parameters::public_params( - reduction_count, - true, - lang_pallas_rc.clone(), - Utf8Path::new(PUBLIC_PARAMS_PATH), - ) - .unwrap(); - let frames = prover - .get_evaluation_frames( - ptr, - empty_sym_env(&store), - &mut store, - limit, + let pp = + public_parameters::public_params::<_, _, MultiFrame<'_, _, Coproc>>( + reduction_count, + true, lang_pallas_rc.clone(), + Utf8Path::new(PUBLIC_PARAMS_PATH), ) .unwrap(); + let frames = MultiFrame::get_evaluation_frames( + |count| prover.needs_frame_padding(count), + ptr, + empty_sym_env(&store), + &store, + limit, + &lang_pallas, + ) + .unwrap(); b.iter(|| { - let result = prover - .prove(&pp, &frames, &store, lang_pallas_rc.clone()) - .unwrap(); + let result = prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap(); black_box(result); }) }); @@ -340,30 +340,30 @@ fn prove_compressed_benchmark(c: &mut Criterion) { let state = State::init_lurk_state().rccell(); + let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, _>>( + reduction_count, + true, + lang_pallas_rc.clone(), + Utf8Path::new(PUBLIC_PARAMS_PATH), + ) + .unwrap(); + group.bench_with_input(benchmark_id, &size, |b, &s| { let ptr = go_base::(&mut store, state.clone(), s.0, s.1); let prover = NovaProver::new(reduction_count, lang_pallas.clone()); - let pp = public_parameters::public_params( - reduction_count, - true, - lang_pallas_rc.clone(), - Utf8Path::new(PUBLIC_PARAMS_PATH), + + let frames = MultiFrame::get_evaluation_frames( + |count| prover.needs_frame_padding(count), + ptr, + empty_sym_env(&store), + &store, + limit, + &lang_pallas, ) .unwrap(); - let frames = prover - .get_evaluation_frames( - ptr, - empty_sym_env(&store), - &mut store, - limit, - lang_pallas_rc.clone(), - ) - .unwrap(); b.iter(|| { - let (proof, _, _, _) = prover - .prove(&pp, &frames, &store, lang_pallas_rc.clone()) - .unwrap(); + let (proof, _, _, _) = prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap(); let compressed_result = proof.compress(&pp).unwrap(); black_box(compressed_result); @@ -395,25 +395,24 @@ fn verify_benchmark(c: &mut Criterion) { group.bench_with_input(benchmark_id, &size, |b, &s| { let ptr = go_base(&mut store, state.clone(), s.0, s.1); let prover = NovaProver::new(reduction_count, lang_pallas.clone()); - let pp = public_parameters::public_params( + let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, _>>( reduction_count, true, lang_pallas_rc.clone(), Utf8Path::new(PUBLIC_PARAMS_PATH), ) .unwrap(); - let frames = prover - .get_evaluation_frames( - ptr, - empty_sym_env(&store), - &mut store, - limit, - lang_pallas_rc.clone(), - ) - .unwrap(); - let (proof, z0, zi, num_steps) = prover - .prove(&pp, &frames, &store, lang_pallas_rc.clone()) - .unwrap(); + let frames = MultiFrame::get_evaluation_frames( + |count| prover.needs_frame_padding(count), + ptr, + empty_sym_env(&store), + &store, + limit, + &lang_pallas, + ) + .unwrap(); + let (proof, z0, zi, num_steps) = + prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap(); b.iter_batched( || z0.clone(), @@ -453,7 +452,7 @@ fn verify_compressed_benchmark(c: &mut Criterion) { group.bench_with_input(benchmark_id, &size, |b, &s| { let ptr = go_base(&mut store, state.clone(), s.0, s.1); let prover = NovaProver::new(reduction_count, lang_pallas.clone()); - let pp = public_parameters::public_params( + let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, _>>( reduction_count, true, lang_pallas_rc.clone(), @@ -464,14 +463,13 @@ fn verify_compressed_benchmark(c: &mut Criterion) { .get_evaluation_frames( ptr, empty_sym_env(&store), - &mut store, + &store, limit, lang_pallas_rc.clone(), ) .unwrap(); - let (proof, z0, zi, num_steps) = prover - .prove(&pp, &frames, &store, lang_pallas_rc.clone()) - .unwrap(); + let (proof, z0, zi, num_steps) = + prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap(); let compressed_proof = proof.compress(&pp).unwrap(); diff --git a/benches/fibonacci.rs b/benches/fibonacci.rs index dcbd4b24cf..01999d4fea 100644 --- a/benches/fibonacci.rs +++ b/benches/fibonacci.rs @@ -9,6 +9,7 @@ use criterion::{ use pasta_curves::pallas; use lurk::{ + circuit::circuit_frame::MultiFrame, eval::{ empty_sym_env, lang::{Coproc, Lang}, @@ -75,7 +76,7 @@ fn fibo_prove( let lang_rc = Arc::new(lang_pallas.clone()); // use cached public params - let pp = public_params( + let pp = public_params::<_, _, MultiFrame<'_, _, _>>( prove_params.reduction_count, true, lang_rc.clone(), @@ -98,13 +99,13 @@ fn fibo_prove( let prover = NovaProver::new(prove_params.reduction_count, lang_pallas.clone()); let frames = &prover - .get_evaluation_frames(ptr, env, &mut store, limit, lang_rc.clone()) + .get_evaluation_frames(ptr, env, &store, limit, lang_rc.clone()) .unwrap(); b.iter_batched( || (frames, lang_rc.clone()), |(frames, lang_rc)| { - let result = prover.prove(&pp, frames, &store, lang_rc); + let result = prover.prove(&pp, frames, &store, &lang_rc); let _ = black_box(result); }, BatchSize::LargeInput, diff --git a/benches/public_params.rs b/benches/public_params.rs index 83584bb7d8..dab9360ebc 100644 --- a/benches/public_params.rs +++ b/benches/public_params.rs @@ -1,6 +1,7 @@ use blstrs::Scalar as Fr; use criterion::{black_box, criterion_group, criterion_main, Criterion, SamplingMode}; use lurk::{ + circuit::circuit_frame::MultiFrame, eval::lang::{Coproc, Lang}, proof::groth16::Groth16Prover, proof::nova, @@ -26,15 +27,26 @@ fn public_params_benchmark(c: &mut Criterion) { group.bench_function("public_params_nova", |b| { b.iter(|| { - let result = nova::public_params(reduction_count, lang_pallas_rc.clone()); + let result = nova::public_params::<_, _, MultiFrame<'_, _, _>>( + reduction_count, + lang_pallas_rc.clone(), + ); black_box(result) }) }); group.bench_function("public_params_groth", |b| { b.iter(|| { - let result = - Groth16Prover::create_groth_params(DEFAULT_REDUCTION_COUNT, lang_bls_rc.clone()); + let result = Groth16Prover::< + _, + Coproc, + Fr, + MultiFrame<'_, Fr, Coproc>, + >::create_groth_params( + DEFAULT_REDUCTION_COUNT, + lang_bls_rc.clone(), + ) + .unwrap(); black_box(result) }) }); diff --git a/benches/sha256_ivc.rs b/benches/sha256_ivc.rs index 2f47147c0f..19de2fa52f 100644 --- a/benches/sha256_ivc.rs +++ b/benches/sha256_ivc.rs @@ -6,6 +6,7 @@ //! Note: The example [example/sha256_ivc.rs] is this same benchmark but as an example //! that's easier to play with and run. +use lurk::circuit::circuit_frame::MultiFrame; use lurk::circuit::gadgets::data::GlobalAllocations; use lurk::state::user_sym; use lurk::{circuit::gadgets::pointer::AllocatedContPtr, tag::Tag}; @@ -226,7 +227,7 @@ fn sha256_ivc_prove( let lang_rc = Arc::new(lang.clone()); // use cached public params - let pp = public_params( + let pp = public_params::<_, _, MultiFrame<'_, _, _>>( reduction_count, true, lang_rc.clone(), @@ -256,7 +257,7 @@ fn sha256_ivc_prove( b.iter_batched( || (frames, lang_rc.clone()), |(frames, lang_rc)| { - let result = prover.prove(&pp, frames, store, lang_rc); + let result = prover.prove(&pp, frames, store, &lang_rc); let _ = black_box(result); }, BatchSize::LargeInput, @@ -309,7 +310,7 @@ fn sha256_ivc_prove_compressed( let lang_rc = Arc::new(lang.clone()); // use cached public params - let pp = public_params( + let pp = public_params::<_, _, MultiFrame<'_, _, _>>( reduction_count, true, lang_rc.clone(), @@ -339,7 +340,7 @@ fn sha256_ivc_prove_compressed( b.iter_batched( || (frames, lang_rc.clone()), |(frames, lang_rc)| { - let (proof, _, _, _) = prover.prove(&pp, frames, store, lang_rc).unwrap(); + let (proof, _, _, _) = prover.prove(&pp, frames, store, &lang_rc).unwrap(); let compressed_result = proof.compress(&pp).unwrap(); let _ = black_box(compressed_result); diff --git a/benches/synthesis.rs b/benches/synthesis.rs index 0d203a8d27..577b7869fc 100644 --- a/benches/synthesis.rs +++ b/benches/synthesis.rs @@ -58,10 +58,13 @@ fn synthesize( let env = empty_sym_env(&store); let fib_n = (reduction_count / 3) as u64; // Heuristic, since one fib is 35 iterations. let ptr = fib::(&mut store, state.clone(), black_box(fib_n)); - let prover = NovaProver::new(*reduction_count, lang_pallas.clone()); + let prover = NovaProver::<_, _, MultiFrame<'_, _, _>>::new( + *reduction_count, + lang_pallas.clone(), + ); let frames = prover - .get_evaluation_frames(ptr, env, &mut store, limit, lang_rc.clone()) + .get_evaluation_frames(ptr, env, &store, limit, lang_rc.clone()) .unwrap(); let folding_config = Arc::new(FoldingConfig::new_ivc(lang_rc.clone(), *reduction_count)); diff --git a/clutch/src/lib.rs b/clutch/src/lib.rs index 37b5a31e9a..414ae3112e 100644 --- a/clutch/src/lib.rs +++ b/clutch/src/lib.rs @@ -8,6 +8,7 @@ use fcomm::{ CommittedExpression, CommittedExpressionMap, LurkCont, LurkPtr, NovaProofCache, Opening, Proof, PtrEvaluation, }; +use lurk::circuit::circuit_frame::MultiFrame; use lurk::lurk_sym_ptr; use lurk::public_parameters::public_params; @@ -147,7 +148,14 @@ impl ReplTrait> for ClutchState> { let lang_rc = Arc::new(lang.clone()); // Load params from disk cache, or generate them in the background. - thread::spawn(move || public_params(reduction_count, true, lang_rc, &public_param_dir())); + thread::spawn(move || { + public_params::<_, _, MultiFrame<'_, _, Coproc<_>>>( + reduction_count, + true, + lang_rc, + &public_param_dir(), + ) + }); Self { repl_state: ReplState::new(s, limit, command, lang), @@ -531,7 +539,10 @@ impl ClutchState> { fn prove(&mut self, store: &mut Store, rest: Ptr) -> Result>> { let (proof_in_expr, _rest1) = store.car_cdr(&rest)?; - let prover = NovaProver::>::new(self.reduction_count, (*self.lang()).clone()); + let prover = NovaProver::<'_, F, Coproc, MultiFrame<'_, F, Coproc>>::new( + self.reduction_count, + (*self.lang()).clone(), + ); let pp = public_params(self.reduction_count, true, self.lang(), &public_param_dir())?; let proof = if rest.is_nil() { diff --git a/examples/circom.rs b/examples/circom.rs index 199fd468b4..23958bc5da 100644 --- a/examples/circom.rs +++ b/examples/circom.rs @@ -32,6 +32,7 @@ use std::marker::PhantomData; use std::sync::Arc; use std::time::Instant; +use lurk::circuit::circuit_frame::MultiFrame; use lurk::circuit::gadgets::circom::CircomGadget; use lurk::circuit::gadgets::pointer::AllocatedPtr; @@ -114,13 +115,16 @@ fn main() { let expr = format!("({coproc_expr})"); let ptr = store.read(&expr).unwrap(); - let nova_prover = NovaProver::>::new(REDUCTION_COUNT, lang.clone()); + let nova_prover = NovaProver::, MultiFrame<'_, _, _>>::new( + REDUCTION_COUNT, + lang.clone(), + ); let lang_rc = Arc::new(lang); println!("Setting up public parameters..."); let pp_start = Instant::now(); - let pp = public_params::<_, Sha256Coproc>( + let pp = public_params::<_, Sha256Coproc, MultiFrame<'_, _, _>>( REDUCTION_COUNT, true, lang_rc.clone(), @@ -135,7 +139,7 @@ fn main() { let proof_start = Instant::now(); let (proof, z0, zi, num_steps) = nova_prover - .evaluate_and_prove(&pp, ptr, empty_sym_env(store), store, 10000, lang_rc) + .evaluate_and_prove(&pp, ptr, empty_sym_env(store), store, 10000, &lang_rc) .unwrap(); let proof_end = proof_start.elapsed(); diff --git a/examples/sha256.rs b/examples/sha256.rs index 8804ead50f..3e79d11fb2 100644 --- a/examples/sha256.rs +++ b/examples/sha256.rs @@ -3,6 +3,7 @@ use std::marker::PhantomData; use std::sync::Arc; use std::time::Instant; +use lurk::circuit::circuit_frame::MultiFrame; use lurk::circuit::gadgets::constraints::alloc_equal; use lurk::circuit::gadgets::data::{allocate_constant, GlobalAllocations}; use lurk::circuit::gadgets::pointer::{AllocatedContPtr, AllocatedPtr}; @@ -190,13 +191,16 @@ fn main() { let cproc_call = store.list(&[cproc_sym_ptr]); - let nova_prover = NovaProver::>::new(REDUCTION_COUNT, lang.clone()); + let nova_prover = NovaProver::, MultiFrame<'_, _, _>>::new( + REDUCTION_COUNT, + lang.clone(), + ); let lang_rc = Arc::new(lang); println!("Setting up public parameters..."); let pp_start = Instant::now(); - let pp = public_params::<_, Sha256Coproc>( + let pp = public_params::<_, Sha256Coproc, MultiFrame<'_, _, _>>( REDUCTION_COUNT, true, lang_rc.clone(), @@ -217,7 +221,14 @@ fn main() { let (proof, z0, zi, num_steps) = tracing_texray::examine(tracing::info_span!("prog_start")) .in_scope(|| { nova_prover - .evaluate_and_prove(&pp, cproc_call, empty_sym_env(store), store, 10000, lang_rc) + .evaluate_and_prove( + &pp, + cproc_call, + empty_sym_env(store), + store, + 10000, + &lang_rc, + ) .unwrap() }); let proof_end = proof_start.elapsed(); diff --git a/examples/sha256_ivc.rs b/examples/sha256_ivc.rs index 082589deb0..edd7a33800 100644 --- a/examples/sha256_ivc.rs +++ b/examples/sha256_ivc.rs @@ -2,6 +2,7 @@ use std::marker::PhantomData; use std::sync::Arc; use std::time::Instant; +use lurk::circuit::circuit_frame::MultiFrame; use lurk::circuit::gadgets::data::GlobalAllocations; use lurk::circuit::gadgets::pointer::{AllocatedContPtr, AllocatedPtr}; use lurk::coprocessor::{CoCircuit, Coprocessor}; @@ -193,7 +194,8 @@ fn main() { ); let lang_rc = Arc::new(lang.clone()); - let nova_prover = NovaProver::>::new(REDUCTION_COUNT, lang); + let nova_prover = + NovaProver::, MultiFrame<'_, _, _>>::new(REDUCTION_COUNT, lang); println!("Setting up public parameters (rc = {REDUCTION_COUNT})..."); @@ -207,7 +209,7 @@ fn main() { println!("Beginning proof step..."); let proof_start = Instant::now(); let (proof, z0, zi, num_steps) = nova_prover - .evaluate_and_prove(pp, call, empty_sym_env(store), store, 10000, lang_rc) + .evaluate_and_prove(pp, call, empty_sym_env(store), store, 10000, &lang_rc) .unwrap(); let proof_end = proof_start.elapsed(); diff --git a/fcomm/src/bin/fcomm.rs b/fcomm/src/bin/fcomm.rs index 04d89ed510..2f35e6b3ed 100644 --- a/fcomm/src/bin/fcomm.rs +++ b/fcomm/src/bin/fcomm.rs @@ -1,4 +1,5 @@ use abomonation::Abomonation; +use lurk::circuit::circuit_frame::MultiFrame; use lurk::lurk_sym_ptr; use lurk::proof::nova::{CurveCycleEquipped, G1, G2}; use nova::traits::Group; @@ -231,7 +232,10 @@ impl Open { let s = &mut Store::::default(); let rc = ReductionCount::try_from(self.reduction_count).expect("reduction count"); - let prover = NovaProver::>::new(rc.count(), lang.clone()); + let prover = NovaProver::<'_, S1, Coproc, MultiFrame<'_, S1, Coproc>>::new( + rc.count(), + lang.clone(), + ); let lang_rc = Arc::new(lang.clone()); let pp = public_params(rc.count(), true, lang_rc, &public_param_dir()).expect("public params"); @@ -336,7 +340,10 @@ impl Prove { fn prove(&self, limit: usize, lang: &Lang>) { let s = &mut Store::::default(); let rc = ReductionCount::try_from(self.reduction_count).unwrap(); - let prover = NovaProver::>::new(rc.count(), lang.clone()); + let prover = NovaProver::<'_, S1, Coproc, MultiFrame<'_, S1, Coproc>>::new( + rc.count(), + lang.clone(), + ); let lang_rc = Arc::new(lang.clone()); let pp = public_params(rc.count(), true, lang_rc.clone(), &public_param_dir()).unwrap(); diff --git a/fcomm/src/lib.rs b/fcomm/src/lib.rs index f301445c29..69a21fd110 100644 --- a/fcomm/src/lib.rs +++ b/fcomm/src/lib.rs @@ -14,7 +14,7 @@ use hex::FromHex; #[cfg(not(target_arch = "wasm32"))] use lurk::field::FWrap; use lurk::{ - circuit::ToInputs, + circuit::{circuit_frame::MultiFrame, ToInputs}, eval::{ empty_sym_env, lang::{Coproc, Lang}, @@ -286,7 +286,7 @@ where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { pub claim: Claim, - pub proof: nova::Proof<'a, F, Coproc>, + pub proof: nova::Proof<'a, F, Coproc, MultiFrame<'a, F, Coproc>>, pub num_steps: usize, pub reduction_count: ReductionCount, } @@ -645,8 +645,8 @@ impl<'a> Opening { limit: usize, chain: bool, only_use_cached_proofs: bool, - nova_prover: &'a NovaProver>, - pp: &'a PublicParams<'_, S1, Coproc>, + nova_prover: &'a NovaProver<'_, S1, Coproc, MultiFrame<'a, S1, Coproc>>, + pp: &'a PublicParams>>, lang: Arc>>, ) -> Result, Error> { let claim = Self::apply(s, input, function, limit, chain, &lang)?; @@ -666,8 +666,8 @@ impl<'a> Opening { request: &OpeningRequest, limit: usize, only_use_cached_proofs: bool, - nova_prover: &'a NovaProver>, - pp: &'a PublicParams<'_, S1, Coproc>, + nova_prover: &'a NovaProver<'_, S1, Coproc, MultiFrame<'a, S1, Coproc>>, + pp: &'a PublicParams>>, lang: Arc>>, ) -> Result, Error> { let input = request.input.expr.ptr(s, limit, &lang); @@ -799,8 +799,8 @@ impl<'a> Proof<'a, S1> { supplied_env: Option>, limit: usize, only_use_cached_proofs: bool, - nova_prover: &'a NovaProver>, - pp: &'a PublicParams<'_, S1, Coproc>, + nova_prover: &'a NovaProver<'_, S1, Coproc, MultiFrame<'a, S1, Coproc>>, + pp: &'a PublicParams>>, lang: Arc>>, ) -> Result { let env = supplied_env.unwrap_or_else(|| empty_sym_env(s)); @@ -837,8 +837,8 @@ impl<'a> Proof<'a, S1> { claim: &Claim, limit: usize, only_use_cached_proofs: bool, - nova_prover: &'a NovaProver>, - pp: &'a PublicParams<'_, S1, Coproc>, + nova_prover: &'a NovaProver<'_, S1, Coproc, MultiFrame<'a, S1, Coproc>>, + pp: &'a PublicParams>>, lang: &Arc>>, ) -> Result { let reduction_count = nova_prover.reduction_count(); @@ -881,7 +881,7 @@ impl<'a> Proof<'a, S1> { }; let (proof, _public_input, _public_output, num_steps) = nova_prover - .evaluate_and_prove(pp, expr, env, s, limit, lang.clone()) + .evaluate_and_prove(pp, expr, env, s, limit, lang) .expect("Nova proof failed"); let proof = Self { @@ -922,7 +922,7 @@ impl<'a> Proof<'a, S1> { pub fn verify( &self, - pp: &PublicParams<'_, S1, Coproc>, + pp: &PublicParams>>, lang: &Lang>, ) -> Result { let (public_inputs, public_outputs) = self.io_vecs(lang)?; @@ -1236,7 +1236,10 @@ mod test { .expect("function_map set"); for (function_input, _expected_output) in io { - let prover = NovaProver::>::new(rc.count(), lang.clone()); + let prover = NovaProver::<'_, S1, Coproc, MultiFrame<'_, S1, Coproc>>::new( + rc.count(), + lang.clone(), + ); let input = s.read(function_input).expect("Read error"); diff --git a/fcomm/tests/proof_tests.rs b/fcomm/tests/proof_tests.rs index cc892794ec..0e549a5243 100644 --- a/fcomm/tests/proof_tests.rs +++ b/fcomm/tests/proof_tests.rs @@ -234,7 +234,7 @@ fn test_function_aux( let proof = Proof::::read_from_json_path(&proof_path).expect("read proof"); let opening = proof.claim.opening().expect("expected opening claim"); - let mut store = Store::::default(); + let store = Store::::default(); let input = store.read(function_input).expect("store read"); let canonical_input = input.fmt_to_string(&store, initial_lurk_state()); diff --git a/src/circuit/circuit_frame.rs b/src/circuit/circuit_frame.rs index f93d59f503..05172faef0 100644 --- a/src/circuit/circuit_frame.rs +++ b/src/circuit/circuit_frame.rs @@ -16,11 +16,13 @@ use crate::{ pointer::{AllocatedContPtr, AllocatedPtr, AsAllocatedHashComponents}, }, config::CONFIG, + eval::{empty_sym_env, lang::Lang}, field::LurkField, hash::HashConst, hash_witness::{ ConsCircuitWitness, ConsName, ContCircuitWitness, ContName, HashCircuitWitnessCache, }, + proof::CEKState, store::NamedConstants, tag::Tag, }; @@ -39,9 +41,11 @@ use crate::eval::{Frame, Meta, Witness, IO}; use crate::expr::Thunk; use crate::hash_witness::HashWitness; use crate::lurk_sym_ptr; -use crate::proof::{supernova::FoldingConfig, Provable}; -use crate::ptr::Ptr; -use crate::store::Store; +use crate::proof::{ + supernova::FoldingConfig, EvaluationStore, FrameLike, MultiFrameTrait, Provable, +}; +use crate::ptr::{ContPtr, Ptr}; +use crate::store::{self, Store}; use crate::tag::{ContTag, ExprTag, Op1, Op2}; use num_bigint::BigUint; use num_integer::Integer; @@ -69,6 +73,205 @@ pub struct MultiFrame<'a, F: LurkField, C: Coprocessor> { pub meta: Meta, } +impl CEKState, ContPtr> for IO { + fn expr(&self) -> &Ptr { + &self.expr + } + fn env(&self) -> &Ptr { + &self.env + } + fn cont(&self) -> &ContPtr { + &self.cont + } +} + +impl> FrameLike, ContPtr> + for Frame, Witness, F, C> +{ + type FrameIO = IO; + fn input(&self) -> &Self::FrameIO { + &self.input + } + fn output(&self) -> &Self::FrameIO { + &self.output + } +} + +impl<'a, F: LurkField, C: Coprocessor> FrameLike, ContPtr> for CircuitFrame<'a, F, C> { + // TODO: fix the inability to return an error here + // We *could* add an Error type here, but actually, this is a case where a builder pattern + // would resolve the initialization of these structures + type FrameIO = IO; + fn input(&self) -> &Self::FrameIO { + self.input.as_ref().unwrap() + } + fn output(&self) -> &Self::FrameIO { + self.output.as_ref().unwrap() + } +} + +impl EvaluationStore for Store { + type Ptr = Ptr; + type ContPtr = ContPtr; + type Error = store::Error; + + fn read(&self, expr: &str) -> Result { + Store::read(self, expr).map_err(|e| store::Error(e.to_string())) + } + fn initial_empty_env(&self) -> Self::Ptr { + empty_sym_env(self) + } + fn get_cont_terminal(&self) -> Self::ContPtr { + // qualified syntax for the + Store::get_cont_terminal(self) + } + + fn ptr_eq(&self, left: &Self::Ptr, right: &Self::Ptr) -> Result { + self.ptr_eq(left, right) + } +} + +impl<'a, F: LurkField, C: Coprocessor + 'a> MultiFrameTrait<'a, F, C> for MultiFrame<'a, F, C> { + type Ptr = Ptr; + type ContPtr = ContPtr; + type Store = Store; + type StoreError = store::Error; + type EvalFrame = Frame, Witness, F, C>; + type CircuitFrame = CircuitFrame<'a, F, C>; + type GlobalAllocation = GlobalAllocations; + type AllocatedIO = AllocatedIO; + + fn emitted(store: &Self::Store, eval_frame: &Self::EvalFrame) -> Vec> { + match eval_frame.output.maybe_emitted_expression(store) { + Some(ptr) => vec![ptr], + None => Vec::default(), + } + } + + fn get_evaluation_frames( + padding_predicate: impl Fn(usize) -> bool, + expr: Ptr, + env: Ptr, + store: &Self::Store, + limit: usize, + lang: &Lang, + ) -> Result, Witness, F, C>>, crate::error::ProofError> { + let frames = crate::eval::Evaluator::generate_frames( + expr, + env, + store, + limit, + padding_predicate, + lang, + )?; + + store.hydrate_scalar_cache(); + + Ok(frames) + } + + fn io_to_scalar_vector( + store: &Self::Store, + io: &, ContPtr>>::FrameIO, + ) -> Result, Self::StoreError> { + io.to_vector(store) + } + + fn compute_witness(&self, s: &Self::Store) -> WitnessCS { + let mut wcs = WitnessCS::new(); + + let input = self.input.unwrap(); + + let expr = s.hash_expr(&input.expr).unwrap(); + let env = s.hash_expr(&input.env).unwrap(); + let cont = s.hash_cont(&input.cont).unwrap(); + + let z_scalar = vec![ + expr.tag().to_field(), + *expr.value(), + env.tag().to_field(), + *env.value(), + cont.tag().to_field(), + *cont.value(), + ]; + + let mut bogus_cs = WitnessCS::::new(); + let z: Vec> = z_scalar + .iter() + .map(|x| AllocatedNum::alloc(&mut bogus_cs, || Ok(*x)).unwrap()) + .collect::>(); + + let _ = nova::traits::circuit::StepCircuit::synthesize(self, &mut wcs, z.as_slice()); + + wcs + } + + fn cached_witness(&mut self) -> &mut Option> { + &mut self.cached_witness + } + + fn output(&self) -> &Option<, ContPtr>>::FrameIO> { + &self.output + } + + fn frames(&self) -> Option<&Vec> { + self.frames.as_ref() + } + + fn precedes(&self, maybe_next: &Self) -> bool { + self.output == maybe_next.input + } + + fn synthesize_frames>( + &self, + cs: &mut CS, + store: &Self::Store, + input: Self::AllocatedIO, + frames: &[Self::CircuitFrame], + g: &GlobalAllocations, + ) -> Self::AllocatedIO { + let (allocated_expr, allocated_env, allocated_cont) = input; + MultiFrame::synthesize_frames( + self, + cs, + store, + allocated_expr, + allocated_env, + allocated_cont, + frames, + g, + ) + } + + fn blank(folding_config: Arc>, meta: Meta) -> Self { + MultiFrame::blank(folding_config, meta) + } + + fn from_frames( + count: usize, + frames: &[Self::EvalFrame], + store: &'a Self::Store, + folding_config: Arc>, + ) -> Vec { + MultiFrame::from_frames(count, frames, store, folding_config) + } + + /// Make a dummy `MultiFrame`, duplicating `self`'s final `CircuitFrame`. + fn make_dummy( + count: usize, + circuit_frame: Option>, + store: &'a Self::Store, + folding_config: Arc>, + meta: Meta, + ) -> Self { + MultiFrame::make_dummy(count, circuit_frame, store, folding_config, meta) + } + + fn significant_frame_count(frames: &[Self::EvalFrame]) -> usize { + frames.iter().rev().skip_while(|f| f.is_complete()).count() + } +} + impl<'a, F: LurkField, C: Coprocessor> CircuitFrame<'a, F, C> { pub fn blank() -> Self { Self { @@ -5481,13 +5684,16 @@ mod tests { let lang = Arc::new(raw_lang.clone()); let (_, witness, meta) = input.reduce(&store, &lang).unwrap(); - let public_params = Groth16Prover::, Fr>::create_groth_params( + let public_params = Groth16Prover::, Fr, MultiFrame<'_, Fr, Coproc>>::create_groth_params( DEFAULT_REDUCTION_COUNT, lang.clone(), ) .unwrap(); let groth_prover = - Groth16Prover::, Fr>::new(DEFAULT_REDUCTION_COUNT, raw_lang); + Groth16Prover::, Fr, MultiFrame<'_, Fr, Coproc>>::new( + DEFAULT_REDUCTION_COUNT, + raw_lang, + ); let groth_params = &public_params.0; let vk = &groth_params.vk; diff --git a/src/cli/lurk_proof.rs b/src/cli/lurk_proof.rs index 21676d7a5f..eaf4ea8ec1 100644 --- a/src/cli/lurk_proof.rs +++ b/src/cli/lurk_proof.rs @@ -1,14 +1,16 @@ use ::nova::traits::Group; use abomonation::Abomonation; use anyhow::Result; -use pasta_curves::pallas::Scalar; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{ coprocessor::Coprocessor, eval::lang::{Coproc, Lang}, field::LurkField, - proof::nova::{self, CurveCycleEquipped, G1, G2}, + proof::{ + nova::{self, CurveCycleEquipped, G1, G2}, + MultiFrameTrait, + }, public_parameters::public_params, z_ptr::{ZContPtr, ZExprPtr}, z_store::ZStore, @@ -46,15 +48,20 @@ impl HasFieldModulus for LurkProofMeta { } /// Minimal data structure containing just enough for proof verification +#[non_exhaustive] #[derive(Serialize, Deserialize)] -pub(crate) enum LurkProof<'a, F: CurveCycleEquipped> -where - Coproc: Coprocessor, +#[serde(bound(serialize = "F: Serialize", deserialize = "F: DeserializeOwned"))] +pub(crate) enum LurkProof< + 'a, + F: CurveCycleEquipped, + C: Coprocessor, + M: MultiFrameTrait<'a, F, C>, +> where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { Nova { - proof: nova::Proof<'a, F, Coproc>, + proof: nova::Proof<'a, F, C, M>, public_inputs: Vec, public_outputs: Vec, num_steps: usize, @@ -63,9 +70,9 @@ where }, } -impl<'a, F: CurveCycleEquipped> HasFieldModulus for LurkProof<'a, F> +impl<'a, F: CurveCycleEquipped, C: Coprocessor + 'a, M: MultiFrameTrait<'a, F, C>> + HasFieldModulus for LurkProof<'a, F, C, M> where - Coproc: Coprocessor, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { @@ -81,11 +88,13 @@ impl LurkProofMeta { } } -impl<'a, F: CurveCycleEquipped + Serialize> LurkProof<'a, F> +impl<'a, F: CurveCycleEquipped + Serialize, M: MultiFrameTrait<'a, F, Coproc>> + LurkProof<'a, F, Coproc, M> where - Coproc: Coprocessor, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + ::CK1: Sync + Send, + ::CK2: Sync + Send, { #[inline] pub(crate) fn persist(self, proof_key: &str) -> Result<()> { @@ -93,7 +102,26 @@ where } } -impl<'a> LurkProof<'a, Scalar> { +impl< + F: CurveCycleEquipped + DeserializeOwned, + M: MultiFrameTrait<'static, F, Coproc> + 'static, + > LurkProof<'static, F, Coproc, M> +where + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + ::CK1: Sync + Send, + ::CK2: Sync + Send, +{ + pub(crate) fn verify_proof(proof_key: &str) -> Result<()> { + let lurk_proof: LurkProof<'_, F, Coproc, M> = load(proof_path(proof_key))?; + if lurk_proof.verify()? { + println!("✓ Proof \"{proof_key}\" verified"); + } else { + println!("✗ Proof \"{proof_key}\" failed on verification"); + } + Ok(()) + } + fn verify(self) -> Result { match self { Self::Nova { @@ -106,18 +134,8 @@ impl<'a> LurkProof<'a, Scalar> { } => { tracing::info!("Loading public parameters"); let pp = public_params(rc, true, std::sync::Arc::new(lang), &public_params_dir())?; - Ok(proof.verify(&pp, num_steps, &public_inputs, &public_outputs)?) + Ok(proof.verify(&*pp, num_steps, &public_inputs, &public_outputs)?) } } } - - pub(crate) fn verify_proof(proof_key: &str) -> Result<()> { - let lurk_proof: LurkProof<'_, Scalar> = load(proof_path(proof_key))?; - if lurk_proof.verify()? { - println!("✓ Proof \"{proof_key}\" verified"); - } else { - println!("✗ Proof \"{proof_key}\" failed on verification"); - } - Ok(()) - } } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index a30e4add6f..99c53770e1 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -15,6 +15,8 @@ use pasta_curves::pallas; use std::{collections::HashMap, fs}; use crate::{ + circuit::MultiFrame, + eval::lang::Coproc, field::{LanguageField, LurkField}, store::Store, z_data::{from_z_data, ZData}, @@ -519,7 +521,9 @@ impl Cli { &None, &None, ); - LurkProof::verify_proof(&verify_args.proof_id)?; + LurkProof::<_, _, MultiFrame<'_, _, Coproc>>::verify_proof( + &verify_args.proof_id, + )?; Ok(()) } Command::Circom(circom_args) => { diff --git a/src/cli/repl.rs b/src/cli/repl.rs index 74febe9d6d..1748481d16 100644 --- a/src/cli/repl.rs +++ b/src/cli/repl.rs @@ -19,6 +19,7 @@ use tracing::info; use super::{backend::Backend, commitment::Commitment, field_data::load, paths::commitment_path}; use crate::{ + circuit::MultiFrame, cli::paths::{proof_path, public_params_dir}, eval::{ lang::{Coproc, Lang}, @@ -238,11 +239,14 @@ impl Repl { let pp = public_params(self.rc, true, self.lang.clone(), &public_params_dir())?; - let prover = NovaProver::new(self.rc, (*self.lang).clone()); + let prover = NovaProver::, MultiFrame<'_, F, Coproc>>::new( + self.rc, + (*self.lang).clone(), + ); info!("Proving"); let (proof, public_inputs, public_outputs, num_steps) = - prover.prove(&pp, frames, &self.store, self.lang.clone())?; + prover.prove(&pp, frames, &self.store, &self.lang)?; info!("Compressing proof"); let proof = proof.compress(&pp)?; assert_eq!(self.rc * num_steps, pad(n_frames, self.rc)); diff --git a/src/cli/repl/meta_cmd.rs b/src/cli/repl/meta_cmd.rs index d8d37ad7f2..32535435f0 100644 --- a/src/cli/repl/meta_cmd.rs +++ b/src/cli/repl/meta_cmd.rs @@ -1,12 +1,18 @@ +use abomonation::Abomonation; use anyhow::{bail, Context, Result}; use camino::Utf8Path; +use nova::traits::Group; +use serde::de::DeserializeOwned; use std::process; use crate::{ + circuit::MultiFrame, cli::lurk_proof::LurkProof, + eval::lang::Coproc, field::LurkField, lurk_sym_ptr, package::{Package, SymbolRef}, + proof::nova::{CurveCycleEquipped, G1, G2}, ptr::Ptr, tag::{ContTag, ExprTag}, writer::Write, @@ -379,7 +385,14 @@ impl MetaCmd { }; } -impl MetaCmd { +impl MetaCmd +where + // TODO(huitseeker): this is a bit pedantic, revisit later. + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + ::CK1: Sync + Send, + ::CK2: Sync + Send, +{ const VERIFY: MetaCmd = MetaCmd { name: "verify", @@ -398,7 +411,9 @@ impl MetaCmd { run: |repl, cmd, args| { let first = repl.peek1(cmd, args)?; let proof_id = repl.get_string(&first)?; - LurkProof::verify_proof(&proof_id)?; + LurkProof::<_, _, MultiFrame<'_, _, Coproc>>::verify_proof( + &proof_id, + )?; Ok(()) } }; diff --git a/src/eval/mod.rs b/src/eval/mod.rs index d27fa748c5..d68efdf9c2 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -513,7 +513,7 @@ where pub fn generate_frames bool>( expr: Ptr, env: Ptr, - store: &'a mut Store, + store: &'a Store, limit: usize, needs_frame_padding: Fp, lang: &'a Lang, diff --git a/src/eval/tests/mod.rs b/src/eval/tests/mod.rs index e7fbed55ef..bd18e10146 100644 --- a/src/eval/tests/mod.rs +++ b/src/eval/tests/mod.rs @@ -1110,7 +1110,7 @@ fn evaluate_make_tree() { #[test] fn evaluate_make_tree_minimal_regression() { { - let mut s = Store::::default(); + let s = Store::::default(); let limit = 100; let expr = s .read( diff --git a/src/parser.rs b/src/parser.rs index 5174b7f43f..6dc7d64e52 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -35,7 +35,7 @@ pub enum Error { } impl Store { - pub fn read(&mut self, input: &str) -> Result, Error> { + pub fn read(&self, input: &str) -> Result, Error> { let state = State::init_lurk_state().rccell(); match preceded( syntax::parse_space, diff --git a/src/proof/groth16.rs b/src/proof/groth16.rs index 4f8dafab4f..40d819ab57 100644 --- a/src/proof/groth16.rs +++ b/src/proof/groth16.rs @@ -33,6 +33,8 @@ use std::marker::PhantomData; #[cfg(not(target_arch = "wasm32"))] use std::{env, fs::File, io}; +use super::MultiFrameTrait; + const DUMMY_RNG_SEED: [u8; 16] = [ 0x01, 0x03, 0x02, 0x04, 0x05, 0x07, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, ]; @@ -97,7 +99,9 @@ where pub reduction_count: usize, } -impl> Groth16Prover { +impl<'a, C: Coprocessor + 'a, M: MultiFrameTrait<'a, Scalar, C>> + Groth16Prover<'a, Bls12, C, Scalar, M> +{ /// Creates Groth16 parameters using the given reduction count. pub fn create_groth_params( reduction_count: usize, @@ -247,10 +251,16 @@ impl> Groth16Prover { /// A prover struct for the Groth16 proving system. /// Implements the crate::Prover trait. #[derive(Debug)] -pub struct Groth16Prover, F: LurkField> { +pub struct Groth16Prover< + 'a, + E: MultiMillerLoop, + C: Coprocessor + 'a, + F: LurkField, + M: MultiFrameTrait<'a, F, C>, +> { reduction_count: usize, lang: Lang, - _p: PhantomData<(E, C, F)>, + _p: PhantomData<(E, &'a M)>, } /// Public parameters for the Groth16 proving system. @@ -259,7 +269,9 @@ pub struct PublicParams(pub groth16::Parameters) impl PublicParameters for PublicParams {} -impl<'a, C: Coprocessor> Prover<'a, Scalar, C> for Groth16Prover { +impl<'a, C: Coprocessor, M: MultiFrameTrait<'a, Scalar, C>> Prover<'a, Scalar, C, M> + for Groth16Prover<'a, Bls12, C, Scalar, M> +{ type PublicParams = PublicParams; fn new(reduction_count: usize, lang: Lang) -> Self { @@ -374,7 +386,7 @@ mod tests { let rng = OsRng; let lang_rc = Arc::new(lang.clone()); - let public_params = Groth16Prover::<_, C, Fr>::create_groth_params( + let public_params = Groth16Prover::<_, C, Fr, MultiFrame<'_, Fr, C>>::create_groth_params( DEFAULT_REDUCTION_COUNT, lang_rc.clone(), ) @@ -416,10 +428,11 @@ mod tests { .unwrap()); } - let constraint_systems_verified = verify_sequential_css::(&cs).unwrap(); + let constraint_systems_verified = + verify_sequential_css::>(&cs).unwrap(); assert!(constraint_systems_verified); - check_cs_deltas(&cs, limit, lang_rc.clone()); + check_cs_deltas::(&cs, limit, lang_rc.clone()); } let proof_results = (check_groth16).then(|| { @@ -456,13 +469,13 @@ mod tests { } fn check_cs_deltas>( - constraint_systems: &SequentialCS<'_, Fr, C>, + constraint_systems: &SequentialCS>, limit: usize, lang: Arc>, ) { let mut cs_blank = MetricCS::::new(); let folding_config = Arc::new(FoldingConfig::new_ivc(lang, DEFAULT_REDUCTION_COUNT)); - let blank_frame = MultiFrame::::blank(folding_config, Meta::Lurk); + let blank_frame = MultiFrame::<'_, Scalar, C>::blank(folding_config, Meta::Lurk); blank_frame .synthesize(&mut cs_blank) .expect("failed to synthesize"); diff --git a/src/proof/mod.rs b/src/proof/mod.rs index e5710e4117..57d5fde8aa 100644 --- a/src/proof/mod.rs +++ b/src/proof/mod.rs @@ -13,19 +13,158 @@ pub mod nova; /// An adapter to a SuperNova proving system implementation. pub mod supernova; -use crate::circuit::MultiFrame; use crate::coprocessor::Coprocessor; use crate::error::ProofError; +use crate::eval::Meta; use crate::eval::{lang::Lang, Evaluator, Frame, Witness, IO}; use crate::field::LurkField; use crate::ptr::Ptr; use crate::store::Store; +use ::nova::traits::circuit::StepCircuit; +use bellpepper::util_cs::witness_cs::WitnessCS; +use bellpepper_core::ConstraintSystem; use bellpepper_core::{test_cs::TestConstraintSystem, Circuit, SynthesisError}; use std::sync::Arc; +use self::supernova::FoldingConfig; + +/// The State of a CEK machine. +pub trait CEKState { + /// the expression, or control word (C) + fn expr(&self) -> &ExprPtr; + /// the environment (E) + fn env(&self) -> &ExprPtr; + /// the continuation (K) + fn cont(&self) -> &ContPtr; +} + +/// A Frame of evaluation in a CEK machine. +pub trait FrameLike: Sized { + /// the type for the Frame's IO + type FrameIO: CEKState; + /// the input of the frame + fn input(&self) -> &Self::FrameIO; + /// the output of the frame + fn output(&self) -> &Self::FrameIO; +} + +/// A trait for a store of expressions +pub trait EvaluationStore { + /// the type for the Store's pointers + type Ptr; + /// the type for the Store's continuation poitners + type ContPtr; + /// the type for the Store's errors + type Error: std::fmt::Debug; + + /// interpreting a string representation of an expression + fn read(&self, expr: &str) -> Result; + /// getting a pointer to the initial, empty environment + fn initial_empty_env(&self) -> Self::Ptr; + /// getting the terminal continuation pointer + fn get_cont_terminal(&self) -> Self::ContPtr; + + /// hash-equality of the expressions represented by Ptrs + fn ptr_eq(&self, left: &Self::Ptr, right: &Self::Ptr) -> Result; +} + +/// Trait to support multiple `MultiFrame` implementations. +pub trait MultiFrameTrait<'a, F: LurkField, C: Coprocessor + 'a>: + Provable + Circuit + StepCircuit + 'a +{ + /// The associated `Ptr` type + type Ptr: std::fmt::Debug + Eq + Copy; + /// The associated `ContPtr` type + type ContPtr: std::fmt::Debug + Eq + Copy; + /// The associated `Store` type + type Store: Send + Sync + EvaluationStore; + /// The error type for the Store type + type StoreError: Into; + + /// The associated `Frame` type + type EvalFrame: FrameLike; + /// The associated `CircuitFrame` type + type CircuitFrame: FrameLike< + Self::Ptr, + Self::ContPtr, + FrameIO = >::FrameIO, + >; + /// The associated type which manages global allocations + type GlobalAllocation; + /// The associated type of allocated input and output to the circuit + type AllocatedIO; + + /// the emitted frames + fn emitted(store: &Self::Store, eval_frame: &Self::EvalFrame) -> Vec; + + /// Counting the number of non-trivial frames in the evaluation + fn significant_frame_count(frames: &[Self::EvalFrame]) -> usize; + + /// Evaluates and generates the frames of the computation given the expression, environment, and store + fn get_evaluation_frames( + padding_predicate: impl Fn(usize) -> bool, // Determines if the prover needs padding for a given total number of frames + expr: Self::Ptr, + env: Self::Ptr, + store: &Self::Store, + limit: usize, + land: &Lang, + ) -> Result, ProofError>; + + /// Returns a public IO vector when equipped with the local store, and the Self::Frame's IO + fn io_to_scalar_vector( + store: &Self::Store, + io: &>::FrameIO, + ) -> Result, Self::StoreError>; + + /// Returns true if the supplied instance directly precedes this one in a sequential computation trace. + fn precedes(&self, maybe_next: &Self) -> bool; + + /// Populates a WitnessCS with the witness values for the given store. + fn compute_witness(&self, s: &Self::Store) -> WitnessCS; + + /// Returns a reference to the cached witness values + fn cached_witness(&mut self) -> &mut Option>; + + /// The output of the last frame + fn output(&self) -> &Option<>::FrameIO>; + + /// Iterates through the Self::CircuitFrame instances + fn frames(&self) -> Option<&Vec>; + + /// Synthesize some frames. + fn synthesize_frames>( + &self, + cs: &mut CS, + store: &Self::Store, + input: Self::AllocatedIO, + frames: &[Self::CircuitFrame], + g: &Self::GlobalAllocation, + ) -> Self::AllocatedIO; + + /// Synthesize a blank circuit. + fn blank(folding_config: Arc>, meta: Meta) -> Self; + + /// Create an instance from some `Self::Frame`s. + fn from_frames( + count: usize, + frames: &[Self::EvalFrame], + store: &'a Self::Store, + folding_config: Arc>, + ) -> Vec; + + /// Make a dummy instance, duplicating `self`'s final `CircuitFrame`. + fn make_dummy( + count: usize, + circuit_frame: Option, + store: &'a Self::Store, + folding_config: Arc>, + meta: Meta, + ) -> Self; +} + /// Represents a sequential Constraint System for a given proof. -pub(crate) type SequentialCS<'a, F, C> = Vec<(MultiFrame<'a, F, C>, TestConstraintSystem)>; +pub(crate) type SequentialCS = Vec<(M, TestConstraintSystem)>; /// A trait for provable structures over a field `F`. pub trait Provable { @@ -38,10 +177,15 @@ pub trait Provable { } /// Verifies a sequence of constraint systems (CSs) for sequentiality & validity. -pub fn verify_sequential_css>( - css: &SequentialCS<'_, F, C>, +pub fn verify_sequential_css< + 'a, + F: LurkField + Copy, + C: Coprocessor + 'a, + M: MultiFrameTrait<'a, F, C>, +>( + css: &SequentialCS, ) -> Result { - let mut previous_frame: Option<&MultiFrame<'_, F, C>> = None; + let mut previous_frame: Option<&M> = None; for (i, (multiframe, cs)) in css.iter().enumerate() { if let Some(prev) = previous_frame { @@ -68,7 +212,7 @@ pub fn verify_sequential_css>( pub trait PublicParameters {} /// A trait for a prover that works with a field `F`. -pub trait Prover<'a, F: LurkField, C: Coprocessor> { +pub trait Prover<'a, F: LurkField, C: Coprocessor + 'a, M: MultiFrameTrait<'a, F, C>> { /// The associated public parameters type for the prover. type PublicParams: PublicParameters; @@ -112,10 +256,7 @@ pub trait Prover<'a, F: LurkField, C: Coprocessor> { } /// Synthesizes the outer circuit for the prover given a slice of multiframes. - fn outer_synthesize( - &self, - multiframes: &'a [MultiFrame<'_, F, C>], - ) -> Result, SynthesisError> { + fn outer_synthesize(&self, multiframes: &[M]) -> Result, SynthesisError> { // Note: This loop terminates and returns an error on the first occurrence of `SynthesisError`. multiframes .iter() @@ -134,7 +275,7 @@ pub trait Prover<'a, F: LurkField, C: Coprocessor> { &self, expr: Ptr, env: Ptr, - store: &mut Store, + store: &Store, limit: usize, lang: Arc>, ) -> Result, Witness, F, C>>, ProofError> { @@ -149,4 +290,7 @@ pub trait Prover<'a, F: LurkField, C: Coprocessor> { } /// Supertrait for `Prover` that also supports NIVC. -pub trait NIVCProver<'a, F: LurkField, C: Coprocessor>: Prover<'a, F, C> {} +pub trait NIVCProver<'a, F: LurkField, C: Coprocessor + 'a, M: MultiFrameTrait<'a, F, C>>: + Prover<'a, F, C, M> +{ +} diff --git a/src/proof/nova.rs b/src/proof/nova.rs index 00f0f982b5..855432c7ce 100644 --- a/src/proof/nova.rs +++ b/src/proof/nova.rs @@ -1,5 +1,5 @@ #![allow(non_snake_case)] -use std::sync::Mutex; +use std::{marker::PhantomData, sync::Mutex}; use abomonation::Abomonation; use bellpepper::util_cs::witness_cs::WitnessCS; @@ -33,12 +33,13 @@ use crate::config::CONFIG; use crate::coprocessor::Coprocessor; use crate::error::ProofError; -use crate::eval::{lang::Lang, Frame, Meta, Witness, IO}; +use crate::eval::{lang::Lang, Meta}; use crate::field::LurkField; -use crate::proof::{supernova::FoldingConfig, Prover, PublicParameters}; -use crate::ptr::Ptr; +use crate::proof::{supernova::FoldingConfig, MultiFrameTrait, Prover, PublicParameters}; use crate::store::Store; +use super::FrameLike; + /// This trait defines most of the requirements for programming generically over the supported Nova curve cycles /// (currently Pallas/Vesta and BN254/Grumpkin). It being pegged on the `LurkField` trait encodes that we do /// not expect more than one such cycle to be supported at a time for a given field. @@ -123,24 +124,24 @@ pub type C1<'a, F, C> = MultiFrame<'a, F, C>; pub type C2 = TrivialTestCircuit< as Group>::Scalar>; /// Type alias for Nova Public Parameters with the curve cycle types defined above. -pub type NovaPublicParams<'a, F, C> = nova::PublicParams, G2, C1<'a, F, C>, C2>; +pub type NovaPublicParams = nova::PublicParams, G2, C1, C2>; /// A struct that contains public parameters for the Nova proving system. #[derive(Clone, Serialize, Deserialize)] #[serde(bound = "")] -pub struct PublicParams<'a, F, C: Coprocessor> +pub struct PublicParams> where F: CurveCycleEquipped, // technical bounds that would disappear once associated_type_bounds stabilizes < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { - pp: NovaPublicParams<'a, F, C>, - pk: ProverKey, G2, C1<'a, F, C>, C2, SS1, SS2>, - vk: VerifierKey, G2, C1<'a, F, C>, C2, SS1, SS2>, + pp: NovaPublicParams, + pk: ProverKey, G2, SC, C2, SS1, SS2>, + vk: VerifierKey, G2, SC, C2, SS1, SS2>, } -impl<'c, F: CurveCycleEquipped, C: Coprocessor> Abomonation for PublicParams<'c, F, C> +impl> Abomonation for PublicParams where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, @@ -169,27 +170,39 @@ where /// An enum representing the two types of proofs that can be generated and verified. #[derive(Serialize, Deserialize)] -pub enum Proof<'a, F: CurveCycleEquipped, C: Coprocessor> +#[serde(bound = "")] +pub enum Proof<'a, F: CurveCycleEquipped, C: Coprocessor, M: MultiFrameTrait<'a, F, C>> where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { /// A proof for the intermediate steps of a recursive computation - Recursive(Box, G2, C1<'a, F, C>, C2>>), + Recursive( + Box, G2, M, C2>>, + PhantomData<&'a C>, + ), /// A proof for the final step of a recursive computation - Compressed(Box, G2, C1<'a, F, C>, C2, SS1, SS2>>), + Compressed( + Box, G2, M, C2, SS1, SS2>>, + PhantomData<&'a C>, + ), } /// Generates the public parameters for the Nova proving system. -pub fn public_params<'a, F: CurveCycleEquipped, C: Coprocessor>( +pub fn public_params< + 'a, + F: CurveCycleEquipped, + C: Coprocessor + 'a, + M: StepCircuit + MultiFrameTrait<'a, F, C>, +>( num_iters_per_step: usize, lang: Arc>, -) -> PublicParams<'a, F, C> +) -> PublicParams where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { - let (circuit_primary, circuit_secondary) = C1::circuits(num_iters_per_step, lang); + let (circuit_primary, circuit_secondary) = circuits(num_iters_per_step, lang); let commitment_size_hint1 = as RelaxedR1CSSNARKTrait>>::commitment_key_floor(); let commitment_size_hint2 = as RelaxedR1CSSNARKTrait>>::commitment_key_floor(); @@ -204,41 +217,51 @@ where PublicParams { pp, pk, vk } } -impl<'a, F: CurveCycleEquipped, C: Coprocessor> C1<'a, F, C> { - fn circuits(count: usize, lang: Arc>) -> (C1<'a, F, C>, C2) { - let folding_config = Arc::new(FoldingConfig::new_ivc(lang, count)); - ( - MultiFrame::blank(folding_config, Meta::Lurk), - TrivialTestCircuit::default(), - ) - } +/// Generates the circuits for the Nova proving system. +pub fn circuits<'a, F: CurveCycleEquipped, C: Coprocessor + 'a, M: MultiFrameTrait<'a, F, C>>( + count: usize, + lang: Arc>, +) -> (M, C2) { + let folding_config = Arc::new(FoldingConfig::new_ivc(lang, count)); + ( + M::blank(folding_config, Meta::Lurk), + TrivialTestCircuit::default(), + ) } /// A struct for the Nova prover that operates on field elements of type `F`. #[derive(Debug)] -pub struct NovaProver> { +pub struct NovaProver< + 'a, + F: CurveCycleEquipped, + C: Coprocessor + 'a, + M: MultiFrameTrait<'a, F, C>, +> { // `reduction_count` specifies the number of small-step reductions are performed in each recursive step. reduction_count: usize, lang: Lang, + _phantom: PhantomData<&'a M>, } -impl<'a, F: CurveCycleEquipped, C: Coprocessor> PublicParameters for PublicParams<'a, F, C> +impl> PublicParameters for PublicParams where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { } -impl<'a, F: CurveCycleEquipped, C: Coprocessor + 'a> Prover<'a, F, C> for NovaProver +impl<'a, F: CurveCycleEquipped, C: Coprocessor, M: MultiFrameTrait<'a, F, C>> Prover<'a, F, C, M> + for NovaProver<'a, F, C, M> where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { - type PublicParams = PublicParams<'a, F, C>; + type PublicParams = PublicParams; fn new(reduction_count: usize, lang: Lang) -> Self { - NovaProver:: { + NovaProver:: { reduction_count, lang, + _phantom: PhantomData, } } fn reduction_count(&self) -> usize { @@ -250,47 +273,63 @@ where } } -impl> NovaProver +impl<'a, F: CurveCycleEquipped, C: Coprocessor, M: MultiFrameTrait<'a, F, C>> + NovaProver<'a, F, C, M> where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { /// Proves the computation given the public parameters, frames, and store. - pub fn prove<'a>( - &'a self, - pp: &'a PublicParams<'_, F, C>, - frames: &[Frame, Witness, F, C>], - store: &'a Store, - lang: Arc>, - ) -> Result<(Proof<'a, F, C>, Vec, Vec, usize), ProofError> { - let z0 = frames[0].input.to_vector(store)?; - let zi = frames.last().unwrap().output.to_vector(store)?; + pub fn prove( + &self, + pp: &PublicParams, + frames: &[M::EvalFrame], + store: &'a M::Store, + lang: &Arc>, + ) -> Result<(Proof<'a, F, C, M>, Vec, Vec, usize), ProofError> { + let z0 = M::io_to_scalar_vector(store, frames[0].input()).map_err(|e| e.into())?; + let zi = + M::io_to_scalar_vector(store, frames.last().unwrap().output()).map_err(|e| e.into())?; let folding_config = Arc::new(FoldingConfig::new_ivc(lang.clone(), self.reduction_count())); - let circuits = MultiFrame::from_frames(self.reduction_count, frames, store, folding_config); + let circuits = M::from_frames(self.reduction_count(), frames, store, folding_config); let num_steps = circuits.len(); - let proof = - Proof::prove_recursively(pp, store, &circuits, self.reduction_count, z0.clone(), lang)?; + let proof = Proof::prove_recursively( + pp, + store, + &circuits, + self.reduction_count, + z0.clone(), + lang.clone(), + )?; Ok((proof, z0, zi, num_steps)) } /// Evaluates and proves the computation given the public parameters, expression, environment, and store. - pub fn evaluate_and_prove<'a>( - &'a self, - pp: &'a PublicParams<'_, F, C>, - expr: Ptr, - env: Ptr, - store: &'a mut Store, + pub fn evaluate_and_prove( + &self, + pp: &PublicParams, + expr: M::Ptr, + env: M::Ptr, + store: &'a mut M::Store, limit: usize, - lang: Arc>, - ) -> Result<(Proof<'_, F, C>, Vec, Vec, usize), ProofError> { - let frames = self.get_evaluation_frames(expr, env, store, limit, lang.clone())?; + lang: &Arc>, + ) -> Result<(Proof<'a, F, C, M>, Vec, Vec, usize), ProofError> { + let frames = M::get_evaluation_frames( + |count| self.needs_frame_padding(count), + expr, + env, + store, + limit, + lang, + )?; self.prove(pp, &frames, store, lang) } } impl<'a, F: LurkField, C: Coprocessor> MultiFrame<'a, F, C> { + #[allow(dead_code)] // TODO(huitseeker): is this used? fn compute_witness(&self, s: &Store) -> WitnessCS { let mut wcs = WitnessCS::new(); @@ -441,7 +480,7 @@ impl<'a, F: LurkField, C: Coprocessor> StepCircuit for MultiFrame<'a, F, C } } -impl<'a: 'b, 'b, F: CurveCycleEquipped, C: Coprocessor> Proof<'a, F, C> +impl<'a, F: CurveCycleEquipped, C: Coprocessor, M: MultiFrameTrait<'a, F, C>> Proof<'a, F, C, M> where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, @@ -449,9 +488,9 @@ where /// Proves the computation recursively, generating a recursive SNARK proof. #[tracing::instrument(skip_all, name = "Proof::prove_recursively")] pub fn prove_recursively( - pp: &'a PublicParams<'_, F, C>, - store: &'a Store, - circuits: &[C1<'a, F, C>], + pp: &PublicParams, + store: &M::Store, + circuits: &[M], num_iters_per_step: usize, z0: Vec, lang: Arc>, @@ -462,19 +501,16 @@ where let z0_primary = z0; let z0_secondary = Self::z0_secondary(); - assert_eq!( - circuits[0].frames.as_ref().unwrap().len(), - num_iters_per_step - ); + assert_eq!(circuits[0].frames().unwrap().len(), num_iters_per_step); let (_circuit_primary, circuit_secondary): ( MultiFrame<'_, F, C>, TrivialTestCircuit< as Group>::Scalar>, - ) = C1::<'a>::circuits(num_iters_per_step, lang); + ) = crate::proof::nova::circuits(num_iters_per_step, lang); tracing::debug!("circuits.len: {}", circuits.len()); // produce a recursive SNARK - let mut recursive_snark: Option, G2, C1<'a, F, C>, C2>> = None; + let mut recursive_snark: Option, G2, M, C2>> = None; // the shadowing here is voluntary let recursive_snark = if CONFIG.parallelism.recursive_steps.is_parallel() { @@ -494,7 +530,7 @@ where }; let mut mf2 = mf.lock().unwrap(); - mf2.cached_witness = Some(witness); + *mf2.cached_witness() = Some(witness); }); }); @@ -502,7 +538,7 @@ where let circuit_primary = circuit_primary.lock().unwrap(); assert_eq!( num_iters_per_step, - circuit_primary.frames.as_ref().unwrap().len() + circuit_primary.frames().unwrap().iter().len() ); let mut r_snark = recursive_snark.unwrap_or_else(|| { @@ -530,19 +566,16 @@ where .unwrap() } else { for circuit_primary in circuits.iter() { - assert_eq!( - num_iters_per_step, - circuit_primary.frames.as_ref().unwrap().len() - ); + assert_eq!(num_iters_per_step, circuit_primary.frames().unwrap().len()); if debug { // For debugging purposes, synthesize the circuit and check that the constraint system is satisfied. use bellpepper_core::test_cs::TestConstraintSystem; let mut cs = TestConstraintSystem::< as Group>::Scalar>::new(); - let zi = circuit_primary.frames.as_ref().unwrap()[0] - .input - .unwrap() - .to_vector(store)?; + // This is a CircuitFrame, not an EvalFrame + let first_frame = circuit_primary.frames().unwrap().iter().next().unwrap(); + let zi = + M::io_to_scalar_vector(store, first_frame.input()).map_err(|e| e.into())?; let zi_allocated: Vec<_> = zi .iter() .enumerate() @@ -579,32 +612,31 @@ where recursive_snark }; - Ok(Self::Recursive(Box::new(recursive_snark.unwrap()))) + Ok(Self::Recursive( + Box::new(recursive_snark.unwrap()), + PhantomData, + )) } /// Compresses the proof using a (Spartan) Snark (finishing step) - pub fn compress(self, pp: &'a PublicParams<'_, F, C>) -> Result { + pub fn compress(self, pp: &PublicParams) -> Result { match &self { - Self::Recursive(recursive_snark) => Ok(Self::Compressed(Box::new(CompressedSNARK::< - _, - _, - _, - _, - SS1, - SS2, - >::prove( - &pp.pp, - &pp.pk, - recursive_snark, - )?))), - Self::Compressed(_) => Ok(self), + Self::Recursive(recursive_snark, _) => Ok(Self::Compressed( + Box::new(CompressedSNARK::<_, _, _, _, SS1, SS2>::prove( + &pp.pp, + &pp.pk, + recursive_snark, + )?), + PhantomData, + )), + Self::Compressed(_, _) => Ok(self), } } /// Verifies the proof given the public parameters, the number of steps, and the input and output values. pub fn verify( &self, - pp: &PublicParams<'_, F, C>, + pp: &PublicParams, num_steps: usize, z0: &[F], zi: &[F], @@ -614,8 +646,10 @@ where let zi_secondary = z0_secondary.clone(); let (zi_primary_verified, zi_secondary_verified) = match self { - Self::Recursive(p) => p.verify(&pp.pp, num_steps, z0_primary, &z0_secondary), - Self::Compressed(p) => p.verify(&pp.vk, num_steps, z0_primary.to_vec(), z0_secondary), + Self::Recursive(p, _) => p.verify(&pp.pp, num_steps, z0_primary, &z0_secondary), + Self::Compressed(p, _) => { + p.verify(&pp.vk, num_steps, z0_primary.to_vec(), z0_secondary) + } }?; Ok(zi_primary == zi_primary_verified && zi_secondary == zi_secondary_verified) @@ -637,16 +671,15 @@ pub mod tests { use crate::state::{user_sym, State}; use super::*; - use crate::eval::empty_sym_env; + use crate::eval::lang::Coproc; - use crate::proof::Provable; - use crate::ptr::ContPtr; + use crate::proof::{CEKState, EvaluationStore}; use crate::tag::{Op, Op1, Op2}; use bellpepper::util_cs::witness_cs::WitnessCS; use bellpepper::util_cs::{metric_cs::MetricCS, Comparable}; use bellpepper_core::test_cs::TestConstraintSystem; - use bellpepper_core::{Circuit, Delta}; + use bellpepper_core::Delta; use pallas::Scalar as Fr; const DEFAULT_REDUCTION_COUNT: usize = 5; @@ -667,24 +700,29 @@ pub mod tests { } } - pub fn test_aux>( - s: &mut Store, + pub fn test_aux<'a, F: CurveCycleEquipped, C: Coprocessor, M: MultiFrameTrait<'a, F, C>>( + s: &'a M::Store, expr: &str, - expected_result: Option>, - expected_env: Option>, - expected_cont: Option>, - expected_emitted: Option>>, + expected_result: Option, + expected_env: Option, + expected_cont: Option, + expected_emitted: Option<&[M::Ptr]>, expected_iterations: usize, - lang: Option>>, - ) { + lang: Option>>, + ) + // technical bounds that would disappear once associated_type_bounds stabilizes + where + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + { for chunk_size in REDUCTION_COUNTS_TO_TEST { - nova_test_full_aux( + nova_test_full_aux::( s, expr, expected_result, expected_env, expected_cont, - expected_emitted.as_ref(), + expected_emitted, expected_iterations, chunk_size, false, @@ -694,23 +732,33 @@ pub mod tests { } } - fn nova_test_full_aux>( - s: &mut Store, + fn nova_test_full_aux< + 'a, + F: CurveCycleEquipped, + C: Coprocessor, + M: MultiFrameTrait<'a, F, C>, + >( + s: &'a M::Store, expr: &str, - expected_result: Option>, - expected_env: Option>, - expected_cont: Option>, - expected_emitted: Option<&Vec>>, + expected_result: Option, + expected_env: Option, + expected_cont: Option, + expected_emitted: Option<&[M::Ptr]>, expected_iterations: usize, reduction_count: usize, check_nova: bool, limit: Option, - lang: Option>>, - ) { + lang: Option>>, + ) + // technical bounds that would disappear once associated_type_bounds stabilizes + where + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + { let expr = s.read(expr).unwrap(); - let mut f = |l| { - nova_test_full_aux2( + let f = |l| { + nova_test_full_aux2::( s, expr, expected_result, @@ -733,30 +781,47 @@ pub mod tests { }; } - fn nova_test_full_aux2>( - s: &mut Store, - expr: Ptr, - expected_result: Option>, - expected_env: Option>, - expected_cont: Option>, - expected_emitted: Option<&Vec>>, + fn nova_test_full_aux2< + 'a, + F: CurveCycleEquipped, + C: Coprocessor, + M: MultiFrameTrait<'a, F, C>, + >( + s: &'a M::Store, + expr: M::Ptr, + expected_result: Option, + expected_env: Option, + expected_cont: Option, + expected_emitted: Option<&[M::Ptr]>, expected_iterations: usize, reduction_count: usize, check_nova: bool, limit: Option, - lang: Arc>, - ) { + lang: Arc>, + ) + // technical bounds that would disappear once associated_type_bounds stabilizes + where + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, + { let limit = limit.unwrap_or(10000); - let e = empty_sym_env(s); + let e = s.initial_empty_env(); - let nova_prover = NovaProver::::new(reduction_count, (*lang).clone()); + let nova_prover = NovaProver::<'a, F, C, M>::new(reduction_count, (*lang).clone()); + let frames = M::get_evaluation_frames( + |frame_count| nova_prover.needs_frame_padding(frame_count), + expr, + e, + s, + limit, + &lang, + ) + .unwrap(); if check_nova { - let pp = public_params(reduction_count, lang.clone()); - let (proof, z0, zi, num_steps) = nova_prover - .evaluate_and_prove(&pp, expr, empty_sym_env(s), s, limit, lang.clone()) - .unwrap(); + let pp = public_params::<_, _, M>(reduction_count, lang.clone()); + let (proof, z0, zi, num_steps) = nova_prover.prove(&pp, &frames, s, &lang).unwrap(); let res = proof.verify(&pp, num_steps, &z0, &zi); if res.is_err() { @@ -770,12 +835,9 @@ pub mod tests { assert!(res2.unwrap()); } - let frames = nova_prover - .get_evaluation_frames(expr, e, s, limit, lang.clone()) - .unwrap(); let folding_config = Arc::new(FoldingConfig::new_ivc(lang, nova_prover.reduction_count())); - let multiframes = MultiFrame::from_frames( + let multiframes = M::from_frames( nova_prover.reduction_count(), &frames, s, @@ -784,11 +846,11 @@ pub mod tests { let len = multiframes.len(); let adjusted_iterations = nova_prover.expected_total_iterations(expected_iterations); - let mut previous_frame: Option> = None; + let mut previous_frame: Option<&M> = None; - let mut cs_blank = MetricCS::::new(); + let mut cs_blank = MetricCS::::new(); - let blank = MultiFrame::::blank(folding_config, Meta::Lurk); + let blank = M::blank(folding_config, Meta::Lurk); blank .synthesize(&mut cs_blank) .expect("failed to synthesize blank"); @@ -824,35 +886,35 @@ pub mod tests { assert_eq!(None, mismatch(&cs_inputs, &wcs_inputs)); assert_eq!(None, mismatch(&cs_aux, &wcs_aux)); - previous_frame = Some(multiframe.clone()); + previous_frame = Some(multiframe); let delta = cs.delta(&cs_blank, true); assert!(delta == Delta::Equal); } - let output = previous_frame.unwrap().output.unwrap(); + let output = previous_frame.unwrap().output().as_ref().unwrap(); if let Some(expected_emitted) = expected_emitted { - let emitted_vec: Vec<_> = frames - .iter() - .filter_map(|frame| frame.output.maybe_emitted_expression(s)) - .collect(); + let mut emitted_vec = Vec::default(); + for frame in frames.iter() { + emitted_vec.extend(M::emitted(s, frame)); + } assert_eq!(expected_emitted, &emitted_vec); } if let Some(expected_result) = expected_result { - assert!(s.ptr_eq(&expected_result, &output.expr).unwrap()); + assert!(s.ptr_eq(&expected_result, output.expr()).unwrap()); } if let Some(expected_env) = expected_env { - assert!(s.ptr_eq(&expected_env, &output.env).unwrap()); + assert!(s.ptr_eq(&expected_env, output.env()).unwrap()); } if let Some(expected_cont) = expected_cont { - assert_eq!(expected_cont, output.cont); + assert_eq!(&expected_cont, output.cont()); } else { - assert_eq!(s.get_cont_terminal(), output.cont); + assert_eq!(&s.get_cont_terminal(), output.cont()); } - assert_eq!(expected_iterations, Frame::significant_frame_count(&frames)); + assert_eq!(expected_iterations, M::significant_frame_count(&frames)); assert_eq!(adjusted_iterations, len); } @@ -861,12 +923,14 @@ pub mod tests { // more than 30 we ignore it. //////////////////////////////////////////////////////////////////////////// + type M1<'a, Fr> = C1<'a, Fr, Coproc>; + #[test] fn test_prove_binop() { let s = &mut Store::::default(); let expected = s.num(3); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(+ 1 2)", Some(expected), @@ -886,7 +950,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(2); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(+ 1 2)", Some(expected), @@ -904,7 +968,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(3); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((a 5) (b 1) @@ -925,7 +989,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - nova_test_full_aux::>( + nova_test_full_aux::<_, _, M1<'_, _>>( s, "(eq 5 5)", Some(expected), @@ -946,7 +1010,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(= 5 5)", Some(expected), @@ -959,7 +1023,7 @@ pub mod tests { let expected = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(= 5 6)", Some(expected), @@ -976,7 +1040,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, nil); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(= 5 nil)", Some(expected), @@ -988,7 +1052,7 @@ pub mod tests { ); let expected = s.num(5); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(= nil 5)", Some(expected), @@ -1007,7 +1071,7 @@ pub mod tests { let t = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(eq 5 nil)", Some(nil), @@ -1017,7 +1081,7 @@ pub mod tests { 3, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(eq nil 5)", Some(nil), @@ -1027,7 +1091,7 @@ pub mod tests { 3, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(eq nil nil)", Some(t), @@ -1037,14 +1101,14 @@ pub mod tests { 3, None, ); - test_aux::>(s, "(eq 5 5)", Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, "(eq 5 5)", Some(t), None, Some(terminal), None, 3, None); } #[test] fn test_prove_quote_end_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(quote (1) (2))", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(quote (1) (2))", None, None, Some(error), None, 1, None); } #[test] @@ -1052,7 +1116,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(5); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(if t 5 6)", Some(expected), @@ -1065,7 +1129,7 @@ pub mod tests { let expected = s.num(6); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(if nil 5 6)", Some(expected), @@ -1082,7 +1146,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(5); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(if nil 5 6 7)", Some(expected), @@ -1100,7 +1164,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(10); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(if t (+ 5 5) 6)", Some(expected), @@ -1118,7 +1182,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(25); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((exp (lambda (base) (lambda (exponent) @@ -1141,7 +1205,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(25); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((exp (lambda (base) (lambda (exponent) @@ -1163,7 +1227,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - nova_test_full_aux::>( + nova_test_full_aux::<_, _, M1<'_, _>>( s, "(atom 123)", Some(expected), @@ -1178,7 +1242,7 @@ pub mod tests { ); let expected = s.num(1); - nova_test_full_aux::>( + nova_test_full_aux::<_, _, M1<'_, _>>( s, "(car '(1 . 2))", Some(expected), @@ -1193,7 +1257,7 @@ pub mod tests { ); let expected = s.num(2); - nova_test_full_aux::>( + nova_test_full_aux::<_, _, M1<'_, _>>( s, "(cdr '(1 . 2))", Some(expected), @@ -1208,7 +1272,7 @@ pub mod tests { ); let expected = s.num(123); - nova_test_full_aux::>( + nova_test_full_aux::<_, _, M1<'_, _>>( s, "(emit 123)", Some(expected), @@ -1239,7 +1303,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(emit 123)", Some(expected), @@ -1257,7 +1321,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(99); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (x) x) 99)", Some(expected), @@ -1275,7 +1339,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(99); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (y) ((lambda (x) y) 888)) @@ -1295,7 +1359,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(999); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (y) ((lambda (x) @@ -1318,7 +1382,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(888); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (y) ((lambda (x) @@ -1342,7 +1406,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(999); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(((lambda (fn) (lambda (x) (fn x))) @@ -1363,7 +1427,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(9); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(+ 2 (+ 3 4))", Some(expected), @@ -1380,7 +1444,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(9); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(- 9 8 7)", Some(expected), @@ -1390,7 +1454,7 @@ pub mod tests { 2, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(= 9 8 7)", Some(expected), @@ -1405,30 +1469,39 @@ pub mod tests { fn op_syntax_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - let mut test = |op: T| { + let test = |op: T| { let name = op.symbol_name(); if !op.supports_arity(0) { let expr = format!("({name})"); tracing::debug!("{:?}", &expr); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } if !op.supports_arity(1) { let expr = format!("({name} 123)"); tracing::debug!("{:?}", &expr); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } if !op.supports_arity(2) { let expr = format!("({name} 123 456)"); tracing::debug!("{:?}", &expr); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } if !op.supports_arity(3) { let expr = format!("({name} 123 456 789)"); tracing::debug!("{:?}", &expr); let iterations = if op.supports_arity(2) { 2 } else { 1 }; - test_aux::>(s, &expr, None, None, Some(error), None, iterations, None); + test_aux::<_, _, M1<'_, _>>( + s, + &expr, + None, + None, + Some(error), + None, + iterations, + None, + ); } }; @@ -1454,7 +1527,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(4); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(- 9 5)", Some(expected), @@ -1472,7 +1545,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(45); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(* 9 5)", Some(expected), @@ -1490,7 +1563,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(7); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(/ 21 3)", Some(expected), @@ -1507,7 +1580,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(0); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(/ 21 0)", Some(expected), @@ -1524,7 +1597,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, nil); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(/ 21 nil)", Some(expected), @@ -1542,7 +1615,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(5); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(((lambda (x) (lambda (y) @@ -1563,7 +1636,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(current-env)", Some(expected), @@ -1580,7 +1653,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.read("(current-env a)").unwrap(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(current-env a)", Some(expected), @@ -1598,7 +1671,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(1); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((a 1)) a)", @@ -1615,7 +1688,7 @@ pub mod tests { fn test_prove_let_end_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((a 1 2)) a)", None, @@ -1631,7 +1704,7 @@ pub mod tests { fn test_prove_letrec_end_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((a 1 2)) a)", None, @@ -1647,7 +1720,7 @@ pub mod tests { fn test_prove_lambda_empty_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (x)) 0)", None, @@ -1663,28 +1736,28 @@ pub mod tests { fn test_prove_let_empty_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(let)", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(let)", None, None, Some(error), None, 1, None); } #[test] fn test_prove_let_empty_body_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(let ((a 1)))", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(let ((a 1)))", None, None, Some(error), None, 1, None); } #[test] fn test_prove_letrec_empty_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(letrec)", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(letrec)", None, None, Some(error), None, 1, None); } #[test] fn test_prove_letrec_empty_body_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((a 1)))", None, @@ -1701,7 +1774,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(eq nil (let () nil))", Some(expected), @@ -1717,7 +1790,7 @@ pub mod tests { fn test_prove_let_rest_body_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((a 1)) a 1)", None, @@ -1733,7 +1806,7 @@ pub mod tests { fn test_prove_letrec_rest_body_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((a 1)) a 1)", None, @@ -1751,7 +1824,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(3); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let () (+ 1 2))", Some(expected), @@ -1768,7 +1841,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(3); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec () (+ 1 2))", Some(expected), @@ -1786,7 +1859,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(6); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((a 1) (b 2) @@ -1807,7 +1880,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(20); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((((lambda (x) (lambda (y) @@ -1832,7 +1905,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((x 2) (y 3) @@ -1854,7 +1927,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(5); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((true (lambda (a) (lambda (b) @@ -1883,7 +1956,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(6); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((true (lambda (a) (lambda (b) @@ -1912,7 +1985,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(5); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((true (lambda (a) (lambda (b) @@ -1938,7 +2011,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(10); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(if t (+ 5 5) 6)", Some(expected), @@ -1956,7 +2029,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(25); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((exp (lambda (base) (lambda (exponent) @@ -1979,7 +2052,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(25); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((exp (lambda (base exponent) (if (= 0 exponent) @@ -2001,7 +2074,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(25); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((exp (lambda (base) (letrec ((base-inner @@ -2026,7 +2099,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(25); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((exp (lambda (base) (lambda (exponent-remaining) @@ -2049,7 +2122,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(25); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((exp (lambda (base) (letrec ((base-inner @@ -2074,7 +2147,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((even (lambda (n) (if (= 0 n) @@ -2099,7 +2172,7 @@ pub mod tests { fn test_prove_no_mutual_recursion_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((even (lambda (n) (if (= 0 n) @@ -2125,7 +2198,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(1); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(car (cons 1 2))", Some(expected), @@ -2141,28 +2214,28 @@ pub mod tests { fn test_prove_car_end_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(car (1 2) 3)", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(car (1 2) 3)", None, None, Some(error), None, 1, None); } #[test] fn test_prove_cdr_end_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(cdr (1 2) 3)", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(cdr (1 2) 3)", None, None, Some(error), None, 1, None); } #[test] fn test_prove_atom_end_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(atom 123 4)", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(atom 123 4)", None, None, Some(error), None, 1, None); } #[test] fn test_prove_emit_end_is_nil_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "(emit 123 4)", None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(emit 123 4)", None, None, Some(error), None, 1, None); } #[test] @@ -2170,7 +2243,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(2); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(cdr (cons 1 2))", Some(expected), @@ -2187,7 +2260,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda () 123))", Some(expected), @@ -2204,7 +2277,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(10); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((x 9) (f (lambda () (+ x 1)))) (f))", Some(expected), @@ -2227,7 +2300,7 @@ pub mod tests { s.intern_fun(arg, body, env) }; let terminal = s.get_cont_terminal(); - nova_test_full_aux::>( + nova_test_full_aux::<_, _, M1<'_, _>>( s, "((lambda (x) 123))", Some(expected), @@ -2246,7 +2319,7 @@ pub mod tests { fn test_prove_zero_arg_lambda4() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda () 123) 1)", None, @@ -2263,7 +2336,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.read("(123)").unwrap(); let error = s.get_cont_error(); - test_aux::>(s, "(123)", Some(expected), None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, "(123)", Some(expected), None, Some(error), None, 1, None); } #[test] @@ -2271,7 +2344,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(123); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((emit 123))", Some(expected), @@ -2292,7 +2365,7 @@ pub mod tests { (x 6) (data (data-function))) x)"; - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, expr, Some(expected), @@ -2310,7 +2383,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((f (lambda (x) @@ -2333,7 +2406,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(2); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(((lambda (a) (lambda (b) @@ -2355,7 +2428,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(3); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(((lambda (a) (lambda (b) @@ -2377,7 +2450,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(2); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(car (cdr '(1 2 3 4)))", Some(expected), @@ -2395,7 +2468,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((x 888) @@ -2419,7 +2492,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((f (lambda (x) @@ -2443,7 +2516,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(13); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((double (lambda (x) (* 2 x))) (square (lambda (x) (* x x)))) @@ -2463,7 +2536,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(11); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((double (lambda (x) (* 2 x))) (double-inc (lambda (x) (+ 1 (double x))))) @@ -2483,7 +2556,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(33); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((exp (lambda (base exponent) (if (= 0 exponent) @@ -2514,7 +2587,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(18); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((z 9)) (letrec ((a 1) @@ -2536,7 +2609,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(1); let terminal = s.get_cont_terminal(); - nova_test_full_aux::>( + nova_test_full_aux::<_, _, M1<'_, _>>( s, "(letrec ((next (lambda (a b n target) (if (eq n target) @@ -2590,7 +2663,7 @@ pub mod tests { fn test_prove_terminal_continuation_regression() { let s = &mut Store::::default(); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((a (lambda (x) (cons 2 2)))) (a 1))", @@ -2608,7 +2681,7 @@ pub mod tests { fn test_prove_chained_functional_commitment() { let s = &mut Store::::default(); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((secret 12345) (a (lambda (acc x) @@ -2629,7 +2702,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(begin)", Some(expected), @@ -2647,13 +2720,13 @@ pub mod tests { let expr = "(begin (emit 1) (emit 2) (emit 3))"; let expected_expr = s.num(3); let expected_emitted = vec![s.num(1), s.num(2), s.num(3)]; - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, expr, Some(expected_expr), None, None, - Some(expected_emitted), + Some(&expected_emitted), 13, None, ); @@ -2664,7 +2737,7 @@ pub mod tests { let s = &mut Store::::default(); let expected_a = s.read(r"#\a").unwrap(); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(car "apple")"#, Some(expected_a), @@ -2681,7 +2754,7 @@ pub mod tests { let s = &mut Store::::default(); let expected_pple = s.read(r#" "pple" "#).unwrap(); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cdr "apple")"#, Some(expected_pple), @@ -2698,7 +2771,7 @@ pub mod tests { let s = &mut Store::::default(); let expected_nil = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(car "")"#, Some(expected_nil), @@ -2715,7 +2788,7 @@ pub mod tests { let s = &mut Store::::default(); let expected_empty_str = s.intern_string(""); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cdr "")"#, Some(expected_empty_str), @@ -2732,7 +2805,7 @@ pub mod tests { let s = &mut Store::::default(); let expected_apple = s.read(r#" "apple" "#).unwrap(); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(strcons #\a "pple")"#, Some(expected_apple), @@ -2748,7 +2821,7 @@ pub mod tests { fn test_prove_str_cons_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r"(strcons #\a 123)", None, @@ -2764,7 +2837,7 @@ pub mod tests { fn test_prove_one_arg_cons_error() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, r#"(cons "")"#, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, r#"(cons "")"#, None, None, Some(error), None, 1, None); } #[test] @@ -2772,7 +2845,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(car nil)"#, Some(expected), @@ -2789,7 +2862,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cdr nil)"#, Some(expected), @@ -2805,24 +2878,24 @@ pub mod tests { fn test_prove_car_cdr_invalid_tag_error_sym() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, r#"(car car)"#, None, None, Some(error), None, 2, None); - test_aux::>(s, r#"(cdr car)"#, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, r#"(car car)"#, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, r#"(cdr car)"#, None, None, Some(error), None, 2, None); } #[test] fn test_prove_car_cdr_invalid_tag_error_char() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, r"(car #\a)", None, None, Some(error), None, 2, None); - test_aux::>(s, r"(cdr #\a)", None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, r"(car #\a)", None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, r"(cdr #\a)", None, None, Some(error), None, 2, None); } #[test] fn test_prove_car_cdr_invalid_tag_error_num() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, r#"(car 42)"#, None, None, Some(error), None, 2, None); - test_aux::>(s, r#"(cdr 42)"#, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, r#"(car 42)"#, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, r#"(cdr 42)"#, None, None, Some(error), None, 2, None); } #[test] @@ -2831,7 +2904,7 @@ pub mod tests { let res1 = s.num(1); let res2 = s.num(2); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(car (cons 1 2))"#, Some(res1), @@ -2841,7 +2914,7 @@ pub mod tests { 5, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cdr (cons 1 2))"#, Some(res2), @@ -2857,7 +2930,7 @@ pub mod tests { fn test_prove_car_cdr_invalid_tag_error_lambda() { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(car (lambda (x) x))"#, None, @@ -2867,7 +2940,7 @@ pub mod tests { 2, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cdr (lambda (x) x))"#, None, @@ -2885,7 +2958,7 @@ pub mod tests { let expr = "(open (hide 123 456))"; let expected = s.num(456); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 5, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 5, None); } #[test] @@ -2893,7 +2966,7 @@ pub mod tests { let s = &mut Store::::default(); let expr = "(hide 'x 456)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 3, None); } #[test] @@ -2902,7 +2975,7 @@ pub mod tests { let expr = "(secret (hide 123 456))"; let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 5, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 5, None); } #[test] @@ -2911,7 +2984,7 @@ pub mod tests { let expr = "(open (hide 123 'x))"; let x = s.user_sym("x"); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(x), None, Some(terminal), None, 5, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(x), None, Some(terminal), None, 5, None); } #[test] @@ -2920,7 +2993,7 @@ pub mod tests { let expr = "(open (commit 'x))"; let x = s.user_sym("x"); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(x), None, Some(terminal), None, 4, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(x), None, Some(terminal), None, 4, None); } #[test] @@ -2929,7 +3002,7 @@ pub mod tests { let expr = "(open (commit 123))"; let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 4, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 4, None); } #[test] @@ -2937,7 +3010,7 @@ pub mod tests { let s = &mut Store::::default(); let expr = "(commit 123 456)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 1, None); } #[test] @@ -2945,7 +3018,7 @@ pub mod tests { let s = &mut Store::::default(); let expr = "(open 123 456)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 1, None); } #[test] @@ -2953,7 +3026,7 @@ pub mod tests { let s = &mut Store::::default(); let expr = "(open 'asdf)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 2, None); } #[test] @@ -2961,7 +3034,7 @@ pub mod tests { let s = &mut Store::::default(); let expr = "(secret 'asdf)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 2, None); } #[test] @@ -2970,7 +3043,7 @@ pub mod tests { let expr = "(secret (commit 123))"; let expected = s.num(0); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 4, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 4, None); } #[test] @@ -2979,7 +3052,7 @@ pub mod tests { let expr = "(num 123)"; let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 2, None); } #[test] @@ -2988,7 +3061,7 @@ pub mod tests { let expr = r"(num #\a)"; let expected = s.num(97); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 2, None); } #[test] @@ -2997,7 +3070,7 @@ pub mod tests { let expr = r#"(char 97)"#; let expected_a = s.read(r"#\a").unwrap(); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, expr, Some(expected_a), @@ -3017,7 +3090,7 @@ pub mod tests { let expected_a = s.read(r"#\a").unwrap(); let expected_b = s.read(r"#\b").unwrap(); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, expr, Some(expected_a), @@ -3027,7 +3100,7 @@ pub mod tests { 5, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, expr2, Some(expected_b), @@ -3044,7 +3117,7 @@ pub mod tests { let s = &mut Store::::default(); let expr = "(num (commit 123))"; let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, None, None, Some(terminal), None, 4, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(terminal), None, 4, None); } #[test] @@ -3053,7 +3126,7 @@ pub mod tests { let expr = "(open (comm (num (hide 123 456))))"; let expected = s.num(456); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 9, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 9, None); } #[test] @@ -3062,7 +3135,7 @@ pub mod tests { let expr = "(secret (comm (num (hide 123 456))))"; let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 9, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 9, None); } #[test] @@ -3071,7 +3144,7 @@ pub mod tests { let expr = "(open (comm (num (commit 123))))"; let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 8, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 8, None); } #[test] @@ -3080,7 +3153,7 @@ pub mod tests { let expr = "(secret (comm (num (commit 123))))"; let expected = s.num(0); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 8, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 8, None); } #[test] @@ -3089,7 +3162,7 @@ pub mod tests { let expr = "(open (num (commit 123)))"; let expected = s.num(123); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 6, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 6, None); } #[test] @@ -3099,9 +3172,9 @@ pub mod tests { let expr1 = "(num \"asdf\")"; let expr2 = "(num '(1))"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 2, None); - test_aux::>(s, expr1, None, None, Some(error), None, 2, None); - test_aux::>(s, expr2, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr1, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, None, None, Some(error), None, 2, None); } #[test] @@ -3111,9 +3184,9 @@ pub mod tests { let expr1 = "(comm \"asdf\")"; let expr2 = "(comm '(1))"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 2, None); - test_aux::>(s, expr1, None, None, Some(error), None, 2, None); - test_aux::>(s, expr2, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr1, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, None, None, Some(error), None, 2, None); } #[test] @@ -3123,9 +3196,9 @@ pub mod tests { let expr1 = "(char \"asdf\")"; let expr2 = "(char '(1))"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 2, None); - test_aux::>(s, expr1, None, None, Some(error), None, 2, None); - test_aux::>(s, expr2, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr1, None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, None, None, Some(error), None, 2, None); } #[test] @@ -3134,7 +3207,7 @@ pub mod tests { let expr = "(quote x)"; let x = s.user_sym("x"); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(x), None, Some(terminal), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(x), None, Some(terminal), None, 1, None); } #[test] @@ -3142,7 +3215,7 @@ pub mod tests { fn test_prove_open_opaque_commit() { let s = &mut Store::::default(); let expr = "(open 123)"; - test_aux::>(s, expr, None, None, None, None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, None, None, 2, None); } #[test] @@ -3150,7 +3223,7 @@ pub mod tests { fn test_prove_secret_invalid_tag() { let s = &mut Store::::default(); let expr = "(secret 123)"; - test_aux::>(s, expr, None, None, None, None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, None, None, 2, None); } #[test] @@ -3158,7 +3231,7 @@ pub mod tests { fn test_prove_secret_opaque_commit() { let s = &mut Store::::default(); let expr = "(secret (comm 123))"; - test_aux::>(s, expr, None, None, None, None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, None, None, 2, None); } #[test] @@ -3173,7 +3246,7 @@ pub mod tests { let terminal = s.get_cont_terminal(); let error = s.get_cont_error(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(car "apple")"#, Some(a), @@ -3183,7 +3256,7 @@ pub mod tests { 2, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cdr "apple")"#, Some(pple), @@ -3193,7 +3266,7 @@ pub mod tests { 2, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(car "")"#, Some(nil), @@ -3203,7 +3276,7 @@ pub mod tests { 2, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cdr "")"#, Some(empty), @@ -3213,7 +3286,7 @@ pub mod tests { 2, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(cons #\a "pple")"#, Some(a_pple), @@ -3224,7 +3297,7 @@ pub mod tests { None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(strcons #\a "pple")"#, Some(apple), @@ -3235,7 +3308,7 @@ pub mod tests { None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r"(strcons #\a #\b)", None, @@ -3246,7 +3319,7 @@ pub mod tests { None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(strcons "a" "b")"#, None, @@ -3257,7 +3330,7 @@ pub mod tests { None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, r#"(strcons 1 2)"#, None, @@ -3278,7 +3351,7 @@ pub mod tests { }; let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(expected), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(expected), None, Some(terminal), None, 3, None); } #[ignore] @@ -3406,7 +3479,7 @@ pub mod tests { let t = lurk_sym_ptr!(s, t); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(t), None, Some(terminal), None, 19, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(t), None, Some(terminal), None, 19, None); } #[test] @@ -3418,8 +3491,8 @@ pub mod tests { let res2 = s.num(20); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 17, None); - test_aux::>(s, expr2, Some(res2), None, Some(terminal), None, 9, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 17, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res2), None, Some(terminal), None, 9, None); } #[test] @@ -3435,9 +3508,9 @@ pub mod tests { let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 1, None); - test_aux::>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); - test_aux::>(s, expr3, Some(res3), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, Some(res3), None, Some(terminal), None, 3, None); } // The following functional commitment tests were discovered to fail. They are commented out (as tests) for now so @@ -3453,7 +3526,7 @@ pub mod tests { let res = s.num(10); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 25, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 25, None); } #[test] @@ -3474,7 +3547,7 @@ pub mod tests { let res = s.num(6); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 108, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 108, None); } #[test] @@ -3488,7 +3561,7 @@ pub mod tests { let res = s.num(6); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 152, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 152, None); } #[test] @@ -3498,7 +3571,7 @@ pub mod tests { let expr = "(cons (lambda (x y) nil) nil)"; let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, None, None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(terminal), None, 3, None); } #[test] @@ -3508,7 +3581,7 @@ pub mod tests { let expr = "(eval 'a '(nil))"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 4, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 4, None); } #[test] @@ -3523,7 +3596,7 @@ pub mod tests { let expr = "(let ((a 1)) t)"; let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, None, None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(terminal), None, 3, None); } #[test] @@ -3534,7 +3607,7 @@ pub mod tests { let expr = "nil"; let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, None, None, Some(terminal), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(terminal), None, 1, None); } #[test] @@ -3544,7 +3617,7 @@ pub mod tests { let expr = "(let ((a 1) (b 2)) c)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 7, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 7, None); } #[test] @@ -3553,7 +3626,7 @@ pub mod tests { let expr = "(* 5 (eval '(+ 1 a) '((0 . 3))))"; // two-arg eval, optional second arg is env. This tests for error on malformed env. let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 8, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 8, None); } #[test] @@ -3564,7 +3637,7 @@ pub mod tests { let res = s.uint64(123); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 1, None); } #[test] @@ -3579,10 +3652,10 @@ pub mod tests { let res2 = s.uint64(1); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 7, None); - test_aux::>(s, expr2, Some(res), None, Some(terminal), None, 3, None); - test_aux::>(s, expr3, Some(res), None, Some(terminal), None, 6, None); - test_aux::>(s, expr4, Some(res2), None, Some(terminal), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 7, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, Some(res), None, Some(terminal), None, 6, None); + test_aux::<_, _, M1<'_, _>>(s, expr4, Some(res2), None, Some(terminal), None, 2, None); } #[test] @@ -3594,8 +3667,8 @@ pub mod tests { let res = s.uint64(1); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(res), None, Some(terminal), None, 6, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res), None, Some(terminal), None, 6, None); } #[test] @@ -3610,9 +3683,9 @@ pub mod tests { let res3 = s.uint64(0); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); - test_aux::>(s, expr3, Some(res3), None, Some(terminal), None, 6, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, Some(res3), None, Some(terminal), None, 6, None); } #[test] @@ -3630,9 +3703,9 @@ pub mod tests { let terminal = s.get_cont_terminal(); let error = s.get_cont_error(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); - test_aux::>(s, expr3, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, None, None, Some(error), None, 3, None); } #[test] @@ -3650,9 +3723,9 @@ pub mod tests { let terminal = s.get_cont_terminal(); let error = s.get_cont_error(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); - test_aux::>(s, expr3, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, None, None, Some(error), None, 3, None); } #[test] @@ -3665,9 +3738,9 @@ pub mod tests { let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 3, None); - test_aux::>(s, expr2, None, None, Some(error), None, 3, None); - test_aux::>(s, expr3, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, None, None, Some(error), None, 3, None); } #[test] @@ -3691,18 +3764,18 @@ pub mod tests { let nil = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(t), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(nil), None, Some(terminal), None, 3, None); - test_aux::>(s, expr3, Some(t), None, Some(terminal), None, 3, None); - test_aux::>(s, expr4, Some(nil), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(nil), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr4, Some(nil), None, Some(terminal), None, 3, None); - test_aux::>(s, expr5, Some(nil), None, Some(terminal), None, 3, None); - test_aux::>(s, expr6, Some(t), None, Some(terminal), None, 3, None); - test_aux::>(s, expr7, Some(nil), None, Some(terminal), None, 3, None); - test_aux::>(s, expr8, Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr5, Some(nil), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr6, Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr7, Some(nil), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr8, Some(t), None, Some(terminal), None, 3, None); - test_aux::>(s, expr9, Some(t), None, Some(terminal), None, 3, None); - test_aux::>(s, expr10, Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr9, Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr10, Some(t), None, Some(terminal), None, 3, None); } #[test] @@ -3718,10 +3791,10 @@ pub mod tests { let res3 = s.intern_u64(2); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(res), None, Some(terminal), None, 2, None); - test_aux::>(s, expr3, Some(res2), None, Some(terminal), None, 3, None); - test_aux::>(s, expr4, Some(res3), None, Some(terminal), None, 5, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res), None, Some(terminal), None, 2, None); + test_aux::<_, _, M1<'_, _>>(s, expr3, Some(res2), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr4, Some(res3), None, Some(terminal), None, 5, None); } #[test] @@ -3734,8 +3807,8 @@ pub mod tests { let nil = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(t), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(nil), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(t), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(nil), None, Some(terminal), None, 3, None); } #[test] @@ -3748,8 +3821,8 @@ pub mod tests { let res2 = s.read("(1u64 . 1)").unwrap(); let terminal = s.get_cont_terminal(); - test_aux::>(s, expr, Some(res), None, Some(terminal), None, 3, None); - test_aux::>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, Some(res), None, Some(terminal), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr2, Some(res2), None, Some(terminal), None, 3, None); } #[test] @@ -3759,7 +3832,7 @@ pub mod tests { let expr = "(hide 0u64 123)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 3, None); } #[test] @@ -3769,7 +3842,7 @@ pub mod tests { let expr = "(% 0 0)"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 3, None); } #[test] @@ -3778,7 +3851,7 @@ pub mod tests { let expr = "(let ((a (lambda (x) (+ x 1)))) (a . 1))"; let error = s.get_cont_error(); - test_aux::>(s, expr, None, None, Some(error), None, 3, None); + test_aux::<_, _, M1<'_, _>>(s, expr, None, None, Some(error), None, 3, None); } #[test] @@ -3794,7 +3867,7 @@ pub mod tests { let terminal = s.get_cont_terminal(); let lang: Arc>> = Arc::new(Lang::new()); - nova_test_full_aux2( + nova_test_full_aux2::<_, _, M1<'_, _>>( s, expr, Some(res), @@ -3814,8 +3887,8 @@ pub mod tests { let s = &mut Store::::default(); let error = s.get_cont_error(); - test_aux::>(s, "((lambda ()))", None, None, Some(error), None, 2, None); - test_aux::>( + test_aux::<_, _, M1<'_, _>>(s, "((lambda ()))", None, None, Some(error), None, 2, None); + test_aux::<_, _, M1<'_, _>>( s, "((lambda () 1 2))", None, @@ -3825,7 +3898,7 @@ pub mod tests { 2, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (x)) 1)", None, @@ -3835,7 +3908,7 @@ pub mod tests { 3, None, ); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (x) 1 2) 1)", None, @@ -3853,14 +3926,14 @@ pub mod tests { let s = &mut Store::::default(); let error = s.get_cont_error(); - let mut test = |x| { + let test = |x| { let expr = format!("(let (({x} 123)) {x})"); let expr2 = format!("(letrec (({x} 123)) {x})"); let expr3 = format!("(lambda ({x}) {x})"); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); - test_aux::>(s, &expr2, None, None, Some(error), None, 1, None); - test_aux::>(s, &expr3, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr2, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr3, None, None, Some(error), None, 1, None); }; test(":a"); @@ -3886,37 +3959,37 @@ pub mod tests { { // binop let expr = format!("({} 1 1)", hash_num(s, state.clone(), "+")); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } { // unop let expr = format!("({} '(1 . 2))", hash_num(s, state.clone(), "car")); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } { // let_or_letrec let expr = format!("({} ((a 1)) a)", hash_num(s, state.clone(), "let")); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } { // current-env let expr = format!("({})", hash_num(s, state.clone(), "current-env")); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } { // lambda let expr = format!("({} (x) 123)", hash_num(s, state.clone(), "lambda")); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } { // quote let expr = format!("({} asdf)", hash_num(s, state.clone(), "quote")); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } { // if let expr = format!("({} t 123 456)", hash_num(s, state, "if")); - test_aux::>(s, &expr, None, None, Some(error), None, 1, None); + test_aux::<_, _, M1<'_, _>>(s, &expr, None, None, Some(error), None, 1, None); } } @@ -3949,9 +4022,27 @@ pub mod tests { let error = s.get_cont_error(); let lang = Arc::new(lang); - test_aux(s, expr, Some(res), None, None, None, 2, Some(lang.clone())); - test_aux(s, expr2, Some(res), None, None, None, 4, Some(lang.clone())); - test_aux( + test_aux::<_, _, C1<'_, _, DumbCoproc<_>>>( + s, + expr, + Some(res), + None, + None, + None, + 2, + Some(lang.clone()), + ); + test_aux::<_, _, C1<'_, _, DumbCoproc<_>>>( + s, + expr2, + Some(res), + None, + None, + None, + 4, + Some(lang.clone()), + ); + test_aux::<_, _, C1<'_, _, DumbCoproc<_>>>( s, expr3, None, @@ -3961,7 +4052,16 @@ pub mod tests { 1, Some(lang.clone()), ); - test_aux(s, expr4, None, None, Some(error), None, 1, Some(lang)); + test_aux::<_, _, C1<'_, _, DumbCoproc<_>>>( + s, + expr4, + None, + None, + Some(error), + None, + 1, + Some(lang), + ); } // This is related to issue #426 @@ -3970,7 +4070,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = lurk_sym_ptr!(s, nil); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "((lambda (x) nil) 0)", Some(expected), @@ -3988,7 +4088,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(2); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((x (let ((z 0)) 1))) 2)", Some(expected), @@ -4004,7 +4104,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(1); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(let ((x 0) (y x)) 1)", Some(expected), @@ -4020,7 +4120,7 @@ pub mod tests { let s = &mut Store::::default(); let expected = s.num(3); let terminal = s.get_cont_terminal(); - test_aux::>( + test_aux::<_, _, M1<'_, _>>( s, "(letrec ((x 0) (y (letrec ((inner 1)) 2))) 3)", Some(expected), diff --git a/src/proof/supernova.rs b/src/proof/supernova.rs index 0bcceb9318..c013d49d3b 100644 --- a/src/proof/supernova.rs +++ b/src/proof/supernova.rs @@ -247,7 +247,8 @@ where { } -impl<'a, F: CurveCycleEquipped, C: Coprocessor + 'a> Prover<'a, F, C> for SuperNovaProver +impl<'a, F: CurveCycleEquipped, C: Coprocessor + 'a> Prover<'a, F, C, MultiFrame<'a, F, C>> + for SuperNovaProver where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, diff --git a/src/public_parameters/disk_cache.rs b/src/public_parameters/disk_cache.rs index c11790fb78..35071b35e6 100644 --- a/src/public_parameters/disk_cache.rs +++ b/src/public_parameters/disk_cache.rs @@ -8,18 +8,21 @@ use nova::traits::Group; use crate::coprocessor::Coprocessor; use crate::proof::nova::{CurveCycleEquipped, PublicParams, G1, G2}; +use crate::proof::MultiFrameTrait; use crate::public_parameters::error::Error; -pub(crate) struct PublicParamDiskCache +pub(crate) struct PublicParamDiskCache<'a, F, C, M> where F: CurveCycleEquipped, - C: Coprocessor, + C: Coprocessor + 'a, + M: MultiFrameTrait<'a, F, C>, { dir: Utf8PathBuf, - _t: PhantomData<(F, C)>, + _t: PhantomData<(&'a (), F, C, M)>, } -impl> PublicParamDiskCache +impl<'a, F: CurveCycleEquipped, C: Coprocessor + 'a, M: MultiFrameTrait<'a, F, C>> + PublicParamDiskCache<'a, F, C, M> where // technical bounds that would disappear once associated_type_bounds stabilizes < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, @@ -38,7 +41,7 @@ where self.dir.join(Utf8PathBuf::from(key)) } - pub(crate) fn get(&self, key: &str) -> Result, Error> { + pub(crate) fn get(&self, key: &str) -> Result, Error> { let file = File::open(self.key_path(key))?; let reader = BufReader::new(file); bincode::deserialize_from(reader).map_err(|e| { @@ -54,7 +57,7 @@ where Ok(bytes) } - pub(crate) fn set(&self, key: &str, data: &PublicParams<'static, F, C>) -> Result<(), Error> { + pub(crate) fn set(&self, key: &str, data: &PublicParams) -> Result<(), Error> { let file = File::create(self.key_path(key)).expect("failed to create file"); let writer = BufWriter::new(&file); bincode::serialize_into(writer, &data).map_err(|e| { diff --git a/src/public_parameters/mem_cache.rs b/src/public_parameters/mem_cache.rs index 3c93794dff..2aed902d88 100644 --- a/src/public_parameters/mem_cache.rs +++ b/src/public_parameters/mem_cache.rs @@ -10,6 +10,7 @@ use once_cell::sync::Lazy; use tap::TapFallible; use tracing::{info, warn}; +use crate::proof::MultiFrameTrait; use crate::{ coprocessor::Coprocessor, eval::lang::Lang, @@ -20,7 +21,7 @@ use crate::{proof::nova::CurveCycleEquipped, public_parameters::error::Error}; use super::disk_cache::PublicParamDiskCache; type AnyMap = anymap::Map; -type PublicParamMap = HashMap<(usize, bool), Arc>>; +type PublicParamMap = HashMap<(usize, bool), Arc>>; /// This is a global registry for Coproc-specific parameters. /// It is used to cache parameters for each Coproc, so that they are not @@ -39,9 +40,11 @@ pub(crate) static PUBLIC_PARAM_MEM_CACHE: Lazy = impl PublicParamMemCache { fn get_from_disk_cache_or_update_with< + 'a, F: CurveCycleEquipped, - C: Coprocessor, - Fn: FnOnce(Arc>) -> Arc>, + C: Coprocessor + 'a, + M: MultiFrameTrait<'a, F, C>, + Fn: FnOnce(Arc>) -> Arc>, >( &'static self, rc: usize, @@ -49,7 +52,7 @@ impl PublicParamMemCache { default: Fn, lang: Arc>, disk_cache_path: &Utf8Path, - ) -> Result>, Error> + ) -> Result>, Error> where < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, @@ -67,8 +70,7 @@ impl PublicParamMemCache { match disk_cache.get_raw_bytes(&key) { Ok(mut bytes) => { info!("loading abomonated {lang_key}"); - let (pp, rest) = - unsafe { decode::>(&mut bytes).unwrap() }; + let (pp, rest) = unsafe { decode::>(&mut bytes).unwrap() }; assert!(rest.is_empty()); Ok(Arc::new(pp.clone())) // this clone is VERY expensive } @@ -106,7 +108,8 @@ impl PublicParamMemCache { pub(crate) fn get_from_mem_cache_or_update_with< F: CurveCycleEquipped, C: Coprocessor + 'static, - Fn: FnOnce(Arc>) -> Arc>, + M: MultiFrameTrait<'static, F, C> + 'static, + Fn: FnOnce(Arc>) -> Arc>, >( &'static self, rc: usize, @@ -114,7 +117,7 @@ impl PublicParamMemCache { default: Fn, lang: Arc>, disk_cache_path: &Utf8Path, - ) -> Result>, Error> + ) -> Result>, Error> where F::CK1: Sync + Send, F::CK2: Sync + Send, @@ -124,7 +127,7 @@ impl PublicParamMemCache { // re-grab the lock let mut mem_cache = self.mem_cache.lock().unwrap(); // retrieve the per-Coproc public param table - let entry = mem_cache.entry::>(); + let entry = mem_cache.entry::>(); // deduce the map and populate it if needed let param_entry = entry.or_default(); match param_entry.entry((rc, abomonated)) { diff --git a/src/public_parameters/mod.rs b/src/public_parameters/mod.rs index f9134c1880..e81c48df24 100644 --- a/src/public_parameters/mod.rs +++ b/src/public_parameters/mod.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use crate::coprocessor::Coprocessor; use crate::proof::nova::{CurveCycleEquipped, G1, G2}; +use crate::proof::MultiFrameTrait; use crate::{ eval::lang::Lang, proof::nova::{self, PublicParams}, @@ -28,19 +29,23 @@ pub fn public_params_default_dir() -> Utf8PathBuf { Utf8PathBuf::from(".lurk/public_params") } -pub fn public_params + 'static>( +pub fn public_params< + F: CurveCycleEquipped, + C: Coprocessor + 'static, + M: MultiFrameTrait<'static, F, C> + 'static, +>( rc: usize, abomonated: bool, lang: Arc>, disk_cache_path: &Utf8Path, -) -> Result>, Error> +) -> Result>, Error> where F::CK1: Sync + Send, F::CK2: Sync + Send, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { - let f = |lang: Arc>| Arc::new(nova::public_params(rc, lang)); + let f = |lang: Arc>| Arc::new(nova::public_params::(rc, lang)); mem_cache::PUBLIC_PARAM_MEM_CACHE.get_from_mem_cache_or_update_with( rc, abomonated, @@ -55,19 +60,20 @@ where /// this leads to extremely high performance, but restricts the lifetime of the data /// to the lifetime of the file. Thus, we cannot pass a reference out and must /// rely on a closure to capture the data and continue the computation in `bind`. -pub fn with_public_params( +pub fn with_public_params<'a, F: CurveCycleEquipped, C, M, Fn, T>( rc: usize, lang: Arc>, bind: Fn, ) -> Result where - C: Coprocessor + 'static, - Fn: FnOnce(&PublicParams<'static, F, C>) -> T, + C: Coprocessor + 'a, + M: MultiFrameTrait<'a, F, C>, + Fn: FnOnce(&PublicParams) -> T, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, < as Group>::Scalar as ff::PrimeField>::Repr: Abomonation, { let disk_cache = - disk_cache::PublicParamDiskCache::::new(&public_params_default_dir()).unwrap(); + disk_cache::PublicParamDiskCache::::new(&public_params_default_dir()).unwrap(); // use the cached language key let lang_key = lang.key(); // Sanity-check: we're about to use a lang-dependent disk cache, which should be specialized @@ -120,9 +126,13 @@ mod tests { .join("public_params"); let lang: Arc>> = Arc::new(Lang::new()); + type OG = crate::proof::nova::C1<'static, S1, Coproc>; // Without disk cache, writes to tmpfile - let _public_params = public_params(10, true, lang.clone(), &public_params_dir).unwrap(); + let _public_params = + public_params::, OG>(10, true, lang.clone(), &public_params_dir) + .unwrap(); // With disk cache, reads from tmpfile - let _public_params = public_params(10, true, lang, &public_params_dir).unwrap(); + let _public_params = + public_params::, OG>(10, true, lang, &public_params_dir).unwrap(); } } diff --git a/src/syntax.rs b/src/syntax.rs index db20b5913d..2aa4459c85 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -107,7 +107,7 @@ impl fmt::Display for Syntax { } impl Store { - pub fn intern_syntax(&mut self, syn: Syntax) -> Ptr { + pub fn intern_syntax(&self, syn: Syntax) -> Ptr { match syn { Syntax::Num(_, x) => self.intern_num(x), Syntax::UInt(_, x) => self.intern_uint(x), @@ -252,7 +252,7 @@ mod test { #[test] fn syntax_rootkey_roundtrip() { - let mut store1 = Store::::default(); + let store1 = Store::::default(); let ptr1 = store1.intern_syntax(Syntax::Symbol(Pos::No, Symbol::root_key().into())); let (z_store, z_ptr) = store1.to_z_store_with_ptr(&ptr1).unwrap(); let (store2, ptr2) = z_store.to_store_with_z_ptr(&z_ptr).unwrap(); @@ -263,7 +263,7 @@ mod test { #[test] fn syntax_empty_keyword_roundtrip() { - let mut store1 = Store::::default(); + let store1 = Store::::default(); let ptr1 = store1.intern_syntax(Syntax::Symbol(Pos::No, Symbol::key(&[""]).into())); let (z_store, z_ptr) = store1.to_z_store_with_ptr(&ptr1).unwrap(); let (store2, ptr2) = z_store.to_store_with_z_ptr(&z_ptr).unwrap(); @@ -276,7 +276,7 @@ mod test { // TODO: Proptest the Store/ZStore roundtrip with two distinct syntaxes #[test] fn syntax_full_roundtrip(x in any::>()) { - let mut store1 = Store::::default(); + let store1 = Store::::default(); let ptr1 = store1.intern_syntax(x); let (z_store, z_ptr) = store1.to_z_store_with_ptr(&ptr1).unwrap(); let (store2, ptr2) = z_store.to_store_with_z_ptr(&z_ptr).unwrap(); diff --git a/src/z_data/z_expr.rs b/src/z_data/z_expr.rs index 47487ba7bc..5decbd2a54 100644 --- a/src/z_data/z_expr.rs +++ b/src/z_data/z_expr.rs @@ -216,7 +216,7 @@ mod tests { #[test] // TODO: Overflows stack in non-release mode fn prop_expr_z_expr_roundtrip(x in any::>()) { - let mut store = Store::::default(); + let store = Store::::default(); let ptr = store.intern_syntax(x); let expr = store.fetch(&ptr).unwrap(); @@ -230,7 +230,7 @@ mod tests { #[test] fn unit_expr_z_expr() { - let mut store = Store::::default(); + let store = Store::::default(); let x = "(+ 1 1)"; let ptr = store.read(x).unwrap(); let expr = store.fetch(&ptr).unwrap(); diff --git a/src/z_data/z_ptr.rs b/src/z_data/z_ptr.rs index fa40144a58..7eb4f5588e 100644 --- a/src/z_data/z_ptr.rs +++ b/src/z_data/z_ptr.rs @@ -131,7 +131,7 @@ pub type ZExprPtr = ZPtr; impl ZExprPtr { /// Parses and hashes a Lurk source string into a ZExprPtr pub fn from_lurk_str(value: &str) -> Result { - let mut store = Store::::default(); + let store = Store::::default(); let ptr = store .read(value) .map_err(|e| store::Error(format!("Parse error: {}", e)))?;