zinc_uair/
ideal_collector.rs1use zinc_utils::from_ref::FromRef;
2
3use crate::{
4 ConstraintBuilder, TraceRow, Uair,
5 dummy_semiring::DummySemiring,
6 ideal::{Ideal, IdealCheck, IdealCheckError},
7};
8
9pub struct IdealCollector<I: Ideal> {
12 pub ideals: Vec<IdealOrZero<I>>,
13}
14
15impl<I: Ideal> IdealCollector<I> {
16 pub fn new(num_constraints: usize) -> Self {
20 Self {
21 ideals: Vec::with_capacity(num_constraints),
22 }
23 }
24}
25
26pub fn collect_ideals<U: Uair>(num_constraints: usize) -> IdealCollector<U::Ideal> {
30 let mut ideal_collector = IdealCollector::new(num_constraints);
31
32 let sig = U::signature();
33 let (up_dummy, down_dummy) = sig.dummy_rows(DummySemiring);
34 let up_row = TraceRow::from_slice_with_layout(&up_dummy, sig.total_cols().as_column_layout());
35 let down_row =
36 TraceRow::from_slice_with_layout(&down_dummy, sig.down_cols().as_column_layout());
37 U::constrain(&mut ideal_collector, up_row, down_row);
38
39 ideal_collector
40}
41
42impl<I> ConstraintBuilder for IdealCollector<I>
43where
44 I: Ideal,
45{
46 type Expr = DummySemiring;
47 type Ideal = IdealOrZero<I>;
48
49 fn assert_in_ideal(&mut self, _expr: Self::Expr, ideal: &Self::Ideal) {
50 self.ideals.push(ideal.clone());
51 }
52
53 fn assert_zero(&mut self, _expr: Self::Expr) {
54 self.ideals.push(IdealOrZero::zero());
55 }
56}
57
58#[derive(Clone, Copy, Debug)]
61pub enum IdealOrZero<I: Ideal> {
62 NonZero(I),
63 Zero,
64}
65
66impl<I: Ideal> IdealOrZero<I> {
67 pub fn zero() -> Self {
68 IdealOrZero::Zero
69 }
70
71 pub fn is_zero_ideal(&self) -> bool {
74 matches!(self, IdealOrZero::Zero)
75 }
76
77 pub fn map<I2: Ideal>(&self, f: impl FnOnce(&I) -> I2) -> IdealOrZero<I2> {
78 match self {
79 IdealOrZero::NonZero(ideal) => IdealOrZero::NonZero(f(ideal)),
80 IdealOrZero::Zero => IdealOrZero::Zero,
81 }
82 }
83}
84
85impl<I: Ideal> Ideal for IdealOrZero<I> {}
86
87impl<I: Ideal> FromRef<IdealOrZero<I>> for IdealOrZero<I> {
88 fn from_ref(value: &IdealOrZero<I>) -> Self {
89 value.clone()
90 }
91}
92
93impl<I: Ideal> FromRef<I> for IdealOrZero<I> {
94 fn from_ref(value: &I) -> Self {
95 IdealOrZero::NonZero(value.clone())
96 }
97}
98
99impl<I: Ideal> IdealCheck<DummySemiring> for IdealOrZero<I> {
100 fn contains(&self, _value: &DummySemiring) -> Result<bool, IdealCheckError> {
101 Ok(true)
103 }
104}