From aff7ff1c579d86cb6e71870cbf22a5f6a530954d Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 29 Sep 2023 12:23:50 +0200 Subject: [PATCH 1/3] Do not treat constants specially during parsing. --- asm_to_pil/src/vm_to_constrained.rs | 1 - ast/src/parsed/display.rs | 1 - ast/src/parsed/mod.rs | 2 -- ast/src/parsed/visitor.rs | 2 -- backend/src/pilstark/json_exporter/mod.rs | 5 ----- executor/src/witgen/expression_evaluator.rs | 3 --- halo2/src/circuit_builder.rs | 3 --- parser/src/powdr.lalrpop | 2 +- pil_analyzer/src/evaluator.rs | 1 - pil_analyzer/src/pil_analyzer.rs | 3 +-- pilopt/src/lib.rs | 6 ++---- 11 files changed, 4 insertions(+), 25 deletions(-) diff --git a/asm_to_pil/src/vm_to_constrained.rs b/asm_to_pil/src/vm_to_constrained.rs index 19ed3916e..995fbddc7 100644 --- a/asm_to_pil/src/vm_to_constrained.rs +++ b/asm_to_pil/src/vm_to_constrained.rs @@ -575,7 +575,6 @@ impl ASMPILConverter { value: Expression, ) -> Vec<(T, AffineExpressionComponent)> { match value { - Expression::Constant(_) => panic!(), Expression::PublicReference(_) => panic!(), Expression::FunctionCall(_) => panic!(), Expression::Reference(reference) => { diff --git a/ast/src/parsed/display.rs b/ast/src/parsed/display.rs index 24c16eb5f..e4cf0706d 100644 --- a/ast/src/parsed/display.rs +++ b/ast/src/parsed/display.rs @@ -423,7 +423,6 @@ pub fn format_expressions(expressions: &[Expression Display for Expression { fn fmt(&self, f: &mut Formatter<'_>) -> Result { match self { - Expression::Constant(name) => write!(f, "{name}"), Expression::Reference(reference) => write!(f, "{reference}"), Expression::PublicReference(name) => write!(f, ":{name}"), Expression::Number(value) => write!(f, "{value}"), diff --git a/ast/src/parsed/mod.rs b/ast/src/parsed/mod.rs index d96cf9ab2..472cb8795 100644 --- a/ast/src/parsed/mod.rs +++ b/ast/src/parsed/mod.rs @@ -67,8 +67,6 @@ impl Default for SelectedExpressions { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum Expression> { - /// Reference to a constant, "%ConstantName" - Constant(String), Reference(Ref), PublicReference(String), Number(T), diff --git a/ast/src/parsed/visitor.rs b/ast/src/parsed/visitor.rs index 9059daa45..c28829617 100644 --- a/ast/src/parsed/visitor.rs +++ b/ast/src/parsed/visitor.rs @@ -114,7 +114,6 @@ impl ExpressionVisitable> for Expression { } match self { Expression::Reference(_) - | Expression::Constant(_) | Expression::PublicReference(_) | Expression::Number(_) | Expression::String(_) => {} @@ -152,7 +151,6 @@ impl ExpressionVisitable> for Expression { } match self { Expression::Reference(_) - | Expression::Constant(_) | Expression::PublicReference(_) | Expression::Number(_) | Expression::String(_) => {} diff --git a/backend/src/pilstark/json_exporter/mod.rs b/backend/src/pilstark/json_exporter/mod.rs index 333db0a29..3de8c7506 100644 --- a/backend/src/pilstark/json_exporter/mod.rs +++ b/backend/src/pilstark/json_exporter/mod.rs @@ -235,11 +235,6 @@ impl<'a, T: FieldElement> Exporter<'a, T> { /// returns the degree and the JSON value (intermediate polynomial IDs) fn expression_to_json(&self, expr: &Expression) -> (u32, StarkyExpr) { match expr { - Expression::Constant(name) => { - panic!( - "Constant {name} was not inlined. optimize_constants needs to be run at least." - ) - } Expression::Reference(analyzed::Reference::Poly(reference)) => { self.polynomial_reference_to_json(reference) } diff --git a/executor/src/witgen/expression_evaluator.rs b/executor/src/witgen/expression_evaluator.rs index 30c12cf15..e45b97b3b 100644 --- a/executor/src/witgen/expression_evaluator.rs +++ b/executor/src/witgen/expression_evaluator.rs @@ -37,9 +37,6 @@ where // @TODO if we iterate on processing the constraints in the same row, // we could store the simplified values. match expr { - Expression::Constant(name) => { - panic!("Constants should have been replaced, but {name} is still there.") - } Expression::Reference(Reference::Poly(poly)) => self.variables.value(poly), Expression::Number(n) => Ok((*n).into()), Expression::BinaryOperation(left, op, right) => { diff --git a/halo2/src/circuit_builder.rs b/halo2/src/circuit_builder.rs index fcfc5e6ab..71a0ab2ef 100644 --- a/halo2/src/circuit_builder.rs +++ b/halo2/src/circuit_builder.rs @@ -256,9 +256,6 @@ fn expression_2_expr(cd: &CircuitData, expr: &Expression) _ => unimplemented!("{:?}", expr), } } - Expression::Constant(name) => { - panic!("Constant {name} was not inlined. optimize_constants needs to be run at least.") - } _ => unimplemented!("{:?}", expr), } diff --git a/parser/src/powdr.lalrpop b/parser/src/powdr.lalrpop index 723b90bd3..d96319a8d 100644 --- a/parser/src/powdr.lalrpop +++ b/parser/src/powdr.lalrpop @@ -462,7 +462,7 @@ UnaryOp: UnaryOperator = { Term: Box> = { FunctionCall => Box::new(Expression::FunctionCall(<>)), - ConstantIdentifier => Box::new(Expression::Constant(<>)), + ConstantIdentifier => Box::new(Expression::Reference(PolynomialReference::new(<>).single().local().current())), ShiftedPolynomialReference => Box::new(Expression::Reference(<>)), PublicReference => Box::new(Expression::PublicReference(<>)), FieldElement => Box::new(Expression::Number(<>)), diff --git a/pil_analyzer/src/evaluator.rs b/pil_analyzer/src/evaluator.rs index 357315f1a..a88505b06 100644 --- a/pil_analyzer/src/evaluator.rs +++ b/pil_analyzer/src/evaluator.rs @@ -32,7 +32,6 @@ pub struct Evaluator<'a, T> { impl<'a, T: FieldElement> Evaluator<'a, T> { pub fn evaluate(&self, expr: &Expression) -> Result { match expr { - Expression::Constant(name) => Ok(self.constants[name]), Expression::Reference(Reference::LocalVar(i, _name)) => Ok(self.variables[*i as usize]), Expression::Reference(Reference::Poly(poly)) => { if !poly.next && poly.index.is_none() { diff --git a/pil_analyzer/src/pil_analyzer.rs b/pil_analyzer/src/pil_analyzer.rs index 0eb2d548b..6f173a191 100644 --- a/pil_analyzer/src/pil_analyzer.rs +++ b/pil_analyzer/src/pil_analyzer.rs @@ -51,7 +51,7 @@ struct PILAnalyzer { macro_expander: MacroExpander, } -impl From> for Analyzed { +impl From> for Analyzed { fn from( PILAnalyzer { constants, @@ -560,7 +560,6 @@ impl<'a, T: FieldElement> ExpressionProcessor<'a, T> { pub fn process_expression(&mut self, expr: parsed::Expression) -> Expression { use parsed::Expression as PExpression; match expr { - PExpression::Constant(name) => Expression::Constant(name), PExpression::Reference(poly) => { if poly.namespace().is_none() && self.local_variables.contains_key(poly.name()) { let id = self.local_variables[poly.name()]; diff --git a/pilopt/src/lib.rs b/pilopt/src/lib.rs index 65138db22..9b37436c5 100644 --- a/pilopt/src/lib.rs +++ b/pilopt/src/lib.rs @@ -46,16 +46,14 @@ pub fn optimize_constants(mut pil_file: Analyzed) -> Analyze /// Inlines references to symbols with a single constant value. fn inline_constant_values(pil_file: &mut Analyzed) { let constants = &pil_file.constants.clone(); - pil_file.post_visit_expressions_mut(&mut |e| match e { - Expression::Reference(Reference::Poly(poly)) => { + pil_file.post_visit_expressions_mut(&mut |e| { + if let Expression::Reference(Reference::Poly(poly)) = e { if !poly.next && poly.index.is_none() { if let Some(value) = constants.get(&poly.name) { *e = Expression::Number(*value) } } } - Expression::Constant(name) => *e = Expression::Number(constants[name]), - _ => {} }); } From 1e81bb36ac477dc2079fd6125e74a2afb9917021 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sat, 30 Sep 2023 00:11:53 +0200 Subject: [PATCH 2/3] Move constants to generic definitions. --- ast/src/analyzed/display.rs | 33 ++++---- ast/src/analyzed/mod.rs | 28 ++++--- backend/src/pilstark/json_exporter/mod.rs | 18 +++-- executor/src/constant_evaluator/mod.rs | 2 - pil_analyzer/src/evaluator.rs | 38 +++++---- pil_analyzer/src/pil_analyzer.rs | 93 +++++++++++++---------- pilopt/src/lib.rs | 3 +- 7 files changed, 126 insertions(+), 89 deletions(-) diff --git a/ast/src/analyzed/display.rs b/ast/src/analyzed/display.rs index 6b020f49a..93dc9f1f4 100644 --- a/ast/src/analyzed/display.rs +++ b/ast/src/analyzed/display.rs @@ -11,28 +11,25 @@ use super::*; impl Display for Analyzed { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - for (name, value) in &self.constants { - writeln!(f, "constant {name} = {value};")?; - } - - let mut namespace = "Global".to_string(); + let mut current_namespace = "Global".to_string(); let mut update_namespace = |name: &str, degree: DegreeType, f: &mut Formatter<'_>| { - if let Some(dot) = name.find('.') { - if name[..dot] != namespace { - namespace = name[..dot].to_string(); - writeln!(f, "namespace {namespace}({degree});")?; + let new_name = if let Some(dot) = name.find('.') { + if name[..dot] != current_namespace { + current_namespace = name[..dot].to_string(); + writeln!(f, "namespace {current_namespace}({degree});")?; } - Ok(name[dot + 1..].to_string()) + &name[dot + 1..] } else { - Ok(name.to_string()) - } + name + }; + Ok((new_name.to_string(), ¤t_namespace != "Global")) }; for statement in &self.source_order { match statement { StatementIdentifier::Definition(name) => { let (symbol, definition) = &self.definitions[name]; - let name = update_namespace(name, symbol.degree, f)?; + let (name, is_local) = update_namespace(name, symbol.degree, f)?; match symbol.kind { SymbolKind::Poly(poly_type) => { let kind = match &poly_type { @@ -47,6 +44,14 @@ impl Display for Analyzed { writeln!(f, ";")? } } + SymbolKind::Constant() => { + let indentation = if is_local { " " } else { "" }; + writeln!( + f, + "{indentation}constant {name}{};", + definition.as_ref().unwrap() + )?; + } SymbolKind::Other() => { write!(f, " let {name}")?; if let Some(value) = definition { @@ -59,7 +64,7 @@ impl Display for Analyzed { StatementIdentifier::PublicDeclaration(name) => { let decl = &self.public_declarations[name]; // TODO we do not know the degree of the namespace here. - let name = update_namespace(&decl.name, 0, f)?; + let (name, _) = update_namespace(&decl.name, 0, f)?; writeln!( f, " public {name} = {}({});", diff --git a/ast/src/analyzed/mod.rs b/ast/src/analyzed/mod.rs index 9c37d3c76..0b4e37c0e 100644 --- a/ast/src/analyzed/mod.rs +++ b/ast/src/analyzed/mod.rs @@ -25,8 +25,6 @@ pub enum StatementIdentifier { #[derive(Debug)] pub struct Analyzed { - /// Constants are not namespaced! - pub constants: HashMap, pub definitions: HashMap>)>, pub public_declarations: HashMap, pub identities: Vec>>, @@ -141,7 +139,9 @@ impl Analyzed { let mut names_to_remove: HashSet = Default::default(); self.definitions.retain(|name, (poly, _def)| { - if to_remove.contains(&(poly as &Symbol).into()) { + if matches!(poly.kind, SymbolKind::Poly(_)) + && to_remove.contains(&(poly as &Symbol).into()) + { names_to_remove.insert(name.clone()); false } else { @@ -157,15 +157,18 @@ impl Analyzed { true }); self.definitions.values_mut().for_each(|(poly, _def)| { - let poly_id = PolyID::from(poly as &Symbol); - assert!(!to_remove.contains(&poly_id)); - poly.id = replacements[&poly_id].id; + if matches!(poly.kind, SymbolKind::Poly(_)) { + let poly_id = PolyID::from(poly as &Symbol); + assert!(!to_remove.contains(&poly_id)); + poly.id = replacements[&poly_id].id; + } }); self.pre_visit_expressions_mut(&mut |expr| { if let Expression::Reference(Reference::Poly(poly)) = expr { - let poly_id = poly.poly_id.unwrap(); - assert!(!to_remove.contains(&poly_id)); - poly.poly_id = Some(replacements[&poly_id]); + poly.poly_id = poly.poly_id.map(|poly_id| { + assert!(!to_remove.contains(&poly_id)); + replacements[&poly_id] + }); } }); } @@ -240,11 +243,16 @@ impl Symbol { } } +/// The "kind" of a symbol. In the future, this will be mostly +/// replaced by its type. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum SymbolKind { /// Fixed, witness or intermediate polynomial Poly(PolynomialType), - /// Other symbol, could be a constant, depends on the type. + /// A constant value. + Constant(), + /// Other symbol, depends on the type. + /// Examples include functions not of the type "int -> fe". Other(), } diff --git a/backend/src/pilstark/json_exporter/mod.rs b/backend/src/pilstark/json_exporter/mod.rs index 3de8c7506..76fd48573 100644 --- a/backend/src/pilstark/json_exporter/mod.rs +++ b/backend/src/pilstark/json_exporter/mod.rs @@ -145,6 +145,7 @@ fn symbol_kind_to_json_string(k: SymbolKind) -> &'static str { match k { SymbolKind::Poly(poly_type) => polynomial_type_to_json_string(poly_type), SymbolKind::Other() => panic!("Cannot translate \"other\" symbol to json."), + SymbolKind::Constant() => unreachable!(), } } @@ -183,12 +184,15 @@ impl<'a, T: FieldElement> Exporter<'a, T> { self.analyzed .definitions .iter() - .map(|(name, (symbol, _value))| { - let id = if symbol.kind == SymbolKind::Poly(PolynomialType::Intermediate) { - self.intermediate_poly_expression_ids[&symbol.id] - } else { - symbol.id - }; + .filter_map(|(name, (symbol, _value))| { + let id = match symbol.kind { + SymbolKind::Poly(PolynomialType::Intermediate) => { + Some(self.intermediate_poly_expression_ids[&symbol.id]) + } + SymbolKind::Poly(_) => Some(symbol.id), + SymbolKind::Other() | SymbolKind::Constant() => None, + }?; + let out = Reference { polType: None, type_: symbol_kind_to_json_string(symbol.kind).to_string(), @@ -198,7 +202,7 @@ impl<'a, T: FieldElement> Exporter<'a, T> { elementType: None, len: symbol.length.map(|l| l as usize), }; - (name.clone(), out) + Some((name.clone(), out)) }) .collect::>() } diff --git a/executor/src/constant_evaluator/mod.rs b/executor/src/constant_evaluator/mod.rs index bfeab5e13..6bf3cd6c6 100644 --- a/executor/src/constant_evaluator/mod.rs +++ b/executor/src/constant_evaluator/mod.rs @@ -41,7 +41,6 @@ fn generate_values( .into_par_iter() .map(|i| { Evaluator { - constants: &analyzed.constants, definitions: &analyzed.definitions, variables: &[i.into()], function_cache: other_constants, @@ -52,7 +51,6 @@ fn generate_values( .collect(), FunctionValueDefinition::Array(values) => { let evaluator = Evaluator { - constants: &analyzed.constants, definitions: &analyzed.definitions, variables: &[], function_cache: other_constants, diff --git a/pil_analyzer/src/evaluator.rs b/pil_analyzer/src/evaluator.rs index a88505b06..ec6651dd3 100644 --- a/pil_analyzer/src/evaluator.rs +++ b/pil_analyzer/src/evaluator.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use ast::{ - analyzed::{Analyzed, Expression, FunctionValueDefinition, Reference, Symbol}, + analyzed::{Analyzed, Expression, FunctionValueDefinition, Reference, Symbol, SymbolKind}, evaluate_binary_operation, evaluate_unary_operation, parsed::{FunctionCall, MatchArm, MatchPattern}, }; @@ -13,7 +13,6 @@ pub fn evaluate_expression( expression: &Expression, ) -> Result { Evaluator { - constants: &analyzed.constants, definitions: &analyzed.definitions, function_cache: &Default::default(), variables: &[], @@ -21,8 +20,26 @@ pub fn evaluate_expression( .evaluate(expression) } +/// Returns a HashMap of all symbols that have a constant single value. +pub fn compute_constants(analyzed: &Analyzed) -> HashMap { + analyzed + .definitions + .iter() + .filter_map(|(name, (symbol, value))| { + (symbol.kind == SymbolKind::Constant()).then(|| { + let Some(FunctionValueDefinition::Expression(value)) = value else { + panic!() + }; + ( + name.to_owned(), + evaluate_expression(analyzed, value).unwrap(), + ) + }) + }) + .collect() +} + pub struct Evaluator<'a, T> { - pub constants: &'a HashMap, pub definitions: &'a HashMap>)>, /// Contains full value tables of functions (columns) we already evaluated. pub function_cache: &'a HashMap<&'a str, Vec>, @@ -35,17 +52,10 @@ impl<'a, T: FieldElement> Evaluator<'a, T> { Expression::Reference(Reference::LocalVar(i, _name)) => Ok(self.variables[*i as usize]), Expression::Reference(Reference::Poly(poly)) => { if !poly.next && poly.index.is_none() { - let name = poly.name.to_owned(); - if let Some(value) = self.constants.get(&name) { - Ok(*value) - } else { - let (_, value) = &self.definitions[&name]; - match value { - Some(FunctionValueDefinition::Expression(value)) => { - self.evaluate(value) - } - _ => Err("Cannot evaluate function values".to_string()), - } + let (_, value) = &self.definitions[&poly.name.to_string()]; + match value { + Some(FunctionValueDefinition::Expression(value)) => self.evaluate(value), + _ => Err("Cannot evaluate function-typed values".to_string()), } } else { Err("Cannot evaluate arrays or next references.".to_string()) diff --git a/pil_analyzer/src/pil_analyzer.rs b/pil_analyzer/src/pil_analyzer.rs index 6f173a191..39f3ddb20 100644 --- a/pil_analyzer/src/pil_analyzer.rs +++ b/pil_analyzer/src/pil_analyzer.rs @@ -35,8 +35,6 @@ pub fn process_pil_file_contents(contents: &str) -> Analyzed struct PILAnalyzer { namespace: String, polynomial_degree: DegreeType, - /// Constants are not namespaced! - constants: HashMap, definitions: HashMap>)>, public_declarations: HashMap, identities: Vec>>, @@ -54,7 +52,6 @@ struct PILAnalyzer { impl From> for Analyzed { fn from( PILAnalyzer { - constants, definitions, public_declarations, identities, @@ -66,9 +63,7 @@ impl From> for Analyzed { .iter() .map(|(name, (poly, _))| (name.clone(), poly.clone())) .collect::>(); - let constant_names = constants.keys().cloned().collect::>(); let mut result = Self { - constants, definitions, public_declarations, identities, @@ -78,13 +73,13 @@ impl From> for Analyzed { let poly = ids .get(&reference.name) .unwrap_or_else(|| panic!("Column {} not found.", reference.name)); - reference.poly_id = Some(poly.into()); + if let SymbolKind::Poly(_) = &poly.kind { + reference.poly_id = Some(poly.into()); + } }; result.pre_visit_expressions_mut(&mut |e| { if let Expression::Reference(Reference::Poly(reference)) = e { - if !constant_names.contains(&reference.name) { - assign_id(reference); - } + assign_id(reference); } }); result @@ -103,6 +98,7 @@ impl PILAnalyzer { SymbolKind::Poly(PolynomialType::Committed), SymbolKind::Poly(PolynomialType::Constant), SymbolKind::Poly(PolynomialType::Intermediate), + SymbolKind::Constant(), SymbolKind::Other(), ] .into_iter() @@ -196,8 +192,18 @@ impl PILAnalyzer { Some(definition), ); } - PilStatement::ConstantDefinition(_start, name, value) => { - self.handle_constant_definition(name, self.evaluate_expression(value).unwrap()) + PilStatement::ConstantDefinition(start, name, value) => { + // Check it is a constant. + if let Err(err) = self.evaluate_expression(value.clone()) { + panic!("Could not evaluate constant: {name} = {value}: {err}"); + } + self.handle_polynomial_definition( + self.to_source_ref(start), + name, + None, + SymbolKind::Constant(), + Some(FunctionDefinition::Expression(value)), + ); } PilStatement::LetStatement(start, name, value) => { self.handle_generic_definition(start, name, value) @@ -256,19 +262,20 @@ impl PILAnalyzer { ); } _ => { - if let Ok(constant) = self.evaluate_expression(value.clone()) { + let symbol_kind = if self.evaluate_expression(value.clone()).is_ok() { // Value evaluates to a constant number => treat it as a constant - self.handle_constant_definition(name.to_string(), constant); + SymbolKind::Constant() } else { // Otherwise, treat it as "generic definition" - self.handle_polynomial_definition( - self.to_source_ref(start), - name, - None, - SymbolKind::Other(), - Some(FunctionDefinition::Expression(value)), - ); - } + SymbolKind::Other() + }; + self.handle_polynomial_definition( + self.to_source_ref(start), + name, + None, + symbol_kind, + Some(FunctionDefinition::Expression(value)), + ); } } } @@ -375,7 +382,12 @@ impl PILAnalyzer { let counter = self.symbol_counters.get_mut(&symbol_kind).unwrap(); let id = *counter; *counter += length.unwrap_or(1); - let absolute_name = self.namespaced(&name); + let absolute_name = if symbol_kind == SymbolKind::Constant() { + // Constants are not namespaced. + name.to_owned() + } else { + self.prepend_current_namespace(&name) + }; let symbol = Symbol { id, source, @@ -391,6 +403,7 @@ impl PILAnalyzer { assert!(!have_array_size); assert!( symbol_kind == SymbolKind::Other() + || symbol_kind == SymbolKind::Constant() || symbol_kind == SymbolKind::Poly(PolynomialType::Intermediate) ); FunctionValueDefinition::Expression(self.process_expression(expr)) @@ -453,11 +466,6 @@ impl PILAnalyzer { .push(StatementIdentifier::PublicDeclaration(name)); } - fn handle_constant_definition(&mut self, name: String, value: T) { - let is_new = self.constants.insert(name.to_string(), value).is_none(); - assert!(is_new, "Constant {name} was defined twice."); - } - fn dispense_id(&mut self, kind: IdentityKind) -> u64 { let cnt = self.identity_counter.entry(kind).or_default(); let id = *cnt; @@ -465,12 +473,12 @@ impl PILAnalyzer { id } - pub fn namespaced(&self, name: &str) -> String { - self.namespaced_ref(&None, name) + fn prepend_current_namespace(&self, name: &str) -> String { + format!("{}.{name}", self.namespace) } - fn namespaced_ref(&self, namespace: &Option, name: &str) -> String { - if name.starts_with('%') || (namespace.is_none() && self.constants.contains_key(name)) { + pub fn namespaced_ref_to_absolute(&self, namespace: &Option, name: &str) -> String { + if name.starts_with('%') || self.definitions.contains_key(&name.to_string()) { assert!(namespace.is_none()); // Constants are not namespaced name.to_string() @@ -481,7 +489,6 @@ impl PILAnalyzer { fn evaluate_expression(&self, expr: ::ast::parsed::Expression) -> Result { Evaluator { - constants: &self.constants, definitions: &self.definitions, function_cache: &Default::default(), variables: &[], @@ -594,7 +601,7 @@ impl<'a, T: FieldElement> ExpressionProcessor<'a, T> { Expression::UnaryOperation(op, Box::new(self.process_expression(*value))) } PExpression::FunctionCall(c) => Expression::FunctionCall(parsed::FunctionCall { - id: self.analyzer.namespaced(&c.id), + id: self.analyzer.namespaced_ref_to_absolute(&None, &c.id), arguments: self.process_expressions(c.arguments), }), PExpression::MatchExpression(scrutinee, arms) => Expression::MatchExpression( @@ -651,7 +658,9 @@ impl<'a, T: FieldElement> ExpressionProcessor<'a, T> { .as_ref() .map(|i| self.analyzer.evaluate_expression(*i.clone()).unwrap()) .map(|i| i.to_degree()); - let name = self.analyzer.namespaced_ref(poly.namespace(), poly.name()); + let name = self + .analyzer + .namespaced_ref_to_absolute(poly.namespace(), poly.name()); PolynomialReference { name, poly_id: None, @@ -851,18 +860,20 @@ namespace T(65536); #[test] fn let_definitions() { - let input = r#"namespace N(65536); + let input = r#"constant %r = 65536; +namespace N(%r); let x; - let t = |i| i + 1; - let z = 7; - let other = [1, 2]; + let z = 2; + let t = |i| i + z; + let other = [1, z]; let other_fun = |i, j| (i + 7, (|k| k - i)); "#; - let expected = r#"constant z = 7; + let expected = r#"constant %r = 65536; namespace N(65536); col witness x; - col fixed t(i) { (i + 1) }; - let other = [1, 2]; + constant z = 2; + col fixed t(i) { (i + z) }; + let other = [1, z]; let other_fun = |i, j| ((i + 7), |k| (k - i)); "#; let formatted = process_pil_file_contents::(input).to_string(); diff --git a/pilopt/src/lib.rs b/pilopt/src/lib.rs index 9b37436c5..b99acb82f 100644 --- a/pilopt/src/lib.rs +++ b/pilopt/src/lib.rs @@ -13,6 +13,7 @@ use ast::parsed::visitor::ExpressionVisitable; use ast::parsed::UnaryOperator; use ast::{evaluate_binary_operation, evaluate_unary_operation}; use number::FieldElement; +use pil_analyzer::evaluator::compute_constants; pub fn optimize(mut pil_file: Analyzed) -> Analyzed { let col_count_pre = (pil_file.commitment_count(), pil_file.constant_count()); @@ -45,7 +46,7 @@ pub fn optimize_constants(mut pil_file: Analyzed) -> Analyze /// Inlines references to symbols with a single constant value. fn inline_constant_values(pil_file: &mut Analyzed) { - let constants = &pil_file.constants.clone(); + let constants = compute_constants(pil_file); pil_file.post_visit_expressions_mut(&mut |e| { if let Expression::Reference(Reference::Poly(poly)) = e { if !poly.next && poly.index.is_none() { From 764ef2db0b94d5ac8a2f4626492904c0ba8bb57e Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 4 Oct 2023 17:55:10 +0200 Subject: [PATCH 3/3] Rename function. --- pil_analyzer/src/pil_analyzer.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pil_analyzer/src/pil_analyzer.rs b/pil_analyzer/src/pil_analyzer.rs index 39f3ddb20..0432f1483 100644 --- a/pil_analyzer/src/pil_analyzer.rs +++ b/pil_analyzer/src/pil_analyzer.rs @@ -149,7 +149,7 @@ impl PILAnalyzer { PilStatement::Include(_, include) => self.handle_include(include), PilStatement::Namespace(_, name, degree) => self.handle_namespace(name, degree), PilStatement::PolynomialDefinition(start, name, value) => { - self.handle_polynomial_definition( + self.handle_symbol_definition( self.to_source_ref(start), name, None, @@ -167,7 +167,7 @@ impl PILAnalyzer { PolynomialType::Constant, ), PilStatement::PolynomialConstantDefinition(start, name, definition) => { - self.handle_polynomial_definition( + self.handle_symbol_definition( self.to_source_ref(start), name, None, @@ -184,7 +184,7 @@ impl PILAnalyzer { PilStatement::PolynomialCommitDeclaration(start, mut polynomials, Some(definition)) => { assert!(polynomials.len() == 1); let name = polynomials.pop().unwrap(); - self.handle_polynomial_definition( + self.handle_symbol_definition( self.to_source_ref(start), name.name, name.array_size, @@ -197,7 +197,7 @@ impl PILAnalyzer { if let Err(err) = self.evaluate_expression(value.clone()) { panic!("Could not evaluate constant: {name} = {value}: {err}"); } - self.handle_polynomial_definition( + self.handle_symbol_definition( self.to_source_ref(start), name, None, @@ -238,7 +238,7 @@ impl PILAnalyzer { match value { None => { // No value provided => treat it as a witness column. - self.handle_polynomial_definition( + self.handle_symbol_definition( self.to_source_ref(start), name, None, @@ -253,7 +253,7 @@ impl PILAnalyzer { body, }) if params.len() == 1 => { // Assigned value is a lambda expression with a single parameter => treat it as a fixed column. - self.handle_polynomial_definition( + self.handle_symbol_definition( self.to_source_ref(start), name, None, @@ -269,7 +269,7 @@ impl PILAnalyzer { // Otherwise, treat it as "generic definition" SymbolKind::Other() }; - self.handle_polynomial_definition( + self.handle_symbol_definition( self.to_source_ref(start), name, None, @@ -354,7 +354,7 @@ impl PILAnalyzer { polynomial_type: PolynomialType, ) { for PolynomialName { name, array_size } in polynomials { - self.handle_polynomial_definition( + self.handle_symbol_definition( source.clone(), name, array_size, @@ -364,7 +364,7 @@ impl PILAnalyzer { } } - fn handle_polynomial_definition( + fn handle_symbol_definition( &mut self, source: SourceRef, name: String,