Skip to content

Commit

Permalink
feat: log builtin (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
katat authored Sep 27, 2024
1 parent 09451d3 commit 19dedf6
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
28 changes: 27 additions & 1 deletion src/backends/r1cs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,38 @@ impl CellVar {

impl<F: BackendField> BackendVar for LinearCombination<F> {}

impl<F: BackendField> std::fmt::Debug for LinearCombination<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// format the linear combination as a single string
let mut lc = String::new();
for (i, (var, factor)) in self.terms.iter().enumerate() {
if i > 0 {
lc.push_str(" + ");
}

// format the factor
let factor = factor.pretty();
match factor.as_str() {
"1" => lc.push_str(&format!("v_{}", var.index)),
_ => lc.push_str(&format!("{} * v_{}", factor, var.index)),
}
}
// constant
if self.constant != F::zero() {
lc.push_str(&format!(" + {}", self.constant.pretty()));
}

// Write the formatted string to the formatter
write!(f, "{}", lc)
}
}

/// Linear combination of variables and constants.
/// For example, the linear combination is represented as a * f_a + b * f_b + f_c
/// f_a and f_b are the coefficients of a and b respectively.
/// a and b are represented by CellVar.
/// The constant f_c is represented by the constant field, will always multiply with the variable at index 0 which is always 1.
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, PartialEq, Eq)]
pub struct LinearCombination<F>
where
F: BackendField,
Expand Down
39 changes: 37 additions & 2 deletions src/stdlib/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,33 @@ use crate::{
circuit_writer::{CircuitWriter, VarInfo},
constants::Span,
error::{Error, ErrorKind, Result},
helpers::PrettyField,
parser::types::{GenericParameters, TyKind},
var::{ConstOrCell, Var},
};

use super::{FnInfoType, Module};

pub const QUALIFIED_BUILTINS: &str = "std/builtins";
pub const BUILTIN_FN_NAMES: [&str; 2] = ["assert", "assert_eq"];
pub const BUILTIN_FN_NAMES: [&str; 3] = ["assert", "assert_eq", "log"];

const ASSERT_FN: &str = "assert(condition: Bool)";
const ASSERT_EQ_FN: &str = "assert_eq(lhs: Field, rhs: Field)";
// todo: currently only supports a single field var
// to support all the types, we can bypass the type check for this log function for now
const LOG_FN: &str = "log(var: Field)";

pub struct BuiltinsLib {}

impl Module for BuiltinsLib {
const MODULE: &'static str = "builtins";

fn get_fns<B: Backend>() -> Vec<(&'static str, FnInfoType<B>)> {
vec![(ASSERT_FN, assert_fn), (ASSERT_EQ_FN, assert_eq_fn)]
vec![
(ASSERT_FN, assert_fn),
(ASSERT_EQ_FN, assert_eq_fn),
(LOG_FN, log_fn),
]
}
}

Expand Down Expand Up @@ -121,3 +129,30 @@ fn assert_fn<B: Backend>(

Ok(None)
}

/// Logging
fn log_fn<B: Backend>(
compiler: &mut CircuitWriter<B>,
generics: &GenericParameters,
vars: &[VarInfo<B::Field, B::Var>],
span: Span,
) -> Result<Option<Var<B::Field, B::Var>>> {
println!("---log span: {:?}---", span);
for var in vars {
// typ
println!("typ: {:?}", var.typ);
// mutable
println!("mutable: {:?}", var.mutable);
// var
var.var.iter().for_each(|v| match v {
ConstOrCell::Const(cst) => {
println!("cst: {:?}", cst.pretty());
}
ConstOrCell::Cell(cvar) => {
println!("cvar: {:?}", cvar);
}
});
}

Ok(None)
}

0 comments on commit 19dedf6

Please sign in to comment.