Skip to content

Commit b7125bf

Browse files
Introduce Stability command (#3061)
### Changes - Add the stability command and related options ``` Usage: Dafny check-stability [<file>...] [options] Arguments: <file> input files Options: --iterations <n> Attempt to verify each proof n times with n random seeds. If random-seed is used, each proof attempt will use a new random seed derived from this one. If not, it will use a different seed between iterations. [default: 10] --random-seed <seed> Turn on randomization of the input that Boogie passes to the SMT solver and turn on randomization in the SMT solver itself. Certain Boogie inputs are unstable in the sense that changes to the input that preserve its meaning may cause the output to change. This option simulates meaning-preserving changes to the input without requiring the user to actually make those changes. The input changes are renaming variables and reordering declarations in the input, and setting solver options that have similar effects. [default: 0] --format <configuration> Logs verification results using the given test result format. The currently supported formats are `trx`, `csv`, and `text`. These are: the XML-based format commonly used for test results for .NET languages, a custom CSV schema, and a textual format meant for human consumption. You can provide configuration using the same string format as when using the --logger option for dotnet test, such as: --format:trx;LogFileName=<...>.z The `trx` and `csv` formats automatically choose an output file name by default, and print the name of this file to the console. The `text` format prints its output to the console by default, but can send output to a file given the `LogFileName` option. The `text` format also includes a more detailed breakdown of what assertions appear in each assertion batch. When combined with the isolate-assertions option, it will provide approximate time and resource use costs for each assertion, allowing identification of especially expensive assertions. [] --isolate-assertions Verify each assertion in isolation. [default: False] ``` ### Testing - Updated existing tests to use the new command and options. Note that tests for --random-seed and --iterations were and are missing! <!-- Is this a user-visible change? Remember to update RELEASE_NOTES.md --> <!-- Is this a bug fix? Remember to include a test in Test/git-issues/ --> <!-- Is this a bug fix for an issue introduced in the latest release? Mention this in the PR details and ensure a patch release is considered --> <!-- Does this PR need tests? Add them to `Test/` or to `Source/*.Test/…` and run them with `dotnet test` --> <!-- Are you moving a large amount of code? Read CONTRIBUTING.md to learn how to do that while maintaining git history --> <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>
1 parent 7e62528 commit b7125bf

File tree

6 files changed

+57
-5
lines changed

6 files changed

+57
-5
lines changed

Source/DafnyDriver/Commands/CommandRegistry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.CommandLine.Parsing;
66
using System.IO;
77
using System.Linq;
8-
using System.Threading.Tasks;
98
using JetBrains.Annotations;
109
using Microsoft.Boogie;
1110
using Microsoft.Dafny.LanguageServer;
@@ -31,6 +30,7 @@ static CommandRegistry() {
3130
AddCommand(new RunCommand());
3231
AddCommand(new BuildCommand());
3332
AddCommand(new TranslateCommand());
33+
AddCommand(new MeasureComplexityCommand());
3434
AddCommand(new ServerCommand());
3535
AddCommand(new TestCommand());
3636
AddCommand(new GenerateTestsCommand());
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System.Collections.Generic;
2+
using System.CommandLine;
3+
using System.CommandLine.Invocation;
4+
using System.Linq;
5+
6+
namespace Microsoft.Dafny;
7+
8+
public class MeasureComplexityCommand : ICommandSpec {
9+
public IEnumerable<Option> Options => new Option[] {
10+
Iterations,
11+
RandomSeed,
12+
Format,
13+
IsolateAssertions,
14+
}.Concat(ICommandSpec.VerificationOptions).
15+
Concat(ICommandSpec.CommonOptions);
16+
17+
static MeasureComplexityCommand() {
18+
DafnyOptions.RegisterLegacyBinding(Iterations, (o, v) => o.RandomSeedIterations = (int)v);
19+
DafnyOptions.RegisterLegacyBinding(RandomSeed, (o, v) => o.RandomSeed = (int)v);
20+
DafnyOptions.RegisterLegacyBinding(IsolateAssertions, (o, v) => o.VcsSplitOnEveryAssert = v);
21+
DafnyOptions.RegisterLegacyBinding(Format, (o, v) => o.VerificationLoggerConfigs = v);
22+
}
23+
24+
private static readonly Option<uint> RandomSeed = new("--random-seed", () => 0U,
25+
$"Turn on randomization of the input that Dafny passes to the SMT solver and turn on randomization in the SMT solver itself. Certain Dafny proofs are complex in the sense that changes to the proof that preserve its meaning may cause its verification result to change. This option simulates meaning-preserving changes to the proofs without requiring the user to actually make those changes. The proof changes are renaming variables and reordering declarations in the SMT input passed to the solver, and setting solver options that have similar effects.");
26+
27+
private static readonly Option<uint> Iterations = new("--iterations", () => 10U,
28+
$"Attempt to verify each proof n times with n random seeds, each seed derived from the previous one. {RandomSeed.Name} can be used to specify the first seed, which will otherwise be 0.") {
29+
ArgumentHelpName = "n"
30+
};
31+
32+
private static readonly Option<bool> IsolateAssertions = new("--isolate-assertions", @"Verify each assertion in isolation.");
33+
34+
private static readonly Option<List<string>> Format = new("--format", $@"
35+
Logs verification results using the given test result format. The currently supported formats are `trx`, `csv`, and `text`. These are: the XML-based format commonly used for test results for .NET languages, a custom CSV schema, and a textual format meant for human consumption. You can provide configuration using the same string format as when using the --logger option for dotnet test, such as: --format ""trx;LogFileName=<...>"");
36+
37+
The `trx` and `csv` formats automatically choose an output file name by default, and print the name of this file to the console. The `text` format prints its output to the console by default, but can send output to a file given the `LogFileName` option.
38+
39+
The `text` format also includes a more detailed breakdown of what assertions appear in each assertion batch. When combined with the {IsolateAssertions.Name} option, it will provide approximate time and resource use costs for each assertion, allowing identification of especially expensive assertions.".TrimStart()) {
40+
ArgumentHelpName = "configuration"
41+
};
42+
43+
public Command Create() {
44+
var result = new Command("measure-complexity", "(Experimental) Measure the complexity of verifying the program.");
45+
result.AddArgument(ICommandSpec.FilesArgument);
46+
return result;
47+
}
48+
49+
public void PostProcess(DafnyOptions dafnyOptions, Options options, InvocationContext context) {
50+
dafnyOptions.Compile = false;
51+
}
52+
}

Test/logger/CSVLogger.dfy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %exits-with 4 %dafny /verificationLogger:csv";"LogFileName="%t.csv" "%s"
1+
// RUN: %exits-with 4 %baredafny measure-complexity --format:csv";"LogFileName="%t.csv" "%s"
22
// RUN: %OutputCheck --file-to-check "%t.csv" "%s"
33

44
// CHECK: TestResult\.DisplayName,TestResult\.Outcome,TestResult\.Duration,TestResult\.ResourceCount

Test/logger/TextLogger.dfy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %exits-with 4 %dafny /compile:0 /verificationLogger:text /vcsSplitOnEveryAssert "%s" > "%t"
1+
// RUN: %exits-with 4 %baredafny measure-complexity --format:text --isolate-assertions "%s" > "%t"
22
// RUN: %OutputCheck --file-to-check "%t" "%s"
33
// CHECK: Overall outcome: Errors
44
// CHECK: Overall time: .*

Test/logger/TextLoggerBatch.dfy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %exits-with 4 %dafny /compile:0 /verificationLogger:text "%s" > "%t"
1+
// RUN: %exits-with 4 %baredafny measure-complexity --format:text "%s" > "%t"
22
// RUN: %OutputCheck --file-to-check "%t" "%s"
33
// CHECK: Overall outcome: Errors
44
// CHECK: Overall time: .*

Test/logger/VerificationLogger.dfy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %exits-with 4 %dafny /verificationLogger:trx";"LogFileName="%t.trx" "%s"
1+
// RUN: %exits-with 4 %baredafny measure-complexity --iterations=2 --random-seed=1 --format:trx";"LogFileName="%t.trx" "%s"
22
// RUN: %OutputCheck --file-to-check "%t.trx" "%s"
33

44
// CHECK: \<UnitTestResult.* testName="ExampleWithSplits \(correctness\) \(assertion batch 3\)" .*\>

0 commit comments

Comments
 (0)