1#![doc = include_str!("../README.md")]
2#![deny(rustdoc::broken_intra_doc_links)]
3#![deny(missing_debug_implementations)]
4#![deny(missing_docs)]
5
6use haloumi_core::{cmp::CmpOp, felt::Felt, slot::Slot};
7
8pub mod error;
9pub mod lowerable;
10
11pub type Result<T> = std::result::Result<T, error::Error>;
13
14pub trait Lowering: ExprLowering {
16 fn generate_constraint(
18 &self,
19 op: CmpOp,
20 lhs: &Self::CellOutput,
21 rhs: &Self::CellOutput,
22 ) -> Result<()>;
23
24 fn num_constraints(&self) -> usize;
26
27 fn checked_generate_constraint(
29 &self,
30 op: CmpOp,
31 lhs: &Self::CellOutput,
32 rhs: &Self::CellOutput,
33 ) -> Result<()> {
34 let before = self.num_constraints();
35 self.generate_constraint(op, lhs, rhs)?;
36 let after = self.num_constraints();
37 if before >= after {
38 return Err(error::Error::LastConstraintNotGenerated);
39 }
40 Ok(())
41 }
42
43 fn generate_comment(&self, s: String) -> Result<()>;
45
46 fn generate_assume_deterministic(&self, slot: Slot) -> Result<()>;
49
50 fn generate_call(
52 &self,
53 name: &str,
54 selectors: &[Self::CellOutput],
55 outputs: &[Slot],
56 ) -> Result<()>;
57
58 fn generate_assert(&self, expr: &Self::CellOutput) -> Result<()>;
62
63 fn generate_post_condition(&self, expr: &Self::CellOutput) -> Result<()>;
67}
68
69pub trait ExprLowering {
71 type CellOutput;
73
74 fn lower_sum(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput)
76 -> Result<Self::CellOutput>;
77
78 fn lower_product(
80 &self,
81 lhs: &Self::CellOutput,
82 rhs: &Self::CellOutput,
83 ) -> Result<Self::CellOutput>;
84
85 fn lower_neg(&self, expr: &Self::CellOutput) -> Result<Self::CellOutput>;
87
88 fn lower_constant(&self, f: Felt) -> Result<Self::CellOutput>;
90
91 fn lower_eq(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
93
94 fn lower_lt(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
96
97 fn lower_le(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
99
100 fn lower_gt(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
102
103 fn lower_ge(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
105
106 fn lower_ne(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
108
109 fn lower_and(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput)
111 -> Result<Self::CellOutput>;
112
113 fn lower_or(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
115
116 fn lower_not(&self, value: &Self::CellOutput) -> Result<Self::CellOutput>;
118
119 fn lower_true(&self) -> Result<Self::CellOutput>;
121
122 fn lower_false(&self) -> Result<Self::CellOutput>;
124
125 fn lower_det(&self, expr: &Self::CellOutput) -> Result<Self::CellOutput>;
130
131 fn lower_implies(
133 &self,
134 lhs: &Self::CellOutput,
135 rhs: &Self::CellOutput,
136 ) -> Result<Self::CellOutput>;
137
138 fn lower_iff(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput)
140 -> Result<Self::CellOutput>;
141
142 fn lower_function_input(&self, i: usize) -> Slot;
144
145 fn lower_function_output(&self, o: usize) -> Slot;
147
148 fn lower_function_inputs(&self, ins: impl IntoIterator<Item = usize>) -> Vec<Slot> {
150 ins.into_iter()
151 .map(|i| self.lower_function_input(i))
152 .collect()
153 }
154
155 fn lower_function_outputs(&self, outs: impl IntoIterator<Item = usize>) -> Vec<Slot> {
157 outs.into_iter()
158 .map(|o| self.lower_function_output(o))
159 .collect()
160 }
161
162 fn lower_funcio<IO>(&self, io: IO) -> Result<Self::CellOutput>
164 where
165 IO: Into<Slot>;
166}