halo2_proofs/dev/
util.rs
1use std::collections::BTreeMap;
2
3use group::ff::Field;
4use pasta_curves::arithmetic::FieldExt;
5
6use super::{metadata, CellValue, Value};
7use crate::{
8 plonk::{Any, Column, ColumnType, Expression, Gate, VirtualCell},
9 poly::Rotation,
10};
11
12pub(super) fn format_value<F: Field>(v: F) -> String {
13 if v.is_zero_vartime() {
14 "0".into()
15 } else if v == F::one() {
16 "1".into()
17 } else if v == -F::one() {
18 "-1".into()
19 } else {
20 let s = format!("{:?}", v);
22 let s = s.strip_prefix("0x").unwrap();
24 let s = s.trim_start_matches('0');
25 format!("0x{}", s)
26 }
27}
28
29pub(super) fn load<'a, F: FieldExt, T: ColumnType>(
30 n: i32,
31 row: i32,
32 queries: &'a [(Column<T>, Rotation)],
33 cells: &'a [Vec<CellValue<F>>],
34) -> impl Fn(usize, usize, Rotation) -> Value<F> + 'a {
35 move |index, _, _| {
36 let (column, at) = &queries[index];
37 let resolved_row = (row + at.0) % n;
38 cells[column.index()][resolved_row as usize].into()
39 }
40}
41
42pub(super) fn load_instance<'a, F: FieldExt, T: ColumnType>(
43 n: i32,
44 row: i32,
45 queries: &'a [(Column<T>, Rotation)],
46 cells: &'a [Vec<F>],
47) -> impl Fn(usize, usize, Rotation) -> Value<F> + 'a {
48 move |index, _, _| {
49 let (column, at) = &queries[index];
50 let resolved_row = (row + at.0) % n;
51 Value::Real(cells[column.index()][resolved_row as usize])
52 }
53}
54
55fn cell_value<'a, F: FieldExt>(
56 virtual_cells: &'a [VirtualCell],
57 column_type: Any,
58 load: impl Fn(usize, usize, Rotation) -> Value<F> + 'a,
59) -> impl Fn(usize, usize, Rotation) -> BTreeMap<metadata::VirtualCell, String> + 'a {
60 move |query_index, column_index, rotation| {
61 virtual_cells
62 .iter()
63 .find(|c| {
64 c.column.column_type() == &column_type
65 && c.column.index() == column_index
66 && c.rotation == rotation
67 })
68 .map(|cell| {
70 (
71 cell.clone().into(),
72 match load(query_index, column_index, rotation) {
73 Value::Real(v) => format_value(v),
74 Value::Poison => unreachable!(),
75 },
76 )
77 })
78 .into_iter()
79 .collect()
80 }
81}
82
83pub(super) fn cell_values<'a, F: FieldExt>(
84 gate: &Gate<F>,
85 poly: &Expression<F>,
86 load_fixed: impl Fn(usize, usize, Rotation) -> Value<F> + 'a,
87 load_advice: impl Fn(usize, usize, Rotation) -> Value<F> + 'a,
88 load_instance: impl Fn(usize, usize, Rotation) -> Value<F> + 'a,
89) -> Vec<(metadata::VirtualCell, String)> {
90 let virtual_cells = gate.queried_cells();
91 let cell_values = poly.evaluate(
92 &|_| BTreeMap::default(),
93 &|_| panic!("virtual selectors are removed during optimization"),
94 &cell_value(virtual_cells, Any::Fixed, load_fixed),
95 &cell_value(virtual_cells, Any::Advice, load_advice),
96 &cell_value(virtual_cells, Any::Instance, load_instance),
97 &|a| a,
98 &|mut a, mut b| {
99 a.append(&mut b);
100 a
101 },
102 &|mut a, mut b| {
103 a.append(&mut b);
104 a
105 },
106 &|a, _| a,
107 );
108 cell_values.into_iter().collect()
109}