@@ -16,16 +16,16 @@ Module Name:
16
16
Notes:
17
17
18
18
--*/
19
- #include " math/polynomial/algebraic_numbers.h"
20
- #include " math/polynomial/upolynomial.h"
21
19
#include " util/mpbq.h"
22
20
#include " util/basic_interval.h"
23
- #include " math/polynomial/sexpr2upolynomial.h"
24
21
#include " util/scoped_ptr_vector.h"
25
22
#include " util/mpbqi.h"
26
23
#include " util/timeit.h"
27
- #include " math/polynomial/algebraic_params.hpp"
28
24
#include " util/common_msgs.h"
25
+ #include " math/polynomial/algebraic_numbers.h"
26
+ #include " math/polynomial/upolynomial.h"
27
+ #include " math/polynomial/sexpr2upolynomial.h"
28
+ #include " math/polynomial/algebraic_params.hpp"
29
29
30
30
namespace algebraic_numbers {
31
31
@@ -124,6 +124,10 @@ namespace algebraic_numbers {
124
124
~imp () {
125
125
}
126
126
127
+ bool acell_inv (algebraic_cell const & c) {
128
+ return c.m_sign_lower == (upm ().eval_sign_at (c.m_p_sz , c.m_p , lower (&c)) == polynomial::sign_neg);
129
+ }
130
+
127
131
void checkpoint () {
128
132
if (!m_limit.inc ())
129
133
throw algebraic_exception (Z3_CANCELED_MSG);
@@ -366,24 +370,25 @@ namespace algebraic_numbers {
366
370
return c;
367
371
}
368
372
369
- int sign_lower (algebraic_cell * c) {
370
- return c->m_sign_lower == 0 ? 1 : - 1 ;
373
+ polynomial::sign sign_lower (algebraic_cell * c) const {
374
+ return c->m_sign_lower == 0 ? polynomial::sign_pos : polynomial::sign_neg ;
371
375
}
372
376
373
- mpbq & lower (algebraic_cell * c) {
374
- return c->m_interval .lower ();
375
- }
377
+ mpbq const & lower (algebraic_cell const * c) const { return c->m_interval .lower (); }
376
378
377
- mpbq & upper (algebraic_cell * c) {
378
- return c->m_interval .upper ();
379
- }
379
+ mpbq const & upper (algebraic_cell const * c) const { return c->m_interval .upper (); }
380
+
381
+ mpbq & lower (algebraic_cell * c) { return c->m_interval .lower (); }
382
+
383
+ mpbq & upper (algebraic_cell * c) { return c->m_interval .upper (); }
380
384
381
385
void update_sign_lower (algebraic_cell * c) {
382
386
polynomial::sign sl = upm ().eval_sign_at (c->m_p_sz , c->m_p , lower (c));
383
387
// The isolating intervals are refinable. Thus, the polynomial has opposite signs at lower and upper.
384
388
SASSERT (sl != polynomial::sign_zero);
385
389
SASSERT (upm ().eval_sign_at (c->m_p_sz , c->m_p , upper (c)) == -sl);
386
390
c->m_sign_lower = sl == polynomial::sign_neg;
391
+ SASSERT (acell_inv (*c));
387
392
}
388
393
389
394
// Make sure the GCD of the coefficients is one and the leading coefficient is positive
@@ -393,6 +398,7 @@ namespace algebraic_numbers {
393
398
if (upm ().m ().is_neg (c->m_p [c->m_p_sz -1 ])) {
394
399
upm ().neg (c->m_p_sz , c->m_p );
395
400
c->m_sign_lower = !(c->m_sign_lower );
401
+ SASSERT (acell_inv (*c));
396
402
}
397
403
}
398
404
@@ -469,6 +475,8 @@ namespace algebraic_numbers {
469
475
target->m_sign_lower = source->m_sign_lower ;
470
476
target->m_not_rational = source->m_not_rational ;
471
477
target->m_i = source->m_i ;
478
+ SASSERT (acell_inv (*source));
479
+ SASSERT (acell_inv (*target));
472
480
}
473
481
474
482
void set (numeral & a, unsigned sz, mpz const * p, mpbq const & lower, mpbq const & upper, bool minimal) {
@@ -499,7 +507,7 @@ namespace algebraic_numbers {
499
507
update_sign_lower (c);
500
508
normalize_coeffs (c);
501
509
}
502
- SASSERT (sign_lower ( a.to_algebraic ()) == upm (). eval_sign_at (a. to_algebraic ()-> m_p_sz , a. to_algebraic ()-> m_p , a. to_algebraic ()-> m_interval . lower ()));
510
+ SASSERT (acell_inv (* a.to_algebraic ()));
503
511
}
504
512
TRACE (" algebraic" , tout << " a: " ; display_root (tout, a); tout << " \n " ;);
505
513
}
@@ -519,6 +527,7 @@ namespace algebraic_numbers {
519
527
algebraic_cell * c = new (mem) algebraic_cell ();
520
528
a.m_cell = TAG (void *, c, ROOT);
521
529
copy (c, b.to_algebraic ());
530
+ SASSERT (acell_inv (*c));
522
531
}
523
532
}
524
533
else {
@@ -532,6 +541,7 @@ namespace algebraic_numbers {
532
541
del_poly (a.to_algebraic ());
533
542
del_interval (a.to_algebraic ());
534
543
copy (a.to_algebraic (), b.to_algebraic ());
544
+ SASSERT (acell_inv (*a.to_algebraic ()));
535
545
}
536
546
}
537
547
}
@@ -693,6 +703,7 @@ namespace algebraic_numbers {
693
703
algebraic_cell * c = a.to_algebraic ();
694
704
if (!upm ().normalize_interval_core (c->m_p_sz , c->m_p , sign_lower (c), bqm (), lower (c), upper (c)))
695
705
reset (a);
706
+ SASSERT (acell_inv (*c));
696
707
}
697
708
}
698
709
@@ -727,7 +738,9 @@ namespace algebraic_numbers {
727
738
Return FALSE, if actual root was found.
728
739
*/
729
740
bool refine_core (algebraic_cell * c) {
730
- return upm ().refine_core (c->m_p_sz , c->m_p , sign_lower (c), bqm (), lower (c), upper (c));
741
+ bool r = upm ().refine_core (c->m_p_sz , c->m_p , sign_lower (c), bqm (), lower (c), upper (c));
742
+ SASSERT (acell_inv (*c));
743
+ return r;
731
744
}
732
745
733
746
/* *
@@ -746,15 +759,17 @@ namespace algebraic_numbers {
746
759
if (a.is_basic ())
747
760
return false ;
748
761
algebraic_cell * c = a.to_algebraic ();
749
- if (!refine_core (c)) {
762
+ if (refine_core (c)) {
763
+ return true ;
764
+ }
765
+ else {
750
766
// root was found
751
767
scoped_mpq r (qm ());
752
768
to_mpq (qm (), lower (c), r);
753
769
del (c);
754
770
a.m_cell = mk_basic_cell (r);
755
771
return false ;
756
772
}
757
- return true ;
758
773
}
759
774
760
775
bool refine (numeral & a, unsigned k) {
@@ -776,6 +791,7 @@ namespace algebraic_numbers {
776
791
a.m_cell = mk_basic_cell (r);
777
792
return false ;
778
793
}
794
+ SASSERT (acell_inv (*c));
779
795
return true ;
780
796
}
781
797
@@ -1573,6 +1589,7 @@ namespace algebraic_numbers {
1573
1589
upm ().p_minus_x (c->m_p_sz , c->m_p );
1574
1590
bqim ().neg (c->m_interval );
1575
1591
update_sign_lower (c);
1592
+ SASSERT (acell_inv (*c));
1576
1593
}
1577
1594
}
1578
1595
@@ -1583,38 +1600,41 @@ namespace algebraic_numbers {
1583
1600
if (a.is_basic ())
1584
1601
return ;
1585
1602
algebraic_cell * cell_a = a.to_algebraic ();
1586
- mpbq & lower = cell_a->m_interval .lower ();
1587
- mpbq & upper = cell_a->m_interval .upper ();
1588
- if (!bqm ().is_zero (lower) && !bqm ().is_zero (upper))
1603
+ SASSERT (acell_inv (*cell_a));
1604
+ mpbq & _lower = cell_a->m_interval .lower ();
1605
+ mpbq & _upper = cell_a->m_interval .upper ();
1606
+ if (!bqm ().is_zero (_lower) && !bqm ().is_zero (_upper))
1589
1607
return ;
1590
- int sign_l = sign_lower (cell_a);
1591
- SASSERT (sign_l != 0 );
1592
- int sign_u = -sign_l;
1608
+ auto sign_l = sign_lower (cell_a);
1609
+ SASSERT (! polynomial::is_zero (sign_l) );
1610
+ auto sign_u = -sign_l;
1593
1611
1594
- #define REFINE_LOOP (BOUND, TARGET_SIGN ) \
1595
- while (true ) { \
1596
- bqm ().div2 (BOUND); \
1612
+ #define REFINE_LOOP (BOUND, TARGET_SIGN ) \
1613
+ while (true ) { \
1614
+ bqm ().div2 (BOUND); \
1597
1615
polynomial::sign new_sign = upm ().eval_sign_at (cell_a->m_p_sz , cell_a->m_p , BOUND); \
1598
- if (new_sign == polynomial::sign_zero) { \
1599
- /* found actual root */ \
1600
- scoped_mpq r (qm ()); \
1601
- to_mpq (qm (), BOUND, r); \
1602
- set (a, r); \
1603
- return ; \
1604
- } \
1605
- if (new_sign == TARGET_SIGN) \
1606
- return ; \
1607
- }
1608
-
1609
- if (bqm ().is_zero (lower)) {
1610
- bqm ().set (lower, upper);
1611
- REFINE_LOOP (lower, sign_l);
1616
+ if (new_sign == polynomial::sign_zero) { \
1617
+ /* found actual root */ \
1618
+ scoped_mpq r (qm ()); \
1619
+ to_mpq (qm (), BOUND, r); \
1620
+ set (a, r); \
1621
+ break ; \
1622
+ } \
1623
+ if (new_sign == TARGET_SIGN) { \
1624
+ break ; \
1625
+ } \
1626
+ }
1627
+
1628
+ if (bqm ().is_zero (_lower)) {
1629
+ bqm ().set (_lower, _upper);
1630
+ REFINE_LOOP (_lower, sign_l);
1612
1631
}
1613
1632
else {
1614
- SASSERT (bqm ().is_zero (upper ));
1615
- bqm ().set (upper, lower );
1616
- REFINE_LOOP (upper , sign_u);
1633
+ SASSERT (bqm ().is_zero (_upper ));
1634
+ bqm ().set (_upper, _lower );
1635
+ REFINE_LOOP (_upper , sign_u);
1617
1636
}
1637
+ SASSERT (acell_inv (*cell_a));
1618
1638
}
1619
1639
1620
1640
void inv (numeral & a) {
@@ -1642,6 +1662,8 @@ namespace algebraic_numbers {
1642
1662
// convert isolating interval back as a binary rational bound
1643
1663
upm ().convert_q2bq_interval (cell_a->m_p_sz , cell_a->m_p , inv_lower, inv_upper, bqm (), lower (cell_a), upper (cell_a));
1644
1664
TRACE (" algebraic_bug" , tout << " after inv: " ; display_root (tout, a); tout << " \n " ; display_interval (tout, a); tout << " \n " ;);
1665
+ update_sign_lower (cell_a);
1666
+ SASSERT (acell_inv (*cell_a));
1645
1667
}
1646
1668
}
1647
1669
@@ -2118,7 +2140,6 @@ namespace algebraic_numbers {
2118
2140
// compute the resultants
2119
2141
polynomial_ref q_i (pm ());
2120
2142
std::stable_sort (xs.begin (), xs.end (), var_degree_lt (*this , x2v));
2121
- // std::cout << "R: " << R << "\n";
2122
2143
for (unsigned i = 0 ; i < xs.size (); i++) {
2123
2144
checkpoint ();
2124
2145
polynomial::var x_i = xs[i];
@@ -2127,7 +2148,6 @@ namespace algebraic_numbers {
2127
2148
SASSERT (!v_i.is_basic ());
2128
2149
algebraic_cell * c = v_i.to_algebraic ();
2129
2150
q_i = pm ().to_polynomial (c->m_p_sz , c->m_p , x_i);
2130
- // std::cout << "q_i: " << q_i << std::endl;
2131
2151
pm ().resultant (R, q_i, x_i, R);
2132
2152
SASSERT (!pm ().is_zero (R));
2133
2153
}
@@ -2136,7 +2156,6 @@ namespace algebraic_numbers {
2136
2156
upm ().to_numeral_vector (R, _R);
2137
2157
unsigned k = upm ().nonzero_root_lower_bound (_R.size (), _R.c_ptr ());
2138
2158
TRACE (" anum_eval_sign" , tout << " R: " << R << " \n k: " << k << " \n ri: " << ri << " \n " ;);
2139
- // std::cout << "R: " << R << "\n";
2140
2159
scoped_mpbq mL (bqm ()), L (bqm ());
2141
2160
bqm ().set (mL , -1 );
2142
2161
bqm ().set (L, 1 );
0 commit comments