diff --git a/src/solvers/strings/string_constraint_generator.h b/src/solvers/strings/string_constraint_generator.h index f439e5f28b3..01c9d2f119e 100644 --- a/src/solvers/strings/string_constraint_generator.h +++ b/src/solvers/strings/string_constraint_generator.h @@ -133,8 +133,6 @@ class string_constraint_generatort final std::pair add_axioms_for_equals_ignore_case(const function_application_exprt &f); - std::pair - add_axioms_for_is_empty(const function_application_exprt &f); std::pair add_axioms_for_is_prefix( const array_string_exprt &prefix, const array_string_exprt &str, diff --git a/src/solvers/strings/string_constraint_generator_main.cpp b/src/solvers/strings/string_constraint_generator_main.cpp index 81603410ed6..aa1904934c5 100644 --- a/src/solvers/strings/string_constraint_generator_main.cpp +++ b/src/solvers/strings/string_constraint_generator_main.cpp @@ -225,7 +225,21 @@ string_constraint_generatort::add_axioms_for_function_application( else if(id == ID_cprover_string_equals_ignore_case_func) return add_axioms_for_equals_ignore_case(expr); else if(id == ID_cprover_string_is_empty_func) - return add_axioms_for_is_empty(expr); + { + // Inlined logic from deprecated add_axioms_for_is_empty + // Returns true when the string is empty (length == 0) + PRECONDITION(expr.type() == bool_typet() || expr.type().id() == ID_c_bool); + PRECONDITION(expr.arguments().size() == 1); + const array_string_exprt s0 = + get_string_expr(array_pool, expr.arguments()[0]); + const symbol_exprt is_empty = fresh_symbol("is_empty"); + string_constraintst constraints; + constraints.existential = { + implies_exprt(is_empty, equal_to(array_pool.get_or_create_length(s0), 0)), + implies_exprt( + equal_to(array_pool.get_or_create_length(s0), 0), is_empty)}; + return {typecast_exprt(is_empty, expr.type()), std::move(constraints)}; + } else if(id == ID_cprover_string_char_at_func) return add_axioms_for_char_at(expr); else if(id == ID_cprover_string_is_prefix_func) diff --git a/src/solvers/strings/string_constraint_generator_testing.cpp b/src/solvers/strings/string_constraint_generator_testing.cpp index 9fab7d39601..0a54cf25d2e 100644 --- a/src/solvers/strings/string_constraint_generator_testing.cpp +++ b/src/solvers/strings/string_constraint_generator_testing.cpp @@ -10,11 +10,10 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com /// \file /// Generates string constraints for string functions that return Boolean values -#include "string_constraint_generator.h" - -#include #include +#include "string_constraint_generator.h" + /// Add axioms stating that the returned expression is true exactly when the /// offset is greater or equal to 0 and the first string is a prefix of the /// second one, starting at position offset. @@ -120,31 +119,6 @@ string_constraint_generatort::add_axioms_for_is_prefix( return {typecast_exprt(pair.first, f.type()), std::move(pair.second)}; } -/// Add axioms stating that the returned value is true exactly when the argument -/// string is empty. -/// \deprecated should use `string_length(s)==0` instead -/// \param f: function application with a string argument -/// \return a Boolean expression -DEPRECATED(SINCE(2017, 10, 5, "should use `string_length s == 0` instead")) -std::pair -string_constraint_generatort::add_axioms_for_is_empty( - const function_application_exprt &f) -{ - PRECONDITION(f.type() == bool_typet() || f.type().id() == ID_c_bool); - PRECONDITION(f.arguments().size() == 1); - // We add axioms: - // a1 : is_empty => |s0| = 0 - // a2 : s0 => is_empty - - symbol_exprt is_empty = fresh_symbol("is_empty"); - array_string_exprt s0 = get_string_expr(array_pool, f.arguments()[0]); - string_constraintst constraints; - constraints.existential = { - implies_exprt(is_empty, equal_to(array_pool.get_or_create_length(s0), 0)), - implies_exprt(equal_to(array_pool.get_or_create_length(s0), 0), is_empty)}; - return {typecast_exprt(is_empty, f.type()), std::move(constraints)}; -} - /// Test if the target is a suffix of the string /// /// Add axioms ensuring the return value is true when the first string ends with