From 4fd0100770e1e50dbd5b7caa75eb87215607bd3e Mon Sep 17 00:00:00 2001 From: Dhole Date: Mon, 6 Mar 2023 01:29:27 +0100 Subject: [PATCH] WIP --- src/analyze.rs | 79 +++++++++++++++++++++++++++----------------------- src/expr.rs | 4 +-- src/plaf.rs | 37 ++++++++++++++++++++++- 3 files changed, 81 insertions(+), 39 deletions(-) diff --git a/src/analyze.rs b/src/analyze.rs index b600008..9fffc61 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -1,4 +1,4 @@ -use crate::expr::{Ex, Expr}; +use crate::expr::{Expr, Var}; use num_bigint::{BigInt, BigUint, Sign}; use num_traits::{cast::ToPrimitive, One, Zero}; @@ -108,11 +108,11 @@ pub struct Attrs { } #[derive(Debug)] -pub struct Analysis { - pub vars_attrs: HashMap, +pub struct Analysis { + pub vars_attrs: HashMap, } -impl Analysis { +impl Analysis { pub fn new() -> Self { Self { vars_attrs: HashMap::new(), @@ -129,7 +129,7 @@ fn to_biguint(c: BigInt, p: &BigUint) -> BigUint { } } -pub fn find_bounds_poly(e: &Ex, p: &BigUint, analysis: &mut Analysis) { +pub fn find_bounds_poly(e: &Expr, p: &BigUint, analysis: &mut Analysis) { let (exhaustive, solutions_list) = find_solutions(e); let mut solutions = HashMap::new(); if exhaustive { @@ -140,6 +140,11 @@ pub fn find_bounds_poly(e: &Ex, p: &BigUint, analysis: &mut Analysis) { .or_insert(vec![value.clone()]); } } + // If there are several exhaustive solutions but they involve different variables, we can't + // bound any variable. + if solutions.keys().count() > 1 { + solutions = HashMap::new(); + } let bound_base = Bound::new_range(BigUint::zero(), p.clone() - BigUint::one()); for var in e.vars().iter() { let bound = match solutions.get(var) { @@ -154,49 +159,51 @@ pub fn find_bounds_poly(e: &Ex, p: &BigUint, analysis: &mut Analysis) { } } -// Attempt to find solutions to `e(X) == 0` by matching on the pattern `(x - A)(y - B)...`. -// Returns true when the solutions returned are exhaustive. -pub fn find_solutions(e: &Ex) -> (bool, Vec<(String, BigInt)>) { +fn find_solutions_base(e: &Expr) -> (bool, Vec<(V, BigInt)>) { use Expr::*; - fn find_solutions_base(e: &Ex) -> (bool, Vec<(String, BigInt)>) { - match e { - Const(_) => (true, Vec::new()), - Var(v) => (true, vec![(v.clone(), BigInt::zero())]), - Neg(e) => find_solutions_base(e), - Sum(es) => { - let mut var: Option = None; - let mut con: Option = None; - let mut neg = false; - for e in es { - match (e, &var, &con) { + match e { + Const(_) => (true, Vec::new()), + Var(v) => (true, vec![(v.clone(), BigInt::zero())]), + Neg(e) => find_solutions_base(e), + Sum(es) => { + let mut var: Option = None; + let mut con: Option = None; + let mut neg = false; + for e in es { + match (e, &var, &con) { + (Const(c), _, None) => { + neg ^= true; + con = Some(c.clone().into()); + } + (Var(v), None, _) => { + var = Some(v.clone()); + } + (Neg(e), _, _) => match (&**e, &var, &con) { (Const(c), _, None) => { - neg ^= true; con = Some(c.clone().into()); } (Var(v), None, _) => { + neg ^= true; var = Some(v.clone()); } - (Neg(e), _, _) => match (&**e, &var, &con) { - (Const(c), _, None) => { - con = Some(c.clone().into()); - } - (Var(v), None, _) => { - neg ^= true; - var = Some(v.clone()); - } - _ => return (false, Vec::new()), - }, _ => return (false, Vec::new()), - } + }, + _ => return (false, Vec::new()), } - if neg { - con = Some(-con.unwrap()); - } - (true, vec![(var.unwrap(), con.unwrap())]) } - _ => (false, Vec::new()), + if neg { + con = Some(-con.unwrap()); + } + (true, vec![(var.unwrap(), con.unwrap())]) } + _ => (false, Vec::new()), } +} + +// Attempt to find solutions to `e(X) == 0` by matching on the pattern `(x - A)(y - B)...`. +// Returns true when the solutions returned are exhaustive. +pub fn find_solutions(e: &Expr) -> (bool, Vec<(V, BigInt)>) { + use Expr::*; match e { Mul(es) => { let mut exhaustive = true; diff --git a/src/expr.rs b/src/expr.rs index 15526c1..1ebd87d 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -23,7 +23,7 @@ use std::{ // fn is_one(&self) -> bool; // } -pub trait Var: Clone + Debug + PartialEq {} +pub trait Var: Clone + Debug + PartialEq + Eq + Hash + Ord + Display {} impl Var for &'static str {} impl Var for String {} @@ -315,7 +315,7 @@ fn mul(lhs: BigUint, rhs: &BigUint, p: &BigUint) -> BigUint { (lhs * rhs).mod_floor(p) } -impl Expr { +impl Expr { pub fn eval(&self, p: &BigUint, vars: &HashMap) -> BigUint { use Expr::*; match self { diff --git a/src/plaf.rs b/src/plaf.rs index b28d35e..df147d2 100644 --- a/src/plaf.rs +++ b/src/plaf.rs @@ -1,4 +1,4 @@ -use crate::expr::{self, ColumnKind, Expr, PlonkVar as Var}; +use crate::expr::{self, Column, ColumnKind, Expr, PlonkVar as Var}; use num_bigint::BigUint; use std::fmt::{self, Debug, Display, Write}; @@ -170,6 +170,41 @@ pub struct Plaf { pub fixed: Vec>>, } +pub struct VarDisplay<'a> { + pub v: &'a Var, + pub plaf: &'a Plaf, +} + +impl Display for VarDisplay<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use ColumnKind::*; + use Var::*; + match self.v { + ColumnQuery { + column: Column { kind, index }, + rotation, + } => { + write!( + f, + "{}", + match kind { + Witness => self.plaf.columns.witness[*index].name(), + Public => self.plaf.columns.public[*index].name(), + Fixed => self.plaf.columns.fixed[*index].name(), + }, + )?; + if *rotation != 0 { + write!(f, "[{}]", rotation)?; + } + } + Challenge { index, phase: _ } => { + write!(f, "{}", self.plaf.info.challenges[*index].name())? + } + } + Ok(()) + } +} + impl Plaf { pub fn fmt_column(&self, f: &mut W, c: &expr::Column) -> fmt::Result { use ColumnKind::*;