|
1 | 1 | use super::{assert_clause_len, assert_eq, RuleArgs, RuleResult}; |
2 | 2 | use crate::{ |
3 | 3 | ast::{Operator, Rc, Sort, Term}, |
4 | | - checker::error::PolynomialError, |
5 | | - checker::rules::{assert_num_premises, get_premise_term}, |
| 4 | + checker::{ |
| 5 | + error::PolynomialError, |
| 6 | + rules::{assert_is_expected, assert_num_premises, get_premise_term}, |
| 7 | + }, |
6 | 8 | }; |
7 | 9 | use indexmap::{map::Entry, IndexMap}; |
8 | 10 | use rug::{ops::NegAssign, Integer, Rational}; |
@@ -231,3 +233,27 @@ pub fn poly_simp_rel(RuleArgs { conclusion, premises, .. }: RuleArgs) -> RuleRes |
231 | 233 | ((op1, _), (op2, _)) => Err(PolynomialError::InvalidOperators(op1, op2).into()), |
232 | 234 | } |
233 | 235 | } |
| 236 | + |
| 237 | +pub fn bv_poly_simp_eq(RuleArgs { conclusion, premises, pool, .. }: RuleArgs) -> RuleResult { |
| 238 | + assert_num_premises(premises, 1)?; |
| 239 | + assert_clause_len(conclusion, 1)?; |
| 240 | + |
| 241 | + let ((c1, (x1, x2)), (c2, (y1, y2))) = |
| 242 | + match_term_err!((= (* c1 (- x1 x2)) (* c2 (- y1 y2))) = get_premise_term(&premises[0])?)?; |
| 243 | + |
| 244 | + let sort = pool.sort(c1); |
| 245 | + let Sort::BitVec(width) = sort.as_sort().unwrap() else { |
| 246 | + unreachable!() // The parser ensures that the sort is a bitvector sort |
| 247 | + }; |
| 248 | + let one = pool.add(Term::new_bv(Integer::from(1), *width)); |
| 249 | + assert_is_expected(c1, one.clone())?; |
| 250 | + assert_is_expected(c2, one)?; |
| 251 | + |
| 252 | + let ((l1, l2), (r1, r2)) = match_term_err!((= (= x1 x2) (= y1 y2)) = &conclusion[0])?; |
| 253 | + |
| 254 | + assert_eq(l1, x1)?; |
| 255 | + assert_eq(l2, x2)?; |
| 256 | + assert_eq(r1, y1)?; |
| 257 | + assert_eq(r2, y2)?; |
| 258 | + Ok(()) |
| 259 | +} |
0 commit comments