Skip to content

Commit

Permalink
Support constant exponentiation in p3 (powdr-labs#1902)
Browse files Browse the repository at this point in the history
This turns `a**3` into `a * a * a` inside plonky3 instead of panicking.
cc @leonardoalt
  • Loading branch information
Schaeff authored Oct 14, 2024
1 parent f24c402 commit 83cba13
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions plonky3/src/circuit_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! every row.
use itertools::Itertools;
use p3_field::AbstractField;
use std::{
cell::RefCell,
collections::{BTreeMap, BTreeSet, HashMap},
Expand All @@ -26,7 +27,7 @@ use crate::{CallbackResult, MultiStageAir, MultistageAirBuilder, NextStageTraceC
use powdr_ast::parsed::visitor::ExpressionVisitable;

use powdr_executor::witgen::WitgenCallback;
use powdr_number::FieldElement;
use powdr_number::{FieldElement, LargeInt};

type Witness<T> = Mutex<RefCell<Vec<(String, Vec<T>)>>>;

Expand Down Expand Up @@ -220,6 +221,7 @@ where
publics: &BTreeMap<&String, <AB as AirBuilderWithPublicValues>::PublicVar>,
challenges: &BTreeMap<u32, BTreeMap<u64, <AB as MultistageAirBuilder>::Challenge>>,
) -> AB::Expr {
use AlgebraicBinaryOperator::*;
let res = match e {
AlgebraicExpression::Reference(r) => {
let poly_id = r.poly_id;
Expand All @@ -245,19 +247,37 @@ where
.expect("Referenced public value does not exist"))
.into(),
AlgebraicExpression::Number(n) => AB::Expr::from(n.into_p3_field()),
AlgebraicExpression::BinaryOperation(AlgebraicBinaryOperation {
left,
op: Pow,
right,
}) => match **right {
AlgebraicExpression::Number(n) => {
let left = self.to_plonky3_expr::<AB>(
left,
traces_by_stage,
fixed,
publics,
challenges,
);
(0u32..n.to_integer().try_into_u32().unwrap())
.fold(AB::Expr::from(<AB::F as AbstractField>::one()), |acc, _| {
acc * left.clone()
})
}
_ => unimplemented!("pow with non-constant exponent"),
},
AlgebraicExpression::BinaryOperation(AlgebraicBinaryOperation { left, op, right }) => {
let left =
self.to_plonky3_expr::<AB>(left, traces_by_stage, fixed, publics, challenges);
let right =
self.to_plonky3_expr::<AB>(right, traces_by_stage, fixed, publics, challenges);

match op {
AlgebraicBinaryOperator::Add => left + right,
AlgebraicBinaryOperator::Sub => left - right,
AlgebraicBinaryOperator::Mul => left * right,
AlgebraicBinaryOperator::Pow => {
unreachable!("exponentiations should have been evaluated")
}
Add => left + right,
Sub => left - right,
Mul => left * right,
Pow => unreachable!("This case was handled above"),
}
}
AlgebraicExpression::UnaryOperation(AlgebraicUnaryOperation { op, expr }) => {
Expand Down

0 comments on commit 83cba13

Please sign in to comment.