1use ark_ff::{Field, One, Zero};
2use kimchi_msm::{Logup, LookupTableID};
3
4#[derive(Copy, Clone, Debug)]
6pub enum LookupMode {
7 Read,
8 Write,
9}
10
11#[derive(Clone, Debug)]
13pub struct RAMLookup<T, ID: LookupTableID> {
14 pub(crate) table_id: ID,
16 pub(crate) mode: LookupMode,
18 pub(crate) magnitude: T,
20 pub(crate) value: Vec<T>,
22}
23
24impl<T, ID> RAMLookup<T, ID>
25where
26 T: Clone
27 + std::ops::Add<T, Output = T>
28 + std::ops::Sub<T, Output = T>
29 + std::ops::Mul<T, Output = T>
30 + std::fmt::Debug
31 + One
32 + Zero,
33 ID: LookupTableID,
34{
35 pub fn new(mode: LookupMode, table_id: ID, magnitude: T, value: &[T]) -> Self {
37 Self {
38 mode,
39 table_id,
40 magnitude,
41 value: value.to_vec(),
42 }
43 }
44
45 pub fn numerator(&self) -> T {
47 match self.mode {
48 LookupMode::Read => T::zero() - self.magnitude.clone(),
49 LookupMode::Write => self.magnitude.clone(),
50 }
51 }
52
53 pub fn into_logup(self) -> Logup<T, ID> {
55 Logup::new(self.table_id, self.numerator(), &self.value)
56 }
57
58 pub fn read_if(if_is_true: T, table_id: ID, value: Vec<T>) -> Self {
60 Self {
61 mode: LookupMode::Read,
62 magnitude: if_is_true,
63 table_id,
64 value,
65 }
66 }
67
68 pub fn write_if(if_is_true: T, table_id: ID, value: Vec<T>) -> Self {
70 Self {
71 mode: LookupMode::Write,
72 magnitude: if_is_true,
73 table_id,
74 value,
75 }
76 }
77
78 pub fn read_one(table_id: ID, value: Vec<T>) -> Self {
80 Self {
81 mode: LookupMode::Read,
82 magnitude: T::one(),
83 table_id,
84 value,
85 }
86 }
87
88 pub fn write_one(table_id: ID, value: Vec<T>) -> Self {
90 Self {
91 mode: LookupMode::Write,
92 magnitude: T::one(),
93 table_id,
94 value,
95 }
96 }
97}
98
99impl<F: std::fmt::Display + Field, ID: LookupTableID> std::fmt::Display for RAMLookup<F, ID> {
100 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 let numerator = match self.mode {
102 LookupMode::Read => -self.magnitude,
103 LookupMode::Write => self.magnitude,
104 };
105 write!(
106 formatter,
107 "numerator: {}\ntable_id: {:?}\nvalue:\n[\n",
108 numerator,
109 self.table_id.to_field::<F>()
110 )?;
111 for value in self.value.iter() {
112 writeln!(formatter, "\t{}", value)?;
113 }
114 write!(formatter, "]")?;
115 Ok(())
116 }
117}