CBMC
string_insertion_builtin_function.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: String solver
4 
5 Author: Romain Brenguier, romain.brenguier@diffblue.com
6 
7 \*******************************************************************/
8 
10 #include <algorithm>
11 #include <iterator>
12 
14 {
15  PRECONDITION(args.size() == 1);
16  return equal_exprt(
18  plus_exprt(
21 }
22 
24  const exprt &return_code,
25  const std::vector<exprt> &fun_args,
26  array_poolt &array_pool)
27  : string_builtin_functiont(return_code, array_pool)
28 {
29  PRECONDITION(fun_args.size() > 4);
30  const auto arg1 = expr_checked_cast<struct_exprt>(fun_args[2]);
31  input1 = array_pool.find(arg1.op1(), arg1.op0());
32  const auto arg2 = expr_checked_cast<struct_exprt>(fun_args[4]);
33  input2 = array_pool.find(arg2.op1(), arg2.op0());
34  result = array_pool.find(fun_args[1], fun_args[0]);
35  args.push_back(fun_args[3]);
36  args.insert(args.end(), fun_args.begin() + 5, fun_args.end());
37 }
38 
40  const std::vector<mp_integer> &input1_value,
41  const std::vector<mp_integer> &input2_value,
42  const std::vector<mp_integer> &args_value) const
43 {
44  PRECONDITION(args_value.size() >= 1 && args_value.size() <= 3);
45  const auto offset = std::min(
46  std::max(args_value[0], mp_integer(0)), mp_integer(input1_value.size()));
47  const auto start = args_value.size() > 1
48  ? std::max(args_value[1], mp_integer(0))
49  : mp_integer(0);
50 
51  const mp_integer input2_size(input2_value.size());
52  const auto end =
53  args_value.size() > 2
54  ? std::max(std::min(args_value[2], input2_size), mp_integer(0))
55  : input2_size;
56 
57  std::vector<mp_integer> eval_result(input1_value);
58  eval_result.insert(
59  eval_result.begin() + numeric_cast_v<std::size_t>(offset),
60  input2_value.begin() + numeric_cast_v<std::size_t>(start),
61  input2_value.begin() + numeric_cast_v<std::size_t>(end));
62  return eval_result;
63 }
64 
66  const std::function<exprt(const exprt &)> &get_value) const
67 {
68  const auto &input1_value = eval_string(input1, get_value);
69  const auto &input2_value = eval_string(input2, get_value);
70  if(!input2_value.has_value() || !input1_value.has_value())
71  return {};
72 
73  std::vector<mp_integer> arg_values;
74  const auto &insert = std::back_inserter(arg_values);
75  const mp_integer unknown('?');
77  args.begin(), args.end(), insert, [&](const exprt &e) { // NOLINT
78  if(const auto val = numeric_cast<mp_integer>(get_value(e)))
79  return *val;
80  return unknown;
81  });
82 
83  const auto result_value = eval(*input1_value, *input2_value, arg_values);
84  const auto length = from_integer(result_value.size(), result.length_type());
85  const array_typet type(to_type_with_subtype(result.type()).subtype(), length);
86  return make_string(result_value, type);
87 }
88 
91  message_handlert &message_handler) const
92 {
93  PRECONDITION(args.size() == 1);
94  const exprt &offset = args[0];
95  PRECONDITION(offset.type() == input1.length_type());
97  const exprt offset1 = maximum(
100 
102 
103  // Axiom 1.
105 
106  // Axiom 2.
107  constraints.universal.push_back([&] { // NOLINT
108  const symbol_exprt i = generator.fresh_symbol("QA_insert1", index_type);
109  return string_constraintt(
110  i, offset1, equal_exprt(result[i], input1[i]), message_handler);
111  }());
112 
113  // Axiom 3.
114  constraints.universal.push_back([&] { // NOLINT
115  const symbol_exprt i = generator.fresh_symbol("QA_insert2", index_type);
116  return string_constraintt(
117  i,
119  equal_exprt(result[plus_exprt(i, offset1)], input2[i]),
120  message_handler);
121  }());
122 
123  // Axiom 4.
124  constraints.universal.push_back([&] { // NOLINT
125  const symbol_exprt i = generator.fresh_symbol("QA_insert3", index_type);
126  return string_constraintt(
127  i,
128  offset1,
130  equal_exprt(
132  input1[i]),
133  message_handler);
134  }());
135 
136  // return_code = 0
137  constraints.existential.push_back(
139 
140  return constraints;
141 }
array_string_exprt::length_type
const typet & length_type() const
Definition: string_expr.h:69
mp_integer
BigInt mp_integer
Definition: smt_terms.h:17
array_poolt::find
array_string_exprt find(const exprt &pointer, const exprt &length)
Creates a new array if the pointer is not pointing to an array.
Definition: array_pool.cpp:184
minimum
exprt minimum(const exprt &a, const exprt &b)
Definition: string_constraint_generator_main.cpp:398
string_insertion_builtin_functiont::length_constraint
exprt length_constraint() const override
Definition: string_insertion_builtin_function.cpp:13
typet
The type of an expression, extends irept.
Definition: type.h:28
transform
static abstract_object_pointert transform(const exprt &expr, const std::vector< abstract_object_pointert > &operands, const abstract_environmentt &environment, const namespacet &ns)
Definition: abstract_value_object.cpp:159
array_poolt
Correspondance between arrays and pointers string representations.
Definition: array_pool.h:41
string_builtin_functiont::return_code
exprt return_code
Definition: string_builtin_function.h:111
string_constraintt
Definition: string_constraint.h:55
string_constraint_generatort::fresh_symbol
symbol_generatort fresh_symbol
Definition: string_constraint_generator.h:61
array_poolt::get_or_create_length
exprt get_or_create_length(const array_string_exprt &s)
Get the length of an array_string_exprt from the array_pool.
Definition: array_pool.cpp:26
to_type_with_subtype
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition: type.h:193
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
exprt
Base class for all expressions.
Definition: expr.h:55
string_constraintst
Collection of constraints of different types: existential formulas, universal formulas,...
Definition: string_constraint_generator.h:38
string_insertion_builtin_function.h
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
index_type
bitvector_typet index_type()
Definition: c_types.cpp:22
equal_exprt
Equality.
Definition: std_expr.h:1305
string_constraint_generatort
Definition: string_constraint_generator.h:47
string_builtin_functiont::array_pool
array_poolt & array_pool
Definition: string_builtin_function.h:122
string_insertion_builtin_functiont::input1
array_string_exprt input1
Definition: string_insertion_builtin_function.h:19
string_insertion_builtin_functiont::eval
virtual std::vector< mp_integer > eval(const std::vector< mp_integer > &input1_value, const std::vector< mp_integer > &input2_value, const std::vector< mp_integer > &args_value) const
Evaluate the result from a concrete valuation of the arguments.
Definition: string_insertion_builtin_function.cpp:39
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
string_insertion_builtin_functiont::result
array_string_exprt result
Definition: string_insertion_builtin_function.h:18
maximum
exprt maximum(const exprt &a, const exprt &b)
Definition: string_constraint_generator_main.cpp:403
string_insertion_builtin_functiont::string_insertion_builtin_functiont
string_insertion_builtin_functiont(const exprt &return_code, const std::vector< exprt > &fun_args, array_poolt &array_pool)
Constructor from arguments of a function application.
Definition: string_insertion_builtin_function.cpp:23
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
make_string
static array_string_exprt make_string(Iter begin, Iter end, const array_typet &array_type)
Definition: string_builtin_function.cpp:59
message_handlert
Definition: message.h:27
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
get_return_code_type
signedbv_typet get_return_code_type()
Definition: string_constraint_generator_main.cpp:182
string_builtin_functiont
Base class for string functions that are built in the solver.
Definition: string_builtin_function.h:72
eval_string
optionalt< std::vector< mp_integer > > eval_string(const array_string_exprt &a, const std::function< exprt(const exprt &)> &get_value)
Given a function get_value which gives a valuation to expressions, attempt to find the current value ...
Definition: string_builtin_function.cpp:24
array_typet
Arrays with given size.
Definition: std_types.h:762
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
zero_if_negative
exprt zero_if_negative(const exprt &expr)
Returns a non-negative version of the argument.
Definition: string_constraint_generator_main.cpp:411
string_insertion_builtin_functiont::constraints
string_constraintst constraints(string_constraint_generatort &generator, message_handlert &message_handler) const override
Constraints ensuring the result corresponds to input1 where we inserted input2 at position offset giv...
Definition: string_insertion_builtin_function.cpp:89
type_with_subtypet::subtype
const typet & subtype() const
Definition: type.h:172
string_insertion_builtin_functiont::input2
array_string_exprt input2
Definition: string_insertion_builtin_function.h:20
string_insertion_builtin_functiont::args
std::vector< exprt > args
Definition: string_insertion_builtin_function.h:21
string_constraintst::existential
std::vector< exprt > existential
Definition: string_constraint_generator.h:40
string_constraintst::universal
std::vector< string_constraintt > universal
Definition: string_constraint_generator.h:41