|
1 | | -use super::{assert_clause_len, RuleArgs, RuleResult}; |
| 1 | +use super::{assert_clause_len, assert_eq, RuleArgs, RuleResult}; |
2 | 2 | use crate::{ |
3 | 3 | ast::{Operator, Rc, Sort, Term}, |
4 | 4 | checker::error::PolynomialError, |
| 5 | + checker::rules::{assert_num_premises, get_premise_term}, |
5 | 6 | }; |
6 | 7 | use indexmap::{map::Entry, IndexMap}; |
7 | 8 | use rug::{ops::NegAssign, Integer, Rational}; |
@@ -191,3 +192,42 @@ pub fn bv_poly_simp(RuleArgs { conclusion, pool, .. }: RuleArgs) -> RuleResult { |
191 | 192 | Ok(()) |
192 | 193 | } |
193 | 194 | } |
| 195 | + |
| 196 | +pub fn poly_simp_rel(RuleArgs { conclusion, premises, .. }: RuleArgs) -> RuleResult { |
| 197 | + use Operator::*; |
| 198 | + |
| 199 | + assert_num_premises(premises, 1)?; |
| 200 | + assert_clause_len(conclusion, 1)?; |
| 201 | + let prem = get_premise_term(&premises[0])?; |
| 202 | + |
| 203 | + let ((c1, xs), (c2, ys)) = match_term_err!((= (* c1 xs) (* c2 ys)) = prem)?; |
| 204 | + let (x1, x2) = |
| 205 | + match_term_err!((to_real (- x1 x2)) = xs).or_else(|_| match_term_err!((- x1 x2) = xs))?; |
| 206 | + let (y1, y2) = |
| 207 | + match_term_err!((to_real (- y1 y2)) = ys).or_else(|_| match_term_err!((- y1 y2) = ys))?; |
| 208 | + |
| 209 | + let (c1, c2) = (c1.as_fraction_err()?, c2.as_fraction_err()?); |
| 210 | + for c in [&c1, &c2] { |
| 211 | + rassert!(!c.is_zero(), PolynomialError::CoeffIsZero(c.clone())); |
| 212 | + } |
| 213 | + |
| 214 | + let (left, right) = match_term_err!((= l r) = &conclusion[0])?; |
| 215 | + match (left.as_op_err()?, right.as_op_err()?) { |
| 216 | + ( |
| 217 | + (op @ (LessThan | LessEq | Equals | GreaterEq | GreaterThan), [l1, l2]), |
| 218 | + (op2, [r1, r2]), |
| 219 | + ) if op2 == op => { |
| 220 | + rassert!( |
| 221 | + op == Equals || c1.is_positive() == c2.is_positive(), |
| 222 | + PolynomialError::CoeffDifferentSignums(c1.clone(), c2.clone()), |
| 223 | + ); |
| 224 | + |
| 225 | + assert_eq(l1, x1)?; |
| 226 | + assert_eq(l2, x2)?; |
| 227 | + assert_eq(r1, y1)?; |
| 228 | + assert_eq(r2, y2)?; |
| 229 | + Ok(()) |
| 230 | + } |
| 231 | + ((op1, _), (op2, _)) => Err(PolynomialError::InvalidOperators(op1, op2).into()), |
| 232 | + } |
| 233 | +} |
0 commit comments