1use std::cmp;
4use std::collections::HashSet;
5use std::fmt;
6
7use ff::Field;
8
9use super::{Cell, RegionIndex};
10use crate::plonk::{Advice, Any, Assigned, Column, Error, Fixed, Instance, Selector, TableColumn};
11
12pub trait RegionLayouter<F: Field>: fmt::Debug {
43 fn enable_selector<'v>(
45 &'v mut self,
46 annotation: &'v (dyn Fn() -> String + 'v),
47 selector: &Selector,
48 offset: usize,
49 ) -> Result<(), Error>;
50
51 fn assign_advice<'v>(
53 &'v mut self,
54 annotation: &'v (dyn Fn() -> String + 'v),
55 column: Column<Advice>,
56 offset: usize,
57 to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
58 ) -> Result<Cell, Error>;
59
60 fn assign_advice_from_constant<'v>(
67 &'v mut self,
68 annotation: &'v (dyn Fn() -> String + 'v),
69 column: Column<Advice>,
70 offset: usize,
71 constant: Assigned<F>,
72 ) -> Result<Cell, Error>;
73
74 fn assign_advice_from_instance<'v>(
79 &mut self,
80 annotation: &'v (dyn Fn() -> String + 'v),
81 instance: Column<Instance>,
82 row: usize,
83 advice: Column<Advice>,
84 offset: usize,
85 ) -> Result<(Cell, Option<F>), Error>;
86
87 fn assign_fixed<'v>(
89 &'v mut self,
90 annotation: &'v (dyn Fn() -> String + 'v),
91 column: Column<Fixed>,
92 offset: usize,
93 to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
94 ) -> Result<Cell, Error>;
95
96 fn constrain_constant(&mut self, cell: Cell, constant: Assigned<F>) -> Result<(), Error>;
100
101 fn constrain_equal(&mut self, left: Cell, right: Cell) -> Result<(), Error>;
105}
106
107pub trait TableLayouter<F: Field>: fmt::Debug {
113 fn assign_cell<'v>(
117 &'v mut self,
118 annotation: &'v (dyn Fn() -> String + 'v),
119 column: TableColumn,
120 offset: usize,
121 to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
122 ) -> Result<(), Error>;
123}
124
125#[derive(Clone, Debug)]
128pub struct RegionShape {
129 pub(super) region_index: RegionIndex,
130 pub(super) columns: HashSet<RegionColumn>,
131 pub(super) row_count: usize,
132}
133
134#[derive(Eq, PartialEq, Copy, Clone, Debug, Hash)]
137pub enum RegionColumn {
138 Column(Column<Any>),
140 Selector(Selector),
142}
143
144impl From<Column<Any>> for RegionColumn {
145 fn from(column: Column<Any>) -> RegionColumn {
146 RegionColumn::Column(column)
147 }
148}
149
150impl From<Selector> for RegionColumn {
151 fn from(selector: Selector) -> RegionColumn {
152 RegionColumn::Selector(selector)
153 }
154}
155
156impl Ord for RegionColumn {
157 fn cmp(&self, other: &Self) -> cmp::Ordering {
158 match (self, other) {
159 (Self::Column(ref a), Self::Column(ref b)) => a.cmp(b),
160 (Self::Selector(ref a), Self::Selector(ref b)) => a.0.cmp(&b.0),
161 (Self::Column(_), Self::Selector(_)) => cmp::Ordering::Less,
162 (Self::Selector(_), Self::Column(_)) => cmp::Ordering::Greater,
163 }
164 }
165}
166
167impl PartialOrd for RegionColumn {
168 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
169 Some(self.cmp(other))
170 }
171}
172
173impl RegionShape {
174 pub fn new(region_index: RegionIndex) -> Self {
176 RegionShape {
177 region_index,
178 columns: HashSet::default(),
179 row_count: 0,
180 }
181 }
182
183 pub fn region_index(&self) -> RegionIndex {
185 self.region_index
186 }
187
188 pub fn columns(&self) -> &HashSet<RegionColumn> {
190 &self.columns
191 }
192
193 pub fn row_count(&self) -> usize {
195 self.row_count
196 }
197}
198
199impl<F: Field> RegionLayouter<F> for RegionShape {
200 fn enable_selector<'v>(
201 &'v mut self,
202 _: &'v (dyn Fn() -> String + 'v),
203 selector: &Selector,
204 offset: usize,
205 ) -> Result<(), Error> {
206 self.columns.insert((*selector).into());
208 self.row_count = cmp::max(self.row_count, offset + 1);
209 Ok(())
210 }
211
212 fn assign_advice<'v>(
213 &'v mut self,
214 _: &'v (dyn Fn() -> String + 'v),
215 column: Column<Advice>,
216 offset: usize,
217 _to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
218 ) -> Result<Cell, Error> {
219 self.columns.insert(Column::<Any>::from(column).into());
220 self.row_count = cmp::max(self.row_count, offset + 1);
221
222 Ok(Cell {
223 region_index: self.region_index,
224 row_offset: offset,
225 column: column.into(),
226 })
227 }
228
229 fn assign_advice_from_constant<'v>(
230 &'v mut self,
231 annotation: &'v (dyn Fn() -> String + 'v),
232 column: Column<Advice>,
233 offset: usize,
234 constant: Assigned<F>,
235 ) -> Result<Cell, Error> {
236 self.assign_advice(annotation, column, offset, &mut || Ok(constant))
238 }
239
240 fn assign_advice_from_instance<'v>(
241 &mut self,
242 _: &'v (dyn Fn() -> String + 'v),
243 _: Column<Instance>,
244 _: usize,
245 advice: Column<Advice>,
246 offset: usize,
247 ) -> Result<(Cell, Option<F>), Error> {
248 self.columns.insert(Column::<Any>::from(advice).into());
249 self.row_count = cmp::max(self.row_count, offset + 1);
250
251 Ok((
252 Cell {
253 region_index: self.region_index,
254 row_offset: offset,
255 column: advice.into(),
256 },
257 None,
258 ))
259 }
260
261 fn assign_fixed<'v>(
262 &'v mut self,
263 _: &'v (dyn Fn() -> String + 'v),
264 column: Column<Fixed>,
265 offset: usize,
266 _to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
267 ) -> Result<Cell, Error> {
268 self.columns.insert(Column::<Any>::from(column).into());
269 self.row_count = cmp::max(self.row_count, offset + 1);
270
271 Ok(Cell {
272 region_index: self.region_index,
273 row_offset: offset,
274 column: column.into(),
275 })
276 }
277
278 fn constrain_constant(&mut self, _cell: Cell, _constant: Assigned<F>) -> Result<(), Error> {
279 Ok(())
281 }
282
283 fn constrain_equal(&mut self, _left: Cell, _right: Cell) -> Result<(), Error> {
284 Ok(())
286 }
287}