summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Clément Pit--Claudel <clement.pitclaudel@live.com>2015-07-17 17:25:10 -0700
committerGravatar Clément Pit--Claudel <clement.pitclaudel@live.com>2015-07-17 17:25:10 -0700
commit7c766a43a77845ed1af5a0e5367e7a21edf13a8f (patch)
tree21911b3d9a25d4cc74dca3f831a635929428b993
parentfc6ebea9b9ec614e4e014c64d9cad7940deb86fb (diff)
parent61a5be0930c43694d270809ed5550c74b6e59e5d (diff)
Merge my autoTriggers work into the master branch
This contains trigger related things under the autoTriggers flag (disabled by default), and some bug-fixes and cleanups that are already enabled.
-rw-r--r--Binaries/DafnyPrelude.bpl8
-rw-r--r--INSTALL34
-rw-r--r--LICENSE22
-rw-r--r--Source/Dafny/Cloner.cs21
-rw-r--r--Source/Dafny/Compiler.cs137
-rw-r--r--Source/Dafny/Dafny.atg39
-rw-r--r--Source/Dafny/DafnyAst.cs189
-rw-r--r--Source/Dafny/DafnyOptions.cs48
-rw-r--r--Source/Dafny/Makefile4
-rw-r--r--Source/Dafny/Parser.cs1002
-rw-r--r--Source/Dafny/RefinementTransformer.cs9
-rw-r--r--Source/Dafny/Resolver.cs481
-rw-r--r--Source/Dafny/Rewriter.cs46
-rw-r--r--Source/Dafny/Scanner.cs167
-rw-r--r--Source/Dafny/SccGraph.cs10
-rw-r--r--Source/Dafny/Translator.cs493
-rw-r--r--Source/Dafny/Util.cs149
-rw-r--r--Source/DafnyDriver/DafnyDriver.cs7
-rw-r--r--Source/DafnyExtension/IdentifierTagger.cs24
-rw-r--r--Test/VerifyThis2015/Problem3.dfy2
-rw-r--r--Test/dafny0/Basics.dfy2
-rw-r--r--Test/dafny0/EqualityTypes.dfy112
-rw-r--r--Test/dafny0/EqualityTypes.dfy.expect24
-rw-r--r--Test/dafny0/Fuel.dfy423
-rw-r--r--Test/dafny0/Fuel.dfy.expect95
-rw-r--r--Test/dafny0/JustWarnings.dfy19
-rw-r--r--Test/dafny0/JustWarnings.dfy.expect4
-rw-r--r--Test/dafny0/Modules0.dfy14
-rw-r--r--Test/dafny0/Modules0.dfy.expect19
-rw-r--r--Test/dafny0/NestedMatch.dfy2
-rw-r--r--Test/dafny0/NestedPatterns.dfy8
-rw-r--r--Test/dafny0/ResolutionErrors.dfy10
-rw-r--r--Test/dafny0/Shadows.dfy42
-rw-r--r--Test/dafny0/Shadows.dfy.expect12
-rw-r--r--Test/dafny0/Trait/TraitsDecreases.dfy46
-rw-r--r--Test/dafny0/Trait/TraitsDecreases.dfy.expect20
-rw-r--r--Test/dafny4/Circ.dfy2
-rw-r--r--Test/dafny4/NipkowKlein-chapter3.dfy6
-rw-r--r--Test/dafny4/NipkowKlein-chapter3.dfy.expect2
-rw-r--r--Test/dafny4/NumberRepresentations.dfy2
-rw-r--r--Test/hofs/Classes.dfy17
-rw-r--r--Test/hofs/Classes.dfy.expect5
-rw-r--r--Test/hofs/Examples.dfy14
-rw-r--r--Test/hofs/Fold.dfy2
-rw-r--r--Test/hofs/Monads.dfy34
-rw-r--r--Test/hofs/Naked.dfy10
-rw-r--r--Test/hofs/Naked.dfy.expect8
-rw-r--r--Test/hofs/ReadsReads.dfy52
-rw-r--r--Test/hofs/Requires.dfy82
-rw-r--r--Test/hofs/Requires.dfy.expect5
-rw-r--r--Test/hofs/ResolveError.dfy34
-rw-r--r--Test/hofs/ResolveError.dfy.expect6
-rw-r--r--Test/hofs/Simple.dfy20
-rw-r--r--Test/hofs/Simple.dfy.expect5
-rw-r--r--Test/hofs/TreeMapSimple.dfy24
-rw-r--r--Test/hofs/Twice.dfy4
-rw-r--r--Test/hofs/VectorUpdate.dfy65
-rw-r--r--Test/hofs/VectorUpdate.dfy.expect2
-rw-r--r--Test/irondafny0/FIFO.dfy43
-rw-r--r--Test/irondafny0/FIFO.dfy.expect8
-rw-r--r--Test/irondafny0/LIFO.dfy43
-rw-r--r--Test/irondafny0/LIFO.dfy.expect8
-rw-r--r--Test/irondafny0/Queue.dfyi22
-rw-r--r--Test/irondafny0/inheritreqs0.dfy22
-rw-r--r--Test/irondafny0/inheritreqs0.dfy.expect6
-rw-r--r--Test/irondafny0/inheritreqs1.dfy22
-rw-r--r--Test/irondafny0/inheritreqs1.dfy.expect6
-rw-r--r--Test/irondafny0/opened_workaround.dfy21
-rw-r--r--Test/irondafny0/opened_workaround.dfy.expect3
-rw-r--r--Test/irondafny0/xrefine0.dfy6
-rw-r--r--Test/irondafny0/xrefine0.dfy.expect2
-rw-r--r--Test/irondafny0/xrefine1.dfy77
-rw-r--r--Test/irondafny0/xrefine1.dfy.expect6
-rw-r--r--Test/irondafny0/xrefine2.dfy77
-rw-r--r--Test/irondafny0/xrefine2.dfy.expect9
-rw-r--r--Test/irondafny0/xrefine3.dfy72
-rw-r--r--Test/irondafny0/xrefine3.dfy.expect6
77 files changed, 3517 insertions, 1087 deletions
diff --git a/Binaries/DafnyPrelude.bpl b/Binaries/DafnyPrelude.bpl
index dbf9b76c..2ca10f73 100644
--- a/Binaries/DafnyPrelude.bpl
+++ b/Binaries/DafnyPrelude.bpl
@@ -273,6 +273,8 @@ const unique class._System.set: ClassName;
const unique class._System.seq: ClassName;
const unique class._System.multiset: ClassName;
+function Tclass._System.object(): Ty;
+
function /*{:never_pattern true}*/ dtype(ref): Ty; // changed from ClassName to Ty
function TypeTuple(a: ClassName, b: ClassName): ClassName;
@@ -287,6 +289,12 @@ axiom (forall a: ClassName, b: ClassName :: { TypeTuple(a,b) }
type HandleType;
+function SetRef_to_SetBox(s: [ref]bool): Set Box;
+axiom (forall s: [ref]bool, bx: Box :: { SetRef_to_SetBox(s)[bx] }
+ SetRef_to_SetBox(s)[bx] == s[$Unbox(bx): ref]);
+axiom (forall s: [ref]bool :: { SetRef_to_SetBox(s) }
+ $Is(SetRef_to_SetBox(s), TSet(Tclass._System.object())));
+
// ---------------------------------------------------------------
// -- Datatypes --------------------------------------------------
// ---------------------------------------------------------------
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 00000000..2a70587e
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,34 @@
+Building on Linux
+=================
+
+1. Create an empty base directory
+
+ mkdir BASE-DRIECTORY
+ cd BASE-DRIECTORY
+
+2. Download and build Boogie:
+
+ git clone https://github.com/boogie-org/boogie
+ cd boogie
+ mozroots --import --sync
+ wget https://nuget.org/nuget.exe
+ mono ./nuget.exe restore Source/Boogie.sln
+ xbuild Source/Boogie.sln
+
+3. Download and build Dafny:
+
+ hg clone https://hg.codeplex.com/dafny
+ cd dafny/Sources/
+ xbuild Dafny.sln
+
+4. Download and build Z3
+
+ git clone https://github.com/Z3Prover/z3.git
+ cd z3
+ ./configure && make && sudo make install
+
+5. Symlink the z3 binaries so that Boogie and Z3 can find them:
+
+ cd BASE-DIRECTORY
+ ln -s /usr/bin/z3 boogie/Binaries/z3.exe
+ ln -s /usr/bin/z3 dafny/Binaries/z3.exe
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..327f6778
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+Microsoft Public License (MS-PL)
+
+This license governs use of the accompanying software. If you use the software, you
+accept this license. If you do not accept the license, do not use the software.
+
+1. Definitions
+The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
+same meaning here as under U.S. copyright law.
+A "contribution" is the original software, or any additions or changes to the software.
+A "contributor" is any person that distributes its contribution under this license.
+"Licensed patents" are a contributor's patent claims that read directly on its contribution.
+
+2. Grant of Rights
+(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
+(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
+
+3. Conditions and Limitations
+(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
+(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
+(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
+(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
+(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
diff --git a/Source/Dafny/Cloner.cs b/Source/Dafny/Cloner.cs
index be77f6b4..f959b537 100644
--- a/Source/Dafny/Cloner.cs
+++ b/Source/Dafny/Cloner.cs
@@ -17,12 +17,15 @@ namespace Microsoft.Dafny
if (m is DefaultModuleDecl) {
nw = new DefaultModuleDecl();
} else {
- nw = new ModuleDefinition(Tok(m.tok), name, m.IsAbstract, m.IsFacade, m.RefinementBaseName, m.Module, CloneAttributes(m.Attributes), true);
+ nw = new ModuleDefinition(Tok(m.tok), name, m.IsAbstract, m.IsFacade, m.IsExclusiveRefinement, m.RefinementBaseName, m.Module, CloneAttributes(m.Attributes), true);
}
foreach (var d in m.TopLevelDecls) {
nw.TopLevelDecls.Add(CloneDeclaration(d, nw));
}
- nw.RefinementBase = m.RefinementBase;
+ if (null != m.RefinementBase) {
+ nw.RefinementBase = m.RefinementBase;
+ }
+ nw.ClonedFrom = m;
nw.Height = m.Height;
return nw;
}
@@ -33,7 +36,7 @@ namespace Microsoft.Dafny
if (d is OpaqueTypeDecl) {
var dd = (OpaqueTypeDecl)d;
- return new OpaqueTypeDecl(Tok(dd.tok), dd.Name, m, dd.EqualitySupport, dd.TypeArgs.ConvertAll(CloneTypeParam), CloneAttributes(dd.Attributes));
+ return new OpaqueTypeDecl(Tok(dd.tok), dd.Name, m, dd.EqualitySupport, dd.TypeArgs.ConvertAll(CloneTypeParam), CloneAttributes(dd.Attributes), d);
} else if (d is TypeSynonymDecl) {
var dd = (TypeSynonymDecl)d;
var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
@@ -41,9 +44,9 @@ namespace Microsoft.Dafny
} else if (d is NewtypeDecl) {
var dd = (NewtypeDecl)d;
if (dd.Var == null) {
- return new NewtypeDecl(Tok(dd.tok), dd.Name, m, CloneType(dd.BaseType), CloneAttributes(dd.Attributes));
+ return new NewtypeDecl(Tok(dd.tok), dd.Name, m, CloneType(dd.BaseType), CloneAttributes(dd.Attributes), dd);
} else {
- return new NewtypeDecl(Tok(dd.tok), dd.Name, m, CloneBoundVar(dd.Var), CloneExpr(dd.Constraint), CloneAttributes(dd.Attributes));
+ return new NewtypeDecl(Tok(dd.tok), dd.Name, m, CloneBoundVar(dd.Var), CloneExpr(dd.Constraint), CloneAttributes(dd.Attributes), dd);
}
} else if (d is TupleTypeDecl) {
var dd = (TupleTypeDecl)d;
@@ -52,7 +55,7 @@ namespace Microsoft.Dafny
var dd = (IndDatatypeDecl)d;
var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
var ctors = dd.Ctors.ConvertAll(CloneCtor);
- var dt = new IndDatatypeDecl(Tok(dd.tok), dd.Name, m, tps, ctors, CloneAttributes(dd.Attributes));
+ var dt = new IndDatatypeDecl(Tok(dd.tok), dd.Name, m, tps, ctors, CloneAttributes(dd.Attributes), dd);
return dt;
} else if (d is CoDatatypeDecl) {
var dd = (CoDatatypeDecl)d;
@@ -105,7 +108,7 @@ namespace Microsoft.Dafny
if (d is DefaultClassDecl) {
return new DefaultClassDecl(m, mm);
} else {
- return new ClassDecl(Tok(dd.tok), dd.Name, m, tps, mm, CloneAttributes(dd.Attributes), dd.TraitsTyp.ConvertAll(CloneType));
+ return new ClassDecl(Tok(dd.tok), dd.Name, m, tps, mm, CloneAttributes(dd.Attributes), dd.TraitsTyp.ConvertAll(CloneType), dd);
}
} else if (d is ModuleDecl) {
if (d is LiteralModuleDecl) {
@@ -138,7 +141,7 @@ namespace Microsoft.Dafny
}
public TypeParameter CloneTypeParam(TypeParameter tp) {
- return new TypeParameter(Tok(tp.tok), tp.Name, tp.EqualitySupport);
+ return new TypeParameter(Tok(tp.tok), tp.Name, tp.EqualitySupport, tp);
}
public MemberDecl CloneMember(MemberDecl member) {
@@ -545,7 +548,7 @@ namespace Microsoft.Dafny
} else if (stmt is CalcStmt) {
var s = (CalcStmt)stmt;
- r = new CalcStmt(Tok(s.Tok), Tok(s.EndTok), CloneCalcOp(s.Op), s.Lines.ConvertAll(CloneExpr), s.Hints.ConvertAll(CloneBlockStmt), s.StepOps.ConvertAll(CloneCalcOp), CloneCalcOp(s.ResultOp));
+ r = new CalcStmt(Tok(s.Tok), Tok(s.EndTok), CloneCalcOp(s.Op), s.Lines.ConvertAll(CloneExpr), s.Hints.ConvertAll(CloneBlockStmt), s.StepOps.ConvertAll(CloneCalcOp), CloneCalcOp(s.ResultOp), CloneAttributes(s.Attributes));
} else if (stmt is MatchStmt) {
var s = (MatchStmt)stmt;
diff --git a/Source/Dafny/Compiler.cs b/Source/Dafny/Compiler.cs
index fd2392e6..4fdd34f6 100644
--- a/Source/Dafny/Compiler.cs
+++ b/Source/Dafny/Compiler.cs
@@ -940,15 +940,144 @@ namespace Microsoft.Dafny {
}
}
- void CompileReturnBody(Expression body, int indent) {
- Contract.Requires(0 <= indent);
- body = body.Resolved;
+ void TrCasePatternOpt(CasePattern pat, Expression rhs, string rhs_string, int indent) {
+ Contract.Requires(pat != null);
+ Contract.Requires(pat.Var != null || rhs != null);
+ if (pat.Var != null) {
+ // The trivial Dafny "pattern" expression
+ // var x := G
+ // is translated into C# as:
+ // var x := G;
+ var bv = pat.Var;
+ if (!bv.IsGhost) {
+ Indent(indent);
+ wr.Write("{0} {1} = ", TypeName(bv.Type), "@" + bv.CompileName);
+ if (rhs != null) {
+ TrExpr(rhs);
+ } else {
+ wr.Write(rhs_string);
+ }
+ wr.Write(";\n");
+ }
+ } else if (pat.Arguments != null) {
+ // The Dafny "pattern" expression
+ // var Pattern(x,y) := G
+ // is translated into C# as:
+ // var tmp := G;
+ // var x := dtorX(tmp);
+ // var y := dtorY(tmp);
+ var ctor = pat.Ctor;
+ Contract.Assert(ctor != null); // follows from successful resolution
+ Contract.Assert(pat.Arguments.Count == ctor.Formals.Count); // follows from successful resolution
+
+ // Create the temporary variable to hold G
+ var tmp_name = idGenerator.FreshId("_let_tmp_rhs");
+ Indent(indent);
+ wr.Write("{0} {1} = ", TypeName(rhs.Type), tmp_name);
+ TrExpr(rhs);
+ wr.WriteLine(";");
+
+ var k = 0; // number of non-ghost formals processed
+ for (int i = 0; i < pat.Arguments.Count; i++) {
+ var arg = pat.Arguments[i];
+ var formal = ctor.Formals[i];
+ if (formal.IsGhost) {
+ // nothing to compile, but do a sanity check
+ Contract.Assert(!Contract.Exists(arg.Vars, bv => !bv.IsGhost));
+ } else {
+ TrCasePatternOpt(arg, null, string.Format("(({0})({1})._D).@{2}", DtCtorName(ctor, ((DatatypeValue)pat.Expr).InferredTypeArgs), tmp_name, FormalName(formal, k)), indent);
+ k++;
+ }
+ }
+ }
+ }
+
+ void ReturnExpr(Expression expr, int indent) {
Indent(indent);
wr.Write("return ");
- TrExpr(body);
+ TrExpr(expr);
wr.WriteLine(";");
}
+ void TrExprOpt(Expression expr, int indent) {
+ Contract.Requires(expr != null);
+ if (expr is LetExpr) {
+ var e = (LetExpr)expr;
+ if (e.Exact) {
+ for (int i = 0; i < e.LHSs.Count; i++) {
+ var lhs = e.LHSs[i];
+ if (Contract.Exists(lhs.Vars, bv => !bv.IsGhost)) {
+ TrCasePatternOpt(lhs, e.RHSs[i], null, indent);
+ }
+ }
+ TrExprOpt(e.Body, indent);
+ } else {
+ // We haven't optimized the other cases, so fallback to normal compilation
+ ReturnExpr(e, indent);
+ }
+ } else if (expr is ITEExpr) {
+ ITEExpr e = (ITEExpr)expr;
+ Indent(indent);
+ wr.Write("if (");
+ TrExpr(e.Test);
+ wr.Write(") {\n");
+ TrExprOpt(e.Thn, indent + IndentAmount);
+ Indent(indent);
+ wr.WriteLine("} else {");
+ TrExprOpt(e.Els, indent + IndentAmount);
+ Indent(indent);
+ wr.WriteLine("}");
+ } else if (expr is MatchExpr) {
+ var e = (MatchExpr)expr;
+ // var _source = E;
+ // if (source.is_Ctor0) {
+ // FormalType f0 = ((Dt_Ctor0)source._D).a0;
+ // ...
+ // return Body0;
+ // } else if (...) {
+ // ...
+ // } else if (true) {
+ // ...
+ // }
+ string source = idGenerator.FreshId("_source");
+ Indent(indent);
+ wr.Write("{0} {1} = ", TypeName(e.Source.Type), source);
+ TrExpr(e.Source);
+ wr.WriteLine(";");
+
+ if (e.Cases.Count == 0) {
+ // the verifier would have proved we never get here; still, we need some code that will compile
+ wr.Write("throw new System.Exception();");
+ } else {
+ int i = 0;
+ var sourceType = (UserDefinedType)e.Source.Type.NormalizeExpand();
+ foreach (MatchCaseExpr mc in e.Cases) {
+ //Indent(indent);
+ MatchCasePrelude(source, sourceType, cce.NonNull(mc.Ctor), mc.Arguments, i, e.Cases.Count, indent);
+ TrExprOpt(mc.Body, indent + IndentAmount);
+ i++;
+ }
+ Indent(indent);
+ wr.WriteLine("}");
+ }
+ } else if (expr is StmtExpr) {
+ var e = (StmtExpr)expr;
+ TrExprOpt(e.E, indent);
+ } else {
+ // We haven't optimized any other cases, so fallback to normal compilation
+ ReturnExpr(expr, indent);
+ }
+ }
+
+ void CompileReturnBody(Expression body, int indent) {
+ Contract.Requires(0 <= indent);
+ body = body.Resolved;
+ //Indent(indent);
+ //wr.Write("return ");
+ TrExprOpt(body, indent);
+ //wr.WriteLine(";");
+ }
+
// ----- Type ---------------------------------------------------------------------------------
readonly string DafnySetClass = "Dafny.Set";
diff --git a/Source/Dafny/Dafny.atg b/Source/Dafny/Dafny.atg
index 6cc0af5a..f30542d0 100644
--- a/Source/Dafny/Dafny.atg
+++ b/Source/Dafny/Dafny.atg
@@ -299,6 +299,9 @@ bool IsGenericInstantiation() {
return false;
}
}
+/* Returns true if the next thing is of the form:
+ * "<" Type { "," Type } ">"
+ */
bool IsTypeList(ref IToken pt) {
if (pt.kind != _openAngleBracket) {
return false;
@@ -306,6 +309,10 @@ bool IsTypeList(ref IToken pt) {
pt = scanner.Peek();
return IsTypeSequence(ref pt, _closeAngleBracket);
}
+/* Returns true if the next thing is of the form:
+ * Type { "," Type }
+ * followed by an endBracketKind.
+ */
bool IsTypeSequence(ref IToken pt, int endBracketKind) {
while (true) {
if (!IsType(ref pt)) {
@@ -343,7 +350,7 @@ bool IsType(ref IToken pt) {
case _map:
case _imap:
pt = scanner.Peek();
- return IsTypeList(ref pt);
+ return pt.kind != _openAngleBracket || IsTypeList(ref pt);
case _ident:
while (true) {
// invariant: next token is an ident
@@ -362,6 +369,11 @@ bool IsType(ref IToken pt) {
}
case _openparen:
pt = scanner.Peek();
+ if (pt.kind == _closeparen) {
+ // end of type list
+ pt = scanner.Peek();
+ return true;
+ }
return IsTypeSequence(ref pt, _closeparen);
default:
return false;
@@ -515,7 +527,7 @@ Dafny
| OtherTypeDecl<defaultModule, out td> (. defaultModule.TopLevelDecls.Add(td); .)
| IteratorDecl<defaultModule, out iter> (. defaultModule.TopLevelDecls.Add(iter); .)
| TraitDecl<defaultModule, out trait> (. defaultModule.TopLevelDecls.Add(trait); .)
- | ClassMemberDecl<membersDefaultClass, false, !DafnyOptions.O.AllowGlobals>
+ | ClassMemberDecl<membersDefaultClass, false, !DafnyOptions.O.AllowGlobals, false>
}
(. // find the default class in the default module, then append membersDefaultClass to its member list
DefaultClassDecl defaultClass = null;
@@ -542,6 +554,7 @@ SubModuleDecl<ModuleDefinition parent, out ModuleDecl submodule>
ModuleDecl sm;
submodule = null; // appease compiler
bool isAbstract = false;
+ bool isExclusively = false;
bool opened = false;
.)
( [ "abstract" (. isAbstract = true; .) ]
@@ -549,7 +562,9 @@ SubModuleDecl<ModuleDefinition parent, out ModuleDecl submodule>
{ Attribute<ref attrs> }
NoUSIdent<out id>
- [ "refines" QualifiedModuleName<out idRefined> ] (. module = new ModuleDefinition(id, id.val, isAbstract, false, idRefined == null ? null : idRefined, parent, attrs, false); .)
+ [ "exclusively" "refines" QualifiedModuleName<out idRefined> (. isExclusively = true; .)
+ | "refines" QualifiedModuleName<out idRefined> (. isExclusively = false; .) ]
+ (. module = new ModuleDefinition(id, id.val, isAbstract, false, isExclusively, idRefined == null ? null : idRefined, parent, attrs, false, this); .)
"{" (. module.BodyStartTok = t; .)
{ SubModuleDecl<module, out sm> (. module.TopLevelDecls.Add(sm); .)
| ClassDecl<module, out c> (. module.TopLevelDecls.Add(c); .)
@@ -558,7 +573,7 @@ SubModuleDecl<ModuleDefinition parent, out ModuleDecl submodule>
| NewtypeDecl<module, out td> (. module.TopLevelDecls.Add(td); .)
| OtherTypeDecl<module, out td> (. module.TopLevelDecls.Add(td); .)
| IteratorDecl<module, out iter> (. module.TopLevelDecls.Add(iter); .)
- | ClassMemberDecl<namedModuleDefaultClassMembers, false, !DafnyOptions.O.AllowGlobals>
+ | ClassMemberDecl<namedModuleDefaultClassMembers, false, !DafnyOptions.O.AllowGlobals, true>
}
"}" (. module.BodyEndTok = t;
module.TopLevelDecls.Add(new DefaultClassDecl(module, namedModuleDefaultClassMembers));
@@ -615,7 +630,7 @@ ClassDecl<ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c>
{"," Type<out trait> (. traits.Add(trait); .) }
]
"{" (. bodyStart = t; .)
- { ClassMemberDecl<members, true, false>
+ { ClassMemberDecl<members, true, false, false>
}
"}"
(. c = new ClassDecl(id, id.val, module, typeArgs, members, attrs, traits);
@@ -639,7 +654,7 @@ ClassDecl<ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c>
NoUSIdent<out id>
[ GenericParameters<typeArgs> ]
"{" (. bodyStart = t; .)
- { ClassMemberDecl<members, true, false>
+ { ClassMemberDecl<members, true, false, false>
}
"}"
(. trait = new TraitDecl(id, id.val, module, typeArgs, members, attrs);
@@ -648,7 +663,7 @@ ClassDecl<ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c>
.)
.
-ClassMemberDecl<.List<MemberDecl> mm, bool allowConstructors, bool moduleLevelDecl.>
+ClassMemberDecl<.List<MemberDecl> mm, bool allowConstructors, bool moduleLevelDecl, bool permitAbstractDecl.>
= (. Contract.Requires(cce.NonNullElements(mm));
Method/*!*/ m;
Function/*!*/ f;
@@ -682,7 +697,7 @@ ClassMemberDecl<.List<MemberDecl> mm, bool allowConstructors, bool moduleLevelDe
mmod.IsProtected = false;
}
.)
- MethodDecl<mmod, allowConstructors, out m> (. mm.Add(m); .)
+ MethodDecl<mmod, allowConstructors, permitAbstractDecl, out m> (. mm.Add(m); .)
)
.
DatatypeDecl<ModuleDefinition/*!*/ module, out DatatypeDecl/*!*/ dt>
@@ -934,7 +949,7 @@ GenericParameters<.List<TypeParameter/*!*/>/*!*/ typeArgs.>
">"
.
/*------------------------------------------------------------------------*/
-MethodDecl<MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m>
+MethodDecl<MemberModifiers mmod, bool allowConstructor, bool permitAbstractDecl, out Method/*!*/ m>
= (. Contract.Ensures(Contract.ValueAtReturn(out m) !=null);
IToken/*!*/ id = Token.NoToken;
bool hasName = false; IToken keywordToken;
@@ -1015,7 +1030,7 @@ MethodDecl<MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m>
[ BlockStmt<out body, out bodyStart, out bodyEnd>
]
(.
- if (DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported") && !Attributes.Contains(attrs, "decl") && theVerifyThisFile) {
+ if (!permitAbstractDecl && DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported") && !Attributes.Contains(attrs, "decl") && theVerifyThisFile) {
SemErr(t, "a method with an ensures clause must have a body, unless given the :axiom attribute");
}
@@ -1965,6 +1980,7 @@ ModifyStmt<out Statement s>
CalcStmt<out Statement s>
= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
Token x;
+ Attributes attrs = null;
CalcStmt.CalcOp op, calcOp = Microsoft.Dafny.CalcStmt.DefaultOp, resOp = Microsoft.Dafny.CalcStmt.DefaultOp;
var lines = new List<Expression>();
var hints = new List<BlockStmt>();
@@ -1976,6 +1992,7 @@ CalcStmt<out Statement s>
IToken danglingOperator = null;
.)
"calc" (. x = t; .)
+ { IF(IsAttribute()) Attribute<ref attrs> }
[ CalcOp<out opTok, out calcOp> (. maybeOp = calcOp.ResultOp(calcOp); // guard against non-transitive calcOp (like !=)
if (maybeOp == null) {
SemErr(opTok, "the main operator of a calculation must be transitive");
@@ -2024,7 +2041,7 @@ CalcStmt<out Statement s>
// Repeat the last line to create a dummy line for the dangling hint
lines.Add(lines[lines.Count - 1]);
}
- s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp);
+ s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp, attrs);
.)
.
CalcOp<out IToken x, out CalcStmt.CalcOp/*!*/ op>
diff --git a/Source/Dafny/DafnyAst.cs b/Source/Dafny/DafnyAst.cs
index af51d650..21f5fadd 100644
--- a/Source/Dafny/DafnyAst.cs
+++ b/Source/Dafny/DafnyAst.cs
@@ -87,7 +87,7 @@ namespace Microsoft.Dafny {
public class BuiltIns
{
- public readonly ModuleDefinition SystemModule = new ModuleDefinition(Token.NoToken, "_System", false, false, null, null, null, true);
+ public readonly ModuleDefinition SystemModule = new ModuleDefinition(Token.NoToken, "_System", false, false, /*isExclusiveRefinement:*/ false, null, null, null, true);
readonly Dictionary<int, ClassDecl> arrayTypeDecls = new Dictionary<int, ClassDecl>();
readonly Dictionary<int, ArrowTypeDecl> arrowTypeDecls = new Dictionary<int, ArrowTypeDecl>();
readonly Dictionary<int, TupleTypeDecl> tupleTypeDecls = new Dictionary<int, TupleTypeDecl>();
@@ -306,6 +306,22 @@ namespace Microsoft.Dafny {
return null;
}
+
+ /// <summary>
+ /// Same as FindExpressions, but returns all matches
+ /// </summary>
+ public static List<List<Expression>> FindAllExpressions(Attributes attrs, string nm) {
+ Contract.Requires(nm != null);
+ List<List<Expression>> ret = null;
+ for (; attrs != null; attrs = attrs.Prev) {
+ if (attrs.Name == nm) {
+ ret = ret ?? new List<List<Expression>>(); // Avoid allocating the list in the common case where we don't find nm
+ ret.Add(attrs.Args);
+ }
+ }
+ return ret;
+ }
+
/// <summary>
/// Returns true if "nm" is a specified attribute whose arguments match the "allowed" parameter.
/// - if "nm" is not found in attrs, return false and leave value unmodified. Otherwise,
@@ -1471,6 +1487,8 @@ namespace Microsoft.Dafny {
IToken INamedRegion.BodyEndTok { get { return BodyEndTok; } }
string INamedRegion.Name { get { return Name; } }
string compileName;
+ private readonly Declaration clonedFrom;
+
public virtual string CompileName {
get {
if (compileName == null) {
@@ -1481,12 +1499,19 @@ namespace Microsoft.Dafny {
}
public Attributes Attributes; // readonly, except during class merging in the refinement transformations
- public Declaration(IToken tok, string name, Attributes attributes) {
+ public Declaration(IToken tok, string name, Attributes attributes, Declaration clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
this.tok = tok;
this.Name = name;
this.Attributes = attributes;
+ this.clonedFrom = clonedFrom;
+ }
+
+ public Declaration ClonedFrom {
+ get {
+ return this.clonedFrom;
+ }
}
[Pure]
@@ -1498,12 +1523,10 @@ namespace Microsoft.Dafny {
internal FreshIdGenerator IdGenerator = new FreshIdGenerator();
}
- public class OpaqueType_AsParameter : TypeParameter
- {
+ public class OpaqueType_AsParameter : TypeParameter {
public readonly List<TypeParameter> TypeArgs;
public OpaqueType_AsParameter(IToken tok, string name, EqualitySupportValue equalitySupport, List<TypeParameter> typeArgs)
- : base(tok, name, equalitySupport)
- {
+ : base(tok, name, equalitySupport) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(typeArgs != null);
@@ -1551,8 +1574,8 @@ namespace Microsoft.Dafny {
}
public int PositionalIndex; // which type parameter this is (ie. in C<S, T, U>, S is 0, T is 1 and U is 2).
- public TypeParameter(IToken tok, string name, EqualitySupportValue equalitySupport = EqualitySupportValue.Unspecified)
- : base(tok, name, null) {
+ public TypeParameter(IToken tok, string name, EqualitySupportValue equalitySupport = EqualitySupportValue.Unspecified, Declaration clonedFrom = null)
+ : base(tok, name, null, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
EqualitySupport = equalitySupport;
@@ -1627,7 +1650,7 @@ namespace Microsoft.Dafny {
}
public class ModuleSignature {
-
+ private ModuleDefinition exclusiveRefinement = null;
public readonly Dictionary<string, TopLevelDecl> TopLevels = new Dictionary<string, TopLevelDecl>();
public readonly Dictionary<string, Tuple<DatatypeCtor, bool>> Ctors = new Dictionary<string, Tuple<DatatypeCtor, bool>>();
public readonly Dictionary<string, MemberDecl> StaticMembers = new Dictionary<string, MemberDecl>();
@@ -1648,6 +1671,25 @@ namespace Microsoft.Dafny {
return false;
}
}
+
+ public ModuleDefinition ExclusiveRefinement {
+ get {
+ if (null == exclusiveRefinement) {
+ return ModuleDef == null ? null : ModuleDef.ExclusiveRefinement;
+ } else {
+ return exclusiveRefinement;
+ }
+ }
+
+ set {
+ if (null == ExclusiveRefinement) {
+ exclusiveRefinement = null;
+ } else {
+ throw new InvalidOperationException("An exclusive refinement relationship cannot be amended.");
+ }
+ }
+ }
+
}
public class ModuleDefinition : INamedRegion
@@ -1663,22 +1705,64 @@ namespace Microsoft.Dafny {
public readonly Attributes Attributes;
public readonly List<IToken> RefinementBaseName; // null if no refinement base
public ModuleDecl RefinementBaseRoot; // filled in early during resolution, corresponds to RefinementBaseName[0]
- public ModuleDefinition RefinementBase; // filled in during resolution (null if no refinement base)
+
public List<Include> Includes;
public readonly List<TopLevelDecl> TopLevelDecls = new List<TopLevelDecl>(); // filled in by the parser; readonly after that
public readonly Graph<ICallable> CallGraph = new Graph<ICallable>(); // filled in during resolution
public int Height; // height in the topological sorting of modules; filled in during resolution
public readonly bool IsAbstract;
+ public readonly bool IsExclusiveRefinement;
public readonly bool IsFacade; // True iff this module represents a module facade (that is, an abstract interface)
private readonly bool IsBuiltinName; // true if this is something like _System that shouldn't have it's name mangled.
+
+ private ModuleDefinition exclusiveRefinement;
+
+ public ModuleDefinition ExclusiveRefinement {
+ get { return exclusiveRefinement; }
+ set {
+ if (null == exclusiveRefinement) {
+ if (!value.IsExclusiveRefinement) {
+ throw new ArgumentException(
+ string.Format("Exclusive refinement of {0} with 'new' module {0} is disallowed.",
+ Name,
+ value.Name));
+ }
+ // todo: validate state of `value`.
+ exclusiveRefinement = value;
+ } else {
+ throw new InvalidOperationException(string.Format("Exclusive refinement of {0} has already been established {1}; cannot reestabilish as {2}.", Name, exclusiveRefinement.Name, value.Name));
+ }
+ }
+ }
+
+ public int ExclusiveRefinementCount { get; set; }
+
+ private ModuleDefinition refinementBase; // filled in during resolution via RefinementBase property (null if no refinement base yet or at all).
+
+ public ModuleDefinition RefinementBase {
+ get {
+ return refinementBase;
+ }
+
+ set {
+ // the refinementBase member may only be changed once.
+ if (null != refinementBase) {
+ throw new InvalidOperationException(string.Format("This module ({0}) already has a refinement base ({1}).", Name, refinementBase.Name));
+ }
+ refinementBase = value;
+ }
+ }
+
+ public ModuleDefinition ClonedFrom { get; set; }
+
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(cce.NonNullElements(TopLevelDecls));
Contract.Invariant(CallGraph != null);
}
- public ModuleDefinition(IToken tok, string name, bool isAbstract, bool isFacade, List<IToken> refinementBase, ModuleDefinition parent, Attributes attributes, bool isBuiltinName)
+ public ModuleDefinition(IToken tok, string name, bool isAbstract, bool isFacade, bool isExclusiveRefinement, List<IToken> refinementBase, ModuleDefinition parent, Attributes attributes, bool isBuiltinName, Parser parser = null)
{
Contract.Requires(tok != null);
Contract.Requires(name != null);
@@ -1689,10 +1773,19 @@ namespace Microsoft.Dafny {
RefinementBaseName = refinementBase;
IsAbstract = isAbstract;
IsFacade = isFacade;
+ IsExclusiveRefinement = isExclusiveRefinement;
RefinementBaseRoot = null;
- RefinementBase = null;
+ this.refinementBase = null;
Includes = new List<Include>();
IsBuiltinName = isBuiltinName;
+
+ if (isExclusiveRefinement && !DafnyOptions.O.IronDafny) {
+ parser.errors.SynErr(
+ tok.filename,
+ tok.line,
+ tok.col,
+ "The exclusively keyword is experimental and only available when IronDafny features are enabled (/ironDafny).");
+ }
}
public virtual bool IsDefaultModule {
get {
@@ -1829,7 +1922,9 @@ namespace Microsoft.Dafny {
}
public class DefaultModuleDecl : ModuleDefinition {
- public DefaultModuleDecl() : base(Token.NoToken, "_module", false, false, null, null, null, true) {
+ public DefaultModuleDecl()
+ : base(Token.NoToken, "_module", false, false, /*isExclusiveRefinement:*/ false, null, null, null, true)
+ {
}
public override bool IsDefaultModule {
get {
@@ -1847,8 +1942,8 @@ namespace Microsoft.Dafny {
Contract.Invariant(cce.NonNullElements(TypeArgs));
}
- public TopLevelDecl(IToken tok, string name, ModuleDefinition module, List<TypeParameter> typeArgs, Attributes attributes)
- : base(tok, name, attributes) {
+ public TopLevelDecl(IToken tok, string name, ModuleDefinition module, List<TypeParameter> typeArgs, Attributes attributes, Declaration clonedFrom = null)
+ : base(tok, name, attributes, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(cce.NonNullElements(typeArgs));
@@ -1904,8 +1999,8 @@ namespace Microsoft.Dafny {
}
public ClassDecl(IToken tok, string name, ModuleDefinition module,
- List<TypeParameter> typeArgs, [Captured] List<MemberDecl> members, Attributes attributes, List<Type> traits)
- : base(tok, name, module, typeArgs, attributes) {
+ List<TypeParameter> typeArgs, [Captured] List<MemberDecl> members, Attributes attributes, List<Type> traits, ClassDecl clonedFrom = null)
+ : base(tok, name, module, typeArgs, attributes, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
@@ -1919,6 +2014,12 @@ namespace Microsoft.Dafny {
return false;
}
}
+
+ public new ClassDecl ClonedFrom {
+ get {
+ return (ClassDecl)base.ClonedFrom;
+ }
+ }
}
public class DefaultClassDecl : ClassDecl {
@@ -1981,8 +2082,8 @@ namespace Microsoft.Dafny {
}
public DatatypeDecl(IToken tok, string name, ModuleDefinition module, List<TypeParameter> typeArgs,
- [Captured] List<DatatypeCtor> ctors, Attributes attributes)
- : base(tok, name, module, typeArgs, attributes) {
+ [Captured] List<DatatypeCtor> ctors, Attributes attributes, DatatypeDecl clonedFrom = null)
+ : base(tok, name, module, typeArgs, attributes, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
@@ -1996,6 +2097,12 @@ namespace Microsoft.Dafny {
return (TypeArgs.Count == 0 && Ctors.TrueForAll(ctr => ctr.Formals.Count == 0));
}
}
+
+ public new DatatypeDecl ClonedFrom {
+ get {
+ return (DatatypeDecl)base.ClonedFrom;
+ }
+ }
}
public class IndDatatypeDecl : DatatypeDecl
@@ -2008,8 +2115,8 @@ namespace Microsoft.Dafny {
public ES EqualitySupport = ES.NotYetComputed;
public IndDatatypeDecl(IToken tok, string name, ModuleDefinition module, List<TypeParameter> typeArgs,
- [Captured] List<DatatypeCtor> ctors, Attributes attributes)
- : base(tok, name, module, typeArgs, ctors, attributes) {
+ [Captured] List<DatatypeCtor> ctors, Attributes attributes, IndDatatypeDecl clonedFrom = null)
+ : base(tok, name, module, typeArgs, ctors, attributes, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
@@ -2017,6 +2124,12 @@ namespace Microsoft.Dafny {
Contract.Requires(cce.NonNullElements(ctors));
Contract.Requires(1 <= ctors.Count);
}
+
+ public new IndDatatypeDecl ClonedFrom {
+ get {
+ return (IndDatatypeDecl)base.ClonedFrom;
+ }
+ }
}
public class TupleTypeDecl : IndDatatypeDecl
@@ -2101,7 +2214,7 @@ namespace Microsoft.Dafny {
public List<DatatypeDestructor> Destructors = new List<DatatypeDestructor>(); // contents filled in during resolution; includes both implicit (not mentionable in source) and explicit destructors
public DatatypeCtor(IToken tok, string name, [Captured] List<Formal> formals, Attributes attributes)
- : base(tok, name, attributes) {
+ : base(tok, name, attributes, null) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(cce.NonNullElements(formals));
@@ -2137,6 +2250,7 @@ namespace Microsoft.Dafny {
public interface ICallable : ICodeContext
{
IToken Tok { get; }
+ string WhatKind { get; }
string NameRelativeToModule { get; }
Specification<Expression> Decreases { get; }
/// <summary>
@@ -2148,6 +2262,7 @@ namespace Microsoft.Dafny {
}
public class DontUseICallable : ICallable
{
+ public string WhatKind { get { throw new cce.UnreachableException(); } }
public bool IsGhost { get { throw new cce.UnreachableException(); } }
public List<TypeParameter> TypeArgs { get { throw new cce.UnreachableException(); } }
public List<Formal> Ins { get { throw new cce.UnreachableException(); } }
@@ -2311,7 +2426,7 @@ namespace Microsoft.Dafny {
public TopLevelDecl EnclosingClass; // filled in during resolution
public MemberDecl RefinementBase; // filled in during the pre-resolution refinement transformation; null if the member is new here
public MemberDecl(IToken tok, string name, bool hasStaticKeyword, bool isGhost, Attributes attributes)
- : base(tok, name, attributes) {
+ : base(tok, name, attributes, null) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
HasStaticKeyword = hasStaticKeyword;
@@ -2448,8 +2563,8 @@ namespace Microsoft.Dafny {
Contract.Invariant(TheType != null && Name == TheType.Name);
}
- public OpaqueTypeDecl(IToken tok, string name, ModuleDefinition module, TypeParameter.EqualitySupportValue equalitySupport, List<TypeParameter> typeArgs, Attributes attributes)
- : base(tok, name, module, typeArgs, attributes) {
+ public OpaqueTypeDecl(IToken tok, string name, ModuleDefinition module, TypeParameter.EqualitySupportValue equalitySupport, List<TypeParameter> typeArgs, Attributes attributes, Declaration clonedFrom = null)
+ : base(tok, name, module, typeArgs, attributes, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
@@ -2490,16 +2605,16 @@ namespace Microsoft.Dafny {
public readonly BoundVar Var; // can be null (if non-null, then object.ReferenceEquals(Var.Type, BaseType))
public readonly Expression Constraint; // is null iff Var is
public NativeType NativeType; // non-null for fixed-size representations (otherwise, use BigIntegers for integers)
- public NewtypeDecl(IToken tok, string name, ModuleDefinition module, Type baseType, Attributes attributes)
- : base(tok, name, module, new List<TypeParameter>(), attributes) {
+ public NewtypeDecl(IToken tok, string name, ModuleDefinition module, Type baseType, Attributes attributes, NewtypeDecl clonedFrom = null)
+ : base(tok, name, module, new List<TypeParameter>(), attributes, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
Contract.Requires(baseType != null);
BaseType = baseType;
}
- public NewtypeDecl(IToken tok, string name, ModuleDefinition module, BoundVar bv, Expression constraint, Attributes attributes)
- : base(tok, name, module, new List<TypeParameter>(), attributes) {
+ public NewtypeDecl(IToken tok, string name, ModuleDefinition module, BoundVar bv, Expression constraint, Attributes attributes, NewtypeDecl clonedFrom = null)
+ : base(tok, name, module, new List<TypeParameter>(), attributes, clonedFrom) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
@@ -2530,6 +2645,12 @@ namespace Microsoft.Dafny {
get { throw new cce.UnreachableException(); } // see comment above about ICallable.Decreases
set { throw new cce.UnreachableException(); } // see comment above about ICallable.Decreases
}
+
+ public new NewtypeDecl ClonedFrom {
+ get {
+ return (NewtypeDecl)base.ClonedFrom;
+ }
+ }
}
public class TypeSynonymDecl : TopLevelDecl, RedirectingTypeDecl
@@ -2875,6 +2996,7 @@ namespace Microsoft.Dafny {
public override string WhatKind { get { return "function"; } }
public readonly bool IsProtected;
public bool IsRecursive; // filled in during resolution
+ public bool IsFueled; // filled in during resolution if anyone tries to adjust this function's fuel
public readonly List<TypeParameter> TypeArgs;
public readonly List<Formal> Formals;
public readonly Type ResultType;
@@ -2900,7 +3022,7 @@ namespace Microsoft.Dafny {
return Contract.Exists(Decreases.Expressions, e => e is WildcardExpr);
}
}
-
+
/// <summary>
/// The "AllCalls" field is used for non-FixpointPredicate, non-PrefixPredicate functions only (so its value should not be relied upon for FixpointPredicate and PrefixPredicate functions).
/// It records all function calls made by the Function, including calls made in the body as well as in the specification.
@@ -2945,6 +3067,7 @@ namespace Microsoft.Dafny {
Contract.Requires(cce.NonNullElements(ens));
Contract.Requires(decreases != null);
this.IsProtected = isProtected;
+ this.IsFueled = false; // Defaults to false. Only set to true if someone mentions this function in a fuel annotation
this.TypeArgs = typeArgs;
this.Formals = formals;
this.ResultType = resultType;
@@ -2969,6 +3092,9 @@ namespace Microsoft.Dafny {
}
ModuleDefinition ICodeContext.EnclosingModule { get { return this.EnclosingClass.Module; } }
bool ICodeContext.MustReverify { get { return false; } }
+
+ [Pure]
+ public bool IsFuelAware() { return IsRecursive || IsFueled; }
}
public class Predicate : Function
@@ -4641,7 +4767,7 @@ namespace Microsoft.Dafny {
Contract.Invariant(StepOps.Count == Hints.Count);
}
- public CalcStmt(IToken tok, IToken endTok, CalcOp op, List<Expression> lines, List<BlockStmt> hints, List<CalcOp> stepOps, CalcOp resultOp)
+ public CalcStmt(IToken tok, IToken endTok, CalcOp op, List<Expression> lines, List<BlockStmt> hints, List<CalcOp> stepOps, CalcOp resultOp, Attributes attrs)
: base(tok, endTok)
{
Contract.Requires(tok != null);
@@ -4666,6 +4792,7 @@ namespace Microsoft.Dafny {
}
this.Steps = new List<Expression>();
this.Result = null;
+ this.Attributes = attrs;
}
public override IEnumerable<Statement> SubStatements
diff --git a/Source/Dafny/DafnyOptions.cs b/Source/Dafny/DafnyOptions.cs
index a809cbd6..8972c490 100644
--- a/Source/Dafny/DafnyOptions.cs
+++ b/Source/Dafny/DafnyOptions.cs
@@ -15,7 +15,11 @@ namespace Microsoft.Dafny
public override string VersionNumber {
get {
- return System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion;
+ return System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion
+#if ENABLE_IRONDAFNY
+ + "[IronDafny]"
+#endif
+ ;
}
}
public override string VersionSuffix {
@@ -58,6 +62,16 @@ namespace Microsoft.Dafny
public bool Optimize = false;
public bool AutoTriggers = false;
public bool PrintTooltips = false;
+ public bool PrintStats = false;
+ public bool PrintFunctionCallGraph = false;
+ public bool WarnShadowing = false;
+ public bool IronDafny =
+#if ENABLE_IRONDAFNY
+ true
+#else
+ false
+#endif
+ ;
protected override bool ParseOption(string name, Bpl.CommandLineOptionEngine.CommandLineParseState ps) {
var args = ps.args; // convenient synonym
@@ -174,6 +188,18 @@ namespace Microsoft.Dafny
case "allowGlobals":
AllowGlobals = true;
return true;
+
+ case "stats":
+ PrintStats = true;
+ return true;
+
+ case "funcCallGraph":
+ PrintFunctionCallGraph = true;
+ return true;
+
+ case "warnShadowing":
+ WarnShadowing = true;
+ return true;
case "countVerificationErrors": {
int countErrors = 1; // defaults to reporting verification errors
@@ -200,6 +226,16 @@ namespace Microsoft.Dafny
return true;
}
+ case "noIronDafny": {
+ IronDafny = false;
+ return true;
+ }
+
+ case "ironDafny": {
+ IronDafny = true;
+ return true;
+ }
+
default:
break;
}
@@ -281,7 +317,7 @@ namespace Microsoft.Dafny
/noAutoReq Ignore autoReq attributes
/allowGlobals Allow the implicit class '_default' to contain fields, instance functions,
and instance methods. These class members are declared at the module scope,
- outside of explicit classes. This command-line option is provided to simply
+ outside of explicit classes. This command-line option is provided to simplify
a transition from the behavior in the language prior to version 1.9.3, from
which point onward all functions and methods declared at the module scope are
implicitly static and fields declarations are not allowed at the module scope.
@@ -300,6 +336,14 @@ namespace Microsoft.Dafny
System.Collections.Immutable.dll in the source directory to successfully
compile).
- passes /optimize flag to csc.exe.
+ /stats Print interesting statistics about the Dafny files supplied.
+ /funcCallGraph Print out the function call graph. Format is: func,mod=callee*
+ /warnShadowing Emits a warning if the name of a declared variable caused another variable
+ to be shadowed
+ /ironDafny Enable experimental features needed to support Ironclad/Ironfleet. Use of
+ these features may cause your code to become incompatible with future
+ releases of Dafny.
+ /noIronDafny Disable Ironclad/Ironfleet features, if enabled by default.
/printTooltips
Dump additional positional information (displayed as mouse-over tooltips by
the VS plugin) to stdout as 'Info' messages.
diff --git a/Source/Dafny/Makefile b/Source/Dafny/Makefile
index 4c01c780..e8c0f5e0 100644
--- a/Source/Dafny/Makefile
+++ b/Source/Dafny/Makefile
@@ -4,8 +4,8 @@
# from http://boogiepartners.codeplex.com/. Update the FRAME_DIR variable to
# point to whatever directory you install that into.
# ###############################################################################
-COCO_EXE_DIR = ..\..\..\boogiepartners\CocoRdownload
-FRAME_DIR = ..\..\..\boogiepartners\CocoR\Modified
+COCO_EXE_DIR = ..\..\..\boogie-partners\CocoRdownload
+FRAME_DIR = ..\..\..\boogie-partners\CocoR\Modified
COCO = $(COCO_EXE_DIR)\Coco.exe
# "all" depends on 2 files, really (Parser.cs and Scanner.cs), but they
diff --git a/Source/Dafny/Parser.cs b/Source/Dafny/Parser.cs
index b183fff1..76e0ebba 100644
--- a/Source/Dafny/Parser.cs
+++ b/Source/Dafny/Parser.cs
@@ -72,10 +72,10 @@ public class Parser {
public const int _star = 56;
public const int _notIn = 57;
public const int _ellipsis = 58;
- public const int maxT = 137;
+ public const int maxT = 138;
- const bool _T = true;
- const bool _x = false;
+ const bool T = true;
+ const bool x = false;
const int minErrDist = 2;
public Scanner/*!*/ scanner;
@@ -370,6 +370,9 @@ bool IsGenericInstantiation() {
return false;
}
}
+/* Returns true if the next thing is of the form:
+ * "<" Type { "," Type } ">"
+ */
bool IsTypeList(ref IToken pt) {
if (pt.kind != _openAngleBracket) {
return false;
@@ -377,6 +380,10 @@ bool IsTypeList(ref IToken pt) {
pt = scanner.Peek();
return IsTypeSequence(ref pt, _closeAngleBracket);
}
+/* Returns true if the next thing is of the form:
+ * Type { "," Type }
+ * followed by an endBracketKind.
+ */
bool IsTypeSequence(ref IToken pt, int endBracketKind) {
while (true) {
if (!IsType(ref pt)) {
@@ -414,7 +421,7 @@ bool IsType(ref IToken pt) {
case _map:
case _imap:
pt = scanner.Peek();
- return IsTypeList(ref pt);
+ return pt.kind != _openAngleBracket || IsTypeList(ref pt);
case _ident:
while (true) {
// invariant: next token is an ident
@@ -433,6 +440,11 @@ bool IsType(ref IToken pt) {
}
case _openparen:
pt = scanner.Peek();
+ if (pt.kind == _closeparen) {
+ // end of type list
+ pt = scanner.Peek();
+ return true;
+ }
return IsTypeSequence(ref pt, _closeparen);
default:
return false;
@@ -540,43 +552,43 @@ bool IsType(ref IToken pt) {
}
while (StartOf(1)) {
switch (la.kind) {
- case 60: case 61: case 63: {
+ case 60: case 61: case 64: {
SubModuleDecl(defaultModule, out submodule);
defaultModule.TopLevelDecls.Add(submodule);
break;
}
- case 68: {
+ case 69: {
ClassDecl(defaultModule, out c);
defaultModule.TopLevelDecls.Add(c);
break;
}
- case 74: case 75: {
+ case 75: case 76: {
DatatypeDecl(defaultModule, out dt);
defaultModule.TopLevelDecls.Add(dt);
break;
}
- case 77: {
+ case 78: {
NewtypeDecl(defaultModule, out td);
defaultModule.TopLevelDecls.Add(td);
break;
}
- case 78: {
+ case 79: {
OtherTypeDecl(defaultModule, out td);
defaultModule.TopLevelDecls.Add(td);
break;
}
- case 79: {
+ case 80: {
IteratorDecl(defaultModule, out iter);
defaultModule.TopLevelDecls.Add(iter);
break;
}
- case 70: {
+ case 71: {
TraitDecl(defaultModule, out trait);
defaultModule.TopLevelDecls.Add(trait);
break;
}
- case 37: case 38: case 39: case 40: case 41: case 71: case 72: case 73: case 76: case 82: case 83: case 84: case 85: {
- ClassMemberDecl(membersDefaultClass, false, !DafnyOptions.O.AllowGlobals);
+ case 37: case 38: case 39: case 40: case 41: case 72: case 73: case 74: case 77: case 83: case 84: case 85: case 86: {
+ ClassMemberDecl(membersDefaultClass, false, !DafnyOptions.O.AllowGlobals, false);
break;
}
}
@@ -606,6 +618,7 @@ bool IsType(ref IToken pt) {
ModuleDecl sm;
submodule = null; // appease compiler
bool isAbstract = false;
+ bool isExclusively = false;
bool opened = false;
if (la.kind == 60 || la.kind == 61) {
@@ -618,52 +631,60 @@ bool IsType(ref IToken pt) {
Attribute(ref attrs);
}
NoUSIdent(out id);
- if (la.kind == 62) {
- Get();
- QualifiedModuleName(out idRefined);
+ if (la.kind == 62 || la.kind == 63) {
+ if (la.kind == 62) {
+ Get();
+ Expect(63);
+ QualifiedModuleName(out idRefined);
+ isExclusively = true;
+ } else {
+ Get();
+ QualifiedModuleName(out idRefined);
+ isExclusively = false;
+ }
}
- module = new ModuleDefinition(id, id.val, isAbstract, false, idRefined == null ? null : idRefined, parent, attrs, false);
+ module = new ModuleDefinition(id, id.val, isAbstract, false, isExclusively, idRefined == null ? null : idRefined, parent, attrs, false, this);
Expect(45);
module.BodyStartTok = t;
while (StartOf(1)) {
switch (la.kind) {
- case 60: case 61: case 63: {
+ case 60: case 61: case 64: {
SubModuleDecl(module, out sm);
module.TopLevelDecls.Add(sm);
break;
}
- case 68: {
+ case 69: {
ClassDecl(module, out c);
module.TopLevelDecls.Add(c);
break;
}
- case 70: {
+ case 71: {
TraitDecl(module, out trait);
module.TopLevelDecls.Add(trait);
break;
}
- case 74: case 75: {
+ case 75: case 76: {
DatatypeDecl(module, out dt);
module.TopLevelDecls.Add(dt);
break;
}
- case 77: {
+ case 78: {
NewtypeDecl(module, out td);
module.TopLevelDecls.Add(td);
break;
}
- case 78: {
+ case 79: {
OtherTypeDecl(module, out td);
module.TopLevelDecls.Add(td);
break;
}
- case 79: {
+ case 80: {
IteratorDecl(module, out iter);
module.TopLevelDecls.Add(iter);
break;
}
- case 37: case 38: case 39: case 40: case 41: case 71: case 72: case 73: case 76: case 82: case 83: case 84: case 85: {
- ClassMemberDecl(namedModuleDefaultClassMembers, false, !DafnyOptions.O.AllowGlobals);
+ case 37: case 38: case 39: case 40: case 41: case 72: case 73: case 74: case 77: case 83: case 84: case 85: case 86: {
+ ClassMemberDecl(namedModuleDefaultClassMembers, false, !DafnyOptions.O.AllowGlobals, true);
break;
}
}
@@ -672,22 +693,22 @@ bool IsType(ref IToken pt) {
module.BodyEndTok = t;
module.TopLevelDecls.Add(new DefaultClassDecl(module, namedModuleDefaultClassMembers));
submodule = new LiteralModuleDecl(module, parent);
- } else if (la.kind == 63) {
+ } else if (la.kind == 64) {
Get();
- if (la.kind == 64) {
+ if (la.kind == 65) {
Get();
opened = true;
}
NoUSIdent(out id);
- if (la.kind == 65 || la.kind == 66) {
- if (la.kind == 65) {
+ if (la.kind == 66 || la.kind == 67) {
+ if (la.kind == 66) {
Get();
QualifiedModuleName(out idPath);
submodule = new AliasModuleDecl(idPath, id, parent, opened);
} else {
Get();
QualifiedModuleName(out idPath);
- if (la.kind == 67) {
+ if (la.kind == 68) {
Get();
QualifiedModuleName(out idAssignment);
}
@@ -695,7 +716,7 @@ bool IsType(ref IToken pt) {
}
}
if (la.kind == 27) {
- while (!(la.kind == 0 || la.kind == 27)) {SynErr(138); Get();}
+ while (!(la.kind == 0 || la.kind == 27)) {SynErr(139); Get();}
Get();
errors.Warning(t, "the semi-colon that used to terminate a sub-module declaration has been deprecated; in the new syntax, just leave off the semi-colon");
}
@@ -705,7 +726,7 @@ bool IsType(ref IToken pt) {
submodule = new AliasModuleDecl(idPath, id, parent, opened);
}
- } else SynErr(139);
+ } else SynErr(140);
}
void ClassDecl(ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c) {
@@ -719,8 +740,8 @@ bool IsType(ref IToken pt) {
List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
IToken bodyStart;
- while (!(la.kind == 0 || la.kind == 68)) {SynErr(140); Get();}
- Expect(68);
+ while (!(la.kind == 0 || la.kind == 69)) {SynErr(141); Get();}
+ Expect(69);
while (la.kind == 45) {
Attribute(ref attrs);
}
@@ -728,7 +749,7 @@ bool IsType(ref IToken pt) {
if (la.kind == 51) {
GenericParameters(typeArgs);
}
- if (la.kind == 69) {
+ if (la.kind == 70) {
Get();
Type(out trait);
traits.Add(trait);
@@ -741,7 +762,7 @@ bool IsType(ref IToken pt) {
Expect(45);
bodyStart = t;
while (StartOf(2)) {
- ClassMemberDecl(members, true, false);
+ ClassMemberDecl(members, true, false, false);
}
Expect(46);
c = new ClassDecl(id, id.val, module, typeArgs, members, attrs, traits);
@@ -760,13 +781,13 @@ bool IsType(ref IToken pt) {
IToken bodyStart = Token.NoToken; // dummy assignment
bool co = false;
- while (!(la.kind == 0 || la.kind == 74 || la.kind == 75)) {SynErr(141); Get();}
- if (la.kind == 74) {
+ while (!(la.kind == 0 || la.kind == 75 || la.kind == 76)) {SynErr(142); Get();}
+ if (la.kind == 75) {
Get();
- } else if (la.kind == 75) {
+ } else if (la.kind == 76) {
Get();
co = true;
- } else SynErr(142);
+ } else SynErr(143);
while (la.kind == 45) {
Attribute(ref attrs);
}
@@ -774,7 +795,7 @@ bool IsType(ref IToken pt) {
if (la.kind == 51) {
GenericParameters(typeArgs);
}
- Expect(65);
+ Expect(66);
bodyStart = t;
DatatypeMemberDecl(ctors);
while (la.kind == 23) {
@@ -782,7 +803,7 @@ bool IsType(ref IToken pt) {
DatatypeMemberDecl(ctors);
}
if (la.kind == 27) {
- while (!(la.kind == 0 || la.kind == 27)) {SynErr(143); Get();}
+ while (!(la.kind == 0 || la.kind == 27)) {SynErr(144); Get();}
Get();
errors.Warning(t, "the semi-colon that used to terminate a (co)datatype declaration has been deprecated; in the new syntax, just leave off the semi-colon");
}
@@ -803,12 +824,12 @@ bool IsType(ref IToken pt) {
Type baseType = null;
Expression wh;
- Expect(77);
+ Expect(78);
while (la.kind == 45) {
Attribute(ref attrs);
}
NoUSIdent(out id);
- Expect(65);
+ Expect(66);
if (IsIdentColonOrBar()) {
NoUSIdent(out bvId);
if (la.kind == 21) {
@@ -822,7 +843,7 @@ bool IsType(ref IToken pt) {
} else if (StartOf(3)) {
Type(out baseType);
td = new NewtypeDecl(theVerifyThisFile ? id : new IncludeToken(id), id.val, module, baseType, attrs);
- } else SynErr(144);
+ } else SynErr(145);
}
void OtherTypeDecl(ModuleDefinition module, out TopLevelDecl td) {
@@ -833,7 +854,7 @@ bool IsType(ref IToken pt) {
td = null;
Type ty;
- Expect(78);
+ Expect(79);
while (la.kind == 45) {
Attribute(ref attrs);
}
@@ -850,18 +871,18 @@ bool IsType(ref IToken pt) {
if (la.kind == 51) {
GenericParameters(typeArgs);
}
- if (la.kind == 65) {
+ if (la.kind == 66) {
Get();
Type(out ty);
td = new TypeSynonymDecl(id, id.val, typeArgs, module, ty, attrs);
}
- } else SynErr(145);
+ } else SynErr(146);
if (td == null) {
td = new OpaqueTypeDecl(id, id.val, module, eqSupport, typeArgs, attrs);
}
if (la.kind == 27) {
- while (!(la.kind == 0 || la.kind == 27)) {SynErr(146); Get();}
+ while (!(la.kind == 0 || la.kind == 27)) {SynErr(147); Get();}
Get();
errors.Warning(t, "the semi-colon that used to terminate an opaque-type declaration has been deprecated; in the new syntax, just leave off the semi-colon");
}
@@ -890,8 +911,8 @@ bool IsType(ref IToken pt) {
IToken bodyStart = Token.NoToken;
IToken bodyEnd = Token.NoToken;
- while (!(la.kind == 0 || la.kind == 79)) {SynErr(147); Get();}
- Expect(79);
+ while (!(la.kind == 0 || la.kind == 80)) {SynErr(148); Get();}
+ Expect(80);
while (la.kind == 45) {
Attribute(ref attrs);
}
@@ -901,8 +922,8 @@ bool IsType(ref IToken pt) {
GenericParameters(typeArgs);
}
Formals(true, true, ins);
- if (la.kind == 80 || la.kind == 81) {
- if (la.kind == 80) {
+ if (la.kind == 81 || la.kind == 82) {
+ if (la.kind == 81) {
Get();
} else {
Get();
@@ -913,7 +934,7 @@ bool IsType(ref IToken pt) {
} else if (la.kind == 58) {
Get();
signatureEllipsis = t;
- } else SynErr(148);
+ } else SynErr(149);
while (StartOf(5)) {
IteratorSpec(reads, mod, decreases, req, ens, yieldReq, yieldEns, ref readsAttrs, ref modAttrs, ref decrAttrs);
}
@@ -940,8 +961,8 @@ bool IsType(ref IToken pt) {
List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
IToken bodyStart;
- while (!(la.kind == 0 || la.kind == 70)) {SynErr(149); Get();}
- Expect(70);
+ while (!(la.kind == 0 || la.kind == 71)) {SynErr(150); Get();}
+ Expect(71);
while (la.kind == 45) {
Attribute(ref attrs);
}
@@ -952,7 +973,7 @@ bool IsType(ref IToken pt) {
Expect(45);
bodyStart = t;
while (StartOf(2)) {
- ClassMemberDecl(members, true, false);
+ ClassMemberDecl(members, true, false, false);
}
Expect(46);
trait = new TraitDecl(id, id.val, module, typeArgs, members, attrs);
@@ -961,18 +982,18 @@ bool IsType(ref IToken pt) {
}
- void ClassMemberDecl(List<MemberDecl> mm, bool allowConstructors, bool moduleLevelDecl) {
+ void ClassMemberDecl(List<MemberDecl> mm, bool allowConstructors, bool moduleLevelDecl, bool permitAbstractDecl) {
Contract.Requires(cce.NonNullElements(mm));
Method/*!*/ m;
Function/*!*/ f;
MemberModifiers mmod = new MemberModifiers();
IToken staticToken = null, protectedToken = null;
- while (la.kind == 71 || la.kind == 72 || la.kind == 73) {
- if (la.kind == 71) {
+ while (la.kind == 72 || la.kind == 73 || la.kind == 74) {
+ if (la.kind == 72) {
Get();
mmod.IsGhost = true;
- } else if (la.kind == 72) {
+ } else if (la.kind == 73) {
Get();
mmod.IsStatic = true; staticToken = t;
} else {
@@ -980,7 +1001,7 @@ bool IsType(ref IToken pt) {
mmod.IsProtected = true; protectedToken = t;
}
}
- if (la.kind == 76) {
+ if (la.kind == 77) {
if (moduleLevelDecl) {
SemErr(la, "fields are not allowed to be declared at the module level; instead, wrap the field in a 'class' declaration");
mmod.IsStatic = false;
@@ -1006,9 +1027,9 @@ bool IsType(ref IToken pt) {
mmod.IsProtected = false;
}
- MethodDecl(mmod, allowConstructors, out m);
+ MethodDecl(mmod, allowConstructors, permitAbstractDecl, out m);
mm.Add(m);
- } else SynErr(150);
+ } else SynErr(151);
}
void Attribute(ref Attributes attrs) {
@@ -1093,8 +1114,8 @@ bool IsType(ref IToken pt) {
Attributes attrs = null;
IToken/*!*/ id; Type/*!*/ ty;
- while (!(la.kind == 0 || la.kind == 76)) {SynErr(151); Get();}
- Expect(76);
+ while (!(la.kind == 0 || la.kind == 77)) {SynErr(152); Get();}
+ Expect(77);
if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
while (la.kind == 45) {
@@ -1131,7 +1152,7 @@ bool IsType(ref IToken pt) {
if (la.kind == 37) {
Get();
- if (la.kind == 82) {
+ if (la.kind == 83) {
Get();
isFunctionMethod = true;
}
@@ -1151,11 +1172,11 @@ bool IsType(ref IToken pt) {
} else if (la.kind == 58) {
Get();
signatureEllipsis = t;
- } else SynErr(152);
+ } else SynErr(153);
} else if (la.kind == 38) {
Get();
isPredicate = true;
- if (la.kind == 82) {
+ if (la.kind == 83) {
Get();
isFunctionMethod = true;
}
@@ -1182,7 +1203,7 @@ bool IsType(ref IToken pt) {
} else if (la.kind == 58) {
Get();
signatureEllipsis = t;
- } else SynErr(153);
+ } else SynErr(154);
} else if (la.kind == 39) {
Get();
Expect(38);
@@ -1205,7 +1226,7 @@ bool IsType(ref IToken pt) {
} else if (la.kind == 58) {
Get();
signatureEllipsis = t;
- } else SynErr(154);
+ } else SynErr(155);
} else if (la.kind == 41) {
Get();
isCoPredicate = true;
@@ -1227,8 +1248,8 @@ bool IsType(ref IToken pt) {
} else if (la.kind == 58) {
Get();
signatureEllipsis = t;
- } else SynErr(155);
- } else SynErr(156);
+ } else SynErr(156);
+ } else SynErr(157);
decreases = isIndPredicate || isCoPredicate ? null : new List<Expression/*!*/>();
while (StartOf(9)) {
FunctionSpec(reqs, reads, ens, decreases);
@@ -1264,7 +1285,7 @@ bool IsType(ref IToken pt) {
}
- void MethodDecl(MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m) {
+ void MethodDecl(MemberModifiers mmod, bool allowConstructor, bool permitAbstractDecl, out Method/*!*/ m) {
Contract.Ensures(Contract.ValueAtReturn(out m) !=null);
IToken/*!*/ id = Token.NoToken;
bool hasName = false; IToken keywordToken;
@@ -1287,9 +1308,9 @@ bool IsType(ref IToken pt) {
IToken bodyStart = Token.NoToken;
IToken bodyEnd = Token.NoToken;
- while (!(StartOf(10))) {SynErr(157); Get();}
+ while (!(StartOf(10))) {SynErr(158); Get();}
switch (la.kind) {
- case 82: {
+ case 83: {
Get();
break;
}
@@ -1298,12 +1319,12 @@ bool IsType(ref IToken pt) {
isLemma = true;
break;
}
- case 83: {
+ case 84: {
Get();
isCoLemma = true;
break;
}
- case 84: {
+ case 85: {
Get();
isCoLemma = true;
errors.Warning(t, "the 'comethod' keyword has been deprecated; it has been renamed to 'colemma'");
@@ -1316,7 +1337,7 @@ bool IsType(ref IToken pt) {
isIndLemma = true;
break;
}
- case 85: {
+ case 86: {
Get();
if (allowConstructor) {
isConstructor = true;
@@ -1326,7 +1347,7 @@ bool IsType(ref IToken pt) {
break;
}
- default: SynErr(158); break;
+ default: SynErr(159); break;
}
keywordToken = t;
if (isLemma) {
@@ -1369,7 +1390,7 @@ bool IsType(ref IToken pt) {
GenericParameters(typeArgs);
}
Formals(true, !mmod.IsGhost, ins);
- if (la.kind == 81) {
+ if (la.kind == 82) {
Get();
if (isConstructor) { SemErr(t, "constructors cannot have out-parameters"); }
Formals(false, !mmod.IsGhost, outs);
@@ -1377,14 +1398,14 @@ bool IsType(ref IToken pt) {
} else if (la.kind == 58) {
Get();
signatureEllipsis = t;
- } else SynErr(159);
+ } else SynErr(160);
while (StartOf(11)) {
MethodSpec(req, mod, ens, dec, ref decAttrs, ref modAttrs);
}
if (la.kind == 45) {
BlockStmt(out body, out bodyStart, out bodyEnd);
}
- if (DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported") && !Attributes.Contains(attrs, "decl") && theVerifyThisFile) {
+ if (!permitAbstractDecl && DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported") && !Attributes.Contains(attrs, "decl") && theVerifyThisFile) {
SemErr(t, "a method with an ensures clause must have a body, unless given the :axiom attribute");
}
@@ -1450,14 +1471,14 @@ bool IsType(ref IToken pt) {
} else if (la.kind == 2) {
Get();
id = t;
- } else SynErr(160);
+ } else SynErr(161);
Expect(21);
Type(out ty);
}
void OldSemi() {
if (la.kind == 27) {
- while (!(la.kind == 0 || la.kind == 27)) {SynErr(161); Get();}
+ while (!(la.kind == 0 || la.kind == 27)) {SynErr(162); Get();}
Get();
}
}
@@ -1480,7 +1501,7 @@ bool IsType(ref IToken pt) {
Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
isGhost = false;
- if (la.kind == 71) {
+ if (la.kind == 72) {
Get();
if (allowGhostKeyword) { isGhost = true; } else { SemErr(t, "formal cannot be declared 'ghost' in this context"); }
}
@@ -1532,7 +1553,7 @@ bool IsType(ref IToken pt) {
Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
Contract.Ensures(Contract.ValueAtReturn(out identName)!=null);
string name = null; id = Token.NoToken; ty = new BoolType()/*dummy*/; isGhost = false;
- if (la.kind == 71) {
+ if (la.kind == 72) {
Get();
isGhost = true;
}
@@ -1554,7 +1575,7 @@ bool IsType(ref IToken pt) {
id = t; name = id.val;
Expect(21);
Type(out ty);
- } else SynErr(162);
+ } else SynErr(163);
if (name != null) {
identName = name;
} else {
@@ -1742,7 +1763,7 @@ bool IsType(ref IToken pt) {
ty = new UserDefinedType(e.tok, e);
break;
}
- default: SynErr(163); break;
+ default: SynErr(164); break;
}
if (la.kind == 29) {
Type t2;
@@ -1763,7 +1784,7 @@ bool IsType(ref IToken pt) {
void Formals(bool incoming, bool allowGhostKeyword, List<Formal> formals) {
Contract.Requires(cce.NonNullElements(formals)); IToken id; Type ty; bool isGhost;
Expect(49);
- if (la.kind == 1 || la.kind == 71) {
+ if (la.kind == 1 || la.kind == 72) {
GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
while (la.kind == 22) {
@@ -1781,7 +1802,7 @@ List<MaybeFreeExpression/*!*/>/*!*/ yieldReq, List<MaybeFreeExpression/*!*/>/*!*
ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; bool isYield = false; Attributes ensAttrs = null;
- while (!(StartOf(13))) {SynErr(164); Get();}
+ while (!(StartOf(13))) {SynErr(165); Get();}
if (la.kind == 43) {
Get();
while (IsAttribute()) {
@@ -1809,13 +1830,13 @@ ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
}
OldSemi();
} else if (StartOf(14)) {
- if (la.kind == 86) {
+ if (la.kind == 87) {
Get();
isFree = true;
errors.Warning(t, "the 'free' keyword is soon to be deprecated");
}
- if (la.kind == 88) {
+ if (la.kind == 89) {
Get();
isYield = true;
}
@@ -1829,7 +1850,7 @@ ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
req.Add(new MaybeFreeExpression(e, isFree));
}
- } else if (la.kind == 87) {
+ } else if (la.kind == 88) {
Get();
while (IsAttribute()) {
Attribute(ref ensAttrs);
@@ -1842,7 +1863,7 @@ ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
}
- } else SynErr(165);
+ } else SynErr(166);
} else if (la.kind == 35) {
Get();
while (IsAttribute()) {
@@ -1850,7 +1871,7 @@ ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
}
DecreasesList(decreases, false, false);
OldSemi();
- } else SynErr(166);
+ } else SynErr(167);
}
void BlockStmt(out BlockStmt/*!*/ block, out IToken bodyStart, out IToken bodyEnd) {
@@ -1872,7 +1893,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Contract.Requires(cce.NonNullElements(req)); Contract.Requires(cce.NonNullElements(mod)); Contract.Requires(cce.NonNullElements(ens)); Contract.Requires(cce.NonNullElements(decreases));
Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; Attributes ensAttrs = null;
- while (!(StartOf(16))) {SynErr(167); Get();}
+ while (!(StartOf(16))) {SynErr(168); Get();}
if (la.kind == 42) {
Get();
while (IsAttribute()) {
@@ -1886,8 +1907,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
mod.Add(fe);
}
OldSemi();
- } else if (la.kind == 44 || la.kind == 86 || la.kind == 87) {
- if (la.kind == 86) {
+ } else if (la.kind == 44 || la.kind == 87 || la.kind == 88) {
+ if (la.kind == 87) {
Get();
isFree = true;
errors.Warning(t, "the 'free' keyword is soon to be deprecated");
@@ -1898,7 +1919,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression(out e, false, false);
OldSemi();
req.Add(new MaybeFreeExpression(e, isFree));
- } else if (la.kind == 87) {
+ } else if (la.kind == 88) {
Get();
while (IsAttribute()) {
Attribute(ref ensAttrs);
@@ -1906,7 +1927,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression(out e, false, false);
OldSemi();
ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
- } else SynErr(168);
+ } else SynErr(169);
} else if (la.kind == 35) {
Get();
while (IsAttribute()) {
@@ -1914,7 +1935,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
DecreasesList(decreases, true, false);
OldSemi();
- } else SynErr(169);
+ } else SynErr(170);
}
void FrameExpression(out FrameExpression fe, bool allowSemi, bool allowLambda) {
@@ -1927,18 +1948,18 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(7)) {
Expression(out e, allowSemi, allowLambda);
feTok = e.tok;
- if (la.kind == 89) {
+ if (la.kind == 90) {
Get();
Ident(out id);
fieldName = id.val; feTok = id;
}
fe = new FrameExpression(feTok, e, fieldName);
- } else if (la.kind == 89) {
+ } else if (la.kind == 90) {
Get();
Ident(out id);
fieldName = id.val;
fe = new FrameExpression(id, new ImplicitThisExpr(id), fieldName);
- } else SynErr(170);
+ } else SynErr(171);
}
void DecreasesList(List<Expression> decreases, bool allowWildcard, bool allowLambda) {
@@ -1993,7 +2014,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Contract.Requires(cce.NonNullElements(reads));
Contract.Requires(decreases == null || cce.NonNullElements(decreases));
Expression/*!*/ e; FrameExpression/*!*/ fe;
- while (!(StartOf(17))) {SynErr(171); Get();}
+ while (!(StartOf(17))) {SynErr(172); Get();}
if (la.kind == 44) {
Get();
Expression(out e, false, false);
@@ -2009,7 +2030,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
reads.Add(fe);
}
OldSemi();
- } else if (la.kind == 87) {
+ } else if (la.kind == 88) {
Get();
Expression(out e, false, false);
OldSemi();
@@ -2023,7 +2044,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
DecreasesList(decreases, false, false);
OldSemi();
- } else SynErr(172);
+ } else SynErr(173);
}
void FunctionBody(out Expression/*!*/ e, out IToken bodyStart, out IToken bodyEnd) {
@@ -2042,7 +2063,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
fe = new FrameExpression(t, new WildcardExpr(t), null);
} else if (StartOf(18)) {
FrameExpression(out fe, allowSemi, false);
- } else SynErr(173);
+ } else SynErr(174);
}
void PossiblyWildExpression(out Expression e, bool allowLambda) {
@@ -2053,7 +2074,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = new WildcardExpr(t);
} else if (StartOf(7)) {
Expression(out e, false, allowLambda);
- } else SynErr(174);
+ } else SynErr(175);
}
void Stmt(List<Statement/*!*/>/*!*/ ss) {
@@ -2070,14 +2091,14 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
IToken bodyStart, bodyEnd;
int breakCount;
- while (!(StartOf(19))) {SynErr(175); Get();}
+ while (!(StartOf(19))) {SynErr(176); Get();}
switch (la.kind) {
case 45: {
BlockStmt(out bs, out bodyStart, out bodyEnd);
s = bs;
break;
}
- case 100: {
+ case 101: {
AssertStmt(out s);
break;
}
@@ -2085,31 +2106,31 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
AssumeStmt(out s);
break;
}
- case 101: {
+ case 102: {
PrintStmt(out s);
break;
}
- case 1: case 2: case 3: case 4: case 8: case 10: case 19: case 20: case 23: case 49: case 130: case 131: case 132: case 133: case 134: case 135: {
+ case 1: case 2: case 3: case 4: case 8: case 10: case 19: case 20: case 23: case 49: case 131: case 132: case 133: case 134: case 135: case 136: {
UpdateStmt(out s);
break;
}
- case 71: case 76: {
+ case 72: case 77: {
VarDeclStatement(out s);
break;
}
- case 97: {
+ case 98: {
IfStmt(out s);
break;
}
- case 98: {
+ case 99: {
WhileStmt(out s);
break;
}
- case 99: {
+ case 100: {
MatchStmt(out s);
break;
}
- case 102: case 103: {
+ case 103: case 104: {
ForallStmt(out s);
break;
}
@@ -2117,11 +2138,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
CalcStmt(out s);
break;
}
- case 104: {
+ case 105: {
ModifyStmt(out s);
break;
}
- case 90: {
+ case 91: {
Get();
x = t;
NoUSIdent(out id);
@@ -2130,24 +2151,24 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
s.Labels = new LList<Label>(new Label(x, id.val), s.Labels);
break;
}
- case 91: {
+ case 92: {
Get();
x = t; breakCount = 1; label = null;
if (la.kind == 1) {
NoUSIdent(out id);
label = id.val;
- } else if (la.kind == 27 || la.kind == 91) {
- while (la.kind == 91) {
+ } else if (la.kind == 27 || la.kind == 92) {
+ while (la.kind == 92) {
Get();
breakCount++;
}
- } else SynErr(176);
- while (!(la.kind == 0 || la.kind == 27)) {SynErr(177); Get();}
+ } else SynErr(177);
+ while (!(la.kind == 0 || la.kind == 27)) {SynErr(178); Get();}
Expect(27);
s = label != null ? new BreakStmt(x, t, label) : new BreakStmt(x, t, breakCount);
break;
}
- case 88: case 94: {
+ case 89: case 95: {
ReturnStmt(out s);
break;
}
@@ -2155,7 +2176,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
SkeletonStmt(out s);
break;
}
- default: SynErr(178); break;
+ default: SynErr(179); break;
}
}
@@ -2164,7 +2185,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression e = dummyExpr; Attributes attrs = null;
IToken dotdotdot = null;
- Expect(100);
+ Expect(101);
x = t;
while (IsAttribute()) {
Attribute(ref attrs);
@@ -2174,7 +2195,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 58) {
Get();
dotdotdot = t;
- } else SynErr(179);
+ } else SynErr(180);
Expect(27);
if (dotdotdot != null) {
s = new SkeletonStatement(new AssertStmt(x, t, new LiteralExpr(x, true), attrs), dotdotdot, null);
@@ -2199,7 +2220,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 58) {
Get();
dotdotdot = t;
- } else SynErr(180);
+ } else SynErr(181);
Expect(27);
if (dotdotdot != null) {
s = new SkeletonStatement(new AssumeStmt(x, t, new LiteralExpr(x, true), attrs), dotdotdot, null);
@@ -2214,7 +2235,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
IToken x; Expression e;
var args = new List<Expression>();
- Expect(101);
+ Expect(102);
x = t;
Expression(out e, false, true);
args.Add(e);
@@ -2244,14 +2265,14 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
Expect(27);
endTok = t; rhss.Add(new ExprRhs(e, attrs));
- } else if (la.kind == 22 || la.kind == 93 || la.kind == 95) {
+ } else if (la.kind == 22 || la.kind == 94 || la.kind == 96) {
lhss.Add(e);
while (la.kind == 22) {
Get();
Lhs(out e);
lhss.Add(e);
}
- if (la.kind == 93) {
+ if (la.kind == 94) {
Get();
x = t;
Rhs(out r);
@@ -2261,7 +2282,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Rhs(out r);
rhss.Add(r);
}
- } else if (la.kind == 95) {
+ } else if (la.kind == 96) {
Get();
x = t;
if (la.kind == _assume) {
@@ -2269,13 +2290,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
suchThatAssume = t;
}
Expression(out suchThat, false, true);
- } else SynErr(181);
+ } else SynErr(182);
Expect(27);
endTok = t;
} else if (la.kind == 21) {
Get();
SemErr(t, "invalid statement (did you forget the 'label' keyword?)");
- } else SynErr(182);
+ } else SynErr(183);
if (suchThat != null) {
s = new AssignSuchThatStmt(x, endTok, lhss, suchThat, suchThatAssume, null);
} else {
@@ -2299,11 +2320,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Attributes attrs = null;
IToken endTok;
- if (la.kind == 71) {
+ if (la.kind == 72) {
Get();
isGhost = true; x = t;
}
- Expect(76);
+ Expect(77);
if (!isGhost) { x = t; }
while (la.kind == 45) {
Attribute(ref attrs);
@@ -2318,8 +2339,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
LocalIdentTypeOptional(out d, isGhost);
lhss.Add(d); d.Attributes = attrs; attrs = null;
}
- if (la.kind == 45 || la.kind == 93 || la.kind == 95) {
- if (la.kind == 93) {
+ if (la.kind == 45 || la.kind == 94 || la.kind == 96) {
+ if (la.kind == 94) {
Get();
assignTok = t;
Rhs(out r);
@@ -2333,7 +2354,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
while (la.kind == 45) {
Attribute(ref attrs);
}
- Expect(95);
+ Expect(96);
assignTok = t;
if (la.kind == _assume) {
Expect(30);
@@ -2342,7 +2363,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression(out suchThat, false, true);
}
}
- while (!(la.kind == 0 || la.kind == 27)) {SynErr(183); Get();}
+ while (!(la.kind == 0 || la.kind == 27)) {SynErr(184); Get();}
Expect(27);
endTok = t;
ConcreteUpdateStatement update;
@@ -2376,7 +2397,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
List<GuardedAlternative> alternatives;
ifStmt = dummyStmt; // to please the compiler
- Expect(97);
+ Expect(98);
x = t;
if (IsAlternative()) {
AlternativeBlock(out alternatives, out endTok);
@@ -2392,13 +2413,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
endTok = thn.EndTok;
if (la.kind == 34) {
Get();
- if (la.kind == 97) {
+ if (la.kind == 98) {
IfStmt(out s);
els = s; endTok = s.EndTok;
} else if (la.kind == 45) {
BlockStmt(out bs, out bodyStart, out bodyEnd);
els = bs; endTok = bs.EndTok;
- } else SynErr(184);
+ } else SynErr(185);
}
if (guardEllipsis != null) {
ifStmt = new SkeletonStatement(new IfStmt(x, endTok, guard, thn, els), guardEllipsis, null);
@@ -2406,7 +2427,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
ifStmt = new IfStmt(x, endTok, guard, thn, els);
}
- } else SynErr(185);
+ } else SynErr(186);
}
void WhileStmt(out Statement stmt) {
@@ -2425,7 +2446,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
stmt = dummyStmt; // to please the compiler
bool isDirtyLoop = true;
- Expect(98);
+ Expect(99);
x = t;
if (IsLoopSpec() || IsAlternative()) {
while (StartOf(22)) {
@@ -2451,7 +2472,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(58);
bodyEllipsis = t; endTok = t; isDirtyLoop = false;
} else if (StartOf(23)) {
- } else SynErr(186);
+ } else SynErr(187);
if (guardEllipsis != null || bodyEllipsis != null) {
if (mod != null) {
SemErr(mod[0].E.tok, "'modifies' clauses are not allowed on refining loops");
@@ -2469,7 +2490,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
stmt = new WhileStmt(x, endTok, guard, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(mod, modAttrs), body);
}
- } else SynErr(187);
+ } else SynErr(188);
}
void MatchStmt(out Statement/*!*/ s) {
@@ -2478,7 +2499,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
List<MatchCaseStmt/*!*/> cases = new List<MatchCaseStmt/*!*/>();
bool usesOptionalBrace = false;
- Expect(99);
+ Expect(100);
x = t;
Expression(out e, true, true);
if (la.kind == _lbrace) {
@@ -2494,7 +2515,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
CaseStatement(out c);
cases.Add(c);
}
- } else SynErr(188);
+ } else SynErr(189);
s = new MatchStmt(x, t, e, cases, usesOptionalBrace);
}
@@ -2511,15 +2532,15 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
IToken bodyStart, bodyEnd;
IToken tok = Token.NoToken;
- if (la.kind == 102) {
+ if (la.kind == 103) {
Get();
x = t; tok = x;
- } else if (la.kind == 103) {
+ } else if (la.kind == 104) {
Get();
x = t;
errors.Warning(t, "the 'parallel' keyword has been deprecated; the comprehension statement now uses the keyword 'forall' (and the parentheses around the bound variables are now optional)");
- } else SynErr(189);
+ } else SynErr(190);
if (la.kind == _openparen) {
Expect(49);
if (la.kind == 1) {
@@ -2530,19 +2551,19 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (la.kind == _ident) {
QuantifierDomain(out bvars, out attrs, out range);
}
- } else SynErr(190);
+ } else SynErr(191);
if (bvars == null) { bvars = new List<BoundVar>(); }
if (range == null) { range = new LiteralExpr(x, true); }
- while (la.kind == 86 || la.kind == 87) {
+ while (la.kind == 87 || la.kind == 88) {
isFree = false;
- if (la.kind == 86) {
+ if (la.kind == 87) {
Get();
isFree = true;
errors.Warning(t, "the 'free' keyword is soon to be deprecated");
}
- Expect(87);
+ Expect(88);
Expression(out e, false, true);
ens.Add(new MaybeFreeExpression(e, isFree));
OldSemi();
@@ -2565,6 +2586,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void CalcStmt(out Statement s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null);
Token x;
+ Attributes attrs = null;
CalcStmt.CalcOp op, calcOp = Microsoft.Dafny.CalcStmt.DefaultOp, resOp = Microsoft.Dafny.CalcStmt.DefaultOp;
var lines = new List<Expression>();
var hints = new List<BlockStmt>();
@@ -2577,6 +2599,9 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(31);
x = t;
+ while (IsAttribute()) {
+ Attribute(ref attrs);
+ }
if (StartOf(25)) {
CalcOp(out opTok, out calcOp);
maybeOp = calcOp.ResultOp(calcOp); // guard against non-transitive calcOp (like !=)
@@ -2616,7 +2641,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 31) {
CalcStmt(out subCalc);
hintEnd = subCalc.EndTok; subhints.Add(subCalc);
- } else SynErr(191);
+ } else SynErr(192);
}
var h = new BlockStmt(hintStart, hintEnd, subhints); // if the hint is empty, hintStart is the first token of the next line, but it doesn't matter because the block statement is just used as a container
hints.Add(h);
@@ -2631,7 +2656,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
// Repeat the last line to create a dummy line for the dangling hint
lines.Add(lines[lines.Count - 1]);
}
- s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp);
+ s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp, attrs);
}
@@ -2642,7 +2667,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
BlockStmt body = null; IToken bodyStart;
IToken ellipsisToken = null;
- Expect(104);
+ Expect(105);
tok = t;
while (IsAttribute()) {
Attribute(ref attrs);
@@ -2658,14 +2683,14 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 58) {
Get();
ellipsisToken = t;
- } else SynErr(192);
+ } else SynErr(193);
if (la.kind == 45) {
BlockStmt(out body, out bodyStart, out endTok);
} else if (la.kind == 27) {
- while (!(la.kind == 0 || la.kind == 27)) {SynErr(193); Get();}
+ while (!(la.kind == 0 || la.kind == 27)) {SynErr(194); Get();}
Get();
endTok = t;
- } else SynErr(194);
+ } else SynErr(195);
s = new ModifyStmt(tok, endTok, mod, attrs, body);
if (ellipsisToken != null) {
s = new SkeletonStatement(s, ellipsisToken, null);
@@ -2679,13 +2704,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
AssignmentRhs r;
bool isYield = false;
- if (la.kind == 94) {
+ if (la.kind == 95) {
Get();
returnTok = t;
- } else if (la.kind == 88) {
+ } else if (la.kind == 89) {
Get();
returnTok = t; isYield = true;
- } else SynErr(195);
+ } else SynErr(196);
if (StartOf(26)) {
Rhs(out r);
rhss = new List<AssignmentRhs>(); rhss.Add(r);
@@ -2711,7 +2736,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression e;
Expect(58);
dotdotdot = t;
- if (la.kind == 92) {
+ if (la.kind == 93) {
Get();
names = new List<IToken>(); exprs = new List<Expression>(); whereTok = t;
Ident(out tok);
@@ -2721,7 +2746,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Ident(out tok);
names.Add(tok);
}
- Expect(93);
+ Expect(94);
Expression(out e, false, true);
exprs.Add(e);
while (la.kind == 22) {
@@ -2748,7 +2773,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
r = dummyRhs; // to please compiler
Attributes attrs = null;
- if (la.kind == 96) {
+ if (la.kind == 97) {
Get();
newToken = t;
TypeAndToken(out x, out ty);
@@ -2783,7 +2808,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (StartOf(7)) {
Expression(out e, false, true);
r = new ExprRhs(e);
- } else SynErr(196);
+ } else SynErr(197);
while (la.kind == 45) {
Attribute(ref attrs);
}
@@ -2804,7 +2829,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
while (la.kind == 26 || la.kind == 47 || la.kind == 49) {
Suffix(ref e);
}
- } else SynErr(197);
+ } else SynErr(198);
}
void Expressions(List<Expression> args) {
@@ -2853,16 +2878,16 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (StartOf(7)) {
Expression(out ee, true, true);
e = ee;
- } else SynErr(198);
+ } else SynErr(199);
}
void LoopSpec(List<MaybeFreeExpression> invariants, List<Expression> decreases, ref List<FrameExpression> mod, ref Attributes decAttrs, ref Attributes modAttrs) {
Expression e; FrameExpression fe;
bool isFree = false; Attributes attrs = null;
- if (la.kind == 36 || la.kind == 86) {
- while (!(la.kind == 0 || la.kind == 36 || la.kind == 86)) {SynErr(199); Get();}
- if (la.kind == 86) {
+ if (la.kind == 36 || la.kind == 87) {
+ while (!(la.kind == 0 || la.kind == 36 || la.kind == 87)) {SynErr(200); Get();}
+ if (la.kind == 87) {
Get();
isFree = true; errors.Warning(t, "the 'free' keyword is soon to be deprecated");
}
@@ -2874,7 +2899,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
invariants.Add(new MaybeFreeExpression(e, isFree, attrs));
OldSemi();
} else if (la.kind == 35) {
- while (!(la.kind == 0 || la.kind == 35)) {SynErr(200); Get();}
+ while (!(la.kind == 0 || la.kind == 35)) {SynErr(201); Get();}
Get();
while (IsAttribute()) {
Attribute(ref decAttrs);
@@ -2882,7 +2907,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
DecreasesList(decreases, true, true);
OldSemi();
} else if (la.kind == 42) {
- while (!(la.kind == 0 || la.kind == 42)) {SynErr(201); Get();}
+ while (!(la.kind == 0 || la.kind == 42)) {SynErr(202); Get();}
Get();
mod = mod ?? new List<FrameExpression>();
while (IsAttribute()) {
@@ -2896,7 +2921,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
mod.Add(fe);
}
OldSemi();
- } else SynErr(202);
+ } else SynErr(203);
}
void CaseStatement(out MatchCaseStmt/*!*/ c) {
@@ -2933,12 +2958,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
arguments.Add(pat);
}
Expect(50);
- } else SynErr(203);
+ } else SynErr(204);
Expect(28);
- while (!(StartOf(28))) {SynErr(204); Get();}
+ while (!(StartOf(28))) {SynErr(205); Get();}
while (IsNotEndOfCase()) {
Stmt(body);
- while (!(StartOf(28))) {SynErr(205); Get();}
+ while (!(StartOf(28))) {SynErr(206); Get();}
}
c = new MatchCaseStmt(x, name, arguments, body);
}
@@ -2986,7 +3011,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
IdentTypeOptional(out bv);
pat = new CasePattern(bv.tok, bv);
- } else SynErr(206);
+ } else SynErr(207);
if (pat == null) {
pat = new CasePattern(t, "_ParseError", new List<CasePattern>());
}
@@ -3024,7 +3049,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
case 53: {
Get();
x = t; binOp = BinaryExpr.Opcode.Eq;
- if (la.kind == 105) {
+ if (la.kind == 106) {
Get();
Expect(47);
Expression(out k, true, true);
@@ -3042,12 +3067,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; binOp = BinaryExpr.Opcode.Gt;
break;
}
- case 106: {
+ case 107: {
Get();
x = t; binOp = BinaryExpr.Opcode.Le;
break;
}
- case 107: {
+ case 108: {
Get();
x = t; binOp = BinaryExpr.Opcode.Ge;
break;
@@ -3062,32 +3087,32 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; binOp = BinaryExpr.Opcode.Neq;
break;
}
- case 108: {
+ case 109: {
Get();
x = t; binOp = BinaryExpr.Opcode.Le;
break;
}
- case 109: {
+ case 110: {
Get();
x = t; binOp = BinaryExpr.Opcode.Ge;
break;
}
- case 110: case 111: {
+ case 111: case 112: {
EquivOp();
x = t; binOp = BinaryExpr.Opcode.Iff;
break;
}
- case 112: case 113: {
+ case 113: case 114: {
ImpliesOp();
x = t; binOp = BinaryExpr.Opcode.Imp;
break;
}
- case 114: case 115: {
+ case 115: case 116: {
ExpliesOp();
x = t; binOp = BinaryExpr.Opcode.Exp;
break;
}
- default: SynErr(207); break;
+ default: SynErr(208); break;
}
if (k == null) {
op = new Microsoft.Dafny.CalcStmt.BinaryCalcOp(binOp);
@@ -3098,67 +3123,67 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
void EquivOp() {
- if (la.kind == 110) {
+ if (la.kind == 111) {
Get();
- } else if (la.kind == 111) {
+ } else if (la.kind == 112) {
Get();
- } else SynErr(208);
+ } else SynErr(209);
}
void ImpliesOp() {
- if (la.kind == 112) {
+ if (la.kind == 113) {
Get();
- } else if (la.kind == 113) {
+ } else if (la.kind == 114) {
Get();
- } else SynErr(209);
+ } else SynErr(210);
}
void ExpliesOp() {
- if (la.kind == 114) {
+ if (la.kind == 115) {
Get();
- } else if (la.kind == 115) {
+ } else if (la.kind == 116) {
Get();
- } else SynErr(210);
+ } else SynErr(211);
}
void AndOp() {
- if (la.kind == 116) {
+ if (la.kind == 117) {
Get();
- } else if (la.kind == 117) {
+ } else if (la.kind == 118) {
Get();
- } else SynErr(211);
+ } else SynErr(212);
}
void OrOp() {
- if (la.kind == 118) {
+ if (la.kind == 119) {
Get();
- } else if (la.kind == 119) {
+ } else if (la.kind == 120) {
Get();
- } else SynErr(212);
+ } else SynErr(213);
}
void NegOp() {
- if (la.kind == 120) {
+ if (la.kind == 121) {
Get();
- } else if (la.kind == 121) {
+ } else if (la.kind == 122) {
Get();
- } else SynErr(213);
+ } else SynErr(214);
}
void Forall() {
- if (la.kind == 102) {
+ if (la.kind == 103) {
Get();
- } else if (la.kind == 122) {
+ } else if (la.kind == 123) {
Get();
- } else SynErr(214);
+ } else SynErr(215);
}
void Exists() {
- if (la.kind == 123) {
+ if (la.kind == 124) {
Get();
- } else if (la.kind == 124) {
+ } else if (la.kind == 125) {
Get();
- } else SynErr(215);
+ } else SynErr(216);
}
void QSep() {
@@ -3166,7 +3191,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 25) {
Get();
- } else SynErr(216);
+ } else SynErr(217);
}
void EquivExpression(out Expression e0, bool allowSemi, bool allowLambda) {
@@ -3184,12 +3209,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
LogicalExpression(out e0, allowSemi, allowLambda);
if (IsImpliesOp() || IsExpliesOp()) {
- if (la.kind == 112 || la.kind == 113) {
+ if (la.kind == 113 || la.kind == 114) {
ImpliesOp();
x = t;
ImpliesExpression(out e1, allowSemi, allowLambda);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.Imp, e0, e1);
- } else if (la.kind == 114 || la.kind == 115) {
+ } else if (la.kind == 115 || la.kind == 116) {
ExpliesOp();
x = t;
LogicalExpression(out e1, allowSemi, allowLambda);
@@ -3200,7 +3225,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
LogicalExpression(out e1, allowSemi, allowLambda);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.Exp, e0, e1);
}
- } else SynErr(217);
+ } else SynErr(218);
}
}
@@ -3208,7 +3233,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
RelationalExpression(out e0, allowSemi, allowLambda);
if (IsAndOp() || IsOrOp()) {
- if (la.kind == 116 || la.kind == 117) {
+ if (la.kind == 117 || la.kind == 118) {
AndOp();
x = t;
RelationalExpression(out e1, allowSemi, allowLambda);
@@ -3219,7 +3244,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
RelationalExpression(out e1, allowSemi, allowLambda);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1);
}
- } else if (la.kind == 118 || la.kind == 119) {
+ } else if (la.kind == 119 || la.kind == 120) {
OrOp();
x = t;
RelationalExpression(out e1, allowSemi, allowLambda);
@@ -3230,7 +3255,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
RelationalExpression(out e1, allowSemi, allowLambda);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1);
}
- } else SynErr(218);
+ } else SynErr(219);
}
}
@@ -3366,7 +3391,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
case 53: {
Get();
x = t; op = BinaryExpr.Opcode.Eq;
- if (la.kind == 105) {
+ if (la.kind == 106) {
Get();
Expect(47);
Expression(out k, true, true);
@@ -3384,12 +3409,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; op = BinaryExpr.Opcode.Gt;
break;
}
- case 106: {
+ case 107: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 107: {
+ case 108: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
@@ -3397,7 +3422,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
case 54: {
Get();
x = t; op = BinaryExpr.Opcode.Neq;
- if (la.kind == 105) {
+ if (la.kind == 106) {
Get();
Expect(47);
Expression(out k, true, true);
@@ -3405,7 +3430,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
break;
}
- case 125: {
+ case 126: {
Get();
x = t; op = BinaryExpr.Opcode.In;
break;
@@ -3415,11 +3440,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; op = BinaryExpr.Opcode.NotIn;
break;
}
- case 120: {
+ case 121: {
Get();
x = t; y = Token.NoToken;
if (la.val == "!") {
- Expect(120);
+ Expect(121);
y = t;
}
if (y == Token.NoToken) {
@@ -3438,17 +3463,17 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; op = BinaryExpr.Opcode.Neq;
break;
}
- case 108: {
+ case 109: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 109: {
+ case 110: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- default: SynErr(219); break;
+ default: SynErr(220); break;
}
}
@@ -3464,23 +3489,23 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void AddOp(out IToken x, out BinaryExpr.Opcode op) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null); x = Token.NoToken; op=BinaryExpr.Opcode.Add/*(dummy)*/;
- if (la.kind == 126) {
+ if (la.kind == 127) {
Get();
x = t; op = BinaryExpr.Opcode.Add;
- } else if (la.kind == 127) {
+ } else if (la.kind == 128) {
Get();
x = t; op = BinaryExpr.Opcode.Sub;
- } else SynErr(220);
+ } else SynErr(221);
}
void UnaryExpression(out Expression e, bool allowSemi, bool allowLambda) {
Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr;
- if (la.kind == 127) {
+ if (la.kind == 128) {
Get();
x = t;
UnaryExpression(out e, allowSemi, allowLambda);
e = new NegationExpression(x, e);
- } else if (la.kind == 120 || la.kind == 121) {
+ } else if (la.kind == 121 || la.kind == 122) {
NegOp();
x = t;
UnaryExpression(out e, allowSemi, allowLambda);
@@ -3530,7 +3555,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
while (IsSuffix()) {
Suffix(ref e);
}
- } else SynErr(221);
+ } else SynErr(222);
}
void MulOp(out IToken x, out BinaryExpr.Opcode op) {
@@ -3538,13 +3563,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (la.kind == 56) {
Get();
x = t; op = BinaryExpr.Opcode.Mul;
- } else if (la.kind == 128) {
+ } else if (la.kind == 129) {
Get();
x = t; op = BinaryExpr.Opcode.Div;
- } else if (la.kind == 129) {
+ } else if (la.kind == 130) {
Get();
x = t; op = BinaryExpr.Opcode.Mod;
- } else SynErr(222);
+ } else SynErr(223);
}
void MapDisplayExpr(IToken/*!*/ mapToken, bool finite, out Expression e) {
@@ -3579,10 +3604,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (IsGenericInstantiation()) {
typeArgs = new List<Type>();
GenericInstantiation(typeArgs);
- } else if (la.kind == 105) {
+ } else if (la.kind == 106) {
HashCall(id, out openParen, out typeArgs, out args);
} else if (StartOf(30)) {
- } else SynErr(223);
+ } else SynErr(224);
e = new ExprDotName(id, e, id.val, typeArgs);
if (openParen != null) {
e = new ApplySuffix(openParen, e, args);
@@ -3594,14 +3619,14 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(7)) {
Expression(out ee, true, true);
e0 = ee;
- if (la.kind == 136) {
+ if (la.kind == 137) {
Get();
anyDots = true;
if (StartOf(7)) {
Expression(out ee, true, true);
e1 = ee;
}
- } else if (la.kind == 93) {
+ } else if (la.kind == 94) {
Get();
Expression(out ee, true, true);
e1 = ee;
@@ -3635,15 +3660,15 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
multipleIndices.Add(ee);
}
- } else SynErr(224);
- } else if (la.kind == 136) {
+ } else SynErr(225);
+ } else if (la.kind == 137) {
Get();
anyDots = true;
if (StartOf(7)) {
Expression(out ee, true, true);
e1 = ee;
}
- } else SynErr(225);
+ } else SynErr(226);
if (multipleIndices != null) {
e = new MultiSelectExpr(x, e, multipleIndices);
// make sure an array class with this dimensionality exists
@@ -3687,7 +3712,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
Expect(50);
e = new ApplySuffix(openParen, e, args);
- } else SynErr(226);
+ } else SynErr(227);
}
void ISetDisplayExpr(IToken/*!*/ setToken, bool finite, out Expression e) {
@@ -3729,7 +3754,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
}
Expect(50);
- } else SynErr(227);
+ } else SynErr(228);
while (la.kind == 43 || la.kind == 44) {
if (la.kind == 43) {
Get();
@@ -3755,7 +3780,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = dummyExpr;
switch (la.kind) {
- case 97: {
+ case 98: {
Get();
x = t;
Expression(out e, true, true);
@@ -3766,11 +3791,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = new ITEExpr(x, e, e0, e1);
break;
}
- case 99: {
+ case 100: {
MatchExpression(out e, allowSemi, allowLambda);
break;
}
- case 102: case 122: case 123: case 124: {
+ case 103: case 123: case 124: case 125: {
QuantifierGuts(out e, allowSemi, allowLambda);
break;
}
@@ -3786,13 +3811,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
SetComprehensionExpr(x, false, out e, allowSemi, allowLambda);
break;
}
- case 30: case 31: case 100: {
+ case 30: case 31: case 101: {
StmtInExpr(out s);
Expression(out e, allowSemi, allowLambda);
e = new StmtExpr(s.Tok, s, e);
break;
}
- case 71: case 76: {
+ case 72: case 77: {
LetExpr(out e, allowSemi, allowLambda);
break;
}
@@ -3808,11 +3833,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
MapComprehensionExpr(x, false, out e, allowSemi, allowLambda);
break;
}
- case 90: {
+ case 91: {
NamedExpr(out e, allowSemi, allowLambda);
break;
}
- default: SynErr(228); break;
+ default: SynErr(229); break;
}
}
@@ -3824,10 +3849,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (IsGenericInstantiation()) {
typeArgs = new List<Type>();
GenericInstantiation(typeArgs);
- } else if (la.kind == 105) {
+ } else if (la.kind == 106) {
HashCall(id, out openParen, out typeArgs, out args);
} else if (StartOf(30)) {
- } else SynErr(229);
+ } else SynErr(230);
e = new NameSegment(id, id.val, typeArgs);
if (openParen != null) {
e = new ApplySuffix(openParen, e, args);
@@ -3856,7 +3881,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
e = new SeqDisplayExpr(x, elements);
Expect(48);
- } else SynErr(230);
+ } else SynErr(231);
}
void MultiSetExpr(out Expression e) {
@@ -3880,7 +3905,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression(out e, true, true);
e = new MultiSetFormingExpr(x, e);
Expect(50);
- } else SynErr(231);
+ } else SynErr(232);
}
void ConstAtomExpression(out Expression e, bool allowSemi, bool allowLambda) {
@@ -3889,17 +3914,17 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = dummyExpr; Type toType = null;
switch (la.kind) {
- case 130: {
+ case 131: {
Get();
e = new LiteralExpr(t, false);
break;
}
- case 131: {
+ case 132: {
Get();
e = new LiteralExpr(t, true);
break;
}
- case 132: {
+ case 133: {
Get();
e = new LiteralExpr(t);
break;
@@ -3927,12 +3952,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
break;
}
- case 133: {
+ case 134: {
Get();
e = new ThisExpr(t);
break;
}
- case 134: {
+ case 135: {
Get();
x = t;
Expect(49);
@@ -3941,7 +3966,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = new UnaryOpExpr(x, UnaryOpExpr.Opcode.Fresh, e);
break;
}
- case 135: {
+ case 136: {
Get();
x = t;
Expect(49);
@@ -3976,7 +4001,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
ParensExpression(out e, allowSemi, allowLambda);
break;
}
- default: SynErr(232); break;
+ default: SynErr(233); break;
}
}
@@ -3988,7 +4013,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
S = Util.RemoveUnderscores(t.val);
try {
- n = BigIntegerParser.Parse(S);
+ n = BigIntegerParser.Parse(S);
} catch (System.FormatException) {
SemErr("incorrectly formatted number");
n = BigInteger.Zero;
@@ -3999,13 +4024,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
S = Util.RemoveUnderscores(t.val.Substring(2));
try {
// note: leading 0 required when parsing positive hex numbers
- n = BigIntegerParser.Parse("0" + S, System.Globalization.NumberStyles.HexNumber);
+ n = BigIntegerParser.Parse("0" + S, System.Globalization.NumberStyles.HexNumber);
} catch (System.FormatException) {
SemErr("incorrectly formatted number");
n = BigInteger.Zero;
}
- } else SynErr(233);
+ } else SynErr(234);
}
void Dec(out Basetypes.BigDec d) {
@@ -4049,20 +4074,20 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 29) {
Get();
oneShot = true;
- } else SynErr(234);
+ } else SynErr(235);
}
void MapLiteralExpressions(out List<ExpressionPair> elements) {
Expression/*!*/ d, r;
elements = new List<ExpressionPair/*!*/>();
Expression(out d, true, true);
- Expect(93);
+ Expect(94);
Expression(out r, true, true);
elements.Add(new ExpressionPair(d,r));
while (la.kind == 22) {
Get();
Expression(out d, true, true);
- Expect(93);
+ Expect(94);
Expression(out r, true, true);
elements.Add(new ExpressionPair(d,r));
}
@@ -4096,7 +4121,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
List<MatchCaseExpr/*!*/> cases = new List<MatchCaseExpr/*!*/>();
bool usesOptionalBrace = false;
- Expect(99);
+ Expect(100);
x = t;
Expression(out e, allowSemi, allowLambda);
if (la.kind == _lbrace) {
@@ -4112,7 +4137,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
CaseExpression(out c, allowSemi, allowLambda);
cases.Add(c);
}
- } else SynErr(235);
+ } else SynErr(236);
e = new MatchExpr(x, e, cases, usesOptionalBrace);
}
@@ -4124,13 +4149,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression range;
Expression/*!*/ body;
- if (la.kind == 102 || la.kind == 122) {
+ if (la.kind == 103 || la.kind == 123) {
Forall();
x = t; univ = true;
- } else if (la.kind == 123 || la.kind == 124) {
+ } else if (la.kind == 124 || la.kind == 125) {
Exists();
x = t;
- } else SynErr(236);
+ } else SynErr(237);
QuantifierDomain(out bvars, out attrs, out range);
QSep();
Expression(out body, allowSemi, allowLambda);
@@ -4173,13 +4198,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void StmtInExpr(out Statement s) {
s = dummyStmt;
- if (la.kind == 100) {
+ if (la.kind == 101) {
AssertStmt(out s);
} else if (la.kind == 30) {
AssumeStmt(out s);
} else if (la.kind == 31) {
CalcStmt(out s);
- } else SynErr(237);
+ } else SynErr(238);
}
void LetExpr(out Expression e, bool allowSemi, bool allowLambda) {
@@ -4192,11 +4217,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Attributes attrs = null;
e = dummyExpr;
- if (la.kind == 71) {
+ if (la.kind == 72) {
Get();
isGhost = true; x = t;
}
- Expect(76);
+ Expect(77);
if (!isGhost) { x = t; }
CasePattern(out pat);
if (isGhost) { pat.Vars.Iter(bv => bv.IsGhost = true); }
@@ -4209,13 +4234,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
letLHSs.Add(pat);
}
- if (la.kind == 93) {
+ if (la.kind == 94) {
Get();
- } else if (la.kind == 45 || la.kind == 95) {
+ } else if (la.kind == 45 || la.kind == 96) {
while (la.kind == 45) {
Attribute(ref attrs);
}
- Expect(95);
+ Expect(96);
exact = false;
foreach (var lhs in letLHSs) {
if (lhs.Arguments != null) {
@@ -4223,7 +4248,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
}
- } else SynErr(238);
+ } else SynErr(239);
Expression(out e, false, true);
letRHSs.Add(e);
while (la.kind == 22) {
@@ -4241,7 +4266,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = dummyExpr;
Expression expr;
- Expect(90);
+ Expect(91);
x = t;
NoUSIdent(out d);
Expect(21);
@@ -4283,7 +4308,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
arguments.Add(pat);
}
Expect(50);
- } else SynErr(239);
+ } else SynErr(240);
Expect(28);
Expression(out body, allowSemi, allowLambda);
c = new MatchCaseExpr(x, name, arguments, body);
@@ -4291,7 +4316,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void HashCall(IToken id, out IToken openParen, out List<Type> typeArgs, out List<Expression> args) {
Expression k; args = new List<Expression>(); typeArgs = null;
- Expect(105);
+ Expect(106);
id.val = id.val + "#";
if (la.kind == 51) {
typeArgs = new List<Type>();
@@ -4348,7 +4373,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 43) {
Get();
x = t;
- } else SynErr(240);
+ } else SynErr(241);
}
@@ -4364,38 +4389,38 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
static readonly bool[,]/*!*/ set = {
- {_T,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_T, _x,_x,_x,_T, _x,_x,_T,_T, _T,_x,_x,_T, _T,_x,_x,_T, _T,_x,_T,_T, _T,_T,_T,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_x,_T,_T, _x,_x,_T,_T, _T,_x,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _T,_x,_T,_T, _x,_x,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_x,_T, _x,_x,_x,_x, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_T,_x,_x, _T,_x,_x,_x, _x,_x,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_T,_x,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_T, _T,_T,_x,_x, _x,_x,_T,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_x,_T, _x,_T,_x,_x, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_T,_T,_T, _x,_T,_T,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_T, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_T,_x,_T, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_T,_T, _T,_x,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_T,_T,_T, _T,_T,_x,_T, _T,_T,_T,_x, _x,_T,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_x,_T, _x,_x,_x,_x, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x,_T,_T, _T,_T,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_T,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_x,_T,_T, _x,_x,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_T,_T,_T, _x,_T,_T,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_T, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_x, _x,_x,_x,_x, _x,_T,_x,_T, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_T,_T, _T,_x,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_T,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_x,_T,_T, _x,_x,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_T,_T,_T, _x,_T,_T,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_T, _x,_T,_x,_x, _x,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_T,_x,_T, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_T,_T, _T,_x,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_T,_T,_T, _x,_T,_T,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_T, _x,_T,_x,_x, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_T,_x,_T, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_T,_T, _T,_x,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_x,_T,_T, _x,_x,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_T,_T, _x,_x,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_T,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_x,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_T,_T,_T, _x,_T,_T,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_T, _x,_T,_x,_x, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _T,_T,_x,_T, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_T,_T, _T,_x,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_x,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_T,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_x,_x,_T, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_x,_T,_T, _x,_x,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_T,_T,_T, _x,_x,_x},
- {_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_T,_x, _x,_T,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_T, _x,_x,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_x,_x,_x, _x,_T,_x,_T, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x},
- {_T,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_x, _T,_T,_x,_T, _x,_x,_x,_x, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_T,_T,_T, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x},
- {_T,_T,_T,_T, _T,_x,_x,_x, _T,_x,_T,_x, _x,_x,_x,_x, _x,_x,_x,_T, _T,_T,_T,_T, _T,_T,_x,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_x, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_x, _T,_T,_x,_T, _x,_x,_x,_x, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_T,_T,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x}
+ {T,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,x,x,T, x,x,x,T, x,x,T,T, T,x,x,T, T,x,x,T, T,x,T,T, T,T,T,x, x,T,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,T,x,T, T,x,x,T, T,T,x,x, T,x,x,T, T,T,T,T, T,T,x,T, T,x,x,T, x,x,T,T, T,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,T,x,x, T,x,x,x, x,T,x,T, T,T,T,T, T,T,T,T, T,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,T,T,x, x,T,x,x, x,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,x,x, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, x,x,T,x, x,x,x,T, x,x,x,x, x,x,x,x, T,T,x,x, T,x,T,x, x,T,x,T, T,T,T,T, T,T,T,T, T,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,T,T,T, x,T,T,T, T,x,x,T, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, T,x,x,T, T,T,T,T, T,x,x,x},
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,T,T, T,T,x,T, T,T,T,x, x,T,x,T, x,x,x,x, x,x,x,x, T,T,x,x, T,x,x,x, x,T,x,T, T,T,T,T, T,T,T,T, T,x,x,T, T,T,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,x, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,x,x,T, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,T,x,T, T,x,x,T, x,x,T,T, T,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x},
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,T,T,T, x,T,T,T, T,x,x,T, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,x,x, x,x,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, T,x,x,T, T,T,T,T, T,x,x,x},
+ {T,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,x,x,T, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,T,x,T, T,x,x,T, x,x,T,T, T,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,T,T,T, x,T,T,T, T,x,x,T, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, T,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, T,x,x,T, T,T,T,T, T,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,T,T,T, x,T,T,T, T,x,x,T, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, T,x,x,T, T,T,T,T, T,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,x,x,T, x,x,x,x, x,x,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,T,x,T, T,x,x,T, x,x,T,T, T,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,x,x,T, x,x,x,x, x,x,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,T, T,T,x,T, T,x,x,T, x,x,T,T, T,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,T,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,x,x,x, T,x,T,x, x,T,T,T, x,T,T,T, T,x,x,T, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,T,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, T,x,x,T, T,T,T,T, T,x,x,x},
+ {x,x,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x},
+ {T,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,x,x,T, x,x,x,x, x,x,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,T,x,T, T,x,x,T, x,x,T,T, T,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,T,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {T,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, T,T,x,x, T,x,x,x, x,T,x,T, T,T,T,T, T,T,T,T, T,x,x,T, T,T,T,T, T,T,T,T, T,x,T,T, T,x,T,T, T,T,T,T, T,T,x,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x,x, x,x,T,T, T,T,T,T, T,T,T,T, T,T,x,x},
+ {T,T,T,T, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,T, T,T,T,T, T,T,x,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, T,T,T,T, T,T,T,T, T,T,T,x, T,T,x,x, T,x,x,x, x,T,x,T, T,T,T,T, T,T,T,T, T,x,x,T, T,T,T,T, T,T,T,T, T,x,T,T, x,x,T,T, T,T,T,T, T,T,x,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,x,x, x,x,T,T, T,T,T,T, T,T,T,T, T,T,x,x}
};
} // end Parser
@@ -4482,185 +4507,186 @@ public class Errors {
case 59: s = "\"include\" expected"; break;
case 60: s = "\"abstract\" expected"; break;
case 61: s = "\"module\" expected"; break;
- case 62: s = "\"refines\" expected"; break;
- case 63: s = "\"import\" expected"; break;
- case 64: s = "\"opened\" expected"; break;
- case 65: s = "\"=\" expected"; break;
- case 66: s = "\"as\" expected"; break;
- case 67: s = "\"default\" expected"; break;
- case 68: s = "\"class\" expected"; break;
- case 69: s = "\"extends\" expected"; break;
- case 70: s = "\"trait\" expected"; break;
- case 71: s = "\"ghost\" expected"; break;
- case 72: s = "\"static\" expected"; break;
- case 73: s = "\"protected\" expected"; break;
- case 74: s = "\"datatype\" expected"; break;
- case 75: s = "\"codatatype\" expected"; break;
- case 76: s = "\"var\" expected"; break;
- case 77: s = "\"newtype\" expected"; break;
- case 78: s = "\"type\" expected"; break;
- case 79: s = "\"iterator\" expected"; break;
- case 80: s = "\"yields\" expected"; break;
- case 81: s = "\"returns\" expected"; break;
- case 82: s = "\"method\" expected"; break;
- case 83: s = "\"colemma\" expected"; break;
- case 84: s = "\"comethod\" expected"; break;
- case 85: s = "\"constructor\" expected"; break;
- case 86: s = "\"free\" expected"; break;
- case 87: s = "\"ensures\" expected"; break;
- case 88: s = "\"yield\" expected"; break;
- case 89: s = "\"`\" expected"; break;
- case 90: s = "\"label\" expected"; break;
- case 91: s = "\"break\" expected"; break;
- case 92: s = "\"where\" expected"; break;
- case 93: s = "\":=\" expected"; break;
- case 94: s = "\"return\" expected"; break;
- case 95: s = "\":|\" expected"; break;
- case 96: s = "\"new\" expected"; break;
- case 97: s = "\"if\" expected"; break;
- case 98: s = "\"while\" expected"; break;
- case 99: s = "\"match\" expected"; break;
- case 100: s = "\"assert\" expected"; break;
- case 101: s = "\"print\" expected"; break;
- case 102: s = "\"forall\" expected"; break;
- case 103: s = "\"parallel\" expected"; break;
- case 104: s = "\"modify\" expected"; break;
- case 105: s = "\"#\" expected"; break;
- case 106: s = "\"<=\" expected"; break;
- case 107: s = "\">=\" expected"; break;
- case 108: s = "\"\\u2264\" expected"; break;
- case 109: s = "\"\\u2265\" expected"; break;
- case 110: s = "\"<==>\" expected"; break;
- case 111: s = "\"\\u21d4\" expected"; break;
- case 112: s = "\"==>\" expected"; break;
- case 113: s = "\"\\u21d2\" expected"; break;
- case 114: s = "\"<==\" expected"; break;
- case 115: s = "\"\\u21d0\" expected"; break;
- case 116: s = "\"&&\" expected"; break;
- case 117: s = "\"\\u2227\" expected"; break;
- case 118: s = "\"||\" expected"; break;
- case 119: s = "\"\\u2228\" expected"; break;
- case 120: s = "\"!\" expected"; break;
- case 121: s = "\"\\u00ac\" expected"; break;
- case 122: s = "\"\\u2200\" expected"; break;
- case 123: s = "\"exists\" expected"; break;
- case 124: s = "\"\\u2203\" expected"; break;
- case 125: s = "\"in\" expected"; break;
- case 126: s = "\"+\" expected"; break;
- case 127: s = "\"-\" expected"; break;
- case 128: s = "\"/\" expected"; break;
- case 129: s = "\"%\" expected"; break;
- case 130: s = "\"false\" expected"; break;
- case 131: s = "\"true\" expected"; break;
- case 132: s = "\"null\" expected"; break;
- case 133: s = "\"this\" expected"; break;
- case 134: s = "\"fresh\" expected"; break;
- case 135: s = "\"old\" expected"; break;
- case 136: s = "\"..\" expected"; break;
- case 137: s = "??? expected"; break;
- case 138: s = "this symbol not expected in SubModuleDecl"; break;
- case 139: s = "invalid SubModuleDecl"; break;
- case 140: s = "this symbol not expected in ClassDecl"; break;
- case 141: s = "this symbol not expected in DatatypeDecl"; break;
- case 142: s = "invalid DatatypeDecl"; break;
- case 143: s = "this symbol not expected in DatatypeDecl"; break;
- case 144: s = "invalid NewtypeDecl"; break;
- case 145: s = "invalid OtherTypeDecl"; break;
- case 146: s = "this symbol not expected in OtherTypeDecl"; break;
- case 147: s = "this symbol not expected in IteratorDecl"; break;
- case 148: s = "invalid IteratorDecl"; break;
- case 149: s = "this symbol not expected in TraitDecl"; break;
- case 150: s = "invalid ClassMemberDecl"; break;
- case 151: s = "this symbol not expected in FieldDecl"; break;
- case 152: s = "invalid FunctionDecl"; break;
+ case 62: s = "\"exclusively\" expected"; break;
+ case 63: s = "\"refines\" expected"; break;
+ case 64: s = "\"import\" expected"; break;
+ case 65: s = "\"opened\" expected"; break;
+ case 66: s = "\"=\" expected"; break;
+ case 67: s = "\"as\" expected"; break;
+ case 68: s = "\"default\" expected"; break;
+ case 69: s = "\"class\" expected"; break;
+ case 70: s = "\"extends\" expected"; break;
+ case 71: s = "\"trait\" expected"; break;
+ case 72: s = "\"ghost\" expected"; break;
+ case 73: s = "\"static\" expected"; break;
+ case 74: s = "\"protected\" expected"; break;
+ case 75: s = "\"datatype\" expected"; break;
+ case 76: s = "\"codatatype\" expected"; break;
+ case 77: s = "\"var\" expected"; break;
+ case 78: s = "\"newtype\" expected"; break;
+ case 79: s = "\"type\" expected"; break;
+ case 80: s = "\"iterator\" expected"; break;
+ case 81: s = "\"yields\" expected"; break;
+ case 82: s = "\"returns\" expected"; break;
+ case 83: s = "\"method\" expected"; break;
+ case 84: s = "\"colemma\" expected"; break;
+ case 85: s = "\"comethod\" expected"; break;
+ case 86: s = "\"constructor\" expected"; break;
+ case 87: s = "\"free\" expected"; break;
+ case 88: s = "\"ensures\" expected"; break;
+ case 89: s = "\"yield\" expected"; break;
+ case 90: s = "\"`\" expected"; break;
+ case 91: s = "\"label\" expected"; break;
+ case 92: s = "\"break\" expected"; break;
+ case 93: s = "\"where\" expected"; break;
+ case 94: s = "\":=\" expected"; break;
+ case 95: s = "\"return\" expected"; break;
+ case 96: s = "\":|\" expected"; break;
+ case 97: s = "\"new\" expected"; break;
+ case 98: s = "\"if\" expected"; break;
+ case 99: s = "\"while\" expected"; break;
+ case 100: s = "\"match\" expected"; break;
+ case 101: s = "\"assert\" expected"; break;
+ case 102: s = "\"print\" expected"; break;
+ case 103: s = "\"forall\" expected"; break;
+ case 104: s = "\"parallel\" expected"; break;
+ case 105: s = "\"modify\" expected"; break;
+ case 106: s = "\"#\" expected"; break;
+ case 107: s = "\"<=\" expected"; break;
+ case 108: s = "\">=\" expected"; break;
+ case 109: s = "\"\\u2264\" expected"; break;
+ case 110: s = "\"\\u2265\" expected"; break;
+ case 111: s = "\"<==>\" expected"; break;
+ case 112: s = "\"\\u21d4\" expected"; break;
+ case 113: s = "\"==>\" expected"; break;
+ case 114: s = "\"\\u21d2\" expected"; break;
+ case 115: s = "\"<==\" expected"; break;
+ case 116: s = "\"\\u21d0\" expected"; break;
+ case 117: s = "\"&&\" expected"; break;
+ case 118: s = "\"\\u2227\" expected"; break;
+ case 119: s = "\"||\" expected"; break;
+ case 120: s = "\"\\u2228\" expected"; break;
+ case 121: s = "\"!\" expected"; break;
+ case 122: s = "\"\\u00ac\" expected"; break;
+ case 123: s = "\"\\u2200\" expected"; break;
+ case 124: s = "\"exists\" expected"; break;
+ case 125: s = "\"\\u2203\" expected"; break;
+ case 126: s = "\"in\" expected"; break;
+ case 127: s = "\"+\" expected"; break;
+ case 128: s = "\"-\" expected"; break;
+ case 129: s = "\"/\" expected"; break;
+ case 130: s = "\"%\" expected"; break;
+ case 131: s = "\"false\" expected"; break;
+ case 132: s = "\"true\" expected"; break;
+ case 133: s = "\"null\" expected"; break;
+ case 134: s = "\"this\" expected"; break;
+ case 135: s = "\"fresh\" expected"; break;
+ case 136: s = "\"old\" expected"; break;
+ case 137: s = "\"..\" expected"; break;
+ case 138: s = "??? expected"; break;
+ case 139: s = "this symbol not expected in SubModuleDecl"; break;
+ case 140: s = "invalid SubModuleDecl"; break;
+ case 141: s = "this symbol not expected in ClassDecl"; break;
+ case 142: s = "this symbol not expected in DatatypeDecl"; break;
+ case 143: s = "invalid DatatypeDecl"; break;
+ case 144: s = "this symbol not expected in DatatypeDecl"; break;
+ case 145: s = "invalid NewtypeDecl"; break;
+ case 146: s = "invalid OtherTypeDecl"; break;
+ case 147: s = "this symbol not expected in OtherTypeDecl"; break;
+ case 148: s = "this symbol not expected in IteratorDecl"; break;
+ case 149: s = "invalid IteratorDecl"; break;
+ case 150: s = "this symbol not expected in TraitDecl"; break;
+ case 151: s = "invalid ClassMemberDecl"; break;
+ case 152: s = "this symbol not expected in FieldDecl"; break;
case 153: s = "invalid FunctionDecl"; break;
case 154: s = "invalid FunctionDecl"; break;
case 155: s = "invalid FunctionDecl"; break;
case 156: s = "invalid FunctionDecl"; break;
- case 157: s = "this symbol not expected in MethodDecl"; break;
- case 158: s = "invalid MethodDecl"; break;
+ case 157: s = "invalid FunctionDecl"; break;
+ case 158: s = "this symbol not expected in MethodDecl"; break;
case 159: s = "invalid MethodDecl"; break;
- case 160: s = "invalid FIdentType"; break;
- case 161: s = "this symbol not expected in OldSemi"; break;
- case 162: s = "invalid TypeIdentOptional"; break;
- case 163: s = "invalid TypeAndToken"; break;
- case 164: s = "this symbol not expected in IteratorSpec"; break;
- case 165: s = "invalid IteratorSpec"; break;
+ case 160: s = "invalid MethodDecl"; break;
+ case 161: s = "invalid FIdentType"; break;
+ case 162: s = "this symbol not expected in OldSemi"; break;
+ case 163: s = "invalid TypeIdentOptional"; break;
+ case 164: s = "invalid TypeAndToken"; break;
+ case 165: s = "this symbol not expected in IteratorSpec"; break;
case 166: s = "invalid IteratorSpec"; break;
- case 167: s = "this symbol not expected in MethodSpec"; break;
- case 168: s = "invalid MethodSpec"; break;
+ case 167: s = "invalid IteratorSpec"; break;
+ case 168: s = "this symbol not expected in MethodSpec"; break;
case 169: s = "invalid MethodSpec"; break;
- case 170: s = "invalid FrameExpression"; break;
- case 171: s = "this symbol not expected in FunctionSpec"; break;
- case 172: s = "invalid FunctionSpec"; break;
- case 173: s = "invalid PossiblyWildFrameExpression"; break;
- case 174: s = "invalid PossiblyWildExpression"; break;
- case 175: s = "this symbol not expected in OneStmt"; break;
- case 176: s = "invalid OneStmt"; break;
- case 177: s = "this symbol not expected in OneStmt"; break;
- case 178: s = "invalid OneStmt"; break;
- case 179: s = "invalid AssertStmt"; break;
- case 180: s = "invalid AssumeStmt"; break;
- case 181: s = "invalid UpdateStmt"; break;
+ case 170: s = "invalid MethodSpec"; break;
+ case 171: s = "invalid FrameExpression"; break;
+ case 172: s = "this symbol not expected in FunctionSpec"; break;
+ case 173: s = "invalid FunctionSpec"; break;
+ case 174: s = "invalid PossiblyWildFrameExpression"; break;
+ case 175: s = "invalid PossiblyWildExpression"; break;
+ case 176: s = "this symbol not expected in OneStmt"; break;
+ case 177: s = "invalid OneStmt"; break;
+ case 178: s = "this symbol not expected in OneStmt"; break;
+ case 179: s = "invalid OneStmt"; break;
+ case 180: s = "invalid AssertStmt"; break;
+ case 181: s = "invalid AssumeStmt"; break;
case 182: s = "invalid UpdateStmt"; break;
- case 183: s = "this symbol not expected in VarDeclStatement"; break;
- case 184: s = "invalid IfStmt"; break;
+ case 183: s = "invalid UpdateStmt"; break;
+ case 184: s = "this symbol not expected in VarDeclStatement"; break;
case 185: s = "invalid IfStmt"; break;
- case 186: s = "invalid WhileStmt"; break;
+ case 186: s = "invalid IfStmt"; break;
case 187: s = "invalid WhileStmt"; break;
- case 188: s = "invalid MatchStmt"; break;
- case 189: s = "invalid ForallStmt"; break;
+ case 188: s = "invalid WhileStmt"; break;
+ case 189: s = "invalid MatchStmt"; break;
case 190: s = "invalid ForallStmt"; break;
- case 191: s = "invalid CalcStmt"; break;
- case 192: s = "invalid ModifyStmt"; break;
- case 193: s = "this symbol not expected in ModifyStmt"; break;
- case 194: s = "invalid ModifyStmt"; break;
- case 195: s = "invalid ReturnStmt"; break;
- case 196: s = "invalid Rhs"; break;
- case 197: s = "invalid Lhs"; break;
- case 198: s = "invalid Guard"; break;
- case 199: s = "this symbol not expected in LoopSpec"; break;
+ case 191: s = "invalid ForallStmt"; break;
+ case 192: s = "invalid CalcStmt"; break;
+ case 193: s = "invalid ModifyStmt"; break;
+ case 194: s = "this symbol not expected in ModifyStmt"; break;
+ case 195: s = "invalid ModifyStmt"; break;
+ case 196: s = "invalid ReturnStmt"; break;
+ case 197: s = "invalid Rhs"; break;
+ case 198: s = "invalid Lhs"; break;
+ case 199: s = "invalid Guard"; break;
case 200: s = "this symbol not expected in LoopSpec"; break;
case 201: s = "this symbol not expected in LoopSpec"; break;
- case 202: s = "invalid LoopSpec"; break;
- case 203: s = "invalid CaseStatement"; break;
- case 204: s = "this symbol not expected in CaseStatement"; break;
+ case 202: s = "this symbol not expected in LoopSpec"; break;
+ case 203: s = "invalid LoopSpec"; break;
+ case 204: s = "invalid CaseStatement"; break;
case 205: s = "this symbol not expected in CaseStatement"; break;
- case 206: s = "invalid CasePattern"; break;
- case 207: s = "invalid CalcOp"; break;
- case 208: s = "invalid EquivOp"; break;
- case 209: s = "invalid ImpliesOp"; break;
- case 210: s = "invalid ExpliesOp"; break;
- case 211: s = "invalid AndOp"; break;
- case 212: s = "invalid OrOp"; break;
- case 213: s = "invalid NegOp"; break;
- case 214: s = "invalid Forall"; break;
- case 215: s = "invalid Exists"; break;
- case 216: s = "invalid QSep"; break;
- case 217: s = "invalid ImpliesExpliesExpression"; break;
- case 218: s = "invalid LogicalExpression"; break;
- case 219: s = "invalid RelOp"; break;
- case 220: s = "invalid AddOp"; break;
- case 221: s = "invalid UnaryExpression"; break;
- case 222: s = "invalid MulOp"; break;
- case 223: s = "invalid Suffix"; break;
+ case 206: s = "this symbol not expected in CaseStatement"; break;
+ case 207: s = "invalid CasePattern"; break;
+ case 208: s = "invalid CalcOp"; break;
+ case 209: s = "invalid EquivOp"; break;
+ case 210: s = "invalid ImpliesOp"; break;
+ case 211: s = "invalid ExpliesOp"; break;
+ case 212: s = "invalid AndOp"; break;
+ case 213: s = "invalid OrOp"; break;
+ case 214: s = "invalid NegOp"; break;
+ case 215: s = "invalid Forall"; break;
+ case 216: s = "invalid Exists"; break;
+ case 217: s = "invalid QSep"; break;
+ case 218: s = "invalid ImpliesExpliesExpression"; break;
+ case 219: s = "invalid LogicalExpression"; break;
+ case 220: s = "invalid RelOp"; break;
+ case 221: s = "invalid AddOp"; break;
+ case 222: s = "invalid UnaryExpression"; break;
+ case 223: s = "invalid MulOp"; break;
case 224: s = "invalid Suffix"; break;
case 225: s = "invalid Suffix"; break;
case 226: s = "invalid Suffix"; break;
- case 227: s = "invalid LambdaExpression"; break;
- case 228: s = "invalid EndlessExpression"; break;
- case 229: s = "invalid NameSegment"; break;
- case 230: s = "invalid DisplayExpr"; break;
- case 231: s = "invalid MultiSetExpr"; break;
- case 232: s = "invalid ConstAtomExpression"; break;
- case 233: s = "invalid Nat"; break;
- case 234: s = "invalid LambdaArrow"; break;
- case 235: s = "invalid MatchExpression"; break;
- case 236: s = "invalid QuantifierGuts"; break;
- case 237: s = "invalid StmtInExpr"; break;
- case 238: s = "invalid LetExpr"; break;
- case 239: s = "invalid CaseExpression"; break;
- case 240: s = "invalid DotSuffix"; break;
+ case 227: s = "invalid Suffix"; break;
+ case 228: s = "invalid LambdaExpression"; break;
+ case 229: s = "invalid EndlessExpression"; break;
+ case 230: s = "invalid NameSegment"; break;
+ case 231: s = "invalid DisplayExpr"; break;
+ case 232: s = "invalid MultiSetExpr"; break;
+ case 233: s = "invalid ConstAtomExpression"; break;
+ case 234: s = "invalid Nat"; break;
+ case 235: s = "invalid LambdaArrow"; break;
+ case 236: s = "invalid MatchExpression"; break;
+ case 237: s = "invalid QuantifierGuts"; break;
+ case 238: s = "invalid StmtInExpr"; break;
+ case 239: s = "invalid LetExpr"; break;
+ case 240: s = "invalid CaseExpression"; break;
+ case 241: s = "invalid DotSuffix"; break;
default: s = "error " + n; break;
}
diff --git a/Source/Dafny/RefinementTransformer.cs b/Source/Dafny/RefinementTransformer.cs
index 05146b7d..2d32f78a 100644
--- a/Source/Dafny/RefinementTransformer.cs
+++ b/Source/Dafny/RefinementTransformer.cs
@@ -86,6 +86,15 @@ namespace Microsoft.Dafny
if (Resolver.ResolvePath(m.RefinementBaseRoot, m.RefinementBaseName, out RefinedSig, reporter)) {
if (RefinedSig.ModuleDef != null) {
m.RefinementBase = RefinedSig.ModuleDef;
+ if (m.IsExclusiveRefinement) {
+ if (null == m.RefinementBase.ExclusiveRefinement) {
+ m.RefinementBase.ExclusiveRefinement = m;
+ } else {
+ this.reporter.Error(
+ m.tok,
+ "no more than one exclusive refinement may exist for a given module.");
+ }
+ }
PreResolveWorker(m);
} else {
reporter.Error(m.RefinementBaseName[0], "module ({0}) named as refinement base is not a literal module or simple reference to a literal module", Util.Comma(".", m.RefinementBaseName, x => x.val));
diff --git a/Source/Dafny/Resolver.cs b/Source/Dafny/Resolver.cs
index 9d560561..8d23f374 100644
--- a/Source/Dafny/Resolver.cs
+++ b/Source/Dafny/Resolver.cs
@@ -50,15 +50,27 @@ namespace Microsoft.Dafny
Contract.Requires(msg != null);
Error(e.tok, msg, args);
}
+
+ private bool reportWarnings = true;
+ /// <summary>
+ /// Set whether or not to report warnings. Return the state of the previous behavior.
+ /// </summary>
+ public bool ReportWarnings(bool b) {
+ var old = reportWarnings;
+ reportWarnings = b;
+ return old;
+ }
public void Warning(IToken tok, string msg, params object[] args) {
Contract.Requires(tok != null);
Contract.Requires(msg != null);
- ConsoleColor col = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine("{0}({1},{2}): Warning: {3}",
- DafnyOptions.Clo.UseBaseNameForFileName ? System.IO.Path.GetFileName(tok.filename) : tok.filename, tok.line, tok.col - 1,
- string.Format(msg, args));
- Console.ForegroundColor = col;
+ if (reportWarnings) {
+ ConsoleColor col = Console.ForegroundColor;
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine("{0}({1},{2}): Warning: {3}",
+ DafnyOptions.Clo.UseBaseNameForFileName ? System.IO.Path.GetFileName(tok.filename) : tok.filename, tok.line, tok.col - 1,
+ string.Format(msg, args));
+ Console.ForegroundColor = col;
+ }
}
}
@@ -319,6 +331,33 @@ namespace Microsoft.Dafny
systemNameInfo = RegisterTopLevelDecls(prog.BuiltIns.SystemModule, false);
prog.CompileModules.Add(prog.BuiltIns.SystemModule);
+
+ // first, we need to detect which top-level modules have exclusive refinement relationships.
+ foreach (ModuleDecl decl in sortedDecls) {
+ if (decl is LiteralModuleDecl) {
+ var literalDecl = (LiteralModuleDecl)decl;
+ var m = literalDecl.ModuleDef;
+ if (m.RefinementBaseRoot != null) {
+ if (m.IsExclusiveRefinement) {
+ foreach (var d in sortedDecls) {
+ // refinement dependencies won't be later in the sorted module list than the one we're looking at.
+ if (Object.ReferenceEquals(d, decl)) {
+ break;
+ }
+ if (d is LiteralModuleDecl) {
+ var ld = (LiteralModuleDecl)d;
+ // currently, only exclusive refinements of top-level modules are supported.
+ if (string.Equals(m.RefinementBaseName[0].val, m.RefinementBaseRoot.Name, StringComparison.InvariantCulture)
+ && string.Equals(m.RefinementBaseName[0].val, ld.ModuleDef.Name, StringComparison.InvariantCulture)) {
+ ld.ModuleDef.ExclusiveRefinementCount += 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
foreach (var decl in sortedDecls) {
if (decl is LiteralModuleDecl) {
// The declaration is a literal module, so it has members and such that we need
@@ -353,6 +392,7 @@ namespace Microsoft.Dafny
// compilation should only proceed if everything is good, including the signature (which preResolveErrorCount does not include);
Contract.Assert(!useCompileSignatures);
useCompileSignatures = true; // set Resolver-global flag to indicate that Signatures should be followed to their CompiledSignature
+ var oldWarnings = ReportWarnings(false); // turn off warning reporting for the clone
var nw = new Cloner().CloneModuleDefinition(m, m.CompileName + "_Compile");
var compileSig = RegisterTopLevelDecls(nw, true);
compileSig.Refines = refinementTransformer.RefinedSig;
@@ -360,6 +400,7 @@ namespace Microsoft.Dafny
ResolveModuleDefinition(nw, compileSig);
prog.CompileModules.Add(nw);
useCompileSignatures = false; // reset the flag
+ ReportWarnings(oldWarnings);
}
} else if (decl is AliasModuleDecl) {
var alias = (AliasModuleDecl)decl;
@@ -374,20 +415,27 @@ namespace Microsoft.Dafny
var abs = (ModuleFacadeDecl)decl;
ModuleSignature p;
if (ResolvePath(abs.Root, abs.Path, out p, this)) {
- abs.Signature = MakeAbstractSignature(p, abs.FullCompileName, abs.Height, prog.Modules);
abs.OriginalSignature = p;
- ModuleSignature compileSig;
- if (abs.CompilePath != null) {
- if (ResolvePath(abs.CompileRoot, abs.CompilePath, out compileSig, this)) {
- if (refinementTransformer.CheckIsRefinement(compileSig, p)) {
- abs.Signature.CompileSignature = compileSig;
- } else {
- Error(abs.CompilePath[0],
- "module " + Util.Comma(".", abs.CompilePath, x => x.val) + " must be a refinement of " + Util.Comma(".", abs.Path, x => x.val));
+ // ModuleDefinition.ExclusiveRefinement may not be set at this point but ExclusiveRefinementCount will be.
+ if (0 == abs.Root.Signature.ModuleDef.ExclusiveRefinementCount) {
+ abs.Signature = MakeAbstractSignature(p, abs.FullCompileName, abs.Height, prog.Modules);
+ ModuleSignature compileSig;
+ if (abs.CompilePath != null) {
+ if (ResolvePath(abs.CompileRoot, abs.CompilePath, out compileSig, this)) {
+ if (refinementTransformer.CheckIsRefinement(compileSig, p)) {
+ abs.Signature.CompileSignature = compileSig;
+ } else {
+ Error(
+ abs.CompilePath[0],
+ "module " + Util.Comma(".", abs.CompilePath, x => x.val) + " must be a refinement of "
+ + Util.Comma(".", abs.Path, x => x.val));
+ }
+ abs.Signature.IsGhost = compileSig.IsGhost;
+ // always keep the ghost information, to supress a spurious error message when the compile module isn't actually a refinement
}
- abs.Signature.IsGhost = compileSig.IsGhost;
- // always keep the ghost information, to supress a spurious error message when the compile module isn't actually a refinement
}
+ } else {
+ abs.Signature = p;
}
} else {
abs.Signature = new ModuleSignature(); // there was an error, give it a valid but empty signature
@@ -469,6 +517,25 @@ namespace Microsoft.Dafny
}
}
}
+
+ // Determine, for each function, whether someone tries to adjust its fuel parameter
+ foreach (var module in prog.Modules) {
+ CheckForFuelAdjustments(module.tok, module.Attributes, module, this);
+ foreach (var clbl in ModuleDefinition.AllItersAndCallables(module.TopLevelDecls)) {
+ Statement body = null;
+ if (clbl is Method) {
+ body = ((Method)clbl).Body;
+ CheckForFuelAdjustments(clbl.Tok,((Method)clbl).Attributes, module, this);
+ } else if (clbl is IteratorDecl) {
+ body = ((IteratorDecl)clbl).Body;
+ CheckForFuelAdjustments(clbl.Tok, ((IteratorDecl)clbl).Attributes, module, this);
+ }
+ if (body != null) {
+ var c = new FuelAdjustment_Visitor(this);
+ c.Visit(body, new FuelAdjustment_Context(module, this));
+ }
+ }
+ }
}
void FillInDefaultDecreasesClauses(Program prog)
@@ -697,8 +764,8 @@ namespace Microsoft.Dafny
var datatypeDependencies = new Graph<IndDatatypeDecl>();
var codatatypeDependencies = new Graph<CoDatatypeDecl>();
int prevErrorCount = ErrorCount;
- ResolveAttributes(m.Attributes, new ResolveOpts(new NoContext(m.Module), false));
ResolveTopLevelDecls_Signatures(m, m.TopLevelDecls, datatypeDependencies, codatatypeDependencies);
+ ResolveAttributes(m.Attributes, new ResolveOpts(new NoContext(m.Module), false)); // Must follow ResolveTopLevelDecls_Signatures, in case attributes refer to members
if (ErrorCount == prevErrorCount) {
ResolveTopLevelDecls_Meat(m.TopLevelDecls, datatypeDependencies, codatatypeDependencies);
}
@@ -866,20 +933,31 @@ namespace Microsoft.Dafny
sig.IsGhost = moduleDef.IsAbstract;
List<TopLevelDecl> declarations = moduleDef.TopLevelDecls;
- if (useImports) {
- // First go through and add anything from the opened imports
- foreach (var im in declarations) {
- if (im is ModuleDecl && ((ModuleDecl)im).Opened) {
- var s = GetSignature(((ModuleDecl)im).Signature);
+ // First go through and add anything from the opened imports
+ foreach (var im in declarations) {
+ if (im is ModuleDecl && ((ModuleDecl)im).Opened) {
+ var s = GetSignature(((ModuleDecl)im).Signature);
+
+ if (useImports || DafnyOptions.O.IronDafny) {
// classes:
foreach (var kv in s.TopLevels) {
- TopLevelDecl d;
- if (sig.TopLevels.TryGetValue(kv.Key, out d)) {
- sig.TopLevels[kv.Key] = AmbiguousTopLevelDecl.Create(moduleDef, d, kv.Value);
- } else {
- sig.TopLevels.Add(kv.Key, kv.Value);
+ // IronDafny: we need to pull the members of the opened module's _default class in so that they can be merged.
+ if (useImports || string.Equals(kv.Key, "_default", StringComparison.InvariantCulture)) {
+ TopLevelDecl d;
+ if (sig.TopLevels.TryGetValue(kv.Key, out d)) {
+ if (DafnyOptions.O.IronDafny && kv.Value.ClonedFrom == d) {
+ sig.TopLevels[kv.Key] = kv.Value;
+ } else {
+ sig.TopLevels[kv.Key] = AmbiguousTopLevelDecl.Create(moduleDef, d, kv.Value);
+ }
+ } else {
+ sig.TopLevels.Add(kv.Key, kv.Value);
+ }
}
}
+ }
+
+ if (useImports) {
// constructors:
foreach (var kv in s.Ctors) {
Tuple<DatatypeCtor, bool> pair;
@@ -895,6 +973,9 @@ namespace Microsoft.Dafny
sig.Ctors.Add(kv.Key, kv.Value);
}
}
+ }
+
+ if (useImports || DafnyOptions.O.IronDafny) {
// static members:
foreach (var kv in s.StaticMembers) {
MemberDecl md;
@@ -904,7 +985,7 @@ namespace Microsoft.Dafny
// add new
sig.StaticMembers.Add(kv.Key, kv.Value);
}
- }
+ }
}
}
}
@@ -1193,7 +1274,8 @@ namespace Microsoft.Dafny
}
private ModuleSignature MakeAbstractSignature(ModuleSignature p, string Name, int Height, List<ModuleDefinition> mods) {
- var mod = new ModuleDefinition(Token.NoToken, Name + ".Abs", true, true, null, null, null, false);
+ var mod = new ModuleDefinition(Token.NoToken, Name + ".Abs", true, true, /*isExclusiveRefinement:*/ false, null, null, null, false);
+ mod.ClonedFrom = p.ModuleDef;
mod.Height = Height;
foreach (var kv in p.TopLevels) {
mod.TopLevelDecls.Add(CloneDeclaration(kv.Value, mod, mods, Name));
@@ -1202,6 +1284,7 @@ namespace Microsoft.Dafny
sig.Refines = p.Refines;
sig.CompileSignature = p;
sig.IsGhost = p.IsGhost;
+ sig.ExclusiveRefinement = p.ExclusiveRefinement;
mods.Add(mod);
ResolveModuleDefinition(mod, sig);
return sig;
@@ -1369,7 +1452,7 @@ namespace Microsoft.Dafny
Contract.Assert(dd.Constraint != null); // follows from NewtypeDecl invariant
scope.PushMarker();
var added = scope.Push(dd.Var.Name, dd.Var);
- Contract.Assert(added);
+ Contract.Assert(added == Scope<IVariable>.PushResult.Success);
ResolveType(dd.Var.tok, dd.Var.Type, dd, ResolveTypeOptionEnum.DontInfer, null);
ResolveExpression(dd.Constraint, new ResolveOpts(dd, false, true));
Contract.Assert(dd.Constraint.Type != null); // follows from postcondition of ResolveExpression
@@ -2111,7 +2194,8 @@ namespace Microsoft.Dafny
proxy.T = new ObjectType();
return true;
}
- return !(t is TypeProxy); // all other proxies indicate the type has not yet been determined
+ // all other proxies indicate the type has not yet been determined, provided their type parameters have been
+ return !(t is TypeProxy) && t.TypeArgs.All(tt => IsDetermined(tt.Normalize()));
}
ISet<TypeProxy> UnderspecifiedTypeProxies = new HashSet<TypeProxy>();
bool CheckTypeIsDetermined(IToken tok, Type t, string what) {
@@ -2350,6 +2434,58 @@ namespace Microsoft.Dafny
#endregion CheckTailRecursive
// ------------------------------------------------------------------------------------------------------
+ // ----- FuelAdjustmentChecks ---------------------------------------------------------------------------
+ // ------------------------------------------------------------------------------------------------------
+ #region FuelAdjustmentChecks
+
+ protected static void CheckForFuelAdjustments(IToken tok, Attributes attrs, ModuleDefinition currentModule, ResolutionErrorReporter reporter) {
+ List<List<Expression>> results = Attributes.FindAllExpressions(attrs, "fuel");
+
+ if (results != null) {
+ foreach (List<Expression> args in results) {
+ if (args != null && args.Count >= 2) {
+ // Try to extract the function from the first argument
+ MemberSelectExpr selectExpr = args[0].Resolved as MemberSelectExpr;
+ if (selectExpr != null) {
+ Function f = selectExpr.Member as Function;
+ if (f != null) {
+ f.IsFueled = true;
+ if (f.IsProtected && currentModule != f.EnclosingClass.Module) {
+ reporter.Error(tok, "cannot adjust fuel for protected function {0} from another module", f.Name);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public class FuelAdjustment_Context
+ {
+ public ModuleDefinition currentModule;
+ public ResolutionErrorReporter reporter;
+ public FuelAdjustment_Context(ModuleDefinition currentModule, ResolutionErrorReporter reporter) {
+ this.currentModule = currentModule;
+ this.reporter = reporter;
+ }
+ }
+
+ class FuelAdjustment_Visitor : ResolverTopDownVisitor<FuelAdjustment_Context>
+ {
+ public FuelAdjustment_Visitor(Resolver resolver)
+ : base(resolver) {
+ Contract.Requires(resolver != null);
+ }
+
+ protected override bool VisitOneStmt(Statement stmt, ref FuelAdjustment_Context st) {
+ Resolver.CheckForFuelAdjustments(stmt.Tok, stmt.Attributes, st.currentModule, st.reporter);
+ return true;
+ }
+ }
+
+ #endregion FuelAdjustmentChecks
+
+ // ------------------------------------------------------------------------------------------------------
// ----- FixpointPredicateChecks ------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------
#region FixpointPredicateChecks
@@ -2631,6 +2767,14 @@ namespace Microsoft.Dafny
foreach (var v in s.BoundVars) {
CheckEqualityTypes_Type(v.Tok, v.Type);
}
+ // do substatements and subexpressions, except attributes and ensures clauses, since they are not compiled
+ foreach (var ss in s.SubStatements) {
+ Visit(ss, st);
+ }
+ if (s.Range != null) {
+ Visit(s.Range, st);
+ }
+ return false; // we're done
}
return true;
}
@@ -2689,6 +2833,18 @@ namespace Microsoft.Dafny
foreach (var bv in e.BoundVars) {
CheckEqualityTypes_Type(bv.tok, bv.Type);
}
+ } else if (expr is MemberSelectExpr) {
+ var e = (MemberSelectExpr)expr;
+ if (e.Member is Function || e.Member is Method) {
+ var i = 0;
+ foreach (var tp in ((ICallable)e.Member).TypeArgs) {
+ var actualTp = e.TypeApplication[e.Member.EnclosingClass.TypeArgs.Count + i];
+ if (tp.MustSupportEquality && !actualTp.SupportsEquality) {
+ Error(e.tok, "type parameter {0} ({1}) passed to {5} '{2}' must support equality (got {3}){4}", i, tp.Name, e.Member.Name, actualTp, TypeEqualityErrorMessageHint(actualTp), e.Member.WhatKind);
+ }
+ i++;
+ }
+ }
} else if (expr is FunctionCallExpr) {
var e = (FunctionCallExpr)expr;
Contract.Assert(e.Function.TypeArgs.Count <= e.TypeArgumentSubstitutions.Count);
@@ -2711,7 +2867,7 @@ namespace Microsoft.Dafny
i++;
}
return false; // we've done what there is to be done
- } else if (expr is SetDisplayExpr || expr is MultiSetDisplayExpr || expr is MapDisplayExpr || expr is MultiSetFormingExpr) {
+ } else if (expr is SetDisplayExpr || expr is MultiSetDisplayExpr || expr is MapDisplayExpr || expr is MultiSetFormingExpr || expr is StaticReceiverExpr) {
// This catches other expressions whose type may potentially be illegal
CheckEqualityTypes_Type(expr.tok, expr.Type);
}
@@ -2727,11 +2883,8 @@ namespace Microsoft.Dafny
} else if (type is SetType) {
var st = (SetType)type;
var argType = st.Arg;
- if (!st.Finite) {
- Error(tok, "isets do not support equality: {0}", st);
- }
if (!argType.SupportsEquality) {
- Error(tok, "set argument type must support equality (got {0}){1}", argType, TypeEqualityErrorMessageHint(argType));
+ Error(tok, "{2}set argument type must support equality (got {0}){1}", argType, TypeEqualityErrorMessageHint(argType), st.Finite ? "" : "i");
}
CheckEqualityTypes_Type(tok, argType);
@@ -2744,11 +2897,8 @@ namespace Microsoft.Dafny
} else if (type is MapType) {
var mt = (MapType)type;
- if (!mt.Finite) {
- Error(tok, "imaps do not support equality: {0}", mt);
- }
if (!mt.Domain.SupportsEquality) {
- Error(tok, "map domain type must support equality (got {0}){1}", mt.Domain, TypeEqualityErrorMessageHint(mt.Domain));
+ Error(tok, "{2}map domain type must support equality (got {0}){1}", mt.Domain, TypeEqualityErrorMessageHint(mt.Domain), mt.Finite ? "" : "i");
}
CheckEqualityTypes_Type(tok, mt.Domain);
CheckEqualityTypes_Type(tok, mt.Range);
@@ -3476,12 +3626,43 @@ namespace Microsoft.Dafny
tp.Parent = parent;
tp.PositionalIndex = index;
}
- if (!allTypeParameters.Push(tp.Name, tp) && emitErrors) {
- Error(tp, "Duplicate type-parameter name: {0}", tp.Name);
+ var r = allTypeParameters.Push(tp.Name, tp);
+ if (emitErrors) {
+ if (r == Scope<TypeParameter>.PushResult.Duplicate) {
+ Error(tp, "Duplicate type-parameter name: {0}", tp.Name);
+ } else if (r == Scope<TypeParameter>.PushResult.Shadow) {
+ Warning(tp.tok, "Shadowed type-parameter name: {0}", tp.Name);
+ }
}
}
}
+ void ScopePushAndReport(Scope<IVariable> scope, IVariable v, string kind) {
+ Contract.Requires(scope != null);
+ Contract.Requires(v != null);
+ Contract.Requires(kind != null);
+ ScopePushAndReport(scope, v.Name, v, v.Tok, kind);
+ }
+
+ void ScopePushAndReport<Thing>(Scope<Thing> scope, string name, Thing thing, IToken tok, string kind) where Thing : class {
+ Contract.Requires(scope != null);
+ Contract.Requires(name != null);
+ Contract.Requires(thing != null);
+ Contract.Requires(tok != null);
+ Contract.Requires(kind != null);
+ var r = scope.Push(name, thing);
+ switch (r) {
+ case Scope<Thing>.PushResult.Success:
+ break;
+ case Scope<Thing>.PushResult.Duplicate:
+ Error(tok, "Duplicate {0} name: {1}", kind, name);
+ break;
+ case Scope<Thing>.PushResult.Shadow:
+ Warning(tok, "Shadowed {0} name: {1}", kind, name);
+ break;
+ }
+ }
+
/// <summary>
/// Assumes type parameters have already been pushed
/// </summary>
@@ -3493,9 +3674,7 @@ namespace Microsoft.Dafny
}
var option = f.TypeArgs.Count == 0 ? new ResolveTypeOption(f) : new ResolveTypeOption(ResolveTypeOptionEnum.AllowPrefix);
foreach (Formal p in f.Formals) {
- if (!scope.Push(p.Name, p)) {
- Error(p, "Duplicate parameter name: {0}", p.Name);
- }
+ ScopePushAndReport(scope, p, "parameter");
ResolveType(p.tok, p.Type, f, option, f.TypeArgs);
}
ResolveType(f.tok, f.ResultType, f, option, f.TypeArgs);
@@ -3603,16 +3782,12 @@ namespace Microsoft.Dafny
var option = m.TypeArgs.Count == 0 ? new ResolveTypeOption(m) : new ResolveTypeOption(ResolveTypeOptionEnum.AllowPrefix);
// resolve in-parameters
foreach (Formal p in m.Ins) {
- if (!scope.Push(p.Name, p)) {
- Error(p, "Duplicate parameter name: {0}", p.Name);
- }
+ ScopePushAndReport(scope, p, "parameter");
ResolveType(p.tok, p.Type, m, option, m.TypeArgs);
}
// resolve out-parameters
foreach (Formal p in m.Outs) {
- if (!scope.Push(p.Name, p)) {
- Error(p, "Duplicate parameter name: {0}", p.Name);
- }
+ ScopePushAndReport(scope, p, "parameter");
ResolveType(p.tok, p.Type, m, option, m.TypeArgs);
}
scope.PopMarker();
@@ -4143,8 +4318,15 @@ namespace Microsoft.Dafny
} else if (r.Type is Resolver_IdentifierExpr.ResolverType_Type) {
var d = r.Decl;
if (d is OpaqueTypeDecl) {
- t.ResolvedParam = ((OpaqueTypeDecl)d).TheType; // resolve like a type parameter, and it may have type parameters if it's an opaque type
- t.ResolvedClass = d; // Store the decl, so the compiler will generate the fully qualified name
+ var dd = (OpaqueTypeDecl)d;
+ if (dd.Module.ClonedFrom != null && dd.Module.ClonedFrom.ExclusiveRefinement != null) {
+ t.ResolvedParam = ((OpaqueTypeDecl)dd.ClonedFrom).TheType;
+ t.ResolvedClass = d; // Store the decl, so the compiler will generate the fully qualified name
+ } else {
+ t.ResolvedParam = ((OpaqueTypeDecl)d).TheType;
+ // resolve like a type parameter, and it may have type parameters if it's an opaque type
+ t.ResolvedClass = d; // Store the decl, so the compiler will generate the fully qualified name
+ }
} else if (d is NewtypeDecl) {
var dd = (NewtypeDecl)d;
var caller = context as ICallable;
@@ -4267,8 +4449,23 @@ namespace Microsoft.Dafny
return false;
}
var aa = (UserDefinedType)a;
+ var rca = aa.ResolvedClass;
var bb = (UserDefinedType)b;
- if (aa.ResolvedClass != null && aa.ResolvedClass == bb.ResolvedClass) {
+ var rcb = bb.ResolvedClass;
+ if (DafnyOptions.O.IronDafny)
+ {
+ while (rca != null && rca.Module.IsAbstract && rca.ClonedFrom != null)
+ {
+ // todo: should ClonedFrom be a TopLevelDecl?
+ // todo: should ClonedFrom be moved to TopLevelDecl?
+ rca = (TopLevelDecl)rca.ClonedFrom;
+ }
+ while (rcb != null && rcb.Module.IsAbstract && rcb.ClonedFrom != null)
+ {
+ rcb = (TopLevelDecl)rcb.ClonedFrom;
+ }
+ }
+ if (rca != null && rca == rcb) {
// these are both resolved class/datatype types
Contract.Assert(aa.TypeArgs.Count == bb.TypeArgs.Count);
bool successSoFar = true;
@@ -4277,12 +4474,12 @@ namespace Microsoft.Dafny
}
return successSoFar;
}
- else if ((bb.ResolvedClass is TraitDecl) && (aa.ResolvedClass is TraitDecl)) {
- return ((TraitDecl)bb.ResolvedClass).FullCompileName == ((TraitDecl)aa.ResolvedClass).FullCompileName;
- } else if ((bb.ResolvedClass is ClassDecl) && (aa.ResolvedClass is TraitDecl)) {
- return ((ClassDecl)bb.ResolvedClass).TraitsObj.Any(tr => tr.FullCompileName == ((TraitDecl)aa.ResolvedClass).FullCompileName);
- } else if ((aa.ResolvedClass is ClassDecl) && (bb.ResolvedClass is TraitDecl)) {
- return ((ClassDecl)aa.ResolvedClass).TraitsObj.Any(tr => tr.FullCompileName == ((TraitDecl)bb.ResolvedClass).FullCompileName);
+ else if ((rcb is TraitDecl) && (rca is TraitDecl)) {
+ return ((TraitDecl)rcb).FullCompileName == ((TraitDecl)rca).FullCompileName;
+ } else if ((rcb is ClassDecl) && (rca is TraitDecl)) {
+ return ((ClassDecl)rcb).TraitsObj.Any(tr => tr.FullCompileName == ((TraitDecl)rca).FullCompileName);
+ } else if ((rca is ClassDecl) && (rcb is TraitDecl)) {
+ return ((ClassDecl)rca).TraitsObj.Any(tr => tr.FullCompileName == ((TraitDecl)rcb).FullCompileName);
} else if (aa.ResolvedParam != null && aa.ResolvedParam == bb.ResolvedParam) {
// type parameters
if (aa.TypeArgs.Count != bb.TypeArgs.Count) {
@@ -4771,9 +4968,7 @@ namespace Microsoft.Dafny
}
// Add the locals to the scope
foreach (var local in s.Locals) {
- if (!scope.Push(local.Name, local)) {
- Error(local.Tok, "Duplicate local-variable name: {0}", local.Name);
- }
+ ScopePushAndReport(scope, local, "local-variable");
}
// With the new locals in scope, it's now time to resolve the attributes on all the locals
foreach (var local in s.Locals) {
@@ -5064,9 +5259,7 @@ namespace Microsoft.Dafny
int prevErrorCount = ErrorCount;
scope.PushMarker();
foreach (BoundVar v in s.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "local-variable");
ResolveType(v.tok, v.Type, codeContext, ResolveTypeOptionEnum.InferTypeProxies, null);
}
ResolveExpression(s.Range, new ResolveOpts(codeContext, true, specContextOnly));
@@ -5258,7 +5451,8 @@ namespace Microsoft.Dafny
// convert CasePattern in MatchCaseExpr to BoundVar and flatten the MatchCaseExpr.
Type type = new InferredTypeProxy();
string name = FreshTempVarName("_mc#", codeContext);
- BoundVar bv = new BoundVar(s.Tok, name, type);
+ MatchCaseToken mcToken = new MatchCaseToken(s.Tok);
+ BoundVar bv = new BoundVar(mcToken, name, type);
List<CasePattern> patternSubst = new List<CasePattern>();
if (dtd != null) {
DesugarMatchCaseStmt(s, dtd, bv, patternSubst, codeContext);
@@ -5297,6 +5491,14 @@ namespace Microsoft.Dafny
Error(stmt, "the declared type of the formal ({0}) does not agree with the corresponding type in the constructor's signature ({1})", v.Type, st);
}
v.IsGhost = formal.IsGhost;
+
+ // update the type of the boundvars in the MatchCaseToken
+ if (v.tok is MatchCaseToken) {
+ MatchCaseToken mt = (MatchCaseToken)v.tok;
+ foreach (Tuple<IToken, BoundVar, bool> entry in mt.varList) {
+ UnifyTypes(entry.Item2.Type, v.Type);
+ }
+ }
}
i++;
}
@@ -5345,11 +5547,11 @@ namespace Microsoft.Dafny
* case (Suc(a), Suc(b)) => minus(a, b)
* To:
* match x
- * case Zero => match y
+ * case Zero => match y (originalToken)
* case _ => zero
- * case Suc(_) => match y
+ * case Suc(_) => match y (AutoGeneratedToken)
* case Zero => x
- * case Suc(a) => match y
+ * case Suc(a) => match y (AutoGeneratedToken)
* case (b) => minus(a,b)
*/
void DesugarMatchStmtWithTupleExpression(MatchStmt me) {
@@ -5361,6 +5563,9 @@ namespace Microsoft.Dafny
} else {
Expression source = e.Arguments[0];
List<MatchCaseStmt> cases = new List<MatchCaseStmt>();
+ // only keep the token for the first appearance, use autogenerated for the rest, otherwise more than one hovertext
+ // will show up in the IDE.
+ bool keepOrigToken = true;
foreach (MatchCaseStmt mc in me.Cases) {
if (mc.CasePatterns == null || mc.CasePatterns.Count != e.Arguments.Count) {
Error(mc.tok, "case arguments count does not match source arguments count");
@@ -5376,9 +5581,10 @@ namespace Microsoft.Dafny
List<Statement> body = mc.Body;
for (int i = e.Arguments.Count; 1 <= --i; ) {
// others go into the body
- body = CreateMatchCaseStmtBody(me.Tok, e.Arguments[i], mc.CasePatterns[i], body);
+ body = CreateMatchCaseStmtBody(me.Tok, e.Arguments[i], mc.CasePatterns[i], body, keepOrigToken);
}
cases.Add(new MatchCaseStmt(cp.tok, cp.Id, patterns, body));
+ keepOrigToken = false;
}
}
me.UpdateSource(source);
@@ -5387,7 +5593,7 @@ namespace Microsoft.Dafny
}
}
- List<Statement> CreateMatchCaseStmtBody(Boogie.IToken tok, Expression source, CasePattern cp, List<Statement> body) {
+ List<Statement> CreateMatchCaseStmtBody(Boogie.IToken tok, Expression source, CasePattern cp, List<Statement> body, bool keepToken) {
List<MatchCaseStmt> cases = new List<MatchCaseStmt>();
List<CasePattern> patterns;
if (cp.Var != null) {
@@ -5401,6 +5607,10 @@ namespace Microsoft.Dafny
patterns = cp.Arguments;
}
cases.Add(new MatchCaseStmt(cp.tok, cp.Id, patterns, body));
+ if (!keepToken) {
+ AutoGeneratedTokenCloner cloner = new AutoGeneratedTokenCloner();
+ source = cloner.CloneExpr(source);
+ }
List<Statement> list = new List<Statement>();
// endTok??
list.Add(new MatchStmt(tok, tok, source, cases, false));
@@ -5512,9 +5722,7 @@ namespace Microsoft.Dafny
if (pat.Var != null) {
BoundVar v = pat.Var;
if (topLevel) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate parameter name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "parameter");
} else {
if (scope.Find(v.Name) != null) {
Error(v, "Duplicate parameter name: {0}", v.Name);
@@ -5536,7 +5744,7 @@ namespace Microsoft.Dafny
// case Cons(y, #mc#) => match #mc#
// case Cons(z, zs) => body
- Expression source = new NameSegment(pat.tok, v.Name, null);
+ Expression source = new NameSegment(new AutoGeneratedToken(pat.tok), v.Name, null);
List<MatchCaseStmt> cases = new List<MatchCaseStmt>();
cases.Add(new MatchCaseStmt(pat.tok, pat.Id, pat.Arguments == null ? new List<CasePattern>() : pat.Arguments, mc.Body));
List<Statement> list = new List<Statement>();
@@ -5561,6 +5769,27 @@ namespace Microsoft.Dafny
foreach (MatchCaseStmt c in current.Cases) {
old.Cases.Add(c);
}
+ // add the token from mc to old_mc so the identifiers will show correctly in the IDE
+ List<BoundVar> arguments = new List<BoundVar>();
+ Contract.Assert(old_mc.Arguments.Count == mc.Arguments.Count);
+ for (int i = 0; i < old_mc.Arguments.Count; i++) {
+ var bv = old_mc.Arguments[i];
+ MatchCaseToken mcToken;
+ if (!(bv.tok is MatchCaseToken)) {
+ // create a MatchCaseToken
+ mcToken = new MatchCaseToken(bv.tok);
+ // clone the bv but with the MatchCaseToken
+ var bvNew = new BoundVar(mcToken, bv.Name, bv.Type);
+ bvNew.IsGhost = bv.IsGhost;
+ arguments.Add(bvNew);
+ } else {
+ mcToken = (MatchCaseToken)bv.tok;
+ arguments.Add(bv);
+ }
+ mcToken.AddVar(bv.tok, bv, true);
+ mcToken.AddVar(mc.Arguments[i].tok, mc.Arguments[i], true);
+ }
+ old_mc.Arguments = arguments;
thingsChanged = true;
}
} else {
@@ -5610,7 +5839,9 @@ namespace Microsoft.Dafny
// what if match body already has the bv?? need to make a new bv
Type type = new InferredTypeProxy();
string name = FreshTempVarName("_mc#", codeContext);
- BoundVar bv = new BoundVar(one.tok, name, type);
+ BoundVar bv = new BoundVar(new MatchCaseToken(one.tok), name, type);
+ ((MatchCaseToken)bv.tok).AddVar(bv1.tok, bv1, true);
+ ((MatchCaseToken)bv.tok).AddVar(bv2.tok, bv2, true);
SubstituteMatchCaseBoundVar(one, bv1, bv);
SubstituteMatchCaseBoundVar(other, bv2, bv);
}
@@ -6105,8 +6336,8 @@ namespace Microsoft.Dafny
} else if (prev != null) {
Error(lnode.Tok, "label shadows an enclosing label");
} else {
- bool b = labeledStatements.Push(lnode.Name, ss);
- Contract.Assert(b); // since we just checked for duplicates, we expect the Push to succeed
+ var r = labeledStatements.Push(lnode.Name, ss);
+ Contract.Assert(r == Scope<Statement>.PushResult.Success); // since we just checked for duplicates, we expect the Push to succeed
if (l == ss.Labels) { // add it only once
inSpecOnlyContext.Add(ss, specContextOnly);
}
@@ -7444,9 +7675,7 @@ namespace Microsoft.Dafny
// Check for duplicate names now, because not until after resolving the case pattern do we know if identifiers inside it refer to bound variables or nullary constructors
var c = 0;
foreach (var v in lhs.Vars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate let-variable name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "let-variable");
c++;
}
if (c == 0) {
@@ -7465,9 +7694,7 @@ namespace Microsoft.Dafny
foreach (var lhs in e.LHSs) {
Contract.Assert(lhs.Var != null); // the parser already checked that every LHS is a BoundVar, not a general pattern
var v = lhs.Var;
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate let-variable name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "let-variable");
ResolveType(v.tok, v.Type, opts.codeContext, ResolveTypeOptionEnum.InferTypeProxies, null);
}
foreach (var rhs in e.RHSs) {
@@ -7499,9 +7726,7 @@ namespace Microsoft.Dafny
ResolveTypeParameters(e.TypeArgs, true, e);
scope.PushMarker();
foreach (BoundVar v in e.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "bound-variable");
var option = typeQuantifier ? new ResolveTypeOption(e) : new ResolveTypeOption(ResolveTypeOptionEnum.InferTypeProxies);
ResolveType(v.tok, v.Type, opts.codeContext, option, typeQuantifier ? e.TypeArgs : null);
}
@@ -7555,9 +7780,7 @@ namespace Microsoft.Dafny
int prevErrorCount = ErrorCount;
scope.PushMarker();
foreach (BoundVar v in e.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "bound-variable");
ResolveType(v.tok, v.Type, opts.codeContext, ResolveTypeOptionEnum.InferTypeProxies, null);
}
ResolveExpression(e.Range, opts);
@@ -7586,9 +7809,7 @@ namespace Microsoft.Dafny
Error(e.tok, "a map comprehension must have exactly one bound variable.");
}
foreach (BoundVar v in e.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "bound-variable");
ResolveType(v.tok, v.Type, opts.codeContext, ResolveTypeOptionEnum.InferTypeProxies, null);
}
ResolveExpression(e.Range, opts);
@@ -7621,9 +7842,7 @@ namespace Microsoft.Dafny
int prevErrorCount = ErrorCount;
scope.PushMarker();
foreach (BoundVar v in e.BoundVars) {
- if (!scope.Push(v.Name, v)) {
- Error(v, "Duplicate bound-variable name: {0}", v.Name);
- }
+ ScopePushAndReport(scope, v, "bound-variable");
ResolveType(v.tok, v.Type, opts.codeContext, ResolveTypeOptionEnum.InferTypeProxies, null);
}
@@ -7722,7 +7941,7 @@ namespace Microsoft.Dafny
// convert CasePattern in MatchCaseExpr to BoundVar and flatten the MatchCaseExpr.
Type type = new InferredTypeProxy();
string name = FreshTempVarName("_mc#", opts.codeContext);
- BoundVar bv = new BoundVar(me.tok, name, type);
+ BoundVar bv = new BoundVar(new MatchCaseToken(me.tok), name, type);
List<CasePattern> patternSubst = new List<CasePattern>();
if (dtd != null) {
DesugarMatchCaseExpr(me, dtd, bv, patternSubst, opts.codeContext);
@@ -7762,6 +7981,14 @@ namespace Microsoft.Dafny
Error(expr, "the declared type of the formal ({0}) does not agree with the corresponding type in the constructor's signature ({1})", v.Type, st);
}
v.IsGhost = formal.IsGhost;
+
+ // update the type of the boundvars in the MatchCaseToken
+ if (v.tok is MatchCaseToken) {
+ MatchCaseToken mt = (MatchCaseToken)v.tok;
+ foreach (Tuple<IToken, BoundVar, bool> entry in mt.varList) {
+ UnifyTypes(entry.Item2.Type, v.Type);
+ }
+ }
}
i++;
}
@@ -7959,7 +8186,7 @@ namespace Microsoft.Dafny
// case Cons(y, #mc#) => match #mc#
// case Cons(z, zs) => body
- Expression source = new NameSegment(pat.tok, v.Name, null);
+ Expression source = new NameSegment(new AutoGeneratedToken(pat.tok), v.Name, null);
List<MatchCaseExpr> cases = new List<MatchCaseExpr>();
cases.Add(new MatchCaseExpr(pat.tok, pat.Id, pat.Arguments == null ? new List<CasePattern>() : pat.Arguments, mc.Body));
MatchExpr e = new MatchExpr(pat.tok, source, cases, false);
@@ -7989,6 +8216,27 @@ namespace Microsoft.Dafny
foreach (MatchCaseExpr c in current.Cases) {
old.Cases.Add(c);
}
+ // add the token from mc to old_mc so the identifiers will show correctly in the IDE
+ List<BoundVar> arguments = new List<BoundVar>();
+ Contract.Assert(old_mc.Arguments.Count == mc.Arguments.Count);
+ for (int i = 0; i < old_mc.Arguments.Count; i++) {
+ var bv = old_mc.Arguments[i];
+ MatchCaseToken mcToken;
+ if (!(bv.tok is MatchCaseToken)) {
+ // create a MatchCaseToken
+ mcToken = new MatchCaseToken(bv.tok);
+ // clone the bv but with the MatchCaseToken
+ var bvNew = new BoundVar(mcToken, bv.Name, bv.Type);
+ bvNew.IsGhost = bv.IsGhost;
+ arguments.Add(bvNew);
+ } else {
+ mcToken = (MatchCaseToken)bv.tok;
+ arguments.Add(bv);
+ }
+ mcToken.AddVar(bv.tok, bv, true);
+ mcToken.AddVar(mc.Arguments[i].tok, mc.Arguments[i], true);
+ }
+ old_mc.Arguments = arguments;
thingsChanged = true;
} else {
// duplicate cases, do nothing for now. The error will be reported during resolving
@@ -8001,6 +8249,7 @@ namespace Microsoft.Dafny
return thingsChanged;
}
+
bool SameMatchCaseExpr(MatchCaseExpr one, MatchCaseExpr other, ICodeContext codeContext) {
// this method is called after all the CasePattern in the match cases are converted
// into BoundVars.
@@ -8032,7 +8281,11 @@ namespace Microsoft.Dafny
// what if match body already has the bv?? need to make a new bv
Type type = new InferredTypeProxy();
string name = FreshTempVarName("_mc#", codeContext);
- BoundVar bv = new BoundVar(one.tok, name, type);
+ MatchCaseToken mcToken = new MatchCaseToken(one.tok);
+ BoundVar bv = new BoundVar(mcToken, name, type);
+ mcToken.AddVar(bv1.tok, bv1, true);
+ mcToken.AddVar(bv2.tok, bv2, true);
+ // substitute the appeareance of old bv with the new bv in the match case
SubstituteMatchCaseBoundVar(one, bv1, bv);
SubstituteMatchCaseBoundVar(other, bv2, bv);
}
@@ -8338,12 +8591,6 @@ namespace Microsoft.Dafny
r = ResolveExprDotCall(expr.tok, receiver, member, expr.OptTypeArguments, opts.codeContext, allowMethodCall);
}
#endif
- } else if (option.Opt == ResolveTypeOptionEnum.AllowPrefixExtend && expr.OptTypeArguments == null) {
- // it woulc plausibly be a type parameter, but isn't; we will declare it automatically
- tp = new TypeParameter(expr.tok, expr.Name, defaultTypeArguments.Count, option.Parent);
- defaultTypeArguments.Add(tp);
- r = new Resolver_IdentifierExpr(expr.tok, tp);
- allTypeParameters.Push(expr.Name, tp);
} else {
// ----- None of the above
Error(expr.tok, "Undeclared top-level type or type parameter: {0} (did you forget to qualify a name?)", expr.Name);
@@ -10314,17 +10561,27 @@ namespace Microsoft.Dafny
}
}
- // Pushes name-->thing association and returns "true", if name has not already been pushed since the last marker.
- // If name already has been pushed since the last marker, does nothing and returns "false".
- public bool Push(string name, Thing thing) {
+ public enum PushResult { Duplicate, Shadow, Success }
+
+ /// <summary>
+ /// Pushes name-->thing association and returns "Success", if name has not already been pushed since the last marker.
+ /// If name already has been pushed since the last marker, does nothing and returns "Duplicate".
+ /// If the appropriate command-line option is supplied, then this method will also check if "name" shadows a previous
+ /// name; if it does, then it will return "Shadow" instead of "Success".
+ /// </summary>
+ public PushResult Push(string name, Thing thing) {
Contract.Requires(name != null);
Contract.Requires(thing != null);
if (Find(name, true) != null) {
- return false;
+ return PushResult.Duplicate;
} else {
+ var r = PushResult.Success;
+ if (DafnyOptions.O.WarnShadowing && Find(name, false) != null) {
+ r = PushResult.Shadow;
+ }
names.Add(name);
things.Add(thing);
- return true;
+ return r;
}
}
diff --git a/Source/Dafny/Rewriter.cs b/Source/Dafny/Rewriter.cs
index 480b3f61..d6f54aa7 100644
--- a/Source/Dafny/Rewriter.cs
+++ b/Source/Dafny/Rewriter.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using Bpl = Microsoft.Boogie;
+using IToken = Microsoft.Boogie.IToken;
namespace Microsoft.Dafny
{
@@ -1169,10 +1170,10 @@ namespace Microsoft.Dafny
}
public override BoundVar CloneBoundVar(BoundVar bv) {
- // replace bv with this.var is bv == oldvar
+ // replace bv with this.var if bv == oldvar
BoundVar bvNew;
if (oldvar != null && bv.Name.Equals(oldvar.Name)) {
- bvNew = new BoundVar(Tok(bv.tok), oldvar.Name, CloneType(bv.Type));
+ bvNew = new BoundVar(new AutoGeneratedToken(bv.tok), var.Name, CloneType(bv.Type));
} else {
bvNew = new BoundVar(Tok(bv.tok), bv.Name, CloneType(bv.Type));
}
@@ -1183,7 +1184,7 @@ namespace Microsoft.Dafny
public override NameSegment CloneNameSegment(Expression expr) {
var e = (NameSegment)expr;
if (oldvar != null && e.Name.Equals(oldvar.Name)) {
- return new NameSegment(Tok(e.tok), var.Name, e.OptTypeArguments == null ? null : e.OptTypeArguments.ConvertAll(CloneType));
+ return new NameSegment(new AutoGeneratedToken(e.tok), var.Name, e.OptTypeArguments == null ? null : e.OptTypeArguments.ConvertAll(CloneType));
} else {
return new NameSegment(Tok(e.tok), e.Name, e.OptTypeArguments == null ? null : e.OptTypeArguments.ConvertAll(CloneType));
}
@@ -1191,14 +1192,22 @@ namespace Microsoft.Dafny
public override Expression CloneApplySuffix(ApplySuffix e) {
// if the ApplySuffix matches the CasePattern, then replace it with the BoundVar.
- if (FindMatchingPattern(e)) {
- return new NameSegment(e.tok, this.var.Name, null);
+ CasePattern cp = null;
+ if (FindMatchingPattern(e, out cp)) {
+ if (this.var.tok is MatchCaseToken) {
+ Contract.Assert(e.Args.Count == cp.Arguments.Count);
+ for (int i = 0; i < e.Args.Count; i++) {
+ ((MatchCaseToken)this.var.tok).AddVar(e.Args[i].tok, cp.Arguments[i].Var, false);
+ }
+ }
+ return new NameSegment(new AutoGeneratedToken(e.tok), this.var.Name, null);
} else {
return new ApplySuffix(Tok(e.tok), CloneExpr(e.Lhs), e.Args.ConvertAll(CloneExpr));
}
}
- private bool FindMatchingPattern(ApplySuffix e) {
+ private bool FindMatchingPattern(ApplySuffix e, out CasePattern pattern) {
+ pattern = null;
if (patternSubst == null) {
return false;
}
@@ -1226,12 +1235,37 @@ namespace Microsoft.Dafny
}
}
if (found) {
+ pattern = cp;
return true;
}
}
return false;
}
}
+
+ // MatchCaseToken is used to record BoundVars that are consolidated due to rewrite of
+ // nested match patterns. We want to record the original BoundVars that are consolidated
+ // so that they will show up in the IDE correctly.
+ public class MatchCaseToken : AutoGeneratedToken
+ {
+ public readonly List<Tuple<IToken, BoundVar, bool>> varList;
+ public MatchCaseToken(IToken tok)
+ : base(tok) {
+ varList = new List<Tuple<IToken, BoundVar, bool>>();
+ }
+
+ public void AddVar(IToken tok, BoundVar var, bool isDefinition) {
+ varList.Add(new Tuple<IToken, BoundVar, bool>(tok, var, isDefinition));
+ }
+ }
+
+ // A cloner that replace the original token with AutoGeneratedToken.
+ class AutoGeneratedTokenCloner : Cloner
+ {
+ public override IToken Tok(IToken tok) {
+ return new AutoGeneratedToken(tok);
+ }
+ }
}
diff --git a/Source/Dafny/Scanner.cs b/Source/Dafny/Scanner.cs
index 4c5eedb4..325a2f2c 100644
--- a/Source/Dafny/Scanner.cs
+++ b/Source/Dafny/Scanner.cs
@@ -211,8 +211,8 @@ public class UTF8Buffer: Buffer {
public class Scanner {
const char EOL = '\n';
const int eofSym = 0; /* pdt */
- const int maxT = 137;
- const int noSym = 137;
+ const int maxT = 138;
+ const int noSym = 138;
[ContractInvariantMethod]
@@ -537,53 +537,54 @@ public class Scanner {
case "include": t.kind = 59; break;
case "abstract": t.kind = 60; break;
case "module": t.kind = 61; break;
- case "refines": t.kind = 62; break;
- case "import": t.kind = 63; break;
- case "opened": t.kind = 64; break;
- case "as": t.kind = 66; break;
- case "default": t.kind = 67; break;
- case "class": t.kind = 68; break;
- case "extends": t.kind = 69; break;
- case "trait": t.kind = 70; break;
- case "ghost": t.kind = 71; break;
- case "static": t.kind = 72; break;
- case "protected": t.kind = 73; break;
- case "datatype": t.kind = 74; break;
- case "codatatype": t.kind = 75; break;
- case "var": t.kind = 76; break;
- case "newtype": t.kind = 77; break;
- case "type": t.kind = 78; break;
- case "iterator": t.kind = 79; break;
- case "yields": t.kind = 80; break;
- case "returns": t.kind = 81; break;
- case "method": t.kind = 82; break;
- case "colemma": t.kind = 83; break;
- case "comethod": t.kind = 84; break;
- case "constructor": t.kind = 85; break;
- case "free": t.kind = 86; break;
- case "ensures": t.kind = 87; break;
- case "yield": t.kind = 88; break;
- case "label": t.kind = 90; break;
- case "break": t.kind = 91; break;
- case "where": t.kind = 92; break;
- case "return": t.kind = 94; break;
- case "new": t.kind = 96; break;
- case "if": t.kind = 97; break;
- case "while": t.kind = 98; break;
- case "match": t.kind = 99; break;
- case "assert": t.kind = 100; break;
- case "print": t.kind = 101; break;
- case "forall": t.kind = 102; break;
- case "parallel": t.kind = 103; break;
- case "modify": t.kind = 104; break;
- case "exists": t.kind = 123; break;
- case "in": t.kind = 125; break;
- case "false": t.kind = 130; break;
- case "true": t.kind = 131; break;
- case "null": t.kind = 132; break;
- case "this": t.kind = 133; break;
- case "fresh": t.kind = 134; break;
- case "old": t.kind = 135; break;
+ case "exclusively": t.kind = 62; break;
+ case "refines": t.kind = 63; break;
+ case "import": t.kind = 64; break;
+ case "opened": t.kind = 65; break;
+ case "as": t.kind = 67; break;
+ case "default": t.kind = 68; break;
+ case "class": t.kind = 69; break;
+ case "extends": t.kind = 70; break;
+ case "trait": t.kind = 71; break;
+ case "ghost": t.kind = 72; break;
+ case "static": t.kind = 73; break;
+ case "protected": t.kind = 74; break;
+ case "datatype": t.kind = 75; break;
+ case "codatatype": t.kind = 76; break;
+ case "var": t.kind = 77; break;
+ case "newtype": t.kind = 78; break;
+ case "type": t.kind = 79; break;
+ case "iterator": t.kind = 80; break;
+ case "yields": t.kind = 81; break;
+ case "returns": t.kind = 82; break;
+ case "method": t.kind = 83; break;
+ case "colemma": t.kind = 84; break;
+ case "comethod": t.kind = 85; break;
+ case "constructor": t.kind = 86; break;
+ case "free": t.kind = 87; break;
+ case "ensures": t.kind = 88; break;
+ case "yield": t.kind = 89; break;
+ case "label": t.kind = 91; break;
+ case "break": t.kind = 92; break;
+ case "where": t.kind = 93; break;
+ case "return": t.kind = 95; break;
+ case "new": t.kind = 97; break;
+ case "if": t.kind = 98; break;
+ case "while": t.kind = 99; break;
+ case "match": t.kind = 100; break;
+ case "assert": t.kind = 101; break;
+ case "print": t.kind = 102; break;
+ case "forall": t.kind = 103; break;
+ case "parallel": t.kind = 104; break;
+ case "modify": t.kind = 105; break;
+ case "exists": t.kind = 124; break;
+ case "in": t.kind = 126; break;
+ case "false": t.kind = 131; break;
+ case "true": t.kind = 132; break;
+ case "null": t.kind = 133; break;
+ case "this": t.kind = 134; break;
+ case "fresh": t.kind = 135; break;
+ case "old": t.kind = 136; break;
default: break;
}
}
@@ -844,52 +845,52 @@ public class Scanner {
else if (ch >= '0' && ch <= '9') {AddCh(); goto case 65;}
else {t.kind = 5; break;}
case 66:
- {t.kind = 89; break;}
+ {t.kind = 90; break;}
case 67:
- {t.kind = 93; break;}
+ {t.kind = 94; break;}
case 68:
- {t.kind = 95; break;}
+ {t.kind = 96; break;}
case 69:
- {t.kind = 105; break;}
+ {t.kind = 106; break;}
case 70:
- {t.kind = 107; break;}
- case 71:
{t.kind = 108; break;}
- case 72:
+ case 71:
{t.kind = 109; break;}
- case 73:
+ case 72:
{t.kind = 110; break;}
- case 74:
+ case 73:
{t.kind = 111; break;}
- case 75:
+ case 74:
{t.kind = 112; break;}
- case 76:
+ case 75:
{t.kind = 113; break;}
+ case 76:
+ {t.kind = 114; break;}
case 77:
- {t.kind = 115; break;}
+ {t.kind = 116; break;}
case 78:
if (ch == '&') {AddCh(); goto case 79;}
else {goto case 0;}
case 79:
- {t.kind = 116; break;}
- case 80:
{t.kind = 117; break;}
- case 81:
+ case 80:
{t.kind = 118; break;}
- case 82:
+ case 81:
{t.kind = 119; break;}
+ case 82:
+ {t.kind = 120; break;}
case 83:
- {t.kind = 121; break;}
- case 84:
{t.kind = 122; break;}
+ case 84:
+ {t.kind = 123; break;}
case 85:
- {t.kind = 124; break;}
+ {t.kind = 125; break;}
case 86:
- {t.kind = 126; break;}
+ {t.kind = 127; break;}
case 87:
- {t.kind = 128; break;}
- case 88:
{t.kind = 129; break;}
+ case 88:
+ {t.kind = 130; break;}
case 89:
recEnd = pos; recKind = 21;
if (ch == ':') {AddCh(); goto case 30;}
@@ -905,14 +906,14 @@ public class Scanner {
if (ch == '.') {AddCh(); goto case 97;}
else {t.kind = 26; break;}
case 92:
- recEnd = pos; recKind = 65;
+ recEnd = pos; recKind = 66;
if (ch == '>') {AddCh(); goto case 33;}
else if (ch == '=') {AddCh(); goto case 98;}
- else {t.kind = 65; break;}
+ else {t.kind = 66; break;}
case 93:
- recEnd = pos; recKind = 127;
+ recEnd = pos; recKind = 128;
if (ch == '>') {AddCh(); goto case 34;}
- else {t.kind = 127; break;}
+ else {t.kind = 128; break;}
case 94:
recEnd = pos; recKind = 51;
if (ch == '=') {AddCh(); goto case 99;}
@@ -922,26 +923,26 @@ public class Scanner {
if (ch == '=') {AddCh(); goto case 70;}
else {t.kind = 52; break;}
case 96:
- recEnd = pos; recKind = 120;
+ recEnd = pos; recKind = 121;
if (ch == '=') {AddCh(); goto case 41;}
else if (ch == 'i') {AddCh(); goto case 44;}
- else {t.kind = 120; break;}
+ else {t.kind = 121; break;}
case 97:
- recEnd = pos; recKind = 136;
+ recEnd = pos; recKind = 137;
if (ch == '.') {AddCh(); goto case 47;}
- else {t.kind = 136; break;}
+ else {t.kind = 137; break;}
case 98:
recEnd = pos; recKind = 53;
if (ch == '>') {AddCh(); goto case 75;}
else {t.kind = 53; break;}
case 99:
- recEnd = pos; recKind = 106;
+ recEnd = pos; recKind = 107;
if (ch == '=') {AddCh(); goto case 100;}
- else {t.kind = 106; break;}
+ else {t.kind = 107; break;}
case 100:
- recEnd = pos; recKind = 114;
+ recEnd = pos; recKind = 115;
if (ch == '>') {AddCh(); goto case 73;}
- else {t.kind = 114; break;}
+ else {t.kind = 115; break;}
}
t.val = new String(tval, 0, tlen);
diff --git a/Source/Dafny/SccGraph.cs b/Source/Dafny/SccGraph.cs
index 01a72fc5..20b4f65e 100644
--- a/Source/Dafny/SccGraph.cs
+++ b/Source/Dafny/SccGraph.cs
@@ -6,8 +6,8 @@ namespace Microsoft.Dafny {
public class Graph<Node> where Node : class
{
- enum VisitedStatus { Unvisited, OnStack, Visited }
- class Vertex {
+ public enum VisitedStatus { Unvisited, OnStack, Visited }
+ public class Vertex {
public readonly Node N;
public readonly List<Vertex/*!*/>/*!*/ Successors = new List<Vertex/*!*/>();
public List<Vertex/*!*/> SccMembers; // non-null only for the representative of the SCC
@@ -65,6 +65,10 @@ namespace Microsoft.Dafny {
{
}
+ public IEnumerable<Vertex> GetVertices() {
+ return vertices.Values;
+ }
+
/// <summary>
/// Idempotently adds a vertex 'n' to the graph.
/// </summary>
@@ -97,7 +101,7 @@ namespace Microsoft.Dafny {
/// <summary>
/// Returns the vertex for 'n' if 'n' is in the graph. Otherwise, returns null.
/// </summary>
- Vertex FindVertex(Node n) {
+ public Vertex FindVertex(Node n) {
Vertex v;
if (vertices.TryGetValue(n, out v)) {
Contract.Assert(v != null); // follows from postcondition of TryGetValue (since 'vertices' maps to the type Vertex!)
diff --git a/Source/Dafny/Translator.cs b/Source/Dafny/Translator.cs
index 4d35549c..e295d25a 100644
--- a/Source/Dafny/Translator.cs
+++ b/Source/Dafny/Translator.cs
@@ -114,6 +114,7 @@ namespace Microsoft.Dafny {
readonly Dictionary<string, Bpl.Constant> fieldConstants = new Dictionary<string,Constant>();
readonly ISet<string> abstractTypes = new HashSet<string>();
readonly ISet<string> opaqueTypes = new HashSet<string>();
+ FuelContext fuelContext = null;
Program program;
[ContractInvariantMethod]
@@ -625,6 +626,11 @@ namespace Microsoft.Dafny {
}
void AddTypeDecl(NewtypeDecl dd) {
Contract.Requires(dd != null);
+ Contract.Ensures(fuelContext == Contract.OldValue(fuelContext));
+
+ FuelContext oldFuelContext = this.fuelContext;
+ this.fuelContext = FuelSetting.NewFuelContext(dd);
+
AddTypeDecl_Aux(dd.tok, dd.FullName, new List<TypeParameter>());
AddWellformednessCheck(dd);
// Add $Is and $IsAlloc axioms for the newtype
@@ -668,6 +674,7 @@ namespace Microsoft.Dafny {
sink.AddTopLevelDeclaration(new Bpl.Axiom(dd.tok, BplForall(vars, BplTrigger(is_o), body), name));
});
+ this.fuelContext = oldFuelContext;
}
void AddTypeDecl_Aux(IToken tok, string nm, List<TypeParameter> typeArgs) {
Contract.Requires(tok != null);
@@ -1193,7 +1200,7 @@ namespace Microsoft.Dafny {
}
}
- Bpl.Expr LayerSucc(Bpl.Expr e, int amt = 1) {
+ public Bpl.Expr LayerSucc(Bpl.Expr e, int amt = 1) {
if (amt == 0) {
return e;
} else if (amt > 0) {
@@ -1313,6 +1320,7 @@ namespace Microsoft.Dafny {
{
Contract.Requires(sink != null && predef != null);
Contract.Requires(c != null);
+ Contract.Ensures(fuelContext == Contract.OldValue(fuelContext));
sink.AddTopLevelDeclaration(GetClass(c));
if (c is ArrayClassDecl) {
@@ -1399,6 +1407,9 @@ namespace Microsoft.Dafny {
} else if (member is Function) {
var f = (Function)member;
+ FuelContext oldFuelContext = this.fuelContext;
+ this.fuelContext = FuelSetting.NewFuelContext(f);
+
AddClassMember_Function(f);
if (!IsOpaqueFunction(f) && !f.IsBuiltin && !(f.tok is IncludeToken)) { // Opaque function's well-formedness is checked on the full version
AddWellformednessCheck(f);
@@ -1411,9 +1422,11 @@ namespace Microsoft.Dafny {
AddClassMember_Function(cop.PrefixPredicate);
// skip the well-formedness check, because it has already been done for the fixpoint-predicate
}
-
+ this.fuelContext = oldFuelContext;
} else if (member is Method) {
Method m = (Method)member;
+ FuelContext oldFuelContext = this.fuelContext;
+ this.fuelContext = FuelSetting.NewFuelContext(m);
// wellformedness check for method specification
if (m.EnclosingClass is IteratorDecl && m == ((IteratorDecl)m.EnclosingClass).Member_MoveNext) {
@@ -1446,7 +1459,7 @@ namespace Microsoft.Dafny {
sink.AddTopLevelDeclaration(proc);
AddMethodImpl(m, proc, false);
}
-
+ this.fuelContext = oldFuelContext;
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member
}
@@ -1479,7 +1492,7 @@ namespace Microsoft.Dafny {
// declare function
AddFunction(f);
// add synonym axiom
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
AddSynonymAxiom(f);
}
// add frame axiom
@@ -1506,6 +1519,10 @@ namespace Microsoft.Dafny {
void AddIteratorSpecAndBody(IteratorDecl iter) {
Contract.Requires(iter != null);
+ Contract.Ensures(fuelContext == Contract.OldValue(fuelContext));
+
+ FuelContext oldFuelContext = this.fuelContext;
+ this.fuelContext = FuelSetting.NewFuelContext(iter);
// wellformedness check for method specification
Bpl.Procedure proc = AddIteratorProc(iter, MethodTranslationKind.SpecWellformedness);
@@ -1518,6 +1535,7 @@ namespace Microsoft.Dafny {
// ...and its implementation
AddIteratorImpl(iter, proc);
}
+ this.fuelContext = oldFuelContext;
}
Bpl.Procedure AddIteratorProc(IteratorDecl iter, MethodTranslationKind kind) {
@@ -1962,7 +1980,7 @@ namespace Microsoft.Dafny {
var formals = MkTyParamBinders(GetTypeParams(f), out tyargs);
var args = new List<Bpl.Expr>();
Bpl.BoundVariable layer;
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
layer = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$ly", predef.LayerType));
formals.Add(layer);
// Note, "layer" is not added to "args" here; rather, that's done below, as needed
@@ -2133,7 +2151,7 @@ namespace Microsoft.Dafny {
var formals = MkTyParamBinders(GetTypeParams(f), out tyargs);
Bpl.BoundVariable layer;
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
layer = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$ly", predef.LayerType));
formals.Add(layer);
// Note, "layer" is not added to "args" here; rather, that's done below, as needed
@@ -2188,13 +2206,6 @@ namespace Microsoft.Dafny {
foreach (Expression req in f.Req) {
pre = BplAnd(pre, etran.TrExpr(Substitute(req, null, substMap)));
}
- // useViaContext: (mh != ModuleContextHeight || fh != FunctionContextHeight)
- ModuleDefinition mod = f.EnclosingClass.Module;
- Bpl.Expr useViaContext = visibility == FunctionAxiomVisibility.ForeignModuleOnly ? (Bpl.Expr)Bpl.Expr.True :
- Bpl.Expr.Neq(Bpl.Expr.Literal(mod.CallGraph.GetSCCRepresentativeId(f)), etran.FunctionContextHeight());
-
- // ante := (useViaContext && typeAnte && pre)
- ante = BplAnd(useViaContext, BplAnd(ante, pre));
// Add the precondition function and its axiom (which is equivalent to the ante)
if (body == null || (visibility == FunctionAxiomVisibility.IntraModuleOnly && lits == null)) {
@@ -2207,14 +2218,21 @@ namespace Microsoft.Dafny {
}
var appl = FunctionCall(f.tok, RequiresName(f), Bpl.Type.Bool,
formals.ConvertAll(x => (Bpl.Expr)(new Bpl.IdentifierExpr(f.tok, x))));
- sink.AddTopLevelDeclaration(new Axiom(f.tok, BplForall(formals, BplTrigger(appl), Bpl.Expr.Eq(appl, ante))));
- // you could use it to check that it always works, but it makes VSI-Benchmarks/b3.dfy time out:
- // ante = appl;
+ // axiom (forall params :: { f#requires(params) } ante ==> f#requires(params) == pre);
+ sink.AddTopLevelDeclaration(new Axiom(f.tok, BplForall(formals, BplTrigger(appl),
+ BplImp(ante, Bpl.Expr.Eq(appl, pre)))));
if (body == null) {
return null;
}
}
+ // useViaContext: (mh != ModuleContextHeight || fh != FunctionContextHeight)
+ ModuleDefinition mod = f.EnclosingClass.Module;
+ Bpl.Expr useViaContext = visibility == FunctionAxiomVisibility.ForeignModuleOnly ? (Bpl.Expr)Bpl.Expr.True :
+ Bpl.Expr.Neq(Bpl.Expr.Literal(mod.CallGraph.GetSCCRepresentativeId(f)), etran.FunctionContextHeight());
+ // ante := (useViaContext && typeAnte && pre)
+ ante = BplAnd(useViaContext, BplAnd(ante, pre));
+
// useViaCanCall: f#canCall(args)
Bpl.IdentifierExpr canCallFuncID = new Bpl.IdentifierExpr(f.tok, f.FullSanitizedName + "#canCall", Bpl.Type.Bool);
Bpl.Expr useViaCanCall = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(canCallFuncID), Concat(tyargs,args));
@@ -2329,7 +2347,7 @@ namespace Microsoft.Dafny {
void AddSynonymAxiom(Function f) {
Contract.Requires(f != null);
- Contract.Requires(f.IsRecursive);
+ Contract.Requires(f.IsFuelAware());
Contract.Requires(sink != null && predef != null);
// axiom // layer synonym axiom
// (forall s, $Heap, formals ::
@@ -2412,7 +2430,7 @@ namespace Microsoft.Dafny {
var coArgs = new List<Bpl.Expr>(tyexprs);
var prefixArgs = new List<Bpl.Expr>(tyexprs);
var prefixArgsLimited = new List<Bpl.Expr>(tyexprs);
- if (pp.IsRecursive) {
+ if (pp.IsFuelAware()) {
var sV = new Bpl.BoundVariable(tok, new Bpl.TypedIdent(tok, "$ly", predef.LayerType));
var s = new Bpl.IdentifierExpr(tok, sV);
var succS = FunctionCall(tok, BuiltinFunction.LayerSucc, null, s);
@@ -3012,7 +3030,7 @@ namespace Microsoft.Dafny {
AddFunctionOverrideReqsChk(f, builder, etran, substMap);
//adding assert R <= Rank’;
- AddFunctionOverrideTerminationChk(f, builder, etran, substMap);
+ AddOverrideTerminationChk(f, f.OverriddenFunction, builder, etran, substMap);
//adding assert W <= Frame’
AddFunctionOverrideSubsetChk(f, builder, etran, localVariables, substMap);
@@ -3085,13 +3103,13 @@ namespace Microsoft.Dafny {
Bpl.FunctionCall funcIdT = new Bpl.FunctionCall(new Bpl.IdentifierExpr(f.OverriddenFunction.tok, f.OverriddenFunction.FullSanitizedName, TrType(f.OverriddenFunction.ResultType)));
List<Bpl.Expr> argsC = new List<Bpl.Expr>();
List<Bpl.Expr> argsT = new List<Bpl.Expr>();
- if (f.IsRecursive)
+ if (f.IsFuelAware())
{
- argsC.Add(etran.LayerN(1));
+ argsC.Add(etran.layerInterCluster.GetFunctionFuel(f));
}
- if (f.OverriddenFunction.IsRecursive)
+ if (f.OverriddenFunction.IsFuelAware())
{
- argsT.Add(etran.LayerN(1));
+ argsT.Add(etran.layerInterCluster.GetFunctionFuel(f));
}
argsC.Add(etran.HeapExpr);
argsT.Add(etran.HeapExpr);
@@ -3175,35 +3193,6 @@ namespace Microsoft.Dafny {
builder.Add(Assert(tok, q, "expression may read an object not in the parent trait context's reads clause", kv));
}
- private void AddFunctionOverrideTerminationChk(Function f, StmtListBuilder builder, ExpressionTranslator etran, Dictionary<IVariable, Expression> substMap)
- {
- var decrToks = new List<IToken>();
- var decrTypes1 = new List<Type>();
- var decrTypes2 = new List<Type>();
- var decrClass = new List<Expr>();
- var decrTrait = new List<Expr>();
- if (f.Decreases != null)
- {
- foreach (var decC in f.Decreases.Expressions)
- {
- decrToks.Add(decC.tok);
- decrTypes1.Add(decC.Type);
- decrClass.Add(etran.TrExpr(decC));
- }
- }
- if (f.OverriddenFunction.Decreases != null)
- {
- foreach (var decT in f.OverriddenFunction.Decreases.Expressions)
- {
- var decCNew = Substitute(decT, null, substMap);
- decrTypes2.Add(decCNew.Type);
- decrTrait.Add(etran.TrExpr(decCNew));
- }
- }
- var decrChk = DecreasesCheck(decrToks, decrTypes1, decrTypes2, decrClass, decrTrait, null, null, true, false);
- builder.Add(new Bpl.AssertCmd(f.tok, decrChk));
- }
-
private void AddFunctionOverrideReqsChk(Function f, StmtListBuilder builder, ExpressionTranslator etran, Dictionary<IVariable, Expression> substMap)
{
//generating trait pre-conditions with class variables
@@ -3271,7 +3260,7 @@ namespace Microsoft.Dafny {
AddMethodOverrideReqsChk(m, builder, etran, substMap);
//adding assert R <= Rank’;
- AddMethodOverrideTerminationChk(m, builder, etran, substMap);
+ AddOverrideTerminationChk(m, m.OverriddenMethod, builder, etran, substMap);
//adding assert W <= Frame’
AddMethodOverrideSubsetChk(m, builder, etran, localVariables, substMap);
@@ -3358,14 +3347,15 @@ namespace Microsoft.Dafny {
}
}
- private void AddMethodOverrideTerminationChk(Method m, Bpl.StmtListBuilder builder, ExpressionTranslator etran, Dictionary<IVariable, Expression> substMap) {
- Contract.Requires(m != null);
+ private void AddOverrideTerminationChk(ICallable original, ICallable overryd, Bpl.StmtListBuilder builder, ExpressionTranslator etran, Dictionary<IVariable, Expression> substMap) {
+ Contract.Requires(original != null);
+ Contract.Requires(overryd != null);
Contract.Requires(builder != null);
Contract.Requires(etran != null);
Contract.Requires(substMap != null);
// Note, it is as if the trait's method is calling the class's method.
- var contextDecreases = m.OverriddenMethod.Decreases.Expressions;
- var calleeDecreases = m.Decreases.Expressions;
+ var contextDecreases = overryd.Decreases.Expressions;
+ var calleeDecreases = original.Decreases.Expressions;
// We want to check: calleeDecreases <= contextDecreases (note, we can allow equality, since there is a bounded, namely 1, number of dynamic dispatches)
if (Contract.Exists(contextDecreases, e => e is WildcardExpr)) {
// no check needed
@@ -3386,7 +3376,7 @@ namespace Microsoft.Dafny {
N = i;
break;
}
- toks.Add(new NestedToken(m.tok, e1.tok));
+ toks.Add(new NestedToken(original.Tok, e1.tok));
types0.Add(e0.Type.NormalizeExpand());
types1.Add(e1.Type.NormalizeExpand());
callee.Add(etran.TrExpr(e0));
@@ -3419,7 +3409,7 @@ namespace Microsoft.Dafny {
// as "false".
bool allowNoChange = N == decrCountT && decrCountT <= decrCountC;
var decrChk = DecreasesCheck(toks, types0, types1, callee, caller, null, null, allowNoChange, false);
- builder.Add(Assert(m.tok, decrChk, "method's decreases clause must be below or equal to that in the trait"));
+ builder.Add(Assert(original.Tok, decrChk, string.Format("{0}'s decreases clause must be below or equal to that in the trait", original.WhatKind)));
}
private void AddMethodOverrideSubsetChk(Method m, Bpl.StmtListBuilder builder, ExpressionTranslator etran, List<Variable> localVariables, Dictionary<IVariable, Expression> substMap)
@@ -3738,7 +3728,7 @@ namespace Microsoft.Dafny {
var typeParams = TrTypeParamDecls(f.TypeArgs);
{
var formals = new List<Variable>();
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
formals.Add(new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "$ly", predef.LayerType), true));
}
if (!f.IsStatic) {
@@ -3762,7 +3752,7 @@ namespace Microsoft.Dafny {
List<Bpl.Expr> argsF = new List<Bpl.Expr>();
List<Bpl.Expr> argsFFrame = new List<Bpl.Expr>();
List<Bpl.Expr> argsCanCall = new List<Bpl.Expr>();
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
var sV = new Bpl.BoundVariable(f.tok, new Bpl.TypedIdent(f.tok, "$ly", predef.LayerType));
var s = new Bpl.IdentifierExpr(f.tok, sV);
bvars.Add(sV);
@@ -3837,7 +3827,7 @@ namespace Microsoft.Dafny {
var f1args = new List<Bpl.Expr>(tyexprs);
var f0argsCanCall = new List<Bpl.Expr>(tyexprs);
var f1argsCanCall = new List<Bpl.Expr>(tyexprs);
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
Bpl.Expr s; var sV = BplBoundVar("$ly", predef.LayerType, out s);
bvars.Add(sV);
f0args.Add(s); f1args.Add(s); // but don't add to f0argsCanCall or f1argsCanCall
@@ -4079,8 +4069,8 @@ namespace Microsoft.Dafny {
foreach (var p in GetTypeParams(f)) {
args.Add(trTypeParam(p, null));
}
- if (f.IsRecursive) {
- args.Add(etran.LayerN(1));
+ if (f.IsFuelAware()) {
+ args.Add(etran.layerInterCluster.GetFunctionFuel(f));
}
args.Add(etran.HeapExpr);
if (!f.IsStatic) {
@@ -4113,8 +4103,8 @@ namespace Microsoft.Dafny {
foreach (var p in GetTypeParams(f)) {
args.Add(trTypeParam(p, null));
}
- if (f.IsRecursive) {
- args.Add(etran.LayerN(1));
+ if (f.IsFuelAware()) {
+ args.Add(etran.layerInterCluster.GetFunctionFuel(f));
}
args.Add(etran.HeapExpr);
foreach (Variable p in implInParams) {
@@ -5595,7 +5585,7 @@ namespace Microsoft.Dafny {
tyargs.Add(TypeToTy(fm.Type));
}
tyargs.Add(TypeToTy(f.ResultType));
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
Bpl.Expr ly; vars.Add(BplBoundVar("$ly", predef.LayerType, out ly)); args.Add(ly);
formals.Add(BplFormalVar(null, predef.LayerType, true));
}
@@ -5655,7 +5645,6 @@ namespace Microsoft.Dafny {
{
// Requires(Ty.., F#Handle( Ty1, ..., TyN, Layer, self), Heap, arg1, ..., argN)
// = F#Requires(Ty1, .., TyN, Layer, Heap, self, [Unbox] arg1, .., [Unbox] argN)
- // || Scramble(...)
var fhandle = FunctionCall(f.tok, name, predef.HandleType, SnocSelf(args));
var lhs = FunctionCall(f.tok, Requires(arity), Bpl.Type.Bool, Concat(tyargs, Cons(fhandle, Cons(h, lhs_args))));
@@ -5664,9 +5653,7 @@ namespace Microsoft.Dafny {
// In case this is the /requires/ or /reads/ function, then there is no precondition
rhs = Bpl.Expr.True;
} else {
- rhs = BplOr(
- FunctionCall(f.tok, RequiresName(f), Bpl.Type.Bool, Concat(SnocSelf(Snoc(args, h)), rhs_args)),
- MakeScrambler(f.tok, f.FullSanitizedName + "#lessReq", Concat(vars, bvars)));
+ rhs = FunctionCall(f.tok, RequiresName(f), Bpl.Type.Bool, Concat(SnocSelf(Snoc(args, h)), rhs_args));
}
sink.AddTopLevelDeclaration(new Axiom(f.tok,
@@ -5694,15 +5681,6 @@ namespace Microsoft.Dafny {
return name;
}
- public Bpl.Expr MakeScrambler(IToken tk, string name, List<Variable> bvars) {
- var f = new Bpl.Function(tk, name,
- bvars.ConvertAll(bv => (Bpl.Variable)BplFormalVar(null, bv.TypedIdent.Type, true)),
- BplFormalVar(null, Bpl.Type.Bool, false));
-
- sink.AddTopLevelDeclaration(f);
- return FunctionCall(tk, name, Bpl.Type.Bool, bvars.ConvertAll(bv => (Bpl.Expr)new Bpl.IdentifierExpr(tk, bv)));
- }
-
private void AddArrowTypeAxioms(ArrowTypeDecl ad) {
Contract.Requires(ad != null);
var arity = ad.Arity;
@@ -5748,11 +5726,9 @@ namespace Microsoft.Dafny {
{
// forall t1, .., tN+1 : Ty, p: [Heap, Box, ..., Box] Box, heap : Heap, b1, ..., bN : Box
- // :: RequriesN(...) ==> ApplyN(t1, .. tN+1, HandleN(h, r, rd), heap, b1, ..., bN) = h[heap, b1, ..., bN]
- //
- // no precondition for these, but:
- // for requires, we add: RequiresN(...) <== r[heap, b1, ..., bN]
- // for reads, we could: ReadsN(...)[bx] ==> rd[heap, b1, ..., bN][bx] , but we don't
+ // :: ApplyN(t1, .. tN+1, HandleN(h, r, rd), heap, b1, ..., bN) == h[heap, b1, ..., bN]
+ // :: RequiresN(t1, .. tN+1, HandleN(h, r, rd), heap, b1, ..., bN) <== r[heap, b1, ..., bN]
+ // :: ReadsN(t1, .. tN+1, HandleN(h, r, rd), heap, b1, ..., bN) == rd[heap, b1, ..., bN]
Action<string, Bpl.Type, string, Bpl.Type, string, Bpl.Type> SelectorSemantics = (selector, selectorTy, selectorVar, selectorVarTy, precond, precondTy) => {
Contract.Assert((precond == null) == (precondTy == null));
var bvars = new List<Bpl.Variable>();
@@ -5954,7 +5930,7 @@ namespace Microsoft.Dafny {
var inner_name = GetClass(td).TypedIdent.Name;
string name = "T" + inner_name;
// Create the type constructor
- {
+ if (td.Name != "object") { // the type constructor for "object" is in DafnyPrelude.bpl
Bpl.Variable tyVarOut = BplFormalVar(null, predef.Ty, false);
List<Bpl.Variable> args = new List<Bpl.Variable>(
Enumerable.Range(0, arity).Select(i =>
@@ -6160,7 +6136,7 @@ namespace Microsoft.Dafny {
var typeParams = TrTypeParamDecls(f.TypeArgs);
var formals = new List<Variable>();
formals.AddRange(MkTyParamFormals(GetTypeParams(f)));
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
formals.Add(new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "$ly", predef.LayerType), true));
}
formals.Add(new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "$heap", predef.HeapType), true));
@@ -6271,9 +6247,7 @@ namespace Microsoft.Dafny {
} else {
bool splitHappened; // we actually don't care
foreach (var s in TrSplitExpr(p.E, etran, kind == MethodTranslationKind.InterModuleCall ? 0 : int.MaxValue, true /* kind == MethodTranslationKind.Implementation */, out splitHappened)) {
- if ((kind == MethodTranslationKind.IntraModuleCall || kind == MethodTranslationKind.CoCall) && RefinementToken.IsInherited(s.E.tok, currentModule)) {
- // this precondition was inherited into this module, so just ignore it
- } else if (s.IsOnlyChecked && bodyKind) {
+ if (s.IsOnlyChecked && bodyKind) {
// don't include in split
} else if (s.IsOnlyFree && !bodyKind) {
// don't include in split -- it would be ignored, anyhow
@@ -6520,7 +6494,7 @@ namespace Microsoft.Dafny {
// parameters of the procedure
List<Variable> inParams = new List<Variable>();
Bpl.Formal layer;
- if (f.IsRecursive) {
+ if (f.IsFuelAware()) {
layer = new Bpl.Formal(f.tok, new Bpl.TypedIdent(f.tok, "$ly", predef.LayerType), true);
inParams.Add(layer);
} else {
@@ -7043,7 +7017,9 @@ namespace Microsoft.Dafny {
Contract.Requires(locals != null);
Contract.Requires(etran != null);
Contract.Requires(codeContext != null && predef != null);
+ Contract.Ensures(fuelContext == Contract.OldValue(fuelContext));
if (stmt is PredicateStmt) {
+ this.fuelContext = FuelSetting.ExpandFuelContext(stmt.Attributes, this.fuelContext);
if (stmt is AssertStmt || DafnyOptions.O.DisallowSoundnessCheating) {
AddComment(builder, stmt, "assert statement");
PredicateStmt s = (PredicateStmt)stmt;
@@ -7072,6 +7048,7 @@ namespace Microsoft.Dafny {
TrStmt_CheckWellformed(s.Expr, builder, locals, etran, false);
builder.Add(new Bpl.AssumeCmd(stmt.Tok, etran.TrExpr(s.Expr), etran.TrAttributes(stmt.Attributes, null)));
}
+ this.fuelContext = FuelSetting.PopFuelContext();
} else if (stmt is PrintStmt) {
AddComment(builder, stmt, "print statement");
PrintStmt s = (PrintStmt)stmt;
@@ -7304,6 +7281,7 @@ namespace Microsoft.Dafny {
} else if (stmt is WhileStmt) {
AddComment(builder, stmt, "while statement");
+ this.fuelContext = FuelSetting.ExpandFuelContext(stmt.Attributes, this.fuelContext);
var s = (WhileStmt)stmt;
BodyTranslator bodyTr = null;
if (s.Body != null) {
@@ -7314,7 +7292,7 @@ namespace Microsoft.Dafny {
};
}
TrLoop(s, s.Guard, bodyTr, builder, locals, etran);
-
+ this.fuelContext = FuelSetting.PopFuelContext();
} else if (stmt is AlternativeLoopStmt) {
AddComment(builder, stmt, "alternative loop statement");
var s = (AlternativeLoopStmt)stmt;
@@ -7356,6 +7334,7 @@ namespace Microsoft.Dafny {
} else if (stmt is ForallStmt) {
var s = (ForallStmt)stmt;
+ this.fuelContext = FuelSetting.ExpandFuelContext(stmt.Attributes, this.fuelContext);
if (s.Kind == ForallStmt.ParBodyKind.Assign) {
AddComment(builder, stmt, "forall statement (assign)");
Contract.Assert(s.Ens.Count == 0);
@@ -7399,7 +7378,7 @@ namespace Microsoft.Dafny {
} else {
Contract.Assert(false); // unexpected kind
}
-
+ this.fuelContext = FuelSetting.PopFuelContext();
} else if (stmt is CalcStmt) {
/* Translate into:
if (*) {
@@ -7425,6 +7404,7 @@ namespace Microsoft.Dafny {
var s = (CalcStmt)stmt;
Contract.Assert(s.Steps.Count == s.Hints.Count); // established by the resolver
AddComment(builder, stmt, "calc statement");
+ this.fuelContext = FuelSetting.ExpandFuelContext(stmt.Attributes, this.fuelContext);
CurrentIdGenerator.Push(); // put the entire calc statement within its own sub-branch
if (s.Lines.Count > 0) {
Bpl.IfCmd ifCmd = null;
@@ -7489,7 +7469,7 @@ namespace Microsoft.Dafny {
}
}
CurrentIdGenerator.Pop();
-
+ this.fuelContext = FuelSetting.PopFuelContext();
} else if (stmt is MatchStmt) {
var s = (MatchStmt)stmt;
TrStmt_CheckWellformed(s.Source, builder, locals, etran, true);
@@ -10298,6 +10278,227 @@ namespace Microsoft.Dafny {
}
}
+ internal class FuelSettingPair
+ {
+ public int low;
+ public int high;
+
+ public FuelSettingPair(int low = (int)FuelSetting.FuelAmount.LOW, int high = (int)FuelSetting.FuelAmount.HIGH) {
+ this.low = low;
+ this.high = high;
+ }
+ }
+
+ // C#'s version of a type alias
+ internal class FuelContext : Dictionary<Function, FuelSettingPair> { }
+
+ internal class FuelSetting
+ {
+ public enum FuelAmount { NONE, LOW, HIGH };
+ public static Stack<FuelContext> SavedContexts = new Stack<FuelContext>();
+
+ private static FuelSettingPair FuelAttrib(Function f) {
+ Contract.Requires(f != null);
+ Contract.Ensures(Contract.Result<FuelSettingPair>() != null);
+ FuelSettingPair setting = new FuelSettingPair();
+
+ if (f.Attributes != null) {
+ List<Expression> args = Attributes.FindExpressions(f.Attributes, "fuel");
+ if (args != null && args.Count >= 2) {
+ LiteralExpr literalLow = args[0] as LiteralExpr;
+ LiteralExpr literalHigh = args[1] as LiteralExpr;
+
+ if (literalLow != null && literalLow.Value is BigInteger && literalHigh != null && literalHigh.Value is BigInteger) {
+ setting.low = (int)((BigInteger)literalLow.Value);
+ setting.high = (int)((BigInteger)literalHigh.Value);
+ }
+ } else if (args != null && args.Count >= 1) {
+ LiteralExpr literal = args[0] as LiteralExpr;
+ if (literal != null && literal.Value is BigInteger) {
+ setting.low = (int)((BigInteger)literal.Value);
+ setting.high = setting.low + 1;
+ }
+ }
+ }
+
+ return setting;
+ }
+
+ public int amount; // Amount of fuel above that represented by start
+ private Bpl.Expr start; // Starting fuel argument (null indicates LZ)
+ private Translator translator;
+
+ public FuelSetting(Translator translator, int amount, Bpl.Expr start = null) {
+ this.translator = translator;
+ this.amount = amount;
+ this.start = start;
+ }
+
+ public FuelSetting Offset(int offset) {
+ return new FuelSetting(translator, this.amount + offset, start);
+ }
+
+ public Bpl.Expr LayerZero() {
+ Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
+ return new Bpl.IdentifierExpr(Token.NoToken, "$LZ", translator.predef.LayerType);
+ }
+
+ public Bpl.Expr LayerN(int n) {
+ Contract.Requires(0 <= n);
+ Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
+ return translator.LayerSucc(LayerZero(), n);
+ }
+
+ private Bpl.Expr ToExpr(int amount) {
+ if (start == null) {
+ return LayerN(amount);
+ } else {
+ return translator.LayerSucc(start, amount);
+ }
+ }
+
+ public Bpl.Expr ToExpr() {
+ return this.ToExpr(this.amount);
+ }
+
+ /// <summary>
+ /// Get the fuel value for this function, given the ambient environment (represented by the fuel setting)
+ /// the function itself, and the function call's context (if any)
+ /// </summary>
+ public Bpl.Expr GetFunctionFuel(Function f) {
+ Contract.Requires(f != null);
+ if (this.amount == (int)FuelAmount.NONE) {
+ return this.ToExpr();
+ } else {
+ FuelSettingPair setting = null;
+ var found = translator.fuelContext.TryGetValue(f, out setting);
+
+ if (!found) { // If the context doesn't define fuel for this function, check for a fuel attribute (which supplies a default value if none is found)
+ setting = FuelAttrib(f);
+ }
+
+ if (this.amount == (int)FuelAmount.LOW) {
+ return ToExpr(setting.low);
+ } else if (this.amount == (int)FuelAmount.HIGH) {
+ return ToExpr(setting.high);
+ } else {
+ Contract.Assert(false); // Should not reach here
+ return null;
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Finds all fuel related attributes of the form {:fuel function low [high]}
+ /// Adds the setting to the context _if_ the context does not already have a setting for that function.
+ /// In other words, it should be called in order from most to least specific contenxt scope.
+ /// </summary>
+ private static void FindFuelAttributes(Attributes attribs, FuelContext fuelContext) {
+ Function f = null;
+ FuelSettingPair setting = null;
+
+ if (attribs != null) {
+ List<List<Expression>> results = Attributes.FindAllExpressions(attribs, "fuel");
+
+ if (results != null) {
+ foreach (List<Expression> args in results) {
+ if (args != null && args.Count >= 2) {
+ // Try to extract the function from the first argument
+ MemberSelectExpr selectExpr = args[0].Resolved as MemberSelectExpr;
+ if (selectExpr != null) {
+ f = selectExpr.Member as Function;
+ }
+
+ // Try to extract the lower fuel setting
+ LiteralExpr literalLow = args[1] as LiteralExpr;
+ if (literalLow != null && literalLow.Value is BigInteger) {
+ setting = new FuelSettingPair();
+ setting.low = (int)((BigInteger)literalLow.Value);
+ }
+
+ // The user may supply an additional high argument; if not, it defaults to low + 1
+ if (f != null && args.Count >= 3) {
+ LiteralExpr literalHigh = args[2] as LiteralExpr;
+ if (setting != null && literalHigh != null && literalHigh.Value is BigInteger) {
+ setting.high = (int)((BigInteger)literalHigh.Value);
+ if (!fuelContext.ContainsKey(f)) {
+ fuelContext.Add(f, setting);
+ }
+ }
+ } else if (f != null && setting != null) {
+ setting.high = setting.low + 1;
+ if (!fuelContext.ContainsKey(f)) {
+ fuelContext.Add(f, setting);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Extend the given context with fuel information from the declaration itself, and enclosing modules
+ /// </summary>
+ private static void AddFuelContext(FuelContext context, TopLevelDecl decl) {
+ FindFuelAttributes(decl.Attributes, context);
+
+ var module = decl.Module;
+ while (module != null) {
+ FindFuelAttributes(module.Attributes, context);
+ module = module.Module;
+ }
+ }
+
+ /// <summary>
+ /// Creates a summary of all fuel settings in scope, starting from the given class declaration
+ /// </summary>
+ public static FuelContext NewFuelContext(TopLevelDecl decl) {
+ FuelContext context = new FuelContext();
+ AddFuelContext(context, decl);
+ return context;
+ }
+
+ /// <summary>
+ /// Creates a summary of all fuel settings in scope, starting from the given member declaration
+ /// </summary>
+ public static FuelContext NewFuelContext(MemberDecl decl) {
+ FuelContext context = new FuelContext();
+
+ FindFuelAttributes(decl.Attributes, context);
+ AddFuelContext(context, decl.EnclosingClass);
+
+ return context;
+ }
+
+ /// <summary>
+ /// Extends the given fuel context with any new fuel settings found in attribs
+ /// </summary>
+ public static FuelContext ExpandFuelContext(Attributes attribs, FuelContext oldFuelContext) {
+ Contract.Ensures(SavedContexts.Count == Contract.OldValue(SavedContexts.Count) + 1);
+ FuelContext newContext = new FuelContext();
+ FindFuelAttributes(attribs, newContext);
+ if (newContext.Count > 0) {
+ foreach (var pair in oldFuelContext) {
+ if (!newContext.ContainsKey(pair.Key)) { // Local setting takes precedence over old context
+ newContext.Add(pair.Key, pair.Value);
+ }
+ }
+ } else {
+ newContext = oldFuelContext;
+ }
+ SavedContexts.Push(oldFuelContext);
+ return newContext;
+ }
+
+ public static FuelContext PopFuelContext() {
+ Contract.Requires(SavedContexts.Count > 0);
+ return SavedContexts.Pop();
+ }
+
+ }
+
internal class ExpressionTranslator
{
public readonly Bpl.Expr HeapExpr;
@@ -10306,8 +10507,8 @@ namespace Microsoft.Dafny {
public readonly string This;
public readonly string modifiesFrame; // the name of the context's frame variable.
readonly Function applyLimited_CurrentFunction;
- public readonly Bpl.Expr layerInterCluster;
- public readonly Bpl.Expr layerIntraCluster = null; // a value of null says to do the same as for inter-cluster calls
+ public readonly FuelSetting layerInterCluster;
+ public readonly FuelSetting layerIntraCluster = null; // a value of null says to do the same as for inter-cluster calls
public int Statistics_CustomLayerFunctionCount = 0;
public readonly bool ProducingCoCertificates = false; // CLEMENT Where is this used?
public readonly bool stripLits = false;
@@ -10325,41 +10526,16 @@ namespace Microsoft.Dafny {
}
/// <summary>
- /// This is a general constructor, but takes the layerInterCluster as an int.
- /// </summary>
- ExpressionTranslator(Translator translator, PredefinedDecls predef, Bpl.Expr heap, string thisVar,
- Function applyLimited_CurrentFunction, int layerInterCluster, Bpl.Expr layerIntraCluster, string modifiesFrame, bool stripLits) {
-
- Contract.Requires(translator != null);
- Contract.Requires(predef != null);
- Contract.Requires(heap != null);
- Contract.Requires(thisVar != null);
- Contract.Requires(0 <= layerInterCluster);
- Contract.Requires(modifiesFrame != null);
-
- this.translator = translator;
- this.predef = predef;
- this.HeapExpr = heap;
- this.This = thisVar;
- this.applyLimited_CurrentFunction = applyLimited_CurrentFunction;
- this.layerInterCluster = LayerN(layerInterCluster);
- this.layerIntraCluster = layerIntraCluster;
- this.modifiesFrame = modifiesFrame;
- this.stripLits = stripLits;
- }
-
- /// <summary>
/// This is the most general constructor. It is private and takes all the parameters. Whenever
/// one ExpressionTranslator is constructed from another, unchanged parameters are just copied in.
/// </summary>
ExpressionTranslator(Translator translator, PredefinedDecls predef, Bpl.Expr heap, string thisVar,
- Function applyLimited_CurrentFunction, Bpl.Expr layerInterCluster, Bpl.Expr layerIntraCluster, string modifiesFrame, bool stripLits) {
+ Function applyLimited_CurrentFunction, FuelSetting layerInterCluster, FuelSetting layerIntraCluster, string modifiesFrame, bool stripLits) {
Contract.Requires(translator != null);
Contract.Requires(predef != null);
Contract.Requires(heap != null);
- Contract.Requires(thisVar != null);
- Contract.Requires(layerInterCluster != null);
+ Contract.Requires(thisVar != null);
Contract.Requires(modifiesFrame != null);
this.translator = translator;
@@ -10404,7 +10580,7 @@ namespace Microsoft.Dafny {
}
public ExpressionTranslator(Translator translator, PredefinedDecls predef, Bpl.Expr heap, string thisVar)
- : this(translator, predef, heap, thisVar, null, 1, null, "$_Frame", false) {
+ : this(translator, predef, heap, thisVar, null, new FuelSetting(translator, 1), null, "$_Frame", false) {
Contract.Requires(translator != null);
Contract.Requires(predef != null);
Contract.Requires(heap != null);
@@ -10448,9 +10624,9 @@ namespace Microsoft.Dafny {
Contract.Requires(layerArgument != null);
Contract.Ensures(Contract.Result<ExpressionTranslator>() != null);
- return new ExpressionTranslator(translator, predef, HeapExpr, This, null, layerArgument, layerArgument, modifiesFrame, stripLits);
+ return new ExpressionTranslator(translator, predef, HeapExpr, This, null, new FuelSetting(translator, 0, layerArgument), new FuelSetting(translator, 0, layerArgument), modifiesFrame, stripLits);
}
-
+
public ExpressionTranslator WithNoLits() {
Contract.Ensures(Contract.Result<ExpressionTranslator>() != null);
return new ExpressionTranslator(translator, predef, HeapExpr, This, null, layerInterCluster, layerIntraCluster, modifiesFrame, true);
@@ -10461,16 +10637,16 @@ namespace Microsoft.Dafny {
Contract.Requires(layerArgument != null);
Contract.Ensures(Contract.Result<ExpressionTranslator>() != null);
- return new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, /* layerArgument */ layerInterCluster, layerArgument, modifiesFrame, stripLits);
+ return new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, /* layerArgument */ layerInterCluster, new FuelSetting(translator, 0, layerArgument), modifiesFrame, stripLits);
}
public ExpressionTranslator LayerOffset(int offset) {
Contract.Requires(0 <= offset);
Contract.Ensures(Contract.Result<ExpressionTranslator>() != null);
- var et = new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, translator.LayerSucc(layerInterCluster, offset), layerIntraCluster, modifiesFrame, stripLits);
+ var et = new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, layerInterCluster.Offset(offset), layerIntraCluster, modifiesFrame, stripLits);
if (this.oldEtran != null) {
- var etOld = new ExpressionTranslator(translator, predef, Old.HeapExpr, This, applyLimited_CurrentFunction, translator.LayerSucc(layerInterCluster, offset), layerIntraCluster, modifiesFrame, stripLits);
+ var etOld = new ExpressionTranslator(translator, predef, Old.HeapExpr, This, applyLimited_CurrentFunction, layerInterCluster.Offset(offset), layerIntraCluster, modifiesFrame, stripLits);
etOld.oldEtran = etOld;
et.oldEtran = etOld;
}
@@ -10509,17 +10685,6 @@ namespace Microsoft.Dafny {
}
}
- public Bpl.Expr LayerZero() {
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
- return new Bpl.IdentifierExpr(Token.NoToken, "$LZ", predef.LayerType);
- }
-
- public Bpl.Expr LayerN(int n) {
- Contract.Requires(0 <= n);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
- return translator.LayerSucc(LayerZero(), n);
- }
-
public Bpl.IdentifierExpr ModuleContextHeight() {
Contract.Ensures(Contract.Result<Bpl.IdentifierExpr>().Type != null);
return new Bpl.IdentifierExpr(Token.NoToken, "$ModuleContextHeight", Bpl.Type.Int);
@@ -10701,8 +10866,8 @@ namespace Microsoft.Dafny {
},
fn => {
var args = e.TypeApplication.ConvertAll(translator.TypeToTy);
- if (fn.IsRecursive) {
- args.Add(layerInterCluster);
+ if (fn.IsFuelAware()) {
+ args.Add(this.layerInterCluster.GetFunctionFuel(fn));
}
if (!fn.IsStatic) {
args.Add(/* translator.BoxIfUnboxed */(TrExpr(e.Obj)/*, e.Type */));
@@ -10858,15 +11023,15 @@ namespace Microsoft.Dafny {
} else if (expr is FunctionCallExpr) {
FunctionCallExpr e = (FunctionCallExpr)expr;
Bpl.Expr layerArgument;
- if (e.Function.IsRecursive) {
+ if (e.Function.IsFuelAware()) {
Statistics_CustomLayerFunctionCount++;
ModuleDefinition module = e.Function.EnclosingClass.Module;
if (this.applyLimited_CurrentFunction != null &&
this.layerIntraCluster != null &&
ModuleDefinition.InSameSCC(e.Function, applyLimited_CurrentFunction)) {
- layerArgument = this.layerIntraCluster;
+ layerArgument = this.layerIntraCluster.GetFunctionFuel(e.Function);
} else {
- layerArgument = this.layerInterCluster;
+ layerArgument = this.layerInterCluster.GetFunctionFuel(e.Function);
}
} else {
layerArgument = null;
@@ -10941,6 +11106,7 @@ namespace Microsoft.Dafny {
var eeType = e.E.Type.NormalizeExpand();
if (eeType is SetType) {
// generate: (forall $o: ref :: $o != null && X[Box($o)] ==> !old($Heap)[$o,alloc])
+ // TODO: trigger?
Bpl.Variable oVar = new Bpl.BoundVariable(expr.tok, new Bpl.TypedIdent(expr.tok, "$o", predef.RefType));
Bpl.Expr o = new Bpl.IdentifierExpr(expr.tok, oVar);
Bpl.Expr oNotNull = Bpl.Expr.Neq(o, predef.Null);
@@ -10967,7 +11133,7 @@ namespace Microsoft.Dafny {
//TRIGGERS: Does this make sense? dafny0\SmallTests
// BROKEN // NEW_TRIGGER
//TRIG (forall $i: int :: 0 <= $i && $i < Seq#Length(Q#0) && $Unbox(Seq#Index(Q#0, $i)): ref != null ==> !read(old($Heap), $Unbox(Seq#Index(Q#0, $i)): ref, alloc))
- return new Bpl.ForallExpr(expr.tok, new List<Variable> { iVar }, body);
+ return new Bpl.ForallExpr(expr.tok, new List<Variable> { iVar }, body);
} else if (eeType.IsDatatype) {
// translator.FunctionCall(e.tok, BuiltinFunction.DtAlloc, null, TrExpr(e.E), Old.HeapExpr);
Bpl.Expr alloc = translator.MkIsAlloc(TrExpr(e.E), eeType, Old.HeapExpr);
@@ -11051,7 +11217,7 @@ namespace Microsoft.Dafny {
if (cot != null) {
var e0args = e.E0.Type.NormalizeExpand().TypeArgs;
var e1args = e.E1.Type.NormalizeExpand().TypeArgs;
- return translator.CoEqualCall(cot, e0args, e1args, null, LayerN(2), e0, e1, expr.tok);
+ return translator.CoEqualCall(cot, e0args, e1args, null, this.layerInterCluster.LayerN((int)FuelSetting.FuelAmount.HIGH), e0, e1, expr.tok);
}
typ = Bpl.Type.Bool;
bOpcode = BinaryOperator.Opcode.Eq; break;
@@ -11060,7 +11226,7 @@ namespace Microsoft.Dafny {
if (cotx != null) {
var e0args = e.E0.Type.NormalizeExpand().TypeArgs;
var e1args = e.E1.Type.NormalizeExpand().TypeArgs;
- var x = translator.CoEqualCall(cotx, e0args, e1args, null, LayerN(2), e0, e1, expr.tok);
+ var x = translator.CoEqualCall(cotx, e0args, e1args, null, this.layerInterCluster.LayerN((int)FuelSetting.FuelAmount.HIGH), e0, e1, expr.tok);
return Bpl.Expr.Unary(expr.tok, UnaryOperator.Opcode.Not, x);
}
typ = Bpl.Type.Bool;
@@ -11341,7 +11507,7 @@ namespace Microsoft.Dafny {
var e2type = e.E2.Type.NormalizeExpand();
var cot = e1type.AsCoDatatype;
Contract.Assert(cot != null); // the argument types of prefix equality (and prefix disequality) are codatatypes
- var r = translator.CoEqualCall(cot, e1type.TypeArgs, e2type.TypeArgs, e0, LayerN(2), e1, e2);
+ var r = translator.CoEqualCall(cot, e1type.TypeArgs, e2type.TypeArgs, e0, this.layerInterCluster.LayerN((int)FuelSetting.FuelAmount.HIGH), e1, e2);
if (e.Op == TernaryExpr.Opcode.PrefixEqOp) {
return r;
} else {
@@ -11374,8 +11540,7 @@ namespace Microsoft.Dafny {
if (Attributes.ContainsBool(e.Attributes, "layerQuantifier", ref _scratch)) {
// If this is a layer quantifier, quantify over layers here, and use $LS(ly) layers in the translation of the body
var ly = BplBoundVar(e.Refresh("q$ly#", translator.CurrentIdGenerator), predef.LayerType, bvars);
- Expr layer = translator.LayerSucc(ly);
- bodyEtran = new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, layer, layer, modifiesFrame, stripLits);
+ bodyEtran = new ExpressionTranslator(translator, predef, HeapExpr, This, applyLimited_CurrentFunction, new FuelSetting(translator, 1, ly), new FuelSetting(translator, 1, ly), modifiesFrame, stripLits);
}
if (Attributes.ContainsBool(e.Attributes, "heapQuantifier", ref _scratch)) {
var h = BplBoundVar(e.Refresh("q$heap#", translator.CurrentIdGenerator), predef.HeapType, bvars);
@@ -11496,7 +11661,7 @@ namespace Microsoft.Dafny {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
}
}
-
+
private Expr TrLambdaExpr(LambdaExpr e) {
var bvars = new List<Bpl.Variable>();
var bargs = new List<Bpl.Expr>();
@@ -11534,13 +11699,10 @@ namespace Microsoft.Dafny {
}
var rdvars = new List<Bpl.Variable>();
- var o = translator.UnboxIfBoxed(BplBoundVar(varNameGen.FreshId("#o#"), predef.BoxType, rdvars), new ObjectType());
-
- Bpl.Expr ante = Bpl.Expr.And(Bpl.Expr.Neq(o, predef.Null), et.IsAlloced(e.tok, o));
- Bpl.Expr consequent = translator.InRWClause(e.tok, o, null, e.Reads.ConvertAll(su.SubstFrameExpr), et, null, null);
- Bpl.Expr rdbody =
- new Bpl.LambdaExpr(e.tok, new List<TypeVariable>(), rdvars, null,
- BplImp(ante, consequent));
+ var o = BplBoundVar(varNameGen.FreshId("#o#"), predef.RefType, rdvars);
+ Bpl.Expr rdbody = new Bpl.LambdaExpr(e.tok, new List<TypeVariable>(), rdvars, null,
+ translator.InRWClause(e.tok, o, null, e.Reads.ConvertAll(su.SubstFrameExpr), et, null, null));
+ rdbody = translator.FunctionCall(e.tok, "SetRef_to_SetBox", predef.SetType(e.tok, true, predef.BoxType), rdbody);
return MaybeLit(
translator.FunctionCall(e.tok, BuiltinFunction.AtLayer, predef.HandleType,
@@ -11549,7 +11711,7 @@ namespace Microsoft.Dafny {
new Bpl.LambdaExpr(e.tok, new List<TypeVariable>(), bvars, null, ebody),
new Bpl.LambdaExpr(e.tok, new List<TypeVariable>(), bvars, null, reqbody),
new Bpl.LambdaExpr(e.tok, new List<TypeVariable>(), bvars, null, rdbody))),
- layerIntraCluster ?? layerInterCluster),
+ layerIntraCluster != null ? layerIntraCluster.ToExpr() : layerInterCluster.ToExpr()),
predef.HandleType);
}
@@ -12641,15 +12803,14 @@ namespace Microsoft.Dafny {
// checked $PrefixEqual#Dt(k, A, B) || (0 < k ==> A.Cons? ==> B.Cons? && A.head == B.head && $PrefixEqual#2#Dt(k - 1, A.tail, B.tail)) // note the #2 in the recursive call, just like for user-defined predicates that are inlined by TrSplitExpr
// free $PrefixEqual#Dt(k, A, B);
var kPos = Bpl.Expr.Lt(Bpl.Expr.Literal(0), k);
- var prefixEqK = CoEqualCall(codecl, e1type.TypeArgs, e2type.TypeArgs, k, etran.LayerN(2), A, B); // FunctionCall(expr.tok, CoPrefixName(codecl, 1), Bpl.Type.Bool, k, A, B);
+ var prefixEqK = CoEqualCall(codecl, e1type.TypeArgs, e2type.TypeArgs, k, etran.layerInterCluster.LayerN((int)FuelSetting.FuelAmount.HIGH), A, B); // FunctionCall(expr.tok, CoPrefixName(codecl, 1), Bpl.Type.Bool, k, A, B);
var kMinusOne = Bpl.Expr.Sub(k, Bpl.Expr.Literal(1));
// for the inlining of the definition of prefix equality, translate the two main equality operands arguments with a higher offset (to obtain #2 functions)
var etran2 = etran.LayerOffset(1);
var A2 = etran2.TrExpr(e.E1);
var B2 = etran2.TrExpr(e.E2);
var needsTokenAdjust = TrSplitNeedsTokenAdjustment(expr);
- // Dan: dafny4/Circ.dfy needs this one to be 2+, rather than 1+
- Bpl.Expr layer = LayerSucc(etran.layerInterCluster, 2);
+ Bpl.Expr layer = etran.layerInterCluster.LayerN((int)FuelSetting.FuelAmount.HIGH);
foreach (var c in CoPrefixEquality(needsTokenAdjust ? new ForceCheckToken(expr.tok) : expr.tok, codecl, e1type.TypeArgs, e2type.TypeArgs, kMinusOne, layer, A2, B2, true)) {
var p = Bpl.Expr.Binary(c.tok, BinaryOperator.Opcode.Or, prefixEqK, Bpl.Expr.Imp(kPos, c));
splits.Add(new SplitExprInfo(SplitExprInfo.K.Checked, p));
@@ -14061,7 +14222,7 @@ namespace Microsoft.Dafny {
r = rr;
} else if (stmt is CalcStmt) {
var s = (CalcStmt)stmt;
- var rr = new CalcStmt(s.Tok, s.EndTok, SubstCalcOp(s.Op), s.Lines.ConvertAll(Substitute), s.Hints.ConvertAll(SubstBlockStmt), s.StepOps.ConvertAll(SubstCalcOp), SubstCalcOp(s.ResultOp));
+ var rr = new CalcStmt(s.Tok, s.EndTok, SubstCalcOp(s.Op), s.Lines.ConvertAll(Substitute), s.Hints.ConvertAll(SubstBlockStmt), s.StepOps.ConvertAll(SubstCalcOp), SubstCalcOp(s.ResultOp), SubstAttributes(s.Attributes));
rr.Steps.AddRange(s.Steps.ConvertAll(Substitute));
rr.Result = Substitute(s.Result);
r = rr;
@@ -14352,7 +14513,7 @@ namespace Microsoft.Dafny {
Contract.Requires(b != null);
Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
- if (a == Bpl.Expr.True || b == Bpl.Expr.True || b == Bpl.Expr.False) {
+ if (a == Bpl.Expr.True || b == Bpl.Expr.True) {
return b;
} else if (a == Bpl.Expr.False) {
return Bpl.Expr.True;
@@ -14384,7 +14545,7 @@ namespace Microsoft.Dafny {
/// Makes a simple trigger
static Bpl.Trigger BplTrigger(Bpl.Expr e) {
- return new Trigger(e.tok, true, new List<Bpl.Expr> { e });
+ return new Bpl.Trigger(e.tok, true, new List<Bpl.Expr> { e });
}
static Bpl.Axiom BplAxiom(Bpl.Expr e) {
diff --git a/Source/Dafny/Util.cs b/Source/Dafny/Util.cs
index f9421659..63659696 100644
--- a/Source/Dafny/Util.cs
+++ b/Source/Dafny/Util.cs
@@ -8,7 +8,7 @@ using Microsoft.Boogie;
namespace Microsoft.Dafny {
- class Util
+ public class Util
{
public static string Comma<T>(IEnumerable<T> l, Func<T, string> f) {
return Comma(",", l, f);
@@ -175,5 +175,152 @@ namespace Microsoft.Dafny {
}
}
+ /// <summary>
+ /// Class dedicated to traversing the function call graph
+ /// </summary>
+ class FunctionCallFinder : TopDownVisitor<List<Function>> {
+ protected override bool VisitOneExpr(Expression expr, ref List<Function> calls) {
+ if (expr is FunctionCallExpr) {
+ calls.Add(((FunctionCallExpr)expr).Function);
+ }
+ return true;
+ }
+ }
+
+ static Graph<Function> BuildFunctionCallGraph(Dafny.Program program) {
+ Graph<Function> functionCallGraph = new Graph<Function>();
+ FunctionCallFinder callFinder = new FunctionCallFinder();
+
+ foreach (var module in program.Modules) {
+ foreach (var decl in module.TopLevelDecls) {
+ if (decl is ClassDecl) {
+ var c = (ClassDecl)decl;
+ foreach (var member in c.Members) {
+ if (member is Function) {
+ var f = (Function)member;
+
+ List<Function> calls = new List<Function>();
+ foreach (var e in f.Reads) { if (e != null && e.E != null) { callFinder.Visit(e.E, calls); } }
+ foreach (var e in f.Req) { if (e != null) { callFinder.Visit(e, calls); } }
+ foreach (var e in f.Ens) { if (e != null) { callFinder.Visit(e, calls); } }
+ if (f.Body != null) {
+ callFinder.Visit(f.Body, calls);
+ }
+
+ foreach (var callee in calls) {
+ functionCallGraph.AddEdge(f, callee);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return functionCallGraph;
+ }
+
+ /// <summary>
+ /// Prints the program's function call graph in a format suitable for consumption in other tools
+ /// </summary>
+ public static void PrintFunctionCallGraph(Dafny.Program program) {
+ var functionCallGraph = BuildFunctionCallGraph(program);
+
+ foreach (var vertex in functionCallGraph.GetVertices()) {
+ var func = vertex.N;
+ Console.Write("{0},{1}=", func.CompileName, func.EnclosingClass.Module.CompileName);
+ foreach (var callee in vertex.Successors) {
+ Console.Write("{0} ", callee.N.CompileName);
+ }
+ Console.Write("\n");
+ }
+ }
+
+ /// <summary>
+ /// Generic statistic counter
+ /// </summary>
+ static void IncrementStat(IDictionary<string, ulong> stats, string stat) {
+ ulong currentValue;
+ if (stats.TryGetValue(stat, out currentValue)) {
+ stats[stat] += 1;
+ } else {
+ stats.Add(stat, 1);
+ }
+ }
+
+ /// <summary>
+ /// Track the maximum value of some statistic
+ /// </summary>
+ static void UpdateMax(IDictionary<string, ulong> stats, string stat, ulong val) {
+ ulong currentValue;
+ if (stats.TryGetValue(stat, out currentValue)) {
+ if (val > currentValue) {
+ stats[stat] = val;
+ }
+ } else {
+ stats.Add(stat, val);
+ }
+ }
+
+ /// <summary>
+ /// Compute various interesting statistics about the Dafny program
+ /// </summary>
+ public static void PrintStats(Dafny.Program program) {
+ SortedDictionary<string, ulong> stats = new SortedDictionary<string, ulong>();
+
+ foreach (var module in program.Modules) {
+ IncrementStat(stats, "Modules");
+ UpdateMax(stats, "Module height (max)", (ulong)module.Height);
+
+ ulong num_scc = (ulong)module.CallGraph.TopologicallySortedComponents().Count;
+ UpdateMax(stats, "Call graph width (max)", num_scc);
+
+ foreach (var decl in module.TopLevelDecls) {
+ if (decl is DatatypeDecl) {
+ IncrementStat(stats, "Datatypes");
+ } else if (decl is ClassDecl) {
+ var c = (ClassDecl)decl;
+ if (c.Name != "_default") {
+ IncrementStat(stats, "Classes");
+ }
+
+ foreach (var member in c.Members) {
+ if (member is Function) {
+ IncrementStat(stats, "Functions (total)");
+ var f = (Function)member;
+ if (f.IsRecursive) {
+ IncrementStat(stats, "Functions recursive");
+ }
+ } else if (member is Method) {
+ IncrementStat(stats, "Methods (total)");
+ var method = (Method)member;
+ if (method.IsRecursive) {
+ IncrementStat(stats, "Methods recursive");
+ }
+ if (method.IsGhost) {
+ IncrementStat(stats, "Methods ghost");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Print out the results, with some nice formatting
+ Console.WriteLine("");
+ Console.WriteLine("Statistics");
+ Console.WriteLine("----------");
+
+ int max_key_length = 0;
+ foreach (var key in stats.Keys) {
+ if (key.Length > max_key_length) {
+ max_key_length = key.Length;
+ }
+ }
+
+ foreach (var keypair in stats) {
+ string keyString = keypair.Key.PadRight(max_key_length + 2);
+ Console.WriteLine("{0} {1,4}", keyString, keypair.Value);
+ }
+ }
}
}
diff --git a/Source/DafnyDriver/DafnyDriver.cs b/Source/DafnyDriver/DafnyDriver.cs
index ce4d726f..9fdc9320 100644
--- a/Source/DafnyDriver/DafnyDriver.cs
+++ b/Source/DafnyDriver/DafnyDriver.cs
@@ -199,6 +199,13 @@ namespace Microsoft.Dafny
}
exitValue = allOk ? ExitValue.VERIFIED : ExitValue.NOT_VERIFIED;
}
+
+ if (err == null && dafnyProgram != null && DafnyOptions.O.PrintStats) {
+ Util.PrintStats(dafnyProgram);
+ }
+ if (err == null && dafnyProgram != null && DafnyOptions.O.PrintFunctionCallGraph) {
+ Util.PrintFunctionCallGraph(dafnyProgram);
+ }
}
return exitValue;
}
diff --git a/Source/DafnyExtension/IdentifierTagger.cs b/Source/DafnyExtension/IdentifierTagger.cs
index 086ac8e4..262dddcd 100644
--- a/Source/DafnyExtension/IdentifierTagger.cs
+++ b/Source/DafnyExtension/IdentifierTagger.cs
@@ -270,7 +270,17 @@ namespace DafnyLanguage
} else if (expr is MatchExpr) {
var e = (MatchExpr)expr;
foreach (var kase in e.Cases) {
- kase.Arguments.ForEach(bv => IdRegion.Add(regions, bv.tok, bv, true, module));
+ kase.Arguments.ForEach(bv => {
+ IdRegion.Add(regions, bv.tok, bv, true, module);
+ // if the arguments is an encapsulation of different boundvars from nested match cases,
+ // add the boundvars so that they can show up in the IDE correctly
+ if (bv.tok is MatchCaseToken) {
+ MatchCaseToken mt = (MatchCaseToken)bv.tok;
+ foreach(Tuple<Bpl.IToken, BoundVar, bool> entry in mt.varList) {
+ IdRegion.Add(regions, entry.Item1, entry.Item2, entry.Item3, module);
+ }
+ }
+ });
}
} else if (expr is ChainingExpression) {
var e = (ChainingExpression)expr;
@@ -313,7 +323,17 @@ namespace DafnyLanguage
} else if (stmt is MatchStmt) {
var s = (MatchStmt)stmt;
foreach (var kase in s.Cases) {
- kase.Arguments.ForEach(bv => IdRegion.Add(regions, bv.tok, bv, true, module));
+ kase.Arguments.ForEach(bv => {
+ IdRegion.Add(regions, bv.tok, bv, true, module);
+ // if the arguments is an encapsulation of different boundvars from nested match cases,
+ // add the boundvars so that they can show up in the IDE correctly
+ if (bv.tok is MatchCaseToken) {
+ MatchCaseToken mt = (MatchCaseToken)bv.tok;
+ foreach (Tuple<Bpl.IToken, BoundVar, bool> entry in mt.varList) {
+ IdRegion.Add(regions, entry.Item1, entry.Item2, entry.Item3, module);
+ }
+ }
+ });
}
} else if (stmt is LoopStmt) {
var s = (LoopStmt)stmt;
diff --git a/Test/VerifyThis2015/Problem3.dfy b/Test/VerifyThis2015/Problem3.dfy
index 10ad2d3a..4205035d 100644
--- a/Test/VerifyThis2015/Problem3.dfy
+++ b/Test/VerifyThis2015/Problem3.dfy
@@ -1,4 +1,4 @@
-// RUN: %dafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %dafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" /vcsMaxKeepGoingSplits:5 "%s" > "%t"
// RUN: %diff "%s.expect" "%t"
// Rustan Leino
diff --git a/Test/dafny0/Basics.dfy b/Test/dafny0/Basics.dfy
index c8fa76c8..89b0f02a 100644
--- a/Test/dafny0/Basics.dfy
+++ b/Test/dafny0/Basics.dfy
@@ -100,7 +100,7 @@ method ExpliesAssociativityM(A: bool, B: bool, C: bool) {
}
}
-method ExpliesShortCircuiting(a: array<T>)
+method ExpliesShortCircuiting(a: array)
{
assert a == null || 0 <= a.Length; // (W)
assert a != null ==> 0 <= a.Length; // (X) -- same as (W)
diff --git a/Test/dafny0/EqualityTypes.dfy b/Test/dafny0/EqualityTypes.dfy
index b2812759..c510cfb1 100644
--- a/Test/dafny0/EqualityTypes.dfy
+++ b/Test/dafny0/EqualityTypes.dfy
@@ -241,3 +241,115 @@ module Deep {
var m1 := map[ko := 5]; // error: bad type
}
}
+
+//--------------------------
+
+module UnderspecifiedTypeParameters {
+ method UP<T>()
+ function method UG<T>(): int
+ method Callee<T(==)>()
+ class TakesParam<U> { }
+
+ method MPG()
+ {
+ var g := UG(); // error: type parameter underspecified
+ UP(); // error: type parameter underspecified
+ }
+ method M() {
+ var zs: set; // error: type is underspecified
+ Callee<(int)>();
+ Callee<set>(); // error: type is underspecified
+ Callee<()>();
+ // The following
+ Callee<TakesParam>(); // error: type is underspecified
+ }
+}
+
+module EqualitySupportingTypes {
+ method P<T>()
+ function method G<T>(): int
+ class AClass<V(==),Y> {
+ static function method H<W,X(==)>(): bool
+ static method Q<A,B(==)>()
+ }
+
+ method Callee<T(==)>()
+ function method FCallee<T>(): T
+
+ datatype Dt = Dt(f: int -> int)
+ codatatype Stream<T> = Cons(T, Stream)
+
+ method M<ArbitraryTypeArg>()
+ {
+ Callee<Dt>(); // error: Dt is not an equality-supporting type
+ Callee<Stream<int>>(); // error: specified type does not support equality
+
+ // set<X> is allowed in a non-ghost context only if X is equality supporting.
+ // Ditto for multiset<X> and map<X,Y>.
+ var s3x: set<Dt>; // error: this type not allowed in a non-ghost context
+ var is3x: iset<Dt>; // error: this type not allowed in a non-ghost context
+ var mast: multiset<ArbitraryTypeArg>; // error: this type not allowed in a non-ghost context
+ var qt: seq<Stream<int>>; // allowed
+ var mp0: map<Dt,int>; // error: this type not allowed in a non-ghost context
+ var mp1: map<int,Dt>; // allowed
+ var imp0: imap<Dt,int>; // error: this type not allowed in a non-ghost context
+ var imp1: imap<int,Dt>; // allowed
+
+ var S := FCallee<set>(); // this gives s:set<?>
+ if 4 in S { // this constrains the type further to be s:set<int>
+ }
+
+ var xy: set<set<int>>;
+ var xz: set<set<Stream<int>>>; // error: set type argument must support equality
+
+ Callee<set<Stream<int>>>(); // bogus: a set shouldn't ever be allowed to take a Stream as an argument (this check seems to be missing for explicit type arguments) -- Note: language definition should be changed, because it doesn't make sense for it to talk about a type appearing in a ghost or non-ghost context. Instead, set/iset/multiset/map/imap should always be allowed to take any type argument, but these types may or may not support equality.
+ var xg := G<set<Stream<int>>>();
+
+ var ac0: AClass<int,int>;
+ var ac1: AClass<Stream<int>,int>; // error: type parameter 0 is required to support equality
+ var ac2: AClass<int,Stream<int>>;
+ var xd0 := ac0.H<real,real>();
+ var xd1 := ac1.H<Stream<real>,real>(); // error (remnant of the fact that the type of ac1 is not allowed)
+ var xd2 := ac2.H<real,Stream<real>>(); // error: type parameter 1 is required to support equality
+ var xe0 := ac0.H<real,real>;
+ var xe1 := ac1.H<Stream<real>,real>; // error (remnant of the fact that the type of ac1 is not allowed)
+ var xe2 := ac2.H<real,Stream<real>>; // error: type parameter 1 is required to support equality
+ var xh0 := AClass<int,int>.H<real,real>();
+ var xh1 := AClass<int,int>.H<Stream<real>,real>();
+ var xh2 := AClass<int,int>.H<real,Stream<real>>(); // error: type parameter 1 is required to support equality
+ var xk0 := AClass<real,real>.H<int,int>;
+ var xk1 := AClass<Stream<real>,real>.H<int,int>; // error: class type param 0 wants an equality-supporting type
+ var xk2 := AClass<real,Stream<real>>.H<int,int>;
+ AClass<Stream<int>,int>.Q<real,real>(); // error: class type param 0 wants an equality-supporting type
+ AClass<int,Stream<int>>.Q<real,real>();
+ AClass<int,Stream<int>>.Q<Stream<real>,real>();
+ AClass<int,Stream<int>>.Q<real,Stream<real>>(); // error: method type param 1 wants an equality-supporting type
+
+/*************************** TESTS YET TO COME
+ var ac8: AClass<real,real>;
+ var xd8 := (if 5/0 == 3 then ac0 else ac8).H<real,real>(); // error: this should be checked by the verifier
+
+ AClass<int,set<Stream<int>>>.Q<real,real>(); // error: cannot utter "set<Stream<int>>" Or is that okay???
+ AClass<int,int>.Q<set<Stream<real>>,real>(); // error: cannot utter "set<Stream<real>>" Or is that okay???
+ var xi0 := AClass<int,set<Stream<int>>>.H<real,real>(); // error: cannot utter "set<Stream<int>>" Or is that okay???
+ var xi1 := AClass<int,int>.H<real,set<Stream<real>>>(); // error: cannot utter "set<Stream<real>>" Or is that okay???
+
+ var x, t, s: seq<int -> int>, fii: int -> int;
+ if s == t {
+ x := 5; // error: assigning to non-ghost variable in ghost context
+ }
+ if fii in s {
+ x := 4; // error: assigning to non-ghost variable in ghost context
+ }
+ if !(fii in s) {
+ x := 3; // error: assigning to non-ghost variable in ghost context
+ }
+
+ ghost var ghostset: set<Stream<int>> := {}; // fine, since this is ghost
+ forall u | 0 <= u < 100
+ ensures var lets: set<Stream<int>> := {}; lets == lets // this is ghost, so the equality requirement doesn't apply
+ {
+ }
+*********************************************/
+ }
+}
diff --git a/Test/dafny0/EqualityTypes.dfy.expect b/Test/dafny0/EqualityTypes.dfy.expect
index 9f277582..1c02f3a0 100644
--- a/Test/dafny0/EqualityTypes.dfy.expect
+++ b/Test/dafny0/EqualityTypes.dfy.expect
@@ -35,4 +35,26 @@ EqualityTypes.dfy(238,24): Error: set argument type must support equality (got C
EqualityTypes.dfy(239,21): Error: multiset argument type must support equality (got Co)
EqualityTypes.dfy(241,8): Error: map domain type must support equality (got Co)
EqualityTypes.dfy(241,14): Error: map domain type must support equality (got Co)
-37 resolution/type errors detected in EqualityTypes.dfy
+EqualityTypes.dfy(255,13): Error: type variable 'T' in the function call to 'UG' could not be determined
+EqualityTypes.dfy(256,4): Error: type '?' to the method 'UP' is not determined
+EqualityTypes.dfy(259,8): Error: the type of this local variable is underspecified
+EqualityTypes.dfy(261,4): Error: type 'set<?>' to the method 'Callee' is not determined
+EqualityTypes.dfy(264,4): Error: type 'TakesParam<?>' to the method 'Callee' is not determined
+EqualityTypes.dfy(284,14): Error: type parameter 0 (T) passed to method Callee must support equality (got Dt)
+EqualityTypes.dfy(285,23): Error: type parameter 0 (T) passed to method Callee must support equality (got Stream<int>)
+EqualityTypes.dfy(289,8): Error: set argument type must support equality (got Dt)
+EqualityTypes.dfy(290,8): Error: iset argument type must support equality (got Dt)
+EqualityTypes.dfy(291,8): Error: multiset argument type must support equality (got ArbitraryTypeArg) (perhaps try declaring type parameter 'ArbitraryTypeArg' on line 282 as 'ArbitraryTypeArg(==)', which says it can only be instantiated with a type that supports equality)
+EqualityTypes.dfy(293,8): Error: map domain type must support equality (got Dt)
+EqualityTypes.dfy(295,8): Error: imap domain type must support equality (got Dt)
+EqualityTypes.dfy(303,8): Error: set argument type must support equality (got Stream<int>)
+EqualityTypes.dfy(309,8): Error: type parameter 0 (V) passed to type AClass must support equality (got Stream<int>)
+EqualityTypes.dfy(312,19): Error: type parameter 0 (V) passed to type AClass must support equality (got Stream<int>)
+EqualityTypes.dfy(313,19): Error: type parameter 1 (X) passed to function H must support equality (got Stream<real>)
+EqualityTypes.dfy(315,19): Error: type parameter 0 (V) passed to type AClass must support equality (got Stream<int>)
+EqualityTypes.dfy(316,19): Error: type parameter 1 (X) passed to function 'H' must support equality (got Stream<real>)
+EqualityTypes.dfy(319,31): Error: type parameter 1 (X) passed to function H must support equality (got Stream<real>)
+EqualityTypes.dfy(321,41): Error: type parameter 0 (V) passed to type AClass must support equality (got Stream<real>)
+EqualityTypes.dfy(323,28): Error: type parameter 0 (V) passed to type AClass must support equality (got Stream<int>)
+EqualityTypes.dfy(326,48): Error: type parameter 1 (B) passed to method Q must support equality (got Stream<real>)
+59 resolution/type errors detected in EqualityTypes.dfy
diff --git a/Test/dafny0/Fuel.dfy b/Test/dafny0/Fuel.dfy
new file mode 100644
index 00000000..c8a1fc2f
--- /dev/null
+++ b/Test/dafny0/Fuel.dfy
@@ -0,0 +1,423 @@
+// RUN: %dafny /compile:0 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+module TestModule1 {
+ function pos(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos(x - 1)
+ }
+
+ method test(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert pos(z) == 0;
+ assert pos(-1) == 0;
+ assert pos(y) == 3 + pos(y - 3); // error: Should fail, due to lack of fuel
+ assert pos(y) == 4 + pos(y - 4); // Succeeds, thanks to the assume from the preceding assert
+ }
+}
+
+// Test with function-level fuel boost
+module TestModule2 {
+ function {:fuel 3} pos1(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos1(x - 1)
+ }
+
+ function {:fuel 3,5} pos2(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos2(x - 1)
+ }
+
+ function {:fuel 3,5} pos3(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos3(x - 1)
+ }
+
+ function {:opaque} {:fuel 3,5} pos4(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos3(x - 1)
+ }
+
+ method test(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert pos1(z) == 0;
+ assert pos1(-1) == 0;
+ assert pos1(y) == 3 + pos1(y - 3);
+ assert pos1(y) == 4 + pos1(y - 4);
+
+ assert pos2(z) == 0;
+ assert pos2(-1) == 0;
+ assert pos2(y) == 3 + pos2(y - 3);
+ assert pos2(y) == 4 + pos2(y - 4);
+
+ if (*) {
+ assert pos3(y) == 5 + pos3(y - 5); // Just enough fuel to get here
+ } else {
+ assert pos3(y) == 6 + pos3(y - 6); // error: Should fail even with a boost, since boost is too small
+ }
+
+ if (*) {
+ assert pos4(z) == 0; // error: Fuel shouldn't overcome opaque
+ } else {
+ reveal_pos4();
+ assert pos4(y) == 5 + pos4(y - 5); // With reveal, everything should work as above
+ }
+
+
+ }
+}
+
+
+module TestModule3 {
+ // This fuel setting is equivalent to opaque, except for literals
+ function {:fuel 0,0} pos(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos(x - 1)
+ }
+
+ method test(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert pos(z) == 0; // error: Opaque setting hides body
+ assert pos(-1) == 0; // Passes, since Dafny's computation mode for lits ignore fuel
+ assert pos(y) == 3 + pos(y - 3);// error: Opaque setting hides body
+ }
+}
+
+// Test fuel settings via different contexts
+module TestModule4 {
+ function pos(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos(x - 1)
+ }
+
+ // Should pass
+ method {:fuel pos,3,5} test1(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert pos(z) == 0;
+ assert pos(-1) == 0;
+ assert pos(y) == 3 + pos(y - 3);
+ }
+
+ method {:fuel pos,0,0} test2(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert pos(z) == 0; // error: Should fail due to "opaque" fuel setting
+ assert pos(-1) == 0;
+ assert pos(y) == 3 + pos(y - 3); // error: Should fail due to "opaque" fuel setting
+ }
+
+ method test3(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert {:fuel pos,0,0} pos(z) == 0; // error: Should fail due to "opaque" fuel setting
+ assert pos(-1) == 0;
+ if (*) {
+ assert pos(y) == 3 + pos(y - 3); // error: Should fail without extra fuel setting
+ assert pos(y) == 6 + pos(y - 6); // error: Should fail even with previous assert turned into assume
+ } else {
+ assert {:fuel pos,3,5} pos(y) == 3 + pos(y - 3); // Should succeed with extra fuel setting
+ assert pos(y) == 6 + pos(y - 6); // Should succeed thanks to previous assert turned into assume
+ }
+ }
+
+ method test4(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ forall t:int {:fuel pos,3} | t > 0
+ ensures true;
+ {
+ assert pos(y) == 3 + pos(y - 3); // Expected to pass, due to local fuel boost
+ }
+
+ if (*) {
+ calc {:fuel pos,3} {
+ pos(y);
+ 3 + pos(y - 3);
+ }
+ }
+
+ assert pos(y) == 3 + pos(y - 3); // error: Should fail, due to lack of fuel outside the forall
+ }
+}
+
+// Test fuel settings via different module contexts
+module TestModule5 {
+ // Test module level fuel settings, with nested modules
+
+ module TestModule5a {
+ module {:fuel TestModule5aiA.pos,3} TestModule5ai {
+ module TestModule5aiA {
+ function pos(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos(x - 1)
+ }
+
+ method test(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert pos(z) == 0;
+ assert pos(-1) == 0;
+ assert pos(y) == 3 + pos(y - 3); // Should pass due to intermediate module's fuel setting
+ }
+ }
+
+ method test(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert TestModule5aiA.pos(z) == 0;
+ assert TestModule5aiA.pos(-1) == 0;
+ assert TestModule5aiA.pos(y) == 3 + TestModule5aiA.pos(y - 3); // Should pass due to module level fuel
+ }
+ }
+
+ method test(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert TestModule5ai.TestModule5aiA.pos(z) == 0;
+ assert TestModule5ai.TestModule5aiA.pos(-1) == 0;
+ assert TestModule5ai.TestModule5aiA.pos(y) == 3 + TestModule5ai.TestModule5aiA.pos(y - 3); // error: Should fail, due to lack of fuel
+ }
+ }
+
+ module {:fuel TestModule5bi.TestModule5biA.pos,3} TestModule5b {
+ module TestModule5bi {
+ module TestModule5biA {
+ function pos(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos(x - 1)
+ }
+
+ method test(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert pos(z) == 0;
+ assert pos(-1) == 0;
+ assert pos(y) == 3 + pos(y - 3); // Should succceed due to outer module fuel setting
+ }
+ }
+ }
+ }
+}
+
+// Test fuel setting for multiple functions
+module TestModule6 {
+ function pos(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos(x - 1)
+ }
+
+ function neg(x:int) : int
+ decreases 1 - x;
+ {
+ if x > 0 then 0
+ else 1 + neg(x + 1)
+ }
+
+ method test1(y:int, z:int)
+ requires y > 5;
+ requires z < 5;
+ {
+ assert pos(y) == 3 + pos(y - 3); // error: Should fail, due to lack of fuel
+
+ assert neg(z) == 3 + neg(z + 3); // error: Should fail, due to lack of fuel
+ }
+
+ method {:fuel pos,3} {:fuel neg,4} test2(y:int, z:int)
+ requires y > 5;
+ requires z < -5;
+ {
+ assert pos(y) == 3 + pos(y - 3);
+
+ assert neg(z) == 3 + neg(z + 3);
+ }
+}
+
+// Test fuel settings with multiple overlapping contexts
+module TestModule7 {
+ function {:fuel 3} pos(x:int) : int
+ {
+ if x < 0 then 0
+ else 1 + pos(x - 1)
+ }
+
+ function {:fuel 0,0} neg(x:int) : int
+ decreases 1 - x;
+ {
+ if x > 0 then 0
+ else 1 + neg(x + 1)
+ }
+
+ method {:fuel neg,4} {:fuel pos,0,0} test1(y:int, z:int)
+ requires y > 5;
+ requires z < -5;
+ {
+ if (*) {
+ assert pos(y) == 3 + pos(y - 3); // error: Method fuel should override function fuel, so this should fail
+ assert neg(z) == 3 + neg(z + 3); // Method fuel should override function fuel, so this succeeds
+ }
+
+ forall t:int {:fuel pos,3} | t > 0
+ ensures true;
+ {
+ assert pos(y) == 3 + pos(y - 3); // Statement fuel should override method fuel, so this should succeed
+ }
+ }
+}
+
+// Test fuel in a slightly more complicated setting
+module TestModule8 {
+
+ newtype byte = i:int | 0 <= i < 0x100
+ newtype uint64 = i:int | 0 <= i < 0x10000000000000000
+
+ datatype G = GUint64
+ | GArray(elt:G)
+ | GTuple(t:seq<G>)
+ | GByteArray
+ | GTaggedUnion(cases:seq<G>)
+
+ datatype V = VUint64(u:uint64)
+ | VTuple(t:seq<V>)
+ | VCase(c:uint64, val:V)
+
+ predicate {:fuel 2} ValInGrammar(val:V, grammar:G)
+ {
+ match val
+ case VUint64(_) => grammar.GUint64?
+ case VTuple(t) => grammar.GTuple? && |t| == |grammar.t|
+ && forall i :: 0 <= i < |t| ==> ValInGrammar(t[i], grammar.t[i])
+ case VCase(c, val) => grammar.GTaggedUnion? && int(c) < |grammar.cases| && ValInGrammar(val, grammar.cases[c])
+ }
+
+ datatype CRequest = CRequest(client:EndPoint, seqno:uint64, request:CAppMessage) | CRequestNoOp()
+
+ type EndPoint
+ function method EndPoint_grammar() : G { GUint64 }
+ function method CRequest_grammar() : G { GTaggedUnion([ GTuple([EndPoint_grammar(), GUint64, CAppMessage_grammar()]), GUint64]) }
+
+ function method parse_EndPoint(val:V) : EndPoint
+ requires ValInGrammar(val, EndPoint_grammar());
+
+ type CAppMessage
+ function method CAppMessage_grammar() : G { GTaggedUnion([GUint64, GUint64, GUint64]) }
+ function method parse_AppMessage(val:V) : CAppMessage
+ requires ValInGrammar(val, CAppMessage_grammar());
+
+ function method {:fuel ValInGrammar,1,2} parse_Request1(val:V) : CRequest
+ requires ValInGrammar(val, CRequest_grammar());
+ {
+ if val.c == 0 then
+ var ep := parse_EndPoint(val.val.t[0]); // With default fuel, error: function precondition, destructor, index
+ CRequest(ep, val.val.t[1].u, parse_AppMessage(val.val.t[2])) // error: index out of range, destructor
+ else
+ CRequestNoOp()
+ }
+
+ function method parse_Request2(val:V) : CRequest
+ requires ValInGrammar(val, CRequest_grammar());
+ {
+ if val.c == 0 then
+ var ep := parse_EndPoint(val.val.t[0]); // With fuel boosted to 2 this succeeds
+ CRequest(ep, val.val.t[1].u, parse_AppMessage(val.val.t[2])) // error: destructor
+ else
+ CRequestNoOp()
+ }
+
+ function method {:fuel ValInGrammar,3} parse_Request3(val:V) : CRequest
+ requires ValInGrammar(val, CRequest_grammar());
+ {
+ if val.c == 0 then
+ var ep := parse_EndPoint(val.val.t[0]);
+ CRequest(ep, val.val.t[1].u, parse_AppMessage(val.val.t[2])) // With one more boost, everything succeeds
+ else
+ CRequestNoOp()
+ }
+
+ // With the method, everything succeeds with one less fuel boost (i.e., 2, rather than 3, as in parse_Request3)
+ method parse_Request4(val:V) returns (req:CRequest)
+ requires ValInGrammar(val, CRequest_grammar());
+ {
+ if val.c == 0 {
+ var ep := parse_EndPoint(val.val.t[0]);
+ req := CRequest(ep, val.val.t[1].u, parse_AppMessage(val.val.t[2]));
+ } else {
+ req := CRequestNoOp();
+ }
+ }
+}
+
+
+// Test fuel when it's applied to a non-recursive function
+module TestModule9 {
+ function abs(x:int) : int
+ {
+ if x < 0 then -1 * x else x
+ }
+
+ // All should pass.
+ method test1(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert abs(z) == -1*z;
+ assert abs(y) == y;
+ assert abs(-1) == 1;
+ }
+
+ // Method-level fuel override
+ method {:fuel abs,0,0} test2(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert abs(z) == -1*z; // error: Cannot see the body of abs
+ assert abs(y) == y; // error: Cannot see the body of abs
+ assert abs(-1) == 1; // lit bypasses fuel, so this should succeed
+ }
+
+ // Statement-level fuel override
+ method test3(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert {:fuel abs,0,0} abs(z) == -1*z; // error: Cannot see the body of abs
+ assert abs(y) == y; // Normal success
+ assert abs(-1) == 1; // lit bypasses fuel, so this should succeed
+ }
+
+ // Giving more fuel to a non-recursive function won't help,
+ // but it shouldn't hurt either.
+ method {:fuel abs,5,7} test4(y:int, z:int)
+ requires y > 5;
+ requires z < 0;
+ {
+ assert abs(z) == -1*z;
+ assert abs(y) == y;
+ assert abs(-1) == 1;
+ }
+}
+
diff --git a/Test/dafny0/Fuel.dfy.expect b/Test/dafny0/Fuel.dfy.expect
new file mode 100644
index 00000000..4c180a9c
--- /dev/null
+++ b/Test/dafny0/Fuel.dfy.expect
@@ -0,0 +1,95 @@
+Fuel.dfy(17,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(65,28): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon6_Else
+Fuel.dfy(69,28): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon6_Then
+ (0,0): anon7_Then
+Fuel.dfy(92,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(94,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(120,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(122,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(129,39): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(132,27): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon3_Then
+Fuel.dfy(133,27): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon3_Then
+Fuel.dfy(157,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon10_Else
+ (0,0): anon9
+Fuel.dfy(200,56): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(245,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(247,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(280,27): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon7_Then
+Fuel.dfy(335,27): Error: possible violation of function precondition
+Fuel.dfy(324,22): Related location
+Execution trace:
+ (0,0): anon0
+ (0,0): anon7_Else
+ (0,0): anon8_Then
+Fuel.dfy(335,50): Error: destructor 't' can only be applied to datatype values constructed by 'VTuple'
+Execution trace:
+ (0,0): anon0
+ (0,0): anon7_Else
+ (0,0): anon8_Then
+Fuel.dfy(335,51): Error: index out of range
+Execution trace:
+ (0,0): anon0
+ (0,0): anon7_Else
+ (0,0): anon8_Then
+Fuel.dfy(336,39): Error: index out of range
+Execution trace:
+ (0,0): anon0
+ (0,0): anon7_Else
+ (0,0): anon8_Then
+Fuel.dfy(336,43): Error: destructor 'u' can only be applied to datatype values constructed by 'VUint64'
+Execution trace:
+ (0,0): anon0
+ (0,0): anon7_Else
+ (0,0): anon8_Then
+Fuel.dfy(346,43): Error: destructor 'u' can only be applied to datatype values constructed by 'VUint64'
+Execution trace:
+ (0,0): anon0
+ (0,0): anon7_Else
+ (0,0): anon8_Then
+Fuel.dfy(397,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(398,23): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+Fuel.dfy(407,39): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+
+Dafny program verifier finished with 51 verified, 24 errors
diff --git a/Test/dafny0/JustWarnings.dfy b/Test/dafny0/JustWarnings.dfy
new file mode 100644
index 00000000..86523f5b
--- /dev/null
+++ b/Test/dafny0/JustWarnings.dfy
@@ -0,0 +1,19 @@
+// RUN: %dafny /compile:0 /print:"%t.print" /dprint:"%t.dprint" /warnShadowing "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+// This file tests the behavior where the Resolver reports some warnings
+// but no errors. In the case of errors, resolution does not continue
+// to clone modules and resolve them, but the cloning does proceed if there
+// are only warnings. Dafny should report only one copy of these warnings,
+// and warnings are therefore turned off when processing the clones. This
+// test file makes sure the warnings don't appear twice.
+
+method M(x: int)
+{
+ var x := 10; // warning: this shadows the parameter 'x'
+}
+
+class C<T> {
+ var u: T
+ method P<T>(t: T) // warning: this shadows the type parameter 'T'
+}
diff --git a/Test/dafny0/JustWarnings.dfy.expect b/Test/dafny0/JustWarnings.dfy.expect
new file mode 100644
index 00000000..5f0e66d8
--- /dev/null
+++ b/Test/dafny0/JustWarnings.dfy.expect
@@ -0,0 +1,4 @@
+JustWarnings.dfy(18,11): Warning: Shadowed type-parameter name: T
+JustWarnings.dfy(13,6): Warning: Shadowed local-variable name: x
+
+Dafny program verifier finished with 3 verified, 0 errors
diff --git a/Test/dafny0/Modules0.dfy b/Test/dafny0/Modules0.dfy
index 34aba3de..dbbffd87 100644
--- a/Test/dafny0/Modules0.dfy
+++ b/Test/dafny0/Modules0.dfy
@@ -71,16 +71,17 @@ module X1 {
}
module X2 {
+ import opened X1
class MyClass2 {
- method Down(x1: MyClass1, x0: MyClass0) {
+ method Down(x1: MyClass1, x0: X0'.MyClass0) {
x1.Down(x0);
}
- method WayDown(x0: MyClass0) {
+ method WayDown(x0: X0'.MyClass0) {
x0.Down();
}
method Up() {
}
- method Somewhere(y: MyClassY) {
+ method Somewhere(y: MyClassY) { // error: no such type in scope
y.M();
}
}
@@ -97,8 +98,7 @@ module YY {
class ClassG {
method T() { }
function method TFunc(): int { 10 }
- method V(y: MyClassY) { // Note, MyClassY is in scope, since we are in the _default
- // module, which imports everything
+ method V(y: MyClassY) {
y.M();
}
}
@@ -141,10 +141,10 @@ class AClassWithSomeField {
SomeField := SomeField + 4;
var a := old(SomeField); // error: old can only be used in ghost contexts
var b := fresh(this); // error: fresh can only be used in ghost contexts
- var c := allocated(this); // error: allocated can only be used in ghost contexts
+// var c := allocated(this); // error: allocated can only be used in ghost contexts
if (fresh(this)) { // this guard makes the if statement a ghost statement
ghost var x := old(SomeField); // this is a ghost context, so it's okay
- ghost var y := allocated(this); // this is a ghost context, so it's okay
+// ghost var y := allocated(this); // this is a ghost context, so it's okay
}
}
}
diff --git a/Test/dafny0/Modules0.dfy.expect b/Test/dafny0/Modules0.dfy.expect
index 5d11f9c9..d2f0bcc8 100644
--- a/Test/dafny0/Modules0.dfy.expect
+++ b/Test/dafny0/Modules0.dfy.expect
@@ -9,13 +9,8 @@ Modules0.dfy(15,11): Error: Duplicate name of top-level declaration: WazzupB
Modules0.dfy(56,21): Error: Undeclared top-level type or type parameter: MyClass1 (did you forget to qualify a name?)
Modules0.dfy(57,21): Error: Undeclared top-level type or type parameter: MyClass2 (did you forget to qualify a name?)
Modules0.dfy(68,21): Error: Undeclared top-level type or type parameter: MyClass2 (did you forget to qualify a name?)
-Modules0.dfy(76,9): Error: type MyClass1 does not have a member Down
-Modules0.dfy(76,13): Error: expected method call, found expression
-Modules0.dfy(79,9): Error: type MyClass0 does not have a member Down
-Modules0.dfy(79,13): Error: expected method call, found expression
-Modules0.dfy(84,8): Error: type MyClassY does not have a member M
-Modules0.dfy(84,9): Error: expected method call, found expression
-Modules0.dfy(92,19): Error: Undeclared top-level type or type parameter: ClassG (did you forget to qualify a name?)
+Modules0.dfy(84,24): Error: Undeclared top-level type or type parameter: MyClassY (did you forget to qualify a name?)
+Modules0.dfy(93,19): Error: Undeclared top-level type or type parameter: ClassG (did you forget to qualify a name?)
Modules0.dfy(226,15): Error: Undeclared top-level type or type parameter: X (did you forget to qualify a name?)
Modules0.dfy(226,8): Error: new can be applied only to reference types (got X)
Modules0.dfy(235,13): Error: module 'B' does not declare a type 'X'
@@ -35,11 +30,5 @@ Modules0.dfy(320,11): Error: Undeclared top-level type or type parameter: Wazzup
Modules0.dfy(321,17): Error: module 'Q_Imp' does not declare a type 'Edon'
Modules0.dfy(323,10): Error: new can be applied only to reference types (got Q_Imp.List<?>)
Modules0.dfy(324,30): Error: member Create does not exist in class Klassy
-Modules0.dfy(102,6): Error: type MyClassY does not have a member M
-Modules0.dfy(102,7): Error: expected method call, found expression
-Modules0.dfy(127,11): Error: ghost variables are allowed only in specification contexts
-Modules0.dfy(142,13): Error: old expressions are allowed only in specification and ghost contexts
-Modules0.dfy(143,13): Error: fresh expressions are allowed only in specification and ghost contexts
-Modules0.dfy(144,13): Error: unresolved identifier: allocated
-Modules0.dfy(147,21): Error: unresolved identifier: allocated
-42 resolution/type errors detected in Modules0.dfy
+Modules0.dfy(101,14): Error: Undeclared top-level type or type parameter: MyClassY (did you forget to qualify a name?)
+31 resolution/type errors detected in Modules0.dfy
diff --git a/Test/dafny0/NestedMatch.dfy b/Test/dafny0/NestedMatch.dfy
index e6e7c489..81319b4a 100644
--- a/Test/dafny0/NestedMatch.dfy
+++ b/Test/dafny0/NestedMatch.dfy
@@ -28,7 +28,7 @@ function last<T>(xs: List<T>): T
case Cons(y, Cons(z, zs)) => last(Cons(z, zs))
}
-method checkLast(y: T) {
+method checkLast<T>(y: T) {
assert last(Cons(y, Nil)) == y;
assert last(Cons(y, Cons(y, Nil))) == last(Cons(y, Nil));
}
diff --git a/Test/dafny0/NestedPatterns.dfy b/Test/dafny0/NestedPatterns.dfy
index ef597936..d1d88b2a 100644
--- a/Test/dafny0/NestedPatterns.dfy
+++ b/Test/dafny0/NestedPatterns.dfy
@@ -69,7 +69,7 @@ method MethodG<T>(xs: List<T>) returns (xxs: List<List<T>>)
case Cons(h, Cons(ht, tt)) =>
}
-method AssertionFailure(xs: List<T>)
+method AssertionFailure(xs: List)
{
match xs
case (Nil) => // BUG: this line causes an assertion in the Dafny implementation (what should happen is that "(Nil)" should not be allowed here)
@@ -100,7 +100,7 @@ method DuplicateIdentifierInPattern2<T>(xs: List<T>)
case Cons(h, Cons(e, e)) => // BUG: here, the duplicate identifier is detected, but the error message is shown 3 times, which is less than ideal
}
-method Tuples0(xs: List<T>, ys: List<T>)
+method Tuples0(xs: List, ys: List)
{
match (xs, ys)
case (Nil, Nil) =>
@@ -110,14 +110,14 @@ method Tuples0(xs: List<T>, ys: List<T>)
// only the identifiers in the last constructors are
}
-method Tuples1(xs: List<T>, ys: List<T>)
+method Tuples1(xs: List, ys: List)
{
match (xs, ys, 4)
case (Nil, Nil) => // BUG: the mismatch of 3 versus 2 arguments in the previous line and this line causes Dafny to crash with an
// assertion failure "mc.CasePatterns.Count == e.Arguments.Count"
}
-method Tuples2(xs: List<T>, ys: List<T>)
+method Tuples2(xs: List, ys: List)
{
match (xs, ys, ())
case (Nil, Nil, ()) => // BUG: Dafny crashes with an assertion failure "e.Arguments.Count >= 1"
diff --git a/Test/dafny0/ResolutionErrors.dfy b/Test/dafny0/ResolutionErrors.dfy
index 761cffa0..8c910959 100644
--- a/Test/dafny0/ResolutionErrors.dfy
+++ b/Test/dafny0/ResolutionErrors.dfy
@@ -1253,14 +1253,14 @@ module SignatureCompletion {
datatype Dt = Ctor(X -> Dt) // error: X is not a declared type
datatype Et<Y> = Ctor(X -> Et, Y) // error: X is not a declared type
- // For methods and functions, signatures can auto-declare type parameters
- method My0(s: set, x: A -> B)
- method My1(x: A -> B, s: set)
+
+ method My0<A,B>(s: set, x: A -> B)
+ method My1<A,B>(x: A -> B, s: set)
method My2<A,B>(s: set, x: A -> B)
method My3<A,B>(x: A -> B, s: set)
- function F0(s: set, x: A -> B): int
- function F1(x: A -> B, s: set): int
+ function F0<A,B>(s: set, x: A -> B): int
+ function F1<A,B>(x: A -> B, s: set): int
function F2<A,B>(s: set, x: A -> B): int
function F3<A,B>(x: A -> B, s: set): int
}
diff --git a/Test/dafny0/Shadows.dfy b/Test/dafny0/Shadows.dfy
new file mode 100644
index 00000000..da1e74d6
--- /dev/null
+++ b/Test/dafny0/Shadows.dfy
@@ -0,0 +1,42 @@
+// RUN: %dafny /compile:0 /print:"%t.print" /dprint:"%t.dprint" /warnShadowing "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+module Module0 {
+ class C<alpha> {
+ method M<beta, beta>(x: beta) // error: duplicate type parameter
+ method P<alpha>(x: alpha) // shadowed type parameter
+ function F<beta, beta>(x: beta): int // error: duplicate type parameter
+ function G<alpha>(x: alpha): int // shadowed type parameter
+
+ method Q0(x: int) returns (x: int) // error: duplicate variable name
+ }
+}
+module Module1 {
+ class D {
+ method Q1(x: int) returns (y: int)
+ {
+ var x; // shadowed
+ var y; // error: duplicate
+ }
+
+ var f: int
+ method R()
+ {
+ var f; // okay
+ var f; // error: duplicate
+ }
+ method S()
+ {
+ var x;
+ {
+ var x; // shadow
+ }
+ }
+ method T()
+ {
+ var x;
+ ghost var b := forall x :: x < 10; // shadow
+ ghost var c := forall y :: forall y :: y != y + 1; // shadow
+ }
+ }
+}
diff --git a/Test/dafny0/Shadows.dfy.expect b/Test/dafny0/Shadows.dfy.expect
new file mode 100644
index 00000000..5083ac64
--- /dev/null
+++ b/Test/dafny0/Shadows.dfy.expect
@@ -0,0 +1,12 @@
+Shadows.dfy(6,19): Error: Duplicate type-parameter name: beta
+Shadows.dfy(7,13): Warning: Shadowed type-parameter name: alpha
+Shadows.dfy(8,21): Error: Duplicate type-parameter name: beta
+Shadows.dfy(9,15): Warning: Shadowed type-parameter name: alpha
+Shadows.dfy(11,31): Error: Duplicate parameter name: x
+Shadows.dfy(18,10): Warning: Shadowed local-variable name: x
+Shadows.dfy(19,10): Error: Duplicate local-variable name: y
+Shadows.dfy(26,10): Error: Duplicate local-variable name: f
+Shadows.dfy(32,12): Warning: Shadowed local-variable name: x
+Shadows.dfy(38,28): Warning: Shadowed bound-variable name: x
+Shadows.dfy(39,40): Warning: Shadowed bound-variable name: y
+5 resolution/type errors detected in Shadows.dfy
diff --git a/Test/dafny0/Trait/TraitsDecreases.dfy b/Test/dafny0/Trait/TraitsDecreases.dfy
index 53ce28be..8ab3672a 100644
--- a/Test/dafny0/Trait/TraitsDecreases.dfy
+++ b/Test/dafny0/Trait/TraitsDecreases.dfy
@@ -106,3 +106,49 @@ class CC extends TT {
decreases *
{ }
}
+
+
+// The following module contains various regression tests
+module More {
+ trait A0 {
+ predicate P() decreases 5
+ }
+ class B0 extends A0 {
+ predicate P() // error: rank is not lower
+ }
+
+ trait A1 {
+ predicate P() decreases 5
+ }
+ class B1 extends A1 {
+ predicate P() reads this // error: rank is not lower
+ }
+
+ trait A2 {
+ predicate P(x: int)
+ }
+ class B2 extends A2 {
+ predicate P(x: int) reads this // error: rank is not lower
+ }
+
+ trait A3 {
+ predicate P() reads this
+ }
+ class B3 extends A3 {
+ predicate P() // error: rank is not lower
+ }
+
+ trait A4 {
+ predicate P(x: int) decreases 5
+ }
+ class B4 extends A4 {
+ predicate P(x: int) // error: rank is not lower
+ }
+
+ trait A5 {
+ method M(x: int) decreases 5
+ }
+ class B5 extends A5 {
+ method M(x: int) // error: rank is not lower
+ }
+}
diff --git a/Test/dafny0/Trait/TraitsDecreases.dfy.expect b/Test/dafny0/Trait/TraitsDecreases.dfy.expect
index 6c76f9a8..2607a0c6 100644
--- a/Test/dafny0/Trait/TraitsDecreases.dfy.expect
+++ b/Test/dafny0/Trait/TraitsDecreases.dfy.expect
@@ -1,3 +1,21 @@
+TraitsDecreases.dfy(117,15): Error: predicate's decreases clause must be below or equal to that in the trait
+Execution trace:
+ (0,0): anon0
+TraitsDecreases.dfy(124,15): Error: predicate's decreases clause must be below or equal to that in the trait
+Execution trace:
+ (0,0): anon0
+TraitsDecreases.dfy(131,15): Error: predicate's decreases clause must be below or equal to that in the trait
+Execution trace:
+ (0,0): anon0
+TraitsDecreases.dfy(138,15): Error: predicate's decreases clause must be below or equal to that in the trait
+Execution trace:
+ (0,0): anon0
+TraitsDecreases.dfy(145,15): Error: predicate's decreases clause must be below or equal to that in the trait
+Execution trace:
+ (0,0): anon0
+TraitsDecreases.dfy(152,12): Error: method's decreases clause must be below or equal to that in the trait
+Execution trace:
+ (0,0): anon0
TraitsDecreases.dfy(57,10): Error: method's decreases clause must be below or equal to that in the trait
Execution trace:
(0,0): anon0
@@ -14,4 +32,4 @@ TraitsDecreases.dfy(88,10): Error: method's decreases clause must be below or eq
Execution trace:
(0,0): anon0
-Dafny program verifier finished with 63 verified, 5 errors
+Dafny program verifier finished with 75 verified, 11 errors
diff --git a/Test/dafny4/Circ.dfy b/Test/dafny4/Circ.dfy
index e7609195..d110c05c 100644
--- a/Test/dafny4/Circ.dfy
+++ b/Test/dafny4/Circ.dfy
@@ -16,6 +16,7 @@ function zip(a: Stream, b: Stream): Stream { Cons(a.head, zip(b, a.tail)) }
colemma BlinkZipProperty()
ensures zip(zeros(), ones()) == blink();
{
+ BlinkZipProperty();
}
// ----- Thue-Morse sequence -----
@@ -75,6 +76,7 @@ colemma FProperty(s: Stream<Bit>)
// def. zip
Cons(s.head, Cons(not(s).head, zip(s.tail, not(s).tail)));
}
+ FProperty(s.tail);
}
// The fix-point theorem now follows easily.
diff --git a/Test/dafny4/NipkowKlein-chapter3.dfy b/Test/dafny4/NipkowKlein-chapter3.dfy
index ab45f536..725d68f6 100644
--- a/Test/dafny4/NipkowKlein-chapter3.dfy
+++ b/Test/dafny4/NipkowKlein-chapter3.dfy
@@ -131,6 +131,12 @@ lemma AsimpCorrect(a: aexp, s: state)
forall a' | a' < a { AsimpCorrect(a', s); }
}
+// The following lemma is not in the Nipkow and Klein book, but it's a fun one to prove.
+lemma ASimplInvolutive(a: aexp)
+ ensures asimp(asimp(a)) == asimp(a)
+{
+}
+
// ----- boolean expressions -----
datatype bexp = Bc(v: bool) | Not(bexp) | And(bexp, bexp) | Less(aexp, aexp)
diff --git a/Test/dafny4/NipkowKlein-chapter3.dfy.expect b/Test/dafny4/NipkowKlein-chapter3.dfy.expect
index ab18d98e..bb45fee9 100644
--- a/Test/dafny4/NipkowKlein-chapter3.dfy.expect
+++ b/Test/dafny4/NipkowKlein-chapter3.dfy.expect
@@ -1,2 +1,2 @@
-Dafny program verifier finished with 28 verified, 0 errors
+Dafny program verifier finished with 30 verified, 0 errors
diff --git a/Test/dafny4/NumberRepresentations.dfy b/Test/dafny4/NumberRepresentations.dfy
index f51ae924..3dba6325 100644
--- a/Test/dafny4/NumberRepresentations.dfy
+++ b/Test/dafny4/NumberRepresentations.dfy
@@ -1,4 +1,4 @@
-// RUN: %dafny /compile:0 /vcsMaxKeepGoingSplits:5 /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %dafny /compile:0 /dprint:"%t.dprint" "%s" > "%t"
// RUN: %diff "%s.expect" "%t"
// We consider a number representation that consists of a sequence of digits. The least
diff --git a/Test/hofs/Classes.dfy b/Test/hofs/Classes.dfy
index 0ceb46f1..9d8044db 100644
--- a/Test/hofs/Classes.dfy
+++ b/Test/hofs/Classes.dfy
@@ -47,3 +47,20 @@ method U(t : T)
t.h := x => x;
assert J(t) == 0; // ok
}
+
+class MyClass {
+ var data: int
+ function method F(): int
+ reads this
+ {
+ data
+ }
+ method M(that: MyClass)
+ requires that != null
+ {
+ var fn := that.F; // "that" is captured into the closure
+ var d := fn();
+ assert d == that.data; // yes
+ assert d == this.data; // error: no reason to believe that this would hold
+ }
+}
diff --git a/Test/hofs/Classes.dfy.expect b/Test/hofs/Classes.dfy.expect
index e490dbe0..1c9e31f0 100644
--- a/Test/hofs/Classes.dfy.expect
+++ b/Test/hofs/Classes.dfy.expect
@@ -1,7 +1,10 @@
+Classes.dfy(64,12): Error: assertion violation
+Execution trace:
+ (0,0): anon0
Classes.dfy(40,6): Error: possible violation of function precondition
Execution trace:
(0,0): anon0
(0,0): anon7_Else
(0,0): anon8_Else
-Dafny program verifier finished with 6 verified, 1 error
+Dafny program verifier finished with 8 verified, 2 errors
diff --git a/Test/hofs/Examples.dfy b/Test/hofs/Examples.dfy
index be2672f5..306d278d 100644
--- a/Test/hofs/Examples.dfy
+++ b/Test/hofs/Examples.dfy
@@ -1,14 +1,14 @@
// RUN: %dafny /print:"%t.print" "%s" > "%t"
// RUN: %diff "%s.expect" "%t"
-function Apply(f: A -> B, x: A): B
+function Apply<A,B>(f: A -> B, x: A): B
reads f.reads(x);
requires f.requires(x);
{
f(x)
}
-function Apply'(f: A -> B) : A -> B
+function Apply'<A,B>(f: A -> B) : A -> B
{
x reads f.reads(x)
requires f.requires(x)
@@ -16,7 +16,7 @@ function Apply'(f: A -> B) : A -> B
}
-function Compose(f: B -> C, g:A -> B): A -> C
+function Compose<A,B,C>(f: B -> C, g:A -> B): A -> C
{
x reads g.reads(x)
reads if g.requires(x) then f.reads(g(x)) else {}
@@ -25,21 +25,21 @@ function Compose(f: B -> C, g:A -> B): A -> C
=> f(g(x))
}
-function W(f : (A,A) -> A): A -> A
+function W<A>(f : (A,A) -> A): A -> A
{
x requires f.requires(x,x)
reads f.reads(x,x)
=> f(x,x)
}
-function Curry(f : (A,B) -> C) : A -> B -> C
+function Curry<A,B,C>(f : (A,B) -> C) : A -> B -> C
{
x => y requires f.requires(x,y)
reads f.reads(x,y)
=> f(x,y)
}
-function Uncurry(f : A -> B -> C) : (A,B) -> C
+function Uncurry<A,B,C>(f : A -> B -> C) : (A,B) -> C
{
(x,y) requires f.requires(x)
requires f(x).requires(y)
@@ -48,7 +48,7 @@ function Uncurry(f : A -> B -> C) : (A,B) -> C
=> f(x)(y)
}
-function S(f : (A,B) -> C, g : A -> B): A -> C
+function S<A,B,C>(f : (A,B) -> C, g : A -> B): A -> C
{
x requires g.requires(x)
requires f.requires(x,g(x))
diff --git a/Test/hofs/Fold.dfy b/Test/hofs/Fold.dfy
index 6ca2d3b1..9bcd9e02 100644
--- a/Test/hofs/Fold.dfy
+++ b/Test/hofs/Fold.dfy
@@ -13,7 +13,7 @@ function method Eval(e : Expr): int
case Lit(i) => i
}
-function method Fold(xs : List<A>, unit : B, f : (A,B) -> B): B
+function method Fold<A,B>(xs : List<A>, unit : B, f : (A,B) -> B): B
reads f.reads;
requires forall x, y :: x < xs ==> f.requires(x,y);
{
diff --git a/Test/hofs/Monads.dfy b/Test/hofs/Monads.dfy
index 3598d2b3..633dd339 100644
--- a/Test/hofs/Monads.dfy
+++ b/Test/hofs/Monads.dfy
@@ -4,29 +4,29 @@
abstract module Monad {
type M<A>
- function method Return(x: A): M<A>
- function method Bind(m: M<A>, f:A -> M<B>):M<B>
- reads f.reads;
- requires forall a :: f.requires(a);
+ function method Return<A>(x: A): M<A>
+ function method Bind<A,B>(m: M<A>, f:A -> M<B>):M<B>
+ reads f.reads
+ requires forall a :: f.requires(a)
// return x >>= f = f x
- lemma LeftIdentity(x : A, f : A -> M<B>)
- requires forall a :: f.requires(a);
- ensures Bind(Return(x),f) == f(x);
+ lemma LeftIdentity<A,B>(x : A, f : A -> M<B>)
+ requires forall a :: f.requires(a)
+ ensures Bind(Return(x),f) == f(x)
// m >>= return = m
- lemma RightIdentity(m : M<A>)
- ensures Bind(m,Return) == m;
+ lemma RightIdentity<A>(m : M<A>)
+ ensures Bind(m,Return) == m
// (m >>= f) >>= g = m >>= (x => f(x) >>= g)
- lemma Associativity(m : M<A>, f:A -> M<B>, g: B -> M<C>)
- requires forall a :: f.requires(a);
- requires forall b :: g.requires(b);
+ lemma Associativity<A,B,C>(m : M<A>, f:A -> M<B>, g: B -> M<C>)
+ requires forall a :: f.requires(a)
+ requires forall b :: g.requires(b)
ensures Bind(Bind(m,f),g) ==
Bind(m,x reads f.reads(x)
reads g.reads
requires f.requires(x)
- requires forall b :: g.requires(b) => Bind(f(x),g));
+ requires forall b :: g.requires(b) => Bind(f(x),g))
}
module Identity refines Monad {
@@ -101,21 +101,21 @@ module List refines Monad {
function method Return<A>(x: A): M<A>
{ Cons(x,Nil) }
- function method Concat(xs: M<A>, ys: M<A>): M<A>
+ function method Concat<A>(xs: M<A>, ys: M<A>): M<A>
{
match xs
case Nil => ys
case Cons(x,xs) => Cons(x,Concat(xs,ys))
}
- function method Join(xss: M<M<A>>) : M<A>
+ function method Join<A>(xss: M<M<A>>) : M<A>
{
match xss
case Nil => Nil
case Cons(xs,xss) => Concat(xs,Join(xss))
}
- function method Map(xs: M<A>, f: A -> B):M<B>
+ function method Map<A,B>(xs: M<A>, f: A -> B):M<B>
reads f.reads;
requires forall a :: f.requires(a);
{
@@ -170,7 +170,7 @@ module List refines Monad {
ensures Concat(Concat(xs,ys),zs) == Concat(xs,Concat(ys,zs));
{}
- lemma BindMorphism(xs : M<A>, ys: M<A>, f : A -> M<B>)
+ lemma BindMorphism<A,B>(xs : M<A>, ys: M<A>, f : A -> M<B>)
requires forall a :: f.requires(a);
ensures Bind(Concat(xs,ys),f) == Concat(Bind(xs,f),Bind(ys,f));
{
diff --git a/Test/hofs/Naked.dfy b/Test/hofs/Naked.dfy
index fa99377f..d23eb507 100644
--- a/Test/hofs/Naked.dfy
+++ b/Test/hofs/Naked.dfy
@@ -19,17 +19,17 @@ module Functions {
module Requires {
function t(x: nat): nat
- requires !t.requires(x);
+ requires !t.requires(x); // error: use of naked function in its own SCC
{ x }
function g(x: nat): nat
- requires !(g).requires(x);
+ requires !(g).requires(x); // error: use of naked function in its own SCC
{ x }
- function g2(x: int): int { h(x) }
-
+ function D(x: int): int // used so termination errors don't mask other errors
+ function g2(x: int): int decreases D(x) { h(x) } // error: precondition violation
function h(x: int): int
- requires !g2.requires(x);
+ requires !g2.requires(x); // error: use of naked function in its own SCC
{ x }
}
diff --git a/Test/hofs/Naked.dfy.expect b/Test/hofs/Naked.dfy.expect
index b4dfc561..514952a1 100644
--- a/Test/hofs/Naked.dfy.expect
+++ b/Test/hofs/Naked.dfy.expect
@@ -21,11 +21,7 @@ Execution trace:
Naked.dfy(26,14): Error: cannot use naked function in recursive setting. Possible solution: eta expansion.
Execution trace:
(0,0): anon0
-Naked.dfy(29,30): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
-Naked.dfy(29,30): Error: possible violation of function precondition
+Naked.dfy(30,45): Error: possible violation of function precondition
Naked.dfy(32,14): Related location
Execution trace:
(0,0): anon0
@@ -47,4 +43,4 @@ Naked.dfy(48,11): Error: cannot use naked function in recursive setting. Possibl
Execution trace:
(0,0): anon0
-Dafny program verifier finished with 1 verified, 12 errors
+Dafny program verifier finished with 2 verified, 11 errors
diff --git a/Test/hofs/ReadsReads.dfy b/Test/hofs/ReadsReads.dfy
index e11473bd..a6f8d922 100644
--- a/Test/hofs/ReadsReads.dfy
+++ b/Test/hofs/ReadsReads.dfy
@@ -2,58 +2,58 @@
// RUN: %diff "%s.expect" "%t"
module ReadsRequiresReads {
- function MyReadsOk(f : A -> B, a : A) : set<object>
- reads f.reads(a);
+ function MyReadsOk<A,B>(f : A -> B, a : A) : set<object>
+ reads f.reads(a)
{
f.reads(a)
}
- function MyReadsOk2(f : A -> B, a : A) : set<object>
- reads f.reads(a);
+ function MyReadsOk2<A,B>(f : A -> B, a : A) : set<object>
+ reads f.reads(a)
{
(f.reads)(a)
}
- function MyReadsOk3(f : A -> B, a : A) : set<object>
- reads (f.reads)(a);
+ function MyReadsOk3<A,B>(f : A -> B, a : A) : set<object>
+ reads (f.reads)(a)
{
f.reads(a)
}
- function MyReadsOk4(f : A -> B, a : A) : set<object>
- reads (f.reads)(a);
+ function MyReadsOk4<A,B>(f : A -> B, a : A) : set<object>
+ reads (f.reads)(a)
{
(f.reads)(a)
}
- function MyReadsBad(f : A -> B, a : A) : set<object>
+ function MyReadsBad<A,B>(f : A -> B, a : A) : set<object>
{
f.reads(a) // error: MyReadsBad does not have permission to read what f.reads(a) reads
}
- function MyReadsBad2(f : A -> B, a : A) : set<object>
+ function MyReadsBad2<A,B>(f : A -> B, a : A) : set<object>
{
(f.reads)(a) // error: MyReadsBad2 does not have permission to read what f.reads(a) reads
}
- function MyReadsOk'(f : A -> B, a : A, o : object) : bool
- reads f.reads(a);
+ function MyReadsOk'<A,B>(f : A -> B, a : A, o : object) : bool
+ reads f.reads(a)
{
o in f.reads(a)
}
- function MyReadsBad'(f : A -> B, a : A, o : object) : bool
+ function MyReadsBad'<A,B>(f : A -> B, a : A, o : object) : bool
{
o in f.reads(a) // error: MyReadsBad' does not have permission to read what f.reads(a) reads
}
- function MyRequiresOk(f : A -> B, a : A) : bool
- reads f.reads(a);
+ function MyRequiresOk<A,B>(f : A -> B, a : A) : bool
+ reads f.reads(a)
{
f.requires(a)
}
- function MyRequiresBad(f : A -> B, a : A) : bool
+ function MyRequiresBad<A,B>(f : A -> B, a : A) : bool
{
f.requires(a) // error: MyRequiresBad does not have permission to read what f.requires(a) reads
}
@@ -72,11 +72,11 @@ module WhatWeKnowAboutReads {
}
class S {
- var s : S;
+ var s : S
}
function ReadsSomething(s : S):()
- reads s;
+ reads s
{()}
method MaybeSomething() {
@@ -105,29 +105,29 @@ module WhatWeKnowAboutReads {
module ReadsAll {
function A(f: int -> int) : int
- reads set o,x | o in f.reads(x) :: o;
- requires forall x :: f.requires(x);
+ reads set o,x | o in f.reads(x) :: o
+ requires forall x :: f.requires(x)
{
f(0) + f(1) + f(2)
}
function method B(f: int -> int) : int
- reads set o,x | o in f.reads(x) :: o;
- requires forall x :: f.requires(x);
+ reads set o,x | o in f.reads(x) :: o
+ requires forall x :: f.requires(x)
{
f(0) + f(1) + f(2)
}
function C(f: int -> int) : int
- reads f.reads;
- requires forall x :: f.requires(x);
+ reads f.reads
+ requires forall x :: f.requires(x)
{
f(0) + f(1) + f(2)
}
function method D(f: int -> int) : int
- reads f.reads;
- requires forall x :: f.requires(x);
+ reads f.reads
+ requires forall x :: f.requires(x)
{
f(0) + f(1) + f(2)
}
diff --git a/Test/hofs/Requires.dfy b/Test/hofs/Requires.dfy
new file mode 100644
index 00000000..68677b3e
--- /dev/null
+++ b/Test/hofs/Requires.dfy
@@ -0,0 +1,82 @@
+// RUN: %dafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+method Main()
+{
+ test0(10);
+ test5(11);
+ test6(12);
+ test1();
+ test2();
+}
+
+predicate valid(x:int)
+{
+ x > 0
+}
+
+function ref1(y:int) : int
+ requires valid(y);
+{
+ y - 1
+}
+
+lemma assumption1()
+ ensures forall a, b :: valid(a) && valid(b) && ref1(a) == ref1(b) ==> a == b;
+{
+}
+
+method test0(a: int)
+{
+ if ref1.requires(a) {
+ // the precondition should suffice to let us call the method
+ ghost var b := ref1(a);
+ }
+}
+method test5(a: int)
+{
+ if valid(a) {
+ // valid(a) is the precondition of ref1
+ assert ref1.requires(a);
+ }
+}
+method test6(a: int)
+{
+ if ref1.requires(a) {
+ // the precondition of ref1 is valid(a)
+ assert valid(a);
+ }
+}
+
+method test1()
+{
+ if * {
+ assert forall a, b :: valid(a) && valid(b) && ref1(a) == ref1(b) ==> a == b;
+ } else {
+ assert forall a, b :: ref1.requires(a) && ref1.requires(b) && ref1(a) == ref1(b)
+ ==> a == b;
+ }
+}
+
+function {:opaque} ref2(y:int) : int // Now with an opaque attribute
+ requires valid(y);
+{
+ y - 1
+}
+
+lemma assumption2()
+ ensures forall a, b :: valid(a) && valid(b) && ref2(a) == ref2(b) ==> a == b;
+{
+ reveal_ref2();
+}
+
+method test2()
+{
+ assumption2();
+ if * {
+ assert forall a, b :: valid(a) && valid(b) && ref2(a) == ref2(b) ==> a == b;
+ } else {
+ assert forall a, b :: ref2.requires(a) && ref2.requires(b) && ref2(a) == ref2(b)
+ ==> a == b;
+ }
+}
diff --git a/Test/hofs/Requires.dfy.expect b/Test/hofs/Requires.dfy.expect
new file mode 100644
index 00000000..b9a40d66
--- /dev/null
+++ b/Test/hofs/Requires.dfy.expect
@@ -0,0 +1,5 @@
+
+Dafny program verifier finished with 20 verified, 0 errors
+Program compiled successfully
+Running...
+
diff --git a/Test/hofs/ResolveError.dfy b/Test/hofs/ResolveError.dfy
index 3c0d7cd9..ae838eb3 100644
--- a/Test/hofs/ResolveError.dfy
+++ b/Test/hofs/ResolveError.dfy
@@ -3,9 +3,9 @@
method ResolutionErrors() {
- var x;
- var g5 := x, y => (y, x); // fail at resolution
- var g6 := x, (y => (y, x)); // fail at resolution
+ var x;
+ var g5 := x, y => (y, x); // fail at resolution
+ var g6 := x, (y => (y, x)); // fail at resolution
}
// cannot assign functions
@@ -23,20 +23,20 @@ method Nope3() {
method RequiresFail(f : int -> int)
// ok
- requires f(0) == 0;
- requires f.requires(0);
- requires f.reads(0) == {};
+ requires f(0) == 0
+ requires f.requires(0)
+ requires f.reads(0) == {}
// fail
- requires f(0) == true;
- requires f(1,2) == 0;
- requires f(true) == 0;
- requires f.requires(true);
- requires f.requires(1) == 0;
- requires f.requires(1,2);
- requires f.reads(true) == {};
- requires f.reads(1) == 0;
- requires f.reads(1,2) == {};
+ requires f(0) == true
+ requires f(1,2) == 0
+ requires f(true) == 0
+ requires f.requires(true)
+ requires f.requires(1) == 0
+ requires f.requires(1,2)
+ requires f.reads(true) == {}
+ requires f.reads(1) == 0
+ requires f.reads(1,2) == {}
{
}
@@ -56,7 +56,7 @@ method Bla() {
assert Bool;
}
-method Pli(f : A -> B) requires f != null;
+method Pli<A,B>(f : A -> B) requires f != null
{
var o : object;
assert f != o;
@@ -102,7 +102,7 @@ module AritySituations {
w := V; // error
}
- method P(r: T -> U, x: T) returns (u: U)
+ method P<T,U>(r: T -> U, x: T) returns (u: U)
requires r.requires(x);
{
u := r(x);
diff --git a/Test/hofs/ResolveError.dfy.expect b/Test/hofs/ResolveError.dfy.expect
index c3e0c242..11471ffd 100644
--- a/Test/hofs/ResolveError.dfy.expect
+++ b/Test/hofs/ResolveError.dfy.expect
@@ -2,8 +2,8 @@ ResolveError.dfy(86,6): Error: RHS (of type ((int,bool)) -> real) not assignable
ResolveError.dfy(91,15): Error: incorrect type of method in-parameter 0 (expected ? -> ?, got (int,bool) -> real)
ResolveError.dfy(101,6): Error: RHS (of type (()) -> real) not assignable to LHS (of type () -> real)
ResolveError.dfy(102,6): Error: RHS (of type () -> real) not assignable to LHS (of type (()) -> real)
-ResolveError.dfy(7,11): Error: the number of left-hand sides (1) and right-hand sides (2) must match for a multi-assignment
-ResolveError.dfy(8,11): Error: the number of left-hand sides (1) and right-hand sides (2) must match for a multi-assignment
+ResolveError.dfy(7,9): Error: the number of left-hand sides (1) and right-hand sides (2) must match for a multi-assignment
+ResolveError.dfy(8,9): Error: the number of left-hand sides (1) and right-hand sides (2) must match for a multi-assignment
ResolveError.dfy(21,6): Error: LHS of assignment must denote a mutable field
ResolveError.dfy(31,16): Error: arguments must have the same type (got int and bool)
ResolveError.dfy(32,12): Error: wrong number of arguments to function application (function type 'int -> int' expects 1, got 2)
@@ -17,7 +17,7 @@ ResolveError.dfy(39,18): Error: wrong number of arguments to function applicatio
ResolveError.dfy(46,15): Error: a reads-clause expression must denote an object or a collection of objects (instead got int)
ResolveError.dfy(47,7): Error: Precondition must be boolean (got int)
ResolveError.dfy(56,9): Error: condition is expected to be of type bool, but is () -> bool
-ResolveError.dfy(59,34): Error: arguments must have the same type (got A -> B and ?)
+ResolveError.dfy(59,39): Error: arguments must have the same type (got A -> B and ?)
ResolveError.dfy(62,11): Error: arguments must have the same type (got A -> B and object)
ResolveError.dfy(68,24): Error: unresolved identifier: _
22 resolution/type errors detected in ResolveError.dfy
diff --git a/Test/hofs/Simple.dfy b/Test/hofs/Simple.dfy
index c27fa82c..6d98531e 100644
--- a/Test/hofs/Simple.dfy
+++ b/Test/hofs/Simple.dfy
@@ -50,7 +50,7 @@ method Main() {
}
function method succ(x : int) : int
- requires x > 0;
+ requires x > 0
{
x + 1
}
@@ -74,24 +74,24 @@ method Main3() {
}
-function P(f: A -> B, x : A): B
- reads (f.reads)(x);
- requires (f.requires)(x);
+function P<A,B>(f: A -> B, x : A): B
+ reads (f.reads)(x)
+ requires (f.requires)(x)
{
f(x)
}
-function Q(f: U -> V, x : U): V
- reads P.reads(f,x);
- requires f.requires(x); // would be nice to be able to write P.requires(f,x)
+function Q<U,V>(f: U -> V, x : U): V
+ reads P.reads(f,x)
+ requires f.requires(x) // would be nice to be able to write P.requires(f,x)
{
P(f,x)
}
-function QQ(f: U -> V, x : U): V
- reads ((() => ((()=>f)()).reads)())((()=>x)());
- requires ((() => ((()=>f)()).requires)())((()=>x)());
+function QQ<U,V>(f: U -> V, x : U): V
+ reads ((() => ((()=>f)()).reads)())((()=>x)())
+ requires ((() => ((()=>f)()).requires)())((()=>x)())
{
((() => P)())((()=>f)(),(()=>x)())
}
diff --git a/Test/hofs/Simple.dfy.expect b/Test/hofs/Simple.dfy.expect
index 1a1027ae..e2f16ef3 100644
--- a/Test/hofs/Simple.dfy.expect
+++ b/Test/hofs/Simple.dfy.expect
@@ -20,13 +20,10 @@ Execution trace:
Simple.dfy(61,10): Error: possible violation of function precondition
Execution trace:
(0,0): anon0
-Simple.dfy(61,18): Error: assertion violation
-Execution trace:
- (0,0): anon0
Simple.dfy(73,10): Error: assertion violation
Execution trace:
(0,0): anon0
Simple.dfy(72,38): anon5_Else
Simple.dfy(73,38): anon6_Else
-Dafny program verifier finished with 14 verified, 7 errors
+Dafny program verifier finished with 14 verified, 6 errors
diff --git a/Test/hofs/TreeMapSimple.dfy b/Test/hofs/TreeMapSimple.dfy
index a853b82c..6b8f1377 100644
--- a/Test/hofs/TreeMapSimple.dfy
+++ b/Test/hofs/TreeMapSimple.dfy
@@ -6,7 +6,7 @@ datatype List<A> = Nil | Cons(head: A,tail: List<A>)
datatype Tree<A> = Branch(val: A,trees: List<Tree<A>>)
function ListData(xs : List) : set
- ensures forall x :: x in ListData(xs) ==> x < xs;
+ ensures forall x :: x in ListData(xs) ==> x < xs
{
match xs
case Nil => {}
@@ -14,32 +14,32 @@ function ListData(xs : List) : set
}
function TreeData(t0 : Tree) : set
- ensures forall t :: t in TreeData(t0) ==> t < t0;
+ ensures forall t :: t in TreeData(t0) ==> t < t0
{
var Branch(x,ts) := t0;
{x} + set t, y | t in ListData(ts) && y in TreeData(t) :: y
}
-function Pre(f : A -> B, s : set<A>) : bool
- reads (set x, y | x in s && y in f.reads(x) :: y);
+function Pre<A,B>(f : A -> B, s : set<A>) : bool
+ reads (set x, y | x in s && y in f.reads(x) :: y)
{
forall x :: x in s ==> f.reads(x) == {} && f.requires(x)
}
-function method Map(xs : List<A>, f : A -> B): List<B>
- reads Pre.reads(f, ListData(xs));
- requires Pre(f, ListData(xs));
- decreases xs;
+function method Map<A,B>(xs : List<A>, f : A -> B): List<B>
+ reads Pre.reads(f, ListData(xs))
+ requires Pre(f, ListData(xs))
+ decreases xs
{
match xs
case Nil => Nil
case Cons(x,xs) => Cons(f(x),Map(xs,f))
}
-function method TMap(t0 : Tree<A>, f : A -> B) : Tree<B>
- reads Pre.reads(f, TreeData(t0));
- requires Pre(f, TreeData(t0));
- decreases t0;
+function method TMap<A,B>(t0 : Tree<A>, f : A -> B) : Tree<B>
+ reads Pre.reads(f, TreeData(t0))
+ requires Pre(f, TreeData(t0))
+ decreases t0
{
var Branch(x,ts) := t0;
Branch(f(x),Map(ts, t requires t in ListData(ts)
diff --git a/Test/hofs/Twice.dfy b/Test/hofs/Twice.dfy
index add7e83c..5d948a58 100644
--- a/Test/hofs/Twice.dfy
+++ b/Test/hofs/Twice.dfy
@@ -1,7 +1,7 @@
// RUN: %dafny /print:"%t.print" "%s" > "%t"
// RUN: %diff "%s.expect" "%t"
-function method Twice(f : A -> A): A -> A
+function method Twice<A>(f : A -> A): A -> A
{
x requires f.requires(x) && f.requires(f(x))
reads f.reads(x) reads if f.requires(x) then f.reads(f(x)) else {}
@@ -29,7 +29,7 @@ method WithReads() {
}
-function method Twice_bad(f : A -> A): A -> A
+function method Twice_bad<A>(f : A -> A): A -> A
{
x requires f.requires(x) && f.requires(f(x))
reads f.reads(x) + f.reads(f(x))
diff --git a/Test/hofs/VectorUpdate.dfy b/Test/hofs/VectorUpdate.dfy
index 96edbe77..ca6b20b3 100644
--- a/Test/hofs/VectorUpdate.dfy
+++ b/Test/hofs/VectorUpdate.dfy
@@ -1,28 +1,59 @@
// RUN: %dafny /compile:3 "%s" > "%t"
// RUN: %diff "%s.expect" "%t"
-method VectorUpdate(N: int, a : array<A>, f : (int,A) -> A)
- requires a != null;
- requires N == a.Length;
- requires forall j :: 0 <= j < N ==> f.requires(j,a[j]);
- requires forall j :: 0 <= j < N ==> a !in f.reads(j,a[j]);
- modifies a;
- ensures forall j :: 0 <= j < N ==> a[j] == f(j,old(a[j]));
+// this is a rather verbose version of the VectorUpdate method
+method VectorUpdate<A>(N: int, a : array<A>, f : (int,A) -> A)
+ requires a != null
+ requires N == a.Length
+ requires forall j :: 0 <= j < N ==> f.requires(j,a[j])
+ requires forall j :: 0 <= j < N ==> a !in f.reads(j,a[j])
+ modifies a
+ ensures forall j :: 0 <= j < N ==> a[j] == f(j,old(a[j]))
{
var i := 0;
- while (i < N)
- invariant 0 <= i <= N;
- invariant forall j :: i <= j < N ==> f.requires(j,a[j]);
- invariant forall j :: 0 <= j < N ==> f.requires(j,old(a[j]));
- invariant forall j :: i <= j < N ==> a !in f.reads(j,a[j]);
- invariant forall j :: i <= j < N ==> a[j] == old(a[j]);
- invariant forall j :: 0 <= j < i ==> a[j] == f(j,old(a[j]));
+ while i < N
+ invariant 0 <= i <= N
+ invariant forall j :: i <= j < N ==> f.requires(j,a[j])
+ invariant forall j :: 0 <= j < N ==> f.requires(j,old(a[j]))
+ invariant forall j :: i <= j < N ==> a !in f.reads(j,a[j])
+ invariant forall j :: i <= j < N ==> a[j] == old(a[j])
+ invariant forall j :: 0 <= j < i ==> a[j] == f(j,old(a[j]))
{
a[i] := f(i,a[i]);
i := i + 1;
}
}
+// here's a shorter version of the method above
+method VectorUpdate'<A>(a : array<A>, f : (int,A) -> A)
+ requires a != null
+ requires forall j :: 0 <= j < a.Length ==> a !in f.reads(j,a[j]) && f.requires(j,a[j])
+ modifies a
+ ensures forall j :: 0 <= j < a.Length ==> a[j] == f(j,old(a[j]))
+{
+ var i := 0;
+ while i < a.Length
+ invariant 0 <= i <= a.Length
+ invariant forall j :: i <= j < a.Length ==> a[j] == old(a[j])
+ invariant forall j :: 0 <= j < i ==> a[j] == f(j,old(a[j]))
+ {
+ a[i] := f(i,a[i]);
+ i := i + 1;
+ }
+}
+
+// here's yet another version
+method VectorUpdate''<A>(a : array<A>, f : (int,A) -> A)
+ requires a != null
+ requires forall j :: 0 <= j < a.Length ==> a !in f.reads(j,a[j]) && f.requires(j,a[j])
+ modifies a
+ ensures forall j :: 0 <= j < a.Length ==> a[j] == f(j,old(a[j]))
+{
+ forall i | 0 <= i < a.Length {
+ a[i] := f(i,a[i]);
+ }
+}
+
method Main()
{
var v := new int[10];
@@ -46,11 +77,11 @@ method Main()
}
method PrintArray(a : array<int>)
- requires a != null;
+ requires a != null
{
var i := 0;
- while (i < a.Length) {
- if (i != 0) {
+ while i < a.Length {
+ if i != 0 {
print ", ";
}
print a[i];
diff --git a/Test/hofs/VectorUpdate.dfy.expect b/Test/hofs/VectorUpdate.dfy.expect
index b01ace00..18a7b110 100644
--- a/Test/hofs/VectorUpdate.dfy.expect
+++ b/Test/hofs/VectorUpdate.dfy.expect
@@ -1,5 +1,5 @@
-Dafny program verifier finished with 6 verified, 0 errors
+Dafny program verifier finished with 10 verified, 0 errors
Program compiled successfully
Running...
diff --git a/Test/irondafny0/FIFO.dfy b/Test/irondafny0/FIFO.dfy
new file mode 100644
index 00000000..ded8f567
--- /dev/null
+++ b/Test/irondafny0/FIFO.dfy
@@ -0,0 +1,43 @@
+// RUN: %dafny /ironDafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+include "Queue.dfyi"
+
+module FIFO exclusively refines Queue {
+ type Item = int
+
+ method Init() returns (q: Queue) {
+ q := [];
+ }
+
+ method Push(item: Item, q: Queue) returns (q': Queue) {
+ return q + [item];
+ }
+
+ method Pop(q: Queue) returns (item: Item, q': Queue)
+ ensures item == q[0]
+ {
+ item := q[0];
+ q' := q[1..];
+ }
+}
+
+module MainImpl refines MainSpec {
+ import Q = FIFO
+
+ method Main()
+ {
+ var q := Q.Init();
+ q := Q.Push(0, q);
+ q := Q.Push(1, q);
+ q := Q.Push(2, q);
+
+ var n: int;
+ n, q := Q.Pop(q);
+ print n, "\n";
+ n, q := Q.Pop(q);
+ print n, "\n";
+ n, q := Q.Pop(q);
+ print n, "\n";
+ }
+}
diff --git a/Test/irondafny0/FIFO.dfy.expect b/Test/irondafny0/FIFO.dfy.expect
new file mode 100644
index 00000000..25021947
--- /dev/null
+++ b/Test/irondafny0/FIFO.dfy.expect
@@ -0,0 +1,8 @@
+
+Dafny program verifier finished with 8 verified, 0 errors
+Program compiled successfully
+Running...
+
+0
+1
+2
diff --git a/Test/irondafny0/LIFO.dfy b/Test/irondafny0/LIFO.dfy
new file mode 100644
index 00000000..8c0a08e8
--- /dev/null
+++ b/Test/irondafny0/LIFO.dfy
@@ -0,0 +1,43 @@
+// RUN: %dafny /ironDafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+include "Queue.dfyi"
+
+module LIFO exclusively refines Queue {
+ type Item = int
+
+ method Init() returns (q: Queue) {
+ q := [];
+ }
+
+ method Push(item: Item, q: Queue) returns (q': Queue) {
+ return [item] + q;
+ }
+
+ method Pop(q: Queue) returns (item: Item, q': Queue)
+ ensures item == q[0]
+ {
+ item := q[0];
+ q' := q[1..];
+ }
+}
+
+module MainImpl refines MainSpec {
+ import Q = LIFO
+
+ method Main()
+ {
+ var q := Q.Init();
+ q := Q.Push(0, q);
+ q := Q.Push(1, q);
+ q := Q.Push(2, q);
+
+ var n: int;
+ n, q := Q.Pop(q);
+ print n, "\n";
+ n, q := Q.Pop(q);
+ print n, "\n";
+ n, q := Q.Pop(q);
+ print n, "\n";
+ }
+}
diff --git a/Test/irondafny0/LIFO.dfy.expect b/Test/irondafny0/LIFO.dfy.expect
new file mode 100644
index 00000000..83f90a5b
--- /dev/null
+++ b/Test/irondafny0/LIFO.dfy.expect
@@ -0,0 +1,8 @@
+
+Dafny program verifier finished with 8 verified, 0 errors
+Program compiled successfully
+Running...
+
+2
+1
+0
diff --git a/Test/irondafny0/Queue.dfyi b/Test/irondafny0/Queue.dfyi
new file mode 100644
index 00000000..9f7eb534
--- /dev/null
+++ b/Test/irondafny0/Queue.dfyi
@@ -0,0 +1,22 @@
+// Queue.dfyi
+
+abstract module Queue {
+ type Item
+ type Queue = seq<Item>
+
+ method Init() returns (q: Queue)
+ ensures |q| == 0;
+
+ method Push(item: Item, q: Queue) returns (q': Queue)
+ ensures |q'| == |q| + 1;
+
+ method Pop(q: Queue) returns (item: Item, q': Queue)
+ requires |q| > 0;
+ ensures item in q;
+ ensures |q'| == |q| - 1;
+}
+
+abstract module MainSpec {
+ import Q as Queue
+}
+
diff --git a/Test/irondafny0/inheritreqs0.dfy b/Test/irondafny0/inheritreqs0.dfy
new file mode 100644
index 00000000..a0117da0
--- /dev/null
+++ b/Test/irondafny0/inheritreqs0.dfy
@@ -0,0 +1,22 @@
+// RUN: %dafny /compile:3 /optimize /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+abstract module Spec {
+ method Greet(b: bool)
+ requires b;
+}
+
+module Impl refines Spec {
+ method Greet(b: bool) {
+ print "o hai!\n";
+ }
+
+ method Xyzzy(b: bool)
+ requires b;
+ {}
+
+ method Main() {
+ Greet(false);
+ Xyzzy(false);
+ }
+}
diff --git a/Test/irondafny0/inheritreqs0.dfy.expect b/Test/irondafny0/inheritreqs0.dfy.expect
new file mode 100644
index 00000000..eaadc85a
--- /dev/null
+++ b/Test/irondafny0/inheritreqs0.dfy.expect
@@ -0,0 +1,6 @@
+inheritreqs0.dfy(19,14): Error BP5002: A precondition for this call might not hold.
+inheritreqs0.dfy[Impl](6,18): Related location: This is the precondition that might not hold.
+Execution trace:
+ (0,0): anon0
+
+Dafny program verifier finished with 6 verified, 1 error
diff --git a/Test/irondafny0/inheritreqs1.dfy b/Test/irondafny0/inheritreqs1.dfy
new file mode 100644
index 00000000..c83d04ac
--- /dev/null
+++ b/Test/irondafny0/inheritreqs1.dfy
@@ -0,0 +1,22 @@
+// RUN: %dafny /compile:3 /optimize /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+abstract module Spec {
+ method Greet(b: bool)
+ requires b;
+}
+
+module Impl refines Spec {
+ method Greet(b: bool) {
+ print "o hai!\n";
+ }
+
+ method Xyzzy(b: bool)
+ requires b;
+ {}
+
+ method Main() {
+ Greet(true);
+ Xyzzy(false);
+ }
+}
diff --git a/Test/irondafny0/inheritreqs1.dfy.expect b/Test/irondafny0/inheritreqs1.dfy.expect
new file mode 100644
index 00000000..27c76fee
--- /dev/null
+++ b/Test/irondafny0/inheritreqs1.dfy.expect
@@ -0,0 +1,6 @@
+inheritreqs1.dfy(20,14): Error BP5002: A precondition for this call might not hold.
+inheritreqs1.dfy(15,18): Related location: This is the precondition that might not hold.
+Execution trace:
+ (0,0): anon0
+
+Dafny program verifier finished with 6 verified, 1 error
diff --git a/Test/irondafny0/opened_workaround.dfy b/Test/irondafny0/opened_workaround.dfy
new file mode 100644
index 00000000..7464c346
--- /dev/null
+++ b/Test/irondafny0/opened_workaround.dfy
@@ -0,0 +1,21 @@
+// RUN: %dafny /ironDafny /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+module A {
+
+ predicate P()
+
+ class C
+ {
+ static method{:axiom} M()
+ ensures P();
+ }
+}
+
+abstract module B {
+ import opened A
+}
+
+abstract module C {
+ import Bee as B // Works
+}
diff --git a/Test/irondafny0/opened_workaround.dfy.expect b/Test/irondafny0/opened_workaround.dfy.expect
new file mode 100644
index 00000000..0be94b4c
--- /dev/null
+++ b/Test/irondafny0/opened_workaround.dfy.expect
@@ -0,0 +1,3 @@
+
+Dafny program verifier finished with 3 verified, 0 errors
+Compilation error: Function _0_A_Compile._default.P has no body
diff --git a/Test/irondafny0/xrefine0.dfy b/Test/irondafny0/xrefine0.dfy
new file mode 100644
index 00000000..b849111c
--- /dev/null
+++ b/Test/irondafny0/xrefine0.dfy
@@ -0,0 +1,6 @@
+// RUN: %dafny /ironDafny /compile:0 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+abstract module Delicious {}
+module Chocolate exclusively refines Delicious {}
+module Strawberry exclusively refines Delicious {}
diff --git a/Test/irondafny0/xrefine0.dfy.expect b/Test/irondafny0/xrefine0.dfy.expect
new file mode 100644
index 00000000..136e06db
--- /dev/null
+++ b/Test/irondafny0/xrefine0.dfy.expect
@@ -0,0 +1,2 @@
+xrefine0.dfy(6,7): Error: no more than one exclusive refinement may exist for a given module.
+1 resolution/type errors detected in xrefine0.dfy
diff --git a/Test/irondafny0/xrefine1.dfy b/Test/irondafny0/xrefine1.dfy
new file mode 100644
index 00000000..4b085e6b
--- /dev/null
+++ b/Test/irondafny0/xrefine1.dfy
@@ -0,0 +1,77 @@
+// RUN: %dafny /ironDafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+abstract module ProtocolSpec {
+ type ProtoT
+
+ predicate Init(p:ProtoT)
+}
+
+abstract module HostSpec {
+ type HostT
+ import P as ProtocolSpec
+
+ function method foo(h:HostT) : P.ProtoT
+}
+
+module ProtocolImpl exclusively refines ProtocolSpec {
+ type ProtoT = bool
+
+ predicate Init(p:ProtoT) { !p }
+
+ method orange(i:nat) returns (j:nat)
+ {
+ j := i + 1;
+ }
+}
+
+module HostImpl exclusively refines HostSpec {
+ import P = ProtocolImpl
+
+ type HostT = int
+
+ function method foo(h:HostT) : P.ProtoT
+ {
+ h > 0
+ }
+
+ method apple(i:nat) returns (j:nat)
+ {
+ j := i + 1;
+ }
+}
+
+abstract module MainSpec {
+ import HI as HostSpec
+ import PI as ProtocolSpec
+
+ method Test(h1:HI.HostT, h2:HI.HostT)
+ requires HI.foo(h1) == HI.foo(h2);
+ requires PI.Init(HI.foo(h1))
+}
+
+module MainImpl exclusively refines MainSpec {
+ import HI = HostImpl
+ import PI = ProtocolImpl
+
+ method Test(h1:HI.HostT, h2:HI.HostT)
+ {
+ var a := HI.foo(h1);
+ print "HI.foo(h1) => ", a, "\n";
+ var b := HI.foo(h2);
+ print "HI.foo(h2) => ", b, "\n";
+ var i := PI.orange(1);
+ print "PI.orange(1) => ", i, "\n";
+ var j := HI.apple(2);
+ print "PI.apple(2) => ", j, "\n";
+ }
+
+ method Main()
+ {
+ Test(-1, 1);
+ }
+}
+
+
+
+
diff --git a/Test/irondafny0/xrefine1.dfy.expect b/Test/irondafny0/xrefine1.dfy.expect
new file mode 100644
index 00000000..ae844fc8
--- /dev/null
+++ b/Test/irondafny0/xrefine1.dfy.expect
@@ -0,0 +1,6 @@
+xrefine1.dfy(71,13): Error BP5002: A precondition for this call might not hold.
+xrefine1.dfy[MainImpl](49,29): Related location: This is the precondition that might not hold.
+Execution trace:
+ (0,0): anon0
+
+Dafny program verifier finished with 12 verified, 1 error
diff --git a/Test/irondafny0/xrefine2.dfy b/Test/irondafny0/xrefine2.dfy
new file mode 100644
index 00000000..1de4e201
--- /dev/null
+++ b/Test/irondafny0/xrefine2.dfy
@@ -0,0 +1,77 @@
+// RUN: %dafny /ironDafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+abstract module ProtocolSpec {
+ type ProtoT
+
+ predicate Init(p:ProtoT)
+}
+
+abstract module HostSpec {
+ type HostT
+ import P as ProtocolSpec
+
+ function method foo(h:HostT) : P.ProtoT
+}
+
+module ProtocolImpl exclusively refines ProtocolSpec {
+ type ProtoT = bool
+
+ predicate Init(p:ProtoT) { p }
+
+ method orange(i:nat) returns (j:nat)
+ {
+ j := i + 1;
+ }
+}
+
+module HostImpl exclusively refines HostSpec {
+ import P = ProtocolImpl
+
+ type HostT = int
+
+ function method foo(h:HostT) : P.ProtoT
+ {
+ h != 0
+ }
+
+ method apple(i:nat) returns (j:nat)
+ {
+ j := i + 1;
+ }
+}
+
+abstract module MainSpec {
+ import HI as HostSpec
+ import PI as ProtocolSpec
+
+ method Test(h1:HI.HostT, h2:HI.HostT)
+ requires HI.foo(h1) == HI.foo(h2);
+ requires PI.Init(HI.foo(h1))
+}
+
+module MainImpl exclusively refines MainSpec {
+ import HI = HostImpl
+ import PI = ProtocolImpl
+
+ method Test(h1:HI.HostT, h2:HI.HostT)
+ {
+ var a := HI.foo(h1);
+ print "HI.foo(h1) => ", a, "\n";
+ var b := HI.foo(h2);
+ print "HI.foo(h2) => ", b, "\n";
+ var i := PI.orange(1);
+ print "PI.orange(1) => ", i, "\n";
+ var j := HI.apple(2);
+ print "PI.apple(2) => ", j, "\n";
+ }
+
+ method Main()
+ {
+ Test(-1, 1);
+ }
+}
+
+
+
+
diff --git a/Test/irondafny0/xrefine2.dfy.expect b/Test/irondafny0/xrefine2.dfy.expect
new file mode 100644
index 00000000..6d3fecd4
--- /dev/null
+++ b/Test/irondafny0/xrefine2.dfy.expect
@@ -0,0 +1,9 @@
+
+Dafny program verifier finished with 13 verified, 0 errors
+Program compiled successfully
+Running...
+
+HI.foo(h1) => True
+HI.foo(h2) => True
+PI.orange(1) => 2
+PI.apple(2) => 3
diff --git a/Test/irondafny0/xrefine3.dfy b/Test/irondafny0/xrefine3.dfy
new file mode 100644
index 00000000..44add7cc
--- /dev/null
+++ b/Test/irondafny0/xrefine3.dfy
@@ -0,0 +1,72 @@
+// RUN: %dafny /ironDafny /compile:3 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+abstract module AlphaSpec {
+ type Alpha
+
+ predicate IsValid(a:Alpha)
+
+ method Init() returns (a:Alpha)
+ ensures IsValid(a);
+}
+
+abstract module BetaSpec {
+ type Beta
+ import A as AlphaSpec
+
+ predicate IsValid(b:Beta)
+
+ method Init(ays:seq<A.Alpha>) returns (b:Beta)
+ requires forall i :: 0 <= i < |ays| ==> A.IsValid(ays[i]);
+ ensures IsValid(b);
+}
+
+module AlphaImpl exclusively refines AlphaSpec {
+ type Alpha = bool
+
+ predicate IsValid(a:Alpha) {
+ a
+ }
+
+ method Init() returns (a:Alpha)
+ ensures IsValid(a);
+ {
+ a := true;
+ }
+}
+
+module BetaImpl exclusively refines BetaSpec {
+ import A = AlphaImpl
+ type Beta = seq<A.Alpha>
+
+ predicate IsValid(b:Beta) {
+ forall i :: 0 <= i < |b| ==> A.IsValid(b[i])
+ }
+
+ method Init(ays:seq<A.Alpha>) returns (b:Beta) {
+ b := ays;
+ }
+}
+
+abstract module MainSpec {
+ import A as AlphaSpec
+ import B as BetaSpec
+
+ method Main()
+ {
+ var a := A.Init();
+ var ays := [a, a];
+ assert forall i :: 0 <= i < |ays| ==> A.IsValid(ays[i]);
+ var b := B.Init(ays);
+ print "o hai!\n";
+ }
+}
+
+module MainImpl exclusively refines MainSpec {
+ import B = BetaImpl
+ import A = AlphaImpl
+}
+
+
+
+
diff --git a/Test/irondafny0/xrefine3.dfy.expect b/Test/irondafny0/xrefine3.dfy.expect
new file mode 100644
index 00000000..1e5a5b4e
--- /dev/null
+++ b/Test/irondafny0/xrefine3.dfy.expect
@@ -0,0 +1,6 @@
+
+Dafny program verifier finished with 14 verified, 0 errors
+Program compiled successfully
+Running...
+
+o hai!