@@ -515,6 +515,129 @@ br_status arith_rewriter::reduce_power(expr * arg1, expr * arg2, op_kind kind, e
515
515
}
516
516
}
517
517
518
+ bool arith_rewriter::is_mul_factor (expr* s, expr* t) {
519
+ if (m_util.is_mul (t))
520
+ return any_of (*to_app (t), [&](expr* m) { return is_mul_factor (s, m); });
521
+ return s == t;
522
+ }
523
+
524
+ bool arith_rewriter::is_add_factor (expr* s, expr* t) {
525
+ if (m_util.is_add (t))
526
+ return all_of (*to_app (t), [&](expr* f) { return is_add_factor (s, f); });
527
+ return is_mul_factor (s, t);
528
+ }
529
+
530
+ expr_ref arith_rewriter::remove_factor (expr* s, expr* t) {
531
+
532
+ if (m_util.is_mul (t)) {
533
+ ptr_buffer<expr> r;
534
+ r.push_back (t);
535
+ for (unsigned i = 0 ; i < r.size (); ++i) {
536
+ expr* arg = r[i];
537
+ if (m_util.is_mul (arg)) {
538
+ r.append (to_app (arg)->get_num_args (), to_app (arg)->get_args ());
539
+ r[i] = r.back ();
540
+ r.pop_back ();
541
+ --i;
542
+ continue ;
543
+ }
544
+ if (s == arg) {
545
+ r[i] = r.back ();
546
+ r.pop_back ();
547
+ break ;
548
+ }
549
+ }
550
+ switch (r.size ()) {
551
+ case 0 :
552
+ return expr_ref (m_util.mk_numeral (rational (1 ), m_util.is_int (t)), m);
553
+ case 1 :
554
+ return expr_ref (r[0 ], m);
555
+ default :
556
+ return expr_ref (m_util.mk_mul (r.size (), r.data ()), m);
557
+ }
558
+ }
559
+ if (m_util.is_add (t)) {
560
+ expr_ref_vector sum (m);
561
+ sum.push_back (t);
562
+ for (unsigned i = 0 ; i < sum.size (); ++i) {
563
+ expr* arg = sum.get (i);
564
+ if (m_util.is_add (arg)) {
565
+ sum.append (to_app (arg)->get_num_args (), to_app (arg)->get_args ());
566
+ sum[i] = sum.back ();
567
+ sum.pop_back ();
568
+ --i;
569
+ continue ;
570
+ }
571
+ sum[i] = remove_factor (s, arg);
572
+ }
573
+ if (sum.size () == 1 )
574
+ return expr_ref (sum.get (0 ), m);
575
+ else
576
+ return expr_ref (m_util.mk_add (sum.size (), sum.data ()), m);
577
+ }
578
+ else {
579
+ SASSERT (s == t);
580
+ return expr_ref (m_util.mk_numeral (rational (1 ), m_util.is_int (t)), m);
581
+ }
582
+ }
583
+
584
+
585
+ void arith_rewriter::get_nl_muls (expr* t, ptr_buffer<expr>& muls) {
586
+ if (m_util.is_mul (t)) {
587
+ for (expr* arg : *to_app (t))
588
+ get_nl_muls (arg, muls);
589
+ }
590
+ else if (!m_util.is_numeral (t))
591
+ muls.push_back (t);
592
+ }
593
+
594
+ expr* arith_rewriter::find_nl_factor (expr* t) {
595
+ ptr_buffer<expr> sum, muls;
596
+ sum.push_back (t);
597
+
598
+ for (unsigned i = 0 ; i < sum.size (); ++i) {
599
+ expr* arg = sum[i];
600
+ if (m_util.is_add (arg))
601
+ sum.append (to_app (arg)->get_num_args (), to_app (arg)->get_args ());
602
+ else if (m_util.is_mul (arg)) {
603
+ muls.reset ();
604
+ get_nl_muls (arg, muls);
605
+ if (muls.size () <= 1 )
606
+ continue ;
607
+ for (auto m : muls) {
608
+ if (is_add_factor (m, t))
609
+ return m;
610
+ }
611
+ return nullptr ;
612
+ }
613
+ }
614
+ return nullptr ;
615
+ }
616
+
617
+ br_status arith_rewriter::factor_le_ge_eq (expr * arg1, expr * arg2, op_kind kind, expr_ref & result) {
618
+
619
+ if (is_zero (arg2)) {
620
+ expr* f = find_nl_factor (arg1);
621
+ if (!f)
622
+ return BR_FAILED;
623
+ expr_ref f2 = remove_factor (f, arg1);
624
+ expr* z = m_util.mk_numeral (rational (0 ), m_util.is_int (arg1));
625
+ result = m.mk_or (m_util.mk_eq (f, z), m_util.mk_eq (f2, z));
626
+ switch (kind) {
627
+ case EQ:
628
+ break ;
629
+ case GE:
630
+ result = m.mk_or (m.mk_iff (m_util.mk_ge (f, z), m_util.mk_ge (f2, z)), result);
631
+ break ;
632
+ case LE:
633
+ result = m.mk_or (m.mk_not (m.mk_iff (m_util.mk_ge (f, z), m_util.mk_ge (f2, z))), result);
634
+ break ;
635
+ }
636
+ return BR_REWRITE3;
637
+ }
638
+ return BR_FAILED;
639
+ }
640
+
518
641
br_status arith_rewriter::mk_le_ge_eq_core (expr * arg1, expr * arg2, op_kind kind, expr_ref & result) {
519
642
expr *orig_arg1 = arg1, *orig_arg2 = arg2;
520
643
expr_ref new_arg1 (m);
@@ -655,7 +778,7 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin
655
778
default : result = m.mk_eq (arg1, arg2); return BR_DONE;
656
779
}
657
780
}
658
- return BR_FAILED ;
781
+ return factor_le_ge_eq (arg1, arg2, kind, result) ;
659
782
}
660
783
661
784
0 commit comments