@@ -1023,12 +1023,10 @@ void string_refinementt::substitute_array_access(exprt &expr) const
1023
1023
// / \pre Symbols other than the universal variable should have been replaced by
1024
1024
// / their valuation in the current model.
1025
1025
// / \param axiom: the not_contains constraint to add the negation of
1026
- // / \param val: the existential witness for the axiom
1027
1026
// / \param univ_var: the universal variable for the negation of the axiom
1028
1027
// / \return: the negation of the axiom under the current evaluation
1029
1028
exprt string_refinementt::negation_of_not_contains_constraint (
1030
1029
const string_not_contains_constraintt &axiom,
1031
- const exprt &val,
1032
1030
const symbol_exprt &univ_var)
1033
1031
{
1034
1032
exprt lbu=axiom.univ_lower_bound ();
@@ -1040,34 +1038,47 @@ exprt string_refinementt::negation_of_not_contains_constraint(
1040
1038
to_integer (to_constant_expr (ubu), ub_int);
1041
1039
if (ub_int<=lb_int)
1042
1040
{
1043
- debug () << " empty constraint with current model" << eom;
1041
+ debug () << " (string_refinement::check_axioms) empty constraint with "
1042
+ << " current model, adding false" << eom;
1044
1043
return false_exprt ();
1045
1044
}
1046
1045
}
1047
1046
1048
1047
exprt lbe=axiom.exists_lower_bound ();
1049
1048
exprt ube=axiom.exists_upper_bound ();
1050
1049
1050
+ INVARIANT (
1051
+ lbe.id ()==ID_constant && ube.id ()==ID_constant,
1052
+ string_refinement_invariantt (" please" ));
1053
+
1054
+ mp_integer lbe_int, ube_int;
1055
+ to_integer (to_constant_expr (lbe), lbe_int);
1056
+ to_integer (to_constant_expr (ube), ube_int);
1057
+
1051
1058
if (axiom.premise ()==false_exprt ())
1052
1059
{
1053
- debug () << " (string_refinement::check_axioms) adding false" << eom;
1060
+ debug () << " (string_refinement::check_axioms) false premise, adding false"
1061
+ << eom;
1054
1062
return false_exprt ();
1055
1063
}
1056
1064
1057
- // Witness is the Skolem function for the existential, which we evaluate at
1058
- // univ_var.
1059
1065
and_exprt univ_bounds (
1060
1066
binary_relation_exprt (lbu, ID_le, univ_var),
1061
1067
binary_relation_exprt (ubu, ID_gt, univ_var));
1062
- and_exprt exists_bounds (
1063
- binary_relation_exprt (lbe, ID_le, val),
1064
- binary_relation_exprt (ube, ID_gt, val));
1065
- equal_exprt equal_chars (
1066
- axiom.s0 ()[plus_exprt (univ_var, val)],
1067
- axiom.s1 ()[val]);
1068
- and_exprt negaxiom (univ_bounds, axiom.premise (), exists_bounds, equal_chars);
1069
-
1070
- debug () << " (sr::check_axioms) negated not_contains axiom: "
1068
+
1069
+ std::vector<exprt> conjuncts;
1070
+ for (mp_integer i=lbe_int; i<ube_int; i=i+1 )
1071
+ {
1072
+ const constant_exprt i_exprt=from_integer (i, univ_var.type ());
1073
+ const equal_exprt equal_chars (
1074
+ axiom.s0 ()[plus_exprt (univ_var, i_exprt)],
1075
+ axiom.s1 ()[i_exprt]);
1076
+ conjuncts.push_back (equal_chars);
1077
+ }
1078
+ exprt equal_strings=conjunction (conjuncts);
1079
+ and_exprt negaxiom (univ_bounds, axiom.premise (), equal_strings);
1080
+
1081
+ debug () << " (string_refinement::check_axioms) negated not_contains axiom: "
1071
1082
<< from_expr (ns, " " , negaxiom) << eom;
1072
1083
substitute_array_access (negaxiom);
1073
1084
return negaxiom;
@@ -1093,21 +1104,23 @@ exprt string_refinementt::negation_of_constraint(
1093
1104
to_integer (to_constant_expr (ub), ub_int);
1094
1105
if (ub_int<=lb_int)
1095
1106
{
1096
- debug () << " empty constraint with current model" << eom;
1107
+ debug () << " (string_refinement::check_axioms) empty constraint with "
1108
+ << " current model, adding false" << eom;
1097
1109
return false_exprt ();
1098
1110
}
1099
1111
}
1100
1112
1101
1113
if (axiom.premise ()==false_exprt ())
1102
1114
{
1103
- debug () << " (string_refinement::check_axioms) adding false" << eom;
1115
+ debug () << " (string_refinement::check_axioms) false premise, adding false"
1116
+ << eom;
1104
1117
return false_exprt ();
1105
1118
}
1106
1119
1107
1120
and_exprt premise (axiom.premise (), axiom.univ_within_bounds ());
1108
1121
and_exprt negaxiom (premise, not_exprt (axiom.body ()));
1109
1122
1110
- debug () << " (sr ::check_axioms) negated axiom: "
1123
+ debug () << " (string_refinement ::check_axioms) negated universal axiom: "
1111
1124
<< from_expr (ns, " " , negaxiom) << eom;
1112
1125
substitute_array_access (negaxiom);
1113
1126
return negaxiom;
@@ -1172,8 +1185,6 @@ bool string_refinementt::check_axioms()
1172
1185
1173
1186
symbol_exprt univ_var=generator.fresh_univ_index (
1174
1187
" not_contains_univ_var" , nc_axiom.s0 ().length ().type ());
1175
- exprt wit=generator.get_witness_of (nc_axiom, univ_var);
1176
- exprt val=get (wit);
1177
1188
const string_not_contains_constraintt nc_axiom_in_model (
1178
1189
get (univ_bound_inf),
1179
1190
get (univ_bound_sup),
@@ -1184,7 +1195,7 @@ bool string_refinementt::check_axioms()
1184
1195
to_string_expr (get (s1)));
1185
1196
1186
1197
const exprt negaxiom=negation_of_not_contains_constraint (
1187
- nc_axiom_in_model, val, univ_var);
1198
+ nc_axiom_in_model, univ_var);
1188
1199
exprt witness;
1189
1200
1190
1201
bool is_sat=is_axiom_sat (negaxiom, univ_var, witness);
@@ -1741,6 +1752,18 @@ exprt string_refinementt::get(const exprt &expr) const
1741
1752
if (it!=found_length.end ())
1742
1753
return get_array (ecopy, it->second );
1743
1754
}
1755
+ else if (refined_string_typet::is_refined_string_type (ecopy.type ()) &&
1756
+ ecopy.id ()==ID_struct)
1757
+ {
1758
+ string_exprt ecopy2=to_string_expr (ecopy);
1759
+ const exprt &econtent=ecopy2.content ();
1760
+ const exprt &elength=ecopy2.length ();
1761
+
1762
+ exprt len=supert::get (elength);
1763
+ len=simplify_expr (len, ns);
1764
+ const exprt arr=get_array (econtent, len);
1765
+ ecopy=string_exprt (len, arr, ecopy.type ());
1766
+ }
1744
1767
1745
1768
ecopy=supert::get (ecopy);
1746
1769
@@ -1772,6 +1795,7 @@ bool string_refinementt::is_axiom_sat(
1772
1795
}
1773
1796
case decision_proceduret::resultt::D_UNSATISFIABLE:
1774
1797
return false ;
1798
+ case decision_proceduret::resultt::D_ERROR:
1775
1799
default :
1776
1800
INVARIANT (false , string_refinement_invariantt (" failure in checking axiom" ));
1777
1801
// To tell the compiler that the previous line bails
0 commit comments