1use std::fmt;
5#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct BoundVar {
8 pub name: String,
9 pub ty: Option<Type>,
10}
11
12impl BoundVar {
13 pub fn new_with_ty(name: &str, ty: &Type) -> Self {
15 BoundVar {
16 name: name.to_string(),
17 ty: Some(ty.clone()),
18 }
19 }
20
21 pub fn new(name: &str) -> Self {
23 BoundVar {
24 name: name.to_string(),
25 ty: None,
26 }
27 }
28
29 pub fn as_expr(&self) -> Expr {
31 Expr::Var(self.name.clone())
32 }
33}
34
35#[derive(Clone, Debug, PartialEq, Eq)]
38pub struct TermSignature {
39 pub args: Vec<BoundVar>,
40 pub ret: BoundVar,
41}
42
43#[derive(Clone, Debug, PartialEq, Eq)]
46pub struct TermAnnotation {
47 pub sig: TermSignature,
48 #[allow(clippy::vec_box)]
50 pub assumptions: Vec<Box<Expr>>,
51
52 #[allow(clippy::vec_box)]
53 pub assertions: Vec<Box<Expr>>,
54}
55
56impl TermAnnotation {
57 pub fn new(sig: TermSignature, assumptions: Vec<Expr>, assertions: Vec<Expr>) -> Self {
59 TermAnnotation {
60 sig,
61 assumptions: assumptions.iter().map(|x| Box::new(x.clone())).collect(),
62 assertions: assertions.iter().map(|x| Box::new(x.clone())).collect(),
63 }
64 }
65
66 pub fn sig(&self) -> &TermSignature {
67 &self.sig
68 }
69
70 pub fn assertions(&self) -> Vec<Expr> {
71 self.assumptions.iter().map(|x| *x.clone()).collect()
72 }
73}
74
75#[derive(Clone, Debug, Hash, PartialEq, Eq)]
77pub enum Type {
78 Poly(u32),
80
81 BitVector,
86
87 BitVectorWithWidth(usize),
89
90 BitVectorUnknown(u32),
93
94 Int,
97
98 Bool,
100
101 Unit,
103}
104
105impl fmt::Display for Type {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 match self {
108 Type::Poly(_) => write!(f, "poly"),
109 Type::BitVector => write!(f, "bv"),
110 Type::BitVectorWithWidth(w) => write!(f, "bv{}", *w),
111 Type::BitVectorUnknown(_) => write!(f, "bv"),
112 Type::Int => write!(f, "Int"),
113 Type::Bool => write!(f, "Bool"),
114 Type::Unit => write!(f, "Unit"),
115 }
116 }
117}
118
119impl Type {
120 pub fn is_poly(&self) -> bool {
121 matches!(self, Type::Poly(_))
122 }
123}
124
125#[derive(Clone, Debug, PartialEq, Eq)]
127pub struct Const {
128 pub ty: Type,
129 pub value: i128,
130 pub width: usize,
131}
132
133#[derive(Clone, Debug, PartialEq, Eq)]
135pub enum Width {
136 Const(usize),
137 RegWidth,
138}
139
140#[derive(Clone, Debug, PartialEq, Eq)]
142pub enum Expr {
143 Var(String),
145 Const(Const),
146 True,
147 False,
148
149 WidthOf(Box<Expr>),
151
152 Not(Box<Expr>),
154 And(Box<Expr>, Box<Expr>),
155 Or(Box<Expr>, Box<Expr>),
156 Imp(Box<Expr>, Box<Expr>),
157 Eq(Box<Expr>, Box<Expr>),
158 Lte(Box<Expr>, Box<Expr>),
159 Lt(Box<Expr>, Box<Expr>),
160
161 BVSgt(Box<Expr>, Box<Expr>),
162 BVSgte(Box<Expr>, Box<Expr>),
163 BVSlt(Box<Expr>, Box<Expr>),
164 BVSlte(Box<Expr>, Box<Expr>),
165 BVUgt(Box<Expr>, Box<Expr>),
166 BVUgte(Box<Expr>, Box<Expr>),
167 BVUlt(Box<Expr>, Box<Expr>),
168 BVUlte(Box<Expr>, Box<Expr>),
169
170 BVSaddo(Box<Expr>, Box<Expr>),
171
172 BVNeg(Box<Expr>),
177 BVNot(Box<Expr>),
178 CLZ(Box<Expr>),
179 CLS(Box<Expr>),
180 Rev(Box<Expr>),
181 BVPopcnt(Box<Expr>),
182
183 BVMul(Box<Expr>, Box<Expr>),
185 BVUDiv(Box<Expr>, Box<Expr>),
186 BVSDiv(Box<Expr>, Box<Expr>),
187 BVAdd(Box<Expr>, Box<Expr>),
188 BVSub(Box<Expr>, Box<Expr>),
189 BVUrem(Box<Expr>, Box<Expr>),
190 BVSrem(Box<Expr>, Box<Expr>),
191 BVAnd(Box<Expr>, Box<Expr>),
192 BVOr(Box<Expr>, Box<Expr>),
193 BVXor(Box<Expr>, Box<Expr>),
194 BVRotl(Box<Expr>, Box<Expr>),
195 BVRotr(Box<Expr>, Box<Expr>),
196 BVShl(Box<Expr>, Box<Expr>),
197 BVShr(Box<Expr>, Box<Expr>),
198 BVAShr(Box<Expr>, Box<Expr>),
199
200 BVSubs(Box<Expr>, Box<Expr>, Box<Expr>),
202
203 BVZeroExtTo(Box<Width>, Box<Expr>),
206 BVZeroExtToVarWidth(Box<Expr>, Box<Expr>),
207
208 BVSignExtTo(Box<Width>, Box<Expr>),
210 BVSignExtToVarWidth(Box<Expr>, Box<Expr>),
211
212 BVExtract(usize, usize, Box<Expr>),
214
215 BVConcat(Vec<Expr>),
217
218 BVIntToBv(usize, Box<Expr>),
220
221 BVToInt(Box<Expr>),
223
224 BVConvTo(Box<Expr>, Box<Expr>),
227
228 Conditional(Box<Expr>, Box<Expr>, Box<Expr>),
230
231 Switch(Box<Expr>, Vec<(Expr, Expr)>),
233
234 LoadEffect(Box<Expr>, Box<Expr>, Box<Expr>),
235
236 StoreEffect(Box<Expr>, Box<Expr>, Box<Expr>, Box<Expr>),
237}
238
239impl Expr {
240 pub fn var(s: &str) -> Expr {
241 Expr::Var(s.to_string())
242 }
243
244 pub fn unary<F: Fn(Box<Expr>) -> Expr>(f: F, x: Expr) -> Expr {
245 f(Box::new(x))
246 }
247
248 pub fn binary<F: Fn(Box<Expr>, Box<Expr>) -> Expr>(f: F, x: Expr, y: Expr) -> Expr {
249 f(Box::new(x), Box::new(y))
250 }
251}