Skip to content

Test gen support string additional options #695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

romainbrenguier
Copy link
Contributor

This adds the option --string-max-length to the string solver, this constrains all the strings to be smaller than the maximal length. This shouldn't affect much the performance of the decision procedure but may be necessary for obtaining concrete traces (when the --trace option is activated).

I also added the options --string-non-empty to constrain the nondet strings to have length at least 1 (to avoid obtaining counter-example that concatenates the empty string two times, which is not very interesting), and --string-printable to constrain strings to contain only characters in the range between (space, U+0020) and ~ (tilde, U+007E). making the example nicer than a sequence of null characters.

This also fixes a couple of bugs in the solver.
This corresponds to PR #652 on master

\*******************************************************************/

exprt string_refinementt::substitute_array_with_expr
(exprt &expr, exprt &index) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use const

{
if(expr.id()==ID_with)
{
with_exprt &with_expr=to_with_expr(expr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const?

\*******************************************************************/

exprt string_refinementt::substitute_array_with_expr
(exprt &expr, exprt &index) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

( on previous line


\*******************************************************************/

exprt string_refinementt::substitute_array_access(exprt &expr) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make const

{
// TODO: only copy when necessary
exprt op(expr.operands()[i]);
expr.operands()[i]=substitute_array_access(op);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that making substitute_* do an in-place substitution could simplify the code.

for(auto &op : expr.operands())
  substitute_array_access(op);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made substitute_array_access in-place 14a1138
But I've let substitute_array_with_expr as it is because I think it is simpler in the current state.


if(index_expr.array().id()==ID_with)
{
exprt subst=substitute_array_with_expr(index_expr.array(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

break after (


size_t last_index=array_expr.operands().size()-1;
assert(last_index>=0);
exprt ite=array_expr.operands()[last_index];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop would be simpler if you considered the first element as default case of the ite chain. Is there a formula readability argument against this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The readability would be fine with first element as default, but I don't see why it would make the loop simpler. It would just shift the bounds by 1?

@@ -26,9 +26,17 @@ class string_constraint_generatort
// to the axiom list.

string_constraint_generatort():
mode(ID_unknown)
mode(ID_unknown),
max_string_length(-1),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the meaning of -1 ?

Function: string_refinementt::set_max_string_length

Inputs:
i - maximum length which is allowed for strings.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer using an unsigned integer and std::numeric_limits::max() as default upper limit. What is "no limit" supposed to mean in your case? What is the relation to MAX_CONCRETE_STRING_SIZE?

found_length[content]=length;
}
}
for(const auto& it : generator.created_strings)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto &it (several instances)

@@ -37,7 +37,7 @@ class optionst;
"(no-sat-preprocessor)" \
"(no-pretty-names)(beautify)" \
"(dimacs)(refine)(max-node-refinement):(refine-arrays)(refine-arithmetic)"\
"(refine-strings)" \
"(refine-strings)(string-non-empty)(string-printable)(string-max-length):" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to put each option on a separate line to facilitate merging.

@@ -61,10 +61,13 @@ class string_refinementt: public bv_refinementt
// Base class
typedef bv_refinementt supert;

unsigned initial_loop_bound;
unsigned long initial_loop_bound;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is ulong needed here? It's initialised from uint.

@peterschrammel
Copy link
Member

Please remove the [string-refine] prefix from commit messages.

mode=_mode;
}
// Constraints on the maximal length of strings
unsigned long max_string_length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a long here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because length of string in java are 32 bits integer, while int in c++ on some systems could be 16 bits if I'm not mistaken

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, minimum size of int is 16 bits. For Java, int32_t would make it independent of the system. For other languages, this might be different. Eg c++ string::max_size() tells me something close to 2^64 on my machine.

ite.type()=char_type;
}

for(long i=last_index-1; i>=0; --i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As pointed out earlier, this loop is not nice. The mixture of long, unsigned, size_t etc is likely to cause trouble. I dig up my earlier proposal that does without indexing.

@romainbrenguier romainbrenguier force-pushed the test-gen-support-string-additional-options branch from 5066dab to 6898cca Compare March 30, 2017 10:51
@peterschrammel
Copy link
Member

Superseded by #738

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants