1use ark_ff::Zero;
2use core::{
3 fmt::{Display, Formatter, Result},
4 ops::{Index, IndexMut},
5};
6use kimchi::circuits::expr::AlphaChallengeTerm;
7use serde::{Deserialize, Serialize};
8use strum::EnumCount;
9use strum_macros::EnumCount as EnumCountMacro;
10
11#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, EnumCountMacro)]
12pub enum ChallengeTerm {
13 ConstraintCombiner,
17 Beta,
19 Gamma,
20 ConstraintHomogeniser,
24 RelationCombiner,
28}
29
30impl Display for ChallengeTerm {
31 fn fmt(&self, f: &mut Formatter) -> Result {
32 match self {
33 ChallengeTerm::ConstraintCombiner => write!(f, "alpha"),
34 ChallengeTerm::Beta => write!(f, "beta"),
35 ChallengeTerm::Gamma => write!(f, "gamma"),
36 ChallengeTerm::ConstraintHomogeniser => write!(f, "u"),
37 ChallengeTerm::RelationCombiner => write!(f, "r"),
38 }
39 }
40}
41
42pub struct Challenges<F> {
43 pub constraint_combiner: F,
47
48 pub beta: F,
50 pub gamma: F,
51
52 pub constraint_homogeniser: F,
56
57 pub relation_combiner: F,
61}
62
63impl<F> Index<usize> for Challenges<F> {
64 type Output = F;
65
66 fn index(&self, index: usize) -> &Self::Output {
67 if index == 0 {
68 &self.constraint_combiner
69 } else if index == 1 {
70 &self.beta
71 } else if index == 2 {
72 &self.gamma
73 } else if index == 3 {
74 &self.constraint_homogeniser
75 } else if index == 4 {
76 &self.relation_combiner
77 } else {
78 panic!(
79 "Index out of bounds, only {} are defined",
80 ChallengeTerm::COUNT
81 )
82 }
83 }
84}
85
86impl<F> IndexMut<usize> for Challenges<F> {
87 fn index_mut(&mut self, index: usize) -> &mut F {
88 if index == 0 {
89 &mut self.constraint_combiner
90 } else if index == 1 {
91 &mut self.beta
92 } else if index == 2 {
93 &mut self.gamma
94 } else if index == 3 {
95 &mut self.constraint_homogeniser
96 } else if index == 4 {
97 &mut self.relation_combiner
98 } else {
99 panic!(
100 "Index out of bounds, only {} are defined",
101 ChallengeTerm::COUNT
102 )
103 }
104 }
105}
106
107impl<F> IndexMut<ChallengeTerm> for Challenges<F> {
108 fn index_mut(&mut self, term: ChallengeTerm) -> &mut F {
109 match term {
110 ChallengeTerm::ConstraintCombiner => &mut self.constraint_combiner,
111 ChallengeTerm::Beta => &mut self.beta,
112 ChallengeTerm::Gamma => &mut self.gamma,
113 ChallengeTerm::ConstraintHomogeniser => &mut self.constraint_homogeniser,
114 ChallengeTerm::RelationCombiner => &mut self.relation_combiner,
115 }
116 }
117}
118
119impl<F: Zero> Default for Challenges<F> {
120 fn default() -> Self {
121 Self {
122 constraint_combiner: F::zero(),
123 beta: F::zero(),
124 gamma: F::zero(),
125 constraint_homogeniser: F::zero(),
126 relation_combiner: F::zero(),
127 }
128 }
129}
130
131impl<F> Index<ChallengeTerm> for Challenges<F> {
132 type Output = F;
133
134 fn index(&self, term: ChallengeTerm) -> &Self::Output {
135 match term {
136 ChallengeTerm::ConstraintCombiner => &self.constraint_combiner,
137 ChallengeTerm::Beta => &self.beta,
138 ChallengeTerm::Gamma => &self.gamma,
139 ChallengeTerm::ConstraintHomogeniser => &self.constraint_homogeniser,
140 ChallengeTerm::RelationCombiner => &self.relation_combiner,
141 }
142 }
143}
144
145impl<'a> AlphaChallengeTerm<'a> for ChallengeTerm {
146 const ALPHA: Self = Self::ConstraintCombiner;
147}