Skip to content

Commit 9edbb90

Browse files
[string-refinement] Change get_array to return optional
Now returns optional with no value if the model of the array is incomplete instead of an empty string. This way the result of get is more coherent: we return the same expression as the input if the model cannot be found, instead of an empty string.
1 parent 86e4782 commit 9edbb90

File tree

1 file changed

+50
-73
lines changed

1 file changed

+50
-73
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 50 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static std::vector<exprt> instantiate(
9191
const index_set_pairt &index_set,
9292
const string_constraint_generatort &generator);
9393

94-
static exprt get_array(
94+
static optionalt<exprt> get_array(
9595
const std::function<exprt(const exprt &)> &super_get,
9696
const namespacet &ns,
9797
const std::size_t max_string_length,
@@ -675,12 +675,12 @@ void string_refinementt::add_lemma(
675675
prop.l_set_to_true(convert(simple_lemma));
676676
}
677677

678-
/// get a model of an array and put it in a certain form. If the size cannot be
679-
/// obtained or if it is too big, return an empty array.
678+
/// Get a model of an array and put it in a certain form.
679+
/// If the model is incomplete or if it is too big, return no value.
680680
/// \par parameters: an expression representing an array and an expression
681681
/// representing an integer
682-
/// \return an array expression or an array_of_exprt
683-
static exprt get_array(
682+
/// \return an optional array expression or array_of_exprt
683+
static optionalt<exprt> get_array(
684684
const std::function<exprt(const exprt &)> &super_get,
685685
const namespacet &ns,
686686
const std::size_t max_string_length,
@@ -701,14 +701,14 @@ static exprt get_array(
701701
{
702702
stream << "(sr::get_array) string of unknown size: "
703703
<< from_expr(ns, "", size_val) << eom;
704-
return empty_ret;
704+
return {};
705705
}
706706

707707
unsigned n;
708708
if(to_unsigned_integer(to_constant_expr(size_val), n))
709709
{
710710
stream << "(sr::get_array) size is not valid" << eom;
711-
return empty_ret;
711+
return {};
712712
}
713713

714714
const array_typet ret_type(char_type, from_integer(n, index_type));
@@ -717,7 +717,7 @@ static exprt get_array(
717717
if(n>max_string_length)
718718
{
719719
stream << "(sr::get_array) long string (size=" << n << ")" << eom;
720-
return empty_ret;
720+
return {};
721721
}
722722

723723
if(n==0)
@@ -751,45 +751,8 @@ static exprt get_array(
751751
ret.move_to_operands(arr_val.operands()[i]);
752752
return ret;
753753
}
754-
else if(arr_val.id() == ID_constant && arr_val.type().id() == ID_pointer)
755-
{
756-
UNREACHABLE;
757-
#if 0
758-
// simplify_expr does not do this simplification (although from_expr does)
759-
if(arr_val.operands().size()==1
760-
&& arr_val.op0().id()==ID_address_of
761-
&& arr_val.op0().op0().id()==ID_index
762-
&& to_index_expr(arr_val.op0().op0()).index().is_zero())
763-
{
764-
arr_val=to_index_expr(arr_val.op0().op0()).array();
765-
}
766-
arr_val=simplify_expr(arr_val, ns);
767-
auto arr_index_set=get_index_set(index_set, arr_val);
768-
if(!arr_index_set.empty())
769-
{
770-
std::map<std::size_t, exprt> value_map;
771-
for(exprt index : arr_index_set)
772-
{
773-
mp_integer mp_key;
774-
to_integer(index, mp_key);
775-
exprt val=simplify_expr(get(index_exprt(arr_val, index)), ns);
776-
value_map[mp_key.to_long()]=val;
777-
}
778-
779-
std::vector<exprt> concrete_array=fill_in_map_as_vector(value_map);
780-
array_exprt arr(ret_type);
781-
arr.operands()=concrete_array;
782-
return arr;
783-
}
784-
#endif
785-
}
786-
#if 0
787-
else
788-
stream << "warning: get_array empty index set for "
789-
<< from_expr(ns, "", arr_val) << eom;
790-
#endif
791-
// default return value is an array of `0`s
792-
return array_of_exprt(from_integer(0, char_type), ret_type);
754+
else
755+
return {};
793756
}
794757

795758
/// convert the content of a string to a more readable representation. This
@@ -820,25 +783,39 @@ static exprt get_char_array_in_model(
820783
stream << "- " << from_expr(ns, "", arr) << ":\n";
821784
stream << indent << indent << "- type: " << from_type(ns, "", arr.type())
822785
<< eom;
823-
exprt arr_model = get_array(super_get, ns, max_string_length, stream, arr);
824-
stream << indent << indent << "- char_array: " << from_expr(ns, "", arr_model)
825-
<< eom;
826-
arr_model = simplify_expr(arr_model, ns);
827-
stream << indent << indent
828-
<< "- simplified_char_array: " << from_expr(ns, "", arr_model) << eom;
829-
const exprt concretized_array =
830-
concretize_arrays_in_expression(arr_model, max_string_length, ns);
831-
stream << indent << indent
832-
<< "- concretized_char_array: " << from_expr(ns, "", concretized_array)
833-
<< eom;
834-
if(concretized_array.id() == ID_array)
835-
stream << indent << indent << "- as_string: \""
836-
<< string_of_array(to_array_expr(concretized_array)) << "\"\n";
786+
const auto arr_model_opt =
787+
get_array(super_get, ns, max_string_length, stream, arr);
788+
if(arr_model_opt)
789+
{
790+
stream << indent << indent
791+
<< "- char_array: " << from_expr(ns, "", *arr_model_opt) << eom;
792+
const exprt simple = simplify_expr(*arr_model_opt, ns);
793+
stream << indent << indent
794+
<< "- simplified_char_array: " << from_expr(ns, "", simple) << eom;
795+
const exprt concretized_array =
796+
concretize_arrays_in_expression(simple, max_string_length, ns);
797+
stream << indent << indent << "- concretized_char_array: "
798+
<< from_expr(ns, "", concretized_array) << eom;
799+
800+
if(concretized_array.id() == ID_array)
801+
{
802+
stream << indent << indent << "- as_string: \""
803+
<< string_of_array(to_array_expr(concretized_array)) << "\"\n";
804+
}
805+
else
806+
{
807+
stream << indent << "- warning: not an array" << eom;
808+
}
809+
810+
stream << indent << indent
811+
<< "- type: " << from_type(ns, "", concretized_array.type()) << eom;
812+
return concretized_array;
813+
}
837814
else
838-
stream << indent << "- warning: not an array" << eom;
839-
stream << indent << indent
840-
<< "- type: " << from_type(ns, "", concretized_array.type()) << eom;
841-
return concretized_array;
815+
{
816+
stream << indent << indent << "- incomplete model" << eom;
817+
return arr;
818+
}
842819
}
843820

844821
/// Display part of the current model by mapping the variables created by the
@@ -1937,17 +1914,17 @@ exprt string_refinementt::get(const exprt &expr) const
19371914
{
19381915
array_string_exprt &arr = to_array_string_expr(ecopy);
19391916
arr.length() = generator.get_length_of_string_array(arr);
1940-
exprt arr_model =
1917+
const auto arr_model_opt =
19411918
get_array(super_get, ns, generator.max_string_length, debug(), arr);
19421919
// Should be refactored with get array or get array in model
1943-
arr_model = simplify_expr(arr_model, ns);
1944-
const exprt concretized_array = concretize_arrays_in_expression(
1945-
arr_model, generator.max_string_length, ns);
1946-
debug() << "get " << from_expr(ns, "", expr) << " --> "
1947-
<< from_expr(ns, "", concretized_array) << eom;
1948-
return concretized_array;
1920+
if(arr_model_opt)
1921+
{
1922+
const exprt arr_model = simplify_expr(*arr_model_opt, ns);
1923+
const exprt concretized_array = concretize_arrays_in_expression(
1924+
arr_model, generator.max_string_length, ns);
1925+
return concretized_array;
1926+
}
19491927
}
1950-
19511928
return supert::get(ecopy);
19521929
}
19531930

0 commit comments

Comments
 (0)