Skip to content

CONTRACTS: Documenting semantic of loop invariant synthesizers #7089

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

Conversation

qinheping
Copy link
Collaborator

This PR contains only documentations. It explain the semantic of the loop-invariant synthesizer interface and the enumerative synthesizer. The motivating discussion is in the PR#7007.

Yes, my original goals of this enumerative_loop_invariant_synthesizert were the scale B: synthesis with guarantees/hard constraints. You are right that there can be varied guarantees other than only B---all checks success.
So I think for the base class, we only expect the returned exprt are loop invariants in the sense that

  1. the instrumented loop invariant checks success no matter other assertions fail or success---so we just ignore even if an assertion is false in the loop;
  2. the base-case is from the whole program with a main function as entry.

Derived classes can have their own guarantees. Each derived class should specify what the users can expect about the returned loop invariants. And users can choose which synthesizer to use with options under the --synthesize-loop-invariants flag.

@codecov
Copy link

codecov bot commented Aug 31, 2022

Codecov Report

Base: 77.86% // Head: 77.88% // Increases project coverage by +0.02% 🎉

Coverage data is based on head (83b85eb) compared to base (787b3c1).
Patch coverage: 89.28% of modified lines in pull request are covered.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #7089      +/-   ##
===========================================
+ Coverage    77.86%   77.88%   +0.02%     
===========================================
  Files         1574     1576       +2     
  Lines       181363   181855     +492     
===========================================
+ Hits        141223   141644     +421     
- Misses       40140    40211      +71     
Impacted Files Coverage Δ
src/goto-instrument/contracts/contracts.h 100.00% <ø> (ø)
...nthesizer/enumerative_loop_invariant_synthesizer.h 100.00% <ø> (ø)
...ment/synthesizer/loop_invariant_synthesizer_base.h 100.00% <ø> (ø)
src/goto-instrument/contracts/cfg_info.h 84.21% <82.35%> (-3.47%) ⬇️
src/ansi-c/c_expr.h 100.00% <100.00%> (ø)
src/ansi-c/c_typecheck_code.cpp 77.15% <100.00%> (ø)
src/goto-instrument/contracts/contracts.cpp 96.29% <100.00%> (+1.97%) ⬆️
src/cpp/cpp_template_type.h 52.94% <0.00%> (-11.35%) ⬇️
src/util/pointer_expr.h 80.83% <0.00%> (-7.29%) ⬇️
... and 91 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@feliperodri feliperodri added aws Bugs or features of importance to AWS CBMC users Code Contracts Function and loop contracts labels Aug 31, 2022
@feliperodri
Copy link
Collaborator

@Herbping @SaswatPadhi @remi-delmas-3000 maybe we should create a folder inside docs named contracts and add all .md files with documentation for code contracts in there instead of keeping adding multiple files with "contracts" prefix. We can then update the CODEOWNERS list of that folder.

assertions fail or success;
2. the base-case is from the whole GOTO program with a main
function as the entry point.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you provide an example here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I find these two points somewhat unclear. An example might help, as Felipe mentioned, especially for point 1.

I would probably just remove point 2. "main function" need not be the entrypoint for CBMC (can be overriden), and the base case is no different from any other symex path -- the path constraint along a path that reaches the loop head is the base case.

It might be worth adding a pointer to semantics of loop invariants (contracts-invariants.md#semantics), which already covers the induction principle.

Copy link
Collaborator Author

@qinheping qinheping Sep 1, 2022

Choose a reason for hiding this comment

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

The first point I want to make here is that we only care about if the invariant is inductive, but not other checks (even if there is assert(0); in the loop). The purpose of the second point is to distinguish: 1) the invariants are inductive for any inputs of the function, and 2) the invariants are inductive for only paths in the given GOTO binary.

As an example, k == 1 is an inductive invariant in the following program. However, it is not always inductive if we only consider the function foo---it doesn't hold when the parameter k is not 1.

void foo(int k)
{
  for(int i = 0; i < 5; i++)
  {
    if(k != 1)
      k = 2;
  }
}

void main()
{
  foo(1);
}

You are right that the semantics of loop invariants is enough to illustrate the point. I will update the text and add a link to the semantics of loop invariants.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I still few this section needs an example. Take a small program, check the program with pointer checks enable using a bound, synthesize the invariant, check the problem again without the bound. One of the most important part of the documentation is to walk potential users and future developers in the process of how to use this tool.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I like the idea of examples. It would also be good to discuss what the initial state is as part of defining / saying they are inductive.

