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

Replace AddAssignedVariables with AddAssignedIdentifiers #945

Merged

Conversation

keyboardDrummer
Copy link
Collaborator

@keyboardDrummer keyboardDrummer commented Sep 10, 2024

Changes

  • Replace AddAssignedVariables with AddAssignedIdentifiers, because the latter can already be computed before resolution, which is useful for Dafny.
  • Enable a function to be declared as "revealed", so it stays revealed even if "hide *" is used.

Testing

@keyboardDrummer keyboardDrummer marked this pull request as ready for review September 11, 2024 08:13
@keyboardDrummer keyboardDrummer enabled auto-merge (squash) September 11, 2024 08:18
Copy link
Collaborator

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

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

I need a bit more context or insights to accept the current design.

return parent is not Function function || child is not Axiom axiom || revealedState.IsRevealed(function)
|| !axiom.CanHide;
|| !axiom.CanHide || function.AlwaysRevealed;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could this additional disjunct go into revealedState.IsRevealed(function)?

public IEnumerable<Variable> GetAssignedVariables() {
List<IdentifierExpr> ids = new();
AddAssignedIdentifiers(ids);
return ids.Select(id => id.Decl);
Copy link
Collaborator

Choose a reason for hiding this comment

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

What you are saying is that .Decl is available only after resolution, whereas the id is available after parsing, correct? If that is the case, could you just add a comment to this function that says something like "Can be called only after resolution" ? Or I'm mistaken.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's correct.

.)
[ "revealed" (. revealed = true; .)
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the use of "revealed"? Every time the function is in scope, its axiom is automatically revealed? Is it like equivalent to having automatic reveal functionName after hide * ?

I would have thought the other way: That whatever visibility functions would have for themselves by default could be overridden by statements in an implementation.

At least, this is the affordance we now provide in Dafny thanks to your hide statements.

Special rules like this remind me of the CSS !important and their 5 prioritization rules that they ended up implementing, with a weight depending on the number of qualifiers in each categories, IDs, classes, tagNames.

So are we envisioning other uses cases? I can think of

  • Functions which are opaque by default, and can be revealed
  • Functions which are revealed by default, and can be hidden
  • Functions which are always opaque even with reveal *, unless we use their name explicitly
  • Functions which are always revealed even with hide *, unless we use their name explicitly
  • Function which can't be made opaque, always revealed
  • Functions which can't be revealed, truly black boxes

My mind is not clear on all these use cases, so perhaps could you detail a bit more why this "revealed" is now necessary and why there is no other way?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Is it like equivalent to having automatic reveal functionName after hide * ?

Yes

perhaps could you detail a bit more why this "revealed" is now necessary and why there is no other way?

Currently Dafny does not allow its users to reference definitions from the prelude, so functions from there can not be revealed, which means they should also not be hidden using hide *. In the future, the prelude should be a Dafny library that users can see and reference, and then we could allow hiding prelude functions using hide *.

So are we envisioning other uses cases?

Indeed in the future we may want more complicated systems for hiding and revealing, but I want to wait for user feedback before designing that.


procedure AlwaysRevealed() {
hide *;
assert alwaysRevealed(3) == 42;
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
assert alwaysRevealed(3) == 42;
hide alwaysRevealed;
assert alwaysRevealed(3) == 42;

Would that work too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, although in Dafny you wouldn't be able to write this, since you can't mark any Dafny functions as being always revealed. Only the prelude functions will get this property.

Copy link
Collaborator

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

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

Looks good to me ! Thanks for the explanations. I understand better why there are functions we don't want to hide, which could be for example part of the prelude.

@keyboardDrummer keyboardDrummer merged commit 50ef2fb into boogie-org:master Sep 11, 2024
5 checks passed
@keyboardDrummer keyboardDrummer deleted the addAssignedIdentifiers branch September 12, 2024 11:40
keyboardDrummer added a commit to dafny-lang/dafny that referenced this pull request Sep 12, 2024
Fixes #5763

Requires the upcoming Boogie version 3.2.5, for which this PR needs to
be merged first: boogie-org/boogie#945

### Description
- No longer allow hiding functions from the Dafny prelude by using `hide
*`. This affected recursive functions because they use `$LS` which is
defined in the prelude.

### How has this been tested?
- Added a CLI test-case to `revealFunctions.dfy`

<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>
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.

2 participants