This commit is contained in:
schaeff
2023-03-28 23:27:07 +02:00
parent eb0eac4f55
commit fa66f1ee13
4 changed files with 24 additions and 62 deletions

View File

@@ -3,7 +3,7 @@ use std::fs;
use std::path::{Path, PathBuf};
use crate::number::{abstract_to_degree, DegreeType};
use crate::parser::ast::{self, ArrayExpression, Repetition};
use crate::parser::ast::{self, ArrayExpression};
pub use crate::parser::ast::{BinaryOperator, UnaryOperator};
use crate::{parser, utils};
@@ -342,8 +342,8 @@ impl PILContext {
}
}
ast::FunctionDefinition::Array(value) => {
let expressions = self
.process_array_expression(&value.clone().concretize(self.polynomial_degree));
let star_value = value.solve(self.polynomial_degree);
let expressions = self.process_array_expression(value, star_value);
assert_eq!(expressions.len() as u64, self.polynomial_degree);
FunctionValueDefinition::Array(expressions)
}
@@ -438,17 +438,21 @@ impl PILContext {
}
}
fn process_array_expression(&mut self, array_expression: &ArrayExpression) -> Vec<Expression> {
fn process_array_expression(
&mut self,
array_expression: &ArrayExpression,
star_value: Option<DegreeType>,
) -> Vec<Expression> {
match array_expression {
ArrayExpression::RepeatedValue(expressions, Repetition::Concrete(times)) => (0..*times)
ArrayExpression::Value(expressions) => self.process_expressions(expressions),
ArrayExpression::RepeatedValue(expressions) => (0..star_value.unwrap())
.flat_map(|_| self.process_expressions(expressions))
.collect(),
ArrayExpression::Concat(left, right) => self
.process_array_expression(left)
.process_array_expression(left, star_value)
.into_iter()
.chain(self.process_array_expression(right))
.chain(self.process_array_expression(right, star_value))
.collect(),
_ => unreachable!("The repetitions should have a concrete value, found *"),
}
}

View File

@@ -98,17 +98,18 @@ pub enum FunctionDefinition {
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ArrayExpression {
RepeatedValue(Vec<Expression>, Repetition),
Value(Vec<Expression>),
RepeatedValue(Vec<Expression>),
Concat(Box<ArrayExpression>, Box<ArrayExpression>),
}
impl ArrayExpression {
pub fn value(v: Vec<Expression>) -> Self {
Self::RepeatedValue(v, Repetition::Concrete(1))
Self::Value(v)
}
pub fn repeated_value(v: Vec<Expression>) -> Self {
Self::RepeatedValue(v, Repetition::Star)
Self::RepeatedValue(v)
}
pub fn concat(self, other: Self) -> Self {
@@ -125,7 +126,7 @@ impl ArrayExpression {
impl ArrayExpression {
/// solve for `*`
fn solve(&self, degree: DegreeType) -> Option<DegreeType> {
pub fn solve(&self, degree: DegreeType) -> Option<DegreeType> {
// the length of this expression is `a + b*x`
let (a, b) = self.len();
// it must match `degree`, and we solve for `x`
@@ -140,8 +141,8 @@ impl ArrayExpression {
/// find the total length of an array expression as an affine expression: `a + b*x`
fn len(&self) -> (DegreeType, DegreeType) {
match self {
ArrayExpression::RepeatedValue(e, Repetition::Star) => (0, e.len() as u64),
ArrayExpression::RepeatedValue(e, Repetition::Concrete(r)) => (e.len() as u64 * r, 0),
ArrayExpression::RepeatedValue(e) => (0, e.len() as u64),
ArrayExpression::Value(e) => (e.len() as u64, 0),
ArrayExpression::Concat(left, right) => {
let (a0, b0) = left.len();
let (a1, b1) = right.len();
@@ -155,38 +156,4 @@ impl ArrayExpression {
}
}
}
// replace `*` by a concrete value `star_value`
fn concretize_aux(self, star_value: DegreeType) -> Self {
match self {
ArrayExpression::RepeatedValue(value, repetition) => {
Self::RepeatedValue(value, repetition.concretize(star_value))
}
ArrayExpression::Concat(left, right) => left
.concretize(star_value)
.concat(right.concretize(star_value)),
}
}
pub fn concretize(self, degree: DegreeType) -> Self {
match self.solve(degree) {
Some(star_value) => self.concretize_aux(star_value),
None => self,
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Repetition {
Concrete(u64),
Star,
}
impl Repetition {
fn concretize(self, star_value: DegreeType) -> Self {
match self {
Repetition::Star => Repetition::Concrete(star_value),
r => r,
}
}
}

View File

@@ -91,26 +91,17 @@ fn format_names(names: &[PolynomialName]) -> String {
impl Display for ArrayExpression {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
ArrayExpression::RepeatedValue(expressions, Repetition::Concrete(1)) => {
ArrayExpression::Value(expressions) => {
write!(f, "[{}]", format_expressions(expressions))
}
ArrayExpression::RepeatedValue(expressions, r) => {
write!(f, "[{}]{}", format_expressions(expressions), r)
ArrayExpression::RepeatedValue(expressions) => {
write!(f, "[{}]*", format_expressions(expressions))
}
ArrayExpression::Concat(left, right) => write!(f, "({} + {})", left, right),
}
}
}
impl Display for Repetition {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
Repetition::Concrete(v) => write!(f, "*{{{}}}", v),
Repetition::Star => write!(f, "*"),
}
}
}
impl Display for FunctionDefinition {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {

View File

@@ -330,8 +330,8 @@ PublicReference: String = {
}
ArrayExpression: ArrayExpression = {
"[" <ExpressionList> "]" => ArrayExpression::RepeatedValue(<>, Repetition::Concrete(1)),
"[" <ExpressionList> "]" "*" => ArrayExpression::RepeatedValue(<>, Repetition::Star),
"[" <ExpressionList> "]" => ArrayExpression::value(<>),
"[" <ExpressionList> "]" "*" => ArrayExpression::repeated_value(<>),
"(" <ArrayExpression> "+" <ArrayExpression> ")" => ArrayExpression::concat(<>),
}