Skip to content
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

Fix: Opaque functions guaranteed to be opaque until revealed #3779

Merged
merged 33 commits into from
Apr 21, 2023

Conversation

MikaelMayer
Copy link
Member

@MikaelMayer MikaelMayer commented Mar 21, 2023

This PR fixes #3719 and (implements) fixes #3778
I added the corresponding test.

In an upcoming PR, we might be able to remove the old mechanism "StartFuelAssert"/"StartFuel" of picking the fuel from the defniition site and letting user define their fuel at the call site, but this is independent.

This is the first PR of a series that will ensure opaqueness is consistent.

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

@MikaelMayer MikaelMayer requested a review from RustanLeino March 21, 2023 19:14
@MikaelMayer MikaelMayer marked this pull request as draft March 22, 2023 14:55
@MikaelMayer MikaelMayer marked this pull request as ready for review March 28, 2023 17:25
Copy link
Member

@atomb atomb left a comment

Choose a reason for hiding this comment

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

Nice improvement! I suspect it could be valuable to recommend Dafny developers put assert false on any path they expect to be unreachable, as a general practice. It makes things clearer, and sometimes makes proofs faster. And, in the case where we warn about unreachable code, it would be easy to filter out those that explicitly included assert false.

C, Processed := C - {v}, Processed + {v};
ghost var pathToV := Find(source, v, paths);

Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason to remove these blank lines?

Copy link
Member Author

Choose a reason for hiding this comment

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

No indeed that does not improve verifiability :-)

Copy link
Member

@atomb atomb left a comment

Choose a reason for hiding this comment

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

Let's wait to merge this until we've assessed any impact on variability.

}
}
}
}
}
}

private void MaybeCreateRevealableConstant(Function f) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The "Maybe" part of the name suggests to me that it may or may not be appropriate to have a revealable constant at all. But here it just indicates that the operation is idempotent--it's performed only once. For that purpose, I suggest still just naming the method CreateRevealableConstant.

Comment on lines 5 to 8
opaque function inc(x:nat) : nat { x + 1 }

// Intermediatary to force lambda
predicate CheckThis(p: ()->bool) { p() }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Formatting:

  • Use one space after :
  • Use no space before :
  • Use a space before and after ->

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, I had just taken the provided test without reformatting.

}

lemma Test() {
assert 1 == R(1) by {reveal R(); }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Formatting: Add one space between { and reveal.

Comment on lines 518 to 521
axiom (forall $ly: LayerType, b: bool ::
{ CanRevealFuel(AsFuelBottom($ly), b) }
CanRevealFuel(AsFuelBottom($ly), b)
== $LZ);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Well done in figuring out the problem and suggesting a solution. I don't think we ever equate anything with $LZ elsewhere. Because of that, my hunch is that it's better to write the axiom as

axiom (forall $ly: LayerType, b: bool :: 
  { CanRevealFuel(AsFuelBottom($ly), b) } 
  CanRevealFuel(AsFuelBottom($ly), b) == AsFuelBottom($ly));

In fact, even more, since the first axiom (LL 514-516) says that CanRevealFuel commutes with $LS, provided the second parameter is known to equal true, I think it seems appropriate to do the analogous thing for the second axiom. That is, I suggest writing the second axiom as

axiom (forall $ly: LayerType, b: bool :: 
  { CanRevealFuel(AsFuelBottom($ly), b) } 
  CanRevealFuel(AsFuelBottom($ly), b) == AsFuelBottom(CanRevealFuel($ly, b)));

RustanLeino
RustanLeino previously approved these changes Apr 4, 2023
atomb
atomb previously approved these changes Apr 7, 2023
@MikaelMayer MikaelMayer enabled auto-merge (squash) April 7, 2023 15:43
@MikaelMayer MikaelMayer disabled auto-merge April 7, 2023 15:52
atomb
atomb previously approved these changes Apr 20, 2023
@MikaelMayer MikaelMayer enabled auto-merge (squash) April 20, 2023 18:05
Copy link
Member

@atomb atomb left a comment

Choose a reason for hiding this comment

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

Nice work!

@MikaelMayer MikaelMayer merged commit 568c9b4 into master Apr 21, 2023
@MikaelMayer MikaelMayer deleted the fix-3719-opaque-leaked-lambda branch April 21, 2023 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants