1use std::{
2 cmp::max,
3 fmt::{self, Display},
4 ops::{Add, BitAnd, BitOr, BitXor, Mul, Neg, Not, Sub},
5 vec,
6};
7
8use rand::random_range;
9use rustc_hash::FxHashSet as HashSet;
10
11use crate::varint::{VarInt, make_mask};
12
13#[cfg(feature = "jit")]
14use crate::jit;
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18pub struct VarId(pub usize);
19
20impl Display for VarId {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 f.write_fmt(format_args!("{}", self.0))
23 }
24}
25
26impl From<usize> for VarId {
27 fn from(value: usize) -> Self {
28 VarId(value)
29 }
30}
31
32#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
34pub enum Expr {
35 Var(VarId),
37
38 Const(u64),
40
41 Not(Box<Expr>),
44 Scale(u64, Box<Expr>),
46
47 And(Vec<Expr>),
50 Or(Vec<Expr>),
52 Xor(Vec<Expr>),
54
55 Add(Vec<Expr>),
58 Mul(Vec<Expr>),
60}
61
62impl Not for Expr {
63 type Output = Expr;
64
65 fn not(self) -> Self::Output {
66 Expr::Not(Box::new(self))
67 }
68}
69
70impl BitXor for Expr {
71 type Output = Expr;
72
73 fn bitxor(self, rhs: Self) -> Self::Output {
74 Expr::Xor(vec![self, rhs])
75 }
76}
77
78impl BitAnd for Expr {
79 type Output = Expr;
80
81 fn bitand(self, rhs: Self) -> Self::Output {
82 Expr::And(vec![self, rhs])
83 }
84}
85
86impl BitOr for Expr {
87 type Output = Expr;
88
89 fn bitor(self, rhs: Self) -> Self::Output {
90 Expr::Or(vec![self, rhs])
91 }
92}
93
94impl Add for Expr {
95 type Output = Expr;
96
97 fn add(self, rhs: Self) -> Self::Output {
98 Expr::Add(vec![self, rhs])
99 }
100}
101
102impl Sub for Expr {
103 type Output = Expr;
104
105 fn sub(self, rhs: Self) -> Self::Output {
106 Expr::Add(vec![self, -rhs])
107 }
108}
109
110impl Mul for Expr {
111 type Output = Expr;
112
113 fn mul(self, rhs: Self) -> Self::Output {
114 Expr::Mul(vec![self, rhs])
115 }
116}
117
118impl Mul<Expr> for u64 {
119 type Output = Expr;
120
121 fn mul(self, rhs: Expr) -> Self::Output {
122 Expr::scale(self, rhs)
123 }
124}
125
126impl Neg for Expr {
127 type Output = Expr;
128
129 fn neg(self) -> Self::Output {
130 Expr::Scale(u64::MAX, Box::new(self))
131 }
132}
133
134impl fmt::Display for Expr {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 f.write_str(&self.repr_masked(64, u64::MAX, true, false))
137 }
138}
139
140impl From<u64> for Expr {
141 fn from(value: u64) -> Self {
142 Expr::Const(value)
143 }
144}
145
146impl Expr {
147 pub fn make_const(c: u64) -> Self {
149 Expr::Const(c)
150 }
151
152 pub const fn zero() -> Self {
154 Expr::Const(0)
155 }
156
157 pub(crate) fn scale(c: u64, e: Expr) -> Expr {
158 match c {
159 0 => Expr::zero(),
160 1 => e,
161 _ => Expr::Scale(c, Box::new(e)),
162 }
163 }
164
165 pub(crate) fn get_factor(&self, mask: u64) -> u64 {
174 let term_factor = |t: &Expr| match t {
175 Expr::Scale(c, _) => c & mask,
176 _ => 1,
177 };
178 match self {
179 Expr::Scale(c, _) => c & mask,
180 Expr::Add(terms) => {
181 let f = term_factor(&terms[0]);
182 if terms.iter().all(|t| term_factor(t) == f) {
183 f
184 } else {
185 1
186 }
187 }
188 _ => 1,
189 }
190 }
191
192 pub fn size(&self) -> usize {
194 let children_size = match self {
195 Expr::Var(_) | Expr::Const(_) => 0,
196
197 Expr::Not(expr) | Expr::Scale(_, expr) => expr.size(),
198
199 Expr::And(exprs)
200 | Expr::Or(exprs)
201 | Expr::Xor(exprs)
202 | Expr::Add(exprs)
203 | Expr::Mul(exprs) => exprs.iter().map(|e| e.size()).sum(),
204 };
205
206 children_size + 1
207 }
208
209 pub(crate) fn eval_bits(&self, vars: &[u64]) -> VarInt {
211 match self {
212 Expr::Var(i) => vars[i.0].into(),
213
214 Expr::Const(c) => (*c).into(),
215
216 Expr::And(exprs) => exprs
217 .iter()
218 .map(|e| e.eval_bits(vars))
219 .fold(VarInt::MAX, |x, y| x & y),
220
221 Expr::Or(exprs) => exprs
222 .iter()
223 .map(|e| e.eval_bits(vars))
224 .fold(VarInt::ZERO, |x, y| x | y),
225
226 Expr::Xor(exprs) => exprs
227 .iter()
228 .map(|e| e.eval_bits(vars))
229 .fold(VarInt::ZERO, |x, y| x ^ y),
230
231 Expr::Add(exprs) => exprs
232 .iter()
233 .map(|e| e.eval_bits(vars))
234 .fold(VarInt::ZERO, |x, y| x + y),
235
236 Expr::Mul(exprs) => exprs
237 .iter()
238 .map(|e| e.eval_bits(vars))
239 .fold(VarInt::ONE, |x, y| x * y),
240
241 Expr::Scale(v, e) => VarInt::from(*v) * e.eval_bits(vars),
242
243 Expr::Not(e) => !e.eval_bits(vars),
244 }
245 }
246
247 pub fn eval(&self, vars: &[u64], n: u8) -> u64 {
249 self.eval_bits(vars).get(make_mask(n))
250 }
251
252 pub fn sem_equal(
256 &self,
257 other: &Expr,
258 n: u8,
259 samples: usize,
260 ) -> Result<(), (Vec<u64>, u64, u64)> {
261 self.sem_equal_masked(other, make_mask(n), samples)
262 }
263
264 pub fn truth_table(&self, t: usize, n: u8) -> Vec<u64> {
267 self.truth_table_masked(t, make_mask(n))
268 }
269
270 pub(crate) fn sem_equal_masked(
274 &self,
275 other: &Expr,
276 mask: u64,
277 count: usize,
278 ) -> Result<(), (Vec<u64>, u64, u64)> {
279 let t = max(
280 self.get_vars()
281 .iter()
282 .copied()
283 .map(|v| v.0)
284 .max()
285 .unwrap_or(0),
286 other
287 .get_vars()
288 .iter()
289 .copied()
290 .map(|v| v.0)
291 .max()
292 .unwrap_or(0),
293 );
294
295 for _ in 0..count {
296 let vars: Vec<_> = (0..=t).map(|_| random_range(0..=mask)).collect();
297
298 let v1 = self.eval_bits(&vars).get(mask);
299 let v2 = other.eval_bits(&vars).get(mask);
300
301 if v1 != v2 {
302 return Err((vars, v1, v2));
303 }
304 }
305
306 Ok(())
307 }
308
309 pub(crate) fn truth_table_masked(&self, t: usize, mask: u64) -> Vec<u64> {
311 let size = 1usize << t;
316 let mut tt = Vec::with_capacity(size);
317
318 let mut vars = vec![0u64; t];
319
320 let vars_from_i = |i: usize, vars: &mut [u64]| {
322 let mut idx = i;
323 for var in vars {
324 *var = (idx & 1) as u64;
325 idx >>= 1;
326 }
327 };
328
329 #[cfg(feature = "jit")]
330 {
331 if t > 10 {
336 let jit_fn = jit::compile(self);
337
338 for i in 0..size {
339 vars_from_i(i, &mut vars);
340 tt.push(jit_fn.eval(&vars) & mask);
341 }
342
343 return tt;
344 }
345 }
346
347 for i in 0..size {
348 vars_from_i(i, &mut vars);
349 tt.push(self.eval_bits(&vars).get(mask));
350 }
351
352 tt
353 }
354
355 pub(crate) fn visit<T, F>(&self, mut f: F) -> T
357 where
358 F: FnMut(&Expr, Vec<T>) -> T + Clone,
359 {
360 match self {
361 Expr::Var(_) | Expr::Const(_) => f(self, vec![]),
362
363 Expr::Not(expr) | Expr::Scale(_, expr) => {
364 let v = vec![expr.visit::<T, F>(f.clone())];
365 f(self, v)
366 }
367
368 Expr::And(exprs)
369 | Expr::Or(exprs)
370 | Expr::Xor(exprs)
371 | Expr::Add(exprs)
372 | Expr::Mul(exprs) => {
373 let v = exprs.iter().map(|e| e.visit(f.clone())).collect();
374 f(self, v)
375 }
376 }
377 }
378
379 pub fn get_vars(&self) -> HashSet<VarId> {
381 self.visit(|e, children: Vec<HashSet<VarId>>| {
382 let mut acc: HashSet<VarId> = children.into_iter().flatten().collect();
383 if let Expr::Var(v) = e {
384 acc.insert(*v);
385 }
386 acc
387 })
388 }
389
390 fn precedence(&self) -> usize {
393 match self {
394 Expr::And(e) | Expr::Or(e) | Expr::Xor(e) | Expr::Add(e) | Expr::Mul(e)
398 if e.len() == 1 =>
399 {
400 e[0].precedence()
401 }
402
403 Expr::Var(_) | Expr::Const(_) => 0,
404
405 Expr::Not(_) => 2,
406
407 Expr::Mul(_) | Expr::Scale(_, _) => 3,
408
409 Expr::Add(_) => 4,
410
411 Expr::And(_) => 8,
412
413 Expr::Xor(_) => 9,
414
415 Expr::Or(_) => 10,
416 }
417 }
418
419 fn parenthesize(&self, parent: &Expr, s: String) -> String {
421 if parent.precedence() < self.precedence() {
425 format!("({})", s)
426 } else {
427 s
428 }
429 }
430
431 pub(crate) fn symbol(&self, latex: bool) -> &str {
432 match (self, latex) {
433 (Expr::Var(_), _) | (Expr::Const(_), _) => "",
434
435 (Expr::Not(_), true) => "\\neg",
436 (Expr::Not(_), false) => "~",
437
438 (Expr::Scale(_, _), true) => "\\cdot",
439 (Expr::Scale(_, _), false) => "*",
440
441 (Expr::And(_), true) => "\\land",
442 (Expr::And(_), false) => "&",
443
444 (Expr::Or(_), true) => "\\lor",
445 (Expr::Or(_), false) => "|",
446
447 (Expr::Xor(_), true) => "\\oplus",
448 (Expr::Xor(_), false) => "^",
449
450 (Expr::Add(_), _) => "+",
451
452 (Expr::Mul(_), true) => "\\cdot",
453 (Expr::Mul(_), false) => "*",
454 }
455 }
456
457 pub(crate) fn repr_masked(&self, n: u8, mask: u64, hex: bool, latex: bool) -> String {
459 let recurs = |e: &Expr| e.parenthesize(self, e.repr_masked(n, mask, hex, latex));
460
461 let join = |exprs: &Vec<Expr>, c: &str| {
462 exprs
463 .iter()
464 .map(recurs)
465 .collect::<Vec<String>>()
466 .join(c)
467 .to_string()
468 };
469
470 if let Expr::And(e) | Expr::Or(e) | Expr::Xor(e) | Expr::Add(e) | Expr::Mul(e) = self
473 && e.len() == 1
474 {
475 return e[0].repr_masked(n, mask, hex, latex);
476 }
477
478 match self {
479 Expr::Var(v) => {
480 if latex {
481 format!("v_{{{}}}", v.0)
482 } else {
483 format!("v{}", v.0)
484 }
485 }
486
487 Expr::Const(c) => VarInt::from(*c).repr(n, mask, hex, latex),
488
489 Expr::Scale(c, expr) => format!(
490 "{} {} {}",
491 VarInt::from(*c).repr(n, mask, hex, latex),
492 self.symbol(latex),
493 recurs(expr)
494 ),
495
496 Expr::Not(expr) => {
497 format!("{} {}", self.symbol(latex), recurs(expr))
498 }
499
500 Expr::Add(exprs) => {
501 let star = if latex { "\\cdot" } else { "*" };
502 let sign_bit = 1u64 << (n - 1);
503
504 let term = |e: &Expr| -> (bool, String) {
509 match e {
510 Expr::Const(c) if c & mask & sign_bit != 0 => {
511 let m = VarInt::from(c.wrapping_neg());
512 (true, m.repr(n, mask, hex, latex))
513 }
514 Expr::Scale(c, inner) if c & mask & sign_bit != 0 => {
515 let m = c.wrapping_neg() & mask;
516 let is = inner.parenthesize(
519 &Expr::Mul(vec![]),
520 inner.repr_masked(n, mask, hex, latex),
521 );
522 if m == 1 {
523 (true, is)
524 } else {
525 let cs = VarInt::from(m).repr(n, mask, hex, latex);
526 (true, format!("{cs} {star} {is}"))
527 }
528 }
529 _ => (false, recurs(e)),
530 }
531 };
532
533 let mut out = String::new();
534 for (i, e) in exprs.iter().enumerate() {
535 let (neg, s) = term(e);
536 if i == 0 {
537 out.push_str(&if neg { format!("-{s}") } else { s });
538 } else {
539 out.push_str(if neg { " - " } else { " + " });
540 out.push_str(&s);
541 }
542 }
543 out
544 }
545
546 Expr::And(exprs) | Expr::Or(exprs) | Expr::Xor(exprs) | Expr::Mul(exprs) => {
547 join(exprs, &format!(" {} ", self.symbol(latex)))
548 }
549 }
550 }
551
552 pub fn repr(&self, n: u8, hex: bool, latex: bool) -> String {
554 self.repr_masked(n, make_mask(n), hex, latex)
555 }
556
557 pub fn is_bitwise(&self) -> bool {
559 match self {
560 Expr::Var(_) => true,
561
562 Expr::Not(expr) => expr.is_bitwise(),
563
564 Expr::And(exprs) | Expr::Or(exprs) | Expr::Xor(exprs) => {
565 exprs.iter().all(|e| e.is_bitwise())
566 }
567
568 _ => false,
569 }
570 }
571
572 pub fn variables_in(&self, allowed_vars: &Vec<usize>) -> bool {
574 match self {
575 Expr::Const(_) => true,
576
577 Expr::Var(i) => allowed_vars.contains(&i.0),
578
579 Expr::Not(expr) | Expr::Scale(_, expr) => expr.variables_in(allowed_vars),
580
581 Expr::And(exprs)
582 | Expr::Or(exprs)
583 | Expr::Xor(exprs)
584 | Expr::Add(exprs)
585 | Expr::Mul(exprs) => exprs.iter().all(|e| e.variables_in(allowed_vars)),
586 }
587 }
588
589 pub(crate) fn replace_var(self, target_var: VarId, replacement: &Expr) -> Self {
591 match self {
592 Expr::Var(v) if v == target_var => replacement.clone(),
593 _ => self.map(|e| e.replace_var(target_var, replacement)),
594 }
595 }
596
597 pub(crate) fn map<F>(self, mut f: F) -> Self
599 where
600 F: FnMut(Self) -> Self,
601 {
602 let vec_map = |exprs: Vec<Expr>, f: F| exprs.into_iter().map(f).collect();
603
604 match self {
605 Expr::Var(_) | Expr::Const(_) => self,
606
607 Expr::Not(expr) => !f(*expr),
608 Expr::Scale(v, expr) => v * f(*expr),
609
610 Expr::And(exprs) => Expr::And(vec_map(exprs, f)),
611 Expr::Or(exprs) => Expr::Or(vec_map(exprs, f)),
612 Expr::Xor(exprs) => Expr::Xor(vec_map(exprs, f)),
613 Expr::Add(exprs) => Expr::Add(vec_map(exprs, f)),
614 Expr::Mul(exprs) => Expr::Mul(vec_map(exprs, f)),
615 }
616 }
617
618 pub(crate) fn try_map<F, E>(self, mut f: F) -> Result<Self, E>
623 where
624 F: FnMut(Self) -> Result<Self, E>,
625 {
626 fn vec_try_map<F, E>(exprs: Vec<Expr>, f: F) -> Result<Vec<Expr>, E>
627 where
628 F: FnMut(Expr) -> Result<Expr, E>,
629 {
630 exprs.into_iter().map(f).collect()
631 }
632
633 Ok(match self {
634 Expr::Var(_) | Expr::Const(_) => self,
635
636 Expr::Not(expr) => !f(*expr)?,
637 Expr::Scale(v, expr) => v * f(*expr)?,
638
639 Expr::And(exprs) => Expr::And(vec_try_map(exprs, f)?),
640 Expr::Or(exprs) => Expr::Or(vec_try_map(exprs, f)?),
641 Expr::Xor(exprs) => Expr::Xor(vec_try_map(exprs, f)?),
642 Expr::Add(exprs) => Expr::Add(vec_try_map(exprs, f)?),
643 Expr::Mul(exprs) => Expr::Mul(vec_try_map(exprs, f)?),
644 })
645 }
646}