1use std::fmt;
4
5use crate::{
6 eqv::{EqvRelation, SymbolicEqv},
7 slot::{arg::ArgNo, cell::CellRef, output::OutputId},
8};
9
10pub mod arg;
11pub mod cell;
12pub mod output;
13
14#[derive(Clone, Copy, Hash, Eq, PartialEq, PartialOrd, Ord)]
19pub enum Slot {
20 Arg(ArgNo),
22 Output(OutputId),
24 Advice(CellRef),
26 Fixed(CellRef),
28 TableLookup(u64, usize, usize, usize, usize),
30 CallOutput(usize, usize),
32 Temp(usize),
34 Challenge(usize, u8, ArgNo),
36}
37
38impl Slot {
39 pub fn advice_abs(col: usize, row: usize) -> Self {
43 Self::Advice(CellRef::absolute(col, row))
44 }
45
46 pub fn advice_rel(col: usize, base: usize, offset: usize) -> Self {
50 Self::Advice(CellRef::relative(col, base, offset))
51 }
52
53 pub fn fixed_abs(col: usize, row: usize) -> Self {
57 Self::Fixed(CellRef::absolute(col, row))
58 }
59
60 pub fn fixed_rel(col: usize, base: usize, offset: usize) -> Self {
64 Self::Fixed(CellRef::relative(col, base, offset))
65 }
66}
67
68impl EqvRelation<Slot> for SymbolicEqv {
69 fn equivalent(lhs: &Slot, rhs: &Slot) -> bool {
77 match (lhs, rhs) {
78 (Slot::Arg(lhs), Slot::Arg(rhs)) => lhs == rhs,
79 (Slot::Output(lhs), Slot::Output(rhs)) => lhs == rhs,
80 (Slot::Advice(lhs), Slot::Advice(rhs)) => Self::equivalent(lhs, rhs),
81 (Slot::Fixed(lhs), Slot::Fixed(rhs)) => Self::equivalent(lhs, rhs),
82 (Slot::TableLookup(_, col0, row0, _, _), Slot::TableLookup(_, col1, row1, _, _)) => {
83 col0 == col1 && row0 == row1
84 }
85 (Slot::CallOutput(_, o0), Slot::CallOutput(_, o1)) => o0 == o1,
86 (Slot::Temp(lhs), Slot::Temp(rhs)) => lhs == rhs,
87 (
88 Slot::Challenge(lhs_index, lhs_phase, _),
89 Slot::Challenge(rhs_index, rhs_phase, _),
90 ) => lhs_index == rhs_index && lhs_phase == rhs_phase,
91 _ => false,
92 }
93 }
94}
95
96impl std::fmt::Debug for Slot {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 Self::Arg(arg) => write!(f, "{arg:?}"),
100 Self::Output(field) => write!(f, "{field:?}"),
101 Self::Advice(c) => write!(f, "adv{c:?}"),
102 Self::Fixed(c) => write!(f, "fix{c:?}"),
103 Self::TableLookup(id, col, row, idx, region_idx) => {
104 write!(f, "lookup{id}[{col},{row}]@({idx},{region_idx})")
105 }
106 Self::CallOutput(call, out) => write!(f, "call{call}->{out}"),
107 Self::Temp(id) => write!(f, "t{}", *id),
108 Self::Challenge(index, phase, _) => write!(f, "challenge{index}@{phase}"),
109 }
110 }
111}
112
113impl std::fmt::Display for Slot {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 match self {
116 Self::Arg(arg) => write!(f, "{arg}"),
117 Self::Output(field) => write!(f, "{field}"),
118 Self::Advice(c) => write!(f, "adv{c}"),
119 Self::Fixed(c) => write!(f, "fix{c}"),
120 Self::TableLookup(id, col, row, idx, region_idx) => {
121 write!(f, "lookup{id}[{col},{row}]@({idx},{region_idx})")
122 }
123 Self::CallOutput(call, out) => write!(f, "call{call}->{out}"),
124 Self::Temp(id) => write!(f, "t{}", *id),
125 Self::Challenge(index, phase, _) => write!(f, "challenge{index}@{phase}"),
126 }
127 }
128}
129
130impl From<ArgNo> for Slot {
131 fn from(value: ArgNo) -> Self {
132 Self::Arg(value)
133 }
134}
135
136impl From<OutputId> for Slot {
137 fn from(value: OutputId) -> Self {
138 Self::Output(value)
139 }
140}