Skip to content

Commit

Permalink
refactor(circuit)!: use challenge's index
Browse files Browse the repository at this point in the history
Make `ConstraintCircuit` less dependent on Triton VM specifics.

BREAKING CHANGE: Remove `CircuitExpression`'s dependency on
`ChallengeID`s, use their index directly instead.
  • Loading branch information
jan-ferdinand committed Mar 20, 2024
1 parent 9bbe963 commit e05e3ff
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 33 deletions.
6 changes: 1 addition & 5 deletions constraint-evaluation-generator/src/codegen/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ impl RustBackend {
use twenty_first::shared_math::mpolynomial::Degree;

use crate::table::challenges::Challenges;
use crate::table::challenges::ChallengeId::*;
use crate::table::extension_table::Evaluable;
use crate::table::extension_table::Quotientable;
use crate::table::master_table::MasterExtTable;
Expand Down Expand Up @@ -321,10 +320,7 @@ impl RustBackend {
CircuitExpression::BConstant(bfe) => Self::tokenize_bfe(*bfe),
CircuitExpression::XConstant(xfe) => Self::tokenize_xfe(*xfe),
CircuitExpression::Input(idx) => quote!(#idx),
CircuitExpression::Challenge(challenge) => {
let challenge_ident = format_ident!("{challenge}");
quote!(challenges[#challenge_ident])
}
CircuitExpression::Challenge(challenge) => quote!(challenges[#challenge]),
CircuitExpression::BinaryOperation(_, _, _) => {
let node_ident = format_ident!("node_{}", circuit.id);
quote!(#node_ident)
Expand Down
2 changes: 1 addition & 1 deletion constraint-evaluation-generator/src/codegen/tasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ impl TasmBackend {
CircuitExpression::BConstant(bfe) => Self::load_ext_field_constant(bfe.into()),
CircuitExpression::XConstant(xfe) => Self::load_ext_field_constant(xfe),
CircuitExpression::Input(input) => Self::load_input(input),
CircuitExpression::Challenge(challenge) => Self::load_challenge(challenge.index()),
CircuitExpression::Challenge(challenge_idx) => Self::load_challenge(challenge_idx),
CircuitExpression::BinaryOperation(_, _, _) => Self::load_evaluated_bin_op(circuit.id),
}
}
Expand Down
19 changes: 6 additions & 13 deletions constraint-evaluation-generator/src/substitution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,13 @@ impl AllSubstitutions {
let num_new_ext_cols = self.ext.len();

// A zero-variant enum cannot be annotated with `repr(usize)`.
let base_repr_usize = match num_new_base_cols == 0 {
true => quote!(),
false => quote!(#[repr(usize)]),
let base_repr_usize = match num_new_base_cols {
0 => quote!(),
_ => quote!(#[repr(usize)]),
};
let ext_repr_usize = match num_new_ext_cols == 0 {
true => quote!(),
false => quote!(#[repr(usize)]),
};
let use_challenge_ids = match num_new_ext_cols == 0 {
true => quote!(),
false => quote!(
use crate::table::challenges::ChallengeId::*;
),
let ext_repr_usize = match num_new_ext_cols {
0 => quote!(),
_ => quote!(#[repr(usize)]),
};

let base_columns = (0..num_new_base_cols)
Expand Down Expand Up @@ -81,7 +75,6 @@ impl AllSubstitutions {
use twenty_first::prelude::BFieldElement;
use twenty_first::prelude::XFieldElement;

#use_challenge_ids
use crate::table::challenges::Challenges;
use crate::table::master_table::NUM_BASE_COLUMNS;
use crate::table::master_table::NUM_EXT_COLUMNS;
Expand Down
47 changes: 44 additions & 3 deletions triton-vm/src/table/challenges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ impl ChallengeId {
}
}

impl From<ChallengeId> for usize {
fn from(id: ChallengeId) -> Self {
id.index()
}
}

/// The `Challenges` struct holds the challenges used in Triton VM. The concrete challenges are
/// known only at runtime. The challenges are indexed using enum [`ChallengeId`]. The `Challenges`
/// struct is essentially a thin wrapper around an array of [`XFieldElement`]s, providing
Expand Down Expand Up @@ -286,27 +292,51 @@ impl Challenges {
}
}

impl Index<usize> for Challenges {
type Output = XFieldElement;

fn index(&self, id: usize) -> &Self::Output {
&self.challenges[id]
}
}

impl Index<Range<usize>> for Challenges {
type Output = [XFieldElement];

fn index(&self, indices: Range<usize>) -> &Self::Output {
&self.challenges[indices.start..indices.end]
}
}

impl Index<RangeInclusive<usize>> for Challenges {
type Output = [XFieldElement];

fn index(&self, indices: RangeInclusive<usize>) -> &Self::Output {
&self.challenges[*indices.start()..=*indices.end()]
}
}

impl Index<ChallengeId> for Challenges {
type Output = XFieldElement;

fn index(&self, id: ChallengeId) -> &Self::Output {
&self.challenges[id.index()]
&self[id.index()]
}
}

impl Index<Range<ChallengeId>> for Challenges {
type Output = [XFieldElement];

fn index(&self, indices: Range<ChallengeId>) -> &Self::Output {
&self.challenges[indices.start.index()..indices.end.index()]
&self[indices.start.index()..indices.end.index()]
}
}

impl Index<RangeInclusive<ChallengeId>> for Challenges {
type Output = [XFieldElement];

fn index(&self, indices: RangeInclusive<ChallengeId>) -> &Self::Output {
&self.challenges[indices.start().index()..=indices.end().index()]
&self[indices.start().index()..=indices.end().index()]
}
}

Expand Down Expand Up @@ -361,4 +391,15 @@ pub(crate) mod tests {

// Ensure the compile-time assertions are actually executed by the compiler.
const _: () = compile_time_index_assertions();

#[test]
fn various_challenge_indexing_operations_are_possible() {
let challenges = Challenges::placeholder(&Claim::default());
let _ = challenges[HashStateWeight0];
let _ = challenges[HashStateWeight0..HashStateWeight8];
let _ = challenges[HashStateWeight0..=HashStateWeight8];
let _ = challenges[0];
let _ = challenges[0..8];
let _ = challenges[0..=8];
}
}
21 changes: 10 additions & 11 deletions triton-vm/src/table/constraint_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@ use num_traits::One;
use num_traits::Zero;
use quote::quote;
use quote::ToTokens;
use strum::IntoEnumIterator;
use twenty_first::prelude::*;
use twenty_first::shared_math::mpolynomial::Degree;

use CircuitExpression::*;

use crate::table::challenges::ChallengeId;
use crate::table::challenges::Challenges;

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -268,7 +266,7 @@ pub enum CircuitExpression<II: InputIndicator> {
BConstant(BFieldElement),
XConstant(XFieldElement),
Input(II),
Challenge(ChallengeId),
Challenge(usize),
BinaryOperation(
BinOp,
Rc<RefCell<ConstraintCircuit<II>>>,
Expand Down Expand Up @@ -361,8 +359,8 @@ impl<II: InputIndicator> Display for ConstraintCircuit<II> {
write!(f, "{bfe}")
}
Input(input) => write!(f, "{input} "),
Challenge(self_challenge_id) => {
write!(f, "#{self_challenge_id}")
Challenge(self_challenge_idx) => {
write!(f, "{self_challenge_idx}")
}
BinaryOperation(operation, lhs, rhs) => {
write!(f, "({}) {operation} ({})", lhs.borrow(), rhs.borrow())
Expand Down Expand Up @@ -522,7 +520,7 @@ impl<II: InputIndicator> ConstraintCircuit<II> {
BConstant(bfe) => bfe.lift(),
XConstant(xfe) => *xfe,
Input(input) => input.evaluate(base_table, ext_table),
Challenge(challenge_id) => challenges[*challenge_id],
Challenge(challenge_id) => challenges.challenges[*challenge_id],
BinaryOperation(binop, lhs, rhs) => {
let lhs_value = lhs.borrow().evaluate(base_table, ext_table, challenges);
let rhs_value = rhs.borrow().evaluate(base_table, ext_table, challenges);
Expand Down Expand Up @@ -996,8 +994,11 @@ impl<II: InputIndicator> ConstraintCircuitBuilder<II> {
}

/// Create challenge leaf node.
pub fn challenge(&self, challenge_id: ChallengeId) -> ConstraintCircuitMonad<II> {
self.make_leaf(Challenge(challenge_id))
pub fn challenge<C>(&self, challenge: C) -> ConstraintCircuitMonad<II>
where
C: Into<usize>,
{
self.make_leaf(Challenge(challenge.into()))
}

fn make_leaf(&self, mut expression: CircuitExpression<II>) -> ConstraintCircuitMonad<II> {
Expand Down Expand Up @@ -1071,10 +1072,9 @@ fn random_circuit_leaf<'a, II: InputIndicator + Arbitrary<'a>>(
builder: &ConstraintCircuitBuilder<II>,
u: &mut Unstructured<'a>,
) -> arbitrary::Result<ConstraintCircuitMonad<II>> {
let challenge_ids = ChallengeId::iter().collect_vec();
let leaf = match u.int_in_range(0..=5)? {
0 => builder.input(u.arbitrary()?),
1 => builder.challenge(*u.choose(&challenge_ids)?),
1 => builder.challenge(u.arbitrary::<usize>()?),
2 => builder.b_constant(u.arbitrary::<BFieldElement>()?),
3 => builder.x_constant(u.arbitrary::<XFieldElement>()?),
4 => builder.one(),
Expand Down Expand Up @@ -1125,7 +1125,6 @@ mod tests {
use test_strategy::proptest;

use crate::table::cascade_table::ExtCascadeTable;
use crate::table::challenges::Challenges;
use crate::table::constraint_circuit::SingleRowIndicator::*;
use crate::table::degree_lowering_table::DegreeLoweringTable;
use crate::table::hash_table::ExtHashTable;
Expand Down

0 comments on commit e05e3ff

Please sign in to comment.