Skip to content

Commit

Permalink
compute the linear and angular coefficients
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurpaulino committed Dec 21, 2023
1 parent a9aa51e commit cbb9984
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 27 deletions.
84 changes: 58 additions & 26 deletions src/fib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! # fib
//! This module contains common definitions for fibonacci in benches and examples

use crate::{
eval::lang::{Coproc, Lang},
eval::lang::Coproc,
field::LurkField,
lem::{eval::{compute_frame, eval_step, evaluate_simple}, pointers::Ptr, store::Store},
lem::{eval::evaluate_simple, pointers::Ptr, store::Store},
};

pub fn fib_expr<F: LurkField>(store: &Store<F>) -> Ptr {
Expand All @@ -14,7 +17,7 @@ pub fn fib_expr<F: LurkField>(store: &Store<F>) -> Ptr {
store.read_with_default_state(program).unwrap()
}

const LIN_COEF: usize = 11;
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
Expand All @@ -29,21 +32,6 @@ pub fn fib_limit(n: usize, rc: usize) -> usize {
rc * (frame / rc + usize::from(frame % rc != 0))
}

pub fn compute_coeff<F: LurkField>(store: &Store<F>) -> (usize, usize) {
let mut input = vec![fib_expr(store), store.intern_nil(), store.cont_outermost()];
let lang: Lang<F, Coproc<F>> = Lang::new();
loop {
// TODO
let (frame, _) =
compute_frame(eval_step(), &[], &input, store, &lang, &mut vec![], 0).unwrap();

input = frame.output.clone();
let expr = frame.output[0];
break;
}
(0, 0)
}

pub fn lurk_fib<F: LurkField>(store: &Store<F>, n: usize) -> Ptr {
let frame_idx = fib_frame(n);
let limit = frame_idx;
Expand All @@ -53,15 +41,15 @@ pub fn lurk_fib<F: LurkField>(store: &Store<F>, n: usize) -> Ptr {

let target_env = &output[1];

// The result is the value of the second binding (of `A`), in the target env.
// The result is the value of the second binding (of `a`), in the target env.
// See relevant excerpt of execution trace below:
//
// INFO lurk::eval > Frame: 11
// Expr: (NEXT B (+ A B))
// Env: ((B . 1) (A . 0) ((NEXT . <FUNCTION (A) (LAMBDA (B) (NEXT B (+ A B)))>)))
// Cont: Tail{ saved_env: (((NEXT . <FUNCTION (A) (LAMBDA (B) (NEXT B (+ A B)))>))), continuation: LetRec{var: FIB,
// saved_env: (((NEXT . <FUNCTION (A) (LAMBDA (B) (NEXT B (+ A B)))>))), body: (FIB), continuation: Tail{ saved_env:
// NIL, continuation: Outermost } } }
// 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 . <FUNCTION (.lurk.user.a .lurk.user.b) (.lurk.user.next .lurk.user.b (+ .lurk.user.a .lurk.user.b))>)))
// Cont: LetRec{ var: .lurk.user.fib,
// saved_env: (((.lurk.user.next . <FUNCTION (.lurk.user.a .lurk.user.b) (.lurk.user.next .lurk.user.b (+ .lurk.user.a .lurk.user.b))>))),
// body: (.lurk.user.fib), continuation: Outermost }

let (_, rest_bindings) = store.car_cdr(target_env).unwrap();
let (second_binding, _) = store.car_cdr(&rest_bindings).unwrap();
Expand All @@ -70,14 +58,58 @@ pub fn lurk_fib<F: LurkField>(store: &Store<F>, n: usize) -> Ptr {

#[cfg(test)]
mod tests {
use crate::{lem::store::Store, fib::lurk_fib};
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<F: LurkField>(store: &Store<F>) -> (usize, usize) {
let mut input = vec![fib_expr(store), store.intern_nil(), store.cont_outermost()];
let lang: Lang<F, Coproc<F>> = 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::<pasta_curves::Fq>::default();
assert_eq!(compute_coeffs(&store), (LIN_COEF, ANG_COEF));
}

#[test]
fn test_fib_io_matches() {
let store = Store::<pasta_curves::Fq>::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));
}
}
2 changes: 1 addition & 1 deletion src/lem/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn get_pc<F: LurkField, C: Coprocessor<F>>(
}
}

pub fn compute_frame<F: LurkField, C: Coprocessor<F>>(
fn compute_frame<F: LurkField, C: Coprocessor<F>>(
lurk_step: &Func,
cprocs_run: &[Func],
input: &[Ptr],
Expand Down

0 comments on commit cbb9984

Please sign in to comment.