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

Sequence implementation in Go missing Elements() method #2038

Closed
robin-aws opened this issue Apr 21, 2022 · 0 comments · Fixed by #2195
Closed

Sequence implementation in Go missing Elements() method #2038

robin-aws opened this issue Apr 21, 2022 · 0 comments · Fixed by #2195
Labels
lang: golang Dafny's transpiler to Go and its runtime part: runtime Happens in Dafny's runtime (Add a `lang` tag if relevant)

Comments

@robin-aws
Copy link
Member

Compiling the following (from https://github.com/dafny-lang/libraries/blob/master/src/Collections/Sequences/Seq.dfy) to Go:

  /* converts a sequence to a set */
  function method {:opaque} ToSet<T>(s: seq<T>): set<T> 
  {
    set x: T | x in s
  }

Results in a Go compiler error:

$ dafny /compileTarget:go src/Scratch.dfy

Dafny program verifier finished with 0 verified, 0 errors
Wrote textual form of target program to Scratch-go/src/Scratch.go
Additional target code written to Scratch-go/src/dafny/dafny.go
Additional target code written to Scratch-go/src/System_/System_.go
# command-line-arguments
src/Scratch-go/src/Scratch.go:47:37: s.Elements undefined (type dafny.Seq has no field or method Elements)

Just a simple omission of a method definition on the Seq structure in the Go runtime.

@robin-aws robin-aws added the lang: golang Dafny's transpiler to Go and its runtime label Apr 21, 2022
@robin-aws robin-aws self-assigned this Apr 21, 2022
@robin-aws robin-aws added the part: runtime Happens in Dafny's runtime (Add a `lang` tag if relevant) label Apr 21, 2022
@robin-aws robin-aws removed their assignment May 26, 2022
robin-aws added a commit that referenced this issue Jun 10, 2022
Resolves #2187. First phase of implementing dafny-lang/rfcs#10.

This change adds two new features on several uses of quantified variables in the language:

1. Quantified variable *domains*, specified with the syntax `x <- C`, where C is an expression with a collection type (i.e. set, multiset, sequence, or map). Besides offering a more compact syntax for a common pattern (i.e. replacing `myLovelyButLongVariableName | myLovelyButLongVariableName in someSet` with `myLovelyButLongVariableName <- someSet`), this is forwards-compatible with the notion of *ordered quantification*, which the two features designed in the linked RFC depend on, and potentially others in the future.

2. Quantified variable *ranges*, specified with the syntax `x | E`, where E is a boolean expression. These replace the existing concept of a single `| E` range after all quantified variables (which is now bound to the last declared variable, with equivalent semantics). These are helpful for restricting the values of one quantified variable so that it can be used in the domain expression of another variable.

These features apply to the quantifier domains used in `forall` and `exists` expressions, `set` and `map` comprehensions, and `forall` statements, and the parsing for quantifier domains is now shared between these features. As a small consequence, set comprehensions now no longer require range expressions, and will default to `| true`.

This new syntax is not fully backwards-compatible: the statement `print set x | 0 <= x < 10, y`, for example, was previously parsed as `print (set x | 0 <= x < 10), (y)` but will now be parsed as `print (set x | 0 <= x < 10, y)` and rejected. The `/quantifierSyntax` option is used to help migrate this otherwise breaking change:

* `/quantifierSyntax:3` keeps the old behaviour where a `| <Range>` always terminates the list of quantified variables.
* `/quantifierSyntax:4` instead attempts to parse additional quantified variables.

Like `/functionSyntax`, this option will default to `4` instead in Dafny 4.0.

This is implemented with pure desugaring for now: the `QuantifiedDomain` production parses a list of `QuantifiedVar` objects, but then immediately rewrites a snippet such as `x <- C | P(x), y <- D(x) | Q(x, y)` into the equivalent (for now) `x | x in C && P(x) && y in D(x) && Q(x, y)`. Token wrappers are used to ensure error messages can still refer to the original syntax. This will not be equivalent once features that depend on the ordering of quantification are added, though, so a subsequent change will add the new fields to `BoundVar` instead and plumb these extra components through the whole Dafny pipeline.

On testing: I duplicated several existing test files and modified them to use the new syntax features, to get good white-box test coverage even though the implementation is very simple for now.

Also resolves #2038 (and the same issue for Java) since I hit it when converting test cases, and it was dead easy to fix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang: golang Dafny's transpiler to Go and its runtime part: runtime Happens in Dafny's runtime (Add a `lang` tag if relevant)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant