diff --git a/benches/sha256.rs b/benches/sha256.rs index 5e25b9ca2..b0c899268 100644 --- a/benches/sha256.rs +++ b/benches/sha256.rs @@ -28,7 +28,8 @@ use lurk::{ instance::{Instance, Kind}, public_params, supernova_public_params, }, - state::{user_sym, State, StateRcCell}, + state::{State, StateRcCell}, + Symbol, }; mod common; @@ -103,7 +104,7 @@ fn sha256_ivc_prove( let limit = 10000; let store = &Store::::default(); - let cproc_sym = user_sym(&format!("sha256_ivc_{arity}")); + let cproc_sym = Symbol::interned(format!("sha256_ivc_{arity}"), state.clone()).unwrap(); let mut lang = Lang::>::new(); lang.add_coprocessor(cproc_sym, Sha256Coprocessor::new(arity)); @@ -191,7 +192,7 @@ fn sha256_ivc_prove_compressed( let limit = 10000; let store = &Store::::default(); - let cproc_sym = user_sym(&format!("sha256_ivc_{arity}")); + let cproc_sym = Symbol::interned(format!("sha256_ivc_{arity}"), state.clone()).unwrap(); let mut lang = Lang::>::new(); lang.add_coprocessor(cproc_sym, Sha256Coprocessor::new(arity)); @@ -281,7 +282,7 @@ fn sha256_nivc_prove( let limit = 10000; let store = &Store::::default(); - let cproc_sym = user_sym(&format!("sha256_ivc_{arity}")); + let cproc_sym = Symbol::interned(format!("sha256_ivc_{arity}"), state.clone()).unwrap(); let mut lang = Lang::>::new(); lang.add_coprocessor(cproc_sym, Sha256Coprocessor::new(arity)); diff --git a/examples/circom.rs b/examples/circom.rs index 08b2db41c..bfa010be8 100644 --- a/examples/circom.rs +++ b/examples/circom.rs @@ -48,6 +48,7 @@ use lurk::public_parameters::{ instance::{Instance, Kind}, public_params, }; +use lurk::state::State; use lurk::Symbol; use lurk_macros::Coproc; @@ -101,14 +102,15 @@ enum Sha256Coproc { /// `cargo run --release --example circom` fn main() { let store = &Store::default(); - let sym_str = Symbol::new(&[".circom_sha256_2"], false); // two inputs + let state = State::init_lurk_state().rccell(); + + let name = Symbol::interned(".circom_sha256_2", state.clone()).unwrap(); // two inputs let circom_sha256: CircomSha256 = CircomSha256::new(0); let mut lang = Lang::>::new(); - lang.add_coprocessor(sym_str, CircomCoprocessor::new(circom_sha256)); + lang.add_coprocessor(name, CircomCoprocessor::new(circom_sha256)); let lang_rc = Arc::new(lang); - let expr = "(.circom_sha256_2)".to_string(); - let ptr = store.read_with_default_state(&expr).unwrap(); + let ptr = store.read(state, "(.circom_sha256_2)").unwrap(); let nova_prover = NovaProver::>::new(REDUCTION_COUNT, lang_rc.clone()); diff --git a/examples/sha256_ivc.rs b/examples/sha256_ivc.rs index dc09e6d2f..bec10e3a8 100644 --- a/examples/sha256_ivc.rs +++ b/examples/sha256_ivc.rs @@ -14,12 +14,18 @@ use lurk::{ instance::{Instance, Kind}, public_params, }, - state::user_sym, + state::{State, StateRcCell}, + Symbol, }; const REDUCTION_COUNT: usize = 10; -fn sha256_ivc(store: &Store, n: usize, input: &[usize]) -> Ptr { +fn sha256_ivc( + store: &Store, + state: StateRcCell, + n: usize, + input: &[usize], +) -> Ptr { assert_eq!(n, input.len()); let input = input .iter() @@ -47,7 +53,7 @@ fn sha256_ivc(store: &Store, n: usize, input: &[usize]) -> Ptr "# ); - store.read_with_default_state(&program).unwrap() + store.read(state, &program).unwrap() } /// Run the example in this file with @@ -64,9 +70,10 @@ fn main() { let n = args.get(1).unwrap_or(&"1".into()).parse().unwrap(); let store = &Store::default(); - let cproc_sym = user_sym(&format!("sha256_ivc_{n}")); + let state = State::init_lurk_state().rccell(); + let cproc_sym = Symbol::interned(format!("sha256_ivc_{n}"), state.clone()).unwrap(); - let call = sha256_ivc(store, n, &(0..n).collect::>()); + let call = sha256_ivc(store, state, n, &(0..n).collect::>()); let mut lang = Lang::>::new(); lang.add_coprocessor(cproc_sym, Sha256Coprocessor::new(n)); diff --git a/examples/sha256_nivc.rs b/examples/sha256_nivc.rs index ae3d86089..204b2fdef 100644 --- a/examples/sha256_nivc.rs +++ b/examples/sha256_nivc.rs @@ -18,12 +18,18 @@ use lurk::{ instance::{Instance, Kind}, supernova_public_params, }, - state::user_sym, + state::{State, StateRcCell}, + Symbol, }; const REDUCTION_COUNT: usize = 10; -fn sha256_nivc(store: &Store, n: usize, input: &[usize]) -> Ptr { +fn sha256_nivc( + store: &Store, + state: StateRcCell, + n: usize, + input: &[usize], +) -> Ptr { assert_eq!(n, input.len()); let input = input .iter() @@ -51,7 +57,7 @@ fn sha256_nivc(store: &Store, n: usize, input: &[usize]) -> Ptr "# ); - store.read_with_default_state(&program).unwrap() + store.read(state, &program).unwrap() } /// Run the example in this file with @@ -68,9 +74,10 @@ fn main() { let n = args.get(1).unwrap_or(&"1".into()).parse().unwrap(); let store = &Store::default(); - let cproc_sym = user_sym(&format!("sha256_nivc_{n}")); + let state = State::init_lurk_state().rccell(); + let cproc_sym = Symbol::interned(format!("sha256_nivc_{n}"), state.clone()).unwrap(); - let call = sha256_nivc(store, n, &(0..n).collect::>()); + let call = sha256_nivc(store, state, n, &(0..n).collect::>()); let mut lang = Lang::>::new(); lang.add_coprocessor(cproc_sym, Sha256Coprocessor::new(n)); diff --git a/src/coprocessor/trie/mod.rs b/src/coprocessor/trie/mod.rs index 41a0c19f8..ba9b83fa1 100644 --- a/src/coprocessor/trie/mod.rs +++ b/src/coprocessor/trie/mod.rs @@ -318,10 +318,9 @@ pub fn install(state: &StateRcCell, lang: &mut Lang` instead? - lang.add_coprocessor((*new_sym).clone(), NewCoprocessor::default()); - lang.add_coprocessor((*lookup_sym).clone(), LookupCoprocessor::default()); - lang.add_coprocessor((*insert_sym).clone(), InsertCoprocessor::default()); + lang.add_coprocessor(new_sym, NewCoprocessor::default()); + lang.add_coprocessor(lookup_sym, LookupCoprocessor::default()); + lang.add_coprocessor(insert_sym, InsertCoprocessor::default()); } pub type ChildMap = InversePoseidonCache; diff --git a/src/lang.rs b/src/lang.rs index 555ee67dc..07c2ebc6c 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -8,6 +8,7 @@ use crate::{ coprocessor::{CoCircuit, Coprocessor}, field::LurkField, lem::{pointers::Ptr, store::Store}, + package::SymbolRef, symbol::Symbol, }; @@ -69,12 +70,10 @@ pub enum Coproc { /// - `F`: A field type that implements the [`crate::field::LurkField`] trait. /// - `C`: A type that implements the [`crate::coprocessor::Coprocessor`] trait. This allows late-binding of the /// exact set of coprocessors to be allowed in the `Lang` struct. -/// -// TODO: Define a trait for the Hash and parameterize on that also. #[derive(Debug, Default, Clone, Deserialize, Serialize)] pub struct Lang> { /// An IndexMap that stores coprocessors with their associated `Sym` keys. - coprocessors: IndexMap, + coprocessors: IndexMap, _p: PhantomData, } @@ -111,8 +110,8 @@ impl Lang { } #[inline] - pub fn add_coprocessor, S: Into>(&mut self, name: S, cproc: T) { - self.coprocessors.insert(name.into(), cproc.into()); + pub fn add_coprocessor>(&mut self, name: SymbolRef, cproc: T) { + self.coprocessors.insert(name, cproc.into()); } pub fn add_binding>>(&mut self, binding: B) { @@ -121,7 +120,7 @@ impl Lang { } #[inline] - pub fn coprocessors(&self) -> &IndexMap { + pub fn coprocessors(&self) -> &IndexMap { &self.coprocessors } @@ -155,21 +154,21 @@ impl Lang { /// modular construction of `Lang`s using `Coprocessor`s. #[derive(Debug)] pub struct Binding { - name: Symbol, + name: SymbolRef, coproc: C, _p: PhantomData, } -impl, S: Into> From<(S, C)> for Binding { - fn from(pair: (S, C)) -> Self { +impl> From<(SymbolRef, C)> for Binding { + fn from(pair: (SymbolRef, C)) -> Self { Self::new(pair.0, pair.1) } } impl Binding { - pub fn new, S: Into>(name: S, coproc: T) -> Self { + pub fn new>(name: SymbolRef, coproc: T) -> Self { Self { - name: name.into(), + name, coproc: coproc.into(), _p: Default::default(), } @@ -191,7 +190,7 @@ pub(crate) mod test { #[test] fn dummy_lang() { let _lang = Lang::::new_with_bindings(vec![( - sym!("coproc", "dummy"), + sym!("coproc", "dummy").into(), DummyCoprocessor::new().into(), )]); } diff --git a/src/lem/eval.rs b/src/lem/eval.rs index dd4a47617..68b03642f 100644 --- a/src/lem/eval.rs +++ b/src/lem/eval.rs @@ -310,7 +310,7 @@ pub fn make_eval_step_from_config>( &ec.lang .coprocessors() .iter() - .map(|(s, c)| (s, c.arity())) + .map(|(s, c)| (s as &Symbol, c.arity())) .collect::>(), ec.is_ivc(), ) @@ -489,7 +489,7 @@ pub fn make_cprocs_funcs_from_lang>( ) -> Vec { lang.coprocessors() .iter() - .map(|(name, c)| run_cproc(name.clone(), c.arity())) + .map(|(name, c)| run_cproc((*name.clone()).clone(), c.arity())) .collect() } diff --git a/src/lem/tests/eval_tests.rs b/src/lem/tests/eval_tests.rs index 74f4181c1..477b591cb 100644 --- a/src/lem/tests/eval_tests.rs +++ b/src/lem/tests/eval_tests.rs @@ -15,6 +15,7 @@ use crate::{ }, state::{State, StateRcCell}, tag::Op, + Symbol, }; fn test_aux>( @@ -3733,11 +3734,13 @@ fn test_eval_non_symbol_binding_error() { #[test] fn test_dumb_lang() { - use crate::{coprocessor::test::DumbCoprocessor, state::user_sym}; + use crate::coprocessor::test::DumbCoprocessor; + + let state = State::init_lurk_state().rccell(); let mut lang = Lang::>::new(); let dumb = DumbCoprocessor::new(); - let name = user_sym("cproc-dumb"); + let name = Symbol::interned("cproc-dumb", state.clone()).unwrap(); let s = &Store::default(); lang.add_coprocessor(name, dumb); @@ -3770,8 +3773,9 @@ fn test_dumb_lang() { let error = s.cont_error(); let terminal = s.cont_terminal(); - test_aux( + test_aux_with_state( s, + state.clone(), expr, Some(res), None, @@ -3780,8 +3784,9 @@ fn test_dumb_lang() { &expect!["3"], &Some(&lang), ); - test_aux( + test_aux_with_state( s, + state.clone(), expr2, Some(res), None, @@ -3790,8 +3795,9 @@ fn test_dumb_lang() { &expect!["5"], &Some(&lang), ); - test_aux( + test_aux_with_state( s, + state.clone(), expr3, Some(res), None, @@ -3800,8 +3806,9 @@ fn test_dumb_lang() { &expect!["9"], &Some(&lang), ); - test_aux( + test_aux_with_state( s, + state.clone(), expr4, Some(error4), None, @@ -3810,8 +3817,9 @@ fn test_dumb_lang() { &expect!["4"], &Some(&lang), ); - test_aux( + test_aux_with_state( s, + state.clone(), expr5, Some(error5), None, @@ -3820,8 +3828,9 @@ fn test_dumb_lang() { &expect!["2"], &Some(&lang), ); - test_aux( + test_aux_with_state( s, + state.clone(), expr6, Some(error6), None, @@ -3830,8 +3839,9 @@ fn test_dumb_lang() { &expect!["3"], &Some(&lang), ); - test_aux( + test_aux_with_state( s, + state.clone(), expr6_, Some(error6), None, @@ -3840,8 +3850,9 @@ fn test_dumb_lang() { &expect!["3"], &Some(&lang), ); - test_aux( + test_aux_with_state( s, + state, expr7, Some(error7), None, @@ -3971,22 +3982,24 @@ fn test_trie_lang() { #[test] fn test_terminator_lang() { - use crate::{coprocessor::test::Terminator, state::user_sym}; + use crate::coprocessor::test::Terminator; + + let state = State::init_lurk_state().rccell(); let mut lang = Lang::>::new(); - let dumb = Terminator::new(); - let name = user_sym("terminate"); + let name = Symbol::interned("terminate", state.clone()).unwrap(); let s = &Store::default(); - lang.add_coprocessor(name, dumb); + lang.add_coprocessor(name, Terminator::new()); let expr = "(terminate)"; let res = s.intern_nil(); let terminal = s.cont_terminal(); - test_aux( + test_aux_with_state( s, + state, expr, Some(res), None, diff --git a/src/lem/tests/nivc_steps.rs b/src/lem/tests/nivc_steps.rs index 85bbd9371..1cdd7e3ff 100644 --- a/src/lem/tests/nivc_steps.rs +++ b/src/lem/tests/nivc_steps.rs @@ -9,15 +9,17 @@ use crate::{ store::{expect_ptrs, intern_ptrs, Store}, Tag, }, - state::user_sym, + state::{user_sym, State}, tag::{ContTag, ExprTag}, + Symbol, }; #[test] fn test_nivc_steps() { + let state = State::init_lurk_state().rccell(); let mut lang = Lang::>::new(); let dumb = DumbCoprocessor::new(); - let name = user_sym("cproc-dumb"); + let name = Symbol::interned("cproc-dumb", state.clone()).unwrap(); let store = Store::::default(); lang.add_coprocessor(name, dumb); @@ -30,7 +32,7 @@ fn test_nivc_steps() { let cproc = &cprocs[0]; // 9^2 + 8 = 89 - let expr = store.read_with_default_state("(cproc-dumb 9 8)").unwrap(); + let expr = store.read(state, "(cproc-dumb 9 8)").unwrap(); let frames = evaluate( Some((&lurk_step, &cprocs, &lang)), diff --git a/src/proof/tests/nova_tests.rs b/src/proof/tests/nova_tests.rs index 31596c7e9..39f00c9f6 100644 --- a/src/proof/tests/nova_tests.rs +++ b/src/proof/tests/nova_tests.rs @@ -9,8 +9,9 @@ use crate::{ tag::Tag, }, num::Num, - state::{user_sym, State, StateRcCell}, + state::{State, StateRcCell}, tag::{ExprTag, Op, Op1, Op2}, + Symbol, }; use super::{ @@ -3926,31 +3927,36 @@ fn test_dumb_lang() { use crate::coprocessor::test::DumbCoprocessor; let s = &Store::::default(); + let state = State::init_lurk_state().rccell(); let mut lang = Lang::>::new(); - let name = user_sym("cproc-dumb"); + let name = Symbol::interned("cproc-dumb", state.clone()).unwrap(); let dumb = DumbCoprocessor::new(); lang.add_coprocessor(name, dumb); + let get_ptr = |input| s.read(state.clone(), input).unwrap(); + // 9^2 + 8 = 89 - let expr = "(cproc-dumb 9 8)"; + let expr = get_ptr("(cproc-dumb 9 8)"); // coprocessors cannot be shadowed - let expr2 = "(let ((cproc-dumb (lambda (a b) (* a b)))) - (cproc-dumb 9 8))"; + let expr2 = get_ptr( + "(let ((cproc-dumb (lambda (a b) (* a b)))) + (cproc-dumb 9 8))", + ); // arguments for coprocessors are evaluated - let expr3 = "(cproc-dumb (+ 1 8) (+ 1 7))"; + let expr3 = get_ptr("(cproc-dumb (+ 1 8) (+ 1 7))"); // wrong number of parameters - let expr4 = "(cproc-dumb 9 8 123)"; - let expr5 = "(cproc-dumb 9)"; + let expr4 = get_ptr("(cproc-dumb 9 8 123)"); + let expr5 = get_ptr("(cproc-dumb 9)"); // wrong parameter type - let expr6 = "(cproc-dumb 'x' 0)"; - let expr6_ = "(cproc-dumb 'x' 'y')"; - let expr7 = "(cproc-dumb 0 'y')"; + let expr6 = get_ptr("(cproc-dumb 'x' 0)"); + let expr6_ = get_ptr("(cproc-dumb 'x' 'y')"); + let expr7 = get_ptr("(cproc-dumb 0 'y')"); let res = s.num_u64(89); let error4 = s.list(vec![s.num_u64(123), s.num_u64(8), s.num_u64(9)]); @@ -3962,7 +3968,7 @@ fn test_dumb_lang() { let terminal = s.cont_terminal(); let lang = Arc::new(lang); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr, Some(res), @@ -3972,7 +3978,7 @@ fn test_dumb_lang() { &expect!["3"], &Some(lang.clone()), ); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr2, Some(res), @@ -3982,7 +3988,7 @@ fn test_dumb_lang() { &expect!["5"], &Some(lang.clone()), ); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr3, Some(res), @@ -3992,7 +3998,7 @@ fn test_dumb_lang() { &expect!["9"], &Some(lang.clone()), ); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr4, Some(error4), @@ -4002,7 +4008,7 @@ fn test_dumb_lang() { &expect!["4"], &Some(lang.clone()), ); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr5, Some(error5), @@ -4012,7 +4018,7 @@ fn test_dumb_lang() { &expect!["2"], &Some(lang.clone()), ); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr6, Some(error6), @@ -4022,7 +4028,7 @@ fn test_dumb_lang() { &expect!["3"], &Some(lang.clone()), ); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr6_, Some(error6), @@ -4032,7 +4038,7 @@ fn test_dumb_lang() { &expect!["3"], &Some(lang.clone()), ); - test_aux::<_, DumbCoprocessor<_>>( + test_aux_ptr::<_, DumbCoprocessor<_>>( s, expr7, Some(error7), @@ -4048,19 +4054,19 @@ fn test_dumb_lang() { fn test_terminator_lang() { use crate::coprocessor::test::Terminator; + let state = State::init_lurk_state().rccell(); let mut lang = Lang::>::new(); - let dumb = Terminator::new(); - let name = user_sym("terminate"); + let name = Symbol::interned("terminate", state.clone()).unwrap(); let s = &Store::default(); - lang.add_coprocessor(name, dumb); + lang.add_coprocessor(name, Terminator::new()); - let expr = "(terminate)"; + let expr = s.read(state, "(terminate)").unwrap(); let res = s.intern_nil(); let terminal = s.cont_terminal(); - test_aux::<_, Terminator<_>>( + test_aux_ptr::<_, Terminator<_>>( s, expr, Some(res), @@ -4076,9 +4082,10 @@ fn test_terminator_lang() { fn test_hello_world_lang() { use crate::coprocessor::test::HelloWorld; + let state = State::init_lurk_state().rccell(); let mut lang = Lang::>::new(); let hello_world = HelloWorld::new(); - let name = user_sym("hello-world"); + let name = Symbol::interned("hello-world", state.clone()).unwrap(); let s = &Store::default(); lang.add_coprocessor(name, hello_world); @@ -4086,9 +4093,11 @@ fn test_hello_world_lang() { let res = HelloWorld::intern_hello_world(s); let terminal = s.cont_terminal(); - test_aux::<_, HelloWorld<_>>( + let expr = s.read(state, "(hello-world)").unwrap(); + + test_aux_ptr::<_, HelloWorld<_>>( s, - "(hello-world)", + expr, Some(res), None, Some(terminal), diff --git a/src/proof/tests/supernova_tests.rs b/src/proof/tests/supernova_tests.rs index 7431fef19..5321999ca 100644 --- a/src/proof/tests/supernova_tests.rs +++ b/src/proof/tests/supernova_tests.rs @@ -10,21 +10,25 @@ use crate::{ }, proof::{supernova::SuperNovaProver, RecursiveSNARKTrait}, public_parameters::{instance::Instance, supernova_public_params}, - state::user_sym, + state::State, + Symbol, }; #[test] fn test_nil_nil_lang() { use crate::coprocessor::test::NilNil; + let state = State::init_lurk_state().rccell(); + let mut lang = Lang::>::new(); - lang.add_coprocessor(user_sym("nil-nil"), NilNil::new()); + let name = Symbol::interned("nil-nil", state.clone()).unwrap(); + lang.add_coprocessor(name, NilNil::new()); let eval_config = EvalConfig::new_nivc(&lang); let lurk_step = make_eval_step_from_config(&eval_config); let cprocs = make_cprocs_funcs_from_lang(&lang); let store = Store::default(); - let expr = store.read_with_default_state("(nil-nil)").unwrap(); + let expr = store.read(state, "(nil-nil)").unwrap(); let frames = evaluate( Some((&lurk_step, &cprocs, &lang)), expr, diff --git a/src/symbol.rs b/src/symbol.rs index 7e68a922a..586172550 100644 --- a/src/symbol.rs +++ b/src/symbol.rs @@ -265,7 +265,8 @@ impl Symbol { } } - /// Attempts to parse and intern a `Symbol` from a string + /// Attempts to parse and intern a `Symbol` from its string representation, + /// creating unknown packages if necessary pub fn interned>(input: A, state: StateRcCell) -> Result { use crate::{parser::syntax::parse_symbol, syntax::Syntax}; use halo2curves::bn256::Fr; // could be any other field