diff options
author | 2012-07-03 01:13:44 -0700 | |
---|---|---|
committer | 2012-07-03 01:13:44 -0700 | |
commit | f5b08b01bd06a4ce88f6cc28f30eb180b45d1419 (patch) | |
tree | cae4418a6b07e0e8587e49929a86e560793aa11f /Source/Dafny/Dafny.atg | |
parent | c66dc1ecd384fdcd402a65ac86824327ee32eb1e (diff) |
Dafny: added copredicates
Diffstat (limited to 'Source/Dafny/Dafny.atg')
-rw-r--r-- | Source/Dafny/Dafny.atg | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/Source/Dafny/Dafny.atg b/Source/Dafny/Dafny.atg index bfce5122..3280e96a 100644 --- a/Source/Dafny/Dafny.atg +++ b/Source/Dafny/Dafny.atg @@ -576,9 +576,9 @@ FunctionDecl<MemberModifiers mmod, out Function/*!*/ f> List<Expression/*!*/> reqs = new List<Expression/*!*/>();
List<Expression/*!*/> ens = new List<Expression/*!*/>();
List<FrameExpression/*!*/> reads = new List<FrameExpression/*!*/>();
- List<Expression/*!*/> decreases = new List<Expression/*!*/>();
+ List<Expression/*!*/> decreases;
Expression body = null;
- bool isPredicate = false;
+ bool isPredicate = false; bool isCoPredicate = false;
bool isFunctionMethod = false;
IToken openParen = null;
IToken bodyStart = Token.NoToken;
@@ -619,14 +619,34 @@ FunctionDecl<MemberModifiers mmod, out Function/*!*/ f> | "..." (. signatureOmitted = true;
openParen = Token.NoToken; .)
)
+
+ /* ----- copredicate ----- */
+ | "copredicate" (. isCoPredicate = true; .)
+ (. if (mmod.IsGhost) { SemErr(t, "copredicates cannot be declared 'ghost' (they are ghost by default)"); }
+ .)
+ { Attribute<ref attrs> }
+ NoUSIdent<out id>
+ (
+ [ GenericParameters<typeArgs> ]
+ [ Formals<true, isFunctionMethod, formals, out openParen>
+ [ ":" (. SemErr(t, "copredicates do not have an explicitly declared return type; it is always bool"); .)
+ ]
+ ]
+ | "..." (. signatureOmitted = true;
+ openParen = Token.NoToken; .)
+ )
)
+ (. decreases = isCoPredicate ? null : new List<Expression/*!*/>(); .)
{ FunctionSpec<reqs, reads, ens, decreases> }
[ FunctionBody<out body, out bodyStart, out bodyEnd>
]
(. if (isPredicate) {
f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals,
reqs, reads, ens, new Specification<Expression>(decreases, null), body, false, attrs, signatureOmitted);
+ } else if (isCoPredicate) {
+ f = new CoPredicate(id, id.val, mmod.IsStatic, typeArgs, openParen, formals,
+ reqs, reads, ens, body, attrs, signatureOmitted);
} else {
f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals, returnType,
reqs, reads, ens, new Specification<Expression>(decreases, null), body, attrs, signatureOmitted);
@@ -635,8 +655,10 @@ FunctionDecl<MemberModifiers mmod, out Function/*!*/ f> f.BodyEndTok = bodyEnd;
.)
.
-FunctionSpec<.List<Expression/*!*/>/*!*/ reqs, List<FrameExpression/*!*/>/*!*/ reads, List<Expression/*!*/>/*!*/ ens, List<Expression/*!*/>/*!*/ decreases.>
-= (. Contract.Requires(cce.NonNullElements(reqs)); Contract.Requires(cce.NonNullElements(reads)); Contract.Requires(cce.NonNullElements(decreases));
+FunctionSpec<.List<Expression/*!*/>/*!*/ reqs, List<FrameExpression/*!*/>/*!*/ reads, List<Expression/*!*/>/*!*/ ens, List<Expression/*!*/> decreases.>
+= (. Contract.Requires(cce.NonNullElements(reqs));
+ Contract.Requires(cce.NonNullElements(reads));
+ Contract.Requires(decreases == null || cce.NonNullElements(decreases));
Expression/*!*/ e; FrameExpression/*!*/ fe; .)
(
SYNC
@@ -646,7 +668,12 @@ FunctionSpec<.List<Expression/*!*/>/*!*/ reqs, List<FrameExpression/*!*/>/*!*/ r }
] SYNC ";"
| "ensures" Expression<out e> SYNC ";" (. ens.Add(e); .)
- | "decreases" DecreasesList<decreases, false> SYNC ";"
+ | "decreases" (. if (decreases == null) {
+ SemErr(t, "'decreases' clauses are meaningless for copredicates, so they are not allowed");
+ decreases = new List<Expression/*!*/>();
+ }
+ .)
+ DecreasesList<decreases, false> SYNC ";"
)
.
PossiblyWildExpression<out Expression/*!*/ e>
|