Skip to content

Commit

Permalink
refactor(circuit)!: no Challenges in evaluate
Browse files Browse the repository at this point in the history
Make `ConstraintCircuit` less dependent on Triton VM specifics:
Remove the dependency on the `Challenges` struct to evaluate a
`ConstraintCircuit`. Instead, use a slice of `XFieldElement`s.
  • Loading branch information
jan-ferdinand committed Mar 20, 2024
1 parent e05e3ff commit 15a8cd7
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 810 deletions.
126 changes: 109 additions & 17 deletions triton-vm/src/stark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,6 @@ pub(crate) mod tests {
use crate::prelude::Program;
use crate::program::NonDeterminism;
use crate::shared_tests::*;
use crate::table::cascade_table;
use crate::table::cascade_table::ExtCascadeTable;
use crate::table::challenges::ChallengeId::LookupTablePublicTerminal;
use crate::table::challenges::ChallengeId::StandardInputIndeterminate;
Expand All @@ -1101,19 +1100,13 @@ pub(crate) mod tests {
use crate::table::extension_table;
use crate::table::extension_table::Evaluable;
use crate::table::extension_table::Quotientable;
use crate::table::hash_table;
use crate::table::hash_table::ExtHashTable;
use crate::table::jump_stack_table;
use crate::table::jump_stack_table::ExtJumpStackTable;
use crate::table::lookup_table;
use crate::table::lookup_table::ExtLookupTable;
use crate::table::master_table::MasterExtTable;
use crate::table::master_table::TableId;
use crate::table::op_stack_table;
use crate::table::op_stack_table::ExtOpStackTable;
use crate::table::processor_table;
use crate::table::processor_table::ExtProcessorTable;
use crate::table::program_table;
use crate::table::program_table::ExtProgramTable;
use crate::table::ram_table;
use crate::table::ram_table::ExtRamTable;
Expand All @@ -1126,7 +1119,6 @@ pub(crate) mod tests {
use crate::table::table_column::ProcessorExtTableColumn::OutputTableEvalArg;
use crate::table::table_column::RamBaseTableColumn;
use crate::table::tasm_air_constraints::air_constraint_evaluation_tasm;
use crate::table::u32_table;
use crate::table::u32_table::ExtU32Table;
use crate::table::MemoryRegion;
use crate::table::TasmConstraintEvaluationMemoryLayout;
Expand Down Expand Up @@ -1662,6 +1654,7 @@ pub(crate) mod tests {
let master_ext_trace_table = master_ext_table.trace_table();
let last_master_base_row = master_base_trace_table.slice(s![-1.., ..]);
let last_master_ext_row = master_ext_trace_table.slice(s![-1.., ..]);
let challenges = challenges.challenges;

for (i, constraint) in terminal_constraints.iter().enumerate() {
let evaluation =
Expand Down Expand Up @@ -2080,6 +2073,105 @@ pub(crate) mod tests {
);
}

macro_rules! check_constraints_fn {
(fn $fn_name:ident for $table:ident) => {
fn $fn_name(
master_base_trace_table: ArrayView2<BFieldElement>,
master_ext_trace_table: ArrayView2<XFieldElement>,
challenges: &Challenges,
) {
assert!(master_base_trace_table.nrows() == master_ext_trace_table.nrows());
let challenges = &challenges.challenges;

let builder = ConstraintCircuitBuilder::new();
for (constraint_idx, constraint) in $table::initial_constraints(&builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![..1, ..]),
master_ext_trace_table.slice(s![..1, ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"{}: Initial constraint {constraint_idx} failed.",
stringify!($table),
);
}

let builder = ConstraintCircuitBuilder::new();
for (constraint_idx, constraint) in $table::consistency_constraints(&builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
for row_idx in 0..master_base_trace_table.nrows() {
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![row_idx..=row_idx, ..]),
master_ext_trace_table.slice(s![row_idx..=row_idx, ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"{}: Consistency constraint {constraint_idx} failed on row {row_idx}.",
stringify!($table),
);
}
}

let builder = ConstraintCircuitBuilder::new();
for (constraint_idx, constraint) in $table::transition_constraints(&builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
for row_idx in 0..master_base_trace_table.nrows() - 1 {
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![row_idx..=row_idx + 1, ..]),
master_ext_trace_table.slice(s![row_idx..=row_idx + 1, ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"{}: Transition constraint {constraint_idx} failed on row {row_idx}.",
stringify!($table),
);
}
}

let builder = ConstraintCircuitBuilder::new();
for (constraint_idx, constraint) in $table::terminal_constraints(&builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![-1.., ..]),
master_ext_trace_table.slice(s![-1.., ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"{}: Terminal constraint {constraint_idx} failed.",
stringify!($table),
);
}
}
};
}

check_constraints_fn!(fn check_program_table_constraints for ExtProgramTable);
check_constraints_fn!(fn check_processor_table_constraints for ExtProcessorTable);
check_constraints_fn!(fn check_op_stack_table_constraints for ExtOpStackTable);
check_constraints_fn!(fn check_ram_table_constraints for ExtRamTable);
check_constraints_fn!(fn check_jump_stack_table_constraints for ExtJumpStackTable);
check_constraints_fn!(fn check_hash_table_constraints for ExtHashTable);
check_constraints_fn!(fn check_cascade_table_constraints for ExtCascadeTable);
check_constraints_fn!(fn check_lookup_table_constraints for ExtLookupTable);
check_constraints_fn!(fn check_u32_table_constraints for ExtU32Table);

fn triton_constraints_evaluate_to_zero(program_and_input: ProgramAndInput) {
let (_, _, master_base_table, master_ext_table, challenges) =
master_tables_for_low_security_level(program_and_input);
Expand All @@ -2092,15 +2184,15 @@ pub(crate) mod tests {
let met = master_ext_table.trace_table();
assert!(mbt.nrows() == met.nrows());

program_table::tests::check_constraints(mbt, met, &challenges);
processor_table::tests::check_constraints(mbt, met, &challenges);
op_stack_table::tests::check_constraints(mbt, met, &challenges);
ram_table::tests::check_constraints(mbt, met, &challenges);
jump_stack_table::tests::check_constraints(mbt, met, &challenges);
hash_table::tests::check_constraints(mbt, met, &challenges);
cascade_table::tests::check_constraints(mbt, met, &challenges);
lookup_table::tests::check_constraints(mbt, met, &challenges);
u32_table::tests::check_constraints(mbt, met, &challenges);
check_program_table_constraints(mbt, met, &challenges);
check_processor_table_constraints(mbt, met, &challenges);
check_op_stack_table_constraints(mbt, met, &challenges);
check_ram_table_constraints(mbt, met, &challenges);
check_jump_stack_table_constraints(mbt, met, &challenges);
check_hash_table_constraints(mbt, met, &challenges);
check_cascade_table_constraints(mbt, met, &challenges);
check_lookup_table_constraints(mbt, met, &challenges);
check_u32_table_constraints(mbt, met, &challenges);
}

#[test]
Expand Down
91 changes: 0 additions & 91 deletions triton-vm/src/table/cascade_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,94 +307,3 @@ impl ExtCascadeTable {
vec![]
}
}

#[cfg(test)]
pub(crate) mod tests {
use assert2::assert;
use assert2::check;

use super::*;

pub fn check_constraints(
master_base_trace_table: ArrayView2<BFieldElement>,
master_ext_trace_table: ArrayView2<XFieldElement>,
challenges: &Challenges,
) {
assert!(master_base_trace_table.nrows() == master_ext_trace_table.nrows());

let circuit_builder = ConstraintCircuitBuilder::new();

for (constraint_idx, constraint) in ExtCascadeTable::initial_constraints(&circuit_builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![..1, ..]),
master_ext_trace_table.slice(s![..1, ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"Initial constraint {constraint_idx} failed."
);
}

let circuit_builder = ConstraintCircuitBuilder::new();
for (constraint_idx, constraint) in
ExtCascadeTable::consistency_constraints(&circuit_builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
for row_idx in 0..master_base_trace_table.nrows() {
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![row_idx..=row_idx, ..]),
master_ext_trace_table.slice(s![row_idx..=row_idx, ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"Consistency constraint {constraint_idx} failed on row {row_idx}."
);
}
}

let circuit_builder = ConstraintCircuitBuilder::new();
for (constraint_idx, constraint) in
ExtCascadeTable::transition_constraints(&circuit_builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
for row_idx in 0..master_base_trace_table.nrows() - 1 {
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![row_idx..=row_idx + 1, ..]),
master_ext_trace_table.slice(s![row_idx..=row_idx + 1, ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"Transition constraint {constraint_idx} failed on row {row_idx}."
);
}
}

let circuit_builder = ConstraintCircuitBuilder::new();
for (constraint_idx, constraint) in ExtCascadeTable::terminal_constraints(&circuit_builder)
.into_iter()
.map(|constraint_monad| constraint_monad.consume())
.enumerate()
{
let evaluated_constraint = constraint.evaluate(
master_base_trace_table.slice(s![-1.., ..]),
master_ext_trace_table.slice(s![-1.., ..]),
challenges,
);
check!(
xfe!(0) == evaluated_constraint,
"Terminal constraint {constraint_idx} failed."
);
}
}
}
15 changes: 8 additions & 7 deletions triton-vm/src/table/constraint_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ use twenty_first::shared_math::mpolynomial::Degree;

use CircuitExpression::*;

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

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum BinOp {
Add,
Expand Down Expand Up @@ -514,13 +512,13 @@ impl<II: InputIndicator> ConstraintCircuit<II> {
&self,
base_table: ArrayView2<BFieldElement>,
ext_table: ArrayView2<XFieldElement>,
challenges: &Challenges,
challenges: &[XFieldElement],
) -> XFieldElement {
match &self.expression {
BConstant(bfe) => bfe.lift(),
XConstant(xfe) => *xfe,
Input(input) => input.evaluate(base_table, ext_table),
Challenge(challenge_id) => challenges.challenges[*challenge_id],
Challenge(challenge_id) => 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 @@ -1125,6 +1123,7 @@ 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 Expand Up @@ -1276,7 +1275,7 @@ mod tests {
/// The employed method is the Schwartz-Zippel lemma.
fn evaluate_assert_unique<II: InputIndicator>(
constraint: &ConstraintCircuit<II>,
challenges: &Challenges,
challenges: &[XFieldElement],
base_rows: ArrayView2<BFieldElement>,
ext_rows: ArrayView2<XFieldElement>,
values: &mut HashMap<XFieldElement, (usize, ConstraintCircuit<II>)>,
Expand Down Expand Up @@ -1322,6 +1321,7 @@ mod tests {
let challenges: [XFieldElement; Challenges::SAMPLE_COUNT] = rng.gen();
let challenges = challenges.to_vec();
let challenges = Challenges::new(challenges, &dummy_claim);
let challenges = &challenges.challenges;

let num_rows = 2;
let base_shape = [num_rows, NUM_BASE_COLUMNS];
Expand All @@ -1333,7 +1333,7 @@ mod tests {

let mut values = HashMap::new();
for c in constraints {
evaluate_assert_unique(c, &challenges, base_rows, ext_rows, &mut values);
evaluate_assert_unique(c, challenges, base_rows, ext_rows, &mut values);
}

let circuit_degree = constraints.iter().map(|c| c.degree()).max().unwrap_or(-1);
Expand Down Expand Up @@ -1969,6 +1969,7 @@ mod tests {
let challenges: [XFieldElement; Challenges::SAMPLE_COUNT] = rng.gen();
let challenges = challenges.to_vec();
let challenges = Challenges::new(challenges, &dummy_claim);
let challenges = &challenges.challenges;

let num_rows = 2;
let num_new_base_constraints = new_base_constraints.len();
Expand All @@ -1984,7 +1985,7 @@ mod tests {

let evaluated_substitution_rules = substitution_rules
.iter()
.map(|c| c.evaluate(base_rows, ext_rows, &challenges));
.map(|c| c.evaluate(base_rows, ext_rows, challenges));

let mut values_to_index = HashMap::new();
for (idx, value) in evaluated_substitution_rules.enumerate() {
Expand Down
Loading

0 comments on commit 15a8cd7

Please sign in to comment.