Skip to content

Intervals with tests #5361

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

Merged
merged 59 commits into from
Jun 4, 2020
Merged

Intervals with tests #5361

merged 59 commits into from
Jun 4, 2020

Conversation

thk123
Copy link
Contributor

@thk123 thk123 commented May 27, 2020

A note to reviewers, this PR, though large, is entirely an isolated addition util/interval. There are lots of ways this code could be improved (I've listed some in #5203) since VSD is based on top of this, I propose merging as is, and then applying fixes after - so I'd encourage not going through this with a fine tooth comb to find the ways it is wrong!

This is a rebase of #5203 that addresses I believe the most pressing issues:

  • ensures all tests are run on Make and CMake builds
  • fixes the errors in operator== that stops the tests actually checking things properly
  • fixes error in to string
  • adds a lot of tests for the missing coverage (still some gaps)
  • highlight some areas where the behavior is wrong
  • fixes bug in eval(ID_minus)
    Some gaps in the tests remain:

logical_or / logical_and / logical_xor
I believe these functions should be removed, and there just be a single method to get the range as a tvt, and then have these functions implemented on tvt. As such, I didn't write the tests.

code in the generate_* and append_* functions
The semantics of these aren't clear to me, and shouldn't be part of the public interface. Probably the code that is uncovered will be hard to cover if the interface is tidier

trivial type getters and constructors
There are loads of these, and they mostly need to be deleted. To avoid breaking, I recommend waiting until VSD is merged before deleting. However, not worth testing in the meantime.

wrappers
interval.cpp implements all of the calling conventions. This wants tidying up, but in the meantime I've not bothered to test every possible calling syntax.

typecast
This is worth testing, but I don't understand what it's doing and it seems fishy. However, it is used in VSD so I'll leave for now, so it can be tested / removed after VSD is merged.

TBH in the brief time I've spent with this, there are a bunch of bugs and inconsistencies here, if there wasn't a mountain of work built on top of it, I'd recommend breaking this into something smaller than works (e.g. remove the untested or broken functionality). However, this isn't really an option, so I suggest we merge like this, merge VSD and perhaps immediately remove the interval portion of the VSD, along with this, and reintroduce it gradually (allowing at least the bulk of VSD to be merged).

  • Each commit message has a non-empty body, explaining why the change was made.
  • Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • [na] My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@codecov
Copy link

codecov bot commented May 27, 2020

Codecov Report

Merging #5361 into develop will increase coverage by 0.00%.
The diff coverage is 68.36%.

Impacted file tree graph

@@            Coverage Diff            @@
##           develop    #5361    +/-   ##
=========================================
  Coverage    68.14%   68.14%            
=========================================
  Files         1171     1173     +2     
  Lines        96641    97333   +692     
=========================================
+ Hits         65858    66331   +473     
- Misses       30783    31002   +219     
Flag Coverage Δ
#cproversmt2 42.47% <ø> (ø)
#regression 65.36% <ø> (-0.01%) ⬇️
#unit 32.18% <68.36%> (+0.36%) ⬆️
Impacted Files Coverage Δ
src/util/interval.cpp 66.92% <66.92%> (ø)
src/util/interval.h 100.00% <100.00%> (ø)
src/solvers/strings/string_builtin_function.h 74.39% <0.00%> (-2.44%) ⬇️
src/util/threeval.h 85.71% <0.00%> (-1.79%) ⬇️
src/pointer-analysis/value_set_fi.h 97.56% <0.00%> (+2.43%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b27b828...1d92ca0. Read the comment docs.

@thk123
Copy link
Contributor Author

thk123 commented May 28, 2020

I've added test for binary eval (And found a bug in the process 😑), will add one for to_string since it also originally contained a bug and then this PR I believe is ready

@thk123
Copy link
Contributor Author

thk123 commented May 28, 2020

Added to_string tests and squashed clang format changes into the original commit that introduces them

@thk123 thk123 force-pushed the fix-vsd-intervals branch 2 times, most recently from 963d5b5 to b9e275b Compare May 28, 2020 09:21
@thk123 thk123 mentioned this pull request May 28, 2020
6 tasks
@thk123 thk123 force-pushed the fix-vsd-intervals branch from b9e275b to cf6e08e Compare May 28, 2020 09:37
@thk123
Copy link
Contributor Author

thk123 commented May 28, 2020

Removed the changes to interval_template, one into separate PR: #5362, the other changes essentially cancelled themselves out, so I just removed them both.

@thk123 thk123 force-pushed the fix-vsd-intervals branch from cf6e08e to c128252 Compare May 28, 2020 11:04
@thk123
Copy link
Contributor Author

thk123 commented May 28, 2020

CI failure is lint - will fix, but ready for review

@thk123 thk123 marked this pull request as ready for review May 28, 2020 13:10
@thk123 thk123 force-pushed the fix-vsd-intervals branch from c128252 to 5f0aeab Compare May 28, 2020 13:14
Copy link
Contributor

@smowton smowton left a comment

Choose a reason for hiding this comment

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

Some things to check, but as you say happy to get this in then fix it up subsequently. I didn't look at the big "fix crap after rebase" commit or the huge 2000-line "add intervals" one due to lack of time.

@@ -0,0 +1,52 @@
/*******************************************************************\
Module: Unit tests for variable/sensitivity/abstract_object::merge
Copy link
Contributor

Choose a reason for hiding this comment

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

Wrong header

REQUIRE(five.eval(ID_minus, eight) == interval_of(-3));
REQUIRE(five.eval(ID_mult, eight) == interval_of(40));
REQUIRE(five.eval(ID_div, eight) == interval_of(0));
REQUIRE(five.eval(ID_mod, eight) == interval_from_to(0, 5));
Copy link
Contributor

Choose a reason for hiding this comment

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

Checking this oddity is known

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is but i've added a comment to highlight it.

@@ -103,3 +103,62 @@ SCENARIO("Unary eval on intervals", "[core][analyses][interval][eval]")
}
}
}

TEST_CASE("binary eval switch", "[core][analyses][interval]")
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment that this only considers singletons?

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 guess - the reason for only considering singletons is each of the opertions is tested seperatly with both singleton and ranges, this test is really to check eval dispatches to the correct function

// REQUIRE(two_to_four.equal(six_to_eight).is_unknown());
REQUIRE_FALSE(two_to_four.equal(five_to_ten).is_true());

REQUIRE_FALSE(two_to_four.not_equal(six_to_eight).is_unknown());
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does the not-unknown one use six_to_eight but the others use five_to_ten?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah this seems like a confusing mess - I've broken it into 3 sections - same interval, overlapping interval, disjoint interval and used consistent intervals for equal and not equal.

REQUIRE(V(a_mod_b.get_upper()) == 5);

const auto b_mod_a = b.modulo(a);
// TODO: precision with single element modulo
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps add commented-out the results you would expect when fixed. Got a ticket for 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.

No - it isn't wrong and we have no intention to fix it any time soon - a ticket will just sit not getting done. I would only raise it once someone actually wanted this to be more precise. Perhaps TODO is wrong, perhaps should just say note modulo is very imprecise.

auto upper_value = numeric_cast<mp_integer>(
five_to_eight.eval(ID_unary_minus).get_upper());
REQUIRE(upper_value.has_value());
REQUIRE(upper_value.value() == -8);
Copy link
Contributor

Choose a reason for hiding this comment

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

Known bug that -((5, 8)) == (-8, -8)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Typo that gets fixed in later commit

THEN("When we apply unary subtraction to it, it should be negated")
{
auto negated_val = numeric_cast<mp_integer>(
five_to_eight.eval(ID_unary_minus).get_lower());
Copy link
Contributor

Choose a reason for hiding this comment

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

Compare equality against expected interval?

lower.type() = type;
if(this->type().id() == ID_bool && is_int(type))
{
unsigned lower_num = !has_no_lower_bound() && get_lower().is_true();
Copy link
Contributor

Choose a reason for hiding this comment

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

has-no-lower-bound but get-lower returns something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well it has a not before the has_no_lower_bound -This function is one of the functions I don't really get, but would want to tidy up only after the code that is already using it is merged so I can change both at the same time if necessary

WHEN("Subtracting two constant intervals")
{
auto lhs =
constant_interval_exprt(constant_exprt("1010", unsignedbv_typet(32)));
Copy link
Contributor

Choose a reason for hiding this comment

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

Use from_integer and perhaps binary numeric literals if you want to emphasise the bitpattern you intend. I think these might be broken too because constant_exprt expects hex representation?

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 thankfully ends up going away

@@ -105,15 +105,16 @@ constant_interval_exprt::plus(const constant_interval_exprt &o) const
}

constant_interval_exprt
constant_interval_exprt::minus(const constant_interval_exprt &o) const
constant_interval_exprt::minus(const constant_interval_exprt &other) const
Copy link
Contributor

Choose a reason for hiding this comment

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

Split commit "Remove swap function in intervals Also, refactor minus and correct a typo in the comments" to do one thing at a time

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Go on then - since it's your last day 😛

Thomas Kiley added 24 commits May 29, 2020 10:37
Currently checks are equivalent intervals, but before wasn't even
checking that
ireps now use hex encoding, updated to modern version to get string of
number
These aren't currently supported and cause a crash when executed
Currently this returns top rather than the actual range
Move some shift tests from the bitwise set of tests
Was wrongly using the unary negation operator, rather than subtracting
one interval from the other.
@thk123 thk123 force-pushed the fix-vsd-intervals branch 2 times, most recently from 4e39366 to 1d92ca0 Compare May 29, 2020 10:58
@thk123 thk123 merged commit 7edbf52 into diffblue:develop Jun 4, 2020
@thk123 thk123 deleted the fix-vsd-intervals branch June 4, 2020 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants