@@ -563,21 +563,32 @@ void seq_axioms::add_itos_axiom(expr* e) {
563
563
/* *
564
564
stoi(s) >= -1
565
565
stoi("") = -1
566
+ stoi(s) >= 0 => len(s) > 0
567
+ stoi(s) >= 0 => is_digit(nth(s,0))
566
568
*/
567
569
void seq_axioms::add_stoi_axiom (expr* e) {
568
570
TRACE (" seq" , tout << mk_pp (e, m) << " \n " ;);
569
571
expr* s = nullptr ;
570
572
VERIFY (seq.str .is_stoi (e, s));
571
- add_axiom (mk_ge (e, -1 ));
572
- add_axiom (~mk_literal (seq.str.mk_is_empty(s)), mk_eq (seq.str .mk_stoi (s), a.mk_int (-1 )));
573
+ add_axiom (mk_ge (e, -1 )); // stoi(s) >= -1
574
+ add_axiom (~mk_eq_empty (s), mk_eq (e, a.mk_int (-1 ))); // s = "" => stoi(s) = -1
575
+ literal ge0 = mk_ge (e, 0 );
576
+ add_axiom (~ge0, is_digit (mk_nth (s, 0 ))); // stoi(s) >= 0 => is_digit(nth(s,0))
577
+
573
578
}
574
579
575
580
/* *
576
581
577
- stoi(s) >= 0, len(s) <= k => stoi(s) = stoi(s, k)
578
- len(s) > 0 => stoi(s, 0) = digit(nth_i(s, 0))
582
+ len(s) <= k => stoi(s) = stoi(s, k)
583
+ len(s) > 0, is_digit(nth(s,0)) => stoi(s, 0) = digit(nth_i(s, 0))
584
+ len(s) > 0, ~is_digit(nth(s,0)) => stoi(s, 0) = -1
585
+
579
586
0 < i, len(s) <= i => stoi(s, i) = stoi(s, i - 1)
580
- 0 < i, len(s) > i => stoi(s, i) = 10*stoi(s, i - 1) + digit(nth_i(s, i - 1))
587
+ 0 < i, len(s) > i, stoi(s, i - 1) >= 0, is_digit(nth(s, i - 1)) => stoi(s, i) = 10*stoi(s, i - 1) + digit(nth_i(s, i - 1))
588
+ 0 < i, len(s) > i, stoi(s, i - 1) < 0 => stoi(s, i) = -1
589
+ 0 < i, len(s) > i, ~is_digit(nth(s, i - 1)) => stoi(s, i) = -1
590
+
591
+
581
592
582
593
Define auxiliary function with the property:
583
594
for 0 <= i < k
@@ -599,17 +610,30 @@ void seq_axioms::add_stoi_axiom(expr* e, unsigned k) {
599
610
m_rewrite (s);
600
611
auto stoi2 = [&](unsigned j) { return m_sk.mk (" seq.stoi" , s, a.mk_int (j), a.mk_int ()); };
601
612
auto digit = [&](unsigned j) { return m_sk.mk_digit2int (mk_nth (s, j)); };
613
+ auto is_digit_ = [&](unsigned j) { return is_digit (mk_nth (s, j)); };
602
614
expr_ref len = mk_len (s);
603
615
literal ge0 = mk_ge (e, 0 );
604
616
literal lek = mk_le (len, k);
605
- add_axiom (~ge0, ~mk_eq (len, a.mk_int(0 )));
606
- add_axiom (~ge0, ~lek, mk_eq (e, stoi2 (k-1 )));
607
- add_axiom (mk_le (len, 0 ), mk_eq (stoi2 (0 ), digit (0 )));
608
- add_axiom (~ge0, is_digit (mk_nth (s, 0 )));
617
+ add_axiom (~lek, mk_eq (e, stoi2 (k-1 ))); // len(s) <= k => stoi(s) = stoi(s, k-1)
618
+ add_axiom (mk_le (len, 0 ), ~is_digit_ (0 ), mk_eq (stoi2 (0 ), digit (0 ))); // len(s) > 0, is_digit(nth(s, 0)) => stoi(s,0) = digit(s,0)
619
+ add_axiom (mk_le (len, 0 ), is_digit_ (0 ), mk_eq (stoi2 (0 ), a.mk_int (-1 ))); // len(s) > 0, ~is_digit(nth(s, 0)) => stoi(s,0) = -1
609
620
for (unsigned i = 1 ; i < k; ++i) {
610
- add_axiom (mk_le (len, i), mk_eq (stoi2 (i), a.mk_add (a.mk_mul (a.mk_int (10 ), stoi2 (i-1 )), digit (i))));
621
+
622
+ // len(s) <= i => stoi(s, i) = stoi(s, i - 1)
623
+
611
624
add_axiom (~mk_le (len, i), mk_eq (stoi2 (i), stoi2 (i-1 )));
612
- add_axiom (~ge0, mk_le (len, i), is_digit (mk_nth (s, i)));
625
+
626
+ // len(s) > i, stoi(s, i - 1) >= 0, is_digit(nth(s, i)) => stoi(s, i) = 10*stoi(s, i - 1) + digit(i)
627
+ // len(s) > i, stoi(s, i - 1) < 0 => stoi(s, i) = -1
628
+ // len(s) > i, ~is_digit(nth(s, i)) => stoi(s, i) = -1
629
+
630
+ add_axiom (mk_le (len, i), ~mk_ge (stoi2(i-1 ), 0 ), ~is_digit_ (i), mk_eq (stoi2 (i), a.mk_add (a.mk_mul (a.mk_int (10 ), stoi2 (i-1 )), digit (i))));
631
+ add_axiom (mk_le (len, i), is_digit_ (i), mk_eq (stoi2 (i), a.mk_int (-1 )));
632
+ add_axiom (mk_le (len, i), mk_ge (stoi2 (i-1 ), 0 ), mk_eq (stoi2 (i), a.mk_int (-1 )));
633
+
634
+ // stoi(s) >= 0, i < len(s) => is_digit(nth(s, i))
635
+
636
+ add_axiom (~ge0, mk_le (len, i), is_digit_ (i));
613
637
}
614
638
}
615
639
0 commit comments