From bce2f72bfe06fbeca8d6878480b707d08e7137a6 Mon Sep 17 00:00:00 2001 From: Remy Willems Date: Wed, 27 Mar 2024 14:36:38 +0100 Subject: [PATCH] Isolate assertions attribute (#5247) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description Add `{:isolate_assertions}` attribute, that has the same meaning as `{:vcs_split_on_every_assert}` ### How has this been tested? 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). --- .../BoogieGenerator.ExpressionTranslator.cs | 15 +++++++- .../Diagnostics/DiagnosticsTest.cs | 4 +- .../Lookup/HoverVerificationTest.cs | 4 +- .../DafnyRuntimeDafny/src/dafnyRuntime.dfy | 2 +- .../binaries/DafnyStandardLibraries-cs.doo | Bin 1360 -> 1360 bytes .../binaries/DafnyStandardLibraries-go.doo | Bin 1379 -> 1379 bytes .../binaries/DafnyStandardLibraries-java.doo | Bin 1341 -> 1341 bytes .../binaries/DafnyStandardLibraries-js.doo | Bin 1886 -> 1886 bytes .../DafnyStandardLibraries-notarget.doo | Bin 1334 -> 1334 bytes .../binaries/DafnyStandardLibraries-py.doo | Bin 1350 -> 1350 bytes .../binaries/DafnyStandardLibraries.doo | Bin 56993 -> 56962 bytes .../src/Std/Arithmetic/DivMod.dfy | 2 +- .../Std/Arithmetic/Internal/DivInternals.dfy | 4 +- .../Std/Arithmetic/Internal/ModInternals.dfy | 10 ++--- .../src/Std/Arithmetic/LittleEndianNat.dfy | 10 ++--- .../DafnyStandardLibraries/src/Std/Base64.dfy | 12 +++--- .../src/Std/Collections/Seq.dfy | 4 +- .../src/Std/JSON/Deserializer.dfy | 2 +- .../src/Std/JSON/Serializer.dfy | 2 +- .../src/Std/JSON/ZeroCopy/Deserializer.dfy | 36 +++++++++--------- .../src/Std/JSON/ZeroCopy/Serializer.dfy | 20 +++++----- .../src/Std/Strings.dfy | 2 +- .../Unicode/UnicodeStringsWithUnicodeChar.dfy | 2 +- .../LitTests/LitTest/VSI-Benchmarks/b4.dfy | 2 +- .../LitTest/VerifyThis2015/Problem1.dfy | 2 +- .../concurrency/09-CounterNoStateMachine.dfy | 2 +- .../concurrency/10-SequenceInvariant.dfy | 2 +- .../concurrency/11-MutexGuard2.legacy.dfy | 2 +- .../concurrency/12-MutexLifetime-short.dfy | 2 +- .../LitTests/LitTest/dafny0/Termination.dfy | 4 +- .../LitTests/LitTest/dafny1/MoreInduction.dfy | 2 +- .../LitTest/dafny1/Rippling.legacy.dfy | 2 +- .../LitTests/LitTest/dafny2/MinWindowMax.dfy | 2 +- .../SmallestMissingNumber-functional.dfy | 4 +- .../LitTest/dafny2/SnapshotableTrees.dfy | 4 +- .../LitTest/dafny4/ACL2-extractor.dfy | 2 +- .../dafny4/SoftwareFoundations-Basics.dfy | 2 +- .../LitTest/git-issues/git-issue-3855.dfy | 2 +- .../LitTests/LitTest/hofs/Folding.dfy | 2 +- .../LitTests/LitTest/lambdas/MatrixAssoc.dfy | 2 +- .../verification/isolate-assertions.dfy | 13 +++++++ .../isolate-assertions.dfy.expect | 8 ++++ .../LitTest/vstte2012/BreadthFirstSearch.dfy | 4 +- .../LitTests/LitTest/vstte2012/Tree.dfy | 2 +- docs/DafnyRef/Attributes.md | 16 ++++---- docs/DafnyRef/UserGuide.md | 6 +-- .../VerificationOptimization.md | 8 ++-- docs/dev/news/5247.feat | 1 + 48 files changed, 132 insertions(+), 97 deletions(-) create mode 100644 Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy create mode 100644 Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy.expect create mode 100644 docs/dev/news/5247.feat diff --git a/Source/DafnyCore/Verifier/BoogieGenerator.ExpressionTranslator.cs b/Source/DafnyCore/Verifier/BoogieGenerator.ExpressionTranslator.cs index e48f467c2f4..774c86a7b3d 100644 --- a/Source/DafnyCore/Verifier/BoogieGenerator.ExpressionTranslator.cs +++ b/Source/DafnyCore/Verifier/BoogieGenerator.ExpressionTranslator.cs @@ -1927,6 +1927,8 @@ public static bool RewriteInExpr(Expression s, bool aggressive) { return false; } + private static readonly Dictionary NullaryAttributesToTranslate; + private static readonly HashSet NullaryAttributesToCopy = new(new[] { "focus", "ignore", @@ -1958,6 +1960,15 @@ public static bool RewriteInExpr(Expression s, bool aggressive) { "error" }); + static ExpressionTranslator() { + NullaryAttributesToTranslate = new() { + { + "isolate_assertions", + "vcs_split_on_every_assert" + } + }; + } + private QKeyValue TrBooleanAttribute(string name, Expression arg, QKeyValue rest) { var boolArg = RemoveLit(TrExpr(arg)); return boolArg is Boogie.LiteralExpr { IsTrue: true } or Boogie.LiteralExpr { IsFalse: true } @@ -1995,7 +2006,9 @@ public QKeyValue TrAttributes(Attributes attrs, string skipThisAttribute) { continue; } - if (NullaryAttributesToCopy.Contains(name) && attr.Args.Count == 0) { + if (NullaryAttributesToTranslate.ContainsKey(name) && attr.Args.Count == 0) { + kv = new QKeyValue(attr.tok, NullaryAttributesToTranslate[name], new List(), kv); + } else if (NullaryAttributesToCopy.Contains(name) && attr.Args.Count == 0) { kv = new QKeyValue(attr.tok, name, new List(), kv); } else if (BooleanAttributesToCopy.Contains(name) && attr.Args.Count == 1) { kv = TrBooleanAttribute(name, attr.Args[0], kv); diff --git a/Source/DafnyLanguageServer.Test/Diagnostics/DiagnosticsTest.cs b/Source/DafnyLanguageServer.Test/Diagnostics/DiagnosticsTest.cs index 1622b88cd95..9922a7938d0 100644 --- a/Source/DafnyLanguageServer.Test/Diagnostics/DiagnosticsTest.cs +++ b/Source/DafnyLanguageServer.Test/Diagnostics/DiagnosticsTest.cs @@ -134,7 +134,7 @@ public async Task DiagnosticsForVerificationTimeoutHasNameAsRange() { [Fact] public async Task NoFlickeringWhenMixingCorrectAndErrorBatches() { var source = @" -method {:vcs_split_on_every_assert} Foo(x: int) { +method {:isolate_assertions} Foo(x: int) { if (x == 0) { assert true; } else if (x == 1) { @@ -158,7 +158,7 @@ public async Task NoFlickeringWhenMixingCorrectAndErrorBatches() { [Fact] public async Task IncrementalBatchDiagnostics() { var source = @" -method {:vcs_split_on_every_assert} Foo(x: int) { +method {:isolate_assertions} Foo(x: int) { if (x == 0) { assert false; } else { diff --git a/Source/DafnyLanguageServer.Test/Lookup/HoverVerificationTest.cs b/Source/DafnyLanguageServer.Test/Lookup/HoverVerificationTest.cs index bf9f348e4ae..c10d2dbaa4d 100644 --- a/Source/DafnyLanguageServer.Test/Lookup/HoverVerificationTest.cs +++ b/Source/DafnyLanguageServer.Test/Lookup/HoverVerificationTest.cs @@ -26,7 +26,7 @@ public class HoverVerificationTest : ClientBasedLanguageServerTest { [Fact(Timeout = MaxTestExecutionTimeMs)] public async Task HoverPutsErrorsFirst() { var documentItem = await GetDocumentItem(@" -method {:vcs_split_on_every_assert} Test(x: int, y: int) +method {:isolate_assertions} Test(x: int, y: int) requires x < y { var callIt := giveIt(x, y); @@ -118,7 +118,7 @@ await SetUp(o => { // LineVerificationStatusOption.Instance.Set(o, true); }); var documentItem = await GetDocumentItem(@" -method {:vcs_split_on_every_assert} f(x: int) { +method {:isolate_assertions} f(x: int) { assert x >= 2; // Hover #1 assert x >= 1; // Hover #2 } diff --git a/Source/DafnyRuntime/DafnyRuntimeDafny/src/dafnyRuntime.dfy b/Source/DafnyRuntime/DafnyRuntimeDafny/src/dafnyRuntime.dfy index 5310094f952..5cf543b6efb 100644 --- a/Source/DafnyRuntime/DafnyRuntimeDafny/src/dafnyRuntime.dfy +++ b/Source/DafnyRuntime/DafnyRuntimeDafny/src/dafnyRuntime.dfy @@ -746,7 +746,7 @@ abstract module {:options "/functionSyntax:4"} Dafny { } } - method {:tailrecursion} {:vcs_split_on_every_assert} AppendOptimized(builder: Vector, e: Sequence, stack: Vector>) + method {:tailrecursion} {:isolate_assertions} AppendOptimized(builder: Vector, e: Sequence, stack: Vector>) requires e.Valid() requires builder.Valid() requires stack.Valid() diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-cs.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-cs.doo index fd2be3e33cdbae862ee5880e1cc50bb4a0dac7ff..ce9c372d9862fb1b7b4c888cf21a212a0651b345 100644 GIT binary patch delta 45 ucmcb>b%BdFz?+#xgn@y9gP}6EY9jArW+1ik^J8WZJ^3b!1(+6LwE+M#pAKXI delta 45 ucmcb>b%BdFz?+#xgn@y9gJEey-bCKV%s^`6=f}(-dh$&c3otFhY6AdA6c2C! diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-go.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-go.doo index 275aeec2dfeac8287011cb925121c5f398bd8a9f..9507cb0304a0cd33ee631e3432dace33b5c05565 100644 GIT binary patch delta 45 ucmaFN^_Yt{z?+#xgn@y9gP|t2Y9jArW+1ik^EYM?J^2lb1(;T6wE+M)Gz?+#xgn@y9gP|(6Y9jArW+1ik^95!QJ^2`m1(;@JwE+Mt0uBiP delta 45 ucmdnXwU>)Gz?+#xgn@y9gJD@i-bCKV%s^`6=L^grdh#(A3oy;dY6Ad1cMlZ+ diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-js.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-js.doo index 6bb204b0e31b2367f12a6ab418499b55b1a96ebe..33410558bdc3e01e9042a1deb18eb220997bb71c 100644 GIT binary patch delta 45 ucmcb|caM)Zz?+#xgn@y9gP}UMY9jArW+1ik^G8+?J^4AC1(;T1w*de=R}R1c delta 45 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�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%0AJ$&ZX68i)E2~9j_xbJ^E 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 0 && ModAuto(n) ensures DivAutoPlus(n) { @@ -137,7 +137,7 @@ module {:disableNonlinearArithmetic} Std.Arithmetic.DivInternals { } } - lemma {:vcs_split_on_every_assert} LemmaDivAutoAuxMinusHelper(n: int) + lemma {:isolate_assertions} LemmaDivAutoAuxMinusHelper(n: int) requires n > 0 && ModAuto(n) ensures forall i, j :: && (j >= 0 && DivMinus(n, i, j) ==> DivMinus(n, i, j + n)) diff --git a/Source/DafnyStandardLibraries/src/Std/Arithmetic/Internal/ModInternals.dfy b/Source/DafnyStandardLibraries/src/Std/Arithmetic/Internal/ModInternals.dfy index 452347eb3b5..e995581699c 100644 --- a/Source/DafnyStandardLibraries/src/Std/Arithmetic/Internal/ModInternals.dfy +++ b/Source/DafnyStandardLibraries/src/Std/Arithmetic/Internal/ModInternals.dfy @@ -76,7 +76,7 @@ module {:disableNonlinearArithmetic} Std.Arithmetic.ModInternals { } } - lemma {:vcs_split_on_every_assert} LemmaDivAddDenominator(n: int, x: int) + lemma {:isolate_assertions} LemmaDivAddDenominator(n: int, x: int) requires n > 0 ensures (x + n) / n == x / n + 1 { @@ -96,7 +96,7 @@ module {:disableNonlinearArithmetic} Std.Arithmetic.ModInternals { } } - lemma {:vcs_split_on_every_assert} LemmaDivSubDenominator(n: int, x: int) + lemma {:isolate_assertions} LemmaDivSubDenominator(n: int, x: int) requires n > 0 ensures (x - n) / n == x / n - 1 { @@ -116,7 +116,7 @@ module {:disableNonlinearArithmetic} Std.Arithmetic.ModInternals { } } - lemma {:vcs_split_on_every_assert} LemmaModAddDenominator(n: int, x: int) + lemma {:isolate_assertions} LemmaModAddDenominator(n: int, x: int) requires n > 0 ensures (x + n) % n == x % n { @@ -136,7 +136,7 @@ module {:disableNonlinearArithmetic} Std.Arithmetic.ModInternals { } } - lemma {:vcs_split_on_every_assert} LemmaModSubDenominator(n: int, x: int) + lemma {:isolate_assertions} LemmaModSubDenominator(n: int, x: int) requires n > 0 ensures (x - n) % n == x % n { @@ -193,7 +193,7 @@ module {:disableNonlinearArithmetic} Std.Arithmetic.ModInternals { } /* proves the quotient remainder theorem */ - lemma {:vcs_split_on_every_assert} LemmaQuotientAndRemainder(x: int, q: int, r: int, n: int) + lemma {:isolate_assertions} LemmaQuotientAndRemainder(x: int, q: int, r: int, n: int) requires n > 0 requires 0 <= r < n requires x == q * n + r diff --git a/Source/DafnyStandardLibraries/src/Std/Arithmetic/LittleEndianNat.dfy b/Source/DafnyStandardLibraries/src/Std/Arithmetic/LittleEndianNat.dfy index 55ee9d2bf98..df45d6cb3a4 100644 --- a/Source/DafnyStandardLibraries/src/Std/Arithmetic/LittleEndianNat.dfy +++ b/Source/DafnyStandardLibraries/src/Std/Arithmetic/LittleEndianNat.dfy @@ -50,7 +50,7 @@ abstract module {:disableNonlinearArithmetic} Std.Arithmetic.LittleEndianNat { } /* Given the same sequence, ToNatRight and ToNatLeft return the same nat. */ - lemma {:vcs_split_on_every_assert} LemmaToNatLeftEqToNatRight(xs: seq) + lemma {:isolate_assertions} LemmaToNatLeftEqToNatRight(xs: seq) ensures ToNatRight(xs) == ToNatLeft(xs) { reveal ToNatRight(); @@ -177,7 +177,7 @@ abstract module {:disableNonlinearArithmetic} Std.Arithmetic.LittleEndianNat { /* The nat representation of a sequence can be calculated using the nat representation of its prefix. */ - lemma {:vcs_split_on_every_assert} LemmaSeqPrefix(xs: seq, i: nat) + lemma {:isolate_assertions} LemmaSeqPrefix(xs: seq, i: nat) requires 0 <= i <= |xs| ensures ToNatRight(xs[..i]) + ToNatRight(xs[i..]) * Pow(BASE(), i) == ToNatRight(xs) { @@ -228,7 +228,7 @@ abstract module {:disableNonlinearArithmetic} Std.Arithmetic.LittleEndianNat { /* Two sequences do not have the same nat representations if their prefixes do not have the same nat representations. Helper lemma for LemmaSeqNeq. */ - lemma {:vcs_split_on_every_assert} LemmaSeqPrefixNeq(xs: seq, ys: seq, i: nat) + lemma {:isolate_assertions} LemmaSeqPrefixNeq(xs: seq, ys: seq, i: nat) requires 0 <= i <= |xs| == |ys| requires ToNatRight(xs[..i]) != ToNatRight(ys[..i]) ensures ToNatRight(xs) != ToNatRight(ys) @@ -524,7 +524,7 @@ abstract module {:disableNonlinearArithmetic} Std.Arithmetic.LittleEndianNat { /* SeqAdd returns the same value as converting the sequences to nats, then adding them. */ - lemma {:vcs_split_on_every_assert} LemmaSeqAdd(xs: seq, ys: seq, zs: seq, cout: nat) + lemma {:isolate_assertions} LemmaSeqAdd(xs: seq, ys: seq, zs: seq, cout: nat) requires |xs| == |ys| requires SeqAdd(xs, ys) == (zs, cout) ensures ToNatRight(xs) + ToNatRight(ys) == ToNatRight(zs) + cout * Pow(BASE(), |xs|) @@ -581,7 +581,7 @@ abstract module {:disableNonlinearArithmetic} Std.Arithmetic.LittleEndianNat { /* SeqSub returns the same value as converting the sequences to nats, then subtracting them. */ - lemma {:vcs_split_on_every_assert} LemmaSeqSub(xs: seq, ys: seq, zs: seq, cout: nat) + lemma {:isolate_assertions} LemmaSeqSub(xs: seq, ys: seq, zs: seq, cout: nat) requires |xs| == |ys| requires SeqSub(xs, ys) == (zs, cout) ensures ToNatRight(xs) - ToNatRight(ys) + cout * Pow(BASE(), |xs|) == ToNatRight(zs) diff --git a/Source/DafnyStandardLibraries/src/Std/Base64.dfy b/Source/DafnyStandardLibraries/src/Std/Base64.dfy index 02bd16eaa06..1bb33df8ad1 100644 --- a/Source/DafnyStandardLibraries/src/Std/Base64.dfy +++ b/Source/DafnyStandardLibraries/src/Std/Base64.dfy @@ -98,7 +98,7 @@ module Std.Base64 { else (c - 65 as char) as index } - lemma {:resource_limit 2000000} {:vcs_split_on_every_assert} CharToIndexToChar(c: char) + lemma {:resource_limit 2000000} {:isolate_assertions} CharToIndexToChar(c: char) requires IsBase64Char(c) ensures IndexToChar(CharToIndex(c)) == c { @@ -122,7 +122,7 @@ module Std.Base64 { } } - lemma {:vcs_split_on_every_assert} IndexToCharToIndex(i: index) + lemma {:isolate_assertions} IndexToCharToIndex(i: index) ensures (IndexToCharIsBase64(i); CharToIndex(IndexToChar(i)) == i) { // TODO: reduce resource use, brittleness @@ -263,7 +263,7 @@ module Std.Base64 { IndexSeqToBV24ToIndexSeq(s); } - opaque function {:vcs_split_on_every_assert} DecodeRecursively(s: seq): (b: seq) + opaque function {:isolate_assertions} DecodeRecursively(s: seq): (b: seq) requires |s| % 4 == 0 decreases |s| { @@ -326,7 +326,7 @@ module Std.Base64 { } } - opaque function {:vcs_split_on_every_assert} EncodeRecursively(b: seq): (s: seq) + opaque function {:isolate_assertions} EncodeRecursively(b: seq): (s: seq) requires |b| % 3 == 0 { if |b| == 0 then [] @@ -677,7 +677,7 @@ module Std.Base64 { } } - lemma {:vcs_split_on_every_assert} DecodeEncode1Padding(s: seq) + lemma {:isolate_assertions} DecodeEncode1Padding(s: seq) requires Is1Padding(s) ensures Encode1Padding(Decode1Padding(s)) == s { @@ -1449,7 +1449,7 @@ module Std.Base64 { seq(|b|, i requires 0 <= i < |b| => b[i] as uint8) } - lemma {:vcs_split_on_every_assert} {:resource_limit 1000000000} UInt8sToBVsToUInt8s(u: seq) + lemma {:isolate_assertions} {:resource_limit 1000000000} UInt8sToBVsToUInt8s(u: seq) ensures BVsToUInt8s(UInt8sToBVs(u)) == u { // TODO: reduce resource use diff --git a/Source/DafnyStandardLibraries/src/Std/Collections/Seq.dfy b/Source/DafnyStandardLibraries/src/Std/Collections/Seq.dfy index 1d8deec010e..dd7095061ff 100644 --- a/Source/DafnyStandardLibraries/src/Std/Collections/Seq.dfy +++ b/Source/DafnyStandardLibraries/src/Std/Collections/Seq.dfy @@ -530,7 +530,7 @@ module Std.Collections.Seq { /* Flattening sequences of sequences is distributive over concatenation. That is, concatenating the flattening of two sequences of sequences is the same as flattening the concatenation of two sequences of sequences. */ - lemma {:vcs_split_on_every_assert} LemmaFlattenConcat(xs: seq>, ys: seq>) + lemma {:isolate_assertions} LemmaFlattenConcat(xs: seq>, ys: seq>) ensures Flatten(xs + ys) == Flatten(xs) + Flatten(ys) { if |xs| == 0 { @@ -781,7 +781,7 @@ module Std.Collections.Seq { /* Filtering a sequence is distributive over concatenation. That is, concatenating two sequences and then using "Filter" is the same as using "Filter" on each sequence separately, and then concatenating the two resulting sequences. */ - lemma {:vcs_split_on_every_assert} + lemma {:isolate_assertions} LemmaFilterDistributesOverConcat(f: (T ~> bool), xs: seq, ys: seq) requires forall i {:trigger xs[i]}:: 0 <= i < |xs| ==> f.requires(xs[i]) requires forall j {:trigger ys[j]}:: 0 <= j < |ys| ==> f.requires(ys[j]) diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy index dd3641eb7f9..6a1a247cbc1 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/Deserializer.dfy @@ -69,7 +69,7 @@ module Std.JSON.Deserializer { hd as uint16 } - function {:tailrecursion} {:vcs_split_on_every_assert} Unescape(str: seq, start: nat := 0, prefix: seq := []): DeserializationResult> + function {:tailrecursion} {:isolate_assertions} Unescape(str: seq, start: nat := 0, prefix: seq := []): DeserializationResult> decreases |str| - start { // Assumes UTF-16 strings if start >= |str| then Success(prefix) diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/Serializer.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/Serializer.dfy index cad694e4b58..a503096f5be 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/Serializer.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/Serializer.dfy @@ -64,7 +64,7 @@ module Std.JSON.Serializer { Failure(o.error) } - function {:vcs_split_on_every_assert} {:resource_limit 1000000} Number(dec: Values.Decimal): Result { + function {:isolate_assertions} {:resource_limit 1000000} Number(dec: Values.Decimal): Result { var minus: jminus := Sign(dec.n); var num: jnum :- Int(Math.Abs(dec.n)); var frac: Maybe := Empty(); diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Deserializer.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Deserializer.dfy index 2d1bb740332..3ba4d60e779 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Deserializer.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Deserializer.dfy @@ -59,7 +59,7 @@ module Std.JSON.ZeroCopy.Deserializer { return Cursor(cs.s, cs.beg, point', cs.end).Split(); } - opaque function {:vcs_split_on_every_assert} {:resource_limit 1000000000} Structural(cs: FreshCursor, parser: Parser) + opaque function {:isolate_assertions} {:resource_limit 1000000000} Structural(cs: FreshCursor, parser: Parser) : (pr: ParseResult>) requires forall cs :: parser.fn.requires(cs) ensures pr.Success? ==> pr.value.StrictlySplitFrom?(cs, st => Spec.Structural(st, parser.spec)) @@ -244,11 +244,11 @@ module Std.JSON.ZeroCopy.Deserializer { elems' } - opaque function {:resource_limit 10000000} {:vcs_split_on_every_assert} AppendLast(ghost cs0: FreshCursor, - ghost json: ValueParser, - elems: Split>, - elem: Split, - sep: Split>) + opaque function {:resource_limit 10000000} {:isolate_assertions} AppendLast(ghost cs0: FreshCursor, + ghost json: ValueParser, + elems: Split>, + elem: Split, + sep: Split>) : (elems': Split>) requires elems.cs.StrictlySplitFrom?(json.cs) requires elems.SplitFrom?(cs0, SuffixedElementsSpec) @@ -280,7 +280,7 @@ module Std.JSON.ZeroCopy.Deserializer { elems' } - lemma {:resource_limit "10e6"} {:vcs_split_on_every_assert} AboutTryStructural(cs: FreshCursor) + lemma {:resource_limit "10e6"} {:isolate_assertions} AboutTryStructural(cs: FreshCursor) ensures var sp := Core.TryStructural(cs); var s0 := sp.t.t.Peek(); @@ -291,14 +291,14 @@ module Std.JSON.ZeroCopy.Deserializer { { } - lemma {:vcs_split_on_every_assert} AboutLists(xs: seq, i: uint32) + lemma {:isolate_assertions} AboutLists(xs: seq, i: uint32) requires 0 <= (i as int) < |xs| ensures xs[(i as int)..(i as int)+1] == [xs[i as int]] {} // The implementation and proof of this function is more painful than // expected due to the tail recursion. - opaque function {:vcs_split_on_every_assert} {:tailrecursion} Elements( + opaque function {:isolate_assertions} {:tailrecursion} Elements( ghost cs0: FreshCursor, json: ValueParser, open: Split>, @@ -419,7 +419,7 @@ module Std.JSON.ZeroCopy.Deserializer { } } - opaque function {:vcs_split_on_every_assert} Bracketed(cs: FreshCursor, json: ValueParser) + opaque function {:isolate_assertions} Bracketed(cs: FreshCursor, json: ValueParser) : (pr: ParseResult) requires cs.SplitFrom?(json.cs) ensures pr.Success? ==> pr.value.StrictlySplitFrom?(cs, BracketedSpec) @@ -476,7 +476,7 @@ module Std.JSON.ZeroCopy.Deserializer { case OtherError(err) => err } - opaque function {:vcs_split_on_every_assert} {:resource_limit 10000000} JSON(cs: Cursors.FreshCursor) : (pr: DeserializationResult>) + opaque function {:isolate_assertions} {:resource_limit 10000000} JSON(cs: Cursors.FreshCursor) : (pr: DeserializationResult>) ensures pr.Success? ==> pr.value.StrictlySplitFrom?(cs, Spec.JSON) { Core.Structural(cs, Parsers.Parser(Values.Value, Spec.Value)).MapFailure(LiftCursorError) @@ -514,7 +514,7 @@ module Std.JSON.ZeroCopy.Deserializer { import opened Utils.Cursors import opened Core - opaque function {:vcs_split_on_every_assert} Value(cs: FreshCursor) : (pr: ParseResult) + opaque function {:isolate_assertions} Value(cs: FreshCursor) : (pr: ParseResult) decreases cs.Length(), 1 ensures pr.Success? ==> pr.value.StrictlySplitFrom?(cs, Spec.Value) { @@ -755,7 +755,7 @@ module Std.JSON.ZeroCopy.Deserializer { else Success(sp) } - opaque function {:vcs_split_on_every_assert} {:resource_limit 100000000} Exp(cs: FreshCursor) : (pr: ParseResult>) + opaque function {:isolate_assertions} {:resource_limit 100000000} Exp(cs: FreshCursor) : (pr: ParseResult>) ensures pr.Success? ==> pr.value.SplitFrom?(cs, exp => Spec.Maybe(exp, Spec.Exp)) { var SP(e, cs) := @@ -842,7 +842,7 @@ module Std.JSON.ZeroCopy.Deserializer { module Arrays refines Sequences { import opened Params = ArrayParams - lemma {:vcs_split_on_every_assert} BracketedToArray(arr: jarray) + lemma {:isolate_assertions} BracketedToArray(arr: jarray) ensures Spec.Bracketed(arr, SuffixedElementSpec) == Spec.Array(arr) { var rItem := (d: jitem) requires d < arr => Spec.Item(d); @@ -857,7 +857,7 @@ module Std.JSON.ZeroCopy.Deserializer { } } - opaque function {:vcs_split_on_every_assert} Array(cs: FreshCursor, json: ValueParser) + opaque function {:isolate_assertions} Array(cs: FreshCursor, json: ValueParser) : (pr: ParseResult) requires cs.SplitFrom?(json.cs) ensures pr.Success? ==> pr.value.StrictlySplitFrom?(cs, Spec.Array) @@ -911,7 +911,7 @@ module Std.JSON.ZeroCopy.Deserializer { Spec.KeyValue(t) } - opaque function {:vcs_split_on_every_assert} Element(cs: FreshCursor, json: ValueParser) + opaque function {:isolate_assertions} Element(cs: FreshCursor, json: ValueParser) : (pr: ParseResult) { var k :- Strings.String(cs); @@ -957,7 +957,7 @@ module Std.JSON.ZeroCopy.Deserializer { module Objects refines Sequences { import opened Params = ObjectParams - lemma {:vcs_split_on_every_assert} BracketedToObject(obj: jobject) + lemma {:isolate_assertions} BracketedToObject(obj: jobject) ensures Spec.Bracketed(obj, SuffixedElementSpec) == Spec.Object(obj) { var rMember := (d: jmember) requires d < obj => Spec.Member(d); @@ -974,7 +974,7 @@ module Std.JSON.ZeroCopy.Deserializer { } } - opaque function {:vcs_split_on_every_assert} {:resource_limit 10000000} Object(cs: FreshCursor, json: ValueParser) + opaque function {:isolate_assertions} {:resource_limit 10000000} Object(cs: FreshCursor, json: ValueParser) : (pr: ParseResult) requires cs.SplitFrom?(json.cs) ensures pr.Success? ==> pr.value.StrictlySplitFrom?(cs, Spec.Object) diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy index 044b8e64a0e..b58b9074ec5 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy @@ -59,7 +59,7 @@ module Std.JSON.ZeroCopy.Serializer { .Append(js.after) } - opaque function {:vcs_split_on_every_assert} Value(v: Grammar.Value, writer: Writer) : (wr: Writer) + opaque function {:isolate_assertions} Value(v: Grammar.Value, writer: Writer) : (wr: Writer) decreases v, 4 ensures wr.Bytes() == writer.Bytes() + Spec.Value(v) { @@ -122,7 +122,7 @@ module Std.JSON.ZeroCopy.Serializer { .Append(str.rq) } - lemma {:vcs_split_on_every_assert} NumberHelper1(num: jnumber, writer: Writer) + lemma {:isolate_assertions} NumberHelper1(num: jnumber, writer: Writer) ensures if num.exp.NonEmpty? then ( if num.frac.NonEmpty? then @@ -151,11 +151,11 @@ module Std.JSON.ZeroCopy.Serializer { } } - lemma {:vcs_split_on_every_assert} NumberHelper2a(num: jnumber, writer: Writer) + lemma {:isolate_assertions} NumberHelper2a(num: jnumber, writer: Writer) ensures Spec.Number(num) == num.minus.Bytes() + num.num.Bytes() + Spec.Maybe(num.frac, Spec.Frac) + Spec.Maybe(num.exp, Spec.Exp) {} - lemma {:vcs_split_on_every_assert} {:resource_limit 10000000} NumberHelper2(num: jnumber, writer: Writer) + lemma {:isolate_assertions} {:resource_limit 10000000} NumberHelper2(num: jnumber, writer: Writer) ensures if num.exp.NonEmpty? then ( if num.frac.NonEmpty? then writer.Bytes() + Spec.Number(num) == writer.Bytes() + num.minus.Bytes() + num.num.Bytes() + num.frac.t.period.Bytes() + num.frac.t.num.Bytes() + num.exp.t.e.Bytes() + num.exp.t.sign.Bytes() + num.exp.t.num.Bytes() else writer.Bytes() + Spec.Number(num) == writer.Bytes() + num.minus.Bytes() + num.num.Bytes() + num.exp.t.e.Bytes() + num.exp.t.sign.Bytes() + num.exp.t.num.Bytes() @@ -217,7 +217,7 @@ module Std.JSON.ZeroCopy.Serializer { } } - opaque function {:vcs_split_on_every_assert} Number(num: jnumber, writer: Writer) : (wr: Writer) + opaque function {:isolate_assertions} Number(num: jnumber, writer: Writer) : (wr: Writer) decreases num, 0 ensures wr.Bytes() == writer.Bytes() + Spec.Number(num) { @@ -266,7 +266,7 @@ module Std.JSON.ZeroCopy.Serializer { } // DISCUSS: Can't be opaque, due to the lambda - function {:vcs_split_on_every_assert} StructuralView(st: Structural, writer: Writer) : (wr: Writer) + function {:isolate_assertions} StructuralView(st: Structural, writer: Writer) : (wr: Writer) ensures wr.Bytes() == writer.Bytes() + Spec.Structural(st, Spec.View) { writer.Append(st.before).Append(st.t).Append(st.after) @@ -397,9 +397,9 @@ module Std.JSON.ZeroCopy.Serializer { } - ghost function {:vcs_split_on_every_assert} SequenceSpec(v: Value, items: seq, - spec: T -> bytes, impl: (Value, T, Writer) --> Writer, - writer: Writer) + ghost function {:isolate_assertions} SequenceSpec(v: Value, items: seq, + spec: T -> bytes, impl: (Value, T, Writer) --> Writer, + writer: Writer) : (wr: Writer) requires SequenceSpecRequires(v, items, spec, impl, writer) decreases v, 1, items @@ -485,7 +485,7 @@ module Std.JSON.ZeroCopy.Serializer { assert wr == MembersSpec(obj, members, writer); } - method {:vcs_split_on_every_assert} ItemsImpl(arr: jarray, writer: Writer) returns (wr: Writer) + method {:isolate_assertions} ItemsImpl(arr: jarray, writer: Writer) returns (wr: Writer) decreases arr, 1 ensures wr == ItemsSpec(arr, arr.data, writer) { diff --git a/Source/DafnyStandardLibraries/src/Std/Strings.dfy b/Source/DafnyStandardLibraries/src/Std/Strings.dfy index a9acc6b46f0..4ff388923e0 100644 --- a/Source/DafnyStandardLibraries/src/Std/Strings.dfy +++ b/Source/DafnyStandardLibraries/src/Std/Strings.dfy @@ -81,7 +81,7 @@ module {:disableNonlinearArithmetic} Std.Strings { /** Convert a String that represents a natural number, back into that number. */ - function {:vcs_split_on_every_assert} ToNat(str: String) : (n: nat) + function {:isolate_assertions} ToNat(str: String) : (n: nat) requires forall c <- str :: IsDigitChar(c) { if str == [] then 0 diff --git a/Source/DafnyStandardLibraries/src/Std/Unicode/UnicodeStringsWithUnicodeChar.dfy b/Source/DafnyStandardLibraries/src/Std/Unicode/UnicodeStringsWithUnicodeChar.dfy index 7b73339301d..e0ea3c7871c 100644 --- a/Source/DafnyStandardLibraries/src/Std/Unicode/UnicodeStringsWithUnicodeChar.dfy +++ b/Source/DafnyStandardLibraries/src/Std/Unicode/UnicodeStringsWithUnicodeChar.dfy @@ -14,7 +14,7 @@ module Std.Unicode.UnicodeStringsWithUnicodeChar refines AbstractUnicodeStrings import Utf8EncodingForm import Utf16EncodingForm - lemma {:vcs_split_on_every_assert} CharIsUnicodeScalarValue(c: char) + lemma {:isolate_assertions} CharIsUnicodeScalarValue(c: char) ensures && var asBits := c as bv24; && asBits <= 0x10_FFFF diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/VSI-Benchmarks/b4.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/VSI-Benchmarks/b4.dfy index 6142067e8a1..82f3a11b505 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/VSI-Benchmarks/b4.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/VSI-Benchmarks/b4.dfy @@ -136,7 +136,7 @@ class Map { } // Removes key from the domain of M (and does nothing if key wasn't in M to begin with) - method {:resource_limit "3e6"} {:vcs_split_on_every_assert} Remove(key: Key) + method {:resource_limit "3e6"} {:isolate_assertions} Remove(key: Key) requires Valid() modifies Repr ensures Valid() && fresh(Repr - old(Repr)) diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/VerifyThis2015/Problem1.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/VerifyThis2015/Problem1.dfy index c8be9fa25d1..47d330ab1b8 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/VerifyThis2015/Problem1.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/VerifyThis2015/Problem1.dfy @@ -156,7 +156,7 @@ lemma Prefix(pat: seq, a: seq) ensures IsRelaxedPrefixAux(pat, a, 0) { } -lemma {:vcs_split_on_every_assert} Same2(pat: seq, a: seq) +lemma {:isolate_assertions} Same2(pat: seq, a: seq) requires IsRelaxedPrefixAux(pat, a, 1) ensures IRP_Alt(pat, a) { diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/09-CounterNoStateMachine.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/09-CounterNoStateMachine.dfy index d9842b142f2..f8d015415ab 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/09-CounterNoStateMachine.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/09-CounterNoStateMachine.dfy @@ -690,7 +690,7 @@ class ClaimIncreasingCounterGreaterThanConstant extends OwnedObject { // assert!(i == 10); // } -method {:vcs_split_on_every_assert} Incrementer(universe: Universe, running: Thread, counter: IncreasingCounter, remaining: Integer) +method {:isolate_assertions} Incrementer(universe: Universe, running: Thread, counter: IncreasingCounter, remaining: Integer) requires universe.globalInv() && running in universe.content && counter in universe.content && remaining in universe.content requires remaining.owner == running && remaining.value == 10 // USER precondition modifies universe, universe.content diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/10-SequenceInvariant.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/10-SequenceInvariant.dfy index 79206c776d2..098d30d3d4b 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/10-SequenceInvariant.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/10-SequenceInvariant.dfy @@ -614,7 +614,7 @@ class ClaimIncreasingCounterGreaterThanConstant extends OwnedObject { // assert!(i == 10); // } -method {:vcs_split_on_every_assert} Incrementer(universe: Universe, running: Thread, counter: IncreasingCounter, remaining: Integer) +method {:isolate_assertions} Incrementer(universe: Universe, running: Thread, counter: IncreasingCounter, remaining: Integer) requires universe.globalInv() && running in universe.content && counter in universe.content && remaining in universe.content requires remaining.owner == running && remaining.value == 10 // USER precondition modifies universe, universe.content diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/11-MutexGuard2.legacy.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/11-MutexGuard2.legacy.dfy index a70667f5843..88ba54711bc 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/11-MutexGuard2.legacy.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/11-MutexGuard2.legacy.dfy @@ -650,7 +650,7 @@ method Acquire(universe: Universe, running: Thread, mutex: Mutex) // drop(l); // deallocate a guard == release mutex // } -method {:vcs_split_on_every_assert} SetData(universe: Universe, running: Thread, mutex: Mutex) +method {:isolate_assertions} SetData(universe: Universe, running: Thread, mutex: Mutex) requires universe.globalInv() && running in universe.content && mutex in universe.content modifies universe, universe.content decreases * diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/12-MutexLifetime-short.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/12-MutexLifetime-short.dfy index 35e3fcd2ab0..c213afc2470 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/12-MutexLifetime-short.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/concurrency/12-MutexLifetime-short.dfy @@ -886,7 +886,7 @@ class MutexGuardU32 extends OwnedObject { } // MutexGuardU32 - constructor {:vcs_split_on_every_assert} (ghost universe: Universe, ghost running: Thread, ghost scope: Lifetime, mutex: Mutex, ghost mutexScope: Lifetime) + constructor {:isolate_assertions} (ghost universe: Universe, ghost running: Thread, ghost scope: Lifetime, mutex: Mutex, ghost mutexScope: Lifetime) requires universe.globalInv() && { running, scope, mutex, mutexScope } <= universe.content requires scope.owner == running && mutexScope.owner == running && scope != mutexScope requires universe.outlives(mutex.lifetime, mutexScope) && universe.outlives(mutexScope, scope) && scope.unused() diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny0/Termination.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny0/Termination.dfy index fc00d0ae492..331c1252809 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny0/Termination.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny0/Termination.dfy @@ -487,7 +487,7 @@ datatype Tree = Empty | Node(root: int, left: Tree, right: Tree) } } - lemma {:induction this} {:vcs_split_on_every_assert} EvensSumToEven() // explicitly use "this" as quantified over by induction hypothesis + lemma {:induction this} {:isolate_assertions} EvensSumToEven() // explicitly use "this" as quantified over by induction hypothesis requires forall u :: u in Elements() ==> u % 2 == 0 ensures Sum() % 2 == 0 // auto: decreases this @@ -500,7 +500,7 @@ datatype Tree = Empty | Node(root: int, left: Tree, right: Tree) right.EvensSumToEven(); } - lemma {:vcs_split_on_every_assert} EvensSumToEvenAutoInduction() // {:induction this} is the default + lemma {:isolate_assertions} EvensSumToEvenAutoInduction() // {:induction this} is the default requires forall u :: u in Elements() ==> u % 2 == 0 ensures Sum() % 2 == 0 // auto: decreases this diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/MoreInduction.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/MoreInduction.dfy index 8bcae1a537b..6c69c586f82 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/MoreInduction.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/MoreInduction.dfy @@ -48,7 +48,7 @@ lemma Theorem(list: List) Lemma(list, Nil); } -lemma {:vcs_split_on_every_assert} Lemma(list: List, ext: List) +lemma {:isolate_assertions} Lemma(list: List, ext: List) requires IsFlat(ext) ensures ToSeq(list) + ToSeq(ext) == ToSeq(Flatten(list, ext)) { diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/Rippling.legacy.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/Rippling.legacy.dfy index 544f10d2f8f..8fffa7ceed4 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/Rippling.legacy.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny1/Rippling.legacy.dfy @@ -594,7 +594,7 @@ lemma P2_alt(n: Nat, xs: List, ys: List) // --------- -lemma {:vcs_split_on_every_assert} Lemma_RevConcat(xs: List, ys: List) +lemma {:isolate_assertions} Lemma_RevConcat(xs: List, ys: List) ensures reverse(concat(xs, ys)) == concat(reverse(ys), reverse(xs)); { match (xs) { diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/MinWindowMax.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/MinWindowMax.dfy index dccc5f9d5ef..460d7bce2c7 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/MinWindowMax.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/MinWindowMax.dfy @@ -25,7 +25,7 @@ method Main() { print "Window size 5: min window-max is ", m, "\n"; // 3 } -method {:resource_limit "100e6"} {:vcs_split_on_every_assert} MinimumWindowMax(a: array, W: int) returns (m: int, start: int) +method {:resource_limit "100e6"} {:isolate_assertions} MinimumWindowMax(a: array, W: int) returns (m: int, start: int) requires 1 <= W <= a.Length ensures 0 <= start <= a.Length - W ensures m == Max(a, start, W) diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SmallestMissingNumber-functional.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SmallestMissingNumber-functional.dfy index 6198c83753d..e6b4d5b59b0 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SmallestMissingNumber-functional.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SmallestMissingNumber-functional.dfy @@ -216,7 +216,7 @@ ghost function IntRange(lo: nat, len: nat): set // ----- Proofs of alternative versions -lemma {:vcs_split_on_every_assert} SMN'_Correct(xs: List, n: nat, len: nat) +lemma {:isolate_assertions} SMN'_Correct(xs: List, n: nat, len: nat) requires NoDuplicates(xs) requires forall x :: x in Elements(xs) ==> n <= x requires len == Length(xs) @@ -251,7 +251,7 @@ lemma {:vcs_split_on_every_assert} SMN'_Correct(xs: List, n: nat, len: nat) } } -lemma {:vcs_split_on_every_assert} SMN''_Correct(xs: List, n: nat, len: nat) +lemma {:isolate_assertions} SMN''_Correct(xs: List, n: nat, len: nat) requires NoDuplicates(xs) requires forall x :: x in Elements(xs) ==> n <= x requires len == Length(xs) diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SnapshotableTrees.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SnapshotableTrees.dfy index a9d5459420b..6e30255ef1b 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SnapshotableTrees.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny2/SnapshotableTrees.dfy @@ -580,7 +580,7 @@ module SnapTree { } // private - static method {:vcs_split_on_every_assert} Push(stIn: List, ghost n: int, p: Node, ghost C: seq, ghost Nodes: set) returns (st: List) + static method {:isolate_assertions} Push(stIn: List, ghost n: int, p: Node, ghost C: seq, ghost Nodes: set) returns (st: List) requires p in Nodes && p.Repr <= Nodes && p.NodeValid() requires 0 <= n <= |C| requires p.Contents <= C[n..] @@ -607,7 +607,7 @@ module SnapTree { case Cons(y, rest) => x := y.data; } - method {:vcs_split_on_every_assert} MoveNext() returns (hasCurrent: bool) + method {:isolate_assertions} MoveNext() returns (hasCurrent: bool) requires Valid() && N <= |Contents| modifies IterRepr ensures Valid() && fresh(IterRepr - old(IterRepr)) && T.Repr == old(T.Repr) diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/ACL2-extractor.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/ACL2-extractor.dfy index 4cbfca1bbd9..0d3eca21e51 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/ACL2-extractor.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/ACL2-extractor.dfy @@ -141,7 +141,7 @@ lemma EqualElementsMakeEqualLists(xs: List, ys: List) // here is the theorem, but applied to the ith element -lemma {:vcs_split_on_every_assert} ExtractorLemma(i: int, xs: List) +lemma {:isolate_assertions} ExtractorLemma(i: int, xs: List) requires 0 <= i < length(xs); ensures nth(i, xtr(nats(length(xs)), xs)) == nth(i, rev(xs)); { diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/SoftwareFoundations-Basics.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/SoftwareFoundations-Basics.dfy index a93c348f0b7..41baa0682b7 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/SoftwareFoundations-Basics.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/dafny4/SoftwareFoundations-Basics.dfy @@ -269,7 +269,7 @@ lemma plus_lemma(a: Nat, b: Nat, c: Nat) {} // This lemma expresses: m*(2*n) == (2*m)*n -lemma {:vcs_split_on_every_assert} mult_lemma(m: Nat, n: Nat) +lemma {:isolate_assertions} mult_lemma(m: Nat, n: Nat) ensures mult(m, plus(n, n)) == mult(plus(m, m), n) { match m { diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-3855.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-3855.dfy index c064909c154..ae5046374ba 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-3855.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-3855.dfy @@ -637,7 +637,7 @@ function partitionOfJustHeapRegions(os : set) : (partition : map) assert r % 2 == 0; } -method {:vcs_split_on_every_assert} FoldL_Use_Direct_lambda(xs: List) +method {:isolate_assertions} FoldL_Use_Direct_lambda(xs: List) { var f := (b,a) => 3*b + 2*a; var r := foldl(f, 0, xs); diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/lambdas/MatrixAssoc.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/lambdas/MatrixAssoc.dfy index bd326b4fed9..0c777579f63 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/lambdas/MatrixAssoc.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/lambdas/MatrixAssoc.dfy @@ -170,7 +170,7 @@ lemma sum_assoc_mult(a: Matrix, b: Matrix, c: Matrix, i: Index, j: Index) } /** (a * (b * c))(i, j) == ((a * b) * c)(i, j) */ -lemma {:vcs_split_on_every_assert} mult_assoc_ij(a: Matrix, b: Matrix, c: Matrix, i: Index, j: Index) +lemma {:isolate_assertions} mult_assoc_ij(a: Matrix, b: Matrix, c: Matrix, i: Index, j: Index) ensures mult(mult(a, b), c)(i)(j) == mult(a, mult(b, c))(i)(j) { calc { diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy new file mode 100644 index 00000000000..327bc1ea5b0 --- /dev/null +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy @@ -0,0 +1,13 @@ +// RUN: %verify --progress --cores=1 %s &> %t.raw +// RUN: %sed 's/time: \d*ms/redacted/g' "%t".raw > %t +// RUN: %diff "%s.expect" "%t" + +method {:isolate_assertions} Foo() { + assert true; + assert true; +} + +method Bar() { + assert true; + assert true; +} \ No newline at end of file diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy.expect b/Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy.expect new file mode 100644 index 00000000000..524e0c4e9e8 --- /dev/null +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/verification/isolate-assertions.dfy.expect @@ -0,0 +1,8 @@ +Verified 0/2 symbols. Waiting for Foo to verify. +Verified part 1/3 of Foo, on line 5 (redacted, resource count: 8.7E+002) +Verified part 2/3 of Foo, on line 6 (redacted, resource count: 3.1E+003) +Verified part 3/3 of Foo, on line 7 (redacted, resource count: 2.8E+003) +Verified 1/2 symbols. Waiting for Bar to verify. +Verified part 1/1 of Bar, on line 10 (redacted, resource count: 3.1E+003) + +Dafny program verifier finished with 4 verified, 0 errors diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/BreadthFirstSearch.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/BreadthFirstSearch.dfy index a7707a5ecef..79489ae4c5e 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/BreadthFirstSearch.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/BreadthFirstSearch.dfy @@ -28,7 +28,7 @@ class BreadthFirstSearch // existential quantifier and no ghost out-parameter. method {:resource_limit "8e6"} - {:vcs_split_on_every_assert} + {:isolate_assertions} BFS(source: Vertex, dest: Vertex, ghost AllVertices: set) returns (d: int, ghost path: List) // source and dest are among AllVertices @@ -199,7 +199,7 @@ class BreadthFirstSearch } } - lemma {:vcs_split_on_every_assert} IsReachFixpoint(source: Vertex, m: nat, n: nat, AllVertices: set) + lemma {:isolate_assertions} IsReachFixpoint(source: Vertex, m: nat, n: nat, AllVertices: set) requires R(source, m, AllVertices) == R(source, m+1, AllVertices); requires m <= n; ensures R(source, m, AllVertices) == R(source, n, AllVertices); diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/Tree.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/Tree.dfy index 0232e4ed78c..37bb623175e 100644 --- a/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/Tree.dfy +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/vstte2012/Tree.dfy @@ -40,7 +40,7 @@ ghost function toList(d: int, t: Tree): seq // property; converting the resulting tree back into a // sequence yields exactly that portion of the input // sequence that has been consumed. -function {:vcs_split_on_every_assert} build_rec(d: int, s: seq): Result +function {:isolate_assertions} build_rec(d: int, s: seq): Result ensures build_rec(d, s).Res? ==> |build_rec(d, s).sOut| < |s| && build_rec(d, s).sOut == s[|s|-|build_rec(d, s).sOut|..] diff --git a/docs/DafnyRef/Attributes.md b/docs/DafnyRef/Attributes.md index bfc7fb70f36..60748d37ae3 100644 --- a/docs/DafnyRef/Attributes.md +++ b/docs/DafnyRef/Attributes.md @@ -398,7 +398,7 @@ in which methods or functions are verified (default: N = 1). `{:resource_limit N}` limits the verifier resource usage to verify the method or function to `N`. This is the per-method equivalent of the command-line flag `/rlimit:N` or `--resource-limit N`. -If using [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) as well, the limit will be set for each assertion. +If using [`{:isolate_assertions}`](#sec-isolate_assertions) as well, the limit will be set for each assertion. The attribute `{:rlimit N}` is also available, and limits the verifier resource usage to verify the method or function to `N * 1000`. This version is deprecated, however. @@ -422,10 +422,10 @@ To give orders of magnitude about resource usage, here is a list of examples ind } ``` -* 40K total resource usage using [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) +* 40K total resource usage using [`{:isolate_assertions}`](#sec-isolate_assertions) ```dafny - method {:vcs_split_on_every_assert} f(a: bool, b: bool) { + method {:isolate_assertions} f(a: bool, b: bool) { assert a: (a ==> b) <==> (!b ==> !a); assert b: (a ==> b) <==> (!b ==> !a); assert c: (a ==> b) <==> (!b ==> !a); @@ -608,7 +608,7 @@ The [assertion batch](#sec-assertion-batches) of a method will not be split unless the cost of an [assertion batch](#sec-assertion-batches) exceeds this number, defaults to 2000.0. In [keep-going mode](#sec-vcs_max_keep_going_splits), only applies to the first round. -If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. +If [`{:isolate_assertions}`](#sec-isolate_assertions) is set, then this parameter is useless. ### 11.2.23. `{:vcs_max_keep_going_splits N}` {#sec-vcs_max_keep_going_splits} @@ -619,7 +619,7 @@ until we succeed proving them, or there is only one single assertion that it timeouts (in which case an error is reported for that assertion). Defaults to 1. -If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. +If [`{:isolate_assertions}`](#sec-isolate_assertions) is set, then this parameter is useless. ### 11.2.24. `{:vcs_max_splits N}` {#sec-vcs_max_splits} @@ -627,10 +627,10 @@ Per-method version of the command-line option `/vcsMaxSplits`. Maximal number of [assertion batches](#sec-assertion-batches) generated for this method. In [keep-going mode](#sec-vcs_max_keep_going_splits), only applies to the first round. Defaults to 1. -If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. +If [`{:isolate_assertions}`](#sec-isolate_assertions) is set, then this parameter is useless. -### 11.2.25. `{:vcs_split_on_every_assert}` {#sec-vcs_split_on_every_assert} -Per-method version of the command-line option `/vcsSplitOnEveryAssert`. +### 11.2.25. `{:isolate_assertions}` {#sec-isolate_assertions} +Per-method version of the command-line option `/vcsSplitOnEveryAssert` In the first and only verification round, this option will split the original [assertion batch](#sec-assertion-batches) into one assertion batch per assertion. diff --git a/docs/DafnyRef/UserGuide.md b/docs/DafnyRef/UserGuide.md index 4c1f2d49f38..6e779312294 100644 --- a/docs/DafnyRef/UserGuide.md +++ b/docs/DafnyRef/UserGuide.md @@ -1434,7 +1434,7 @@ The fundamental unit of verification in `dafny` is an _assertion batch_, which c * If the verifier says it is correct,[^smt-encoding] it means that all the assertions hold. * If the verifier returns a counterexample, this counterexample is used to determine both the failing assertion and the failing path. In order to retrieve additional failing assertions, `dafny` will again query the verifier after turning previously failed assertions into assumptions.[^example-assertion-turned-into-assumption] [^caveat-about-assertion-and-assumption] -* If the verifier returns `unknown` or times out, or even preemptively for difficult assertions or to reduce the chance that the verifier will ‘be confused’ by the many assertions in a large batch, `dafny` may partition the assertions into smaller batches[^smaller-batches]. An extreme case is the use of the `/vcsSplitOnEveryAssert` command-line option or the [`{:vcs_split_on_every_assert}` attribute](#sec-vcs_split_on_every_assert), which causes `dafny` to make one batch for each assertion. +* If the verifier returns `unknown` or times out, or even preemptively for difficult assertions or to reduce the chance that the verifier will ‘be confused’ by the many assertions in a large batch, `dafny` may partition the assertions into smaller batches[^smaller-batches]. An extreme case is the use of the `/vcsSplitOnEveryAssert` command-line option or the [`{:isolate_assertions}` attribute](#sec-isolate_assertions), which causes `dafny` to make one batch for each assertion. [^smt-encoding]: The formula sent to the underlying SMT solver is the negation of the formula that the verifier wants to prove - also called a VC or verification condition. Hence, if the SMT solver returns "unsat", it means that the SMT formula is always false, meaning the verifier's formula is always true. On the other side, if the SMT solver returns "sat", it means that the SMT formula can be made true with a special variable assignment, which means that the verifier's formula is false under that same variable assignment, meaning it's a counter-example for the verifier. In practice and because of quantifiers, the SMT solver will usually return "unknown" instead of "sat", but will still provide a variable assignment that it couldn't prove that it does not make the formula true. `dafny` reports it as a "counter-example" but it might not be a real counter-example, only provide hints about what `dafny` knows. @@ -1450,7 +1450,7 @@ Here is how you can control how `dafny` partitions assertions into batches. * [`{:focus}`](#sec-focus) on an assert generates a separate assertion batch for the assertions of the enclosing block. * [`{:split_here}`](#sec-split_here) on an assert generates a separate assertion batch for assertions after this point. -* [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) on a function or a method generates one assertion batch per assertion +* [`{:isolate_assertions}`](#sec-isolate_assertions) on a function or a method generates one assertion batch per assertion We discourage the use of the following _heuristics attributes_ to partition assertions into batches. The effect of these attributes may vary, because they are low-level attributes and tune low-level heuristics, and will result in splits that could be manually controlled anyway. @@ -2679,7 +2679,7 @@ Legacy options: * `-vcsSplitOnEveryAssert` - prove each (explicit or implicit) assertion in each procedure separately. See also the attribute - [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) for + [`{:isolate_assertions}`](#sec-isolate_assertions) for restricting this option on specific procedures. By default, Boogie attempts to prove that every assertion in a given procedure holds all at once, in a single query to an SMT solver. This usually performs diff --git a/docs/VerificationOptimization/VerificationOptimization.md b/docs/VerificationOptimization/VerificationOptimization.md index d7052b7befa..aa83919a5ce 100644 --- a/docs/VerificationOptimization/VerificationOptimization.md +++ b/docs/VerificationOptimization/VerificationOptimization.md @@ -78,9 +78,9 @@ Dafny provides several attributes that tell it to verify certain assertions sepa * The [`{:focus}`](../DafnyRef/DafnyRef#sec-focus) attribute on an `assert` or `assume` statement tells Dafny to verify all assertions in the containing block, and everything that _always_ follows it, in one batch, and the rest of the definition in another batch (potentially subject to further splitting due to other occurrences of `{:focus}`). -* The [`{:vcs_split_on_every_assert}`](../DafnyRef/DafnyRef#sec-vcs_split_on_every_assert) attribute on a definition tells Dafny to verify each assertion in that definition in its own batch. You can think of this as being similar to having many `{:focus}` or `{:split_here}` occurrences, including on assertions that arise implicitly, such as preconditions of calls or side conditions on partial operations. +* The [`{:isolate_assertions}`](../DafnyRef/DafnyRef#sec-isolate_assertions) attribute on a definition tells Dafny to verify each assertion in that definition in its own batch. You can think of this as being similar to having many `{:focus}` or `{:split_here}` occurrences, including on assertions that arise implicitly, such as preconditions of calls or side conditions on partial operations. -We recommend using `{:vcs_split_on_every_assert}` over either of the other attributes under most circumstances. It can also be specified globally, applying to all definitions, with `dafny verify --isolate-assertions`. If you're using the legacy options without top-level commands, use the `/vcsSplitOnEveryAssert` flag, instead. +We recommend using `{:isolate_assertions}` over either of the other attributes under most circumstances. It can also be specified globally, applying to all definitions, with `dafny verify --isolate-assertions`. If you're using the legacy options without top-level commands, use the `/vcsSplitOnEveryAssert` flag, instead. When Dafny verifies a definition in smaller batches, the VS Code plugin will display performance statistics for each batch when you hover over a particular definition. @@ -91,7 +91,7 @@ Consider the following method, which proves a few simple arithmetic facts. const TWO_TO_THE_32: int := 0x1_00000000 newtype uint32 = x: int | 0 <= x < TWO_TO_THE_32 -method {:vcs_split_on_every_assert} ProveSomeArithmetic(x: uint32) { +method {:isolate_assertions} ProveSomeArithmetic(x: uint32) { assert forall y :: y * y != 115249; // 115249 is prime assert (x as bv32) as uint32 <= x; assert x < 65535 ==> x * 2 == x + x; @@ -104,7 +104,7 @@ Hovering over the name of the definition will show you performance statistics fo Although the time taken to complete verification is ultimately the factor that most impacts the development cycle, this time can depend on CPU frequency scaling, other processes, etc., so Z3 provides a separate measurement of verification difficulty known as a _resource count_. When running the same build of Z3 on the same platform multiple times, the resource count is deterministic, unlike time. Therefore, the IDE displays performance information in terms of Resource Units (RU). -Hovering over a specific assertion will show you performance statistics for the specific batch containing that assertion (and, in the case of `{:vcs_split_on_every_assert}`, only that assertion). +Hovering over a specific assertion will show you performance statistics for the specific batch containing that assertion (and, in the case of `{:isolate_assertions}`, only that assertion). ![image](hover-assertion.png) diff --git a/docs/dev/news/5247.feat b/docs/dev/news/5247.feat new file mode 100644 index 00000000000..b203266de28 --- /dev/null +++ b/docs/dev/news/5247.feat @@ -0,0 +1 @@ +Add the attribute `{:isolate_assertions}`, which does the same as `{:vcs_split_on_every_assert}`. Deprecated `{:vcs_split_on_every_assert}` \ No newline at end of file