1#![doc = include_str!("../README.md")]
2use haloumi_ir_base::{cmp::CmpOp, felt::Felt, func::FuncIO};
7use std::ops::Range;
8
9pub mod error;
10pub mod lowerable;
11
12pub type Result<T> = std::result::Result<T, error::Error>;
13
14pub trait Lowering: ExprLowering {
15 fn generate_constraint(
16 &self,
17 op: CmpOp,
18 lhs: &Self::CellOutput,
19 rhs: &Self::CellOutput,
20 ) -> Result<()>;
21
22 fn num_constraints(&self) -> usize;
23
24 fn checked_generate_constraint(
25 &self,
26 op: CmpOp,
27 lhs: &Self::CellOutput,
28 rhs: &Self::CellOutput,
29 ) -> Result<()> {
30 let before = self.num_constraints();
31 self.generate_constraint(op, lhs, rhs)?;
32 let after = self.num_constraints();
33 if before >= after {
34 return Err(error::Error::LastConstraintNotGenerated);
35 }
36 Ok(())
37 }
38
39 fn generate_comment(&self, s: String) -> Result<()>;
40
41 fn generate_assume_deterministic(&self, func_io: FuncIO) -> Result<()>;
42
43 fn generate_call(
44 &self,
45 name: &str,
46 selectors: &[Self::CellOutput],
47 outputs: &[FuncIO],
48 ) -> Result<()>;
49
50 fn generate_assert(&self, expr: &Self::CellOutput) -> Result<()>;
51
52 fn generate_post_condition(&self, expr: &Self::CellOutput) -> Result<()>;
53}
54
55pub trait ExprLowering {
56 type CellOutput;
57
58 fn lower_sum(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput)
59 -> Result<Self::CellOutput>;
60
61 fn lower_product(
62 &self,
63 lhs: &Self::CellOutput,
64 rhs: &Self::CellOutput,
65 ) -> Result<Self::CellOutput>;
66
67 fn lower_neg(&self, expr: &Self::CellOutput) -> Result<Self::CellOutput>;
68
69 fn lower_constant(&self, f: Felt) -> Result<Self::CellOutput>;
70
71 fn lower_eq(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
72 fn lower_lt(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
73 fn lower_le(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
74 fn lower_gt(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
75 fn lower_ge(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
76 fn lower_ne(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
77 fn lower_and(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput)
78 -> Result<Self::CellOutput>;
79 fn lower_or(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput) -> Result<Self::CellOutput>;
80 fn lower_not(&self, value: &Self::CellOutput) -> Result<Self::CellOutput>;
81 fn lower_true(&self) -> Result<Self::CellOutput>;
82 fn lower_false(&self) -> Result<Self::CellOutput>;
83 fn lower_det(&self, expr: &Self::CellOutput) -> Result<Self::CellOutput>;
84 fn lower_implies(
85 &self,
86 lhs: &Self::CellOutput,
87 rhs: &Self::CellOutput,
88 ) -> Result<Self::CellOutput>;
89 fn lower_iff(&self, lhs: &Self::CellOutput, rhs: &Self::CellOutput)
90 -> Result<Self::CellOutput>;
91
92 fn lower_function_input(&self, i: usize) -> FuncIO;
93 fn lower_function_output(&self, o: usize) -> FuncIO;
94
95 fn lower_function_inputs(&self, ins: Range<usize>) -> Vec<FuncIO> {
96 ins.map(|i| self.lower_function_input(i)).collect()
97 }
98 fn lower_function_outputs(&self, outs: Range<usize>) -> Vec<FuncIO> {
99 outs.map(|o| self.lower_function_output(o)).collect()
100 }
101
102 fn lower_funcio<IO>(&self, io: IO) -> Result<Self::CellOutput>
103 where
104 IO: Into<FuncIO>;
105}