Copy link
Collaborator

@remi-delmas-3000 remi-delmas-3000 Sep 2, 2022

Choose a reason for hiding this comment

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

If the invariants are inferred in the context of a proof harness that does not fully cover the input space of the function that contains the loop, is there a risk that we could assume the invariant in a different context where it could actually not hold without realizing it?
Or would we attempt to re-prove the inferred invariant in each context in which the function that contains the loop gets called ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It could happen but it should not be silent as the check for whether it is a loop invariant should fail in the new context. I presume we have tests for "__CPROVER_invariant that aren't actually true?

@feliperodri feliperodri added Synthesis Invariant synthesis and removed Code Contracts Function and loop contracts labels Aug 31, 2022
Copy link
Contributor

@SaswatPadhi SaswatPadhi left a comment

Choose a reason for hiding this comment

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

Requesting some more clarification on a few things.

assertions fail or success;
2. the base-case is from the whole GOTO program with a main
function as the entry point.

Copy link
Contributor

Choose a reason for hiding this comment

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

I find these two points somewhat unclear. An example might help, as Felipe mentioned, especially for point 1.

I would probably just remove point 2. "main function" need not be the entrypoint for CBMC (can be overriden), and the base case is no different from any other symex path -- the path constraint along a path that reaches the loop head is the base case.

It might be worth adding a pointer to semantics of loop invariants (contracts-invariants.md#semantics), which already covers the induction principle.

@qinheping qinheping force-pushed the manual-loop-invariant-synthesizer branch from 85bf8c2 to 3864e9e Compare September 1, 2022 17:48
/// It handles `goto_model` containing only checks instrumented by
/// `goto-instrument` with the `--pointer-check` flag.
/// It is designed for `goto_model` containing only checks instrumented by
/// `goto-instrument` with the `--pointer-check` flag. H
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// `goto-instrument` with the `--pointer-check` flag. H
/// `goto-instrument` with the `--pointer-check` flag.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Mistakenly marked as resolved?

assertions fail or success;
2. the base-case is from the whole GOTO program with a main
function as the entry point.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I still few this section needs an example. Take a small program, check the program with pointer checks enable using a bound, synthesize the invariant, check the problem again without the bound. One of the most important part of the documentation is to walk potential users and future developers in the process of how to use this tool.

@tautschnig tautschnig self-assigned this Sep 2, 2022
@@ -1146,7 +1146,7 @@ void goto_instrument_parse_optionst::instrument_goto_program()
goto_model.goto_functions.update();
}

if(cmdline.isset("synthesize-loop-invariants"))
if(cmdline.isset("synthesize-loop-invariants-enumerative"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems this commit has more than just "documentation?" I'd recommend to factor out the actual code changes into a commit of their own, even if that makes it just a 3-or-so lines commit.

Copy link
Collaborator

Choose a reason for hiding this comment

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

+1 what @tautschnig says.

Comment on lines 5 to 8
This is a loop invariant synthesizer built in goto-instrument that
synthesize [loop invariants](contracts-invariants.md) for a
pre-existing GOTO binary, annotate the invariant clause into
the GOTO binary, and produce an annotated binary as output.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it really most important to talk about goto-instrument here? I'd expect that users first want to know a sentence about what loop invariants are (and, specifically, what kinds of loop invariants are being synthesized - inductive ones?), and then what capabilities/limitations this synthesizer has (it's an undecidable problem).

@tautschnig tautschnig removed their assignment Sep 2, 2022
assertions fail or success;
2. the base-case is from the whole GOTO program with a main
function as the entry point.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I like the idea of examples. It would also be good to discuss what the initial state is as part of defining / saying they are inductive.


Strategy | Flag | Guarantees
-----------------|------------------------------------------------|----
Enumerative | --synthesize-loop-invariants-enumerative | All checks will succeeded in the annotated GOTO binary
Copy link
Collaborator

Choose a reason for hiding this comment

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

What happens if the asserts (I presume that is what you mean by checks) are false?

@@ -1146,7 +1146,7 @@ void goto_instrument_parse_optionst::instrument_goto_program()
goto_model.goto_functions.update();
}

