19
19
// / equal.
20
20
// / \param res: array of characters for the result
21
21
// / \param sval: a string constant
22
+ // / \param guard: condition under which the axiom should apply, true by default
22
23
// / \return integer expression equal to zero
23
24
exprt string_constraint_generatort::add_axioms_for_constant (
24
25
const array_string_exprt &res,
25
- irep_idt sval)
26
+ irep_idt sval,
27
+ const exprt &guard)
26
28
{
27
29
const typet &index_type = res.length ().type ();
28
30
const typet &char_type = res.content ().type ().subtype ();
@@ -43,12 +45,12 @@ exprt string_constraint_generatort::add_axioms_for_constant(
43
45
const exprt idx = from_integer (i, index_type);
44
46
const exprt c = from_integer (str[i], char_type);
45
47
const equal_exprt lemma (res[idx], c);
46
- axioms.push_back (lemma);
48
+ axioms.push_back (implies_exprt (guard, lemma) );
47
49
}
48
50
49
51
const exprt s_length = from_integer (str.size (), index_type);
50
52
51
- axioms.push_back (res.axiom_for_has_length ( s_length));
53
+ axioms.push_back (implies_exprt (guard, equal_exprt ( res.length (), s_length) ));
52
54
return from_integer (0 , get_return_code_type ());
53
55
}
54
56
@@ -65,6 +67,39 @@ exprt string_constraint_generatort::add_axioms_for_empty_string(
65
67
return from_integer (0 , get_return_code_type ());
66
68
}
67
69
70
+ // / Convert an expression of type string_typet to a string_exprt
71
+ // / \param res: string expression for the result
72
+ // / \param arg: expression of type string typet
73
+ // / \param guard: condition under which `res` should be equal to arg
74
+ // / \return 0 if constraints were added, 1 if expression could not be handled
75
+ // / and no constraint was added. Expression we can handle are of the
76
+ // / form \f$ e := "<string constant>" | (expr)? e : e \f$
77
+ exprt string_constraint_generatort::add_axioms_for_cprover_string (
78
+ const array_string_exprt &res,
79
+ const exprt &arg,
80
+ const exprt &guard)
81
+ {
82
+ if (const auto if_expr = expr_try_dynamic_cast<if_exprt>(arg))
83
+ {
84
+ const and_exprt guard_true (guard, if_expr->cond ());
85
+ const exprt return_code_true =
86
+ add_axioms_for_cprover_string (res, if_expr->true_case (), guard_true);
87
+
88
+ const and_exprt guard_false (guard, not_exprt (if_expr->cond ()));
89
+ const exprt return_code_false =
90
+ add_axioms_for_cprover_string (res, if_expr->false_case (), guard_false);
91
+
92
+ return if_exprt (
93
+ equal_exprt (return_code_true, from_integer (0 , get_return_code_type ())),
94
+ return_code_false,
95
+ return_code_true);
96
+ }
97
+ else if (const auto constant_expr = expr_try_dynamic_cast<constant_exprt>(arg))
98
+ return add_axioms_for_constant (res, constant_expr->get_value (), guard);
99
+ else
100
+ return from_integer (1 , get_return_code_type ());
101
+ }
102
+
68
103
// / String corresponding to an internal cprover string
69
104
// /
70
105
// / Add axioms ensuring that the returned string expression is equal to the
@@ -79,7 +114,5 @@ exprt string_constraint_generatort::add_axioms_from_literal(
79
114
const function_application_exprt::argumentst &args=f.arguments ();
80
115
PRECONDITION (args.size () == 3 ); // Bad args to string literal?
81
116
const array_string_exprt res = char_array_of_pointer (args[1 ], args[0 ]);
82
- const exprt &arg = args[2 ];
83
- irep_idt sval=to_constant_expr (arg).get_value ();
84
- return add_axioms_for_constant (res, sval);
117
+ return add_axioms_for_cprover_string (res, args[2 ], true_exprt ());
85
118
}
0 commit comments