use crate::expression::{Expression, Variable};
use crate::poly::Rotation;
use crate::{lookup, permutation, shuffle};
use ff::Field;
use std::collections::HashMap;
use std::fmt;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct ChallengeMid {
pub index: usize,
pub phase: u8,
}
impl ChallengeMid {
pub fn index(&self) -> usize {
self.index
}
pub fn phase(&self) -> u8 {
self.phase
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct QueryMid {
pub column_index: usize,
pub column_type: Any,
pub rotation: Rotation,
}
impl QueryMid {
pub fn new(column_type: Any, column_index: usize, rotation: Rotation) -> Self {
Self {
column_index,
column_type,
rotation,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum VarMid {
Query(QueryMid),
Challenge(ChallengeMid),
}
impl fmt::Display for VarMid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VarMid::Query(query) => {
match query.column_type {
Any::Fixed => write!(f, "f")?,
Any::Advice => write!(f, "a")?,
Any::Instance => write!(f, "i")?,
};
write!(f, "{}", query.column_index)?;
if query.rotation.0 != 0 {
write!(f, "[{}]", query.rotation.0)?;
}
Ok(())
}
VarMid::Challenge(challenge) => {
write!(f, "ch{}", challenge.index())
}
}
}
}
impl Variable for VarMid {
fn degree(&self) -> usize {
match self {
VarMid::Query(_) => 1,
VarMid::Challenge(_) => 0,
}
}
fn complexity(&self) -> usize {
match self {
VarMid::Query(_) => 1,
VarMid::Challenge(_) => 0,
}
}
fn write_identifier<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
write!(writer, "{}", self)
}
}
pub type ExpressionMid<F> = Expression<F, VarMid>;
#[derive(Clone, Debug)]
pub struct Gate<F: Field, V: Variable> {
pub name: String,
pub poly: Expression<F, V>,
}
impl<F: Field, V: Variable> Gate<F, V> {
pub fn name(&self) -> &str {
self.name.as_str()
}
pub fn polynomial(&self) -> &Expression<F, V> {
&self.poly
}
}
pub type GateMid<F> = Gate<F, VarMid>;
#[derive(Debug, Clone)]
pub struct ConstraintSystemMid<F: Field> {
pub num_fixed_columns: usize,
pub num_advice_columns: usize,
pub num_instance_columns: usize,
pub num_challenges: usize,
pub unblinded_advice_columns: Vec<usize>,
pub advice_column_phase: Vec<u8>,
pub challenge_phase: Vec<u8>,
pub gates: Vec<GateMid<F>>,
pub permutation: permutation::ArgumentMid,
pub lookups: Vec<lookup::ArgumentMid<F>>,
pub shuffles: Vec<shuffle::ArgumentMid<F>>,
pub general_column_annotations: HashMap<ColumnMid, String>,
pub minimum_degree: Option<usize>,
}
impl<F: Field> ConstraintSystemMid<F> {
pub fn phases(&self) -> usize {
let max_phase = self
.advice_column_phase
.iter()
.copied()
.max()
.unwrap_or_default();
max_phase as usize + 1
}
}
#[derive(Debug, Clone)]
pub struct Preprocessing<F: Field> {
pub permutation: permutation::AssemblyMid,
pub fixed: Vec<Vec<F>>,
}
#[derive(Debug, Clone)]
pub struct CompiledCircuit<F: Field> {
pub preprocessing: Preprocessing<F>,
pub cs: ConstraintSystemMid<F>,
}
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub enum Any {
Advice,
Fixed,
Instance,
}
impl std::fmt::Debug for Any {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Any::Advice => f.debug_struct("Advice").finish(),
Any::Fixed => f.debug_struct("Fixed").finish(),
Any::Instance => f.debug_struct("Instance").finish(),
}
}
}
impl Ord for Any {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
match (self, other) {
(Any::Instance, Any::Instance)
| (Any::Fixed, Any::Fixed)
| (Any::Advice, Any::Advice) => std::cmp::Ordering::Equal,
(Any::Instance, Any::Advice)
| (Any::Advice, Any::Fixed)
| (Any::Instance, Any::Fixed) => std::cmp::Ordering::Less,
(Any::Fixed, Any::Instance)
| (Any::Fixed, Any::Advice)
| (Any::Advice, Any::Instance) => std::cmp::Ordering::Greater,
}
}
}
impl PartialOrd for Any {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ColumnMid {
pub column_type: Any,
pub index: usize,
}
impl ColumnMid {
pub fn new(column_type: Any, index: usize) -> Self {
ColumnMid { column_type, index }
}
}
impl fmt::Display for ColumnMid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let column_type = match self.column_type {
Any::Advice => "a",
Any::Fixed => "f",
Any::Instance => "i",
};
write!(f, "{}{}", column_type, self.index)
}
}
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
pub struct Cell {
pub column: ColumnMid,
pub row: usize,
}