key icon indicating copy to clipboard operation
key copied to clipboard

Fix for the LoopInvariantConfigurationDialog

Open unp1 opened this issue 2 years ago • 9 comments

Related Issue

This PR fixes a bug that prevented the interactive provision of a loop invariant.

Intended Change

It should be possible to enter loop invariants manually.

Type of pull request

  • [x] Bug fix (non-breaking change which fixes an issue)
  • [ ] Refactoring (behaviour should not change or only minimally change)
  • [ ] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to change)
  • [x] There are changes to the (Java) code
  • [ ] There are changes to the taclet rule base
  • [ ] There are changes to the deployment/CI infrastructure (gradle, github, ...)
  • [ ] Other:

Ensuring quality

  • [ ] I made sure that introduced/changed code is well documented (javadoc and inline comments).
  • [ ] I made sure that new/changed end-user features are well documented (https://github.com/KeYProject/key-docs).
  • [ ] I added new test case(s) for new functionality.
  • [x] I have tested the feature as follows: Applied a manually entered loop invariant
  • [ ] I have checked that runtime performance has not deteriorated.

Additional information and contact(s)

The problem was if no "free modifies"/"free assignable" was available then creating the whole modifies set "union(freeMod, mod)" led to a NullPointerException. The fix uses "strictly_nothing" as default for free assignables of loops, if non given.

The contributions within this pull request are licensed under GPLv2 (only) for inclusion in KeY.

unp1 avatar Dec 20 '23 09:12 unp1

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (a92f04e) 37.98% compared to head (cc53817) 37.98%.

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #3377   +/-   ##
=========================================
  Coverage     37.98%   37.98%           
  Complexity    17024    17024           
=========================================
  Files          2059     2059           
  Lines        126029   126032    +3     
  Branches      21282    21283    +1     
=========================================
+ Hits          47875    47877    +2     
  Misses        72272    72272           
- Partials       5882     5883    +1     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Dec 20 '23 09:12 codecov[bot]

I do not really understand the problem from the description. By "free modifier", do you mean "assignable_free"? How can this be used in interactively specified loops at all?

WolframPfeifer avatar Dec 20 '23 10:12 WolframPfeifer

Yes and yes :-) The problem is that the "assignable_free" clause cannot be specified in the dialoh and therefore "null" was returned as its instantiation, which then lead to an NPE.

Looking at the code, a specified (via JML) "assignable_free" clause would cause the actual modifies set to be "union(mod, freeMod)", hence I assume, strictly_nothing should be the intended default? This is now used, if no "assignable_free" is given.

A simple example is the attached file. The invariant specification for the dialog is

invariant: i>=0 & i<=n modifies: {} variant: n - i

In the current version that leads to an NPE simple.txt

Changed the "additional information" section in the PR description for more clarity.

unp1 avatar Dec 20 '23 12:12 unp1

Yes and yes :-) The problem is that the assignable_free cannot be specified and therefore "null" was returned as instantiation which then lead to an NPE.

Looking at the code, a specified (via JML) free assignable would cause the actual modifies set to be "union(mod, freeMod)", hence I assume, strictly_nothing should be the intended default (?), which is now used if that no free_assignable can be found.

A simple example is the attached file. The invariant specification to enter in the dialog is

invariant: i>=0 & i<=n modifies: {} variant: n - i

In the current version that leads to an NPE simple.txt

Changed additional information section in the PR description for more clarity.

Thanks for the explanation. I have to admit that I find the ..._free clauses quite confusing. I talked to @flo2702 today, who implemented the ..._free clauses, and he convinced me that indeed \strictly_nothing is the correct default here.

With the changes in this branch, something is very strange now: I can not even close an easy proof with a loop that writes only a single field. The problem seems to be that there are two different self variables (different hashes) ...

WolframPfeifer avatar Dec 20 '23 15:12 WolframPfeifer

With the changes in this branch, something is very strange now: I can not even close an easy proof with a loop that writes only a single field. The problem seems to be that there are two different self variables (different hashes) ...

Just to be sure, you mean when using the dialog for the loop invariant (not as JML annotation)? If yes, I assume the bug is not introduced by this patch as it does not touch anything remotely related to "self", but I can have a look and try to fix it.

If no, that is really strange (and I will have a look in any case ;-)

unp1 avatar Dec 20 '23 15:12 unp1

With the changes in this branch, something is very strange now: I can not even close an easy proof with a loop that writes only a single field. The problem seems to be that there are two different self variables (different hashes) ...

Just to be sure, you mean when using the dialog for the loop invariant (not as JML annotation)? If yes, I assume the bug is not introduced by this patch as it does not touch anything remotely related to "self", but I can have a look and try to fix it.

If no, that is really strange (and I will have a look in any case ;-)

Yes, when using the dialog. I think this error has been on the main branch for a while, but since the dialog did not work anyway, probably nobody noticed it.

WolframPfeifer avatar Dec 20 '23 15:12 WolframPfeifer

With the changes in this branch, something is very strange now: I can not even close an easy proof with a loop that writes only a single field. The problem seems to be that there are two different self variables (different hashes) ...

Just to be sure, you mean when using the dialog for the loop invariant (not as JML annotation)? If yes, I assume the bug is not introduced by this patch as it does not touch anything remotely related to "self", but I can have a look and try to fix it. If no, that is really strange (and I will have a look in any case ;-)

Yes, when using the dialog. I think this error has been on the main branch for a while, but since the dialog did not work anyway, probably nobody noticed it.

The latest commit fixes the duplicate self issue.

There is one general issue: The configurator prefills the dialog with JML loop specifications if available. This uses the "internal self", i.e., the placeholder self from the loop invariant translation. This might either not be present in practice (e.g., if we verify a static method which calls an instance method on some object that contains a loop) or the self is not the correct one. Worst case scenarios:

  1. there is a parser error or
  2. the self is for a different object of a different class ==> In n both cases one needs to replace the used self by the correct object.
  3. the used self variable is for a different object of the same class, in which case the loop specification parses but is not provable and one has to find out why. This might be annoying as one wastes time looking for logic mistakes in the loop invariant and not something as simple as that the 'this' object is the wrong one.

To fix that properly one would need to analyse the sequent to find out which self (if any to use). That is not done in the current fix (for time reasons). I would suggest to open a new feature/bug request so that it can be attacked at later time.

unp1 avatar Dec 21 '23 10:12 unp1

Rebased on current main. Loop invariant dialog works again w/o NPE.

@WolframPfeifer: Ready for review, thanks!

unp1 avatar Aug 13 '24 10:08 unp1

I think the Qodana and Checkerframework fails are unrelated to this PR.

unp1 avatar Aug 13 '24 11:08 unp1