Skip to content

Commit 880cccb

Browse files
snapshot v4 8 1 (#44)
- **Removing old latest** - **Documentation snapshot for v4.8.1**
1 parent 4e41b06 commit 880cccb

File tree

427 files changed

+51742
-167
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

427 files changed

+51742
-167
lines changed

Snapshots.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ layout: default
77

88
- [Current development version](https://dafny.org/dafny)
99
- [Latest release snapshot](https://dafny.org/latest)
10+
- [v4.8.1](https://dafny.org/v4.8.1)
1011
- [v4.6.0](https://dafny.org/v4.6.0)
1112
- [v4.5.0](https://dafny.org/v4.5.0)
1213
- [v4.4.0](https://dafny.org/v4.4.0)

latest/DafnyRef/Attributes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ using integration with the target language environment.
270270
Currently, the only way to satisfy this requirement is to ensure that the specification
271271
of the function or method includes the equivalent of `reads {}` and `modifies {}`.
272272
This ensures that the code does not read or write any shared mutable state,
273-
although it is free to write and write newly allocated objects.
273+
although it is free to read and write newly allocated objects.
274274

275275
### 11.2.7. `{:extern <name>}` {#sec-extern-method}
276276
See [`{:extern <name>}`](#sec-extern).
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
text.dfy(2,9): Error: assertion might not hold
2+
3+
Dafny program verifier finished with 0 verified, 1 error

latest/DafnyRef/Expressions.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ old(x)
632632
allocated(x)
633633
unchanged(x)
634634
fresh(e)
635+
assigned(x)
635636
```
636637

637638
These expressions are never l-values. They include
@@ -644,6 +645,7 @@ These expressions are never l-values. They include
644645
- [unchanged expressions](#sec-unchanged-expression)
645646
- [old expressions](#sec-old-expression)
646647
- [cardinality expressions](#sec-cardinality-expression)
648+
- [assigned expressions](#sec-assigned-expression)
647649

648650
## 9.20. Literal Expressions ([grammar](#g-literal-expression)} {#sec-literal-expression}
649651

@@ -1851,7 +1853,53 @@ value for each optional parameter, and must never name
18511853
non-existent formals. Any optional parameter that is not given a value
18521854
takes on the default value declared in the callee for that optional parameter.
18531855

1854-
## 9.37. Compile-Time Constants {#sec-compile-time-constants}
1856+
## 9.37. Assigned Expressions {#sec-assigned-expression}
1857+
1858+
Examples:
1859+
<!-- %no-check -->
1860+
```dafny
1861+
assigned(x)
1862+
```
1863+
1864+
For any variable, constant, out-parameter, or object field `x`,
1865+
the expression `assigned(x)` evaluates to `true` in a state
1866+
if `x` is definitely assigned in that state.
1867+
1868+
See [Section 12.6](#sec-definite-assignment) for more details on definite assignment.
1869+
1870+
## 9.38. Termination Ordering Expressions {#sec-termination-ordering-expressions}
1871+
1872+
When proving that a loop or recursive callable terminates, Dafny
1873+
automatically generates a proof obligation that the sequence of
1874+
expressions listed in a `decreases` clause gets smaller (in the
1875+
[lexicographic termination ordering](#sec-decreases-clause)) with each
1876+
iteration or recursive call. Normally, this proof obligation is purely
1877+
internal. However, it can be written as a Dafny expression using the
1878+
`decreases to` operator.
1879+
1880+
The Boolean expression `(a, ..., b decreases to a', ..., b')` encodes
1881+
this ordering. For example, the following assertions are valid:
1882+
<!-- %check-verify -->
1883+
```dafny
1884+
method M(x: int, y: int) {
1885+
assert (1 decreases to 0);
1886+
assert (true, false decreases to false, true);
1887+
assert (x, y decreases to x - 1, y);
1888+
}
1889+
```
1890+
1891+
Conversely, the following assertion is invalid:
1892+
<!-- %check-verify Expressions.5.expect -->
1893+
```dafny
1894+
method M(x: int, y: int) {
1895+
assert (x decreases to x + 1);
1896+
}
1897+
```
1898+
1899+
Currently, `decreases to` expressions must be written in parentheses to
1900+
avoid parsing ambiguities.
1901+
1902+
## 9.39. Compile-Time Constants {#sec-compile-time-constants}
18551903

18561904
In certain situations in Dafny it is helpful to know what the value of a
18571905
constant is during program analysis, before verification or execution takes
@@ -1892,13 +1940,15 @@ In Dafny, the following expressions are compile-time constants[^CTC], recursivel
18921940

18931941
[^CTC]: This set of operations that are constant-folded may be enlarged in future versions of `dafny`.
18941942

1895-
## 9.38. List of specification expressions {#sec-list-of-specification-expressions}
1943+
## 9.40. List of specification expressions {#sec-list-of-specification-expressions}
18961944

18971945
The following is a list of expressions that can only appear in specification contexts or in ghost blocks.
18981946

18991947
* [Fresh expressions](#sec-fresh-expression)
19001948
* [Allocated expressions](#sec-allocated-expression)
19011949
* [Unchanged expressions](#sec-unchanged-expression)
19021950
* [Old expressions](#sec-old-expression)
1951+
- [Assigned expressions](#sec-assigned-expression)
19031952
* [Assert and calc expressions](#sec-statement-in-an-expression)
19041953
* [Hash Calls](#sec-hash-call)
1954+
* [Termination ordering expression](#sec-termination-ordering-expressions)

latest/DafnyRef/Modules.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,8 @@ Examples:
352352
```dafny
353353
export E extends F reveals f,g provides g,h
354354
export E reveals *
355-
export reveals f
355+
export reveals f,g provides g,h
356356
export E
357-
export
358357
export E ... reveals f
359358
```
360359

@@ -375,15 +374,16 @@ module using the `import` mechanism.
375374
An _export set_ enables a module to disallow the
376375
use of some declarations outside the module.
377376

378-
Export sets have names; those names are used in `import` statements to
379-
designate which export set of a module is being imported.
380-
If a module `M` has export sets
381-
`E1` and `E2`, we can write ``import A = M`E1`` to create a module alias
382-
`A` that contains only the
383-
names in `E1`. Or we can write ``import A = M`{E1,E2}`` to import the union
377+
An export set has an optional name used to disambiguate
378+
in case of multiple export sets;
379+
If specified, such names are used in `import` statements
380+
to designate which export set of a module is being imported.
381+
If a module `M` has export sets `E1` and `E2`,
382+
we can write ``import A = M`E1`` to create a module alias
383+
`A` that contains only the names in `E1`.
384+
Or we can write ``import A = M`{E1,E2}`` to import the union
384385
of names in `E1` and `E2` as module alias `A`.
385-
As before, ``import M`E1`` is an
386-
abbreviation of ``import M = M`E1``.
386+
As before, ``import M`E1`` is an abbreviation of ``import M = M`E1``.
387387

388388
If no export set is given in an import
389389
statement, the default export set of the module is used.

latest/DafnyRef/Options.txt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
```
2-
Use 'dafny --help' to see help for a newer Dafny CLI format.
2+
Use 'dafny --help' to see help for the new Dafny CLI format.
33
Usage: dafny [ option ... ] [ filename ... ]
44

55
---- General options -------------------------------------------------------
@@ -87,10 +87,6 @@ Usage: dafny [ option ... ] [ filename ... ]
8787
See https://github.com/dafny-lang/dafny/blob/master/Source/DafnyStandardLibraries/README.md for more information.
8888
Not compatible with the /unicodeChar:0 option.
8989

90-
/unicodeChar:<value>
91-
0 - The char type represents any UTF-16 code unit.
92-
1 (default) - The char type represents any Unicode scalar value.
93-
9490
/noIncludes
9591
Ignore include directives.
9692

@@ -184,6 +180,11 @@ Usage: dafny [ option ... ] [ filename ... ]
184180
/verifyAllModules
185181
Verify modules that come from an include directive.
186182

183+
/emitUncompilableCode
184+
Allow compilers to emit uncompilable code that usually contain useful
185+
information about what feature is missing, rather than
186+
stopping on the first problem
187+
187188
/separateModuleOutput
188189
Output verification results for each module separately, rather than
189190
aggregating them after they are all finished.
@@ -447,6 +448,10 @@ Usage: dafny [ option ... ] [ filename ... ]
447448

448449
/loopUnroll:<n>
449450
unroll loops, following up to n back edges (and then some)
451+
default is -1, which means loops are not unrolled
452+
/extractLoops
453+
extract reducible loops into recursive procedures and
454+
inline irreducible loops using the bound supplied by /loopUnroll:<n>
450455
/soundLoopUnrolling
451456
sound loop unrolling
452457
/doModSetAnalysis

latest/DafnyRef/Plugins.md

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ without concern for verifying or compiling the program. Or it might modify the p
66
and then continue on with verification and compilation with the core Dafny tool. A user plugin might also be used
77
in the Language Server and thereby be available in the VSCode (or other) IDE.
88

9-
_ **This is an experimental aspect of Dafny.**
9+
_**This is an experimental aspect of Dafny.**
1010
The plugin API directly exposes the Dafny AST, which is constantly evolving.
1111
Hence, always recompile your plugin against the binary of Dafny that will be importing your plugin._
1212

13-
Plugins are libraries linked to a `Dafny.dll` of the same version as the language server.
13+
Plugins are libraries linked to a `Dafny.dll` of the same version as the Language Server.
1414
A plugin typically defines:
1515

1616
* Zero or one class extending `Microsoft.Dafny.Plugins.PluginConfiguration`, which receives plugins arguments in its method `ParseArguments`, and
17-
1) Can return a list of `Microsoft.Dafny.Plugins.Rewriter`s when its method `GetRewriters()` is called by Dafny,
18-
2) Can return a list of `Microsoft.Dafny.Plugins.Compiler`s when its method `GetCompilers()` is called by Dafny,
19-
3) If the configuration extends the subclass `Microsoft.Dafny.LanguageServer.Plugins.PluginConfiguration`,
20-
then it can return a list of `Microsoft.Dafny.LanguageServer.Plugins.DafnyCodeActionProvider`s when its method `GetDafnyCodeActionProviders()` is called by the Dafny Language Server.
17+
1. Can return a list of `Microsoft.Dafny.Plugins.Rewriter`s when its method `GetRewriters()` is called by Dafny,
18+
2. Can return a list of `Microsoft.Dafny.Plugins.Compiler`s when its method `GetCompilers()` is called by Dafny,
19+
3. If the configuration extends the subclass `Microsoft.Dafny.LanguageServer.Plugins.PluginConfiguration`:
20+
1. Can return a list of `Microsoft.Dafny.LanguageServer.Plugins.DafnyCodeActionProvider`s when its method `GetDafnyCodeActionProviders()` is called by the Dafny Language Server.
21+
2. Can return a modified version of `OmniSharp.Extensions.LanguageServer.Server.LanguageServerOptions` when its method `WithPluginHandlers()` is called by the Dafny Language Server.
2122

2223
* Zero or more classes extending `Microsoft.Dafny.Plugins.Rewriter`.
2324
If a configuration class is provided, it is responsible for instantiating them and returning them in `GetRewriters()`.
@@ -29,6 +30,7 @@ A plugin typically defines:
2930
Only a configuration class of type `Microsoft.Dafny.LanguageServer.Plugins.PluginConfiguration` can be responsible for instantiating them and returning them in `GetDafnyCodeActionProviders()`.
3031

3132
The most important methods of the class `Rewriter` that plugins override are
33+
3234
* (experimental) `PreResolve(ModuleDefinition)`: Here you can optionally modify the AST before it is resolved.
3335
* `PostResolve(ModuleDefinition)`: This method is repeatedly called with every resolved and type-checked module, before verification.
3436
Plugins override this method typically to report additional diagnostics.
@@ -38,11 +40,12 @@ Plugins are typically used to report additional diagnostics such as unsupported
3840

3941
Note that all plugin errors should use the original program's expressions' token and NOT `Token.NoToken`, else no error will be displayed in the IDE.
4042

41-
## 15.1. Code actions plugin tutorial
43+
## 15.1. Language Server plugin tutorial
44+
45+
In this section, we will create a plugin that enhances the functionality of the Language Server.
46+
We will start by showing the steps needed to create a plugin, followed by an example implementation that demonstrates how to provide more code actions and add custom request handlers.
4247

43-
In this section, we will create a plugin to provide more code actions to Dafny.
44-
The code actions will be simple: Add a dummy comment in front of the first method name,
45-
if the selection is on the line of the method.
48+
### 15.1.1. Create plugin project
4649

4750
Assuming the Dafny source code is installed in the folder `dafny/`
4851
start by creating an empty folder next to it, e.g. `PluginTutorial/`
@@ -51,22 +54,33 @@ start by creating an empty folder next to it, e.g. `PluginTutorial/`
5154
mkdir PluginTutorial
5255
cd PluginTutorial
5356
```
57+
5458
Then, create a dotnet class project
59+
5560
```bash
5661
dotnet new classlib
5762
```
63+
5864
It will create a file `Class1.cs` that you can rename
65+
5966
```bash
60-
mv Class1.cs PluginAddComment.cs
67+
mv Class1.cs MyPlugin.cs
6168
```
69+
6270
Open the newly created file `PluginTutorial.csproj`, and add the following after `</PropertyGroup>`:
71+
6372
```xml
6473
<ItemGroup>
6574
<ProjectReference Include="../dafny/source/DafnyLanguageServer/DafnyLanguageServer.csproj" />
6675
</ItemGroup>
6776
```
77+
### 15.1.2. Implement plugin
78+
79+
#### 15.1.2.1. Code actions plugin
6880

69-
Then, open the file `PluginAddComment.cs`, remove everything, and write the imports and a namespace:
81+
This code action plugin will add a code action that allows you to place a dummy comment in front of the first method name, only if the selection is on the line of the method.
82+
83+
Open the file `MyPlugin.cs`, remove everything, and write the imports and a namespace:
7084

7185
```csharp
7286
using Microsoft.Dafny;
@@ -76,18 +90,20 @@ using Microsoft.Dafny.LanguageServer.Language;
7690
using System.Linq;
7791
using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range;
7892

79-
namespace PluginAddComment;
93+
namespace MyPlugin;
8094
```
8195

8296
After that, add a `PluginConfiguration` that will expose all the quickfixers of your plugin.
8397
This class will be discovered and instantiated automatically by Dafny.
98+
8499
```csharp
85100
public class TestConfiguration : PluginConfiguration {
86101
public override DafnyCodeActionProvider[] GetDafnyCodeActionProviders() {
87102
return new DafnyCodeActionProvider[] { new AddCommentDafnyCodeActionProvider() };
88103
}
89104
}
90105
```
106+
91107
Note that you could also override the methods `GetRewriters()` and `GetCompilers()` for other purposes, but this is out of scope for this tutorial.
92108

93109
Then, we need to create the quickFixer `AddCommentDafnyCodeActionProvider` itself:
@@ -102,6 +118,7 @@ public class AddCommentDafnyCodeActionProvider : DafnyCodeActionProvider {
102118

103119
For now, this quick fixer returns nothing. `input` is the program state, and `selection` is where the caret is.
104120
We replace the return statement with a conditional that tests whether the selection is on the first line:
121+
105122
```csharp
106123
var firstTokenRange = input.Program?.GetFirstTopLevelToken()?.GetLspRange();
107124
if(firstTokenRange != null && firstTokenRange.Start.Line == selection.Start.Line) {
@@ -118,6 +135,7 @@ A `DafnyCodeActionEdit` has a `Range` to remove and some `string` to insert inst
118135
of the same `DafnyCodeAction` are applied at the same time if selected.
119136

120137
To create a `DafnyCodeAction`, we can either use the easy-to-use `InstantDafnyCodeAction`, which accepts a title and an array of edits:
138+
121139
```csharp
122140
return new DafnyCodeAction[] {
123141
new InstantDafnyCodeAction("Insert comment", new DafnyCodeActionEdit[] {
@@ -127,6 +145,7 @@ To create a `DafnyCodeAction`, we can either use the easy-to-use `InstantDafnyCo
127145
```
128146

129147
or we can implement our custom inherited class of `DafnyCodeAction`:
148+
130149
```csharp
131150
public class CustomDafnyCodeAction: DafnyCodeAction {
132151
public Range whereToInsert;
@@ -141,14 +160,72 @@ public class CustomDafnyCodeAction: DafnyCodeAction {
141160
}
142161
}
143162
```
163+
144164
In that case, we could return:
165+
145166
```csharp
146167
return new DafnyCodeAction[] {
147168
new CustomDafnyCodeAction(firstTokenRange)
148169
};
149170
```
150171

172+
#### 15.1.2.2. Request handler plugin
173+
174+
This request handler plugin enhances the Language Server to support a request with a `TextDocumentIdentifier` as parameter, which will return a `bool` value denoting whether the provided `DocumentUri` has any `LoopStmt`'s in it.
175+
176+
Open the file `MyPlugin.cs`, remove everything, and write the imports and a namespace:
177+
178+
```csharp
179+
using OmniSharp.Extensions.JsonRpc;
180+
using OmniSharp.Extensions.LanguageServer.Server;
181+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
182+
using Microsoft.Dafny.LanguageServer.Plugins;
183+
using Microsoft.Dafny.LanguageServer.Workspace;
184+
using MediatR;
185+
using Microsoft.Dafny;
186+
187+
namespace MyPlugin;
188+
```
189+
190+
After that, add a `PluginConfiguration` that will add all the request handlers of your plugin.
191+
This class will be discovered and instantiated automatically by Dafny.
192+
193+
```csharp
194+
public class TestConfiguration : PluginConfiguration {
195+
public override LanguageServerOptions WithPluginHandlers(LanguageServerOptions options) {
196+
return options.WithHandler<DummyHandler>();
197+
}
198+
}
199+
```
200+
201+
Then, we need to create the request handler `DummyHandler` itself:
202+
203+
```csharp
204+
[Parallel]
205+
[Method("dafny/request/dummy", Direction.ClientToServer)]
206+
public record DummyParams : TextDocumentIdentifier, IRequest<bool>;
207+
208+
public class DummyHandler : IJsonRpcRequestHandler<DummyParams, bool> {
209+
private readonly IProjectDatabase projects;
210+
public DummyHandler(IProjectDatabase projects) {
211+
this.projects = projects;
212+
}
213+
public async Task<bool> Handle(DummyParams request, CancellationToken cancellationToken) {
214+
var state = await projects.GetParsedDocumentNormalizeUri(request);
215+
if (state == null) {
216+
return false;
217+
}
218+
return state.Program.Descendants().OfType<LoopStmt>().Any();
219+
}
220+
}
221+
```
222+
223+
For more advanced example implementations of request handlers, look at `dafny/Source/DafnyLanguageServer/Handlers/*`.
224+
225+
### 15.1.3. Building plugin
226+
151227
That's it! Now, build your library while inside your folder:
228+
152229
```bash
153230
> dotnet build
154231
```
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
text.dfy(4,2): Warning: note, this loop has no body (loop frame: i)
1+
text.dfy(4,2): Warning: this loop has no body (loop frame: i)
22

33
Dafny program verifier did not attempt verification

0 commit comments

Comments
 (0)