if(cmdline.isset("synthesize-loop-invariants"))
if(cmdline.isset("synthesize-loop-invariants-enumerative"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

+1 what @tautschnig says.

/// It handles `goto_model` containing only checks instrumented by
/// `goto-instrument` with the `--pointer-check` flag.
/// It is designed for `goto_model` containing only checks instrumented by
/// `goto-instrument` with the `--pointer-check` flag. H
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mistakenly marked as resolved?

@kroening
Copy link
Member

kroening commented Sep 2, 2022

On the manual: Please keep in mind that the "CPROVER Manual" is meant to be a beginners' tutorial, and not a reference manual. May I suggest finding a different place for documenting this functionality.

@tautschnig
Copy link
Collaborator

On the manual: Please keep in mind that the "CPROVER Manual" is meant to be a beginners' tutorial, and not a reference manual. May I suggest finding a different place for documenting this functionality.

Perhaps we could move the entire contracts-related documentation from that manual to the man pages? I would rather not see us open yet another place that users need to go to in order to find documentation.

@feliperodri
Copy link
Collaborator

On the manual: Please keep in mind that the "CPROVER Manual" is meant to be a beginners' tutorial, and not a reference manual. May I suggest finding a different place for documenting this functionality.

Perhaps we could move the entire contracts-related documentation from that manual to the man pages? I would rather not see us open yet another place that users need to go to in order to find documentation.

I agree with @tautschnig about not creating another place that users need to go to. However, I think the CPROVER Documentation generated using Doxygen would be a better place than the man pages, right?

@qinheping qinheping force-pushed the manual-loop-invariant-synthesizer branch from 3864e9e to bf6ba31 Compare September 2, 2022 20:16
@qinheping
Copy link
Collaborator Author

On the manual: Please keep in mind that the "CPROVER Manual" is meant to be a beginners' tutorial, and not a reference manual. May I suggest finding a different place for documenting this functionality.

Perhaps we could move the entire contracts-related documentation from that manual to the man pages? I would rather not see us open yet another place that users need to go to in order to find documentation.

I think we can put the semantic, syntax, and usage of contracts in the CPROVER Documentation generated using Doxygen as Felipe suggested; and put the tutorial and examples in the CBMC training material . We may also want to point to the training material from the reference manual so that users can find them easily.

@feliperodri
Copy link
Collaborator

On the manual: Please keep in mind that the "CPROVER Manual" is meant to be a beginners' tutorial, and not a reference manual. May I suggest finding a different place for documenting this functionality.

Perhaps we could move the entire contracts-related documentation from that manual to the man pages? I would rather not see us open yet another place that users need to go to in order to find documentation.

I think we can put the semantic, syntax, and usage of contracts in the CPROVER Documentation generated using Doxygen as Felipe suggested; and put the tutorial and examples in the CBMC training material . We may also want to point to the training material from the reference manual so that users can find them easily.

@jimgrundy @markrtuttle @SaswatPadhi @nwetzler any recommendations?

@martin-cs
Copy link
Collaborator

Linking to #7006

@qinheping qinheping force-pushed the manual-loop-invariant-synthesizer branch from bf6ba31 to 83b85eb Compare September 26, 2022 16:29
@qinheping
Copy link
Collaborator Author

This PR now contains only code comments explaining the semantic of the synthesizer. I will put the manual parts to the cbmc-documentation.
Can this PR be merged at this moment? @feliperodri @tautschnig

Copy link
Collaborator

@feliperodri feliperodri left a comment

Choose a reason for hiding this comment

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

LGTM.

@tautschnig tautschnig dismissed SaswatPadhi’s stale review September 28, 2022 13:40

Comments have been addressed

@feliperodri
Copy link
Collaborator

@peterschrammel could you take another look at this PR?

Copy link
Collaborator

@martin-cs martin-cs left a comment

Choose a reason for hiding this comment

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

Definitely an improvement, so, merge. I would still like some more extensive documentation and examples but that can be another PR>

@martin-cs martin-cs merged commit 941a2c5 into diffblue:develop Sep 29, 2022
@qinheping qinheping deleted the manual-loop-invariant-synthesizer branch January 18, 2023 21:54
@qinheping qinheping restored the manual-loop-invariant-synthesizer branch January 18, 2023 21:54
@qinheping qinheping deleted the manual-loop-invariant-synthesizer branch January 18, 2023 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws Bugs or features of importance to AWS CBMC users documentation Synthesis Invariant synthesis
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants