From bb6d6e34c204b1169aeda2df91ab73cfa6f9276d Mon Sep 17 00:00:00 2001 From: Arthur Paulino Date: Thu, 21 Dec 2023 19:27:57 -0300 Subject: [PATCH] fix structure --- benches/common/fib.rs | 106 ++++++++++++++++++++++++++++++++++++++ benches/common/mod.rs | 2 + benches/fibonacci.rs | 13 ++++- examples/fibonacci.rs | 13 ----- src/fib.rs | 115 ------------------------------------------ src/lib.rs | 1 - 6 files changed, 119 insertions(+), 131 deletions(-) create mode 100644 benches/common/fib.rs delete mode 100644 examples/fibonacci.rs delete mode 100644 src/fib.rs diff --git a/benches/common/fib.rs b/benches/common/fib.rs new file mode 100644 index 0000000000..bbe235fb3d --- /dev/null +++ b/benches/common/fib.rs @@ -0,0 +1,106 @@ +#![allow(dead_code)] + +use lurk::{ + eval::lang::{Coproc, Lang}, + field::LurkField, + lem::{ + eval::{eval_step, evaluate_simple}, + pointers::Ptr, + store::Store, + }, + state::user_sym, +}; + +pub(crate) fn fib_expr(store: &Store) -> Ptr { + let program = r#" +(letrec ((next (lambda (a b) (next b (+ a b)))) + (fib (next 0 1))) + (fib)) +"#; + + store.read_with_default_state(program).unwrap() +} + +const LIN_COEF: usize = 7; +const ANG_COEF: usize = 10; + +// The env output in the `fib_frame`th frame of the above, infinite Fibonacci computation contains a binding of the +// nth Fibonacci number to `a`. +pub(crate) fn fib_frame(n: usize) -> usize { + LIN_COEF + ANG_COEF * n +} + +// Set the limit so the last step will be filled exactly, since Lurk currently only pads terminal/error continuations. +pub(crate) fn fib_limit(n: usize, rc: usize) -> usize { + let frame = fib_frame(n); + rc * (frame / rc + usize::from(frame % rc != 0)) +} + +fn lurk_fib(store: &Store, n: usize) -> Ptr { + let frame_idx = fib_frame(n); + let limit = frame_idx; + let fib_expr = fib_expr(store); + + let (output, ..) = evaluate_simple::>(None, fib_expr, store, limit).unwrap(); + + let target_env = &output[1]; + + // The result is the value of the second binding (of `a`), in the target env. + // See relevant excerpt of execution trace below: + // + // INFO lurk::lem::eval: Frame: 7 + // Expr: (.lurk.user.next .lurk.user.b (+ .lurk.user.a .lurk.user.b)) + // Env: ((.lurk.user.b . 1) (.lurk.user.a . 0) ((.lurk.user.next . ))) + // Cont: LetRec{ var: .lurk.user.fib, + // saved_env: (((.lurk.user.next . ))), + // body: (.lurk.user.fib), continuation: Outermost } + + let (_, rest_bindings) = store.car_cdr(target_env).unwrap(); + let (second_binding, _) = store.car_cdr(&rest_bindings).unwrap(); + store.car_cdr(&second_binding).unwrap().1 +} + +// Returns the linear and angular coefficients for the iteration count of fib +fn compute_coeffs(store: &Store) -> (usize, usize) { + let mut input = vec![fib_expr(store), store.intern_nil(), store.cont_outermost()]; + let lang: Lang> = Lang::new(); + let mut coef_lin = 0; + let coef_ang; + let step_func = eval_step(); + let mut iteration = 0; + loop { + if let Some((elts, _)) = store.fetch_list(&input[0]) { + if store.fetch_symbol(&elts[0]) == Some(user_sym("next")) + && store.fetch_symbol(&elts[1]) == Some(user_sym("b")) + { + if coef_lin == 0 { + // first occurrence of `(next b ...)` + coef_lin = iteration; + } else { + // second occurrence of `(next b ...)` + coef_ang = iteration - coef_lin; + break; + } + } + } + let frame = step_func.call_simple(&input, store, &lang, 0).unwrap(); + input = frame.output.clone(); + iteration += 1; + } + (coef_lin, coef_ang) +} + +pub(crate) fn test_coeffs() { + let store = Store::::default(); + assert_eq!(compute_coeffs(&store), (LIN_COEF, ANG_COEF)); +} + +pub(crate) fn test_fib_io_matches() { + let store = Store::::default(); + let fib_9 = store.num_u64(34); + let fib_10 = store.num_u64(55); + let fib_11 = store.num_u64(89); + assert_eq!(fib_9, lurk_fib(&store, 9)); + assert_eq!(fib_10, lurk_fib(&store, 10)); + assert_eq!(fib_11, lurk_fib(&store, 11)); +} diff --git a/benches/common/mod.rs b/benches/common/mod.rs index 4e9a12145b..3a8c172a9c 100644 --- a/benches/common/mod.rs +++ b/benches/common/mod.rs @@ -1,3 +1,5 @@ +pub(crate) mod fib; + use camino::Utf8PathBuf; use lurk::cli::paths::lurk_default_dir; use lurk::config::lurk_config; diff --git a/benches/fibonacci.rs b/benches/fibonacci.rs index 7e4b831d4b..1a3b3f1711 100644 --- a/benches/fibonacci.rs +++ b/benches/fibonacci.rs @@ -8,7 +8,6 @@ use std::{sync::Arc, time::Duration}; use lurk::{ eval::lang::{Coproc, Lang}, - fib::{fib_expr, fib_frame, fib_limit}, lem::{eval::evaluate, multiframe::MultiFrame, store::Store}, proof::nova::NovaProver, proof::Prover, @@ -19,7 +18,12 @@ use lurk::{ }; mod common; -use common::set_bench_config; +use common::{ + fib::{fib_expr, fib_frame, fib_limit}, + set_bench_config, +}; + +use crate::common::fib::{test_coeffs, test_fib_io_matches}; #[derive(Clone, Debug, Copy)] struct ProveParams { @@ -126,9 +130,14 @@ fn fibonacci_prove( } fn fibonacci_benchmark(c: &mut Criterion) { + // Running tests to make sure the constants are correct + test_coeffs(); + test_fib_io_matches(); + // Uncomment to record the logs. May negatively impact performance //tracing_subscriber::fmt::init(); set_bench_config(); + tracing::debug!("{:?}", lurk::config::LURK_CONFIG); let reduction_counts = rc_env().unwrap_or_else(|_| vec![100]); diff --git a/examples/fibonacci.rs b/examples/fibonacci.rs deleted file mode 100644 index 97750fd143..0000000000 --- a/examples/fibonacci.rs +++ /dev/null @@ -1,13 +0,0 @@ -use pasta_curves::Fq; - -use lurk::{fib::lurk_fib, lem::store::Store, state::State}; - -fn main() { - let store = &Store::::default(); - let n: usize = std::env::args().collect::>()[1].parse().unwrap(); - let state = State::init_lurk_state(); - - let fib = lurk_fib(store, n); - - println!("Fib({n}) = {}", fib.fmt_to_string(store, &state)); -} diff --git a/src/fib.rs b/src/fib.rs deleted file mode 100644 index 6254c172b7..0000000000 --- a/src/fib.rs +++ /dev/null @@ -1,115 +0,0 @@ -//! # fib -//! This module contains common definitions for fibonacci in benches and examples - -use crate::{ - eval::lang::Coproc, - field::LurkField, - lem::{eval::evaluate_simple, pointers::Ptr, store::Store}, -}; - -pub fn fib_expr(store: &Store) -> Ptr { - let program = r#" -(letrec ((next (lambda (a b) (next b (+ a b)))) - (fib (next 0 1))) - (fib)) -"#; - - store.read_with_default_state(program).unwrap() -} - -const LIN_COEF: usize = 7; -const ANG_COEF: usize = 10; - -// The env output in the `fib_frame`th frame of the above, infinite Fibonacci computation contains a binding of the -// nth Fibonacci number to `a`. -pub fn fib_frame(n: usize) -> usize { - LIN_COEF + ANG_COEF * n -} - -// Set the limit so the last step will be filled exactly, since Lurk currently only pads terminal/error continuations. -pub fn fib_limit(n: usize, rc: usize) -> usize { - let frame = fib_frame(n); - rc * (frame / rc + usize::from(frame % rc != 0)) -} - -pub fn lurk_fib(store: &Store, n: usize) -> Ptr { - let frame_idx = fib_frame(n); - let limit = frame_idx; - let fib_expr = fib_expr(store); - - let (output, ..) = evaluate_simple::>(None, fib_expr, store, limit).unwrap(); - - let target_env = &output[1]; - - // The result is the value of the second binding (of `a`), in the target env. - // See relevant excerpt of execution trace below: - // - // INFO lurk::lem::eval: Frame: 7 - // Expr: (.lurk.user.next .lurk.user.b (+ .lurk.user.a .lurk.user.b)) - // Env: ((.lurk.user.b . 1) (.lurk.user.a . 0) ((.lurk.user.next . ))) - // Cont: LetRec{ var: .lurk.user.fib, - // saved_env: (((.lurk.user.next . ))), - // body: (.lurk.user.fib), continuation: Outermost } - - let (_, rest_bindings) = store.car_cdr(target_env).unwrap(); - let (second_binding, _) = store.car_cdr(&rest_bindings).unwrap(); - store.car_cdr(&second_binding).unwrap().1 -} - -#[cfg(test)] -mod tests { - use crate::{ - eval::lang::{Coproc, Lang}, - fib::{fib_expr, lurk_fib, ANG_COEF, LIN_COEF}, - field::LurkField, - lem::{eval::eval_step, store::Store}, - state::user_sym, - }; - - // Returns the linear and angular coefficients for the iteration count of fib - fn compute_coeffs(store: &Store) -> (usize, usize) { - let mut input = vec![fib_expr(store), store.intern_nil(), store.cont_outermost()]; - let lang: Lang> = Lang::new(); - let mut coef_lin = 0; - let coef_ang; - let step_func = eval_step(); - let mut i = 0; - loop { - if let Some((elts, _)) = store.fetch_list(&input[0]) { - if store.fetch_symbol(&elts[0]) == Some(user_sym("next")) - && store.fetch_symbol(&elts[1]) == Some(user_sym("b")) - { - if coef_lin == 0 { - // first occurrence of `(next b ...)` - coef_lin = i; - } else { - // second occurrence of `(next b ...)` - coef_ang = i - coef_lin; - break; - } - } - } - let frame = step_func.call_simple(&input, store, &lang, 0).unwrap(); - input = frame.output.clone(); - i += 1; - } - (coef_lin, coef_ang) - } - - #[test] - fn test_coeffs() { - let store = Store::::default(); - assert_eq!(compute_coeffs(&store), (LIN_COEF, ANG_COEF)); - } - - #[test] - fn test_fib_io_matches() { - let store = Store::::default(); - let fib_9 = store.num_u64(34); - let fib_10 = store.num_u64(55); - let fib_11 = store.num_u64(89); - assert_eq!(fib_9, lurk_fib(&store, 9)); - assert_eq!(fib_10, lurk_fib(&store, 10)); - assert_eq!(fib_11, lurk_fib(&store, 11)); - } -} diff --git a/src/lib.rs b/src/lib.rs index 20575d9578..47b5f72cca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,6 @@ pub mod config; pub mod coprocessor; pub mod error; pub mod eval; -pub mod fib; pub mod field; mod hash; pub mod lem;