summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Unknown <afd@afd-THINK.home>2011-11-08 07:40:51 +0000
committerGravatar Unknown <afd@afd-THINK.home>2011-11-08 07:40:51 +0000
commite4a19d97c8d7d9b5b686d3fa6e52427fd5787341 (patch)
tree0cbecd665c150f6d32380fb300256a8ec939cfa9
parent7505f11202796652fea9cd5815046d1cdd644475 (diff)
parenteaa54c238d6f841b08b8084cf8743e13ac167eb6 (diff)
Merge
-rw-r--r--.hgtags1
-rw-r--r--BCT/BytecodeTranslator/ExpressionTraverser.cs228
-rw-r--r--BCT/BytecodeTranslator/HeapFactory.cs23
-rw-r--r--BCT/BytecodeTranslator/MetadataTraverser.cs68
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs20
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs10
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs28
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs20
-rw-r--r--BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs38
-rw-r--r--BCT/BytecodeTranslator/Program.cs5
-rw-r--r--BCT/BytecodeTranslator/Sink.cs274
-rw-r--r--BCT/BytecodeTranslator/StatementTraverser.cs165
-rw-r--r--BCT/BytecodeTranslator/TranslationHelper.cs49
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs2
-rw-r--r--BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs4
-rw-r--r--BCT/BytecodeTranslator/TraverserFactory.cs4
-rw-r--r--BCT/BytecodeTranslator/WholeProgram.cs37
-rw-r--r--BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt116
-rw-r--r--BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt116
-rw-r--r--Binaries/DafnyPrelude.bpl7
-rw-r--r--Binaries/DafnyRuntime.cs6
-rw-r--r--Chalice/readme.txt5
-rw-r--r--Source/AIFramework/CommonFunctionSymbols.cs2209
-rw-r--r--Source/AbsInt/AbstractInterpretation.cs10
-rw-r--r--Source/AbsInt/ExprFactories.cs47
-rw-r--r--Source/Core/Absy.cs36
-rw-r--r--Source/Core/AbsyExpr.cs5
-rw-r--r--Source/Core/CommandLineOptions.cs123
-rw-r--r--Source/Core/Inline.cs136
-rw-r--r--Source/Core/VCExp.cs1
-rw-r--r--Source/Dafny/Compiler.cs256
-rw-r--r--Source/Dafny/Dafny.atg33
-rw-r--r--Source/Dafny/DafnyAst.cs53
-rw-r--r--Source/Dafny/Parser.cs501
-rw-r--r--Source/Dafny/Printer.cs21
-rw-r--r--Source/Dafny/Resolver.cs233
-rw-r--r--Source/Dafny/Scanner.cs201
-rw-r--r--Source/Dafny/Translator.cs785
-rw-r--r--Source/Model/Model.cs155
-rw-r--r--Source/ModelViewer/DafnyProvider.cs4
-rw-r--r--Source/ModelViewer/Namer.cs4
-rw-r--r--Source/ModelViewer/VccProvider.cs4
-rw-r--r--Source/Provers/Isabelle/Prover.cs2
-rw-r--r--Source/Provers/SMTLib/ProverInterface.cs50
-rw-r--r--Source/Provers/SMTLib/SMTLibLineariser.cs32
-rw-r--r--Source/Provers/SMTLib/SMTLibProcess.cs2
-rw-r--r--Source/Provers/SMTLib/Z3.cs13
-rw-r--r--Source/Provers/Simplify/ProverInterface.cs2
-rw-r--r--Source/Provers/TPTP/ProverInterface.cs6
-rw-r--r--Source/Provers/Z3/Prover.cs7
-rw-r--r--Source/Provers/Z3/ProverInterface.cs33
-rw-r--r--Source/VCExpr/Boogie2VCExpr.cs36
-rw-r--r--Source/VCExpr/SimplifyLikeLineariser.cs19
-rw-r--r--Source/VCGeneration/Check.cs39
-rw-r--r--Source/VCGeneration/Context.cs5
-rw-r--r--Source/VCGeneration/StratifiedVC.cs314
-rw-r--r--Test/bitvectors/Answer8
-rw-r--r--Test/bitvectors/runtest.bat9
-rw-r--r--Test/dafny0/Answer184
-rw-r--r--Test/dafny0/Definedness.dfy25
-rw-r--r--Test/dafny0/Parallel.dfy111
-rw-r--r--Test/dafny0/ParallelResolveErrors.dfy151
-rw-r--r--Test/dafny0/SmallTests.dfy14
-rw-r--r--Test/dafny0/TypeAntecedents.dfy4
-rw-r--r--Test/dafny0/TypeTests.dfy11
-rw-r--r--Test/dafny0/runtest.bat2
-rw-r--r--Test/dafny1/Answer24
-rw-r--r--Test/dafny1/Induction.dfy17
-rw-r--r--Test/dafny1/MoreInduction.dfy34
-rw-r--r--Test/dafny1/Rippling.dfy144
-rw-r--r--Test/dafny2/Answer6
-rw-r--r--Test/dafny2/Classics.dfy103
-rw-r--r--Test/dafny2/SnapshotableTrees.dfy6
-rw-r--r--Test/dafny2/runtest.bat4
-rw-r--r--Test/datatypes/runtest.bat12
-rw-r--r--Test/datatypes/t2.bpl54
-rw-r--r--Test/extractloops/Answer4
-rw-r--r--Test/inline/Answer19
-rw-r--r--Test/inline/expansion.bpl33
-rw-r--r--Test/inline/expansion2.bpl8
-rw-r--r--Test/inline/expansion3.bpl12
-rw-r--r--Test/inline/expansion4.bpl9
-rw-r--r--Test/inline/runtest.bat2
-rw-r--r--Test/stratifiedinline/Answer66
-rw-r--r--Test/test15/Answer286
-rw-r--r--Test/test2/runtest.bat2
-rw-r--r--Test/textbook/Answer4
-rw-r--r--Test/textbook/TuringFactorial.bpl33
-rw-r--r--Test/textbook/runtest.bat3
-rw-r--r--Util/Emacs/dafny-mode.el2
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs4
-rw-r--r--Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs1
-rw-r--r--Util/latex/dafny.sty2
-rw-r--r--Util/vim/syntax/dafny.vim2
-rw-r--r--_admin/Boogie/aste/summary.log32
95 files changed, 4235 insertions, 3815 deletions
diff --git a/.hgtags b/.hgtags
index 825936f3..631a73de 100644
--- a/.hgtags
+++ b/.hgtags
@@ -7,3 +7,4 @@ e57f596b36edd27f66ff7400a6610034ce67d19d emicvccbld_build_2.1.30905.0
79325a9cde979064701fced92e8cfa25dc59276f emicvccbld_build_2.1.31019.0
8b7a180291a5ecb7d1ffa0dbc3483cc4f7685064 emicvccbld_build_2.1.31020.0
f59d45429b672bb429d26e1aff6e9df1d9def6b5 emicvccbld_build_2.1.31022.0
+f3b3df39e9877fb2b3fde172f300f995689e6402 emicvccbld_build_2.1.31028.0
diff --git a/BCT/BytecodeTranslator/ExpressionTraverser.cs b/BCT/BytecodeTranslator/ExpressionTraverser.cs
index 137d5776..dbcc8dad 100644
--- a/BCT/BytecodeTranslator/ExpressionTraverser.cs
+++ b/BCT/BytecodeTranslator/ExpressionTraverser.cs
@@ -23,7 +23,7 @@ using BytecodeTranslator.Phone;
namespace BytecodeTranslator
{
- public class ExpressionTraverser : BaseCodeTraverser
+ public class ExpressionTraverser : CodeTraverser
{
public readonly Stack<Bpl.Expr> TranslatedExpressions;
@@ -65,7 +65,7 @@ namespace BytecodeTranslator
/// </summary>
/// <param name="addressableExpression"></param>
/// <remarks>still a stub</remarks>
- public override void Visit(IAddressableExpression addressableExpression)
+ public override void TraverseChildren(IAddressableExpression addressableExpression)
{
ILocalDefinition/*?*/ local = addressableExpression.Definition as ILocalDefinition;
if (local != null)
@@ -86,7 +86,7 @@ namespace BytecodeTranslator
if (instance == null) {
TranslatedExpressions.Push(f);
} else {
- this.Visit(instance);
+ this.Traverse(instance);
Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
Bpl.IdentifierExpr temp = Bpl.Expr.Ident(this.sink.CreateFreshLocal(field.ResolvedField.Type));
this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(temp, this.sink.Heap.ReadHeap(instanceExpr, f, field.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, temp.Type)));
@@ -97,18 +97,18 @@ namespace BytecodeTranslator
IArrayIndexer/*?*/ arrayIndexer = addressableExpression.Definition as IArrayIndexer;
if (arrayIndexer != null)
{
- this.Visit(arrayIndexer);
+ this.Traverse(arrayIndexer);
return;
}
IAddressDereference/*?*/ addressDereference = addressableExpression.Definition as IAddressDereference;
if (addressDereference != null)
{
- this.Visit(addressDereference);
+ this.Traverse(addressDereference);
return;
}
IBlockExpression block = addressableExpression.Definition as IBlockExpression;
if (block != null) {
- this.Visit(block);
+ this.Traverse(block);
return;
}
IMethodReference/*?*/ method = addressableExpression.Definition as IMethodReference;
@@ -121,7 +121,7 @@ namespace BytecodeTranslator
Contract.Assert(addressableExpression.Definition is IThisReference);
}
- public override void Visit(IAddressDereference addressDereference)
+ public override void TraverseChildren(IAddressDereference addressDereference)
{
IBoundExpression be = addressDereference.Address as IBoundExpression;
if (be != null)
@@ -134,22 +134,22 @@ namespace BytecodeTranslator
return;
}
}
- this.Visit(addressDereference.Address);
+ this.Traverse(addressDereference.Address);
return;
}
- public override void Visit(IArrayIndexer arrayIndexer) {
+ public override void TraverseChildren(IArrayIndexer arrayIndexer) {
if (!IsAtomicInstance(arrayIndexer.IndexedObject)) {
// Simplify the BE so that all nested dereferences and method calls are broken up into separate assignments to locals.
var se = ExpressionSimplifier.Simplify(this.sink, arrayIndexer);
- this.Visit(se);
+ this.Traverse(se);
return;
}
- this.Visit(arrayIndexer.IndexedObject);
+ this.Traverse(arrayIndexer.IndexedObject);
Bpl.Expr arrayExpr = TranslatedExpressions.Pop();
- this.Visit(arrayIndexer.Indices);
+ this.Traverse(arrayIndexer.Indices);
int count = arrayIndexer.Indices.Count();
Bpl.Expr[] indexExprs = new Bpl.Expr[count];
for (int i = count; i > 0; i--) {
@@ -167,24 +167,24 @@ namespace BytecodeTranslator
this.TranslatedExpressions.Push(this.sink.Heap.ReadHeap(arrayExpr, indexExpr, AccessType.Array, this.sink.CciTypeToBoogie(arrayIndexer.Type)));
}
- public override void Visit(ITargetExpression targetExpression)
+ public override void TraverseChildren(ITargetExpression targetExpression)
{
Contract.Assume(false, "The expression containing this as a subexpression should never allow a call to this routine.");
}
- public override void Visit(IThisReference thisReference)
+ public override void TraverseChildren(IThisReference thisReference)
{
TranslatedExpressions.Push(new Bpl.IdentifierExpr(thisReference.Token(),
this.sink.ThisVariable));
}
- public override void Visit(IBoundExpression boundExpression)
+ public override void TraverseChildren(IBoundExpression boundExpression)
{
if (boundExpression.Instance != null && !IsAtomicInstance(boundExpression.Instance)) {
// Simplify the BE so that all nested dereferences and method calls are broken up into separate assignments to locals.
var se = ExpressionSimplifier.Simplify(this.sink, boundExpression);
- this.Visit(se);
+ this.Traverse(se);
return;
}
@@ -214,7 +214,7 @@ namespace BytecodeTranslator
if (instance == null) {
TranslatedExpressions.Push(f);
} else {
- this.Visit(instance);
+ this.Traverse(instance);
Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
var bplType = this.sink.CciTypeToBoogie(field.Type);
var e = this.sink.Heap.ReadHeap(instanceExpr, f, field.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, bplType);
@@ -228,7 +228,7 @@ namespace BytecodeTranslator
IArrayIndexer/*?*/ indexer = boundExpression.Definition as IArrayIndexer;
if (indexer != null)
{
- Visit(indexer);
+ this.Traverse(indexer);
return;
}
#endregion
@@ -240,18 +240,18 @@ namespace BytecodeTranslator
IAddressOf/*?*/ addressOf = deref.Address as IAddressOf;
if (addressOf != null)
{
- this.Visit(addressOf.Expression);
+ this.Traverse(addressOf.Expression);
return;
}
if (boundExpression.Instance != null)
{
// TODO
- this.Visit(boundExpression.Instance);
+ this.Traverse(boundExpression.Instance);
Console.Write("->");
}
else if (deref.Address.Type is IPointerTypeReference)
Console.Write("*");
- this.Visit(deref.Address);
+ this.Traverse(deref.Address);
return;
}
else
@@ -279,9 +279,9 @@ namespace BytecodeTranslator
return be.Instance == null;
}
- public override void Visit(IPopValue popValue) {
+ public override void TraverseChildren(IPopValue popValue) {
var locExpr = this.StmtTraverser.operandStack.Pop();
- this.Visit(locExpr);
+ this.Traverse(locExpr);
this.TranslatedExpressions.Push(this.TranslatedExpressions.Pop());
}
@@ -290,15 +290,15 @@ namespace BytecodeTranslator
/// Otherwise it just translates the expression and skips the address-of
/// operation.
/// </summary>
- public override void Visit(IAddressOf addressOf)
+ public override void TraverseChildren(IAddressOf addressOf)
{
- Visit(addressOf.Expression);
+ this.Traverse(addressOf.Expression);
}
#endregion
#region Translate Constant Access
- public override void Visit(ICompileTimeConstant constant) {
+ public override void TraverseChildren(ICompileTimeConstant constant) {
if (constant.Value == null) {
var bplType = sink.CciTypeToBoogie(constant.Type);
if (bplType == Bpl.Type.Int) {
@@ -406,7 +406,7 @@ namespace BytecodeTranslator
return;
}
- public override void Visit(IDefaultValue defaultValue) {
+ public override void TraverseChildren(IDefaultValue defaultValue) {
var typ = defaultValue.Type;
if (TranslationHelper.IsStruct(typ)) {
@@ -463,7 +463,7 @@ namespace BytecodeTranslator
new Bpl.AssumeCmd(tok,
Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
this.sink.Heap.DynamicType(locExpr),
- this.sink.FindOrCreateType(typ)
+ this.sink.FindOrCreateTypeReference(typ)
)
)
);
@@ -479,7 +479,7 @@ namespace BytecodeTranslator
/// </summary>
/// <param name="methodCall"></param>
/// <remarks>Stub, This one really needs comments!</remarks>
- public override void Visit(IMethodCall methodCall) {
+ public override void TraverseChildren(IMethodCall methodCall) {
var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod;
if (resolvedMethod == Dummy.Method) {
throw new TranslationException(
@@ -494,7 +494,7 @@ namespace BytecodeTranslator
var methodName = MemberHelper.GetMethodSignature(methodCall.MethodToCall, NameFormattingOptions.None);
if (methodName.Equals("GetMeHere.GetMeHere.Assert")) {
// for now, just translate it as "assert e"
- this.Visit(methodCall.Arguments.First());
+ this.Traverse(methodCall.Arguments.First());
Bpl.Expr e = this.TranslatedExpressions.Pop();
this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, e));
return;
@@ -627,7 +627,7 @@ namespace BytecodeTranslator
new Bpl.AssumeCmd(methodCallToken,
Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
this.sink.Heap.DynamicType(thisExpr),
- this.sink.FindOrCreateType(methodCall.MethodToCall.ResolvedMethod.ContainingTypeDefinition)
+ this.sink.FindOrCreateTypeReference(methodCall.MethodToCall.ResolvedMethod.ContainingTypeDefinition)
)
)
);
@@ -641,7 +641,7 @@ namespace BytecodeTranslator
#region Create the 'this' argument for the function call
thisExpr = null;
if (thisArg != null) {
- this.Visit(thisArg);
+ this.Traverse(thisArg);
var e = this.TranslatedExpressions.Pop();
var identifierExpr = e as Bpl.IdentifierExpr;
@@ -663,7 +663,7 @@ namespace BytecodeTranslator
if (penum.Current == null) {
throw new TranslationException("More arguments than parameters in method call");
}
- this.Visit(exp);
+ this.Traverse(exp);
Bpl.Expr e = this.TranslatedExpressions.Pop();
if (penum.Current.Type is IGenericTypeParameter || penum.Current.Type is IGenericMethodParameter)
inexpr.Add(sink.Heap.Box(token, this.sink.CciTypeToBoogie(exp.Type), e));
@@ -689,13 +689,13 @@ namespace BytecodeTranslator
List<ITypeReference> consolidatedTypeArguments = new List<ITypeReference>();
Sink.GetConsolidatedTypeArguments(consolidatedTypeArguments, methodToCall.ContainingType);
foreach (ITypeReference typeReference in consolidatedTypeArguments) {
- inexpr.Add(sink.FindOrCreateType(typeReference));
+ inexpr.Add(sink.FindOrCreateTypeReference(typeReference));
}
}
IGenericMethodInstanceReference methodInstanceReference = methodToCall as IGenericMethodInstanceReference;
if (methodInstanceReference != null) {
foreach (ITypeReference typeReference in methodInstanceReference.GenericArguments) {
- inexpr.Add(sink.FindOrCreateType(typeReference));
+ inexpr.Add(sink.FindOrCreateTypeReference(typeReference));
}
}
@@ -728,7 +728,7 @@ namespace BytecodeTranslator
/// </summary>
/// <remarks>(mschaef) Works, but still a stub </remarks>
/// <param name="assignment"></param>
- public override void Visit(IAssignment assignment) {
+ public override void TraverseChildren(IAssignment assignment) {
Contract.Assert(TranslatedExpressions.Count == 0);
var tok = assignment.Token();
@@ -784,7 +784,7 @@ namespace BytecodeTranslator
var/*?*/ local = container as ILocalDefinition;
if (local != null) {
Contract.Assume(instance == null);
- this.Visit(source);
+ this.Traverse(source);
var e = this.TranslatedExpressions.Pop();
var bplLocal = Bpl.Expr.Ident(this.sink.FindOrCreateLocalVariable(local));
if (structCopy) {
@@ -799,7 +799,7 @@ namespace BytecodeTranslator
var/*?*/ parameter = container as IParameterDefinition;
if (parameter != null) {
Contract.Assume(instance == null);
- this.Visit(source);
+ this.Traverse(source);
var e = this.TranslatedExpressions.Pop();
var bplParam = Bpl.Expr.Ident(this.sink.FindParameterVariable(parameter, this.contractContext));
if (structCopy) {
@@ -813,7 +813,7 @@ namespace BytecodeTranslator
var/*?*/ field = container as IFieldReference;
if (field != null) {
- this.Visit(source);
+ this.Traverse(source);
var e = this.TranslatedExpressions.Pop();
var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field));
if (instance == null) {
@@ -821,7 +821,7 @@ namespace BytecodeTranslator
StmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, f, e));
}
else {
- this.Visit(instance);
+ this.Traverse(instance);
var x = this.TranslatedExpressions.Pop();
var boogieType = sink.CciTypeToBoogie(field.Type);
StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(tok, x, f, e,
@@ -833,11 +833,11 @@ namespace BytecodeTranslator
var/*?*/ arrayIndexer = container as IArrayIndexer;
if (arrayIndexer != null) {
- this.Visit(instance);
+ this.Traverse(instance);
var x = this.TranslatedExpressions.Pop();
- this.Visit(arrayIndexer.Indices);
+ this.Traverse(arrayIndexer.Indices);
var indices_prime = this.TranslatedExpressions.Pop();
- this.Visit(source);
+ this.Traverse(source);
var e = this.TranslatedExpressions.Pop();
StmtTraverser.StmtBuilder.Add(sink.Heap.WriteHeap(Bpl.Token.NoToken, x, indices_prime, e, AccessType.Array, sink.CciTypeToBoogie(arrayIndexer.Type)));
return;
@@ -876,7 +876,7 @@ namespace BytecodeTranslator
// ctor (probably only ever done in a different ctor for the
// struct). The assignment actually looks like "*this := DefaultValue(S)"
Contract.Assume(instance == null);
- this.Visit(source);
+ this.Traverse(source);
var e = this.TranslatedExpressions.Pop();
var bplLocal = Bpl.Expr.Ident(this.sink.ThisVariable);
cmd = Bpl.Cmd.SimpleAssign(tok, bplLocal, e);
@@ -896,7 +896,7 @@ namespace BytecodeTranslator
/// For "new A(...)" generate "{ A a = Alloc(); A..ctor(a); return a; }" where
/// "a" is a fresh local.
/// </summary>
- public override void Visit(ICreateObjectInstance createObjectInstance)
+ public override void TraverseChildren(ICreateObjectInstance createObjectInstance)
{
var ctor = createObjectInstance.MethodToCall;
var resolvedMethod = Sink.Unspecialize(ctor).ResolvedMethod;
@@ -908,7 +908,7 @@ namespace BytecodeTranslator
createObjectInstance.Type.TypeCode == PrimitiveTypeCode.UIntPtr) {
List<Bpl.Expr> args = new List<Bpl.Expr>();
foreach (IExpression e in createObjectInstance.Arguments) {
- this.Visit(e);
+ this.Traverse(e);
args.Add(TranslatedExpressions.Pop());
}
System.Diagnostics.Debug.Assert(args.Count == 1);
@@ -933,7 +933,7 @@ namespace BytecodeTranslator
new Bpl.AssumeCmd(token,
Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
this.sink.Heap.DynamicType(Bpl.Expr.Ident(a)),
- this.sink.FindOrCreateType(createObjectInstance.Type)
+ this.sink.FindOrCreateTypeReference(createObjectInstance.Type)
)
)
);
@@ -941,7 +941,7 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(Bpl.Expr.Ident(a));
}
- public override void Visit(ICreateArray createArrayInstance)
+ public override void TraverseChildren(ICreateArray createArrayInstance)
{
Bpl.IToken cloc = createArrayInstance.Token();
var a = this.sink.CreateFreshLocal(createArrayInstance.Type);
@@ -949,7 +949,7 @@ namespace BytecodeTranslator
Debug.Assert(createArrayInstance.Rank > 0);
Bpl.Expr lengthExpr = Bpl.Expr.Literal(1);
foreach (IExpression expr in createArrayInstance.Sizes) {
- this.Visit(expr);
+ this.Traverse(expr);
lengthExpr = Bpl.Expr.Mul(lengthExpr, TranslatedExpressions.Pop());
}
@@ -959,14 +959,14 @@ namespace BytecodeTranslator
this.StmtTraverser.StmtBuilder.Add(new Bpl.AssumeCmd(cloc, assumeExpr));
TranslatedExpressions.Push(Bpl.Expr.Ident(a));
}
-
- public override void Visit(ICreateDelegateInstance createDelegateInstance)
+
+ public override void TraverseChildren(ICreateDelegateInstance createDelegateInstance)
{
if (createDelegateInstance.Instance == null) {
TranslatedExpressions.Push(Bpl.Expr.Literal(0));
}
else {
- this.Visit(createDelegateInstance.Instance);
+ this.Traverse(createDelegateInstance.Instance);
}
TranslateDelegateCreation(createDelegateInstance.MethodToCallViaDelegate, createDelegateInstance.Type, createDelegateInstance);
@@ -990,13 +990,13 @@ namespace BytecodeTranslator
List<ITypeReference> consolidatedTypeArguments = new List<ITypeReference>();
Sink.GetConsolidatedTypeArguments(consolidatedTypeArguments, methodToCall.ContainingType);
foreach (ITypeReference typeReference in consolidatedTypeArguments) {
- typeParameterExprs.Add(sink.FindOrCreateType(typeReference));
+ typeParameterExprs.Add(sink.FindOrCreateTypeReference(typeReference));
}
}
IGenericMethodInstanceReference methodInstanceReference = methodToCall as IGenericMethodInstanceReference;
if (methodInstanceReference != null) {
foreach (ITypeReference typeReference in methodInstanceReference.GenericArguments) {
- typeParameterExprs.Add(sink.FindOrCreateType(typeReference));
+ typeParameterExprs.Add(sink.FindOrCreateTypeReference(typeReference));
}
}
Bpl.Expr typeParameterExpr =
@@ -1014,9 +1014,9 @@ namespace BytecodeTranslator
#region Translate Binary Operators
- public override void Visit(IAddition addition)
+ public override void TraverseChildren(IAddition addition)
{
- base.Visit(addition);
+ base.TraverseChildren(addition);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e;
@@ -1036,8 +1036,8 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IBitwiseAnd bitwiseAnd) {
- base.Visit(bitwiseAnd);
+ public override void TraverseChildren(IBitwiseAnd bitwiseAnd) {
+ base.TraverseChildren(bitwiseAnd);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e;
@@ -1054,8 +1054,8 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IBitwiseOr bitwiseOr) {
- base.Visit(bitwiseOr);
+ public override void TraverseChildren(IBitwiseOr bitwiseOr) {
+ base.TraverseChildren(bitwiseOr);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e;
@@ -1072,8 +1072,8 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IModulus modulus) {
- base.Visit(modulus);
+ public override void TraverseChildren(IModulus modulus) {
+ base.TraverseChildren(modulus);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e;
@@ -1093,9 +1093,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IDivision division)
+ public override void TraverseChildren(IDivision division)
{
- base.Visit(division);
+ base.TraverseChildren(division);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e;
@@ -1115,8 +1115,8 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IExclusiveOr exclusiveOr) {
- base.Visit(exclusiveOr);
+ public override void TraverseChildren(IExclusiveOr exclusiveOr) {
+ base.TraverseChildren(exclusiveOr);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
var e = new Bpl.NAryExpr(
@@ -1127,9 +1127,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(ISubtraction subtraction)
+ public override void TraverseChildren(ISubtraction subtraction)
{
- base.Visit(subtraction);
+ base.TraverseChildren(subtraction);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e;
@@ -1149,9 +1149,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IMultiplication multiplication)
+ public override void TraverseChildren(IMultiplication multiplication)
{
- base.Visit(multiplication);
+ base.TraverseChildren(multiplication);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e;
@@ -1171,9 +1171,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IGreaterThan greaterThan)
+ public override void TraverseChildren(IGreaterThan greaterThan)
{
- base.Visit(greaterThan);
+ base.TraverseChildren(greaterThan);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
@@ -1195,9 +1195,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IGreaterThanOrEqual greaterEqual)
+ public override void TraverseChildren(IGreaterThanOrEqual greaterEqual)
{
- base.Visit(greaterEqual);
+ base.TraverseChildren(greaterEqual);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
@@ -1219,9 +1219,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(ILessThan lessThan)
+ public override void TraverseChildren(ILessThan lessThan)
{
- base.Visit(lessThan);
+ base.TraverseChildren(lessThan);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
@@ -1243,9 +1243,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(ILessThanOrEqual lessEqual)
+ public override void TraverseChildren(ILessThanOrEqual lessEqual)
{
- base.Visit(lessEqual);
+ base.TraverseChildren(lessEqual);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
@@ -1267,24 +1267,24 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IEquality equal)
+ public override void TraverseChildren(IEquality equal)
{
- base.Visit(equal);
+ base.TraverseChildren(equal);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, lexp, rexp));
}
- public override void Visit(INotEquality nonEqual)
+ public override void TraverseChildren(INotEquality nonEqual)
{
- base.Visit(nonEqual);
+ base.TraverseChildren(nonEqual);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, lexp, rexp));
}
- public override void Visit(IRightShift rightShift) {
- base.Visit(rightShift);
+ public override void TraverseChildren(IRightShift rightShift) {
+ base.TraverseChildren(rightShift);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e = new Bpl.NAryExpr(
@@ -1295,8 +1295,8 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(ILeftShift leftShift) {
- base.Visit(leftShift);
+ public override void TraverseChildren(ILeftShift leftShift) {
+ base.TraverseChildren(leftShift);
Bpl.Expr rexp = TranslatedExpressions.Pop();
Bpl.Expr lexp = TranslatedExpressions.Pop();
Bpl.Expr e = new Bpl.NAryExpr(
@@ -1313,7 +1313,7 @@ namespace BytecodeTranslator
/// TODO:
/// If it isn't either of these short forms then emit the proper expression!
/// </summary>
- public override void Visit(IConditional conditional) {
+ public override void TraverseChildren(IConditional conditional) {
/*
#region Try and reconstruct And, Or, Not expressions
if (conditional.Type.TypeCode == PrimitiveTypeCode.Boolean) {
@@ -1387,10 +1387,10 @@ namespace BytecodeTranslator
StatementTraverser elseStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext);
ExpressionTraverser thenExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, thenStmtTraverser, this.contractContext);
ExpressionTraverser elseExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, elseStmtTraverser, this.contractContext);
- thenExprTraverser.Visit(conditional.ResultIfTrue);
- elseExprTraverser.Visit(conditional.ResultIfFalse);
+ thenExprTraverser.Traverse(conditional.ResultIfTrue);
+ elseExprTraverser.Traverse(conditional.ResultIfFalse);
- this.Visit(conditional.Condition);
+ this.Traverse(conditional.Condition);
Bpl.Expr conditionExpr = this.TranslatedExpressions.Pop();
Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditional.Token(),
@@ -1433,10 +1433,10 @@ namespace BytecodeTranslator
#region Translate Unary Operators
- public override void Visit(ICastIfPossible castIfPossible) {
- base.Visit(castIfPossible.ValueToCast);
+ public override void TraverseChildren(ICastIfPossible castIfPossible) {
+ base.Traverse(castIfPossible.ValueToCast);
var exp = TranslatedExpressions.Pop();
- var e = this.sink.FindOrCreateType(castIfPossible.TargetType);
+ var e = this.sink.FindOrCreateTypeReference(castIfPossible.TargetType);
var callAs = new Bpl.NAryExpr(
castIfPossible.Token(),
new Bpl.FunctionCall(this.sink.Heap.AsFunction),
@@ -1445,14 +1445,14 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(callAs);
return;
}
- public override void Visit(ICheckIfInstance checkIfInstance) {
- var e = this.sink.FindOrCreateType(checkIfInstance.TypeToCheck);
+ public override void TraverseChildren(ICheckIfInstance checkIfInstance) {
+ var e = this.sink.FindOrCreateTypeReference(checkIfInstance.TypeToCheck);
//var callTypeOf = new Bpl.NAryExpr(
// checkIfInstance.Token(),
// new Bpl.FunctionCall(this.sink.Heap.TypeOfFunction),
// new Bpl.ExprSeq(new Bpl.IdentifierExpr(checkIfInstance.Token(), v))
// );
- base.Visit(checkIfInstance.Operand);
+ base.Traverse(checkIfInstance.Operand);
var exp = TranslatedExpressions.Pop();
var dynTypeOfOperand = this.sink.Heap.DynamicType(exp);
//var subtype = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Subtype, dynTypeOfOperand, e);
@@ -1467,9 +1467,9 @@ namespace BytecodeTranslator
return;
}
- public override void Visit(IConversion conversion) {
+ public override void TraverseChildren(IConversion conversion) {
var tok = conversion.ValueToConvert.Token();
- Visit(conversion.ValueToConvert);
+ this.Traverse(conversion.ValueToConvert);
var boogieTypeOfValue = this.sink.CciTypeToBoogie(conversion.ValueToConvert.Type);
var boogieTypeToBeConvertedTo = this.sink.CciTypeToBoogie(conversion.TypeAfterConversion);
if (boogieTypeOfValue == boogieTypeToBeConvertedTo) {
@@ -1578,8 +1578,8 @@ namespace BytecodeTranslator
}
}
- public override void Visit(IOnesComplement onesComplement) {
- base.Visit(onesComplement);
+ public override void TraverseChildren(IOnesComplement onesComplement) {
+ base.TraverseChildren(onesComplement);
var exp = TranslatedExpressions.Pop();
var e = new Bpl.NAryExpr(
onesComplement.Token(),
@@ -1589,9 +1589,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(IUnaryNegation unaryNegation)
+ public override void TraverseChildren(IUnaryNegation unaryNegation)
{
- base.Visit(unaryNegation);
+ base.TraverseChildren(unaryNegation);
Bpl.Expr exp = TranslatedExpressions.Pop();
Bpl.Expr e, zero, realZero;
zero = Bpl.Expr.Literal(0);
@@ -1612,9 +1612,9 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(e);
}
- public override void Visit(ILogicalNot logicalNot)
+ public override void TraverseChildren(ILogicalNot logicalNot)
{
- base.Visit(logicalNot.Operand);
+ base.Traverse(logicalNot.Operand);
Bpl.Expr exp = TranslatedExpressions.Pop();
Bpl.Type operandType = this.sink.CciTypeToBoogie(logicalNot.Operand.Type);
if (operandType == this.sink.Heap.RefType) {
@@ -1631,8 +1631,8 @@ namespace BytecodeTranslator
Bpl.UnaryOperator.Opcode.Not, exp));
}
- public override void Visit(ITypeOf typeOf) {
- var e = this.sink.FindOrCreateType(typeOf.TypeToGet);
+ public override void TraverseChildren(ITypeOf typeOf) {
+ var e = this.sink.FindOrCreateTypeReference(typeOf.TypeToGet);
var callTypeOf = new Bpl.NAryExpr(
typeOf.Token(),
new Bpl.FunctionCall(this.sink.Heap.TypeOfFunction),
@@ -1641,8 +1641,8 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(callTypeOf);
}
- public override void Visit(IVectorLength vectorLength) {
- base.Visit(vectorLength.Vector);
+ public override void TraverseChildren(IVectorLength vectorLength) {
+ base.Traverse(vectorLength.Vector);
var e = TranslatedExpressions.Pop();
TranslatedExpressions.Push(new Bpl.NAryExpr(vectorLength.Token(), new Bpl.FunctionCall(this.sink.Heap.ArrayLengthFunction), new Bpl.ExprSeq(e)));
}
@@ -1650,14 +1650,14 @@ namespace BytecodeTranslator
#endregion
#region CodeContract Expressions
- public override void Visit(IOldValue oldValue)
+ public override void TraverseChildren(IOldValue oldValue)
{
- base.Visit(oldValue);
+ base.TraverseChildren(oldValue);
TranslatedExpressions.Push(new Bpl.OldExpr(oldValue.Token(),
TranslatedExpressions.Pop()));
}
- public override void Visit(IReturnValue returnValue)
+ public override void TraverseChildren(IReturnValue returnValue)
{
if (this.sink.ReturnVariable == null)
{
@@ -1669,9 +1669,9 @@ namespace BytecodeTranslator
}
#endregion
- public override void Visit(IBlockExpression blockExpression) {
- this.StmtTraverser.Visit(blockExpression.BlockStatement);
- this.Visit(blockExpression.Expression);
+ public override void TraverseChildren(IBlockExpression blockExpression) {
+ this.StmtTraverser.Traverse(blockExpression.BlockStatement);
+ this.Traverse(blockExpression.Expression);
}
/// <summary>
diff --git a/BCT/BytecodeTranslator/HeapFactory.cs b/BCT/BytecodeTranslator/HeapFactory.cs
index 727d09c5..45adb36e 100644
--- a/BCT/BytecodeTranslator/HeapFactory.cs
+++ b/BCT/BytecodeTranslator/HeapFactory.cs
@@ -114,7 +114,7 @@ namespace BytecodeTranslator {
[RepresentationFor("null", "const unique null : Ref;")]
public Bpl.Constant NullRef;
- [RepresentationFor("Type", "type Type;")]
+ [RepresentationFor("Type", "type {:datatype} Type;")]
public Bpl.TypeCtorDecl TypeTypeDecl = null;
public Bpl.CtorType TypeType;
@@ -258,12 +258,8 @@ namespace BytecodeTranslator {
/// </summary>
public Bpl.Variable CreateTypeVariable(ITypeReference type, List<Bpl.ConstantParent> parents)
{
- string typename = TypeHelper.GetTypeName(type);
+ string typename = TypeHelper.GetTypeName(type, NameFormattingOptions.DocumentationId);
typename = TranslationHelper.TurnStringIntoValidIdentifier(typename);
- // Need to append something to the name to avoid name clashes with other members (of a different
- // type) that have the same name.
- typename += "$type";
-
Bpl.IToken tok = type.Token();
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, typename, this.TypeType);
Bpl.Constant v = new Bpl.Constant(tok, tident, true /*unique*/, parents, false, null);
@@ -271,18 +267,21 @@ namespace BytecodeTranslator {
}
public Bpl.Function CreateTypeFunction(ITypeReference type, int parameterCount) {
- System.Diagnostics.Debug.Assert(parameterCount > 0);
- string typename = TypeHelper.GetTypeName(type);
+ System.Diagnostics.Debug.Assert(parameterCount >= 0);
+ string typename = TypeHelper.GetTypeName(type, NameFormattingOptions.DocumentationId);
typename = TranslationHelper.TurnStringIntoValidIdentifier(typename);
- // Need to append something to the name to avoid name clashes.
- typename += "$type";
Bpl.IToken tok = type.Token();
Bpl.VariableSeq inputs = new Bpl.VariableSeq();
- for (int i = 0; i < parameterCount; i++) {
- inputs.Add(new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "arg"+i, this.TypeType), true));
+ //for (int i = 0; i < parameterCount; i++) {
+ // inputs.Add(new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "arg"+i, this.TypeType), true));
+ //}
+ foreach (var t in type.ResolvedType.GenericParameters) {
+ inputs.Add(new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, t.Name.Value, this.TypeType), true));
}
Bpl.Variable output = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "result", this.TypeType), false);
Bpl.Function func = new Bpl.Function(tok, typename, inputs, output);
+ var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "constructor", new List<object>(1), null);
+ func.Attributes = attrib;
return func;
}
diff --git a/BCT/BytecodeTranslator/MetadataTraverser.cs b/BCT/BytecodeTranslator/MetadataTraverser.cs
index 19339962..4f0e3667 100644
--- a/BCT/BytecodeTranslator/MetadataTraverser.cs
+++ b/BCT/BytecodeTranslator/MetadataTraverser.cs
@@ -27,7 +27,7 @@ namespace BytecodeTranslator {
/// Responsible for traversing all metadata elements (i.e., everything exclusive
/// of method bodies).
/// </summary>
- public class MetadataTraverser : BaseMetadataTraverser {
+ public class BCTMetadataTraverser : MetadataTraverser {
readonly Sink sink;
public readonly TraverserFactory Factory;
@@ -35,7 +35,7 @@ namespace BytecodeTranslator {
public readonly IDictionary<IUnit, PdbReader> PdbReaders;
public PdbReader/*?*/ PdbReader;
- public MetadataTraverser(Sink sink, IDictionary<IUnit, PdbReader> pdbReaders, TraverserFactory factory)
+ public BCTMetadataTraverser(Sink sink, IDictionary<IUnit, PdbReader> pdbReaders, TraverserFactory factory)
: base() {
this.sink = sink;
this.Factory = factory;
@@ -47,7 +47,7 @@ namespace BytecodeTranslator {
foreach (IPrecondition pre in contract.Preconditions) {
var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true);
ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true);
- exptravers.Visit(pre.Condition); // TODO
+ exptravers.Traverse(pre.Condition); // TODO
// Todo: Deal with Descriptions
var req = new Bpl.Requires(pre.Token(), false, exptravers.TranslatedExpressions.Pop(), "");
translatedPres.Add(req);
@@ -61,7 +61,7 @@ namespace BytecodeTranslator {
foreach (IPostcondition post in contract.Postconditions) {
var stmtTraverser = this.Factory.MakeStatementTraverser(sink, null, true);
ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, stmtTraverser, true);
- exptravers.Visit(post.Condition);
+ exptravers.Traverse(post.Condition);
// Todo: Deal with Descriptions
var ens = new Bpl.Ensures(post.Token(), false, exptravers.TranslatedExpressions.Pop(), "");
translatedPosts.Add(ens);
@@ -74,7 +74,7 @@ namespace BytecodeTranslator {
ICollection<Bpl.IdentifierExpr> modifiedExpr = new List<Bpl.IdentifierExpr>();
foreach (IAddressableExpression mod in contract.ModifiedVariables) {
ExpressionTraverser exptravers = this.Factory.MakeExpressionTraverser(sink, null, true);
- exptravers.Visit(mod);
+ exptravers.Traverse(mod);
Bpl.IdentifierExpr idexp = exptravers.TranslatedExpressions.Pop() as Bpl.IdentifierExpr;
if (idexp == null) {
throw new TranslationException(String.Format("Cannot create IdentifierExpr for Modifyed Variable {0}", mod.ToString()));
@@ -88,16 +88,16 @@ namespace BytecodeTranslator {
#region Overrides
- public override void Visit(IModule module) {
+ public override void TraverseChildren(IModule module) {
this.PdbReaders.TryGetValue(module, out this.PdbReader);
- base.Visit(module);
+ base.TraverseChildren(module);
}
- public override void Visit(IAssembly assembly) {
+ public override void TraverseChildren(IAssembly assembly) {
this.PdbReaders.TryGetValue(assembly, out this.PdbReader);
this.sink.BeginAssembly(assembly);
try {
- base.Visit(assembly);
+ base.TraverseChildren(assembly);
} finally {
this.sink.EndAssembly(assembly);
}
@@ -107,7 +107,7 @@ namespace BytecodeTranslator {
/// Translate the type definition.
/// </summary>
///
- public override void Visit(ITypeDefinition typeDefinition) {
+ public override void TraverseChildren(ITypeDefinition typeDefinition) {
if (!this.sink.TranslateType(typeDefinition)) return;
@@ -117,11 +117,16 @@ namespace BytecodeTranslator {
trackPhonePageNameVariableName(typeDefinition);
trackPhoneApplicationClassname(typeDefinition);
+ var gtp = typeDefinition as IGenericTypeParameter;
+ if (gtp != null) {
+ return;
+ }
+
if (typeDefinition.IsClass) {
bool savedSawCctor = this.sawCctor;
this.sawCctor = false;
- sink.FindOrCreateType(typeDefinition);
- base.Visit(typeDefinition);
+ sink.FindOrCreateTypeReference(typeDefinition);
+ base.TraverseChildren(typeDefinition);
if (!this.sawCctor) {
CreateStaticConstructor(typeDefinition);
}
@@ -130,23 +135,23 @@ namespace BytecodeTranslator {
ITypeDefinition unspecializedType = Microsoft.Cci.MutableContracts.ContractHelper.Unspecialized(typeDefinition).ResolvedType;
sink.AddDelegateType(unspecializedType);
} else if (typeDefinition.IsInterface) {
- sink.FindOrCreateType(typeDefinition);
- base.Visit(typeDefinition);
+ sink.FindOrCreateTypeReference(typeDefinition);
+ base.TraverseChildren(typeDefinition);
} else if (typeDefinition.IsEnum) {
return; // enums just are translated as ints
} else if (typeDefinition.IsStruct) {
- sink.FindOrCreateType(typeDefinition);
+ sink.FindOrCreateTypeReference(typeDefinition);
CreateDefaultStructConstructor(typeDefinition);
CreateStructCopyConstructor(typeDefinition);
- base.Visit(typeDefinition);
+ base.TraverseChildren(typeDefinition);
} else {
Console.WriteLine("Unknown kind of type definition '{0}' was found",
TypeHelper.GetTypeName(typeDefinition));
throw new NotImplementedException(String.Format("Unknown kind of type definition '{0}'.", TypeHelper.GetTypeName(typeDefinition)));
}
- this.Visit(typeDefinition.PrivateHelperMembers);
+ this.Traverse(typeDefinition.PrivateHelperMembers);
foreach (var t in this.privateTypes) {
- this.Visit(t);
+ this.Traverse(t);
}
}
List<ITypeDefinition> privateTypes = new List<ITypeDefinition>();
@@ -221,7 +226,7 @@ namespace BytecodeTranslator {
};
}
- stmtTranslator.Visit(stmts);
+ stmtTranslator.Traverse(stmts);
var translatedStatements = stmtTranslator.StmtBuilder.Collect(Bpl.Token.NoToken);
var lit = Bpl.Expr.Literal(1);
@@ -325,7 +330,7 @@ namespace BytecodeTranslator {
});
}
- stmtTranslator.Visit(stmts);
+ stmtTranslator.Traverse(stmts);
var translatedStatements = stmtTranslator.StmtBuilder.Collect(Bpl.Token.NoToken);
List<Bpl.Variable> vars = new List<Bpl.Variable>();
@@ -352,7 +357,7 @@ namespace BytecodeTranslator {
/// <summary>
///
/// </summary>
- public override void Visit(IMethodDefinition method) {
+ public override void TraverseChildren(IMethodDefinition method) {
if (method.IsStaticConstructor) this.sawCctor = true;
@@ -406,7 +411,7 @@ namespace BytecodeTranslator {
#region Add assignments from In-Params to local-Params
- foreach (MethodParameter mparam in formalMap.Values) {
+ foreach (MethodParameter mparam in formalMap) {
if (mparam.inParameterCopy != null) {
Bpl.IToken tok = method.Token();
stmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok,
@@ -420,7 +425,9 @@ namespace BytecodeTranslator {
#region For non-deferring ctors and all cctors, initialize all fields to null-equivalent values
var inits = InitializeFieldsInConstructor(method);
if (0 < inits.Count) {
- new BlockStatement() { Statements = inits, }.Dispatch(stmtTraverser);
+ foreach (var s in inits) {
+ stmtTraverser.Traverse(s);
+ }
}
#endregion
@@ -481,7 +488,7 @@ namespace BytecodeTranslator {
#region Create Local Vars For Implementation
List<Bpl.Variable> vars = new List<Bpl.Variable>();
- foreach (MethodParameter mparam in formalMap.Values) {
+ foreach (MethodParameter mparam in formalMap) {
if (!mparam.underlyingParameter.IsByReference)
vars.Add(mparam.outParameterCopy);
}
@@ -597,7 +604,7 @@ namespace BytecodeTranslator {
return referencedTypeDefinition;
}
- public override void Visit(IFieldDefinition fieldDefinition) {
+ public override void TraverseChildren(IFieldDefinition fieldDefinition) {
Bpl.Variable fieldVar= this.sink.FindOrCreateFieldVariable(fieldDefinition);
// if tracked by the phone plugin, we need to find out the bpl assigned name for future use
@@ -642,31 +649,30 @@ namespace BytecodeTranslator {
addPhoneTopLevelDeclarations();
foreach (var a in assemblies) {
- a.Dispatch(this);
+ this.Traverse((IAssembly)a);
}
}
#endregion
#region Helpers
- private class FindCtorCall : BaseCodeTraverser {
+ private class FindCtorCall : CodeTraverser {
private bool isDeferringCtor = false;
public ITypeReference containingType;
public static bool IsDeferringCtor(IMethodDefinition method, IBlockStatement body) {
var fcc = new FindCtorCall(method.ContainingType);
- fcc.Visit(body);
+ fcc.Traverse(body);
return fcc.isDeferringCtor;
}
private FindCtorCall(ITypeReference containingType) {
this.containingType = containingType;
}
- public override void Visit(IMethodCall methodCall) {
+ public override void TraverseChildren(IMethodCall methodCall) {
var md = methodCall.MethodToCall.ResolvedMethod;
if (md != null && md.IsConstructor && methodCall.ThisArgument is IThisReference) {
this.isDeferringCtor = TypeHelper.TypesAreEquivalent(md.ContainingType, containingType);
- this.stopTraversal = true;
return;
}
- base.Visit(methodCall);
+ base.TraverseChildren(methodCall);
}
}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs
index 066d4cdf..a5ed9cf3 100644
--- a/BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs
+++ b/BCT/BytecodeTranslator/Phone/PhoneBackKeyCallbackTraverser.cs
@@ -6,7 +6,7 @@ using Microsoft.Cci;
using Microsoft.Cci.MutableCodeModel;
namespace BytecodeTranslator.Phone {
- class PhoneBackKeyCallbackTraverser : BaseCodeTraverser {
+ class PhoneBackKeyCallbackTraverser : CodeTraverser {
private ITypeReference typeBeingTraversed;
private IMetadataHost host;
@@ -14,12 +14,12 @@ namespace BytecodeTranslator.Phone {
this.host = host;
}
- public override void Visit(ITypeDefinition typeDef) {
+ public override void TraverseChildren(ITypeDefinition typeDef) {
typeBeingTraversed = typeDef;
- base.Visit(typeDef);
+ base.TraverseChildren(typeDef);
}
-
- public override void Visit(IMethodCall methodCall) {
+
+ public override void TraverseChildren(IMethodCall methodCall) {
if (methodCall.MethodToCall.ResolvedMethod.IsSpecialName && methodCall.MethodToCall.Name.Value == "add_BackKeyPress") {
// check if it is a back key handler and if it is...
// NAVIGATION TODO this only catches really locally delegate expressions. If it is created before, we see it as a BoundExpression
@@ -91,24 +91,24 @@ namespace BytecodeTranslator.Phone {
PhoneCodeHelper.instance().BackKeyUnknownDelegateOffenders.Add(typeBeingTraversed);
}
}
- base.Visit(methodCall);
+ base.TraverseChildren(methodCall);
}
private void parseBlockForNavigation(IBlockStatement block, out bool navigates, out ICollection<string> navTargets) {
PhoneNavigationCallsTraverser traverser = new PhoneNavigationCallsTraverser(host);
- traverser.Visit(block);
+ traverser.Traverse(block);
navigates = traverser.CodeDoesNavigation;
navTargets = traverser.NavigationTargets;
}
private void parseBlockForEventCancellation(IBlockStatement block, out bool cancels) {
PhoneNavigationCallsTraverser traverser = new PhoneNavigationCallsTraverser(host);
- traverser.Visit(block);
+ traverser.Traverse(block);
cancels = traverser.CancelsEvents;
}
}
- public class PhoneNavigationCallsTraverser : BaseCodeTraverser {
+ public class PhoneNavigationCallsTraverser : CodeTraverser {
private IMetadataHost host;
public bool CancelsEvents { get; private set; }
@@ -120,7 +120,7 @@ namespace BytecodeTranslator.Phone {
this.host = host;
}
- public override void Visit(IMethodCall call) {
+ public override void TraverseChildren(IMethodCall call) {
checkMethodCallForEventCancellation(call);
checkMethodCallForNavigation(call);
}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs
index f3e5ac08..0ed9270c 100644
--- a/BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs
+++ b/BCT/BytecodeTranslator/Phone/PhoneControlFeedbackTraverser.cs
@@ -6,14 +6,14 @@ using Microsoft.Cci;
using Microsoft.Cci.MutableCodeModel;
namespace BytecodeTranslator.Phone {
- class PhoneControlFeedbackCodeTraverser : BaseCodeTraverser {
+ class PhoneControlFeedbackCodeTraverser : CodeTraverser {
private IMetadataReaderHost host;
public PhoneControlFeedbackCodeTraverser(IMetadataReaderHost host) : base() {
this.host = host;
}
- public override void Visit(IMethodCall methodCall) {
+ public override void TraverseChildren(IMethodCall methodCall) {
if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
// check for handlers we do not wish to add feedback checks to
if (methodCall.MethodToCall.Name.Value.StartsWith("add_")) {
@@ -49,16 +49,16 @@ namespace BytecodeTranslator.Phone {
}
- class PhoneControlFeedbackMetadataTraverser : BaseMetadataTraverser {
+ class PhoneControlFeedbackMetadataTraverser : MetadataTraverser {
private IMetadataReaderHost host;
public PhoneControlFeedbackMetadataTraverser(IMetadataReaderHost host) : base() {
this.host = host;
}
- public override void Visit(IMethodDefinition method) {
+ public override void TraverseChildren(IMethodDefinition method) {
PhoneControlFeedbackCodeTraverser codeTraverser = new PhoneControlFeedbackCodeTraverser(host);
- codeTraverser.Visit(method);
+ codeTraverser.TraverseChildren(method);
}
}
}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs
index 391aaaaa..db1aac4c 100644
--- a/BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs
+++ b/BCT/BytecodeTranslator/Phone/PhoneInitializationTraverser.cs
@@ -23,7 +23,7 @@ namespace BytecodeTranslator.Phone {
/// <summary>
/// Traverse code looking for phone specific points of interest, possibly injecting necessary code in-between
/// </summary>
- public class PhoneInitializationCodeTraverser : BaseCodeTraverser {
+ public class PhoneInitializationCodeTraverser : CodeTraverser {
private readonly IMethodDefinition methodBeingTraversed;
private static bool initializationFound= false;
private MetadataReaderHost host;
@@ -185,7 +185,7 @@ namespace BytecodeTranslator.Phone {
}
public void injectPhoneControlsCode(BlockStatement block) {
- this.Visit(block);
+ this.Traverse(block);
}
private void injectPhoneInitializationCode(BlockStatement block, Statement statementAfter) {
@@ -300,9 +300,9 @@ namespace BytecodeTranslator.Phone {
return new List<IStatement>();
}
- public override void Visit(IBlockStatement block) {
+ public override void TraverseChildren(IBlockStatement block) {
foreach (IStatement statement in block.Statements) {
- this.Visit(statement);
+ this.Traverse(statement);
if (initializationFound) {
injectPhoneInitializationCode(block as BlockStatement, statement as Statement);
initializationFound = false;
@@ -311,7 +311,7 @@ namespace BytecodeTranslator.Phone {
}
}
- public override void Visit(IMethodCall methodCall) {
+ public override void TraverseChildren(IMethodCall methodCall) {
if (methodCall.IsStaticCall ||
!methodCall.MethodToCall.ContainingType.ResolvedType.Equals(methodBeingTraversed.Container) ||
methodCall.MethodToCall.Name.Value != "InitializeComponent" ||
@@ -325,7 +325,7 @@ namespace BytecodeTranslator.Phone {
/// <summary>
/// Traverse metadata looking only for PhoneApplicationPage's constructors
/// </summary>
- public class PhoneInitializationMetadataTraverser : BaseMetadataTraverser {
+ public class PhoneInitializationMetadataTraverser : MetadataTraverser {
private MetadataReaderHost host;
public PhoneInitializationMetadataTraverser(MetadataReaderHost host)
@@ -333,30 +333,30 @@ namespace BytecodeTranslator.Phone {
this.host = host;
}
- public override void Visit(IModule module) {
- base.Visit(module);
+ public override void TraverseChildren(IModule module) {
+ base.TraverseChildren(module);
}
- public override void Visit(IAssembly assembly) {
- base.Visit(assembly);
+ public override void TraverseChildren(IAssembly assembly) {
+ base.TraverseChildren(assembly);
}
/// <summary>
/// Check if the type being defined is a PhoneApplicationPage, uninteresting otherwise
/// </summary>
///
- public override void Visit(ITypeDefinition typeDefinition) {
+ public override void TraverseChildren(ITypeDefinition typeDefinition) {
if (typeDefinition.isPhoneApplicationClass(host)) {
PhoneCodeHelper.instance().setMainAppTypeReference(typeDefinition);
} else if (typeDefinition.isPhoneApplicationPageClass(host)) {
- base.Visit(typeDefinition);
+ base.TraverseChildren(typeDefinition);
}
}
/// <summary>
/// Check if it is traversing a constructor. If so, place necessary code after InitializeComponent() call
/// </summary>
- public override void Visit(IMethodDefinition method) {
+ public override void TraverseChildren(IMethodDefinition method) {
if (!method.IsConstructor)
return;
@@ -370,7 +370,7 @@ namespace BytecodeTranslator.Phone {
public void InjectPhoneCodeAssemblies(IEnumerable<IUnit> assemblies) {
foreach (var a in assemblies) {
- a.Dispatch(this);
+ this.Traverse((IAssembly)a);
}
}
}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs
index 97935721..1957c2fa 100644
--- a/BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs
+++ b/BCT/BytecodeTranslator/Phone/PhoneMethodInliningTraverser.cs
@@ -5,7 +5,7 @@ using System.Text;
using Microsoft.Cci;
namespace BytecodeTranslator.Phone {
- public class PhoneMethodInliningMetadataTraverser : BaseMetadataTraverser {
+ public class PhoneMethodInliningMetadataTraverser : MetadataTraverser {
private HashSet<IMethodDefinition> methodsToInline;
private HashSet<IMethodDefinition> iterMethodsToInline;
private PhoneCodeHelper phoneHelper;
@@ -23,21 +23,21 @@ namespace BytecodeTranslator.Phone {
TotalMethodsCount = 0;
}
- public override void Visit(IEnumerable<IModule> modules) {
- foreach (IModule module in modules) {
- assemblyBeingTranslated= module.ContainingAssembly;
- this.Visit(module);
+ public override void TraverseChildren(IAssembly assembly) {
+ foreach (IModule module in assembly.MemberModules) {
+ assemblyBeingTranslated = module.ContainingAssembly;
+ this.Traverse(module);
}
firstPassDone = true;
}
- public override void Visit(IMethodDefinition method) {
+ public override void TraverseChildren(IMethodDefinition method) {
if (!firstPassDone)
TotalMethodsCount++;
if (iterMethodsToInline.Contains(method) || (!firstPassDone && phoneHelper.mustInlineMethod(method))) {
PhoneMethodInliningCodeTraverser codeTraverser= new PhoneMethodInliningCodeTraverser();
- codeTraverser.Visit(method);
+ codeTraverser.TraverseChildren(method);
foreach (IMethodDefinition newMethodDef in codeTraverser.getMethodsFound()) {
bool isExtern = this.assemblyBeingTranslated != null &&
!TypeHelper.GetDefiningUnitReference(newMethodDef.ContainingType).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity);
@@ -62,15 +62,15 @@ namespace BytecodeTranslator.Phone {
public void findAllMethodsToInline(List<IModule> modules) {
while (!isFinished()) {
changedOnLastPass = false;
- Visit(modules);
+ this.Traverse(modules);
}
}
}
- class PhoneMethodInliningCodeTraverser : BaseCodeTraverser {
+ class PhoneMethodInliningCodeTraverser : CodeTraverser {
private HashSet<IMethodDefinition> foundMethods = new HashSet<IMethodDefinition>();
- public override void Visit(IMethodCall methodCall) {
+ public override void TraverseChildren(IMethodCall methodCall) {
foundMethods.Add(methodCall.MethodToCall.ResolvedMethod);
}
diff --git a/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs b/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
index a5571efa..0fa4a884 100644
--- a/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
+++ b/BCT/BytecodeTranslator/Phone/PhoneNavigationTraverser.cs
@@ -7,7 +7,7 @@ using Microsoft.Cci.MutableCodeModel;
using TranslationPlugins;
namespace BytecodeTranslator.Phone {
- public class PhoneNavigationCodeTraverser : BaseCodeTraverser {
+ public class PhoneNavigationCodeTraverser : CodeTraverser {
private MetadataReaderHost host;
private ITypeReference navigationSvcType;
private ITypeReference cancelEventArgsType;
@@ -38,12 +38,12 @@ namespace BytecodeTranslator.Phone {
navigationCallers = new HashSet<IMethodReference>();
}
- public override void Visit(ITypeDefinition typeDef) {
+ public override void TraverseChildren(ITypeDefinition typeDef) {
this.typeTraversed = typeDef;
- base.Visit(typeDef);
+ base.TraverseChildren(typeDef);
}
- public override void Visit(IMethodDefinition method) {
+ public override void TraverseChildren(IMethodDefinition method) {
this.methodTraversed = method;
if (method.IsConstructor && PhoneTypeHelper.isPhoneApplicationClass(typeTraversed, host)) {
navigationCallers.Add(method);
@@ -77,7 +77,7 @@ namespace BytecodeTranslator.Phone {
}
}
}
- base.Visit(method);
+ base.TraverseChildren(method);
}
@@ -87,14 +87,14 @@ namespace BytecodeTranslator.Phone {
private StaticURIMode currentStaticMode= StaticURIMode.NOT_STATIC;
private string unpurifiedFoundURI="";
- public override void Visit(IBlockStatement block) {
+ public override void TraverseChildren(IBlockStatement block) {
IList<Tuple<IStatement,StaticURIMode,string>> staticNavStmts = new List<Tuple<IStatement,StaticURIMode,string>>();
IList<IStatement> nonStaticNavStmts = new List<IStatement>();
foreach (IStatement statement in block.Statements) {
navCallFound = false;
navCallIsStatic = false;
navCallIsBack = false;
- this.Visit(statement);
+ this.Traverse(statement);
if (navCallFound) {
navCallers.Add(methodTraversed);
if (navCallIsStatic) {
@@ -165,7 +165,7 @@ namespace BytecodeTranslator.Phone {
return true;
}
- public override void Visit(IMethodCall methodCall) {
+ public override void TraverseChildren(IMethodCall methodCall) {
string target;
if (isNavigationOnBackKeyPressHandler(methodCall, out target)) {
ICollection<Tuple<IMethodReference,string>> targets;
@@ -316,7 +316,7 @@ namespace BytecodeTranslator.Phone {
/// <summary>
/// Traverse metadata looking only for PhoneApplicationPage's constructors
/// </summary>
- public class PhoneNavigationMetadataTraverser : BaseMetadataTraverser {
+ public class PhoneNavigationMetadataTraverser : MetadataTraverser {
private MetadataReaderHost host;
private ITypeDefinition typeBeingTraversed;
private PhoneNavigationCodeTraverser codeTraverser;
@@ -326,13 +326,15 @@ namespace BytecodeTranslator.Phone {
this.host = host;
}
- public override void Visit(IEnumerable<IAssemblyReference> assemblies) {
- codeTraverser = new PhoneNavigationCodeTraverser(host, assemblies);
- base.Visit(assemblies);
+ public override void TraverseChildren(IModule module) {
+ codeTraverser = new PhoneNavigationCodeTraverser(host, module.AssemblyReferences);
+ base.Traverse(module.AssemblyReferences);
+ base.TraverseChildren(module);
}
+
// TODO can we avoid visiting every type? Are there only a few, identifiable, types that may perform navigation?
- public override void Visit(ITypeDefinition typeDefinition) {
+ public override void TraverseChildren(ITypeDefinition typeDefinition) {
typeBeingTraversed = typeDefinition;
if (typeDefinition.isPhoneApplicationClass(host)) {
NamespaceTypeDefinition mutableTypeDef = typeDefinition as NamespaceTypeDefinition;
@@ -351,22 +353,22 @@ namespace BytecodeTranslator.Phone {
}
}
- codeTraverser.Visit(typeDefinition);
- base.Visit(typeDefinition);
+ codeTraverser.Traverse(typeDefinition);
+ base.TraverseChildren(typeDefinition);
}
// TODO same here. Are there specific methods (and ways to identfy those) that can perform navigation?
- public override void Visit(IMethodDefinition method) {
+ public override void TraverseChildren(IMethodDefinition method) {
if (PhoneCodeHelper.instance().isBackKeyPressOverride(method)) {
PhoneCodeHelper.instance().KnownBackKeyHandlers.Add(method);
PhoneCodeHelper.instance().OnBackKeyPressOverriden = true;
}
- base.Visit(method);
+ base.TraverseChildren(method);
}
public void InjectPhoneCodeAssemblies(IEnumerable<IUnit> assemblies) {
foreach (var a in assemblies) {
- a.Dispatch(this);
+ this.Traverse((IAssembly)a);
}
}
}
diff --git a/BCT/BytecodeTranslator/Program.cs b/BCT/BytecodeTranslator/Program.cs
index d3994a6c..f9b0023d 100644
--- a/BCT/BytecodeTranslator/Program.cs
+++ b/BCT/BytecodeTranslator/Program.cs
@@ -210,6 +210,9 @@ namespace BytecodeTranslator {
pdbReader = new PdbReader(pdbStream, host);
}
module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader) as IModule;
+ // The decompiler does not turn calls to Assert/Assume into Code Model nodes
+ module = new Microsoft.Cci.MutableContracts.ContractExtractor.AssertAssumeExtractor(host, pdbReader).Visit(module);
+
host.RegisterAsLatest(module);
modules.Add(module);
contractExtractors.Add(module, host.GetContractExtractor(module.UnitIdentity));
@@ -396,7 +399,7 @@ namespace BytecodeTranslator {
System.Console.WriteLine("Total methods seen: {0}, inlined: {1}", inlineTraverser.TotalMethodsCount, inlineTraverser.InlinedMethodsCount);
PhoneBackKeyCallbackTraverser traverser = new PhoneBackKeyCallbackTraverser(sink.host);
- traverser.Visit(modules);
+ traverser.Traverse(modules);
}
}
diff --git a/BCT/BytecodeTranslator/Sink.cs b/BCT/BytecodeTranslator/Sink.cs
index faa48773..d20671b2 100644
--- a/BCT/BytecodeTranslator/Sink.cs
+++ b/BCT/BytecodeTranslator/Sink.cs
@@ -223,7 +223,7 @@ namespace BytecodeTranslator {
var key = ((IMethodReference)sig);
this.declaredMethods.TryGetValue(key, out procAndFormalMap);
var formalMap = procAndFormalMap.FormalMap;
- formalMap.TryGetValue(param, out mp);
+ mp = formalMap[param.Index];
return contractContext ? mp.inParameterCopy : mp.outParameterCopy;
}
@@ -433,7 +433,7 @@ namespace BytecodeTranslator {
public struct ProcedureInfo {
private Bpl.DeclWithFormals decl;
- private Dictionary<IParameterDefinition, MethodParameter> formalMap;
+ private MethodParameter[] formalMap; // maps parameter index to formal
private Bpl.Formal thisVariable;
private Bpl.Formal returnVariable;
private Bpl.LocalVariable localExcVariable;
@@ -453,20 +453,20 @@ namespace BytecodeTranslator {
}
public ProcedureInfo(
Bpl.DeclWithFormals decl,
- Dictionary<IParameterDefinition, MethodParameter> formalMap)
+ MethodParameter[] formalMap)
: this(decl) {
this.formalMap = formalMap;
}
public ProcedureInfo(
Bpl.DeclWithFormals decl,
- Dictionary<IParameterDefinition, MethodParameter> formalMap,
+ MethodParameter[] formalMap,
Bpl.Formal returnVariable)
: this(decl, formalMap) {
this.returnVariable = returnVariable;
}
public ProcedureInfo(
Bpl.DeclWithFormals decl,
- Dictionary<IParameterDefinition, MethodParameter> formalMap,
+ MethodParameter[] formalMap,
Bpl.Formal returnVariable,
Bpl.Formal thisVariable,
Bpl.LocalVariable localExcVariable,
@@ -482,7 +482,7 @@ namespace BytecodeTranslator {
}
public Bpl.DeclWithFormals Decl { get { return decl; } }
- public Dictionary<IParameterDefinition, MethodParameter> FormalMap { get { return formalMap; } }
+ public MethodParameter[] FormalMap { get { return formalMap; } }
public Bpl.Formal ThisVariable { get { return thisVariable; } }
public Bpl.Formal ReturnVariable { get { return returnVariable; } }
public Bpl.LocalVariable LocalExcVariable { get { return localExcVariable; } }
@@ -508,13 +508,13 @@ namespace BytecodeTranslator {
int in_count = 0;
int out_count = 0;
MethodParameter mp;
- var formalMap = new Dictionary<IParameterDefinition, MethodParameter>();
+ var formalMap = new MethodParameter[IteratorHelper.EnumerableCount(method.Parameters)];
foreach (IParameterDefinition formal in method.Parameters) {
mp = new MethodParameter(formal, this.CciTypeToBoogie(formal.Type));
if (mp.inParameterCopy != null) in_count++;
if (mp.outParameterCopy != null && formal.IsByReference)
out_count++;
- formalMap.Add(formal, mp);
+ formalMap[formal.Index] = mp;
}
if (method.Type.TypeCode != PrimitiveTypeCode.Void) {
@@ -560,7 +560,7 @@ namespace BytecodeTranslator {
if (thisVariable != null)
invars[i++] = thisVariable;
- foreach (MethodParameter mparam in formalMap.Values) {
+ foreach (MethodParameter mparam in formalMap) {
if (mparam.inParameterCopy != null) {
invars[i++] = mparam.inParameterCopy;
}
@@ -675,7 +675,7 @@ namespace BytecodeTranslator {
if (!TranslationHelper.IsStruct(p2.Type)) continue;
if (!TypeHelper.TypesAreEquivalent(p1.Type, p2.Type)) continue;
var req = new Bpl.Requires(true, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq,
- Bpl.Expr.Ident(formalMap[p1].inParameterCopy), Bpl.Expr.Ident(formalMap[p2].inParameterCopy)));
+ Bpl.Expr.Ident(formalMap[p1.Index].inParameterCopy), Bpl.Expr.Ident(formalMap[p2.Index].inParameterCopy)));
boogiePrecondition.Add(req);
}
}
@@ -715,7 +715,7 @@ namespace BytecodeTranslator {
new Bpl.EnsuresSeq()
);
this.TranslatedProgram.TopLevelDeclarations.Add(proc);
- procAndFormalMap = new ProcedureInfo(proc, new Dictionary<IParameterDefinition, MethodParameter>());
+ procAndFormalMap = new ProcedureInfo(proc, new MethodParameter[0]);
this.declaredStructDefaultCtors.Add(key, procAndFormalMap);
}
return procAndFormalMap.Decl;
@@ -759,7 +759,7 @@ namespace BytecodeTranslator {
new Bpl.EnsuresSeq(ens)
);
this.TranslatedProgram.TopLevelDeclarations.Add(proc);
- procAndFormalMap = new ProcedureInfo(proc, new Dictionary<IParameterDefinition, MethodParameter>());
+ procAndFormalMap = new ProcedureInfo(proc, new MethodParameter[0]);
this.declaredStructCopyCtors.Add(key, procAndFormalMap);
}
return procAndFormalMap.Decl;
@@ -820,16 +820,18 @@ namespace BytecodeTranslator {
return result;
}
- private static int NumGenericParameters(ITypeReference typeReference) {
- ITypeDefinition typeDefinition = typeReference.ResolvedType;
- int numParameters = typeDefinition.GenericParameterCount;
- INestedTypeDefinition ntd = typeDefinition as INestedTypeDefinition;
- while (ntd != null) {
- ITypeDefinition containingType = ntd.ContainingType.ResolvedType;
- numParameters += containingType.GenericParameterCount;
- ntd = containingType as INestedTypeDefinition;
+ private static ushort ConsolidatedGenericParameterCount(ITypeReference typeReference) {
+ Contract.Requires(typeReference != null);
+
+ var typeDefinition = typeReference.ResolvedType;
+ var totalNumberOfParameters = typeDefinition.GenericParameterCount;
+ var nestedTypeDefinition = typeDefinition as INestedTypeDefinition;
+ while (nestedTypeDefinition != null) {
+ var containingType = nestedTypeDefinition.ContainingType.ResolvedType;
+ totalNumberOfParameters += containingType.GenericParameterCount;
+ nestedTypeDefinition = containingType as INestedTypeDefinition;
}
- return numParameters;
+ return totalNumberOfParameters;
}
public static ITypeReference GetUninstantiatedGenericType(ITypeReference typeReference) {
@@ -871,30 +873,29 @@ namespace BytecodeTranslator {
/// <paramref name="type"/> in the Bpl program. I.e., its
/// value represents the expression "typeof(type)".
/// </summary>
- public Bpl.Expr FindOrCreateType(ITypeReference type) {
- // The Heap has to decide how to represent the field (i.e., its type),
- // all the Sink cares about is adding a declaration for it.
+ public Bpl.Expr FindOrCreateTypeReference(ITypeReference type) {
+
+ var gtir = type as IGenericTypeInstanceReference;
+ if (gtir != null) {
+ var genericType = FindOrDefineType(gtir.GenericType);
+ var gArgs = new Bpl.ExprSeq();
+ foreach (var a in gtir.GenericArguments) {
+ var a_prime = FindOrCreateTypeReference(a);
+ gArgs.Add(a_prime);
+ }
+ var typeExpression = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(genericType), gArgs);
+ }
IGenericTypeParameter gtp = type as IGenericTypeParameter;
if (gtp != null) {
- int index = gtp.Index;
- var nestedType = gtp.DefiningType as INestedTypeDefinition;
- while (nestedType != null) {
- // calculate the consolidated index: the parameter knows only its index
- // in the type that declares it, not including any outer containing types
- var containingType = nestedType.ContainingTypeDefinition;
- index += containingType.GenericParameterCount;
- nestedType = containingType as INestedTypeDefinition;
- }
-
- ProcedureInfo info = FindOrCreateProcedure(methodBeingTranslated);
- if (methodBeingTranslated.IsStatic) {
- return Bpl.Expr.Ident(info.TypeParameter(index));
- }
- else {
- Bpl.Expr thisExpr = Bpl.Expr.Ident(this.ThisVariable);
- return new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(childFunctions[index]), new Bpl.ExprSeq(this.Heap.DynamicType(thisExpr)));
+ Bpl.Variable v;
+ if (!this.declaredTypeVariables.TryGetValue(gtp.InternedKey, out v)) {
+ var loc = Bpl.Token.NoToken;
+ var t = CciTypeToBoogie(gtp);
+ v = new Bpl.LocalVariable(loc, new Bpl.TypedIdent(loc, gtp.Name.Value, t));
+ this.declaredTypeVariables.Add(gtp.InternedKey, v);
}
+ return Bpl.Expr.Ident(v);
}
IGenericMethodParameter gmp = type as IGenericMethodParameter;
@@ -908,123 +909,106 @@ namespace BytecodeTranslator {
GetConsolidatedTypeArguments(consolidatedTypeArguments, type);
if (consolidatedTypeArguments.Count > 0) {
- this.FindOrCreateType(uninstantiatedGenericType);
- var key = uninstantiatedGenericType.InternedKey;
- Bpl.Function f = this.declaredTypeFunctions[key];
+ this.FindOrCreateTypeReference(uninstantiatedGenericType);
+ var k = uninstantiatedGenericType.InternedKey;
+ var f2 = this.declaredTypeFunctions[k];
Bpl.ExprSeq args = new Bpl.ExprSeq();
foreach (ITypeReference p in consolidatedTypeArguments) {
- args.Add(FindOrCreateType(p));
+ args.Add(FindOrCreateTypeReference(p));
}
- Bpl.Expr naryExpr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f), args);
+ Bpl.Expr naryExpr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f2), args);
return naryExpr;
}
- int numParameters = NumGenericParameters(type);
+ var f = FindOrDefineType(type);
+ // BUGBUG: Generics!
+ var fCall = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f), new Bpl.ExprSeq());
+ return fCall;
+ }
+
+
+ /// <summary>
+ /// The Heap has to decide how to represent the type.
+ /// All the Sink cares about is adding a declaration for it.
+ /// </summary>
+ private Bpl.Function FindOrDefineType(ITypeReference type) {
+
+ Bpl.Function f;
+
+ var key = type.InternedKey;
+ if (this.declaredTypeFunctions.TryGetValue(key, out f))
+ return f;
+
+ var numParameters = ConsolidatedGenericParameterCount(type);
+
+ f = this.Heap.CreateTypeFunction(type, numParameters);
+ this.declaredTypeFunctions.Add(key, f);
+ this.TranslatedProgram.TopLevelDeclarations.Add(f);
+ DeclareParents(type.ResolvedType, f);
+
bool isExtern = this.assemblyBeingTranslated != null &&
!TypeHelper.GetDefiningUnitReference(type).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity);
-
- if (numParameters > 0) {
- Bpl.Function f;
- var key = type.InternedKey;
- if (!this.declaredTypeFunctions.TryGetValue(key, out f)) {
- Bpl.VariableSeq vseq = new Bpl.VariableSeq();
- for (int i = 0; i < numParameters; i++) {
- vseq.Add(new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, this.Heap.TypeType), true));
- }
- f = this.Heap.CreateTypeFunction(type, numParameters);
- this.declaredTypeFunctions.Add(key, f);
- this.TranslatedProgram.TopLevelDeclarations.Add(f);
- if (numParameters > childFunctions.Count) {
- for (int i = childFunctions.Count; i < numParameters; i++) {
- Bpl.Variable input = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "in", this.Heap.TypeType), true);
- Bpl.Variable output = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "out", this.Heap.TypeType), false);
- Bpl.Function g = new Bpl.Function(Bpl.Token.NoToken, "Child" + i, new Bpl.VariableSeq(input), output);
- TranslatedProgram.TopLevelDeclarations.Add(g);
- childFunctions.Add(g);
- }
- }
- if (isExtern) {
- var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "extern", new List<object>(1), null);
- f.Attributes = attrib;
- }
- else {
- Bpl.VariableSeq qvars = new Bpl.VariableSeq();
- Bpl.ExprSeq exprs = new Bpl.ExprSeq();
- for (int i = 0; i < numParameters; i++) {
- Bpl.Variable v = new Bpl.Constant(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, this.Heap.TypeType));
- qvars.Add(v);
- exprs.Add(Bpl.Expr.Ident(v));
- }
- Bpl.Expr e = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f), exprs);
- for (int i = 0; i < numParameters; i++) {
- Bpl.Expr appl = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(childFunctions[i]), new Bpl.ExprSeq(e));
- Bpl.Trigger trigger = new Bpl.Trigger(Bpl.Token.NoToken, true, new Bpl.ExprSeq(e));
- Bpl.Expr qexpr = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, Bpl.Expr.Eq(appl, Bpl.Expr.Ident(qvars[i])));
- TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, qexpr));
- }
- }
- }
- return null;
- }
- else {
- Bpl.Variable t;
- var key = type.InternedKey;
- if (!this.declaredTypeConstants.TryGetValue(key, out t)) {
- //List<ITypeReference> structuralParents;
- //var parents = GetParents(type.ResolvedType, out structuralParents);
- //t = this.Heap.CreateTypeVariable(type, parents);
- t = this.Heap.CreateTypeVariable(type, null);
- this.declaredTypeConstants.Add(key, t);
- //foreach (var p in structuralParents) {
- // var p_prime = FindOrCreateType(p);
- // //var e = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Subtype, Bpl.Expr.Ident(t), p_prime);
- // var e = new Bpl.NAryExpr(
- // Bpl.Token.NoToken,
- // new Bpl.FunctionCall(this.Heap.Subtype),
- // new Bpl.ExprSeq(Bpl.Expr.Ident(t), p_prime)
- // );
- // var a = new Bpl.Axiom(Bpl.Token.NoToken, e);
- // this.TranslatedProgram.TopLevelDeclarations.Add(a);
- //}
- this.TranslatedProgram.TopLevelDeclarations.Add(t);
- DeclareParents(type.ResolvedType, t);
- if (isExtern) {
- var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "extern", new List<object>(1), null);
- t.Attributes = attrib;
- }
- }
- return Bpl.Expr.Ident(t);
+ if (isExtern) {
+ var attrib = new Bpl.QKeyValue(Bpl.Token.NoToken, "extern", new List<object>(1), null);
+ if (f.Attributes == null)
+ f.Attributes = attrib;
+ else
+ f.Attributes.AddLast(attrib);
}
+ return f;
}
- private void DeclareSuperType(Bpl.Variable typeDefinitionAsBplConstant, ITypeReference superType) {
- var superType_prime = FindOrCreateType(superType);
- var e = new Bpl.NAryExpr(
- Bpl.Token.NoToken,
- new Bpl.FunctionCall(this.Heap.Subtype),
- new Bpl.ExprSeq(Bpl.Expr.Ident(typeDefinitionAsBplConstant), superType_prime)
- );
- var a = new Bpl.Axiom(Bpl.Token.NoToken, e);
- this.TranslatedProgram.TopLevelDeclarations.Add(a);
- if (!superType.ResolvedType.IsInterface) {
- var e2 = new Bpl.NAryExpr(
- Bpl.Token.NoToken,
- new Bpl.FunctionCall(this.Heap.DisjointSubtree),
- new Bpl.ExprSeq(Bpl.Expr.Ident(typeDefinitionAsBplConstant), superType_prime)
- );
- var a2 = new Bpl.Axiom(Bpl.Token.NoToken, e2);
- this.TranslatedProgram.TopLevelDeclarations.Add(a2);
- }
- }
- private void DeclareParents(ITypeDefinition typeDefinition, Bpl.Variable typeDefinitionAsBplConstant) {
+ private void DeclareParents(ITypeDefinition typeDefinition, Bpl.Function typeDefinitionAsBplFunction) {
foreach (var p in typeDefinition.BaseClasses) {
- DeclareSuperType(typeDefinitionAsBplConstant, p);
+ DeclareSuperType(typeDefinitionAsBplFunction, p);
}
foreach (var j in typeDefinition.Interfaces) {
- DeclareSuperType(typeDefinitionAsBplConstant, j);
+ DeclareSuperType(typeDefinitionAsBplFunction, j);
}
return;
}
+ private void DeclareSuperType(Bpl.Function typeDefinitionAsBplFunction, ITypeReference superType) {
+ var superType_prime = FindOrCreateTypeReference(superType);
+ var numberOfGenericParameters = typeDefinitionAsBplFunction.InParams.Length;
+
+ var qvars = new Bpl.VariableSeq();
+ var exprs = new Bpl.ExprSeq();
+ for (int i = 0; i < numberOfGenericParameters; i++) {
+ var t = typeDefinitionAsBplFunction.InParams[i];
+ qvars.Add(t);
+ exprs.Add(Bpl.Expr.Ident(t));
+ }
+
+ // G(t,u)
+ var callToG = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(typeDefinitionAsBplFunction), exprs);
+ // Subtype(G(t,u), super)
+ Bpl.Expr subtype = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.Heap.Subtype), new Bpl.ExprSeq(callToG, superType_prime));
+ Bpl.Expr disjointSubtree = null;
+ var isDisjoint = !superType.ResolvedType.IsInterface;
+ if (isDisjoint) {
+ // DisjointSubtree(G(t,u), super)
+ disjointSubtree = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.Heap.DisjointSubtree), new Bpl.ExprSeq(callToG, superType_prime));
+ }
+
+ if (0 < numberOfGenericParameters) {
+
+ // (forall t : Type, u : Type :: { G(t,u) } Subtype(G(t,u), super))
+ var trigger = new Bpl.Trigger(Bpl.Token.NoToken, true, new Bpl.ExprSeq(callToG));
+ var forall = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, subtype);
+ subtype = forall;
+
+ if (isDisjoint) {
+ // (forall t : Type, u : Type :: { G(t,u) } DisjointSubtree(G(t,u), super))
+ disjointSubtree = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, trigger, disjointSubtree);
+ }
+ }
+
+ this.TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, subtype));
+ if (isDisjoint) {
+ this.TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, disjointSubtree));
+ }
+
+ }
private List<Bpl.ConstantParent> GetParents(ITypeDefinition typeDefinition, out List<ITypeReference> structuralParents) {
var parents = new List<Bpl.ConstantParent>();
@@ -1034,7 +1018,7 @@ namespace BytecodeTranslator {
structuralParents.Add(p);
}
else {
- var v = (Bpl.IdentifierExpr)FindOrCreateType(p);
+ var v = (Bpl.IdentifierExpr)FindOrCreateTypeReference(p);
parents.Add(new Bpl.ConstantParent(v, true));
}
}
@@ -1043,7 +1027,7 @@ namespace BytecodeTranslator {
structuralParents.Add(j);
}
else {
- var v = (Bpl.IdentifierExpr)FindOrCreateType(j);
+ var v = (Bpl.IdentifierExpr)FindOrCreateTypeReference(j);
parents.Add(new Bpl.ConstantParent(v, false));
}
}
@@ -1053,7 +1037,7 @@ namespace BytecodeTranslator {
/// <summary>
/// The keys to the table are the interned key of the type.
/// </summary>
- private Dictionary<uint, Bpl.Variable> declaredTypeConstants = new Dictionary<uint, Bpl.Variable>();
+ private Dictionary<uint, Bpl.Variable> declaredTypeVariables = new Dictionary<uint, Bpl.Variable>();
private Dictionary<uint, Bpl.Function> declaredTypeFunctions = new Dictionary<uint, Bpl.Function>();
private List<Bpl.Function> childFunctions = new List<Bpl.Function>();
@@ -1160,7 +1144,7 @@ namespace BytecodeTranslator {
mostNestedTryStatementTraverser = new MostNestedTryStatementTraverser();
escapingGotoEdges = new Dictionary<ITryCatchFinallyStatement, List<string>>();
nestedTryCatchFinallyStatements = new List<Tuple<ITryCatchFinallyStatement, TryCatchFinallyContext>>();
- mostNestedTryStatementTraverser.Visit(method.Body);
+ mostNestedTryStatementTraverser.Traverse(method.Body);
}
public void BeginAssembly(IAssembly assembly) {
diff --git a/BCT/BytecodeTranslator/StatementTraverser.cs b/BCT/BytecodeTranslator/StatementTraverser.cs
index 15f59a13..7a9340db 100644
--- a/BCT/BytecodeTranslator/StatementTraverser.cs
+++ b/BCT/BytecodeTranslator/StatementTraverser.cs
@@ -22,18 +22,18 @@ using BytecodeTranslator.Phone;
namespace BytecodeTranslator
{
- public class MostNestedTryStatementTraverser : BaseCodeTraverser {
+ public class MostNestedTryStatementTraverser : CodeTraverser {
Dictionary<IName, ITryCatchFinallyStatement> mostNestedTryStatement = new Dictionary<IName, ITryCatchFinallyStatement>();
ITryCatchFinallyStatement currStatement = null;
- public override void Visit(ILabeledStatement labeledStatement) {
+ public override void TraverseChildren(ILabeledStatement labeledStatement) {
if (currStatement != null)
mostNestedTryStatement.Add(labeledStatement.Label, currStatement);
- base.Visit(labeledStatement);
+ base.TraverseChildren(labeledStatement);
}
- public override void Visit(ITryCatchFinallyStatement tryCatchFinallyStatement) {
+ public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement) {
ITryCatchFinallyStatement savedStatement = currStatement;
currStatement = tryCatchFinallyStatement;
- base.Visit(tryCatchFinallyStatement);
+ base.TraverseChildren(tryCatchFinallyStatement);
currStatement = savedStatement;
}
public ITryCatchFinallyStatement MostNestedTryStatement(IName label) {
@@ -43,7 +43,7 @@ namespace BytecodeTranslator
}
}
- public class StatementTraverser : BaseCodeTraverser {
+ public class StatementTraverser : CodeTraverser {
public readonly TraverserFactory factory;
@@ -64,6 +64,7 @@ namespace BytecodeTranslator
PdbReader = pdbReader;
this.contractContext = contractContext;
this.captureState = sink.Options.captureState;
+ this.PreorderVisitor = new SourceContextEmitter(this);
}
#endregion
@@ -71,7 +72,7 @@ namespace BytecodeTranslator
Bpl.Expr ExpressionFor(IExpression expression) {
ExpressionTraverser etrav = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- etrav.Visit(expression);
+ etrav.Traverse(expression);
Contract.Assert(etrav.TranslatedExpressions.Count == 1);
return etrav.TranslatedExpressions.Pop();
}
@@ -87,11 +88,54 @@ namespace BytecodeTranslator
var remover = new AnonymousDelegateRemover(this.sink.host, this.PdbReader);
newTypes = remover.RemoveAnonymousDelegates(methodBody.MethodDefinition, block);
}
- this.Visit(methodBody);
+ this.Traverse(methodBody);
return newTypes;
}
#endregion
+ #region Helper Classes
+ class SourceContextEmitter : CodeVisitor {
+ StatementTraverser parent;
+ public SourceContextEmitter(StatementTraverser parent) {
+ this.parent = parent;
+ }
+
+ public override void Visit(IStatement statement) {
+ EmitSourceContext(statement);
+ if (this.parent.sink.Options.captureState) {
+ var tok = statement.Token();
+ var state = String.Format("s{0}", StatementTraverser.captureStateCounter++);
+ var attrib = new Bpl.QKeyValue(tok, "captureState ", new List<object> { state }, null);
+ this.parent.StmtBuilder.Add(
+ new Bpl.AssumeCmd(tok, Bpl.Expr.True, attrib)
+ );
+ }
+ }
+
+ private void EmitSourceContext(IStatement statement) {
+ if (statement is IEmptyStatement) return;
+ var tok = statement.Token();
+ string fileName = null;
+ int lineNumber = 0;
+ if (this.parent.PdbReader != null) {
+ var slocs = this.parent.PdbReader.GetClosestPrimarySourceLocationsFor(statement.Locations);
+ foreach (var sloc in slocs) {
+ fileName = sloc.Document.Location;
+ lineNumber = sloc.StartLine;
+ break;
+ }
+ if (fileName != null) {
+ var attrib = new Bpl.QKeyValue(tok, "sourceLine", new List<object> { Bpl.Expr.Literal((int)lineNumber) }, null);
+ attrib = new Bpl.QKeyValue(tok, "sourceFile", new List<object> { fileName }, attrib);
+ this.parent.StmtBuilder.Add(
+ new Bpl.AssertCmd(tok, Bpl.Expr.True, attrib)
+ );
+ }
+ }
+ }
+ }
+ #endregion
+
//public override void Visit(ISourceMethodBody methodBody) {
// var block = methodBody.Block as BlockStatement;
// // TODO: Error if cast fails?
@@ -103,50 +147,15 @@ namespace BytecodeTranslator
// base.Visit(methodBody);
//}
- public override void Visit(IBlockStatement block) {
+ public override void TraverseChildren(IBlockStatement block) {
foreach (var s in block.Statements) {
- this.Visit(s);
- }
- }
-
- public override void Visit(IStatement statement) {
- EmitSourceContext(statement);
- if (this.sink.Options.captureState) {
- var tok = statement.Token();
- var state = String.Format("s{0}", StatementTraverser.captureStateCounter++);
- var attrib = new Bpl.QKeyValue(tok, "captureState ", new List<object> { state }, null);
- StmtBuilder.Add(
- new Bpl.AssumeCmd(tok, Bpl.Expr.True, attrib)
- );
- }
- base.Visit(statement);
- }
-
- private void EmitSourceContext(IStatement statement) {
- if (statement is IEmptyStatement) return;
- var tok = statement.Token();
- string fileName = null;
- int lineNumber = 0;
- if (this.PdbReader != null) {
- var slocs = this.PdbReader.GetClosestPrimarySourceLocationsFor(statement.Locations);
- foreach (var sloc in slocs) {
- fileName = sloc.Document.Location;
- lineNumber = sloc.StartLine;
- break;
- }
- if (fileName != null) {
- var attrib = new Bpl.QKeyValue(tok, "sourceLine", new List<object> { Bpl.Expr.Literal((int)lineNumber) }, null);
- attrib = new Bpl.QKeyValue(tok, "sourceFile", new List<object> { fileName }, attrib);
- StmtBuilder.Add(
- new Bpl.AssertCmd(tok, Bpl.Expr.True, attrib)
- );
- }
+ this.Traverse(s);
}
}
#region Basic Statements
- public override void Visit(IAssertStatement assertStatement) {
+ public override void TraverseChildren(IAssertStatement assertStatement) {
Bpl.Expr conditionExpr = ExpressionFor(assertStatement.Condition);
Bpl.Type conditionType = this.sink.CciTypeToBoogie(assertStatement.Condition.Type);
if (conditionType == this.sink.Heap.RefType) {
@@ -165,7 +174,7 @@ namespace BytecodeTranslator
}
}
- public override void Visit(IAssumeStatement assumeStatement) {
+ public override void TraverseChildren(IAssumeStatement assumeStatement) {
Bpl.Expr conditionExpr = ExpressionFor(assumeStatement.Condition);
Bpl.Type conditionType = this.sink.CciTypeToBoogie(assumeStatement.Condition.Type);
if (conditionType == this.sink.Heap.RefType) {
@@ -185,13 +194,13 @@ namespace BytecodeTranslator
/// </summary>
/// <remarks>(mschaef) Works, but still a stub</remarks>
/// <param name="conditionalStatement"></param>
- public override void Visit(IConditionalStatement conditionalStatement) {
+ public override void TraverseChildren(IConditionalStatement conditionalStatement) {
StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- condTraverser.Visit(conditionalStatement.Condition);
- thenTraverser.Visit(conditionalStatement.TrueBranch);
- elseTraverser.Visit(conditionalStatement.FalseBranch);
+ condTraverser.Traverse(conditionalStatement.Condition);
+ thenTraverser.Traverse(conditionalStatement.TrueBranch);
+ elseTraverser.Traverse(conditionalStatement.FalseBranch);
Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop();
Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type);
@@ -221,9 +230,9 @@ namespace BytecodeTranslator
/// </summary>
/// <param name="expressionStatement"></param>
/// <remarks> TODO: might be wrong for the general case</remarks>
- public override void Visit(IExpressionStatement expressionStatement) {
+ public override void TraverseChildren(IExpressionStatement expressionStatement) {
ExpressionTraverser etrav = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- etrav.Visit(expressionStatement.Expression);
+ etrav.Traverse(expressionStatement.Expression);
}
/// <summary>
@@ -231,18 +240,18 @@ namespace BytecodeTranslator
/// </summary>
/// <remarks>(mschaef) Not Implemented</remarks>
/// <param name="breakStatement"></param>
- public override void Visit(IBreakStatement breakStatement) {
+ public override void TraverseChildren(IBreakStatement breakStatement) {
throw new TranslationException("Break statements are not handled");
//StmtBuilder.Add(new Bpl.BreakCmd(breakStatement.Token(), "I dont know"));
}
- public override void Visit(IContinueStatement continueStatement) {
+ public override void TraverseChildren(IContinueStatement continueStatement) {
throw new TranslationException("Continue statements are not handled");
}
- public override void Visit(ISwitchStatement switchStatement) {
+ public override void TraverseChildren(ISwitchStatement switchStatement) {
var eTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- eTraverser.Visit(switchStatement.Expression);
+ eTraverser.Traverse(switchStatement.Expression);
var conditionExpr = eTraverser.TranslatedExpressions.Pop();
// Can't depend on default case existing or its index in the collection.
@@ -258,7 +267,7 @@ namespace BytecodeTranslator
Bpl.StmtList defaultStmts = null;
if (defaultCase != null) {
var defaultBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
- defaultBodyTraverser.Visit(defaultCase.Body);
+ defaultBodyTraverser.Traverse(defaultCase.Body);
defaultStmts = defaultBodyTraverser.StmtBuilder.Collect(defaultCase.Token());
}
@@ -269,12 +278,12 @@ namespace BytecodeTranslator
var switchCase = switchCases[i];
var scTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- scTraverser.Visit(switchCase.Expression);
+ scTraverser.Traverse(switchCase.Expression);
var scConditionExpr = scTraverser.TranslatedExpressions.Pop();
var condition = Bpl.Expr.Eq(conditionExpr, scConditionExpr);
var scBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
- scBodyTraverser.Visit(switchCase.Body);
+ scBodyTraverser.Traverse(switchCase.Body);
ifCmd = new Bpl.IfCmd(switchCase.Token(),
condition,
@@ -294,7 +303,7 @@ namespace BytecodeTranslator
/// the default ctor.
/// Otherwise ignore it.
/// </summary>
- public override void Visit(ILocalDeclarationStatement localDeclarationStatement) {
+ public override void TraverseChildren(ILocalDeclarationStatement localDeclarationStatement) {
var initVal = localDeclarationStatement.InitialValue;
var typ = localDeclarationStatement.LocalVariable.Type;
var isStruct = TranslationHelper.IsStruct(typ);
@@ -329,7 +338,7 @@ namespace BytecodeTranslator
return;
}
- public override void Visit(IPushStatement pushStatement) {
+ public override void TraverseChildren(IPushStatement pushStatement) {
var tok = pushStatement.Token();
var val = pushStatement.ValueToPush;
var dup = val as IDupValue;
@@ -348,12 +357,12 @@ namespace BytecodeTranslator
/// </summary>
/// <remarks>(mschaef) not implemented</remarks>
/// <param name="returnStatement"></param>
- public override void Visit(IReturnStatement returnStatement) {
+ public override void TraverseChildren(IReturnStatement returnStatement) {
Bpl.IToken tok = returnStatement.Token();
if (returnStatement.Expression != null) {
ExpressionTraverser etrav = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- etrav.Visit(returnStatement.Expression);
+ etrav.Traverse(returnStatement.Expression);
if (this.sink.ReturnVariable == null || etrav.TranslatedExpressions.Count < 1) {
throw new TranslationException(String.Format("{0} returns a value that is not supported by the function", returnStatement.ToString()));
@@ -380,7 +389,7 @@ namespace BytecodeTranslator
#region Goto and Labels
- public override void Visit(IGotoStatement gotoStatement) {
+ public override void TraverseChildren(IGotoStatement gotoStatement) {
IName target = gotoStatement.TargetStatement.Label;
ITryCatchFinallyStatement targetStatement = this.sink.MostNestedTryStatement(target);
int count = 0;
@@ -406,24 +415,24 @@ namespace BytecodeTranslator
/// </summary>
/// <remarks> (mschaef) not sure if there is more work to do</remarks>
/// <param name="labeledStatement"></param>
- public override void Visit(ILabeledStatement labeledStatement) {
+ public override void TraverseChildren(ILabeledStatement labeledStatement) {
StmtBuilder.AddLabelCmd(labeledStatement.Label.Value);
- base.Visit(labeledStatement.Statement);
+ base.Traverse(labeledStatement.Statement);
}
#endregion
#region Looping Statements
- public override void Visit(IWhileDoStatement whileDoStatement) {
+ public override void TraverseChildren(IWhileDoStatement whileDoStatement) {
throw new TranslationException("WhileDo statements are not handled");
}
- public override void Visit(IForEachStatement forEachStatement) {
+ public override void TraverseChildren(IForEachStatement forEachStatement) {
throw new TranslationException("ForEach statements are not handled");
}
- public override void Visit(IForStatement forStatement) {
+ public override void TraverseChildren(IForStatement forStatement) {
throw new TranslationException("For statements are not handled");
}
@@ -489,9 +498,9 @@ namespace BytecodeTranslator
StmtBuilder.Add(ifCmd);
}
- public override void Visit(ITryCatchFinallyStatement tryCatchFinallyStatement) {
+ public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement) {
this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InTry));
- this.Visit(tryCatchFinallyStatement.TryBody);
+ this.Traverse(tryCatchFinallyStatement.TryBody);
StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new Bpl.StringSeq(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement))));
this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);
@@ -503,13 +512,13 @@ namespace BytecodeTranslator
List<Bpl.Expr> typeReferences = new List<Bpl.Expr>();
this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InCatch));
foreach (ICatchClause catchClause in tryCatchFinallyStatement.CatchClauses) {
- typeReferences.Insert(0, this.sink.FindOrCreateType(catchClause.ExceptionType));
+ typeReferences.Insert(0, this.sink.FindOrCreateTypeReference(catchClause.ExceptionType));
StatementTraverser catchTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
if (catchClause.ExceptionContainer != Dummy.LocalVariable) {
Bpl.Variable catchClauseVariable = this.sink.FindOrCreateLocalVariable(catchClause.ExceptionContainer);
catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(catchClauseVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
}
- catchTraverser.Visit(catchClause.Body);
+ catchTraverser.Traverse(catchClause.Body);
catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
catchTraverser.StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new Bpl.StringSeq(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement))));
catchStatements.Insert(0, catchTraverser.StmtBuilder.Collect(catchClause.Token()));
@@ -532,7 +541,7 @@ namespace BytecodeTranslator
Bpl.Variable savedLabelVariable = this.sink.CreateFreshLocal(Bpl.Type.Int);
StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)));
StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedLabelVariable), Bpl.Expr.Ident(this.sink.LabelVariable)));
- Visit(tryCatchFinallyStatement.FinallyBody);
+ this.Traverse(tryCatchFinallyStatement.FinallyBody);
StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(savedExcVariable)));
StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Ident(savedLabelVariable)));
this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);
@@ -543,14 +552,14 @@ namespace BytecodeTranslator
RaiseException(raiseExpr);
}
- public override void Visit(IThrowStatement throwStatement) {
+ public override void TraverseChildren(IThrowStatement throwStatement) {
ExpressionTraverser exceptionTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
- exceptionTraverser.Visit(throwStatement.Exception);
+ exceptionTraverser.Traverse(throwStatement.Exception);
StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), exceptionTraverser.TranslatedExpressions.Pop()));
RaiseException();
}
- public override void Visit(IRethrowStatement rethrowStatement) {
+ public override void TraverseChildren(IRethrowStatement rethrowStatement) {
StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
RaiseException();
}
diff --git a/BCT/BytecodeTranslator/TranslationHelper.cs b/BCT/BytecodeTranslator/TranslationHelper.cs
index 883d0eaf..a744f405 100644
--- a/BCT/BytecodeTranslator/TranslationHelper.cs
+++ b/BCT/BytecodeTranslator/TranslationHelper.cs
@@ -15,7 +15,7 @@ using Microsoft.Cci.Contracts;
using Microsoft.Cci.ILToCodeModel;
using Bpl = Microsoft.Boogie;
-
+using System.Text.RegularExpressions;
namespace BytecodeTranslator {
@@ -131,44 +131,25 @@ namespace BytecodeTranslator {
}
public static string TurnStringIntoValidIdentifier(string s) {
+
+ // Do this specially just to make the resulting string a little bit more readable.
+ // REVIEW: Just let the main replacement take care of it?
s = s.Replace("[0:,0:]", "2DArray"); // TODO: Do this programmatically to handle arbitrary arity
s = s.Replace("[0:,0:,0:]", "3DArray");
s = s.Replace("[0:,0:,0:,0:]", "4DArray");
s = s.Replace("[0:,0:,0:,0:,0:]", "5DArray");
- s = s.Replace('!', '$');
- s = s.Replace('*', '$');
- s = s.Replace('+', '$');
- s = s.Replace('(', '$');
- s = s.Replace(')', '$');
- s = s.Replace(',', '$');
s = s.Replace("[]", "array");
- s = s.Replace('<', '$');
- s = s.Replace('>', '$');
- s = s.Replace(':', '$');
- s = s.Replace(' ', '$');
- s = s.Replace('{', '$');
- s = s.Replace('}', '$');
- s = s.Replace('-', '$');
- s = s.Replace(' ', '$');
- s = s.Replace('\t', '$');
- s = s.Replace('\r', '$');
- s = s.Replace('\n', '$');
- s = s.Replace('\b', '$');
- s = s.Replace('\x1B', '$');
- s = s.Replace('/', '$');
- s = s.Replace('\\', '$');
- s = s.Replace('=', '$');
- s = s.Replace('@', '$');
- s = s.Replace(';', '$');
- s = s.Replace('%', '$');
- s = s.Replace('&', '$');
- s = s.Replace('"', '$');
- s = s.Replace('[', '$');
- s = s.Replace(']', '$');
- s = s.Replace('|', '$');
- s = s.Replace('+', '$');
- s = s.Replace('±', '$');
- s = s.Replace('√', '$');
+
+ // The definition of a Boogie identifier is from BoogiePL.atg.
+ // Just negate that to get which characters should be replaced with a dollar sign.
+
+ // letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
+ // digit = "0123456789".
+ // special = "'~#$^_.?`".
+ // nondigit = letter + special.
+ // ident = [ '\\' ] nondigit {nondigit | digit}.
+
+ s = Regex.Replace(s, "[^A-Za-z0-9'~#$^_.?`]", "$");
s = GetRidOfSurrogateCharacters(s);
return s;
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs
index 60f39e03..1ceb7902 100644
--- a/BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs
+++ b/BCT/BytecodeTranslator/TranslationPlugins/Translators/BaseTranslator.cs
@@ -12,7 +12,7 @@ namespace BytecodeTranslator {
private Sink sink;
private IDictionary<IUnit, IContractProvider> contractProviders;
private IDictionary<IUnit, PdbReader> pdbReaders;
- private MetadataTraverser traverser;
+ private BCTMetadataTraverser traverser;
public BaseTranslator(TraverserFactory factory, Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
Factory = factory;
diff --git a/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs b/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs
index f2932ac0..ffd6fe52 100644
--- a/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs
+++ b/BCT/BytecodeTranslator/TranslationPlugins/Translators/PhoneFeedbackTranslator.cs
@@ -28,7 +28,9 @@ namespace BytecodeTranslator.TranslationPlugins.Translators {
}
public override void TranslateAssemblies(IEnumerable<Microsoft.Cci.IUnit> assemblies) {
- traverser.Visit(assemblies);
+ foreach (var a in assemblies) {
+ traverser.Traverse((IAssembly)a);
+ }
}
}
}
diff --git a/BCT/BytecodeTranslator/TraverserFactory.cs b/BCT/BytecodeTranslator/TraverserFactory.cs
index 472cbb0a..bbc2f7f7 100644
--- a/BCT/BytecodeTranslator/TraverserFactory.cs
+++ b/BCT/BytecodeTranslator/TraverserFactory.cs
@@ -25,11 +25,11 @@ namespace BytecodeTranslator {
public abstract Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> reader);
- public virtual MetadataTraverser MakeMetadataTraverser(Sink sink,
+ public virtual BCTMetadataTraverser MakeMetadataTraverser(Sink sink,
IDictionary<IUnit, IContractProvider> contractProviders, // TODO: remove this parameter?
IDictionary<IUnit, PdbReader> sourceLocationProviders)
{
- return new MetadataTraverser(sink, sourceLocationProviders, this);
+ return new BCTMetadataTraverser(sink, sourceLocationProviders, this);
}
public virtual StatementTraverser MakeStatementTraverser(Sink sink, PdbReader/*?*/ pdbReader, bool contractContext) {
return new StatementTraverser(sink, pdbReader, contractContext, this);
diff --git a/BCT/BytecodeTranslator/WholeProgram.cs b/BCT/BytecodeTranslator/WholeProgram.cs
index 83541f7d..d90176a8 100644
--- a/BCT/BytecodeTranslator/WholeProgram.cs
+++ b/BCT/BytecodeTranslator/WholeProgram.cs
@@ -29,13 +29,13 @@ namespace BytecodeTranslator {
/// </summary>
readonly public Dictionary<ITypeReference, List<ITypeReference>> subTypes = new Dictionary<ITypeReference, List<ITypeReference>>();
- public override MetadataTraverser MakeMetadataTraverser(Sink sink,
+ public override BCTMetadataTraverser MakeMetadataTraverser(Sink sink,
IDictionary<IUnit, IContractProvider> contractProviders, // TODO: remove this parameter?
IDictionary<IUnit, PdbReader> pdbReaders) {
return new WholeProgramMetadataSemantics(this, sink, pdbReaders, this);
}
- public class WholeProgramMetadataSemantics : MetadataTraverser {
+ public class WholeProgramMetadataSemantics : BCTMetadataTraverser {
readonly WholeProgram parent;
readonly Sink sink;
@@ -53,13 +53,13 @@ namespace BytecodeTranslator {
var typeRecorder = new RecordSubtypes(this.parent.subTypes);
foreach (var a in assemblies) {
this.codeUnderAnalysis.Add(a, true);
- typeRecorder.Visit(a);
+ typeRecorder.Traverse((IAssembly)a);
}
#endregion
base.TranslateAssemblies(assemblies);
}
- class RecordSubtypes : BaseMetadataTraverser {
+ class RecordSubtypes : MetadataTraverser {
Dictionary<ITypeReference, List<ITypeReference>> subTypes;
@@ -67,14 +67,14 @@ namespace BytecodeTranslator {
this.subTypes = subTypes;
}
- public override void Visit(ITypeDefinition typeDefinition) {
+ public override void TraverseChildren(ITypeDefinition typeDefinition) {
foreach (var baseClass in typeDefinition.BaseClasses) {
if (!this.subTypes.ContainsKey(baseClass)) {
this.subTypes[baseClass] = new List<ITypeReference>();
}
this.subTypes[baseClass].Add(typeDefinition);
}
- base.Visit(typeDefinition);
+ base.TraverseChildren(typeDefinition);
}
}
@@ -100,24 +100,24 @@ namespace BytecodeTranslator {
this.subTypes = parent.subTypes;
}
- public override void Visit(IMethodCall methodCall) {
+ public override void TraverseChildren(IMethodCall methodCall) {
var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod;
bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");
if (isEventAdd || isEventRemove) {
- base.Visit(methodCall);
+ base.TraverseChildren(methodCall);
return;
}
if (!methodCall.IsVirtualCall) {
- base.Visit(methodCall);
+ base.TraverseChildren(methodCall);
return;
}
var containingType = methodCall.MethodToCall.ContainingType;
List<ITypeReference> subTypesOfContainingType;
if (!this.subTypes.TryGetValue(containingType, out subTypesOfContainingType)) {
- base.Visit(methodCall);
+ base.TraverseChildren(methodCall);
return;
}
Contract.Assert(0 < subTypesOfContainingType.Count);
@@ -125,7 +125,7 @@ namespace BytecodeTranslator {
Contract.Assert(!resolvedMethod.IsConstructor);
var overrides = FindOverrides(containingType, resolvedMethod);
if (0 == overrides.Count) {
- base.Visit(methodCall);
+ base.TraverseChildren(methodCall);
return;
}
@@ -163,6 +163,11 @@ namespace BytecodeTranslator {
foreach (var typeMethodPair in overrides) {
var t = typeMethodPair.Item1;
var m = typeMethodPair.Item2;
+ var typeForT = this.sink.FindOrCreateTypeReference(t);
+ if (typeForT == null) {
+ // BUGBUG!! This just silently skips the branch that would dispatch to t's implementation of the method!
+ continue;
+ }
var thenBranch = new Bpl.StmtListBuilder();
methodname = TranslationHelper.CreateUniqueMethodName(m); // REVIEW: Shouldn't this be call to FindOrCreateProcedure?
if (attrib != null)
@@ -173,7 +178,7 @@ namespace BytecodeTranslator {
ifcmd = new Bpl.IfCmd(token,
Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
this.sink.Heap.DynamicType(inexpr[0]),
- this.sink.FindOrCreateType(t)
+ typeForT
),
thenBranch.Collect(token),
null,
@@ -183,6 +188,14 @@ namespace BytecodeTranslator {
elseBranch.Add(ifcmd);
}
+ if (ifcmd == null) {
+ // BUGBUG: then no override made it into the if-statement.
+ // currently that happens when all types are generic.
+ // Should be able to remove this when that is fixed.
+ base.Traverse(methodCall);
+ return;
+ }
+
this.StmtTraverser.StmtBuilder.Add(ifcmd);
return;
diff --git a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt b/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
index b03c319f..155db7c9 100644
--- a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
+++ b/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
@@ -344,7 +344,7 @@ type Ref;
const unique null: Ref;
-type Type;
+type {:datatype} Type;
type Real;
@@ -429,13 +429,13 @@ function $DelegateTypeParameters(Delegate) : Type;
var {:thread_local} $Exception: Ref;
-const unique RegressionTestInput.RealNumbers$type: Type;
+function {:constructor} T$RegressionTestInput.RealNumbers() : Type;
-const {:extern} unique System.Object$type: Type;
+function {:extern} T$System.Object() : Type;
-axiom $Subtype(RegressionTestInput.RealNumbers$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.RealNumbers(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.RealNumbers$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.RealNumbers(), T$System.Object());
procedure RegressionTestInput.RealNumbers.WriteDouble$System.Double($this: Ref, d$in: Real);
@@ -576,11 +576,11 @@ implementation T$RegressionTestInput.RealNumbers.#cctor()
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap$type: Type;
+function {:constructor} T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap() : Type;
-axiom $Subtype(RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), T$System.Object());
const unique F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: Field;
@@ -635,11 +635,11 @@ implementation T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor(
-const unique RegressionTestInput.CreateStruct$type: Type;
+function {:constructor} T$RegressionTestInput.CreateStruct() : Type;
-axiom $Subtype(RegressionTestInput.CreateStruct$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.CreateStruct(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.CreateStruct$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.CreateStruct(), T$System.Object());
procedure RegressionTestInput.CreateStruct.Create($this: Ref) returns ($result: Ref);
@@ -649,17 +649,17 @@ procedure RegressionTestInput.S.#default_ctor(this: Ref);
-const unique RegressionTestInput.S$type: Type;
+function {:constructor} T$RegressionTestInput.S() : Type;
-const {:extern} unique System.ValueType$type: Type;
+function {:extern} T$System.ValueType() : Type;
-axiom $Subtype(System.ValueType$type, System.Object$type);
+axiom $Subtype(T$System.ValueType(), T$System.Object());
-axiom $DisjointSubtree(System.ValueType$type, System.Object$type);
+axiom $DisjointSubtree(T$System.ValueType(), T$System.Object());
-axiom $Subtype(RegressionTestInput.S$type, System.ValueType$type);
+axiom $Subtype(T$RegressionTestInput.S(), T$System.ValueType());
-axiom $DisjointSubtree(RegressionTestInput.S$type, System.ValueType$type);
+axiom $DisjointSubtree(T$RegressionTestInput.S(), T$System.ValueType());
const unique F$RegressionTestInput.S.x: Field;
@@ -675,12 +675,12 @@ implementation RegressionTestInput.CreateStruct.Create($this: Ref) returns ($res
call $tmp0 := Alloc();
call RegressionTestInput.S.#default_ctor($tmp0);
- assume $DynamicType($tmp0) == RegressionTestInput.S$type;
+ assume $DynamicType($tmp0) == T$RegressionTestInput.S();
s := $tmp0;
assert {:sourceFile "C:\dev\BoogieCodePlex\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 141} true;
call $tmp1 := Alloc();
call RegressionTestInput.S.#default_ctor($tmp1);
- assume $DynamicType($tmp1) == RegressionTestInput.S$type;
+ assume $DynamicType($tmp1) == T$RegressionTestInput.S();
s := $tmp1;
assert {:sourceFile "C:\dev\BoogieCodePlex\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 142} true;
assert Box2Int(Read($Heap, s, F$RegressionTestInput.S.x)) == 0;
@@ -745,11 +745,11 @@ implementation T$RegressionTestInput.CreateStruct.#cctor()
-const unique RegressionTestInput.ClassWithArrayTypes$type: Type;
+function {:constructor} T$RegressionTestInput.ClassWithArrayTypes() : Type;
-axiom $Subtype(RegressionTestInput.ClassWithArrayTypes$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.ClassWithArrayTypes(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.ClassWithArrayTypes$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.ClassWithArrayTypes(), T$System.Object());
var F$RegressionTestInput.ClassWithArrayTypes.s: Ref;
@@ -920,11 +920,11 @@ implementation T$RegressionTestInput.ClassWithArrayTypes.#cctor()
-function RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type(arg0: Type) : Type;
+function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T: Type) : Type;
-function Child0(in: Type) : Type;
+axiom (forall T: Type :: { T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T) } $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), T$System.Object()));
-axiom (forall arg0: Type :: { RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type(arg0) } Child0(RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type(arg0)) == arg0);
+axiom (forall T: Type :: { T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T) } $DisjointSubtree(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), T$System.Object()));
const unique F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.x: Field;
@@ -959,11 +959,11 @@ implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1
-const unique RegressionTestInput.BitwiseOperations$type: Type;
+function {:constructor} T$RegressionTestInput.BitwiseOperations() : Type;
-axiom $Subtype(RegressionTestInput.BitwiseOperations$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.BitwiseOperations(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.BitwiseOperations$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.BitwiseOperations(), T$System.Object());
procedure RegressionTestInput.BitwiseOperations.BitwiseAnd$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
@@ -1073,21 +1073,21 @@ implementation T$RegressionTestInput.BitwiseOperations.#cctor()
-const unique RegressionTestInput.AsyncAttribute$type: Type;
+function {:constructor} T$RegressionTestInput.AsyncAttribute() : Type;
-const {:extern} unique System.Attribute$type: Type;
+function {:extern} T$System.Attribute() : Type;
-axiom $Subtype(System.Attribute$type, System.Object$type);
+axiom $Subtype(T$System.Attribute(), T$System.Object());
-axiom $DisjointSubtree(System.Attribute$type, System.Object$type);
+axiom $DisjointSubtree(T$System.Attribute(), T$System.Object());
-const {:extern} unique System.Runtime.InteropServices._Attribute$type: Type;
+function {:extern} T$System.Runtime.InteropServices._Attribute() : Type;
-axiom $Subtype(System.Attribute$type, System.Runtime.InteropServices._Attribute$type);
+axiom $Subtype(T$System.Attribute(), T$System.Runtime.InteropServices._Attribute());
-axiom $Subtype(RegressionTestInput.AsyncAttribute$type, System.Attribute$type);
+axiom $Subtype(T$RegressionTestInput.AsyncAttribute(), T$System.Attribute());
-axiom $DisjointSubtree(RegressionTestInput.AsyncAttribute$type, System.Attribute$type);
+axiom $DisjointSubtree(T$RegressionTestInput.AsyncAttribute(), T$System.Attribute());
procedure RegressionTestInput.AsyncAttribute.#ctor($this: Ref);
@@ -1123,11 +1123,11 @@ implementation T$RegressionTestInput.AsyncAttribute.#cctor()
-const unique RegressionTestInput.RefParameters$type: Type;
+function {:constructor} T$RegressionTestInput.RefParameters() : Type;
-axiom $Subtype(RegressionTestInput.RefParameters$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.RefParameters(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.RefParameters$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.RefParameters(), T$System.Object());
procedure RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int);
@@ -1177,11 +1177,11 @@ implementation T$RegressionTestInput.RefParameters.#cctor()
-const unique RegressionTestInput.NestedGeneric$type: Type;
+function {:constructor} T$RegressionTestInput.NestedGeneric() : Type;
-axiom $Subtype(RegressionTestInput.NestedGeneric$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.NestedGeneric(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.NestedGeneric$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.NestedGeneric(), T$System.Object());
procedure RegressionTestInput.NestedGeneric.#ctor($this: Ref);
@@ -1203,11 +1203,11 @@ implementation RegressionTestInput.NestedGeneric.#ctor($this: Ref)
-const unique RegressionTestInput.NestedGeneric.C$type: Type;
+function {:constructor} T$RegressionTestInput.NestedGeneric.C() : Type;
-axiom $Subtype(RegressionTestInput.NestedGeneric.C$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.NestedGeneric.C(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.NestedGeneric.C$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.NestedGeneric.C(), T$System.Object());
procedure RegressionTestInput.NestedGeneric.C.#ctor($this: Ref);
@@ -1229,9 +1229,11 @@ implementation RegressionTestInput.NestedGeneric.C.#ctor($this: Ref)
-function RegressionTestInput.NestedGeneric.C.G$type(arg0: Type) : Type;
+function {:constructor} T$RegressionTestInput.NestedGeneric.C.G`1(T: Type) : Type;
-axiom (forall arg0: Type :: { RegressionTestInput.NestedGeneric.C.G$type(arg0) } Child0(RegressionTestInput.NestedGeneric.C.G$type(arg0)) == arg0);
+axiom (forall T: Type :: { T$RegressionTestInput.NestedGeneric.C.G`1(T) } $Subtype(T$RegressionTestInput.NestedGeneric.C.G`1(T), T$System.Object()));
+
+axiom (forall T: Type :: { T$RegressionTestInput.NestedGeneric.C.G`1(T) } $DisjointSubtree(T$RegressionTestInput.NestedGeneric.C.G`1(T), T$System.Object()));
procedure RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this: Ref, x$in: int);
@@ -1273,7 +1275,7 @@ implementation RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this:
}
else
{
- call $tmp2 := System.Activator.CreateInstance``1(Child0($DynamicType($this)));
+ call $tmp2 := System.Activator.CreateInstance``1(T);
$tmp1 := Box2Box($tmp2);
if ($Exception != null)
{
@@ -1340,11 +1342,11 @@ implementation {:inline 1} RegressionTestInput.S.#copy_ctor(this: Ref, other: Re
-const unique RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type: Type;
+function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric() : Type;
-axiom $Subtype(RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), T$System.Object());
const unique F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.x: Field;
@@ -1379,11 +1381,11 @@ implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#
-const unique RegressionTestInput.Class0$type: Type;
+function {:constructor} T$RegressionTestInput.Class0() : Type;
-axiom $Subtype(RegressionTestInput.Class0$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.Class0(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.Class0$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.Class0(), T$System.Object());
var F$RegressionTestInput.Class0.StaticInt: int;
@@ -1652,11 +1654,11 @@ implementation T$RegressionTestInput.Class0.#cctor()
-const unique RegressionTestInput.ClassWithBoolTypes$type: Type;
+function {:constructor} T$RegressionTestInput.ClassWithBoolTypes() : Type;
-axiom $Subtype(RegressionTestInput.ClassWithBoolTypes$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.ClassWithBoolTypes(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.ClassWithBoolTypes$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.ClassWithBoolTypes(), T$System.Object());
var F$RegressionTestInput.ClassWithBoolTypes.staticB: bool;
diff --git a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt b/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
index e52668d3..1a2ff101 100644
--- a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
+++ b/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
@@ -330,7 +330,7 @@ type Ref;
const unique null: Ref;
-type Type;
+type {:datatype} Type;
type Real;
@@ -415,13 +415,13 @@ function $DelegateTypeParameters(Delegate) : Type;
var {:thread_local} $Exception: Ref;
-const unique RegressionTestInput.RealNumbers$type: Type;
+function {:constructor} T$RegressionTestInput.RealNumbers() : Type;
-const {:extern} unique System.Object$type: Type;
+function {:extern} T$System.Object() : Type;
-axiom $Subtype(RegressionTestInput.RealNumbers$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.RealNumbers(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.RealNumbers$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.RealNumbers(), T$System.Object());
procedure RegressionTestInput.RealNumbers.WriteDouble$System.Double($this: Ref, d$in: Real);
@@ -562,11 +562,11 @@ implementation T$RegressionTestInput.RealNumbers.#cctor()
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap$type: Type;
+function {:constructor} T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap() : Type;
-axiom $Subtype(RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap(), T$System.Object());
var F$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: [Ref]int;
@@ -621,11 +621,11 @@ implementation T$RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor(
-const unique RegressionTestInput.CreateStruct$type: Type;
+function {:constructor} T$RegressionTestInput.CreateStruct() : Type;
-axiom $Subtype(RegressionTestInput.CreateStruct$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.CreateStruct(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.CreateStruct$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.CreateStruct(), T$System.Object());
procedure RegressionTestInput.CreateStruct.Create($this: Ref) returns ($result: Ref);
@@ -635,17 +635,17 @@ procedure RegressionTestInput.S.#default_ctor(this: Ref);
-const unique RegressionTestInput.S$type: Type;
+function {:constructor} T$RegressionTestInput.S() : Type;
-const {:extern} unique System.ValueType$type: Type;
+function {:extern} T$System.ValueType() : Type;
-axiom $Subtype(System.ValueType$type, System.Object$type);
+axiom $Subtype(T$System.ValueType(), T$System.Object());
-axiom $DisjointSubtree(System.ValueType$type, System.Object$type);
+axiom $DisjointSubtree(T$System.ValueType(), T$System.Object());
-axiom $Subtype(RegressionTestInput.S$type, System.ValueType$type);
+axiom $Subtype(T$RegressionTestInput.S(), T$System.ValueType());
-axiom $DisjointSubtree(RegressionTestInput.S$type, System.ValueType$type);
+axiom $DisjointSubtree(T$RegressionTestInput.S(), T$System.ValueType());
var F$RegressionTestInput.S.x: [Ref]int;
@@ -661,12 +661,12 @@ implementation RegressionTestInput.CreateStruct.Create($this: Ref) returns ($res
call $tmp0 := Alloc();
call RegressionTestInput.S.#default_ctor($tmp0);
- assume $DynamicType($tmp0) == RegressionTestInput.S$type;
+ assume $DynamicType($tmp0) == T$RegressionTestInput.S();
s := $tmp0;
assert {:sourceFile "C:\dev\BoogieCodePlex\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 141} true;
call $tmp1 := Alloc();
call RegressionTestInput.S.#default_ctor($tmp1);
- assume $DynamicType($tmp1) == RegressionTestInput.S$type;
+ assume $DynamicType($tmp1) == T$RegressionTestInput.S();
s := $tmp1;
assert {:sourceFile "C:\dev\BoogieCodePlex\BCT\RegressionTests\RegressionTestInput\Class1.cs"} {:sourceLine 142} true;
assert F$RegressionTestInput.S.x[s] == 0;
@@ -731,11 +731,11 @@ implementation T$RegressionTestInput.CreateStruct.#cctor()
-const unique RegressionTestInput.ClassWithArrayTypes$type: Type;
+function {:constructor} T$RegressionTestInput.ClassWithArrayTypes() : Type;
-axiom $Subtype(RegressionTestInput.ClassWithArrayTypes$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.ClassWithArrayTypes(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.ClassWithArrayTypes$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.ClassWithArrayTypes(), T$System.Object());
var F$RegressionTestInput.ClassWithArrayTypes.s: Ref;
@@ -906,11 +906,11 @@ implementation T$RegressionTestInput.ClassWithArrayTypes.#cctor()
-function RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type(arg0: Type) : Type;
+function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T: Type) : Type;
-function Child0(in: Type) : Type;
+axiom (forall T: Type :: { T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T) } $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), T$System.Object()));
-axiom (forall arg0: Type :: { RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type(arg0) } Child0(RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type(arg0)) == arg0);
+axiom (forall T: Type :: { T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T) } $DisjointSubtree(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1(T), T$System.Object()));
var F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1.x: [Ref]int;
@@ -945,11 +945,11 @@ implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric`1
-const unique RegressionTestInput.BitwiseOperations$type: Type;
+function {:constructor} T$RegressionTestInput.BitwiseOperations() : Type;
-axiom $Subtype(RegressionTestInput.BitwiseOperations$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.BitwiseOperations(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.BitwiseOperations$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.BitwiseOperations(), T$System.Object());
procedure RegressionTestInput.BitwiseOperations.BitwiseAnd$System.Int32$System.Int32($this: Ref, x$in: int, y$in: int) returns ($result: int);
@@ -1059,21 +1059,21 @@ implementation T$RegressionTestInput.BitwiseOperations.#cctor()
-const unique RegressionTestInput.AsyncAttribute$type: Type;
+function {:constructor} T$RegressionTestInput.AsyncAttribute() : Type;
-const {:extern} unique System.Attribute$type: Type;
+function {:extern} T$System.Attribute() : Type;
-axiom $Subtype(System.Attribute$type, System.Object$type);
+axiom $Subtype(T$System.Attribute(), T$System.Object());
-axiom $DisjointSubtree(System.Attribute$type, System.Object$type);
+axiom $DisjointSubtree(T$System.Attribute(), T$System.Object());
-const {:extern} unique System.Runtime.InteropServices._Attribute$type: Type;
+function {:extern} T$System.Runtime.InteropServices._Attribute() : Type;
-axiom $Subtype(System.Attribute$type, System.Runtime.InteropServices._Attribute$type);
+axiom $Subtype(T$System.Attribute(), T$System.Runtime.InteropServices._Attribute());
-axiom $Subtype(RegressionTestInput.AsyncAttribute$type, System.Attribute$type);
+axiom $Subtype(T$RegressionTestInput.AsyncAttribute(), T$System.Attribute());
-axiom $DisjointSubtree(RegressionTestInput.AsyncAttribute$type, System.Attribute$type);
+axiom $DisjointSubtree(T$RegressionTestInput.AsyncAttribute(), T$System.Attribute());
procedure RegressionTestInput.AsyncAttribute.#ctor($this: Ref);
@@ -1109,11 +1109,11 @@ implementation T$RegressionTestInput.AsyncAttribute.#cctor()
-const unique RegressionTestInput.RefParameters$type: Type;
+function {:constructor} T$RegressionTestInput.RefParameters() : Type;
-axiom $Subtype(RegressionTestInput.RefParameters$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.RefParameters(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.RefParameters$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.RefParameters(), T$System.Object());
procedure RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int);
@@ -1163,11 +1163,11 @@ implementation T$RegressionTestInput.RefParameters.#cctor()
-const unique RegressionTestInput.NestedGeneric$type: Type;
+function {:constructor} T$RegressionTestInput.NestedGeneric() : Type;
-axiom $Subtype(RegressionTestInput.NestedGeneric$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.NestedGeneric(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.NestedGeneric$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.NestedGeneric(), T$System.Object());
procedure RegressionTestInput.NestedGeneric.#ctor($this: Ref);
@@ -1189,11 +1189,11 @@ implementation RegressionTestInput.NestedGeneric.#ctor($this: Ref)
-const unique RegressionTestInput.NestedGeneric.C$type: Type;
+function {:constructor} T$RegressionTestInput.NestedGeneric.C() : Type;
-axiom $Subtype(RegressionTestInput.NestedGeneric.C$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.NestedGeneric.C(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.NestedGeneric.C$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.NestedGeneric.C(), T$System.Object());
procedure RegressionTestInput.NestedGeneric.C.#ctor($this: Ref);
@@ -1215,9 +1215,11 @@ implementation RegressionTestInput.NestedGeneric.C.#ctor($this: Ref)
-function RegressionTestInput.NestedGeneric.C.G$type(arg0: Type) : Type;
+function {:constructor} T$RegressionTestInput.NestedGeneric.C.G`1(T: Type) : Type;
-axiom (forall arg0: Type :: { RegressionTestInput.NestedGeneric.C.G$type(arg0) } Child0(RegressionTestInput.NestedGeneric.C.G$type(arg0)) == arg0);
+axiom (forall T: Type :: { T$RegressionTestInput.NestedGeneric.C.G`1(T) } $Subtype(T$RegressionTestInput.NestedGeneric.C.G`1(T), T$System.Object()));
+
+axiom (forall T: Type :: { T$RegressionTestInput.NestedGeneric.C.G`1(T) } $DisjointSubtree(T$RegressionTestInput.NestedGeneric.C.G`1(T), T$System.Object()));
procedure RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this: Ref, x$in: int);
@@ -1259,7 +1261,7 @@ implementation RegressionTestInput.NestedGeneric.C.G`1.#ctor$System.Int32($this:
}
else
{
- call $tmp2 := System.Activator.CreateInstance``1(Child0($DynamicType($this)));
+ call $tmp2 := System.Activator.CreateInstance``1(T);
$tmp1 := Box2Box($tmp2);
if ($Exception != null)
{
@@ -1326,11 +1328,11 @@ implementation {:inline 1} RegressionTestInput.S.#copy_ctor(this: Ref, other: Re
-const unique RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type: Type;
+function {:constructor} T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric() : Type;
-axiom $Subtype(RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric(), T$System.Object());
var F$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.x: [Ref]int;
@@ -1365,11 +1367,11 @@ implementation T$RegressionTestInput.TestForClassesDifferingOnlyInBeingGeneric.#
-const unique RegressionTestInput.Class0$type: Type;
+function {:constructor} T$RegressionTestInput.Class0() : Type;
-axiom $Subtype(RegressionTestInput.Class0$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.Class0(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.Class0$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.Class0(), T$System.Object());
var F$RegressionTestInput.Class0.StaticInt: int;
@@ -1638,11 +1640,11 @@ implementation T$RegressionTestInput.Class0.#cctor()
-const unique RegressionTestInput.ClassWithBoolTypes$type: Type;
+function {:constructor} T$RegressionTestInput.ClassWithBoolTypes() : Type;
-axiom $Subtype(RegressionTestInput.ClassWithBoolTypes$type, System.Object$type);
+axiom $Subtype(T$RegressionTestInput.ClassWithBoolTypes(), T$System.Object());
-axiom $DisjointSubtree(RegressionTestInput.ClassWithBoolTypes$type, System.Object$type);
+axiom $DisjointSubtree(T$RegressionTestInput.ClassWithBoolTypes(), T$System.Object());
var F$RegressionTestInput.ClassWithBoolTypes.staticB: bool;
diff --git a/Binaries/DafnyPrelude.bpl b/Binaries/DafnyPrelude.bpl
index 32430fd3..1fe21204 100644
--- a/Binaries/DafnyPrelude.bpl
+++ b/Binaries/DafnyPrelude.bpl
@@ -489,13 +489,6 @@ axiom (forall r: ref, h: HeapType ::
function array.Length(a: ref): int;
axiom (forall o: ref :: 0 <= array.Length(o));
-procedure UpdateArrayRange(arr: ref, low: int, high: int, rhs: BoxType);
- modifies $Heap;
- ensures $HeapSucc(old($Heap), $Heap);
- ensures (forall i: int :: { read($Heap, arr, IndexField(i)) } low <= i && i < high ==> read($Heap, arr, IndexField(i)) == rhs);
- ensures (forall<alpha> o: ref, f: Field alpha :: { read($Heap, o, f) } read($Heap, o, f) == read(old($Heap), o, f) ||
- (o == arr && FDim(f) == 1 && low <= IndexField_Inverse(f) && IndexField_Inverse(f) < high));
-
// ---------------------------------------------------------------
// -- The heap ---------------------------------------------------
// ---------------------------------------------------------------
diff --git a/Binaries/DafnyRuntime.cs b/Binaries/DafnyRuntime.cs
index 82de380d..e22d52ad 100644
--- a/Binaries/DafnyRuntime.cs
+++ b/Binaries/DafnyRuntime.cs
@@ -298,6 +298,12 @@ namespace Dafny
return elmts;
}
}
+ public IEnumerable<T> UniqueElements {
+ get {
+ var st = Set<T>.FromElements(elmts);
+ return st.Elements;
+ }
+ }
public T Select(BigInteger index) {
return elmts[(int)index];
}
diff --git a/Chalice/readme.txt b/Chalice/readme.txt
index 37998339..f282da3c 100644
--- a/Chalice/readme.txt
+++ b/Chalice/readme.txt
@@ -4,6 +4,11 @@ Chalice - Verification of Concurrent Software
Compiling Chalice: sbt compile
Running Chalice: chalice.bat <file.chalice> [-params]
+ By default, chalice looks for Boogie in C:\Boogie\Binaries. If your
+ Boogie executable is located elsewhere, you can edit chalice.bat
+ to indicate the appropriate location such as
+ REM Chalice command line options
+ set CHALICE_OPTS=/boogie:"C:\Boogie-CodePlex\Binaries\Boogie.exe"
Running the tests for Chalice: see tests/readme.txt
Chalice is built using Simple Build Tool (https://github.com/harrah/xsbt/wiki/Setup)
diff --git a/Source/AIFramework/CommonFunctionSymbols.cs b/Source/AIFramework/CommonFunctionSymbols.cs
index d8e4497f..6f7a9f93 100644
--- a/Source/AIFramework/CommonFunctionSymbols.cs
+++ b/Source/AIFramework/CommonFunctionSymbols.cs
@@ -5,1287 +5,1228 @@
//-----------------------------------------------------------------------------
namespace Microsoft.AbstractInterpretationFramework
{
- using System.Diagnostics.Contracts;
- using System.Collections;
+ using System.Diagnostics.Contracts;
+ using System.Collections;
using System.Collections.Generic;
- //using Microsoft.SpecSharp.Collections;
- using Microsoft.Basetypes;
+ //using Microsoft.SpecSharp.Collections;
+ using Microsoft.Basetypes;
+
+ /// <summary>
+ /// A basic class for function symbols.
+ /// </summary>
+ public class FunctionSymbol : IFunctionSymbol
+ {
+ private readonly string/*!*/ display;
+ private readonly AIType/*!*/ typ;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(display != null);
+ Contract.Invariant(typ != null);
+ }
- /// <summary>
- /// A basic class for function symbols.
- /// </summary>
- public class FunctionSymbol : IFunctionSymbol
- {
- private readonly string/*!*/ display;
- private readonly AIType/*!*/ typ;
- [ContractInvariantMethod]
-void ObjectInvariant()
-{
- Contract.Invariant(display != null);
- Contract.Invariant(typ != null);
-}
+ public FunctionSymbol(AIType/*!*/ typ)
+ : this("FunctionSymbol", typ) {
+ Contract.Requires(typ != null);
+ }
- public FunctionSymbol(AIType/*!*/ typ)
- : this("FunctionSymbol", typ)
- {
- Contract.Requires(typ != null);
- }
+ internal FunctionSymbol(string/*!*/ display, AIType/*!*/ typ) {
+ Contract.Requires(typ != null);
+ Contract.Requires(display != null);
+ this.display = display;
+ this.typ = typ;
+ // base();
+ }
- internal FunctionSymbol(string/*!*/ display, AIType/*!*/ typ){
-Contract.Requires(typ != null);
-Contract.Requires(display != null);
- this.display = display;
- this.typ = typ;
- // base();
- }
+ public AIType/*!*/ AIType { get { Contract.Ensures(Contract.Result<AIType>() != null); return typ; } }
- public AIType/*!*/ AIType { get {Contract.Ensures(Contract.Result<AIType>() != null); return typ; } }
+ [NoDefaultContract]
+ [Pure]
+ public override string/*!*/ ToString() {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return display;
+ }
- [NoDefaultContract]
- [Pure]
- public override string/*!*/ ToString() {
-Contract.Ensures(Contract.Result<string>() != null);
- return display;
- }
+ }
+
+ /// <summary>
+ /// A class for integer constants.
+ /// </summary>
+ public class IntSymbol : FunctionSymbol
+ {
+ public readonly BigNum Value;
- }
-
/// <summary>
- /// A class for integer constants.
+ /// The intention is that this constructor be called only from the Int.Const method.
/// </summary>
- public class IntSymbol : FunctionSymbol
- {
- public readonly BigNum Value;
-
- /// <summary>
- /// The intention is that this constructor be called only from the Int.Const method.
- /// </summary>
- internal IntSymbol(BigNum x)
- : base(cce.NonNull(x.ToString()), Int.Type)
- {
- this.Value = x;
- }
+ internal IntSymbol(BigNum x)
+ : base(cce.NonNull(x.ToString()), Int.Type) {
+ this.Value = x;
+ }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)]
- public override bool Equals(object other)
- {
- IntSymbol isym = other as IntSymbol;
- return isym != null && isym.Value.Equals(this.Value);
- }
-
- [Pure]
- public override int GetHashCode()
- {
- return Value.GetHashCode();
- }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public override bool Equals(object other) {
+ IntSymbol isym = other as IntSymbol;
+ return isym != null && isym.Value.Equals(this.Value);
}
+ [Pure]
+ public override int GetHashCode() {
+ return Value.GetHashCode();
+ }
+ }
+
+ /// <summary>
+ /// A class for bitvector constants.
+ /// </summary>
+ public class BvSymbol : FunctionSymbol
+ {
+ public readonly BigNum Value;
+ public readonly int Bits;
+
/// <summary>
- /// A class for bitvector constants.
+ /// The intention is that this constructor be called only from the Int.Const method.
/// </summary>
- public class BvSymbol : FunctionSymbol
- {
- public readonly BigNum Value;
- public readonly int Bits;
-
- /// <summary>
- /// The intention is that this constructor be called only from the Int.Const method.
- /// </summary>
- internal BvSymbol(BigNum x, int y)
- : base(x + "bv" + y, Bv.Type)
- {
- this.Value = x;
- this.Bits = y;
- }
-
- [Pure][Reads(ReadsAttribute.Reads.Nothing)]
- public override bool Equals(object other)
- {
- BvSymbol isym = other as BvSymbol;
- return isym != null && isym.Value == this.Value && isym.Bits == this.Bits;
- }
-
- [Pure]
- public override int GetHashCode()
- {
- unchecked {
- return Value.GetHashCode() ^ Bits;
- }
- }
+ internal BvSymbol(BigNum x, int y)
+ : base(x + "bv" + y, Bv.Type) {
+ this.Value = x;
+ this.Bits = y;
}
- public class DoubleSymbol : FunctionSymbol
- {
- public readonly double Value;
-
- /// <summary>
- /// The intention is that this constructor be called only from the Double.Const method.
- /// </summary>
- internal DoubleSymbol(double x)
- : base(cce.NonNull(x.ToString()), Double.Type)
- {
- this.Value = x;
- }
-
- [Pure][Reads(ReadsAttribute.Reads.Nothing)]
- public override bool Equals(object other)
- {
- DoubleSymbol dsym = other as DoubleSymbol;
- return dsym != null && dsym.Value == this.Value;
- }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public override bool Equals(object other) {
+ BvSymbol isym = other as BvSymbol;
+ return isym != null && isym.Value == this.Value && isym.Bits == this.Bits;
+ }
- [Pure]
- public override int GetHashCode()
- {
- return Value.GetHashCode();
- }
+ [Pure]
+ public override int GetHashCode() {
+ unchecked {
+ return Value.GetHashCode() ^ Bits;
+ }
}
+ }
+
+ public class DoubleSymbol : FunctionSymbol
+ {
+ public readonly double Value;
/// <summary>
- /// Function symbol based on a string. Uses the string equality for determining equality
- /// of symbol.
+ /// The intention is that this constructor be called only from the Double.Const method.
/// </summary>
- public class NamedSymbol : FunctionSymbol
- {
- public string/*!*/ Value { [NoDefaultContract] get {Contract.Ensures(Contract.Result<string>() != null); return cce.NonNull(this.ToString()); } }
-
- public NamedSymbol(string/*!*/ symbol, AIType/*!*/ typ)
- : base(symbol, typ){
-Contract.Requires(typ != null);
-Contract.Requires(symbol != null);
- }
+ internal DoubleSymbol(double x)
+ : base(cce.NonNull(x.ToString()), Double.Type) {
+ this.Value = x;
+ }
- [NoDefaultContract]
- [Pure][Reads(ReadsAttribute.Reads.Nothing)]
- public override bool Equals(object other)
- {
- NamedSymbol nsym = other as NamedSymbol;
- return nsym != null && this.Value.Equals(nsym.Value);
- }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public override bool Equals(object other) {
+ DoubleSymbol dsym = other as DoubleSymbol;
+ return dsym != null && dsym.Value == this.Value;
+ }
- [NoDefaultContract]
- [Pure]
- public override int GetHashCode()
- {
- return Value.GetHashCode();
- }
+ [Pure]
+ public override int GetHashCode() {
+ return Value.GetHashCode();
}
+ }
- //
- // In the following, the classes like Value and Prop serve two
- // roles. The primary role is to be the base types for AIType.
- // The only objects of these classes are the representative
- // objects that denote an AIType, which are given by the
- // "Type" property. Subtypes in the AIType language are
- // encoded by subclassing. This yields some "higher-orderness"
- // for checking subtyping in the AIType language, by using
- // the Spec#/C# subclassing checks.
- //
- // The other role is simply as a module for collecting like function
- // symbols.
- //
+ /// <summary>
+ /// Function symbol based on a string. Uses the string equality for determining equality
+ /// of symbol.
+ /// </summary>
+ public class NamedSymbol : FunctionSymbol
+ {
+ public string/*!*/ Value { [NoDefaultContract] get { Contract.Ensures(Contract.Result<string>() != null); return cce.NonNull(this.ToString()); } }
+
+ public NamedSymbol(string/*!*/ symbol, AIType/*!*/ typ)
+ : base(symbol, typ) {
+ Contract.Requires(typ != null);
+ Contract.Requires(symbol != null);
+ }
- //-------------------------- Terms ----------------------------------
+ [NoDefaultContract]
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public override bool Equals(object other) {
+ NamedSymbol nsym = other as NamedSymbol;
+ return nsym != null && this.Value.Equals(nsym.Value);
+ }
- /// <summary>
- /// A class with the equality symbol and the ValueType.Type.
- /// </summary>
- public class Value : AIType
- {
- private static readonly AIType/*!*/ valtype = new Value();
- public static AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return valtype; } }
-
- private static readonly FunctionType[]/*!*/ funtypeCache = new FunctionType[5];
- public static FunctionType/*!*/ FunctionType(int inParameterCount) {
-Contract.Requires((0 <= inParameterCount));
-Contract.Ensures(Contract.Result<FunctionType>() != null);
- // Contract.Ensures(Contract.Result<>().Arity == inParameterCount);
- FunctionType result;
- if (inParameterCount < funtypeCache.Length) {
- result = funtypeCache[inParameterCount];
- if (result != null) {
- return result;
- }
- }
- AIType[] signature = new AIType[1 + inParameterCount];
- for (int i = 0; i < signature.Length; i++) {
- signature[i] = valtype;
- }
- result = new FunctionType(signature);
- if (inParameterCount < funtypeCache.Length) {
- funtypeCache[inParameterCount] = result;
- }
- return result;
+ [NoDefaultContract]
+ [Pure]
+ public override int GetHashCode() {
+ return Value.GetHashCode();
+ }
+ }
+
+ //
+ // In the following, the classes like Value and Prop serve two
+ // roles. The primary role is to be the base types for AIType.
+ // The only objects of these classes are the representative
+ // objects that denote an AIType, which are given by the
+ // "Type" property. Subtypes in the AIType language are
+ // encoded by subclassing. This yields some "higher-orderness"
+ // for checking subtyping in the AIType language, by using
+ // the Spec#/C# subclassing checks.
+ //
+ // The other role is simply as a module for collecting like function
+ // symbols.
+ //
+
+ //-------------------------- Terms ----------------------------------
+
+ /// <summary>
+ /// A class with the equality symbol and the ValueType.Type.
+ /// </summary>
+ public class Value : AIType
+ {
+ private static readonly AIType/*!*/ valtype = new Value();
+ public static AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return valtype; } }
+
+ private static readonly FunctionType[]/*!*/ funtypeCache = new FunctionType[5];
+ public static FunctionType/*!*/ FunctionType(int inParameterCount) {
+ Contract.Requires((0 <= inParameterCount));
+ Contract.Ensures(Contract.Result<FunctionType>() != null);
+ // Contract.Ensures(Contract.Result<>().Arity == inParameterCount);
+ FunctionType result;
+ if (inParameterCount < funtypeCache.Length) {
+ result = funtypeCache[inParameterCount];
+ if (result != null) {
+ return result;
}
+ }
+ AIType[] signature = new AIType[1 + inParameterCount];
+ for (int i = 0; i < signature.Length; i++) {
+ signature[i] = valtype;
+ }
+ result = new FunctionType(signature);
+ if (inParameterCount < funtypeCache.Length) {
+ funtypeCache[inParameterCount] = result;
+ }
+ return result;
+ }
- [Once] private static AIType/*!*/ binreltype;
+ [Once]
+ private static AIType/*!*/ binreltype;
- private static AIType/*!*/ BinrelType {
- get {Contract.Ensures(Contract.Result<AIType>() != null);
- if (binreltype == null) {
- binreltype = new FunctionType(Type, Type, Prop.Type);
- }
- return binreltype;
- }
+ private static AIType/*!*/ BinrelType {
+ get {
+ Contract.Ensures(Contract.Result<AIType>() != null);
+ if (binreltype == null) {
+ binreltype = new FunctionType(Type, Type, Prop.Type);
}
+ return binreltype;
+ }
+ }
- [Once] private static FunctionSymbol/*!*/ _eq;
- public static FunctionSymbol/*!*/ Eq {
- get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
- if (_eq == null) {
- _eq = new FunctionSymbol("=", BinrelType);
- }
- return _eq;
- }
+ [Once]
+ private static FunctionSymbol/*!*/ _eq;
+ public static FunctionSymbol/*!*/ Eq {
+ get {
+ Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
+ if (_eq == null) {
+ _eq = new FunctionSymbol("=", BinrelType);
}
- [Once] private static FunctionSymbol/*!*/ _neq;
- public static FunctionSymbol/*!*/ Neq {
- get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
- if (_neq == null) {
- _neq = new FunctionSymbol("!=", BinrelType);
- }
- return _neq;
- }
+ return _eq;
+ }
+ }
+ [Once]
+ private static FunctionSymbol/*!*/ _neq;
+ public static FunctionSymbol/*!*/ Neq {
+ get {
+ Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
+ if (_neq == null) {
+ _neq = new FunctionSymbol("!=", BinrelType);
}
- [Once] private static FunctionSymbol/*!*/ _subtype;
- public static FunctionSymbol/*!*/ Subtype {
- get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
- if (_subtype == null) {
- _subtype = new FunctionSymbol("<:", BinrelType);
- }
- return _subtype;
- }
+ return _neq;
+ }
+ }
+ [Once]
+ private static FunctionSymbol/*!*/ _subtype;
+ public static FunctionSymbol/*!*/ Subtype {
+ get {
+ Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
+ if (_subtype == null) {
+ _subtype = new FunctionSymbol("<:", BinrelType);
}
+ return _subtype;
+ }
+ }
- [Once] private static AIType/*!*/ typeof_type;
- private static AIType/*!*/ TypeofType {
- get {Contract.Ensures(Contract.Result<AIType>() != null);
- if (typeof_type == null) {
- typeof_type = new FunctionType(Ref.Type, Type);
- }
- return typeof_type;
- }
+ [Once]
+ private static AIType/*!*/ typeof_type;
+ private static AIType/*!*/ TypeofType {
+ get {
+ Contract.Ensures(Contract.Result<AIType>() != null);
+ if (typeof_type == null) {
+ typeof_type = new FunctionType(Ref.Type, Type);
}
- [Once] private static FunctionSymbol/*!*/ _typeof;
- public static FunctionSymbol/*!*/ Typeof {
- get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
- if (_typeof == null) {
- _typeof = new FunctionSymbol("typeof", TypeofType);
- }
- return _typeof;
- }
- }
-
- /// <summary>
- /// Value should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- protected Value() { }
-
- }
-
- public class Int : Value
- {
- private static readonly AIType/*!*/ inttype = new Int();
- public static new AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return inttype; } }
-
- private static readonly AIType/*!*/ unaryinttype = new FunctionType(Type, Type);
- private static readonly AIType/*!*/ bininttype = new FunctionType(Type, Type, Type);
- private static readonly AIType/*!*/ relationtype = new FunctionType(Type, Type, Prop.Type);
-
- private static readonly FunctionSymbol/*!*/ _negate = new FunctionSymbol("~", unaryinttype);
- private static readonly FunctionSymbol/*!*/ _add = new FunctionSymbol("+", bininttype);
- private static readonly FunctionSymbol/*!*/ _sub = new FunctionSymbol("-", bininttype);
- private static readonly FunctionSymbol/*!*/ _mul = new FunctionSymbol("*", bininttype);
- private static readonly FunctionSymbol/*!*/ _div = new FunctionSymbol("/", bininttype);
- private static readonly FunctionSymbol/*!*/ _mod = new FunctionSymbol("%", bininttype);
- private static readonly FunctionSymbol/*!*/ _atmost = new FunctionSymbol("<=", relationtype);
- private static readonly FunctionSymbol/*!*/ _less = new FunctionSymbol("<", relationtype);
- private static readonly FunctionSymbol/*!*/ _greater = new FunctionSymbol(">", relationtype);
- private static readonly FunctionSymbol/*!*/ _atleast = new FunctionSymbol(">=", relationtype);
-
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Negate { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _negate; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Add { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _add; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Sub { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _sub; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Mul { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _mul; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Div { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _div; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Mod { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _mod; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ AtMost { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atmost; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Less { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _less; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Greater { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _greater; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ AtLeast { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atleast; } }
-
- public static IntSymbol/*!*/ Const(BigNum x) {
-Contract.Ensures(Contract.Result<IntSymbol>() != null);
- // We could cache things here, but for now we don't.
- return new IntSymbol(x);
+ return typeof_type;
+ }
+ }
+ [Once]
+ private static FunctionSymbol/*!*/ _typeof;
+ public static FunctionSymbol/*!*/ Typeof {
+ get {
+ Contract.Ensures(Contract.Result<FunctionSymbol>() != null);
+ if (_typeof == null) {
+ _typeof = new FunctionSymbol("typeof", TypeofType);
}
+ return _typeof;
+ }
+ }
- /// <summary>
- /// Int should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- private Int() { }
- }
-
- public class Double : Value
- {
- private static readonly AIType/*!*/ doubletype = new Double();
- public static new AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return doubletype; } }
-
- public static DoubleSymbol/*!*/ Const(double x) {
-Contract.Ensures(Contract.Result<DoubleSymbol>() != null);
- // We could cache things here, but for now we don't.
- return new DoubleSymbol(x);
- }
+ /// <summary>
+ /// Value should not be instantiated from the outside, except perhaps in
+ /// subclasses.
+ /// </summary>
+ protected Value() { }
- /// <summary>
- /// Double should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- private Double() { }
- }
-
- public class Bv : Value
- {
- private static readonly AIType/*!*/ bvtype = new Bv();
- public static new AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return bvtype; } }
-
- private static readonly AIType/*!*/ unaryinttype = new FunctionType(Type, Type);
- private static readonly AIType/*!*/ bininttype = new FunctionType(Type, Type, Type);
- private static readonly AIType/*!*/ relationtype = new FunctionType(Type, Type, Prop.Type);
-
- private static readonly FunctionSymbol/*!*/ _negate = new FunctionSymbol("~", unaryinttype);
- private static readonly FunctionSymbol/*!*/ _add = new FunctionSymbol("+", bininttype);
- private static readonly FunctionSymbol/*!*/ _sub = new FunctionSymbol("-", bininttype);
- private static readonly FunctionSymbol/*!*/ _mul = new FunctionSymbol("*", bininttype);
- private static readonly FunctionSymbol/*!*/ _div = new FunctionSymbol("/", bininttype);
- private static readonly FunctionSymbol/*!*/ _mod = new FunctionSymbol("%", bininttype);
- private static readonly FunctionSymbol/*!*/ _concat = new FunctionSymbol("$concat", bininttype);
- private static readonly FunctionSymbol/*!*/ _extract = new FunctionSymbol("$extract", unaryinttype);
- private static readonly FunctionSymbol/*!*/ _atmost = new FunctionSymbol("<=", relationtype);
- private static readonly FunctionSymbol/*!*/ _less = new FunctionSymbol("<", relationtype);
- private static readonly FunctionSymbol/*!*/ _greater = new FunctionSymbol(">", relationtype);
- private static readonly FunctionSymbol/*!*/ _atleast = new FunctionSymbol(">=", relationtype);
-
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Negate { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _negate; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Add { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _add; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Sub { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _sub; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Mul { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _mul; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Div { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _div; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Mod { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null);return _mod; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ AtMost { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atmost; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Less { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _less; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Greater { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _greater; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ AtLeast { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atleast; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Extract { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _extract; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Concat { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _concat; } }
-
- public static BvSymbol/*!*/ Const(BigNum x, int y) {
-Contract.Ensures(Contract.Result<BvSymbol>() != null);
- // We could cache things here, but for now we don't.
- return new BvSymbol(x, y);
- }
+ }
- /// <summary>
- /// Int should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- private Bv() { }
+ public class Int : Value
+ {
+ private static readonly AIType/*!*/ inttype = new Int();
+ public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return inttype; } }
+
+ private static readonly AIType/*!*/ unaryinttype = new FunctionType(Type, Type);
+ private static readonly AIType/*!*/ bininttype = new FunctionType(Type, Type, Type);
+ private static readonly AIType/*!*/ relationtype = new FunctionType(Type, Type, Prop.Type);
+
+ private static readonly FunctionSymbol/*!*/ _negate = new FunctionSymbol("~", unaryinttype);
+ private static readonly FunctionSymbol/*!*/ _add = new FunctionSymbol("+", bininttype);
+ private static readonly FunctionSymbol/*!*/ _sub = new FunctionSymbol("-", bininttype);
+ private static readonly FunctionSymbol/*!*/ _mul = new FunctionSymbol("*", bininttype);
+ private static readonly FunctionSymbol/*!*/ _div = new FunctionSymbol("/", bininttype);
+ private static readonly FunctionSymbol/*!*/ _mod = new FunctionSymbol("%", bininttype);
+ private static readonly FunctionSymbol/*!*/ _atmost = new FunctionSymbol("<=", relationtype);
+ private static readonly FunctionSymbol/*!*/ _less = new FunctionSymbol("<", relationtype);
+ private static readonly FunctionSymbol/*!*/ _greater = new FunctionSymbol(">", relationtype);
+ private static readonly FunctionSymbol/*!*/ _atleast = new FunctionSymbol(">=", relationtype);
+
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Negate { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _negate; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Add { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _add; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Sub { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _sub; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Mul { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _mul; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Div { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _div; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Mod { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _mod; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ AtMost { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atmost; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Less { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _less; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Greater { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _greater; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ AtLeast { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atleast; } }
+
+ public static IntSymbol/*!*/ Const(BigNum x) {
+ Contract.Ensures(Contract.Result<IntSymbol>() != null);
+ // We could cache things here, but for now we don't.
+ return new IntSymbol(x);
}
- public class Ref : Value
- {
- private static readonly AIType/*!*/ reftype = new Ref();
- public static new AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return reftype; } }
-
- private static readonly FunctionSymbol/*!*/ _null = new FunctionSymbol("null", Type);
+ /// <summary>
+ /// Int should not be instantiated from the outside, except perhaps in
+ /// subclasses.
+ /// </summary>
+ private Int() { }
+ }
- public static FunctionSymbol/*!*/ Null { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _null; } }
+ public class Double : Value
+ {
+ private static readonly AIType/*!*/ doubletype = new Double();
+ public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return doubletype; } }
- /// <summary>
- /// Ref should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- private Ref() { }
+ public static DoubleSymbol/*!*/ Const(double x) {
+ Contract.Ensures(Contract.Result<DoubleSymbol>() != null);
+ // We could cache things here, but for now we don't.
+ return new DoubleSymbol(x);
}
- public class HeapStructure : Value
- {
- private static readonly AIType/*!*/ reftype = new HeapStructure();
- public static new AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return reftype; } }
-
-
+ /// <summary>
+ /// Double should not be instantiated from the outside, except perhaps in
+ /// subclasses.
+ /// </summary>
+ private Double() { }
+ }
- /// <summary>
- /// HeapStructure should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- private HeapStructure() { }
+ public class Bv : Value
+ {
+ private static readonly AIType/*!*/ bvtype = new Bv();
+ public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return bvtype; } }
+
+ private static readonly AIType/*!*/ unaryinttype = new FunctionType(Type, Type);
+ private static readonly AIType/*!*/ bininttype = new FunctionType(Type, Type, Type);
+ private static readonly AIType/*!*/ relationtype = new FunctionType(Type, Type, Prop.Type);
+
+ private static readonly FunctionSymbol/*!*/ _negate = new FunctionSymbol("~", unaryinttype);
+ private static readonly FunctionSymbol/*!*/ _add = new FunctionSymbol("+", bininttype);
+ private static readonly FunctionSymbol/*!*/ _sub = new FunctionSymbol("-", bininttype);
+ private static readonly FunctionSymbol/*!*/ _mul = new FunctionSymbol("*", bininttype);
+ private static readonly FunctionSymbol/*!*/ _div = new FunctionSymbol("/", bininttype);
+ private static readonly FunctionSymbol/*!*/ _mod = new FunctionSymbol("%", bininttype);
+ private static readonly FunctionSymbol/*!*/ _concat = new FunctionSymbol("$concat", bininttype);
+ private static readonly FunctionSymbol/*!*/ _extract = new FunctionSymbol("$extract", unaryinttype);
+ private static readonly FunctionSymbol/*!*/ _atmost = new FunctionSymbol("<=", relationtype);
+ private static readonly FunctionSymbol/*!*/ _less = new FunctionSymbol("<", relationtype);
+ private static readonly FunctionSymbol/*!*/ _greater = new FunctionSymbol(">", relationtype);
+ private static readonly FunctionSymbol/*!*/ _atleast = new FunctionSymbol(">=", relationtype);
+
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Negate { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _negate; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Add { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _add; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Sub { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _sub; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Mul { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _mul; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Div { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _div; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Mod { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _mod; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ AtMost { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atmost; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Less { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _less; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Greater { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _greater; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ AtLeast { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _atleast; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Extract { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _extract; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Concat { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _concat; } }
+
+ public static BvSymbol/*!*/ Const(BigNum x, int y) {
+ Contract.Ensures(Contract.Result<BvSymbol>() != null);
+ // We could cache things here, but for now we don't.
+ return new BvSymbol(x, y);
}
- public class FieldName : Value
- {
- private static readonly AIType/*!*/ fieldnametype = new FieldName();
- public static new AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return fieldnametype; } }
+ /// <summary>
+ /// Int should not be instantiated from the outside, except perhaps in
+ /// subclasses.
+ /// </summary>
+ private Bv() { }
+ }
- private static readonly FunctionSymbol/*!*/ _allocated = new FunctionSymbol("$allocated", FieldName.Type);
- public static FunctionSymbol/*!*/ Allocated { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _allocated; } }
+ public class Ref : Value
+ {
+ private static readonly AIType/*!*/ reftype = new Ref();
+ public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return reftype; } }
- /// <summary>
- /// Is this a boolean field that monotonically goes from false to true?
- /// </summary>
- public static bool IsBooleanMonotonicallyWeakening(IFunctionSymbol/*!*/ f){
-Contract.Requires(f != null);
- return f.Equals(Allocated);
- }
+ private static readonly FunctionSymbol/*!*/ _null = new FunctionSymbol("null", Type);
- /// <summary>
- /// FieldName should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- private FieldName() { }
- }
-
- public class Heap : Value
- {
- private static readonly AIType/*!*/ heaptype = new Heap();
- public static new AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return heaptype; } }
-
- // the types in the following, select1, select2, are hard-coded;
- // these types may not always be appropriate
- private static readonly FunctionSymbol/*!*/ _select1 = new FunctionSymbol("sel1",
- // Heap x FieldName -> Prop
- new FunctionType(Type, FieldName.Type, Prop.Type)
- );
- public static FunctionSymbol/*!*/ Select1 { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _select1; } }
-
- private static readonly FunctionSymbol/*!*/ _select2 = new FunctionSymbol("sel2",
- // Heap x Ref x FieldName -> Value
- new FunctionType(Type, Ref.Type, FieldName.Type, Value.Type)
- );
- public static FunctionSymbol/*!*/ Select2 { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _select2; } }
-
- // the types in the following, store1, store2, are hard-coded;
- // these types may not always be appropriate
- private static readonly FunctionSymbol/*!*/ _update1 = new FunctionSymbol("upd1",
- // Heap x FieldName x Value -> Heap
- new FunctionType(Type, FieldName.Type, Value.Type, Type)
- );
- public static FunctionSymbol/*!*/ Update1 { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _update1; } }
-
- private static readonly FunctionSymbol/*!*/ _update2 = new FunctionSymbol("upd2",
- // Heap x Ref x FieldName x Value -> Heap
- new FunctionType(Type, Ref.Type, FieldName.Type, Value.Type, Type)
- );
- public static FunctionSymbol/*!*/ Update2 { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _update2; } }
-
- private static readonly FunctionSymbol/*!*/ _unsupportedHeapOp =
- new FunctionSymbol("UnsupportedHeapOp",
- // Heap x FieldName -> Prop
- new FunctionType(Type, FieldName.Type, Prop.Type)
- );
- public static FunctionSymbol/*!*/ UnsupportedHeapOp { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _unsupportedHeapOp; } }
-
- /// <summary>
- /// Heap should not be instantiated from the outside, except perhaps in
- /// subclasses.
- /// </summary>
- private Heap() { }
- }
-
-// public class List : Value
-// {
-// private static IDictionary/*<AIType!,AIType!>*/! lists = new Hashtable();
-// public static AIType! Type(AIType! typeParameter)
-// {
-// if (lists.Contains(typeParameter))
-// return lists[typeParameter];
-// else
-// {
-// AIType! result = new List(typeParameter);
-// lists[typeParameter] = result;
-// return result;
-// }
-// }
-//
-// private static IDictionary/*<AIType!,AIType!>*/! nils = new Hashtable();
-// public static FunctionSymbol! Nil(AIType! typeParameter)
-// {
-// if (nils.Contains(typeParameter))
-// return nils[typeParameter];
-// else
-// {
-// FunctionSymbol! result = new FunctionSymbol(Type(typeParameter));
-// nils[typeParameter] = result;
-// return result;
-// }
-// }
-//
-// private static IDictionary/*<AIType!,AIType!>*/! cons = new Hashtable();
-// public static FunctionSymbol! Cons(AIType! typeParameter)
-// {
-// if (cons.Contains(typeParameter))
-// return cons[typeParameter];
-// else
-// {
-// FunctionSymbol! result = new FunctionSymbol(
-// new FunctionType(typeParameter, Type(typeParameter), Type(typeParameter))
-// );
-// cons[typeParameter] = result;
-// return result;
-// }
-// }
-//
-// private AIType! typeParameter;
-// public AIType(TypeParameter/*!*/ ){
-//Contract.Requires( != null);
- //return typeParameter; } }
-//
-// /// <summary>
-// /// List should not be instantiated from the outside.
-// /// </summary>
-// private List(AIType! typeParameter)
-// {
-// this.typeParameter = typeParameter;
-// }
-// }
-//
-// public class Pair : Value
-// {
-// private static IDictionary! pairs = new Hashtable();
-// public static AIType! Type(AIType! type1, AIType! type2)
-// {
-// Microsoft.AbstractInterpretationFramework.Collections.Pair typpair
-// = new Microsoft.AbstractInterpretationFramework.Collections.Pair(type1, type2);
-//
-// if (pairs.Contains(typpair))
-// return pairs[typpair];
-// else
-// {
-// AIType! result = new Pair(type1, type2);
-// pairs[typpair] = result;
-// return result;
-// }
-// }
-//
-// private static IDictionary! constructs = new Hashtable();
-// public static FunctionSymbol! Pair(AIType! type1, AIType! type2)
-// {
-// Microsoft.AbstractInterpretationFramework.Collections.Pair typpair
-// = new Microsoft.AbstractInterpretationFramework.Collections.Pair(type1, type2);
-//
-// if (constructs.Contains(typpair))
-// return constructs[typpair];
-// else
-// {
-// FunctionSymbol! result = new FunctionSymbol(
-// new FunctionType(type1, type2, Type(type1, type2))
-// );
-// constructs[typpair] = result;
-// return result;
-// }
-// }
-//
-// protected AIType! type1;
-// protected AIType! type2;
-//
-// public AIType(Type1/*!*/ ){
-//Contract.Requires( != null);
-// return type1; } }
-// public AIType(Type2/*!*/ ){
-//Contract.Requires( != null);
-// return type2; } }
-//
-// /// <summary>
-// /// Pair should not be instantiated from the outside, except by subclasses.
-// /// </summary>
-// protected Pair(AIType! type1, AIType! type2)
-// {
-// this.type1 = type1;
-// this.type2 = type2;
-// }
-// }
+ public static FunctionSymbol/*!*/ Null { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _null; } }
+
+ /// <summary>
+ /// Ref should not be instantiated from the outside, except perhaps in
+ /// subclasses.
+ /// </summary>
+ private Ref() { }
+ }
+
+ public class HeapStructure : Value
+ {
+ private static readonly AIType/*!*/ reftype = new HeapStructure();
+ public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return reftype; } }
- //-------------------------- Propositions ---------------------------
/// <summary>
- /// A class with global propositional symbols and the Prop.Type.
+ /// HeapStructure should not be instantiated from the outside, except perhaps in
+ /// subclasses.
/// </summary>
- public sealed class Prop : AIType
- {
- private static readonly AIType/*!*/ proptype = new Prop();
-
- public static AIType/*!*/ Type { get {Contract.Ensures(Contract.Result<AIType>() != null); return proptype; } }
-
- private static readonly AIType/*!*/ unaryproptype = new FunctionType(Type, Type);
- private static readonly AIType/*!*/ binproptype = new FunctionType(Type, Type, Type);
- private static readonly AIType/*!*/ quantifiertype =
- new FunctionType(new FunctionType(Value.Type, Type), Type);
-
- private static readonly FunctionSymbol/*!*/ _false = new FunctionSymbol("false", Type);
- private static readonly FunctionSymbol/*!*/ _true = new FunctionSymbol("true", Type);
- private static readonly FunctionSymbol/*!*/ _not = new FunctionSymbol("!", unaryproptype);
- private static readonly FunctionSymbol/*!*/ _and = new FunctionSymbol("/\\", binproptype);
- private static readonly FunctionSymbol/*!*/ _or = new FunctionSymbol("\\/", binproptype);
- private static readonly FunctionSymbol/*!*/ _implies = new FunctionSymbol("==>", binproptype);
- private static readonly FunctionSymbol/*!*/ _exists = new FunctionSymbol("Exists", quantifiertype);
- private static readonly FunctionSymbol/*!*/ _forall = new FunctionSymbol("Forall", quantifiertype);
- private static readonly FunctionSymbol/*!*/ _lambda = new FunctionSymbol("Lambda", quantifiertype);
-
-
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ False { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _false; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ True { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _true; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Not { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _not; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ And { [Pure] get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _and; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Or { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _or; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Implies { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _implies; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Exists { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _exists; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Forall { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _forall; } }
- [Pure][Reads(ReadsAttribute.Reads.Nothing)] public static FunctionSymbol/*!*/ Lambda { get {Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _lambda; } }
-
-
- /// <summary>
- /// Prop should not be instantiated from the outside.
- /// </summary>
- private Prop() { }
-
-
-
- //
- // Utility Methods
- //
-
- public static IExpr/*!*/ SimplifiedAnd(IPropExprFactory/*!*/ factory, IExpr/*!*/ e0, IExpr/*!*/ e1){
-Contract.Requires(e1 != null);
-Contract.Requires(e0 != null);
-Contract.Requires(factory != null);
-Contract.Ensures(Contract.Result<IExpr>() != null);
- IFunApp fun0 = e0 as IFunApp;
- if (fun0 != null)
- {
- if (fun0.FunctionSymbol.Equals(Prop.True))
- {
- return e1;
- }
- else if (fun0.FunctionSymbol.Equals(Prop.False))
- {
- return e0;
- }
- }
-
- IFunApp fun1 = e1 as IFunApp;
- if (fun1 != null)
- {
- if (fun1.FunctionSymbol.Equals(Prop.True))
- {
- return e0;
- }
- else if (fun1.FunctionSymbol.Equals(Prop.False))
- {
- return e1;
- }
- }
-
- return factory.And(e0, e1);
- }
-
- public static IExpr/*!*/ SimplifiedAnd(IPropExprFactory/*!*/ factory, IEnumerable/*<IExpr!>*//*!*/ exprs){
-Contract.Requires(exprs != null);
-Contract.Requires(factory != null);
-Contract.Ensures(Contract.Result<IExpr>() != null);
-IExpr/*!*/ result = factory.True;
-Contract.Assert(result != null);
- foreach(IExpr/*!*/ conjunct in exprs){
-Contract.Assert(conjunct != null);
- result = SimplifiedAnd(factory, result, conjunct);
- }
- return result;
- }
+ private HeapStructure() { }
+ }
- public static IExpr/*!*/ SimplifiedOr(IPropExprFactory/*!*/ factory, IExpr/*!*/ e0, IExpr/*!*/ e1){
-Contract.Requires(e1 != null);
-Contract.Requires(e0 != null);
-Contract.Requires(factory != null);
-Contract.Ensures(Contract.Result<IExpr>() != null);
- IFunApp fun0 = e0 as IFunApp;
- if (fun0 != null)
- {
- if (fun0.FunctionSymbol.Equals(Prop.False))
- {
- return e1;
- }
- else if (fun0.FunctionSymbol.Equals(Prop.True))
- {
- return e0;
- }
- }
-
- IFunApp fun1 = e1 as IFunApp;
- if (fun1 != null)
- {
- if (fun1.FunctionSymbol.Equals(Prop.False))
- {
- return e0;
- }
- else if (fun1.FunctionSymbol.Equals(Prop.True))
- {
- return e1;
- }
- }
-
- return factory.Or(e0, e1);
- }
-
- public static IExpr/*!*/ SimplifiedOr(IPropExprFactory/*!*/ factory, IEnumerable/*<IExpr!>*//*!*/ exprs){
-Contract.Requires(exprs != null);
-Contract.Requires(factory != null);
-Contract.Ensures(Contract.Result<IExpr>() != null);
-IExpr/*!*/ result = factory.False;
-Contract.Assert(result != null);
- foreach(IExpr/*!*/ disj in exprs){
-Contract.Assert(disj != null);
- result = SimplifiedOr(factory, result, disj);
- }
- return result;
- }
+ public class FieldName : Value
+ {
+ private static readonly AIType/*!*/ fieldnametype = new FieldName();
+ public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return fieldnametype; } }
+ private static readonly FunctionSymbol/*!*/ _allocated = new FunctionSymbol("$allocated", FieldName.Type);
+ public static FunctionSymbol/*!*/ Allocated { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _allocated; } }
+ /// <summary>
+ /// Is this a boolean field that monotonically goes from false to true?
+ /// </summary>
+ public static bool IsBooleanMonotonicallyWeakening(IFunctionSymbol/*!*/ f) {
+ Contract.Requires(f != null);
+ return f.Equals(Allocated);
+ }
- /// <summary>
- /// Break top-level conjuncts into a list of sub-expressions.
- /// </summary>
- /// <param name="e">The expression to examine.</param>
- /// <returns>A list of conjuncts.</returns>
- internal static IList/*<IExpr!>*//*!*/ BreakConjuncts(IExpr/*!*/ e){
-Contract.Requires(e != null);
- Contract.Ensures(Contract.Result<IList>() != null);
- Contract.Ensures(Contract.ForAll(0, Contract.Result<IList>().Count, i => {
- var sub = Contract.Result<IList>()[i];
- return !(sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(Prop.And);
- }));
- return BreakJuncts(e, Prop.And);
- }
+ /// <summary>
+ /// FieldName should not be instantiated from the outside, except perhaps in
+ /// subclasses.
+ /// </summary>
+ private FieldName() { }
+ }
- /// <summary>
- /// Break top-level disjuncts into a list of sub-expressions.
- /// </summary>
- /// <param name="e">The expression to examine.</param>
- /// <returns>A list of conjuncts.</returns>
- internal static IList/*<IExpr!>*//*!*/ BreakDisjuncts(IExpr/*!*/ e){
-Contract.Requires(e != null);
- Contract.Ensures(Contract.Result<IList>() != null);
- Contract.Ensures(Contract.ForAll(0, Contract.Result<IList>().Count, i => {
- var sub = Contract.Result<IList>()[i];
- return !(sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(Prop.Or);
- }));
- return BreakJuncts(e, Prop.Or);
- }
-
- private static IList/*<IExpr!>*//*!*/ BreakJuncts(IExpr/*!*/ e, IFunctionSymbol/*!*/ sym){
-Contract.Requires(sym != null);
-Contract.Requires(e != null);
- Contract.Ensures(Contract.Result<IList>() != null);
- Contract.Ensures(Contract.ForAll(0, Contract.Result<IList>().Count, i => {
- var sub = Contract.Result<IList>()[i];
- return (sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(sym);
- }));
- ArrayList/*<IExpr!>*//*!*/ result = new ArrayList();
-
- IFunApp f = e as IFunApp;
- if (f != null)
- {
- // If it is a sym, go down into sub-expressions.
- if (f.FunctionSymbol.Equals(sym))
- {
- foreach(IExpr/*!*/ arg in f.Arguments){
-Contract.Assert(arg != null);
- result.AddRange(BreakJuncts(arg,sym));
- }
- }
- // Otherwise, stop.
- else
- {
- result.Add(e);
- }
- }
- else
- {
- result.Add(e);
- }
-
- return result;
- }
- }
+ public class Heap : Value
+ {
+ private static readonly AIType/*!*/ heaptype = new Heap();
+ public static new AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return heaptype; } }
+
+ // the types in the following, select1, select2, are hard-coded;
+ // these types may not always be appropriate
+ private static readonly FunctionSymbol/*!*/ _select1 = new FunctionSymbol("sel1",
+ // Heap x FieldName -> Prop
+ new FunctionType(Type, FieldName.Type, Prop.Type)
+ );
+ public static FunctionSymbol/*!*/ Select1 { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _select1; } }
+
+ private static readonly FunctionSymbol/*!*/ _select2 = new FunctionSymbol("sel2",
+ // Heap x Ref x FieldName -> Value
+ new FunctionType(Type, Ref.Type, FieldName.Type, Value.Type)
+ );
+ public static FunctionSymbol/*!*/ Select2 { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _select2; } }
+
+ // the types in the following, store1, store2, are hard-coded;
+ // these types may not always be appropriate
+ private static readonly FunctionSymbol/*!*/ _update1 = new FunctionSymbol("upd1",
+ // Heap x FieldName x Value -> Heap
+ new FunctionType(Type, FieldName.Type, Value.Type, Type)
+ );
+ public static FunctionSymbol/*!*/ Update1 { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _update1; } }
+
+ private static readonly FunctionSymbol/*!*/ _update2 = new FunctionSymbol("upd2",
+ // Heap x Ref x FieldName x Value -> Heap
+ new FunctionType(Type, Ref.Type, FieldName.Type, Value.Type, Type)
+ );
+ public static FunctionSymbol/*!*/ Update2 { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _update2; } }
+
+ private static readonly FunctionSymbol/*!*/ _unsupportedHeapOp =
+ new FunctionSymbol("UnsupportedHeapOp",
+ // Heap x FieldName -> Prop
+ new FunctionType(Type, FieldName.Type, Prop.Type)
+ );
+ public static FunctionSymbol/*!*/ UnsupportedHeapOp { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _unsupportedHeapOp; } }
/// <summary>
- /// A callback to produce a function body given the bound variable.
+ /// Heap should not be instantiated from the outside, except perhaps in
+ /// subclasses.
/// </summary>
- /// <param name="var">The bound variable to use.</param>
- /// <returns>The function body.</returns>
- public delegate IExpr/*!*/ FunctionBody(IVariable/*!*/ var);
+ private Heap() { }
+ }
+
+ // public class List : Value
+ // {
+ // private static IDictionary/*<AIType!,AIType!>*/! lists = new Hashtable();
+ // public static AIType! Type(AIType! typeParameter)
+ // {
+ // if (lists.Contains(typeParameter))
+ // return lists[typeParameter];
+ // else
+ // {
+ // AIType! result = new List(typeParameter);
+ // lists[typeParameter] = result;
+ // return result;
+ // }
+ // }
+ //
+ // private static IDictionary/*<AIType!,AIType!>*/! nils = new Hashtable();
+ // public static FunctionSymbol! Nil(AIType! typeParameter)
+ // {
+ // if (nils.Contains(typeParameter))
+ // return nils[typeParameter];
+ // else
+ // {
+ // FunctionSymbol! result = new FunctionSymbol(Type(typeParameter));
+ // nils[typeParameter] = result;
+ // return result;
+ // }
+ // }
+ //
+ // private static IDictionary/*<AIType!,AIType!>*/! cons = new Hashtable();
+ // public static FunctionSymbol! Cons(AIType! typeParameter)
+ // {
+ // if (cons.Contains(typeParameter))
+ // return cons[typeParameter];
+ // else
+ // {
+ // FunctionSymbol! result = new FunctionSymbol(
+ // new FunctionType(typeParameter, Type(typeParameter), Type(typeParameter))
+ // );
+ // cons[typeParameter] = result;
+ // return result;
+ // }
+ // }
+ //
+ // private AIType! typeParameter;
+ // public AIType(TypeParameter/*!*/ ){
+ //Contract.Requires( != null);
+ //return typeParameter; } }
+ //
+ // /// <summary>
+ // /// List should not be instantiated from the outside.
+ // /// </summary>
+ // private List(AIType! typeParameter)
+ // {
+ // this.typeParameter = typeParameter;
+ // }
+ // }
+ //
+ // public class Pair : Value
+ // {
+ // private static IDictionary! pairs = new Hashtable();
+ // public static AIType! Type(AIType! type1, AIType! type2)
+ // {
+ // Microsoft.AbstractInterpretationFramework.Collections.Pair typpair
+ // = new Microsoft.AbstractInterpretationFramework.Collections.Pair(type1, type2);
+ //
+ // if (pairs.Contains(typpair))
+ // return pairs[typpair];
+ // else
+ // {
+ // AIType! result = new Pair(type1, type2);
+ // pairs[typpair] = result;
+ // return result;
+ // }
+ // }
+ //
+ // private static IDictionary! constructs = new Hashtable();
+ // public static FunctionSymbol! Pair(AIType! type1, AIType! type2)
+ // {
+ // Microsoft.AbstractInterpretationFramework.Collections.Pair typpair
+ // = new Microsoft.AbstractInterpretationFramework.Collections.Pair(type1, type2);
+ //
+ // if (constructs.Contains(typpair))
+ // return constructs[typpair];
+ // else
+ // {
+ // FunctionSymbol! result = new FunctionSymbol(
+ // new FunctionType(type1, type2, Type(type1, type2))
+ // );
+ // constructs[typpair] = result;
+ // return result;
+ // }
+ // }
+ //
+ // protected AIType! type1;
+ // protected AIType! type2;
+ //
+ // public AIType(Type1/*!*/ ){
+ //Contract.Requires( != null);
+ // return type1; } }
+ // public AIType(Type2/*!*/ ){
+ //Contract.Requires( != null);
+ // return type2; } }
+ //
+ // /// <summary>
+ // /// Pair should not be instantiated from the outside, except by subclasses.
+ // /// </summary>
+ // protected Pair(AIType! type1, AIType! type2)
+ // {
+ // this.type1 = type1;
+ // this.type2 = type2;
+ // }
+ // }
+
+ //-------------------------- Propositions ---------------------------
+
+
+ /// <summary>
+ /// A class with global propositional symbols and the Prop.Type.
+ /// </summary>
+ public sealed class Prop : AIType
+ {
+ private static readonly AIType/*!*/ proptype = new Prop();
+
+ public static AIType/*!*/ Type { get { Contract.Ensures(Contract.Result<AIType>() != null); return proptype; } }
+
+ private static readonly AIType/*!*/ unaryproptype = new FunctionType(Type, Type);
+ private static readonly AIType/*!*/ binproptype = new FunctionType(Type, Type, Type);
+ private static readonly AIType/*!*/ quantifiertype =
+ new FunctionType(new FunctionType(Value.Type, Type), Type);
+
+ private static readonly FunctionSymbol/*!*/ _false = new FunctionSymbol("false", Type);
+ private static readonly FunctionSymbol/*!*/ _true = new FunctionSymbol("true", Type);
+ private static readonly FunctionSymbol/*!*/ _not = new FunctionSymbol("!", unaryproptype);
+ private static readonly FunctionSymbol/*!*/ _and = new FunctionSymbol("/\\", binproptype);
+ private static readonly FunctionSymbol/*!*/ _or = new FunctionSymbol("\\/", binproptype);
+ private static readonly FunctionSymbol/*!*/ _implies = new FunctionSymbol("==>", binproptype);
+ private static readonly FunctionSymbol/*!*/ _exists = new FunctionSymbol("Exists", quantifiertype);
+ private static readonly FunctionSymbol/*!*/ _forall = new FunctionSymbol("Forall", quantifiertype);
+ private static readonly FunctionSymbol/*!*/ _lambda = new FunctionSymbol("Lambda", quantifiertype);
+
+
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ False { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _false; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ True { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _true; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Not { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _not; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ And { [Pure] get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _and; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Or { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _or; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Implies { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _implies; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Exists { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _exists; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Forall { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _forall; } }
+ [Pure]
+ [Reads(ReadsAttribute.Reads.Nothing)]
+ public static FunctionSymbol/*!*/ Lambda { get { Contract.Ensures(Contract.Result<FunctionSymbol>() != null); return _lambda; } }
+
/// <summary>
- /// An interface for constructing propositional expressions.
- ///
- /// This interface should be implemented by the client. An implementation of
- /// of this class should generally be used as a singleton object.
+ /// Prop should not be instantiated from the outside.
/// </summary>
- ///
- [ContractClass(typeof(IPropExprFactoryContracts))]
- public interface IPropExprFactory
- {
- IFunApp/*!*/ False { get /*ensures result.FunctionSymbol.Equals(Prop.False);*/; }
- IFunApp/*!*/ True { get /*ensures result.FunctionSymbol.Equals(Prop.True);*/; }
-
- IFunApp/*!*/ Not(IExpr/*!*/ p) /*ensures result.FunctionSymbol.Equals(Prop.Not);*/;
-
- IFunApp/*!*/ And(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.And);*/;
- IFunApp/*!*/ Or(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.Or);*/;
-
- IFunApp/*!*/ Implies(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.Implies);*/;
- }
- [ContractClassFor(typeof(IPropExprFactory))]
- public abstract class IPropExprFactoryContracts:IPropExprFactory{
- #region IPropExprFactory Members
- IFunApp IPropExprFactory.Implies(IExpr p, IExpr q)
- {
- Contract.Requires(p != null);
- Contract.Requires(q != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
+ private Prop() { }
+
+
+
+ //
+ // Utility Methods
+ //
+
+ public static IExpr/*!*/ SimplifiedAnd(IPropExprFactory/*!*/ factory, IExpr/*!*/ e0, IExpr/*!*/ e1) {
+ Contract.Requires(e1 != null);
+ Contract.Requires(e0 != null);
+ Contract.Requires(factory != null);
+ Contract.Ensures(Contract.Result<IExpr>() != null);
+ IFunApp fun0 = e0 as IFunApp;
+ if (fun0 != null) {
+ if (fun0.FunctionSymbol.Equals(Prop.True)) {
+ return e1;
+ } else if (fun0.FunctionSymbol.Equals(Prop.False)) {
+ return e0;
+ }
+ }
+
+ IFunApp fun1 = e1 as IFunApp;
+ if (fun1 != null) {
+ if (fun1.FunctionSymbol.Equals(Prop.True)) {
+ return e0;
+ } else if (fun1.FunctionSymbol.Equals(Prop.False)) {
+ return e1;
+ }
+ }
+
+ return factory.And(e0, e1);
}
-IFunApp IPropExprFactory.False
-{
-
- get { Contract.Ensures(Contract.Result<IFunApp>() != null);throw new System.NotImplementedException(); }
-}
+ public static IExpr/*!*/ SimplifiedAnd(IPropExprFactory/*!*/ factory, IEnumerable/*<IExpr!>*//*!*/ exprs) {
+ Contract.Requires(exprs != null);
+ Contract.Requires(factory != null);
+ Contract.Ensures(Contract.Result<IExpr>() != null);
+ IExpr/*!*/ result = factory.True;
+ Contract.Assert(result != null);
+ foreach (IExpr/*!*/ conjunct in exprs) {
+ Contract.Assert(conjunct != null);
+ result = SimplifiedAnd(factory, result, conjunct);
+ }
+ return result;
+ }
-IFunApp IPropExprFactory.True
-{
- get {Contract.Ensures(Contract.Result<IFunApp>() != null); throw new System.NotImplementedException(); }
-}
+ public static IExpr/*!*/ SimplifiedOr(IPropExprFactory/*!*/ factory, IExpr/*!*/ e0, IExpr/*!*/ e1) {
+ Contract.Requires(e1 != null);
+ Contract.Requires(e0 != null);
+ Contract.Requires(factory != null);
+ Contract.Ensures(Contract.Result<IExpr>() != null);
+ IFunApp fun0 = e0 as IFunApp;
+ if (fun0 != null) {
+ if (fun0.FunctionSymbol.Equals(Prop.False)) {
+ return e1;
+ } else if (fun0.FunctionSymbol.Equals(Prop.True)) {
+ return e0;
+ }
+ }
-IFunApp IPropExprFactory.Not(IExpr p)
-{
- Contract.Requires(p != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp fun1 = e1 as IFunApp;
+ if (fun1 != null) {
+ if (fun1.FunctionSymbol.Equals(Prop.False)) {
+ return e0;
+ } else if (fun1.FunctionSymbol.Equals(Prop.True)) {
+ return e1;
+ }
+ }
-IFunApp IPropExprFactory.And(IExpr p, IExpr q)
-{
- Contract.Requires(p != null);
- Contract.Requires(q != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ return factory.Or(e0, e1);
+ }
-IFunApp IPropExprFactory.Or(IExpr p, IExpr q)
-{Contract.Requires(p != null);
- Contract.Requires(q != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ public static IExpr/*!*/ SimplifiedOr(IPropExprFactory/*!*/ factory, IEnumerable/*<IExpr!>*//*!*/ exprs) {
+ Contract.Requires(exprs != null);
+ Contract.Requires(factory != null);
+ Contract.Ensures(Contract.Result<IExpr>() != null);
+ IExpr/*!*/ result = factory.False;
+ Contract.Assert(result != null);
+ foreach (IExpr/*!*/ disj in exprs) {
+ Contract.Assert(disj != null);
+ result = SimplifiedOr(factory, result, disj);
+ }
+ return result;
+ }
-#endregion
-}
-
/// <summary>
- /// Like IPropExprFactory, but also with quantifiers.
+ /// Break top-level conjuncts into a list of sub-expressions.
/// </summary>
- ///
- [ContractClass(typeof(IQuantPropExprFactoryContracts))]
- public interface IQuantPropExprFactory : IPropExprFactory {
- /// <summary>
- /// Produce an existential given the lambda-expression.
- /// </summary>
- /// <param name="p">The lambda-expression.</param>
- /// <returns>The existential.</returns>
- IFunApp/*!*/ Exists(IFunction/*!*/ p) /*ensures result.FunctionSymbol.Equals(Prop.Exists);*/;
- IFunApp/*!*/ Forall(IFunction/*!*/ p) /*ensures result.FunctionSymbol.Equals(Prop.Forall);*/;
-
- /// <summary>
- /// Produce an existential given a callback that can produce a function body given the
- /// bound variable to use. The implementer of this method is responsible for generating
- /// a fresh new variable to pass to the FunctionBody callback to use as the bound variable.
- /// </summary>
- /// <param name="body">The function body callback.</param>
- /// <returns>The existential.</returns>
- IFunApp/*!*/ Exists(AIType paramType, FunctionBody/*!*/ body) /*ensures result.FunctionSymbol.Equals(Prop.Exists);*/;
- IFunApp/*!*/ Forall(AIType paramType, FunctionBody/*!*/ body) /*ensures result.FunctionSymbol.Equals(Prop.Forall);*/;
- }
- [ContractClassFor(typeof(IQuantPropExprFactory))]
- public abstract class IQuantPropExprFactoryContracts:IQuantPropExprFactory{
- #region IQuantPropExprFactory Members
-
-IFunApp IQuantPropExprFactory.Exists(IFunction p)
-{
- Contract.Requires(p != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ /// <param name="e">The expression to examine.</param>
+ /// <returns>A list of conjuncts.</returns>
+ internal static IList/*<IExpr!>*//*!*/ BreakConjuncts(IExpr/*!*/ e) {
+ Contract.Requires(e != null);
+ Contract.Ensures(Contract.Result<IList>() != null);
+ Contract.Ensures(Contract.ForAll(0, Contract.Result<IList>().Count, i => {
+ var sub = Contract.Result<IList>()[i];
+ return !(sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(Prop.And);
+ }));
+ return BreakJuncts(e, Prop.And);
+ }
-IFunApp IQuantPropExprFactory.Forall(IFunction p)
-{Contract.Requires(p != null);Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ /// <summary>
+ /// Break top-level disjuncts into a list of sub-expressions.
+ /// </summary>
+ /// <param name="e">The expression to examine.</param>
+ /// <returns>A list of conjuncts.</returns>
+ internal static IList/*<IExpr!>*//*!*/ BreakDisjuncts(IExpr/*!*/ e) {
+ Contract.Requires(e != null);
+ Contract.Ensures(Contract.Result<IList>() != null);
+ Contract.Ensures(Contract.ForAll(0, Contract.Result<IList>().Count, i => {
+ var sub = Contract.Result<IList>()[i];
+ return !(sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(Prop.Or);
+ }));
+ return BreakJuncts(e, Prop.Or);
+ }
-IFunApp IQuantPropExprFactory.Exists(AIType paramType, FunctionBody body)
-{Contract.Requires(body != null);Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ private static IList/*<IExpr!>*//*!*/ BreakJuncts(IExpr/*!*/ e, IFunctionSymbol/*!*/ sym) {
+ Contract.Requires(sym != null);
+ Contract.Requires(e != null);
+ Contract.Ensures(Contract.Result<IList>() != null);
+ Contract.Ensures(Contract.ForAll(0, Contract.Result<IList>().Count, i => {
+ var sub = Contract.Result<IList>()[i];
+ return (sub is IFunApp) || !((IFunApp)sub).FunctionSymbol.Equals(sym);
+ }));
+ ArrayList/*<IExpr!>*//*!*/ result = new ArrayList();
+
+ IFunApp f = e as IFunApp;
+ if (f != null) {
+ // If it is a sym, go down into sub-expressions.
+ if (f.FunctionSymbol.Equals(sym)) {
+ foreach (IExpr/*!*/ arg in f.Arguments) {
+ Contract.Assert(arg != null);
+ result.AddRange(BreakJuncts(arg, sym));
+ }
+ }
+ // Otherwise, stop.
+ else {
+ result.Add(e);
+ }
+ } else {
+ result.Add(e);
+ }
-IFunApp IQuantPropExprFactory.Forall(AIType paramType, FunctionBody body)
-{Contract.Requires(body != null);Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ return result;
+ }
+ }
-#endregion
+ /// <summary>
+ /// A callback to produce a function body given the bound variable.
+ /// </summary>
+ /// <param name="var">The bound variable to use.</param>
+ /// <returns>The function body.</returns>
+ public delegate IExpr/*!*/ FunctionBody(IVariable/*!*/ var);
+
+ /// <summary>
+ /// An interface for constructing propositional expressions.
+ ///
+ /// This interface should be implemented by the client. An implementation of
+ /// of this class should generally be used as a singleton object.
+ /// </summary>
+ ///
+ [ContractClass(typeof(IPropExprFactoryContracts))]
+ public interface IPropExprFactory
+ {
+ IFunApp/*!*/ False { get /*ensures result.FunctionSymbol.Equals(Prop.False);*/; }
+ IFunApp/*!*/ True { get /*ensures result.FunctionSymbol.Equals(Prop.True);*/; }
+
+ IFunApp/*!*/ Not(IExpr/*!*/ p) /*ensures result.FunctionSymbol.Equals(Prop.Not);*/;
+
+ IFunApp/*!*/ And(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.And);*/;
+ IFunApp/*!*/ Or(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.Or);*/;
+
+ IFunApp/*!*/ Implies(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.Implies);*/;
+ }
+ [ContractClassFor(typeof(IPropExprFactory))]
+ public abstract class IPropExprFactoryContracts : IPropExprFactory
+ {
+ #region IPropExprFactory Members
+ IFunApp IPropExprFactory.Implies(IExpr p, IExpr q) {
+ Contract.Requires(p != null);
+ Contract.Requires(q != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-#region IPropExprFactory Members
+ IFunApp IPropExprFactory.False {
-IFunApp IPropExprFactory.False
-{
- get { throw new System.NotImplementedException(); }
-}
+ get { Contract.Ensures(Contract.Result<IFunApp>() != null); throw new System.NotImplementedException(); }
+ }
-IFunApp IPropExprFactory.True
-{
- get { throw new System.NotImplementedException(); }
-}
+ IFunApp IPropExprFactory.True {
+ get { Contract.Ensures(Contract.Result<IFunApp>() != null); throw new System.NotImplementedException(); }
+ }
-IFunApp IPropExprFactory.Not(IExpr p)
-{
- throw new System.NotImplementedException();
-}
+ IFunApp IPropExprFactory.Not(IExpr p) {
+ Contract.Requires(p != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp IPropExprFactory.And(IExpr p, IExpr q)
-{
- throw new System.NotImplementedException();
-}
+ IFunApp IPropExprFactory.And(IExpr p, IExpr q) {
+ Contract.Requires(p != null);
+ Contract.Requires(q != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp IPropExprFactory.Or(IExpr p, IExpr q)
-{
- throw new System.NotImplementedException();
-}
+ IFunApp IPropExprFactory.Or(IExpr p, IExpr q) {
+ Contract.Requires(p != null);
+ Contract.Requires(q != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp IPropExprFactory.Implies(IExpr p, IExpr q)
-{
- throw new System.NotImplementedException();
-}
-#endregion
-}
- /// <summary>
- /// An interface for constructing value expressions.
- ///
- /// This interface should be implemented by the client. An implementation of
- /// of this class should generally be used as a singleton object.
- /// </summary>
- ///
+ #endregion
+ }
+
+ /// <summary>
+ /// An interface for constructing value expressions.
+ ///
+ /// This interface should be implemented by the client. An implementation of
+ /// of this class should generally be used as a singleton object.
+ /// </summary>
+ ///
[ContractClass(typeof(IValueExprFactoryContracts))]
- public interface IValueExprFactory
- {
- IFunApp/*!*/ Eq (IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Eq);*/;
- IFunApp/*!*/ Neq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Neq);*/;
- }
+ public interface IValueExprFactory
+ {
+ IFunApp/*!*/ Eq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Eq);*/;
+ IFunApp/*!*/ Neq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Neq);*/;
+ }
[ContractClassFor(typeof(IValueExprFactory))]
- public abstract class IValueExprFactoryContracts:IValueExprFactory{
- #region IValueExprFactory Members
+ public abstract class IValueExprFactoryContracts : IValueExprFactory
+ {
+ #region IValueExprFactory Members
-IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1)
-{
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1)
-{
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-#endregion
-}
+ #endregion
+ }
- /// <summary>
- /// An interface for constructing value expressions having to with null.
- ///
- /// This interface should be implemented by the client. An implementation of
- /// of this class should generally be used as a singleton object.
- /// </summary>
- ///
+ /// <summary>
+ /// An interface for constructing value expressions having to with null.
+ ///
+ /// This interface should be implemented by the client. An implementation of
+ /// of this class should generally be used as a singleton object.
+ /// </summary>
+ ///
[ContractClass(typeof(INullnessFactoryContracts))]
- public interface INullnessFactory
- {
- IFunApp/*!*/ Eq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Eq);*/;
- IFunApp/*!*/ Neq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Neq);*/;
- IFunApp/*!*/ Null { get; /*ensures result.FunctionSymbol.Equals(Ref.Null);*/ }
- }
+ public interface INullnessFactory
+ {
+ IFunApp/*!*/ Eq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Eq);*/;
+ IFunApp/*!*/ Neq(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Neq);*/;
+ IFunApp/*!*/ Null { get; /*ensures result.FunctionSymbol.Equals(Ref.Null);*/ }
+ }
[ContractClassFor(typeof(INullnessFactory))]
- public abstract class INullnessFactoryContracts:INullnessFactory{
-#region INullnessFactory Members
+ public abstract class INullnessFactoryContracts : INullnessFactory
+ {
+ #region INullnessFactory Members
-IFunApp INullnessFactory.Eq(IExpr e0, IExpr e1)
-{
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp INullnessFactory.Eq(IExpr e0, IExpr e1) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp INullnessFactory.Neq(IExpr e0, IExpr e1)
-{
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp INullnessFactory.Neq(IExpr e0, IExpr e1) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp INullnessFactory.Null
-{
- get {
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException(); }
-}
+ IFunApp INullnessFactory.Null {
+ get {
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
+ }
-#endregion
-}
+ #endregion
+ }
- /// <summary>
- /// An interface for constructing integer expressions.
- ///
- /// This interface should be implemented by the client. An implementation of
- /// of this class should generally be used as a singleton object.
- /// </summary>
- ///
+ /// <summary>
+ /// An interface for constructing integer expressions.
+ ///
+ /// This interface should be implemented by the client. An implementation of
+ /// of this class should generally be used as a singleton object.
+ /// </summary>
+ ///
[ContractClass(typeof(IIntExprFactoryContracts))]
- public interface IIntExprFactory : IValueExprFactory
- {
- IFunApp/*!*/ Const(BigNum i) /*ensures result.FunctionSymbol.Equals(new IntSymbol(i));*/;
- }
+ public interface IIntExprFactory : IValueExprFactory
+ {
+ IFunApp/*!*/ Const(BigNum i) /*ensures result.FunctionSymbol.Equals(new IntSymbol(i));*/;
+ }
[ContractClassFor(typeof(IIntExprFactory))]
- public abstract class IIntExprFactoryContracts : IIntExprFactory {
-
- #region IIntExprFactory Members
+ public abstract class IIntExprFactoryContracts : IIntExprFactory
+ {
- IFunApp IIntExprFactory.Const(BigNum i) {
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
- }
+ #region IIntExprFactory Members
- #endregion
+ IFunApp IIntExprFactory.Const(BigNum i) {
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
- #region IValueExprFactory Members
+ #endregion
- IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
- throw new System.NotImplementedException();
- }
+ #region IValueExprFactory Members
- IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
- throw new System.NotImplementedException();
- }
+ IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
+ throw new System.NotImplementedException();
+ }
- #endregion
+ IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
+ throw new System.NotImplementedException();
}
+ #endregion
+ }
+
+ /// <summary>
+ /// An interface for constructing linear integer expressions.
+ ///
+ /// This interface should be implemented by the client. An implementation of
+ /// of this class should generally be used as a singleton object.
+ /// </summary>
+ ///
+ [ContractClass(typeof(ILinearExprFactoryContracts))]
+ public interface ILinearExprFactory : IIntExprFactory
+ {
+ IFunApp/*!*/ AtMost(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.AtMost);*/;
+ IFunApp/*!*/ Add(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Add);*/;
/// <summary>
- /// An interface for constructing linear integer expressions.
- ///
- /// This interface should be implemented by the client. An implementation of
- /// of this class should generally be used as a singleton object.
+ /// If "var" is null, returns an expression representing r.
+ /// Otherwise, returns an expression representing r*var.
/// </summary>
- ///
- [ContractClass(typeof(ILinearExprFactoryContracts))]
- public interface ILinearExprFactory : IIntExprFactory
- {
- IFunApp/*!*/ AtMost(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.AtMost);*/;
- IFunApp/*!*/ Add(IExpr/*!*/ e0, IExpr/*!*/ e1) /*ensures result.FunctionSymbol.Equals(Value.Add);*/;
- /// <summary>
- /// If "var" is null, returns an expression representing r.
- /// Otherwise, returns an expression representing r*var.
- /// </summary>
- IExpr/*!*/ Term(Microsoft.Basetypes.Rational r, IVariable var);
-
- IFunApp/*!*/ False { get /*ensures result.FunctionSymbol.Equals(Prop.False);*/; }
- IFunApp/*!*/ True { get /*ensures result.FunctionSymbol.Equals(Prop.True);*/; }
- IFunApp/*!*/ And(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.And);*/;
- }
+ IExpr/*!*/ Term(Microsoft.Basetypes.Rational r, IVariable var);
+
+ IFunApp/*!*/ False { get /*ensures result.FunctionSymbol.Equals(Prop.False);*/; }
+ IFunApp/*!*/ True { get /*ensures result.FunctionSymbol.Equals(Prop.True);*/; }
+ IFunApp/*!*/ And(IExpr/*!*/ p, IExpr/*!*/ q) /*ensures result.FunctionSymbol.Equals(Prop.And);*/;
+ }
[ContractClassFor(typeof(ILinearExprFactory))]
- public abstract class ILinearExprFactoryContracts:ILinearExprFactory{
+ public abstract class ILinearExprFactoryContracts : ILinearExprFactory
+ {
- #region ILinearExprFactory Members
+ #region ILinearExprFactory Members
-IFunApp ILinearExprFactory.AtMost(IExpr e0, IExpr e1)
-{
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp ILinearExprFactory.AtMost(IExpr e0, IExpr e1) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp ILinearExprFactory.Add(IExpr e0, IExpr e1)
-{
- Contract.Requires(e0 != null);
- Contract.Requires(e1 != null);Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp ILinearExprFactory.Add(IExpr e0, IExpr e1) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null); Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IExpr ILinearExprFactory.Term(Rational r, IVariable var)
-{
- Contract.Ensures(Contract.Result<IExpr>() != null);
- throw new System.NotImplementedException();
-}
+ IExpr ILinearExprFactory.Term(Rational r, IVariable var) {
+ Contract.Ensures(Contract.Result<IExpr>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp ILinearExprFactory.False
-{
- get {Contract.Ensures(Contract.Result<IFunApp>() != null); throw new System.NotImplementedException(); }
-}
+ IFunApp ILinearExprFactory.False {
+ get { Contract.Ensures(Contract.Result<IFunApp>() != null); throw new System.NotImplementedException(); }
+ }
-IFunApp ILinearExprFactory.True
-{
- get { Contract.Ensures(Contract.Result<IFunApp>() != null);throw new System.NotImplementedException(); }
-}
+ IFunApp ILinearExprFactory.True {
+ get { Contract.Ensures(Contract.Result<IFunApp>() != null); throw new System.NotImplementedException(); }
+ }
-IFunApp ILinearExprFactory.And(IExpr p, IExpr q)
-{
- Contract.Requires(p != null);
- Contract.Requires(q != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp ILinearExprFactory.And(IExpr p, IExpr q) {
+ Contract.Requires(p != null);
+ Contract.Requires(q != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-#endregion
+ #endregion
-#region IIntExprFactory Members
+ #region IIntExprFactory Members
-IFunApp IIntExprFactory.Const(BigNum i) {
- throw new System.NotImplementedException();
-}
+ IFunApp IIntExprFactory.Const(BigNum i) {
+ throw new System.NotImplementedException();
+ }
-#endregion
+ #endregion
-#region IValueExprFactory Members
+ #region IValueExprFactory Members
-IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
- throw new System.NotImplementedException();
-}
+ IFunApp IValueExprFactory.Eq(IExpr e0, IExpr e1) {
+ throw new System.NotImplementedException();
+ }
-IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
- throw new System.NotImplementedException();
-}
+ IFunApp IValueExprFactory.Neq(IExpr e0, IExpr e1) {
+ throw new System.NotImplementedException();
+ }
-#endregion
+ #endregion
}
+ /// <summary>
+ /// An interface for constructing type expressions and performing some type operations.
+ /// The types are assumed to be arranged in a rooted tree.
+ ///
+ /// This interface should be implemented by the client. An implementation of
+ /// of this class should generally be used as a singleton object.
+ /// </summary>
+ ///
+ [ContractClass(typeof(ITypeExprFactoryContracts))]
+ public interface ITypeExprFactory
+ {
/// <summary>
- /// An interface for constructing type expressions and performing some type operations.
- /// The types are assumed to be arranged in a rooted tree.
- ///
- /// This interface should be implemented by the client. An implementation of
- /// of this class should generally be used as a singleton object.
+ /// Returns an expression denoting the top of the type hierarchy.
/// </summary>
- ///
- [ContractClass(typeof(ITypeExprFactoryContracts))]
- public interface ITypeExprFactory
- {
- /// <summary>
- /// Returns an expression denoting the top of the type hierarchy.
- /// </summary>
- IExpr/*!*/ RootType { get; }
-
- /// <summary>
- /// Returns true iff "t" denotes a type constant.
- /// </summary>
- [Pure]
- bool IsTypeConstant(IExpr/*!*/ t);
-
- /// <summary>
- /// Returns true iff t0 and t1 are types such that t0 and t1 are equal.
- /// </summary>
- [Pure]
- bool IsTypeEqual(IExpr/*!*/ t0, IExpr/*!*/ t1);
-
- /// <summary>
- /// Returns true iff t0 and t1 are types such that t0 is a subtype of t1.
- /// </summary>
- [Pure]
- bool IsSubType(IExpr/*!*/ t0, IExpr/*!*/ t1);
-
- /// <summary>
- /// Returns the most derived supertype of both "t0" and "t1". A precondition is
- /// that "t0" and "t1" both represent types.
- /// </summary>
- IExpr/*!*/ JoinTypes(IExpr/*!*/ t0, IExpr/*!*/ t1);
-
- IFunApp/*!*/ IsExactlyA(IExpr/*!*/ e, IExpr/*!*/ type) /*requires IsTypeConstant(type); ensures result.FunctionSymbol.Equals(Value.Eq);*/;
- IFunApp/*!*/ IsA(IExpr/*!*/ e, IExpr/*!*/ type) /*requires IsTypeConstant(type); ensures result.FunctionSymbol.Equals(Value.Subtype);*/;
- }
+ IExpr/*!*/ RootType { get; }
+
+ /// <summary>
+ /// Returns true iff "t" denotes a type constant.
+ /// </summary>
+ [Pure]
+ bool IsTypeConstant(IExpr/*!*/ t);
+
+ /// <summary>
+ /// Returns true iff t0 and t1 are types such that t0 and t1 are equal.
+ /// </summary>
+ [Pure]
+ bool IsTypeEqual(IExpr/*!*/ t0, IExpr/*!*/ t1);
+
+ /// <summary>
+ /// Returns true iff t0 and t1 are types such that t0 is a subtype of t1.
+ /// </summary>
+ [Pure]
+ bool IsSubType(IExpr/*!*/ t0, IExpr/*!*/ t1);
+
+ /// <summary>
+ /// Returns the most derived supertype of both "t0" and "t1". A precondition is
+ /// that "t0" and "t1" both represent types.
+ /// </summary>
+ IExpr/*!*/ JoinTypes(IExpr/*!*/ t0, IExpr/*!*/ t1);
+
+ IFunApp/*!*/ IsExactlyA(IExpr/*!*/ e, IExpr/*!*/ type) /*requires IsTypeConstant(type); ensures result.FunctionSymbol.Equals(Value.Eq);*/;
+ IFunApp/*!*/ IsA(IExpr/*!*/ e, IExpr/*!*/ type) /*requires IsTypeConstant(type); ensures result.FunctionSymbol.Equals(Value.Subtype);*/;
+ }
[ContractClassFor(typeof(ITypeExprFactory))]
- public abstract class ITypeExprFactoryContracts:ITypeExprFactory{
+ public abstract class ITypeExprFactoryContracts : ITypeExprFactory
+ {
- #region ITypeExprFactory Members
+ #region ITypeExprFactory Members
-IExpr ITypeExprFactory.RootType
-{
- get {Contract.Ensures(Contract.Result<IExpr>() != null); throw new System.NotImplementedException(); }
-}
+ IExpr ITypeExprFactory.RootType {
+ get { Contract.Ensures(Contract.Result<IExpr>() != null); throw new System.NotImplementedException(); }
+ }
-bool ITypeExprFactory.IsTypeConstant(IExpr t)
-{
- Contract.Requires(t != null);
- throw new System.NotImplementedException();
-}
+ bool ITypeExprFactory.IsTypeConstant(IExpr t) {
+ Contract.Requires(t != null);
+ throw new System.NotImplementedException();
+ }
-bool ITypeExprFactory.IsTypeEqual(IExpr t0, IExpr t1)
-{
- Contract.Requires(t0 != null);
- Contract.Requires(t1 != null);
- throw new System.NotImplementedException();
-}
+ bool ITypeExprFactory.IsTypeEqual(IExpr t0, IExpr t1) {
+ Contract.Requires(t0 != null);
+ Contract.Requires(t1 != null);
+ throw new System.NotImplementedException();
+ }
-bool ITypeExprFactory.IsSubType(IExpr t0, IExpr t1)
-{
- Contract.Requires(t0 != null);
- Contract.Requires(t1 != null);
- throw new System.NotImplementedException();
-}
+ bool ITypeExprFactory.IsSubType(IExpr t0, IExpr t1) {
+ Contract.Requires(t0 != null);
+ Contract.Requires(t1 != null);
+ throw new System.NotImplementedException();
+ }
-IExpr ITypeExprFactory.JoinTypes(IExpr t0, IExpr t1)
-{
- Contract.Requires(t0 != null);
- Contract.Requires(t1 != null);
- Contract.Ensures(Contract.Result<IExpr>() != null);
- throw new System.NotImplementedException();
-}
+ IExpr ITypeExprFactory.JoinTypes(IExpr t0, IExpr t1) {
+ Contract.Requires(t0 != null);
+ Contract.Requires(t1 != null);
+ Contract.Ensures(Contract.Result<IExpr>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp ITypeExprFactory.IsExactlyA(IExpr e, IExpr type)
-{
- Contract.Requires(e != null);
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp ITypeExprFactory.IsExactlyA(IExpr e, IExpr type) {
+ Contract.Requires(e != null);
+ Contract.Requires(type != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-IFunApp ITypeExprFactory.IsA(IExpr e, IExpr type)
-{
- Contract.Requires(e != null);
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<IFunApp>() != null);
- throw new System.NotImplementedException();
-}
+ IFunApp ITypeExprFactory.IsA(IExpr e, IExpr type) {
+ Contract.Requires(e != null);
+ Contract.Requires(type != null);
+ Contract.Ensures(Contract.Result<IFunApp>() != null);
+ throw new System.NotImplementedException();
+ }
-#endregion
+ #endregion
+ }
}
-} \ No newline at end of file
diff --git a/Source/AbsInt/AbstractInterpretation.cs b/Source/AbsInt/AbstractInterpretation.cs
index 698141bb..a5847594 100644
--- a/Source/AbsInt/AbstractInterpretation.cs
+++ b/Source/AbsInt/AbstractInterpretation.cs
@@ -686,7 +686,7 @@ namespace Microsoft.Boogie.AbstractInterpretation {
static public AbstractAlgebra BuildIntervalsAbstractDomain() {
Contract.Ensures(Contract.Result<AbstractAlgebra>() != null);
- AI.IQuantPropExprFactory propfactory = new BoogiePropFactory();
+ AI.IPropExprFactory propfactory = new BoogiePropFactory();
AI.ILinearExprFactory linearfactory = new BoogieLinearFactory();
AI.IValueExprFactory valuefactory = new BoogieValueFactory();
IComparer variableComparer = new VariableComparer();
@@ -709,7 +709,7 @@ namespace Microsoft.Boogie.AbstractInterpretation {
AI.Lattice returnLattice;
- AI.IQuantPropExprFactory propfactory = new BoogiePropFactory();
+ AI.IPropExprFactory propfactory = new BoogiePropFactory();
AI.ILinearExprFactory linearfactory = new BoogieLinearFactory();
AI.IIntExprFactory intfactory = new BoogieIntFactory();
AI.IValueExprFactory valuefactory = new BoogieValueFactory();
@@ -772,7 +772,7 @@ namespace Microsoft.Boogie.AbstractInterpretation {
[Peer]
private AI.Lattice lattice;
[Peer]
- private AI.IQuantPropExprFactory propFactory;
+ private AI.IPropExprFactory propFactory;
[Peer]
private AI.ILinearExprFactory linearFactory;
[Peer]
@@ -797,7 +797,7 @@ namespace Microsoft.Boogie.AbstractInterpretation {
}
}
- public AI.IQuantPropExprFactory PropositionFactory {
+ public AI.IPropExprFactory PropositionFactory {
get {
return this.propFactory;
}
@@ -835,7 +835,7 @@ namespace Microsoft.Boogie.AbstractInterpretation {
[Captured]
public AbstractAlgebra(AI.Lattice lattice,
- AI.IQuantPropExprFactory propFactory,
+ AI.IPropExprFactory propFactory,
AI.ILinearExprFactory linearFactory,
AI.IIntExprFactory intFactory,
AI.IValueExprFactory valueFactory,
diff --git a/Source/AbsInt/ExprFactories.cs b/Source/AbsInt/ExprFactories.cs
index 34564cac..9b1ea0a0 100644
--- a/Source/AbsInt/ExprFactories.cs
+++ b/Source/AbsInt/ExprFactories.cs
@@ -10,7 +10,8 @@ using Microsoft.Basetypes;
namespace Microsoft.Boogie.AbstractInterpretation {
- public class BoogiePropFactory : BoogieFactory, AI.IQuantPropExprFactory {
+ public class BoogiePropFactory : BoogieFactory, AI.IPropExprFactory
+ {
public AI.IFunApp False {
get {
Contract.Ensures(Contract.Result<AI.IFunApp>() != null);
@@ -61,17 +62,6 @@ namespace Microsoft.Boogie.AbstractInterpretation {
return (AI.IFunApp)(new ExistsExpr(Token.NoToken, new VariableSeq((Variable)p.Param), IExpr2Expr(p.Body))).IExpr;
}
- public AI.IFunApp Exists(AI.AIType paramType, AI.FunctionBody bodygen) {
- //Contract.Requires(bodygen != null);
- Contract.Ensures(Contract.Result<AI.IFunApp>() != null);
-
- // generate a fresh new variable
- Variable var = FreshBoundVariable(paramType);
- Contract.Assert(var != null);
- Expr expr = IExpr2Expr(bodygen(var));
- Contract.Assert(expr != null);
- return (AI.IFunApp)(new ExistsExpr(Token.NoToken, new VariableSeq(var), expr)).IExpr;
- }
public AI.IFunApp Forall(AI.IFunction p) {
//Contract.Requires(p != null);
@@ -79,39 +69,6 @@ namespace Microsoft.Boogie.AbstractInterpretation {
return (AI.IFunApp)(new ForallExpr(Token.NoToken, new VariableSeq((Variable)p.Param), IExpr2Expr(p.Body))).IExpr;
}
- public AI.IFunApp Forall(AI.AIType paramType, AI.FunctionBody bodygen) {
- //Contract.Requires(bodygen != null);
- Contract.Ensures(Contract.Result<AI.IFunApp>() != null);
-
- // generate a fresh new variable
- Variable var = FreshBoundVariable(paramType);
- Contract.Assert(var != null);
- Expr expr = IExpr2Expr(bodygen(var));
- Contract.Assert(expr != null);
- return (AI.IFunApp)(new ForallExpr(Token.NoToken, new VariableSeq(var), expr)).IExpr;
- }
-
- private static int freshVarNum = 0;
- private static Variable FreshBoundVariable(AI.AIType paramType) {
- Contract.Ensures(Contract.Result<Variable>() != null);
-
- // TODO: Should use the AI.AIType given in Exists and Forall to determine what Boogie type
- // to make this new variable? For now, we use Type.Any.
- Type t = Type.Int;
- Contract.Assert(t != null);
- /*
- if (paramType is AI.Ref)
- t = Type.Ref;
- else if (paramType is AI.FieldName)
- t = Type.Name;
- else
- System.Console.WriteLine("*** unsupported type in AI {0}", paramType); */
- Contract.Assert(false);
- throw new cce.UnreachableException();
- TypedIdent id = new TypedIdent(Token.NoToken, "propfactory_freshvar" + freshVarNum, t);
- freshVarNum++;
- return new BoundVariable(Token.NoToken, id);
- }
}
public class BoogieValueFactory : BoogieFactory, AI.IValueExprFactory {
diff --git a/Source/Core/Absy.cs b/Source/Core/Absy.cs
index a9c41efb..e5e3e549 100644
--- a/Source/Core/Absy.cs
+++ b/Source/Core/Absy.cs
@@ -312,9 +312,6 @@ namespace Microsoft.Boogie {
seeker.Visit(d);
}
}
-
- AxiomExpander expander = new AxiomExpander(this, tc);
- expander.CollectExpansions();
}
public void ComputeStronglyConnectedComponents() {
@@ -761,7 +758,7 @@ namespace Microsoft.Boogie {
Graph<Block> g = ProcessLoops(impl);
CreateProceduresForLoops(impl, g, loopImpls, fullMap);
}
- catch (IrreducibleLoopException e)
+ catch (IrreducibleLoopException)
{
System.Diagnostics.Debug.Assert(!fullMap.ContainsKey(impl.Name));
fullMap[impl.Name] = null;
@@ -1766,43 +1763,14 @@ namespace Microsoft.Boogie {
}
}
- public class Expansion {
- public string ignore; // when to ignore
- public Expr/*!*/ body;
- public TypeVariableSeq/*!*/ TypeParameters;
- public Variable[]/*!*/ formals;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(body != null);
- Contract.Invariant(TypeParameters != null);
- Contract.Invariant(formals != null);
- }
-
-
- public Expansion(string ignore, Expr body,
- TypeVariableSeq/*!*/ typeParams, Variable[] formals) {
- Contract.Requires(typeParams != null);
- Contract.Requires(formals != null);
- Contract.Requires(body != null);
- this.ignore = ignore;
- this.body = body;
- this.TypeParameters = typeParams;
- this.formals = formals;
- }
- }
+
public class Function : DeclWithFormals {
public string Comment;
// the body is only set if the function is declared with {:inline}
public Expr Body;
- public List<Expansion/*!*/> expansions;
public bool doingExpansion;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(expansions, true));
- }
-
private bool neverTrigger;
private bool neverTriggerComputed;
diff --git a/Source/Core/AbsyExpr.cs b/Source/Core/AbsyExpr.cs
index 630f6f14..9a0fe64e 100644
--- a/Source/Core/AbsyExpr.cs
+++ b/Source/Core/AbsyExpr.cs
@@ -494,8 +494,6 @@ namespace Microsoft.Boogie {
public override void Typecheck(TypecheckingContext tc) {
//Contract.Requires(tc != null);
- if (Val is BvConst && CommandLineOptions.Clo.Verify && CommandLineOptions.Clo.Bitvectors == CommandLineOptions.BvHandling.None)
- tc.Error(this, "no bitvector handling specified, please use /bv:i or /bv:z flag");
this.Type = ShallowType;
}
@@ -2241,9 +2239,6 @@ namespace Microsoft.Boogie {
TypeParameters == null) {
TypeParamInstantiation tpInsts;
Type = Fun.Typecheck(ref Args, out tpInsts, tc);
- if (Type != null && Type.IsBv && CommandLineOptions.Clo.Verify && CommandLineOptions.Clo.Bitvectors == CommandLineOptions.BvHandling.None) {
- tc.Error(this, "no bitvector handling specified, please use /bv:i or /bv:z flag");
- }
TypeParameters = tpInsts;
}
IOverloadedAppliable oa = Fun as IOverloadedAppliable;
diff --git a/Source/Core/CommandLineOptions.cs b/Source/Core/CommandLineOptions.cs
index 591b7383..4ffccdc5 100644
--- a/Source/Core/CommandLineOptions.cs
+++ b/Source/Core/CommandLineOptions.cs
@@ -137,6 +137,8 @@ namespace Microsoft.Boogie {
public bool OverlookBoogieTypeErrors = false;
public bool Verify = true;
public bool DisallowSoundnessCheating = false;
+ public int DafnyInduction = 3;
+ public int DafnyInductionHeuristic = 6;
public bool TraceVerify = false;
public int /*(0:3)*/ ErrorTrace = 1;
public bool IntraproceduralInfer = true;
@@ -199,14 +201,8 @@ namespace Microsoft.Boogie {
Contract.Invariant((0 <= PrintErrorModel && PrintErrorModel <= 2) || PrintErrorModel == 4);
Contract.Invariant(0 <= EnhancedErrorMessages && EnhancedErrorMessages < 2);
Contract.Invariant(0 <= StepsBeforeWidening && StepsBeforeWidening <= 9);
- Contract.Invariant(-1 <= BracketIdsInVC && BracketIdsInVC <= 1);
+ Contract.Invariant(-1 <= BracketIdsInVC && BracketIdsInVC < 2);
Contract.Invariant(cce.NonNullElements(ProverOptions));
-
-
-
-
-
-
}
public int CheckingLevel = 2;
@@ -236,12 +232,6 @@ namespace Microsoft.Boogie {
public string/*?*/ ModelViewFile = null;
public int EnhancedErrorMessages = 0;
public bool ForceBplErrors = false; // if true, boogie error is shown even if "msg" attribute is present
- public enum BvHandling {
- None,
- Z3Native,
- ToInt
- }
- public BvHandling Bitvectors = BvHandling.Z3Native;
public bool UseArrayTheory = false;
public bool MonomorphicArrays {
get {
@@ -725,6 +715,16 @@ namespace Microsoft.Boogie {
break;
}
+ case "-induction":
+ case "/induction":
+ ps.GetNumericArgument(ref DafnyInduction, 4);
+ break;
+
+ case "-inductionHeuristic":
+ case "/inductionHeuristic":
+ ps.GetNumericArgument(ref DafnyInductionHeuristic, 7);
+ break;
+
case "-contracts":
case "/contracts":
case "-c":
@@ -945,31 +945,6 @@ namespace Microsoft.Boogie {
ForceBplErrors = true;
break;
- case "-bv":
- case "/bv":
- if (ps.ConfirmArgumentCount(1)) {
- if (TheProverFactory == null) {
- TheProverFactory = ProverFactory.Load("Z3");
- ProverName = "Z3".ToUpper();
- }
-
- switch (args[ps.i]) {
- case "n":
- Bitvectors = BvHandling.None;
- break;
- case "z":
- Bitvectors = BvHandling.Z3Native;
- break;
- case "i":
- Bitvectors = BvHandling.ToInt;
- break;
- default:
- ps.Error("Invalid argument \"{0}\" to option {1}", args[ps.i], ps.s);
- break;
- }
- }
- break;
-
case "-contractInfer":
case "/contractInfer":
ContractInfer = true;
@@ -1470,8 +1445,8 @@ namespace Microsoft.Boogie {
if (TheProverFactory == null) {
cce.BeginExpose(this);
{
- TheProverFactory = ProverFactory.Load("Z3");
- ProverName = "Z3".ToUpper();
+ TheProverFactory = ProverFactory.Load("SMTLIB");
+ ProverName = "SMTLIB".ToUpper();
}
cce.EndExpose();
}
@@ -1877,7 +1852,6 @@ namespace Microsoft.Boogie {
{:ignore}
Ignore the declaration (after checking for duplicate names).
- See also below for more options when :ignore is used with axioms.
{:extern}
If two top-level declarations introduce the same name (for example, two
@@ -1888,22 +1862,6 @@ namespace Microsoft.Boogie {
one of them to keep; otherwise, Boogie ignore the :extern declaration
and keeps the other.
- ---- On axioms -------------------------------------------------------------
-
- {:inline true}
- Works on axiom of the form:
- (forall VARS :: f(VARS) = expr(VARS))
- Makes Boogie replace f(VARS) with expr(VARS) everywhere just before
- doing VC generation.
-
- {:ignore ""p,q..""}
- Exclude the axiom when generating VC for a prover supporting any
- of the features 'p', 'q', ...
- All the provers support the feature 'all'.
- Simplify supports 'simplify' and 'simplifyLike'.
- Z3 supports 'z3', 'simplifyLike' and either 'bvInt' (if the /bv:i
- option is passed) or 'bvDefSem' (for /bv:z).
-
---- On implementations and procedures -------------------------------------
{:inline N}
@@ -1918,15 +1876,6 @@ namespace Microsoft.Boogie {
{:verify false}
Skip verification of an implementation.
- {:forceBvZ3Native true}
- Verify the given implementation with the native Z3 bitvector
- handling. Only works if /bv:i (or /bv:z, but then it does not do
- anything) is given on the command line.
-
- {:forceBvInt true}
- Use int translation for the given implementation. Only work with
- /bv:z (or /bv:i).
-
{:vcs_max_cost N}
{:vcs_max_splits N}
{:vcs_max_keep_going_splits N}
@@ -1942,12 +1891,13 @@ namespace Microsoft.Boogie {
---- On functions ----------------------------------------------------------
+ {:builtin ""spec""}
{:bvbuiltin ""spec""}
- Z3 specific, used only with /bv:z.
+ Rewrite the function to built-in prover function symbol 'fn'.
- {:bvint ""fn""}
- With /bv:i rewrite the function to function symbol 'fn', except if
- the 'fn' is 'id', in which case just strip the function altogether.
+ {:inline}
+ {:inline true}
+ Expand function according to its definition before going to the prover.
{:never_pattern true}
Terms starting with this function symbol will never be
@@ -2094,6 +2044,18 @@ namespace Microsoft.Boogie {
out.cs, regardless of verification outcome
/noCheating:<n> : 0 (default) - allow assume statements and free invariants
1 - treat all assumptions as asserts, and drop free.
+ /induction:<n> : 0 - never do induction, not even when attributes request it
+ 1 - only apply induction when attributes request it
+ 2 - apply induction as requested (by attributes) and also
+ for heuristically chosen quantifiers
+ 3 (default) - apply induction as requested, and for
+ heuristically chosen quantifiers and ghost methods
+ /inductionHeuristic: 0 - least discriminating induction heuristic (that is,
+ lean toward applying induction more often)
+ 1,2,3,4,5 - levels in between, ordered as follows as
+ far as how discriminating they are:
+ 0 < 1 < 2 < (3,4) < 5 < 6
+ 6 (default) - most discriminating
---- Boogie options --------------------------------------------------------
@@ -2164,10 +2126,11 @@ namespace Microsoft.Boogie {
1 - remove empty blocks (default)
/coalesceBlocks:<c> : 0 = do not coalesce blocks
1 = coalesce blocks (default)
- /vc:<variety> : n = nested block (default for non-/prover:z3),
+ /vc:<variety> : n = nested block (default for /prover:Simplify),
m = nested block reach,
b = flat block, r = flat block reach,
- s = structured, l = local, d = dag (default with /prover:z3)
+ s = structured, l = local,
+ d = dag (default, except with /prover:Simplify)
doomed = doomed
/traceverify : print debug output during verification condition generation
/subsumption:<c> : apply subsumption to asserted conditions:
@@ -2176,10 +2139,6 @@ namespace Microsoft.Boogie {
statement in that position) is ignored in checking contexts
(like other free things); this option includes these free
loop invariants as assumes in both contexts
- /bv:<bv> : bitvector handling
- n = none
- z = native Z3 bitvectors (default)
- i = unsoundly translate bitvectors to integers
/inline:<i> : use inlining strategy <i> for procedures with the :inline
attribute, see /attrHelp for details:
none
@@ -2261,17 +2220,17 @@ namespace Microsoft.Boogie {
1 (default) - include useful Trace labels in error output,
2 - include all Trace labels in the error output
/vcBrackets:<b> : bracket odd-charactered identifier names with |'s. <b> is:
- 0 - no (default with /prover:Z3),
+ 0 - no (default with non-/prover:Simplify),
1 - yes (default with /prover:Simplify)
/prover:<tp> : use theorem prover <tp>, where <tp> is either the name of
a DLL containing the prover interface located in the
Boogie directory, or a full path to a DLL containing such
an interface. The standard interfaces shipped include:
- Z3 (default)
- Simplify
- SMTLib (only writes to a file)
- ContractInference (uses Z3)
- Z3api (Z3 using Managed .NET API)
+ SMTLib (default, uses the SMTLib2 format and calls Z3)
+ Z3 (uses Z3 with the Simplify format)
+ Simplify
+ ContractInference (uses Z3)
+ Z3api (Z3 using Managed .NET API)
/proverOpt:KEY[=VALUE] : Provide a prover-specific option (short form /p).
/proverLog:<file> : Log input for the theorem prover. Like filenames
supplied as arguments to other options, <file> can use the
diff --git a/Source/Core/Inline.cs b/Source/Core/Inline.cs
index 802fd390..d9c33bd4 100644
--- a/Source/Core/Inline.cs
+++ b/Source/Core/Inline.cs
@@ -601,140 +601,4 @@ namespace Microsoft.Boogie {
}
}
} // end class CodeCopier
-
-
- public class AxiomExpander : Duplicator {
- readonly Program/*!*/ program;
- readonly TypecheckingContext/*!*/ tc;
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(program != null);
- Contract.Invariant(tc != null);
- }
-
-
- public AxiomExpander(Program prog, TypecheckingContext t) {
- Contract.Requires(t != null);
- Contract.Requires(prog != null);
- program = prog;
- tc = t;
- }
-
- public void CollectExpansions() {
- foreach (Declaration/*!*/ decl in program.TopLevelDeclarations) {
- Contract.Assert(decl != null);
- Axiom ax = decl as Axiom;
- if (ax != null) {
- bool expand = false;
- if (!ax.CheckBooleanAttribute("inline", ref expand)) {
- Error(decl.tok, "{:inline ...} expects either true or false as the argument");
- }
- if (expand) {
- AddExpansion(ax.Expr, ax.FindStringAttribute("ignore"));
- }
- }
- Function f = decl as Function;
- if (f != null && f.Body != null) {
- Variable[]/*!*/ formals = new Variable[f.InParams.Length];
- Contract.Assert(formals != null);
- for (int i = 0; i < formals.Length; ++i)
- formals[i] = f.InParams[i];
- AddExpansion(f, new Expansion(null, f.Body,
- new TypeVariableSeq(f.TypeParameters),
- formals));
- }
- }
- }
-
- void Error(IToken tok, string msg) {
- Contract.Requires(tok != null);
- tc.Error(tok, "expansion: " + msg);
- }
-
- void AddExpansion(Expr axiomBody, string ignore) {
- Contract.Requires(axiomBody != null);
- // it would be sooooooooo much easier with pattern matching
- ForallExpr all = axiomBody as ForallExpr;
- if (all != null) {
- NAryExpr nary = all.Body as NAryExpr;
- BinaryOperator bin = nary == null ? null : nary.Fun as BinaryOperator;
- //System.Console.WriteLine("{0} {1} {2}", nary==null, bin==null, bin==null?0 : bin.Op);
- if (nary != null && bin != null && (bin.Op == BinaryOperator.Opcode.Eq || bin.Op == BinaryOperator.Opcode.Iff)) {
-
- NAryExpr func = nary.Args[0] as NAryExpr;
- //System.Console.WriteLine("{0} {1}", func == null, func == null ? null : func.Fun.GetType());
- while (func != null && func.Fun is TypeCoercion)
- func = func.Args[0] as NAryExpr;
- if (func != null && func.Fun is FunctionCall) {
- Function fn = cce.NonNull((FunctionCall)func.Fun).Func;
- Expansion exp = new Expansion(ignore, cce.NonNull(nary.Args[1]),
- new TypeVariableSeq(),
- new Variable[func.Args.Length]);
- int pos = 0;
- HashSet<Declaration> parms = new HashSet<Declaration>();
- foreach (Expr/*!*/ e in func.Args) {
- Contract.Assert(e != null);
- IdentifierExpr id = e as IdentifierExpr;
- if (id == null) {
- Error(e.tok, "only identifiers supported as function arguments");
- return;
- }
- exp.formals[pos++] = id.Decl;
- if (parms.Contains(id.Decl)) {
- Error(all.tok, "an identifier was used more than once");
- return;
- }
- parms.Add(id.Decl);
- if (!all.Dummies.Has(id.Decl)) {
- Error(all.tok, "identifier was not quantified over");
- return;
- }
- }
- if (func.Args.Length != all.Dummies.Length) {
- Error(all.tok, "more variables quantified over, than used in function");
- return;
- }
-
- HashSet<TypeVariable/*!*/> typeVars = new HashSet<TypeVariable/*!*/>();
- foreach (TypeVariable/*!*/ v in cce.NonNull(func.TypeParameters).FormalTypeParams) {
- Contract.Assert(v != null);
- if (!func.TypeParameters[v].IsVariable) {
- Error(all.tok, "only identifiers supported as type parameters");
- return;
- }
- TypeVariable/*!*/ formal = func.TypeParameters[v].AsVariable;
- Contract.Assert(formal != null);
- exp.TypeParameters.Add(formal);
- if (typeVars.Contains(formal)) {
- Error(all.tok, "an identifier was used more than once");
- return;
- }
- typeVars.Add(formal);
- if (!all.TypeParameters.Has(formal)) {
- Error(all.tok, "identifier was not quantified over");
- return;
- }
- }
- if (((FunctionCall)func.Fun).Func.TypeParameters.Length != all.TypeParameters.Length) {
- Error(all.tok, "more variables quantified over, than used in function");
- return;
- }
- AddExpansion(fn, exp);
- return;
- }
- }
- }
-
- Error(axiomBody.tok, "axiom to be expanded must have form (forall VARS :: f(VARS) == expr(VARS))");
- }
-
- void AddExpansion(Function fn, Expansion x) {
- Contract.Requires(x != null);
- Contract.Requires(fn != null);
- if (fn.expansions == null) {
- fn.expansions = new List<Expansion/*!*/>();
- }
- fn.expansions.Add(x);
- }
- }
} // end namespace \ No newline at end of file
diff --git a/Source/Core/VCExp.cs b/Source/Core/VCExp.cs
index f6a976e5..6bc43e14 100644
--- a/Source/Core/VCExp.cs
+++ b/Source/Core/VCExp.cs
@@ -29,7 +29,6 @@ namespace Microsoft.Boogie {
public bool ForceLogStatus = false;
public int TimeLimit = 0;
public int MemoryLimit = 0;
- public CommandLineOptions.BvHandling BitVectors = CommandLineOptions.BvHandling.None;
public int Verbosity = 0;
public string ProverPath;
diff --git a/Source/Dafny/Compiler.cs b/Source/Dafny/Compiler.cs
index 47f5a98a..61b0398f 100644
--- a/Source/Dafny/Compiler.cs
+++ b/Source/Dafny/Compiler.cs
@@ -690,12 +690,6 @@ namespace Microsoft.Dafny {
CheckHasNoAssumes(s);
}
}
- } else if (stmt is ForeachStmt) {
- ForeachStmt s = (ForeachStmt)stmt;
- foreach (PredicateStmt t in s.BodyPrefix) {
- CheckHasNoAssumes(t);
- }
- CheckHasNoAssumes(s.GivenBody);
} else if (stmt is ParallelStmt) {
var s = (ParallelStmt)stmt;
CheckHasNoAssumes(s.Body);
@@ -773,50 +767,8 @@ namespace Microsoft.Dafny {
} else if (stmt is AssignStmt) {
AssignStmt s = (AssignStmt)stmt;
- if (s.Lhs is SeqSelectExpr && !((SeqSelectExpr)s.Lhs).SelectOne) {
- SeqSelectExpr sel = (SeqSelectExpr)s.Lhs;
- if (!(s.Rhs is HavocRhs)) {
- // Generate the following:
- // tmpArr = sel.Seq;
- // tmpLow = sel.E0; // or 0 if sel.E0==null
- // tmpHigh = sel.Eq; // or arr.Length if sel.E1==null
- // tmpRhs = s.Rhs;
- // for (int tmpI = tmpLow; tmpI < tmpHigh; tmpI++) {
- // tmpArr[tmpI] = tmpRhs;
- // }
- string arr = "_arr" + tmpVarCount;
- string low = "_low" + tmpVarCount;
- string high = "_high" + tmpVarCount;
- string rhs = "_rhs" + tmpVarCount;
- string i = "_i" + tmpVarCount;
- tmpVarCount++;
- Indent(indent); wr.Write("{0} {1} = ", TypeName(cce.NonNull(sel.Seq.Type)), arr); TrExpr(sel.Seq); wr.WriteLine(";");
- Indent(indent); wr.Write("int {0} = ", low);
- if (sel.E0 == null) {
- wr.Write("0");
- } else {
- TrExpr(sel.E0);
- }
- wr.WriteLine(";");
- Indent(indent); wr.Write("int {0} = ", high);
- if (sel.E1 == null) {
- wr.Write("new BigInteger(arr.Length)");
- } else {
- TrExpr(sel.E1);
- }
- wr.WriteLine(";");
- Indent(indent); wr.Write("{0} {1} = ", TypeName(cce.NonNull(sel.Type)), rhs); TrAssignmentRhs(s.Rhs); wr.WriteLine(";");
- Indent(indent);
- wr.WriteLine("for (BigInteger {0} = {1}; {0} < {2}; {0}++) {{", i, low, high);
- Indent(indent + IndentAmount);
- wr.WriteLine("{0}[(int)({1})] = {2};", arr, i, rhs);
- Indent(indent);
- wr.WriteLine(";");
- }
-
- } else {
- TrRhs(null, s.Lhs, s.Rhs, indent);
- }
+ Contract.Assert(!(s.Lhs is SeqSelectExpr) || ((SeqSelectExpr)s.Lhs).SelectOne); // multi-element array assignments are not allowed
+ TrRhs(null, s.Lhs, s.Rhs, indent);
} else if (stmt is VarDecl) {
TrVarDecl((VarDecl)stmt, true, indent);
@@ -895,61 +847,179 @@ namespace Microsoft.Dafny {
} else if (stmt is ParallelStmt) {
var s = (ParallelStmt)stmt;
- Error("parallel statements are not yet supported by the Dafny compiler; stay tuned");
- // TODO
-
- } else if (stmt is ForeachStmt) {
- ForeachStmt s = (ForeachStmt)stmt;
- // List<Pair<TType,RhsType>> pendingUpdates = new List<Pair<TType,RhsType>>();
- // foreach (TType x in S) {
- // if (Range(x)) {
- // assert/assume ...;
- // pendingUpdates.Add(new Pair(x,RHS));
+ if (s.Kind != ParallelStmt.ParBodyKind.Assign) {
+ // Call and Proof have no side effects, so they can simply be optimized away.
+ return;
+ }
+ var s0 = (AssignStmt)s.S0;
+ if (s0.Rhs is HavocRhs) {
+ // The parallel statement says to havoc a bunch of things. This can be efficiently compiled
+ // into doing nothing.
+ return;
+ }
+ var rhs = ((ExprRhs)s0.Rhs).Expr;
+
+ // Compile:
+ // parallel (w,x,y,z | Range(w,x,y,z)) {
+ // LHS(w,x,y,z) := RHS(w,x,y,z);
// }
- // }
- // foreach (Pair<TType,RhsType> p in pendingUpdates) {
- // p.Car.m = p.Cdr;
- // }
- string pu = "_pendingUpdates" + tmpVarCount;
- string pr = "_pair" + tmpVarCount;
+ // where w,x,y,z have types seq<W>,set<X>,int,bool and LHS has L-1 top-level subexpressions
+ // (that is, L denotes the number of top-level subexpressions of LHS plus 1),
+ // into:
+ // var ingredients = new List< L-Tuple >();
+ // foreach (W w in sq.UniqueElements) {
+ // foreach (X x in st.Elements) {
+ // for (BigInteger y = Lo; j < Hi; j++) {
+ // for (bool z in Helper.AllBooleans) {
+ // if (Range(w,x,y,z)) {
+ // ingredients.Add(new L-Tuple( LHS0(w,x,y,z), LHS1(w,x,y,z), ..., RHS(w,x,y,z) ));
+ // }
+ // }
+ // }
+ // }
+ // }
+ // foreach (L-Tuple l in ingredients) {
+ // LHS[ l0, l1, l2, ..., l(L-2) ] = l(L-1);
+ // }
+ //
+ // Note, because the .NET Tuple class only supports up to 8 components, the compiler implementation
+ // here supports arrays only up to 6 dimensions. This does not seem like a serious practical limitation.
+ // However, it may be more noticeable if the parallel statement supported parallel assignments in its
+ // body. To support cases where tuples would need more than 8 components, .NET Tuple's would have to
+ // be nested.
+
+ // Temporary names
+ string ingredients = "_ingredients" + tmpVarCount;
+ string tup = "_tup" + tmpVarCount;
tmpVarCount++;
- string TType = TypeName(s.BoundVar.Type);
- string RhsType = TypeName(cce.NonNull(s.BodyAssign.Lhs.Type));
- Indent(indent);
- wr.WriteLine("List<Pair<{0},{1}>> {2} = new List<Pair<{0},{1}>>();", TType, RhsType, pu);
+ // Compute L
+ int L;
+ string tupleTypeArgs;
+ if (s0.Lhs is FieldSelectExpr) {
+ var lhs = (FieldSelectExpr)s0.Lhs;
+ L = 2;
+ tupleTypeArgs = TypeName(lhs.Obj.Type);
+ } else if (s0.Lhs is SeqSelectExpr) {
+ var lhs = (SeqSelectExpr)s0.Lhs;
+ L = 3;
+ // note, we might as well do the BigInteger-to-int cast for array indices here, before putting things into the Tuple rather than when they are extracted from the Tuple
+ tupleTypeArgs = TypeName(lhs.Seq.Type) + ",int";
+ } else {
+ var lhs = (MultiSelectExpr)s0.Lhs;
+ L = 2 + lhs.Indices.Count;
+ if (8 < L) {
+ Error("compiler currently does not support assignments to more-than-6-dimensional arrays in parallel statements");
+ return;
+ }
+ tupleTypeArgs = TypeName(lhs.Array.Type);
+ for (int i = 0; i < lhs.Indices.Count; i++) {
+ // note, we might as well do the BigInteger-to-int cast for array indices here, before putting things into the Tuple rather than when they are extracted from the Tuple
+ tupleTypeArgs += ",int";
+ }
+ }
+ tupleTypeArgs += "," + TypeName(rhs.Type);
+ // declare and construct "ingredients"
Indent(indent);
- wr.Write("foreach ({0} @{1} in (", TType, s.BoundVar.Name);
- TrExpr(s.Collection);
- wr.WriteLine(").Elements) {");
+ wr.WriteLine("var {0} = new List<System.Tuple<{1}>>();", ingredients, tupleTypeArgs);
- Indent(indent + IndentAmount);
- wr.Write("if (");
- TrExpr(s.Range);
- wr.WriteLine(") {");
-
- foreach (PredicateStmt p in s.BodyPrefix) {
- TrStmt(p, indent + 2*IndentAmount);
+ var n = s.BoundVars.Count;
+ Contract.Assert(s.Bounds.Count == n);
+ for (int i = 0; i < n; i++) {
+ Indent(indent + i * IndentAmount);
+ var bound = s.Bounds[i];
+ var bv = s.BoundVars[i];
+ if (bound is QuantifierExpr.BoolBoundedPool) {
+ wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.Name);
+ } else if (bound is QuantifierExpr.IntBoundedPool) {
+ var b = (QuantifierExpr.IntBoundedPool)bound;
+ wr.Write("for (var @{0} = ", bv.Name);
+ TrExpr(b.LowerBound);
+ wr.Write("; @{0} < ", bv.Name);
+ TrExpr(b.UpperBound);
+ wr.Write("; @{0}++) {{ ", bv.Name);
+ } else if (bound is QuantifierExpr.SetBoundedPool) {
+ var b = (QuantifierExpr.SetBoundedPool)bound;
+ wr.Write("foreach (var @{0} in (", bv.Name);
+ TrExpr(b.Set);
+ wr.Write(").Elements) { ");
+ } else if (bound is QuantifierExpr.SeqBoundedPool) {
+ var b = (QuantifierExpr.SeqBoundedPool)bound;
+ wr.Write("foreach (var @{0} in (", bv.Name);
+ TrExpr(b.Seq);
+ wr.Write(").UniqueElements) { ");
+ } else {
+ Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
+ }
+ wr.WriteLine();
}
- Indent(indent + 2*IndentAmount);
- wr.Write("{0}.Add(new Pair<{1},{2}>(@{3}, ", pu, TType, RhsType, s.BoundVar.Name);
- ExprRhs rhsExpr = s.BodyAssign.Rhs as ExprRhs;
- if (rhsExpr != null) {
- TrExpr(rhsExpr.Expr);
+
+ // if (range) {
+ // ingredients.Add(new L-Tuple( LHS0(w,x,y,z), LHS1(w,x,y,z), ..., RHS(w,x,y,z) ));
+ // }
+ Indent(indent + n * IndentAmount);
+ wr.Write("if ");
+ TrParenExpr(s.Range);
+ wr.WriteLine(" {");
+
+ Indent(indent + (n + 1) * IndentAmount);
+ wr.Write("{0}.Add(new System.Tuple<{1}>(", ingredients, tupleTypeArgs);
+ if (s0.Lhs is FieldSelectExpr) {
+ var lhs = (FieldSelectExpr)s0.Lhs;
+ TrExpr(lhs.Obj);
+ } else if (s0.Lhs is SeqSelectExpr) {
+ var lhs = (SeqSelectExpr)s0.Lhs;
+ TrExpr(lhs.Seq);
+ wr.Write(", (int)(");
+ TrExpr(lhs.E0);
+ wr.Write(")");
} else {
- wr.Write(DefaultValue(s.BodyAssign.Lhs.Type));
+ var lhs = (MultiSelectExpr)s0.Lhs;
+ TrExpr(lhs.Array);
+ for (int i = 0; i < lhs.Indices.Count; i++) {
+ wr.Write(", (int)(");
+ TrExpr(lhs.Indices[i]);
+ wr.Write(")");
+ }
+ wr.WriteLine("] = {0}.Item{1};", tup, L);
}
- wr.WriteLine("))");
+ wr.Write(", ");
+ TrExpr(rhs);
+ wr.WriteLine("));");
- Indent(indent + IndentAmount); wr.WriteLine("}");
- Indent(indent); wr.WriteLine("}");
+ Indent(indent + n * IndentAmount);
+ wr.WriteLine("}");
- Indent(indent); wr.WriteLine("foreach (Pair<{0},{1}> {2} in {3}) {{", TType, RhsType, pr, pu);
+ for (int i = n; 0 <= --i; ) {
+ Indent(indent + i * IndentAmount);
+ wr.WriteLine("}");
+ }
+
+ // foreach (L-Tuple l in ingredients) {
+ // LHS[ l0, l1, l2, ..., l(L-2) ] = l(L-1);
+ // }
+ Indent(indent);
+ wr.WriteLine("foreach (var {0} in {1}) {{", tup, ingredients);
Indent(indent + IndentAmount);
- FieldSelectExpr fse = (FieldSelectExpr)s.BodyAssign.Lhs;
- wr.WriteLine("{0}.Car.{1} = {0}.Cdr;", pr, fse.FieldName);
- Indent(indent); wr.WriteLine("}");
+ if (s0.Lhs is FieldSelectExpr) {
+ var lhs = (FieldSelectExpr)s0.Lhs;
+ wr.WriteLine("{0}.Item1.@{1} = {0}.Item2;", tup, lhs.FieldName);
+ } else if (s0.Lhs is SeqSelectExpr) {
+ var lhs = (SeqSelectExpr)s0.Lhs;
+ wr.WriteLine("{0}.Item1[{0}.Item2] = {0}.Item3;", tup);
+ } else {
+ var lhs = (MultiSelectExpr)s0.Lhs;
+ wr.Write("{0}.Item1[");
+ string sep = "";
+ for (int i = 0; i < lhs.Indices.Count; i++) {
+ wr.Write("{0}{1}.Item{2}", sep, tup, i + 2);
+ sep = ", ";
+ }
+ wr.WriteLine("] = {0}.Item{1};", tup, L);
+ }
+ Indent(indent);
+ wr.WriteLine("}");
} else if (stmt is MatchStmt) {
MatchStmt s = (MatchStmt)stmt;
diff --git a/Source/Dafny/Dafny.atg b/Source/Dafny/Dafny.atg
index 0092b4d9..fa857aad 100644
--- a/Source/Dafny/Dafny.atg
+++ b/Source/Dafny/Dafny.atg
@@ -631,7 +631,6 @@ OneStmt<out Statement/*!*/ s>
| IfStmt<out s>
| WhileStmt<out s>
| MatchStmt<out s>
- | ForeachStmt<out s>
| ParallelStmt<out s>
| "label" (. x = t; .)
Ident<out id> ":"
@@ -886,36 +885,7 @@ CaseStatement<out MatchCaseStmt/*!*/ c>
(. c = new MatchCaseStmt(x, id.val, arguments, body); .)
.
/*------------------------------------------------------------------------*/
-ForeachStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- IToken/*!*/ x, boundVar;
- Type/*!*/ ty;
- Expression/*!*/ collection;
- Expression/*!*/ range;
- List<PredicateStmt/*!*/> bodyPrefix = new List<PredicateStmt/*!*/>();
- Statement bodyAssign = null;
- .)
- "foreach" (. x = t;
- range = new LiteralExpr(x, true);
- ty = new InferredTypeProxy();
- .)
- "(" Ident<out boundVar>
- [ ":" Type<out ty> ]
- "in" Expression<out collection>
- [ "|" Expression<out range> ]
- ")"
- "{"
- { AssertStmt<out s> (. if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); } .)
- | AssumeStmt<out s> (. if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); } .)
- }
- UpdateStmt<out s> (. bodyAssign = s; .)
- "}" (. if (bodyAssign != null) {
- s = new ForeachStmt(x, new BoundVar(boundVar, boundVar.val, ty), collection, range, bodyPrefix, bodyAssign);
- } else {
- s = dummyStmt; // some error occurred in parsing the bodyAssign
- }
- .)
- .
+
AssertStmt<out Statement/*!*/ s>
= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e; .)
"assert" (. x = t; .)
@@ -952,6 +922,7 @@ ParallelStmt<out Statement/*!*/ s>
"parallel" (. x = t; .)
"("
QuantifierDomain<out bvars, out attrs, out range>
+ (. if (range == null) { range = new LiteralExpr(x, true); } .)
")"
{ (. isFree = false; .)
[ "free" (. isFree = true; .)
diff --git a/Source/Dafny/DafnyAst.cs b/Source/Dafny/DafnyAst.cs
index d9d5c486..bf8eb6b0 100644
--- a/Source/Dafny/DafnyAst.cs
+++ b/Source/Dafny/DafnyAst.cs
@@ -1040,6 +1040,19 @@ namespace Microsoft.Dafny {
}
}
+ /// <summary>
+ /// A "ThisSurrogate" is used during translation time to make the treatment of the receiver more similar to
+ /// the treatment of other in-parameters.
+ /// </summary>
+ public class ThisSurrogate : Formal
+ {
+ public ThisSurrogate(IToken tok, Type type)
+ : base(tok, "this", type, true, false) {
+ Contract.Requires(tok != null);
+ Contract.Requires(type != null);
+ }
+ }
+
public class BoundVar : NonglobalVariable {
public override bool IsMutable {
get {
@@ -1753,40 +1766,6 @@ namespace Microsoft.Dafny {
}
}
- public class ForeachStmt : Statement
- {
- public readonly BoundVar/*!*/ BoundVar;
- public readonly Expression/*!*/ Collection;
- public readonly Expression/*!*/ Range;
- public readonly List<PredicateStmt/*!*/>/*!*/ BodyPrefix;
- public readonly Statement GivenBody; // used only until resolution; afterwards, use BodyAssign
- public AssignStmt/*!*/ BodyAssign; // filled in during resolution
- [ContractInvariantMethod]
- void ObjectInvariant() {
- Contract.Invariant(BoundVar != null);
- Contract.Invariant(Collection != null);
- Contract.Invariant(Range != null);
- Contract.Invariant(cce.NonNullElements(BodyPrefix));
- Contract.Invariant(GivenBody != null);
- }
-
- public ForeachStmt(IToken tok, BoundVar boundVar, Expression collection, Expression range,
- List<PredicateStmt/*!*/>/*!*/ bodyPrefix, Statement givenBody)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(boundVar != null);
- Contract.Requires(collection != null);
- Contract.Requires(range != null);
- Contract.Requires(cce.NonNullElements(bodyPrefix));
- Contract.Requires(givenBody != null);
- this.BoundVar = boundVar;
- this.Collection = collection;
- this.Range = range;
- this.BodyPrefix = bodyPrefix;
- this.GivenBody = givenBody;
- }
- }
-
public class ParallelStmt : Statement
{
public readonly List<BoundVar/*!*/> BoundVars;
@@ -2043,7 +2022,6 @@ namespace Microsoft.Dafny {
: base(tok) { // represents the Dafny literal "null"
Contract.Requires(tok != null);
this.Value = null;
-
}
public LiteralExpr(IToken tok, BigInteger n)
@@ -2052,7 +2030,6 @@ namespace Microsoft.Dafny {
Contract.Requires(0 <= n.Sign);
this.Value = n;
-
}
public LiteralExpr(IToken tok, int n) :base(tok){
@@ -2331,7 +2308,9 @@ namespace Microsoft.Dafny {
public override IEnumerable<Expression> SubExpressions {
get {
- yield return Receiver;
+ if (!Function.IsStatic) {
+ yield return Receiver;
+ }
foreach (var e in Args) {
yield return e;
}
diff --git a/Source/Dafny/Parser.cs b/Source/Dafny/Parser.cs
index 483217e5..2fc50c37 100644
--- a/Source/Dafny/Parser.cs
+++ b/Source/Dafny/Parser.cs
@@ -18,12 +18,12 @@ public class Parser {
public const int _digits = 2;
public const int _arrayToken = 3;
public const int _string = 4;
- public const int maxT = 105;
+ public const int maxT = 104;
const bool T = true;
const bool x = false;
const int minErrDist = 2;
-
+
public Scanner/*!*/ scanner;
public Errors/*!*/ errors;
@@ -134,10 +134,10 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
if (errDist >= minErrDist) errors.SemErr(t, msg);
errDist = 0;
}
-
- public void SemErr(IToken/*!*/ tok, string/*!*/ msg) {
- Contract.Requires(tok != null);
- Contract.Requires(msg != null);
+
+ public void SemErr(IToken/*!*/ tok, string/*!*/ msg) {
+ Contract.Requires(tok != null);
+ Contract.Requires(msg != null);
errors.SemErr(tok, msg);
}
@@ -150,15 +150,15 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
la = t;
}
}
-
+
void Expect (int n) {
if (la.kind==n) Get(); else { SynErr(n); }
}
-
+
bool StartOf (int s) {
return set[s, la.kind];
}
-
+
void ExpectWeak (int n, int follow) {
if (la.kind == n) Get();
else {
@@ -182,7 +182,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
}
}
-
+
void Dafny() {
ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt;
Attributes attrs; IToken/*!*/ id; List<string/*!*/> theImports;
@@ -375,7 +375,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
mm.Add(m);
} else if (la.kind == 20) {
CouplingInvDecl(mmod, mm);
- } else SynErr(106);
+ } else SynErr(105);
}
void GenericParameters(List<TypeParameter/*!*/>/*!*/ typeArgs) {
@@ -490,7 +490,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
} else if (la.kind == 10) {
Get();
isRefinement = true;
- } else SynErr(107);
+ } else SynErr(106);
if (mmod.IsUnlimited) { SemErr(t, "methods cannot be declared 'unlimited'"); }
if (isConstructor) {
if (mmod.IsGhost) {
@@ -728,7 +728,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
ReferenceType(out tok, out ty);
break;
}
- default: SynErr(108); break;
+ default: SynErr(107); break;
}
}
@@ -779,12 +779,12 @@ List<Expression/*!*/>/*!*/ decreases) {
Expression(out e);
Expect(17);
ens.Add(new MaybeFreeExpression(e, isFree));
- } else SynErr(109);
+ } else SynErr(108);
} else if (la.kind == 32) {
Get();
DecreasesList(decreases, false);
Expect(17);
- } else SynErr(110);
+ } else SynErr(109);
}
void BlockStmt(out Statement/*!*/ block, out IToken bodyStart, out IToken bodyEnd) {
@@ -874,7 +874,7 @@ List<Expression/*!*/>/*!*/ decreases) {
GenericInstantiation(gt);
}
ty = new UserDefinedType(tok, tok.val, gt);
- } else SynErr(111);
+ } else SynErr(110);
}
void FunctionSpec(List<Expression/*!*/>/*!*/ reqs, List<FrameExpression/*!*/>/*!*/ reads, List<Expression/*!*/>/*!*/ ens, List<Expression/*!*/>/*!*/ decreases) {
@@ -906,7 +906,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Get();
DecreasesList(decreases, false);
Expect(17);
- } else SynErr(112);
+ } else SynErr(111);
}
void FunctionBody(out Expression/*!*/ e, out IToken bodyStart, out IToken bodyEnd) {
@@ -925,7 +925,7 @@ List<Expression/*!*/>/*!*/ decreases) {
fe = new FrameExpression(new WildcardExpr(t), null);
} else if (StartOf(6)) {
FrameExpression(out fe);
- } else SynErr(113);
+ } else SynErr(112);
}
void PossiblyWildExpression(out Expression/*!*/ e) {
@@ -936,7 +936,7 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new WildcardExpr(t);
} else if (StartOf(6)) {
Expression(out e);
- } else SynErr(114);
+ } else SynErr(113);
}
void Stmt(List<Statement/*!*/>/*!*/ ss) {
@@ -957,19 +957,19 @@ List<Expression/*!*/>/*!*/ decreases) {
BlockStmt(out s, out bodyStart, out bodyEnd);
break;
}
- case 64: {
+ case 62: {
AssertStmt(out s);
break;
}
- case 65: {
+ case 63: {
AssumeStmt(out s);
break;
}
- case 66: {
+ case 64: {
PrintStmt(out s);
break;
}
- case 1: case 2: case 16: case 33: case 90: case 91: case 92: case 93: case 94: case 95: case 96: {
+ case 1: case 2: case 16: case 33: case 89: case 90: case 91: case 92: case 93: case 94: case 95: {
UpdateStmt(out s);
break;
}
@@ -989,11 +989,7 @@ List<Expression/*!*/>/*!*/ decreases) {
MatchStmt(out s);
break;
}
- case 62: {
- ForeachStmt(out s);
- break;
- }
- case 67: {
+ case 65: {
ParallelStmt(out s);
break;
}
@@ -1017,7 +1013,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Get();
breakCount++;
}
- } else SynErr(115);
+ } else SynErr(114);
Expect(17);
s = label != null ? new BreakStmt(x, label) : new BreakStmt(x, breakCount);
break;
@@ -1026,13 +1022,13 @@ List<Expression/*!*/>/*!*/ decreases) {
ReturnStmt(out s);
break;
}
- default: SynErr(116); break;
+ default: SynErr(115); break;
}
}
void AssertStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e;
- Expect(64);
+ Expect(62);
x = t;
Expression(out e);
Expect(17);
@@ -1041,7 +1037,7 @@ List<Expression/*!*/>/*!*/ decreases) {
void AssumeStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e;
- Expect(65);
+ Expect(63);
x = t;
Expression(out e);
Expect(17);
@@ -1052,7 +1048,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Attributes.Argument/*!*/ arg;
List<Attributes.Argument/*!*/> args = new List<Attributes.Argument/*!*/>();
- Expect(66);
+ Expect(64);
x = t;
AttributeArg(out arg);
args.Add(arg);
@@ -1097,7 +1093,7 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (la.kind == 22) {
Get();
SemErr(t, "invalid statement (did you forget the 'label' keyword?)");
- } else SynErr(117);
+ } else SynErr(116);
s = new UpdateStmt(x, lhss, rhss);
}
@@ -1170,13 +1166,13 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (la.kind == 7) {
BlockStmt(out s, out bodyStart, out bodyEnd);
els = s;
- } else SynErr(118);
+ } else SynErr(117);
}
ifStmt = new IfStmt(x, guard, thn, els);
} else if (la.kind == 7) {
AlternativeBlock(out alternatives);
ifStmt = new AlternativeStmt(x, alternatives);
- } else SynErr(119);
+ } else SynErr(118);
}
void WhileStmt(out Statement/*!*/ stmt) {
@@ -1202,7 +1198,7 @@ List<Expression/*!*/>/*!*/ decreases) {
LoopSpec(out invariants, out decreases, out mod);
AlternativeBlock(out alternatives);
stmt = new AlternativeLoopStmt(x, invariants, decreases, mod, alternatives);
- } else SynErr(120);
+ } else SynErr(119);
}
void MatchStmt(out Statement/*!*/ s) {
@@ -1221,54 +1217,6 @@ List<Expression/*!*/>/*!*/ decreases) {
s = new MatchStmt(x, e, cases);
}
- void ForeachStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null);
- IToken/*!*/ x, boundVar;
- Type/*!*/ ty;
- Expression/*!*/ collection;
- Expression/*!*/ range;
- List<PredicateStmt/*!*/> bodyPrefix = new List<PredicateStmt/*!*/>();
- Statement bodyAssign = null;
-
- Expect(62);
- x = t;
- range = new LiteralExpr(x, true);
- ty = new InferredTypeProxy();
-
- Expect(33);
- Ident(out boundVar);
- if (la.kind == 22) {
- Get();
- Type(out ty);
- }
- Expect(63);
- Expression(out collection);
- if (la.kind == 16) {
- Get();
- Expression(out range);
- }
- Expect(34);
- Expect(7);
- while (la.kind == 64 || la.kind == 65) {
- if (la.kind == 64) {
- AssertStmt(out s);
- if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); }
- } else {
- AssumeStmt(out s);
- if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); }
- }
- }
- UpdateStmt(out s);
- bodyAssign = s;
- Expect(8);
- if (bodyAssign != null) {
- s = new ForeachStmt(x, new BoundVar(boundVar, boundVar.val, ty), collection, range, bodyPrefix, bodyAssign);
- } else {
- s = dummyStmt; // some error occurred in parsing the bodyAssign
- }
-
- }
-
void ParallelStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null);
IToken/*!*/ x;
@@ -1281,10 +1229,11 @@ List<Expression/*!*/>/*!*/ decreases) {
Statement/*!*/ block;
IToken bodyStart, bodyEnd;
- Expect(67);
+ Expect(65);
x = t;
Expect(33);
QuantifierDomain(out bvars, out attrs, out range);
+ if (range == null) { range = new LiteralExpr(x, true); }
Expect(34);
while (la.kind == 29 || la.kind == 31) {
isFree = false;
@@ -1371,7 +1320,7 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (StartOf(6)) {
Expression(out e);
r = new ExprRhs(e);
- } else SynErr(121);
+ } else SynErr(120);
}
void Lhs(out Expression e) {
@@ -1388,7 +1337,7 @@ List<Expression/*!*/>/*!*/ decreases) {
while (la.kind == 51 || la.kind == 53) {
Suffix(ref e);
}
- } else SynErr(122);
+ } else SynErr(121);
}
void Expressions(List<Expression/*!*/>/*!*/ args) {
@@ -1411,7 +1360,7 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (StartOf(6)) {
Expression(out ee);
e = ee;
- } else SynErr(123);
+ } else SynErr(122);
Expect(34);
}
@@ -1510,7 +1459,7 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (StartOf(6)) {
Expression(out e);
arg = new Attributes.Argument(t, e);
- } else SynErr(124);
+ } else SynErr(123);
}
void QuantifierDomain(out List<BoundVar/*!*/> bvars, out Attributes attrs, out Expression range) {
@@ -1538,7 +1487,7 @@ List<Expression/*!*/>/*!*/ decreases) {
void EquivExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
ImpliesExpression(out e0);
- while (la.kind == 68 || la.kind == 69) {
+ while (la.kind == 66 || la.kind == 67) {
EquivOp();
x = t;
ImpliesExpression(out e1);
@@ -1549,7 +1498,7 @@ List<Expression/*!*/>/*!*/ decreases) {
void ImpliesExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
LogicalExpression(out e0);
- if (la.kind == 70 || la.kind == 71) {
+ if (la.kind == 68 || la.kind == 69) {
ImpliesOp();
x = t;
ImpliesExpression(out e1);
@@ -1558,23 +1507,23 @@ List<Expression/*!*/>/*!*/ decreases) {
}
void EquivOp() {
- if (la.kind == 68) {
+ if (la.kind == 66) {
Get();
- } else if (la.kind == 69) {
+ } else if (la.kind == 67) {
Get();
- } else SynErr(125);
+ } else SynErr(124);
}
void LogicalExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
RelationalExpression(out e0);
if (StartOf(13)) {
- if (la.kind == 72 || la.kind == 73) {
+ if (la.kind == 70 || la.kind == 71) {
AndOp();
x = t;
RelationalExpression(out e1);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1);
- while (la.kind == 72 || la.kind == 73) {
+ while (la.kind == 70 || la.kind == 71) {
AndOp();
x = t;
RelationalExpression(out e1);
@@ -1585,7 +1534,7 @@ List<Expression/*!*/>/*!*/ decreases) {
x = t;
RelationalExpression(out e1);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1);
- while (la.kind == 74 || la.kind == 75) {
+ while (la.kind == 72 || la.kind == 73) {
OrOp();
x = t;
RelationalExpression(out e1);
@@ -1596,11 +1545,11 @@ List<Expression/*!*/>/*!*/ decreases) {
}
void ImpliesOp() {
- if (la.kind == 70) {
+ if (la.kind == 68) {
Get();
- } else if (la.kind == 71) {
+ } else if (la.kind == 69) {
Get();
- } else SynErr(126);
+ } else SynErr(125);
}
void RelationalExpression(out Expression/*!*/ e) {
@@ -1694,25 +1643,25 @@ List<Expression/*!*/>/*!*/ decreases) {
}
void AndOp() {
- if (la.kind == 72) {
+ if (la.kind == 70) {
Get();
- } else if (la.kind == 73) {
+ } else if (la.kind == 71) {
Get();
- } else SynErr(127);
+ } else SynErr(126);
}
void OrOp() {
- if (la.kind == 74) {
+ if (la.kind == 72) {
Get();
- } else if (la.kind == 75) {
+ } else if (la.kind == 73) {
Get();
- } else SynErr(128);
+ } else SynErr(127);
}
void Term(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
Factor(out e0);
- while (la.kind == 85 || la.kind == 86) {
+ while (la.kind == 84 || la.kind == 85) {
AddOp(out x, out op);
Factor(out e1);
e0 = new BinaryExpr(x, op, e0, e1);
@@ -1725,7 +1674,7 @@ List<Expression/*!*/>/*!*/ decreases) {
IToken y;
switch (la.kind) {
- case 76: {
+ case 74: {
Get();
x = t; op = BinaryExpr.Opcode.Eq;
break;
@@ -1740,35 +1689,35 @@ List<Expression/*!*/>/*!*/ decreases) {
x = t; op = BinaryExpr.Opcode.Gt;
break;
}
- case 77: {
+ case 75: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 78: {
+ case 76: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- case 79: {
+ case 77: {
Get();
x = t; op = BinaryExpr.Opcode.Neq;
break;
}
- case 80: {
+ case 78: {
Get();
x = t; op = BinaryExpr.Opcode.Disjoint;
break;
}
- case 63: {
+ case 79: {
Get();
x = t; op = BinaryExpr.Opcode.In;
break;
}
- case 81: {
+ case 80: {
Get();
x = t; y = Token.NoToken;
- if (la.kind == 63) {
+ if (la.kind == 79) {
Get();
y = t;
}
@@ -1783,29 +1732,29 @@ List<Expression/*!*/>/*!*/ decreases) {
break;
}
- case 82: {
+ case 81: {
Get();
x = t; op = BinaryExpr.Opcode.Neq;
break;
}
- case 83: {
+ case 82: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 84: {
+ case 83: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- default: SynErr(129); break;
+ default: SynErr(128); break;
}
}
void Factor(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
UnaryExpression(out e0);
- while (la.kind == 44 || la.kind == 87 || la.kind == 88) {
+ while (la.kind == 44 || la.kind == 86 || la.kind == 87) {
MulOp(out x, out op);
UnaryExpression(out e1);
e0 = new BinaryExpr(x, op, e0, e1);
@@ -1814,33 +1763,33 @@ List<Expression/*!*/>/*!*/ decreases) {
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 == 85) {
+ if (la.kind == 84) {
Get();
x = t; op = BinaryExpr.Opcode.Add;
- } else if (la.kind == 86) {
+ } else if (la.kind == 85) {
Get();
x = t; op = BinaryExpr.Opcode.Sub;
- } else SynErr(130);
+ } else SynErr(129);
}
void UnaryExpression(out Expression/*!*/ e) {
Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr;
switch (la.kind) {
- case 86: {
+ case 85: {
Get();
x = t;
UnaryExpression(out e);
e = new BinaryExpr(x, BinaryExpr.Opcode.Sub, new LiteralExpr(x, 0), e);
break;
}
- case 81: case 89: {
+ case 80: case 88: {
NegOp();
x = t;
UnaryExpression(out e);
e = new UnaryExpr(x, UnaryExpr.Opcode.Not, e);
break;
}
- case 38: case 55: case 61: case 99: case 100: case 101: case 102: {
+ case 38: case 55: case 61: case 98: case 99: case 100: case 101: {
EndlessExpression(out e);
break;
}
@@ -1859,14 +1808,14 @@ List<Expression/*!*/>/*!*/ decreases) {
MultiSetExpr(out e);
break;
}
- case 2: case 16: case 33: case 90: case 91: case 92: case 93: case 94: case 95: case 96: {
+ case 2: case 16: case 33: case 89: case 90: case 91: case 92: case 93: case 94: case 95: {
ConstAtomExpression(out e);
while (la.kind == 51 || la.kind == 53) {
Suffix(ref e);
}
break;
}
- default: SynErr(131); break;
+ default: SynErr(130); break;
}
}
@@ -1875,21 +1824,21 @@ List<Expression/*!*/>/*!*/ decreases) {
if (la.kind == 44) {
Get();
x = t; op = BinaryExpr.Opcode.Mul;
- } else if (la.kind == 87) {
+ } else if (la.kind == 86) {
Get();
x = t; op = BinaryExpr.Opcode.Div;
- } else if (la.kind == 88) {
+ } else if (la.kind == 87) {
Get();
x = t; op = BinaryExpr.Opcode.Mod;
- } else SynErr(132);
+ } else SynErr(131);
}
void NegOp() {
- if (la.kind == 81) {
+ if (la.kind == 80) {
Get();
- } else if (la.kind == 89) {
+ } else if (la.kind == 88) {
Get();
- } else SynErr(133);
+ } else SynErr(132);
}
void EndlessExpression(out Expression e) {
@@ -1901,7 +1850,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Get();
x = t;
Expression(out e);
- Expect(97);
+ Expect(96);
Expression(out e0);
Expect(56);
Expression(out e1);
@@ -1912,7 +1861,7 @@ List<Expression/*!*/>/*!*/ decreases) {
QuantifierGuts(out e);
} else if (la.kind == 38) {
ComprehensionExpr(out e);
- } else SynErr(134);
+ } else SynErr(133);
}
void DottedIdentifiersAndFunction(out Expression e) {
@@ -1963,7 +1912,7 @@ List<Expression/*!*/>/*!*/ decreases) {
if (StartOf(6)) {
Expression(out ee);
e0 = ee;
- if (la.kind == 98) {
+ if (la.kind == 97) {
Get();
anyDots = true;
if (StartOf(6)) {
@@ -1985,15 +1934,15 @@ List<Expression/*!*/>/*!*/ decreases) {
multipleIndices.Add(ee);
}
- } else SynErr(135);
- } else if (la.kind == 98) {
+ } else SynErr(134);
+ } else if (la.kind == 97) {
Get();
anyDots = true;
if (StartOf(6)) {
Expression(out ee);
e1 = ee;
}
- } else SynErr(136);
+ } else SynErr(135);
if (multipleIndices != null) {
e = new MultiSelectExpr(x, e, multipleIndices);
// make sure an array class with this dimensionality exists
@@ -2017,7 +1966,7 @@ List<Expression/*!*/>/*!*/ decreases) {
}
Expect(52);
- } else SynErr(137);
+ } else SynErr(136);
}
void DisplayExpr(out Expression e) {
@@ -2041,7 +1990,7 @@ List<Expression/*!*/>/*!*/ decreases) {
}
e = new SeqDisplayExpr(x, elements);
Expect(52);
- } else SynErr(138);
+ } else SynErr(137);
}
void MultiSetExpr(out Expression e) {
@@ -2067,7 +2016,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Expect(34);
} else if (StartOf(16)) {
SemErr("multiset must be followed by multiset literal or expression to coerce in parentheses.");
- } else SynErr(139);
+ } else SynErr(138);
}
void ConstAtomExpression(out Expression/*!*/ e) {
@@ -2076,17 +2025,17 @@ List<Expression/*!*/>/*!*/ decreases) {
e = dummyExpr;
switch (la.kind) {
- case 90: {
+ case 89: {
Get();
e = new LiteralExpr(t, false);
break;
}
- case 91: {
+ case 90: {
Get();
e = new LiteralExpr(t, true);
break;
}
- case 92: {
+ case 91: {
Get();
e = new LiteralExpr(t);
break;
@@ -2096,12 +2045,12 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new LiteralExpr(t, n);
break;
}
- case 93: {
+ case 92: {
Get();
e = new ThisExpr(t);
break;
}
- case 94: {
+ case 93: {
Get();
x = t;
Expect(33);
@@ -2110,7 +2059,7 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new FreshExpr(x, e);
break;
}
- case 95: {
+ case 94: {
Get();
x = t;
Expect(33);
@@ -2119,7 +2068,7 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new AllocatedExpr(x, e);
break;
}
- case 96: {
+ case 95: {
Get();
x = t;
Expect(33);
@@ -2144,7 +2093,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Expect(34);
break;
}
- default: SynErr(140); break;
+ default: SynErr(139); break;
}
}
@@ -2181,13 +2130,13 @@ List<Expression/*!*/>/*!*/ decreases) {
Expression range;
Expression/*!*/ body;
- if (la.kind == 99 || la.kind == 100) {
+ if (la.kind == 98 || la.kind == 99) {
Forall();
x = t; univ = true;
- } else if (la.kind == 101 || la.kind == 102) {
+ } else if (la.kind == 100 || la.kind == 101) {
Exists();
x = t;
- } else SynErr(141);
+ } else SynErr(140);
QuantifierDomain(out bvars, out attrs, out range);
QSep();
Expression(out body);
@@ -2218,7 +2167,7 @@ List<Expression/*!*/>/*!*/ decreases) {
}
Expect(16);
Expression(out range);
- if (la.kind == 103 || la.kind == 104) {
+ if (la.kind == 102 || la.kind == 103) {
QSep();
Expression(out body);
}
@@ -2253,27 +2202,27 @@ List<Expression/*!*/>/*!*/ decreases) {
}
void Forall() {
- if (la.kind == 99) {
+ if (la.kind == 98) {
Get();
- } else if (la.kind == 100) {
+ } else if (la.kind == 99) {
Get();
- } else SynErr(142);
+ } else SynErr(141);
}
void Exists() {
- if (la.kind == 101) {
+ if (la.kind == 100) {
Get();
- } else if (la.kind == 102) {
+ } else if (la.kind == 101) {
Get();
- } else SynErr(143);
+ } else SynErr(142);
}
void QSep() {
- if (la.kind == 103) {
+ if (la.kind == 102) {
Get();
- } else if (la.kind == 104) {
+ } else if (la.kind == 103) {
Get();
- } else SynErr(144);
+ } else SynErr(143);
}
void AttributeBody(ref Attributes attrs) {
@@ -2300,32 +2249,32 @@ List<Expression/*!*/>/*!*/ decreases) {
public void Parse() {
la = new Token();
- la.val = "";
+ la.val = "";
Get();
Dafny();
- Expect(0);
+ Expect(0);
}
-
+
static readonly bool[,]/*!*/ set = {
- {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,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,x, x,x,T,x, T,x,x,x, x,T,T,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,T,T, T,T,x,x, x,x,T,x, T,x,x,x, x,T,T,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,x,x, x,x,T,T, T,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,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, 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,T, 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,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, x,x,x,x, x,x,x,x, x,x,x,x, 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,T, 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,T,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,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,T,x,x, x,x,T,x, x,T,T,T, T,T,T,T, T,x,x,T, T,T,T,x, x,x,x},
- {x,T,T,x, x,x,x,T, x,x,x,T, x,x,x,x, T,x,T,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,T,T, T,x,x,x, x,x,x,T, x,x,x,T, x,T,T,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,T,T, T,T,T,T, T,x,x,x, x,x,x,x, x,x,x},
- {x,T,T,x, 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,x,x, x,T,x,x, x,x,T,T, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,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,T,x,x, x,x,T,x, x,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,T, 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,x,x,x, 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,T,T,x, 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,x,x, x,T,x,x, x,x,T,T, x,x,x,x, T,x,x,x, x,x,T,T, 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,T,x,x, x,x,T,x, x,T,T,T, T,T,T,T, T,x,x,T, T,T,T,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,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,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, 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,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, x,x,x,x, 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,x,x,x, x,x,x,x, x,x,x,x, x,x,x,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, 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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,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,T, T,x,x,x, x,x,x,x, T,T,x,T, x,x,x,T, T,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, T,T,x,x, x,T,x,x, T,x,x,x, T,T,T,x, x,x,x,T, 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,x,x,x, x,x,x,x, x,T,T,x, x,x,x,T, T,x,x},
- {x,T,T,x, 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,x,x, x,T,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,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,T,x,x, x,x,T,x, x,T,T,T, T,T,T,T, T,x,x,T, T,T,T,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,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,x, x,x,T,x, T,x,x,x, x,T,T,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,T,T, T,T,x,x, x,x,T,x, T,x,x,x, x,T,T,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,x, x,x,T,T, T,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,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,T,x,T, 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,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, x,x,x,x, x,x,x,x, x,x,x,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,T, 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,T,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,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, T,x,x,x, x,T,x,x, T,T,T,T, T,T,T,T, x,x,T,T, T,T,x,x, x,x},
+ {x,T,T,x, x,x,x,T, x,x,x,T, x,x,x,x, T,x,T,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,T,T, T,x,x,x, x,x,x,T, x,x,x,T, 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,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x},
+ {x,T,T,x, 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,x,x, x,T,x,x, x,x,T,T, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,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, T,x,x,x, x,T,x,x, 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,T, 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,x,x,x, 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,T,T,x, 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,x,x, x,T,x,x, x,x,T,T, x,x,x,x, T,x,x,x, x,x,T,T, 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, T,x,x,x, x,T,x,x, T,T,T,T, T,T,T,T, x,x,T,T, T,T,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,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,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, 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,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,x,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,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,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,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,T, T,x,x,x, x,x,x,x, T,T,x,T, x,x,x,T, T,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, T,T,x,x, x,T,x,x, T,x,x,x, T,T,T,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, x,x,x,x, x,x,x,x, T,T,x,x, x,x,T,T, x,x},
+ {x,T,T,x, 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,x,x, x,T,x,x, x,x,T,T, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,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, T,x,x,x, x,T,x,x, T,T,T,T, T,T,T,T, x,x,T,T, T,T,x,x, x,x}
};
} // end Parser
@@ -2334,18 +2283,20 @@ List<Expression/*!*/>/*!*/ decreases) {
public class Errors {
public int count = 0; // number of errors detected
public System.IO.TextWriter/*!*/ errorStream = Console.Out; // error messages go to this stream
- public string errMsgFormat = "{0}({1},{2}): error: {3}"; // 0=filename, 1=line, 2=column, 3=text
- public string warningMsgFormat = "{0}({1},{2}): warning: {3}"; // 0=filename, 1=line, 2=column, 3=text
-
+ public string errMsgFormat = "{0}({1},{2}): error: {3}"; // 0=filename, 1=line, 2=column, 3=text
+ public string warningMsgFormat = "{0}({1},{2}): warning: {3}"; // 0=filename, 1=line, 2=column, 3=text
+
public void SynErr(string filename, int line, int col, int n) {
- SynErr(filename, line, col, GetSyntaxErrorString(n));
- }
- public virtual void SynErr(string filename, int line, int col, string msg) {
- Contract.Requires(msg != null);
+ SynErr(filename, line, col, GetSyntaxErrorString(n));
+ }
+
+ public virtual void SynErr(string filename, int line, int col, string/*!*/ msg) {
+ Contract.Requires(msg != null);
errorStream.WriteLine(errMsgFormat, filename, line, col, msg);
count++;
- }
- string GetSyntaxErrorString(int n) {
+ }
+
+ string GetSyntaxErrorString(int n) {
string s;
switch (n) {
case 0: s = "EOF expected"; break;
@@ -2410,93 +2361,92 @@ public class Errors {
case 59: s = "\"while\" expected"; break;
case 60: s = "\"invariant\" expected"; break;
case 61: s = "\"match\" expected"; break;
- case 62: s = "\"foreach\" expected"; break;
- case 63: s = "\"in\" expected"; break;
- case 64: s = "\"assert\" expected"; break;
- case 65: s = "\"assume\" expected"; break;
- case 66: s = "\"print\" expected"; break;
- case 67: s = "\"parallel\" expected"; break;
- case 68: s = "\"<==>\" expected"; break;
- case 69: s = "\"\\u21d4\" expected"; break;
- case 70: s = "\"==>\" expected"; break;
- case 71: s = "\"\\u21d2\" expected"; break;
- case 72: s = "\"&&\" expected"; break;
- case 73: s = "\"\\u2227\" expected"; break;
- case 74: s = "\"||\" expected"; break;
- case 75: s = "\"\\u2228\" expected"; break;
- case 76: s = "\"==\" expected"; break;
- case 77: s = "\"<=\" expected"; break;
- case 78: s = "\">=\" expected"; break;
- case 79: s = "\"!=\" expected"; break;
- case 80: s = "\"!!\" expected"; break;
- case 81: s = "\"!\" expected"; break;
- case 82: s = "\"\\u2260\" expected"; break;
- case 83: s = "\"\\u2264\" expected"; break;
- case 84: s = "\"\\u2265\" expected"; break;
- case 85: s = "\"+\" expected"; break;
- case 86: s = "\"-\" expected"; break;
- case 87: s = "\"/\" expected"; break;
- case 88: s = "\"%\" expected"; break;
- case 89: s = "\"\\u00ac\" expected"; break;
- case 90: s = "\"false\" expected"; break;
- case 91: s = "\"true\" expected"; break;
- case 92: s = "\"null\" expected"; break;
- case 93: s = "\"this\" expected"; break;
- case 94: s = "\"fresh\" expected"; break;
- case 95: s = "\"allocated\" expected"; break;
- case 96: s = "\"old\" expected"; break;
- case 97: s = "\"then\" expected"; break;
- case 98: s = "\"..\" expected"; break;
- case 99: s = "\"forall\" expected"; break;
- case 100: s = "\"\\u2200\" expected"; break;
- case 101: s = "\"exists\" expected"; break;
- case 102: s = "\"\\u2203\" expected"; break;
- case 103: s = "\"::\" expected"; break;
- case 104: s = "\"\\u2022\" expected"; break;
- case 105: s = "??? expected"; break;
- case 106: s = "invalid ClassMemberDecl"; break;
- case 107: s = "invalid MethodDecl"; break;
- case 108: s = "invalid TypeAndToken"; break;
+ case 62: s = "\"assert\" expected"; break;
+ case 63: s = "\"assume\" expected"; break;
+ case 64: s = "\"print\" expected"; break;
+ case 65: s = "\"parallel\" expected"; break;
+ case 66: s = "\"<==>\" expected"; break;
+ case 67: s = "\"\\u21d4\" expected"; break;
+ case 68: s = "\"==>\" expected"; break;
+ case 69: s = "\"\\u21d2\" expected"; break;
+ case 70: s = "\"&&\" expected"; break;
+ case 71: s = "\"\\u2227\" expected"; break;
+ case 72: s = "\"||\" expected"; break;
+ case 73: s = "\"\\u2228\" expected"; break;
+ case 74: s = "\"==\" expected"; break;
+ case 75: s = "\"<=\" expected"; break;
+ case 76: s = "\">=\" expected"; break;
+ case 77: s = "\"!=\" expected"; break;
+ case 78: s = "\"!!\" expected"; break;
+ case 79: s = "\"in\" expected"; break;
+ case 80: s = "\"!\" expected"; break;
+ case 81: s = "\"\\u2260\" expected"; break;
+ case 82: s = "\"\\u2264\" expected"; break;
+ case 83: s = "\"\\u2265\" expected"; break;
+ case 84: s = "\"+\" expected"; break;
+ case 85: s = "\"-\" expected"; break;
+ case 86: s = "\"/\" expected"; break;
+ case 87: s = "\"%\" expected"; break;
+ case 88: s = "\"\\u00ac\" expected"; break;
+ case 89: s = "\"false\" expected"; break;
+ case 90: s = "\"true\" expected"; break;
+ case 91: s = "\"null\" expected"; break;
+ case 92: s = "\"this\" expected"; break;
+ case 93: s = "\"fresh\" expected"; break;
+ case 94: s = "\"allocated\" expected"; break;
+ case 95: s = "\"old\" expected"; break;
+ case 96: s = "\"then\" expected"; break;
+ case 97: s = "\"..\" expected"; break;
+ case 98: s = "\"forall\" expected"; break;
+ case 99: s = "\"\\u2200\" expected"; break;
+ case 100: s = "\"exists\" expected"; break;
+ case 101: s = "\"\\u2203\" expected"; break;
+ case 102: s = "\"::\" expected"; break;
+ case 103: s = "\"\\u2022\" expected"; break;
+ case 104: s = "??? expected"; break;
+ case 105: s = "invalid ClassMemberDecl"; break;
+ case 106: s = "invalid MethodDecl"; break;
+ case 107: s = "invalid TypeAndToken"; break;
+ case 108: s = "invalid MethodSpec"; break;
case 109: s = "invalid MethodSpec"; break;
- case 110: s = "invalid MethodSpec"; break;
- case 111: s = "invalid ReferenceType"; break;
- case 112: s = "invalid FunctionSpec"; break;
- case 113: s = "invalid PossiblyWildFrameExpression"; break;
- case 114: s = "invalid PossiblyWildExpression"; break;
+ case 110: s = "invalid ReferenceType"; break;
+ case 111: s = "invalid FunctionSpec"; break;
+ case 112: s = "invalid PossiblyWildFrameExpression"; break;
+ case 113: s = "invalid PossiblyWildExpression"; break;
+ case 114: s = "invalid OneStmt"; break;
case 115: s = "invalid OneStmt"; break;
- case 116: s = "invalid OneStmt"; break;
- case 117: s = "invalid UpdateStmt"; break;
+ case 116: s = "invalid UpdateStmt"; break;
+ case 117: s = "invalid IfStmt"; break;
case 118: s = "invalid IfStmt"; break;
- case 119: s = "invalid IfStmt"; break;
- case 120: s = "invalid WhileStmt"; break;
- case 121: s = "invalid Rhs"; break;
- case 122: s = "invalid Lhs"; break;
- case 123: s = "invalid Guard"; break;
- case 124: s = "invalid AttributeArg"; break;
- case 125: s = "invalid EquivOp"; break;
- case 126: s = "invalid ImpliesOp"; break;
- case 127: s = "invalid AndOp"; break;
- case 128: s = "invalid OrOp"; break;
- case 129: s = "invalid RelOp"; break;
- case 130: s = "invalid AddOp"; break;
- case 131: s = "invalid UnaryExpression"; break;
- case 132: s = "invalid MulOp"; break;
- case 133: s = "invalid NegOp"; break;
- case 134: s = "invalid EndlessExpression"; break;
+ case 119: s = "invalid WhileStmt"; break;
+ case 120: s = "invalid Rhs"; break;
+ case 121: s = "invalid Lhs"; break;
+ case 122: s = "invalid Guard"; break;
+ case 123: s = "invalid AttributeArg"; break;
+ case 124: s = "invalid EquivOp"; break;
+ case 125: s = "invalid ImpliesOp"; break;
+ case 126: s = "invalid AndOp"; break;
+ case 127: s = "invalid OrOp"; break;
+ case 128: s = "invalid RelOp"; break;
+ case 129: s = "invalid AddOp"; break;
+ case 130: s = "invalid UnaryExpression"; break;
+ case 131: s = "invalid MulOp"; break;
+ case 132: s = "invalid NegOp"; break;
+ case 133: s = "invalid EndlessExpression"; break;
+ case 134: s = "invalid Suffix"; break;
case 135: s = "invalid Suffix"; break;
case 136: s = "invalid Suffix"; break;
- case 137: s = "invalid Suffix"; break;
- case 138: s = "invalid DisplayExpr"; break;
- case 139: s = "invalid MultiSetExpr"; break;
- case 140: s = "invalid ConstAtomExpression"; break;
- case 141: s = "invalid QuantifierGuts"; break;
- case 142: s = "invalid Forall"; break;
- case 143: s = "invalid Exists"; break;
- case 144: s = "invalid QSep"; break;
+ case 137: s = "invalid DisplayExpr"; break;
+ case 138: s = "invalid MultiSetExpr"; break;
+ case 139: s = "invalid ConstAtomExpression"; break;
+ case 140: s = "invalid QuantifierGuts"; break;
+ case 141: s = "invalid Forall"; break;
+ case 142: s = "invalid Exists"; break;
+ case 143: s = "invalid QSep"; break;
default: s = "error " + n; break;
}
- return s;
+ return s;
}
public void SemErr(IToken/*!*/ tok, string/*!*/ msg) { // semantic errors
@@ -2504,8 +2454,9 @@ public class Errors {
Contract.Requires(msg != null);
SemErr(tok.filename, tok.line, tok.col, msg);
}
+
public virtual void SemErr(string filename, int line, int col, string/*!*/ msg) {
- Contract.Requires(msg != null);
+ Contract.Requires(msg != null);
errorStream.WriteLine(errMsgFormat, filename, line, col, msg);
count++;
}
diff --git a/Source/Dafny/Printer.cs b/Source/Dafny/Printer.cs
index f9f1eca0..7f7ba963 100644
--- a/Source/Dafny/Printer.cs
+++ b/Source/Dafny/Printer.cs
@@ -541,27 +541,6 @@ namespace Microsoft.Dafny {
Indent(indent);
wr.Write("}");
- } else if (stmt is ForeachStmt) {
- ForeachStmt s = (ForeachStmt)stmt;
- wr.Write("foreach ({0} in ", s.BoundVar.Name);
- PrintExpression(s.Collection);
- if (!LiteralExpr.IsTrue(s.Range)) {
- wr.Write(" | ");
- PrintExpression(s.Range);
- }
- wr.WriteLine(") {");
- int ind = indent + IndentAmount;
- foreach (PredicateStmt t in s.BodyPrefix) {
- Indent(ind);
- PrintStatement(t, ind);
- wr.WriteLine();
- }
- Indent(ind);
- PrintStatement(s.GivenBody, ind);
- wr.WriteLine();
- Indent(indent);
- wr.Write("}");
-
} else if (stmt is ParallelStmt) {
var s = (ParallelStmt)stmt;
wr.Write("parallel (");
diff --git a/Source/Dafny/Resolver.cs b/Source/Dafny/Resolver.cs
index f970a7a5..a4d99bd0 100644
--- a/Source/Dafny/Resolver.cs
+++ b/Source/Dafny/Resolver.cs
@@ -12,7 +12,7 @@ using Microsoft.Boogie;
namespace Microsoft.Dafny {
public class Resolver {
public int ErrorCount = 0;
- protected virtual void Error(IToken tok, string msg, params object[] args) {
+ void Error(IToken tok, string msg, params object[] args) {
Contract.Requires(tok != null);
Contract.Requires(msg != null);
ConsoleColor col = Console.ForegroundColor;
@@ -43,6 +43,16 @@ namespace Microsoft.Dafny {
Contract.Requires(msg != null);
Error(e.tok, msg, args);
}
+ 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}",
+ tok.filename, tok.line, tok.col - 1,
+ string.Format(msg, args));
+ Console.ForegroundColor = col;
+ }
readonly BuiltIns builtIns;
readonly Dictionary<string/*!*/,TopLevelDecl/*!*/>/*!*/ classes = new Dictionary<string/*!*/,TopLevelDecl/*!*/>();
@@ -403,8 +413,8 @@ namespace Microsoft.Dafny {
ResolveAttributes(cl.Attributes, false);
currentClass = cl;
foreach (MemberDecl member in cl.Members) {
- ResolveAttributes(member.Attributes, false);
if (member is Field) {
+ ResolveAttributes(member.Attributes, false);
// nothing more to do
} else if (member is Function) {
@@ -447,6 +457,7 @@ namespace Microsoft.Dafny {
} else if (member is CouplingInvariant) {
CouplingInvariant inv = (CouplingInvariant)member;
+ ResolveAttributes(member.Attributes, false);
if (inv.Refined != null) {
inv.Formals = new List<Formal>();
scope.PushMarker();
@@ -639,6 +650,7 @@ namespace Microsoft.Dafny {
foreach (Formal p in f.Formals) {
scope.Push(p.Name, p);
}
+ ResolveAttributes(f.Attributes, false);
foreach (Expression r in f.Req) {
ResolveExpression(r, false);
Contract.Assert(r.Type != null); // follows from postcondition of ResolveExpression
@@ -769,9 +781,40 @@ namespace Microsoft.Dafny {
scope.Push(p.Name, p);
}
+ // attributes are allowed to mention both in- and out-parameters
+ ResolveAttributes(m.Attributes, false);
+
// ... continue resolving specification
+ bool twoState = true;
+ if (m.Mod.Count == 0 && m.Outs.Count == 0) {
+ // In this special case, the current translation of parallel Call statements would be unsound.
+ // The reason is that the parallel Call statement does not advance the heap, so there had better
+ // not be any way to say that the post-heap is definitely different than the pre-heap. For example,
+ // the following program, is permitted, would unsoundly verify:
+ // ghost static method M(y: int)
+ // ensures exists o: object :: o != null && fresh(o);
+ // {
+ // var p := new object;
+ // }
+ // method Main() {
+ // parallel (x) { M(x); }
+ // assert false;
+ // }
+ // In fact, here is another method M that together with Main above would yield unsound verification:
+ // class C { ghost var data: int; }
+ // ghost static method M(y: int)
+ // ensures exists c: C :: c != null && c.data != old(c.data);
+ // {
+ // var c := new C;
+ // c.data := c.data + 1;
+ // }
+ // So, it seems best just to disallow two-state postconditions in these cases. Perhaps the error
+ // message will not explain enough of the reasons for this restriction, but the restriction does
+ // not seem to rule out any useful programs.
+ twoState = false;
+ }
foreach (MaybeFreeExpression e in m.Ens) {
- ResolveExpression(e.E, true);
+ ResolveExpression(e.E, twoState);
Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.E.Type, Type.Bool)) {
Error(e.E, "Postcondition must be a boolean (got {0})", e.E.Type);
@@ -1249,7 +1292,7 @@ namespace Microsoft.Dafny {
AssignStmt s = (AssignStmt)stmt;
int prevErrorCount = ErrorCount;
if (s.Lhs is SeqSelectExpr) {
- ResolveSeqSelectExpr((SeqSelectExpr)s.Lhs, true, true); // allow ghosts for now, tighted up below
+ ResolveSeqSelectExpr((SeqSelectExpr)s.Lhs, true, false); // allow ghosts for now, tighted up below
} else {
ResolveExpression(s.Lhs, true); // allow ghosts for now, tighted up below
}
@@ -1302,7 +1345,7 @@ namespace Microsoft.Dafny {
Error(stmt, "Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
}
if (!slhs.SelectOne) {
- Error(stmt, "cannot assign to multiple array elements (try a foreach).");
+ Error(stmt, "cannot assign to a range of array elements (try the 'parallel' statement)");
}
}
@@ -1318,7 +1361,7 @@ namespace Microsoft.Dafny {
s.IsGhost = lvalueIsGhost;
Type lhsType = s.Lhs.Type;
if (lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne) {
- Error(stmt, "cannot assign to multiple array elements (try a foreach).");
+ Error(stmt, "cannot assign to a range of array elements (try the 'parallel' statement)");
//lhsType = UserDefinedType.ArrayElementType(lhsType);
} else {
if (s.Rhs is ExprRhs) {
@@ -1464,62 +1507,6 @@ namespace Microsoft.Dafny {
// any type is fine
}
- } else if (stmt is ForeachStmt) {
- ForeachStmt s = (ForeachStmt)stmt;
-
- ResolveExpression(s.Collection, true);
- Contract.Assert(s.Collection.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(s.Collection.Type, new CollectionTypeProxy(s.BoundVar.Type))) {
- Error(s.Collection, "The type is expected to be a collection of {0} (instead got {1})", s.BoundVar.Type, s.Collection.Type);
- }
-
- scope.PushMarker();
- bool b = scope.Push(s.BoundVar.Name, s.BoundVar);
- Contract.Assert(b); // since we just pushed a marker, we expect the Push to succeed
- ResolveType(s.BoundVar.tok, s.BoundVar.Type);
- int prevErrorCount = ErrorCount;
-
- ResolveExpression(s.Range, true);
- Contract.Assert(s.Range.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(s.Range.Type, Type.Bool)) {
- Error(s.Range, "range condition is expected to be of type {0}, but is {1}", Type.Bool, s.Range.Type);
- }
- bool successfullyResolvedCollectionAndRange = ErrorCount == prevErrorCount;
-
- foreach (PredicateStmt ss in s.BodyPrefix) {
- ResolveStatement(ss, specContextOnly, method);
- }
-
- bool specOnly = specContextOnly ||
- (successfullyResolvedCollectionAndRange && (UsesSpecFeatures(s.Collection) || UsesSpecFeatures(s.Range)));
- s.IsGhost = specOnly;
- ResolveStatement(s.GivenBody, specOnly, method);
- // check for correct usage of BoundVar in LHS and RHS of this assignment
- if (s.GivenBody is AssignStmt) {
- s.BodyAssign = (AssignStmt)s.GivenBody;
- } else if (s.GivenBody is ConcreteSyntaxStatement) {
- var css = (ConcreteSyntaxStatement)s.GivenBody;
- if (css.ResolvedStatements.Count == 1 && css.ResolvedStatements[0] is AssignStmt) {
- s.BodyAssign = (AssignStmt)css.ResolvedStatements[0];
- }
- }
- if (s.BodyAssign == null) {
- Error(s, "update statement inside foreach must be a single assignment statement");
- } else {
- FieldSelectExpr lhs = s.BodyAssign.Lhs as FieldSelectExpr;
- IdentifierExpr obj = lhs == null ? null : lhs.Obj as IdentifierExpr;
- if (obj == null || obj.Var != s.BoundVar) {
- Error(s, "assignment inside foreach must assign to a field of the bound variable of the foreach statement");
- } else {
- var rhs = s.BodyAssign.Rhs as ExprRhs;
- if (rhs != null && rhs.Expr is UnaryExpr && ((UnaryExpr)rhs.Expr).Op == UnaryExpr.Opcode.SetChoose) {
- Error(s, "foreach statement does not support 'choose' statements");
- }
- }
- }
-
- scope.PopMarker();
-
} else if (stmt is ParallelStmt) {
var s = (ParallelStmt)stmt;
@@ -1531,15 +1518,13 @@ namespace Microsoft.Dafny {
}
ResolveType(v.tok, v.Type);
}
- if (s.Range != null) {
- ResolveExpression(s.Range, true);
- Contract.Assert(s.Range.Type != null); // follows from postcondition of ResolveExpression
- if (!UnifyTypes(s.Range.Type, Type.Bool)) {
- Error(stmt, "range restriction in parallel statement must be of type bool (instead got {0})", s.Range.Type);
- }
+ ResolveExpression(s.Range, true);
+ Contract.Assert(s.Range.Type != null); // follows from postcondition of ResolveExpression
+ if (!UnifyTypes(s.Range.Type, Type.Bool)) {
+ Error(stmt, "range restriction in parallel statement must be of type bool (instead got {0})", s.Range.Type);
}
foreach (var ens in s.Ens) {
- ResolveExpression(ens.E, true);
+ ResolveExpression(ens.E, false); // Note, two-state features are not allowed (see the resolution of method postconditions in this file, and see the X_ examples in Test/dafny0/ParallelResolveErrors.dfy)
Contract.Assert(ens.E.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(ens.E.Type, Type.Bool)) {
Error(ens.E, "ensures condition is expected to be of type {0}, but is {1}", Type.Bool, ens.E.Type);
@@ -1570,40 +1555,31 @@ namespace Microsoft.Dafny {
scope.PopMarker();
if (prevErrorCount == ErrorCount) {
- // check for supported kinds
- if (s.Ens.Count == 0) {
- // The supported kinds are Assign and Call. See if it's one of them.
+ // determine the Kind and run some additional checks on the body
+ if (s.Ens.Count != 0) {
+ // The only supported kind with ensures clauses is Proof.
+ s.Kind = ParallelStmt.ParBodyKind.Proof;
+ } else {
+ // There are two special cases:
+ // * Assign, which is the only kind of the parallel statement that allows a heap update.
+ // * Call, which is a single call statement with no side effects or output parameters.
+ // The effect of Assign and the postcondition of Call will be seen outside the parallel
+ // statement.
Statement s0 = s.S0;
if (s0 is AssignStmt) {
- var lhs = ((AssignStmt)s0).Lhs.Resolved;
- if (lhs is IdentifierExpr) {
- Error(s0, "a parallel statement must not update local variables declared outside the parallel body");
- } else if (lhs is FieldSelectExpr) {
- // cool
- } else if (lhs is SeqSelectExpr && ((SeqSelectExpr)lhs).SelectOne) {
- // cool
- } else if (lhs is MultiSelectExpr) {
- // cool
- } else {
- Contract.Assert(false); // unexpected assignment LHS
- }
- var rhs = ((AssignStmt)s0).Rhs; // ExprRhs and HavocRhs are fine, but TypeRhs is not
- // TODO: Occurrences of Choose in RHS must also be handled or disallowed (this happen when Choose is treated like a method member of the set type)
- if (rhs is TypeRhs) {
- Error(rhs.Tok, "new allocation not supported in parallel statements");
- }
s.Kind = ParallelStmt.ParBodyKind.Assign;
} else if (s0 is CallStmt) {
- CheckNoForeignUpdates(s0);
s.Kind = ParallelStmt.ParBodyKind.Call;
} else {
- Error(s, "the body of an ensures-less parallel statement must be one assignment statement or one call statement");
+ s.Kind = ParallelStmt.ParBodyKind.Proof;
+ if (s.Body is BlockStmt && ((BlockStmt)s.Body).Body.Count == 0) {
+ // an empty statement, so don't produce any warning
+ } else {
+ Warning(s.Tok, "the conclusion of the body of this parallel statement will not be known outside the parallel statement; consider using an 'ensures' clause");
+ }
}
- } else {
- // The only supported kind with ensures clauses is Proof. See if that's what the body really is.
- CheckNoForeignUpdates(s.Body);
- s.Kind = ParallelStmt.ParBodyKind.Proof;
}
+ CheckParallelBodyRestrictions(s.Body, s.Kind == ParallelStmt.ParBodyKind.Assign);
}
} else if (stmt is MatchStmt) {
@@ -2064,30 +2040,42 @@ namespace Microsoft.Dafny {
}
}
- public void CheckNoForeignUpdates(Statement stmt) {
+ /// <summary>
+ /// This method performs some additional checks on the body "stmt" of a parallel statement
+ /// </summary>
+ public void CheckParallelBodyRestrictions(Statement stmt, bool allowHeapUpdates) {
Contract.Requires(stmt != null);
if (stmt is PredicateStmt) {
// cool
} else if (stmt is PrintStmt) {
Error(stmt, "print statement is not allowed inside a parallel statement");
} else if (stmt is BreakStmt) {
- // TODO: this case can be checked already in the first pass through the parallel body, by doing so from an empty set of labeled statements and resetting the loop-stack
+ // this case can be checked already in the first pass through the parallel body, by doing so from an empty set of labeled statements and resetting the loop-stack
} else if (stmt is ReturnStmt) {
Error(stmt, "return statement is not allowed inside a parallel statement");
} else if (stmt is ConcreteSyntaxStatement) {
var s = (ConcreteSyntaxStatement)stmt;
foreach (var ss in s.ResolvedStatements) {
- CheckNoForeignUpdates(ss);
+ CheckParallelBodyRestrictions(ss, allowHeapUpdates);
}
} else if (stmt is AssignStmt) {
var s = (AssignStmt)stmt;
- var idExpr = s.Lhs as IdentifierExpr;
+ var idExpr = s.Lhs.Resolved as IdentifierExpr;
if (idExpr != null) {
if (scope.ContainsDecl(idExpr.Var)) {
Error(stmt, "body of parallel statement is attempting to update a variable declared outside the parallel statement");
}
- } else {
- Error(stmt, "the body of the enclosing parallel statement may not updated heap locations");
+ } else if (!allowHeapUpdates) {
+ Error(stmt, "the body of the enclosing parallel statement may not update heap locations");
+ }
+ var rhs = s.Rhs; // ExprRhs and HavocRhs are fine, but TypeRhs is not
+ if (rhs is TypeRhs) {
+ Error(rhs.Tok, "new allocation not supported in parallel statements");
+ } else if (rhs is ExprRhs) {
+ var r = ((ExprRhs)rhs).Expr.Resolved;
+ if (r is UnaryExpr && ((UnaryExpr)r).Op == UnaryExpr.Opcode.SetChoose) {
+ Error(r, "set choose operator not supported inside parallel statement");
+ }
}
} else if (stmt is VarDecl) {
// cool
@@ -2100,7 +2088,7 @@ namespace Microsoft.Dafny {
Error(stmt, "body of parallel statement is attempting to update a variable declared outside the parallel statement");
}
} else {
- Error(stmt, "the body of the enclosing parallel statement may not updated heap locations");
+ Error(stmt, "the body of the enclosing parallel statement may not update heap locations");
}
}
if (s.Method.Mod.Count != 0) {
@@ -2111,40 +2099,37 @@ namespace Microsoft.Dafny {
var s = (BlockStmt)stmt;
scope.PushMarker();
foreach (var ss in s.Body) {
- CheckNoForeignUpdates(ss);
+ CheckParallelBodyRestrictions(ss, allowHeapUpdates);
}
scope.PopMarker();
} else if (stmt is IfStmt) {
var s = (IfStmt)stmt;
- CheckNoForeignUpdates(s.Thn);
+ CheckParallelBodyRestrictions(s.Thn, allowHeapUpdates);
if (s.Els != null) {
- CheckNoForeignUpdates(s.Els);
+ CheckParallelBodyRestrictions(s.Els, allowHeapUpdates);
}
} else if (stmt is AlternativeStmt) {
var s = (AlternativeStmt)stmt;
foreach (var alt in s.Alternatives) {
foreach (var ss in alt.Body) {
- CheckNoForeignUpdates(ss);
+ CheckParallelBodyRestrictions(ss, allowHeapUpdates);
}
}
} else if (stmt is WhileStmt) {
WhileStmt s = (WhileStmt)stmt;
- CheckNoForeignUpdates(s.Body);
+ CheckParallelBodyRestrictions(s.Body, allowHeapUpdates);
} else if (stmt is AlternativeLoopStmt) {
var s = (AlternativeLoopStmt)stmt;
foreach (var alt in s.Alternatives) {
foreach (var ss in alt.Body) {
- CheckNoForeignUpdates(ss);
+ CheckParallelBodyRestrictions(ss, allowHeapUpdates);
}
}
- } else if (stmt is ForeachStmt) {
- Error(stmt, "foreach statement not allowed in body of parallel statement");
-
} else if (stmt is ParallelStmt) {
var s = (ParallelStmt)stmt;
switch (s.Kind) {
@@ -2164,7 +2149,7 @@ namespace Microsoft.Dafny {
var s = (MatchStmt)stmt;
foreach (var kase in s.Cases) {
foreach (var ss in kase.Body) {
- CheckNoForeignUpdates(ss);
+ CheckParallelBodyRestrictions(ss, allowHeapUpdates);
}
}
@@ -3293,13 +3278,14 @@ namespace Microsoft.Dafny {
/// <summary>
/// Tries to find a bounded pool for each of the bound variables "bvars" of "expr". If this process
/// fails, then "null" is returned and the bound variables for which the process fails are added to "missingBounds".
- /// Requires "e" to be successfully resolved.
+ /// Requires "expr" to be successfully resolved.
/// </summary>
List<QuantifierExpr.BoundedPool> DiscoverBounds(IToken tok, List<BoundVar> bvars, Expression expr, bool polarity, List<BoundVar> missingBounds) {
Contract.Requires(tok != null);
Contract.Requires(bvars != null);
Contract.Requires(missingBounds != null);
- Contract.Requires(expr.Type != null); // a sanity check (but not a complete proof) that "e" has been resolved
+ Contract.Requires(expr != null);
+ Contract.Requires(expr.Type != null); // a sanity check (but not a complete proof) that "expr" has been resolved
Contract.Ensures(
(Contract.Result<List<QuantifierExpr.BoundedPool>>() != null &&
Contract.Result<List<QuantifierExpr.BoundedPool>>().Count == bvars.Count &&
@@ -3889,10 +3875,10 @@ namespace Microsoft.Dafny {
return cce.NonNull(e.Var).IsGhost;
} else if (expr is DatatypeValue) {
DatatypeValue dtv = (DatatypeValue)expr;
- return Contract.Exists(dtv.Arguments, arg=> UsesSpecFeatures(arg));
+ return dtv.Arguments.Exists(arg => UsesSpecFeatures(arg));
} else if (expr is DisplayExpression) {
DisplayExpression e = (DisplayExpression)expr;
- return Contract.Exists( e.Elements,ee=> UsesSpecFeatures(ee));
+ return e.Elements.Exists(ee => UsesSpecFeatures(ee));
} else if (expr is FieldSelectExpr) {
FieldSelectExpr e = (FieldSelectExpr)expr;
return cce.NonNull(e.Field).IsGhost || UsesSpecFeatures(e.Obj);
@@ -3914,7 +3900,7 @@ namespace Microsoft.Dafny {
if (cce.NonNull(e.Function).IsGhost) {
return true;
}
- return Contract.Exists( e.Args,arg=> UsesSpecFeatures(arg));
+ return e.Args.Exists(arg => UsesSpecFeatures(arg));
} else if (expr is OldExpr) {
OldExpr e = (OldExpr)expr;
return UsesSpecFeatures(e.E);
@@ -3931,9 +3917,14 @@ namespace Microsoft.Dafny {
return true;
}
return UsesSpecFeatures(e.E0) || UsesSpecFeatures(e.E1);
- } else if (expr is QuantifierExpr) {
- var e = (QuantifierExpr)expr;
- return e.Bounds == null; // if the resolver found bounds, then the quantifier can be compiled
+ } else if (expr is ComprehensionExpr) {
+ if (expr is QuantifierExpr && ((QuantifierExpr)expr).Bounds == null) {
+ return true; // the quantifier cannot be compiled if the resolver found no bounds
+ }
+ return Contract.Exists(expr.SubExpressions, se => UsesSpecFeatures(se));
+ } else if (expr is SetComprehension) {
+ var e = (SetComprehension)expr;
+ return (e.Range != null && UsesSpecFeatures(e.Range)) || (e.Term != null && UsesSpecFeatures(e.Term));
} else if (expr is WildcardExpr) {
return false;
} else if (expr is ITEExpr) {
@@ -3944,7 +3935,7 @@ namespace Microsoft.Dafny {
if (UsesSpecFeatures(me.Source)) {
return true;
}
- return Contract.Exists( me.Cases,mc=> UsesSpecFeatures(mc.Body));
+ return me.Cases.Exists(mc => UsesSpecFeatures(mc.Body));
} else if (expr is ConcreteSyntaxExpression) {
var e = (ConcreteSyntaxExpression)expr;
return e.ResolvedExpression != null && UsesSpecFeatures(e.ResolvedExpression);
diff --git a/Source/Dafny/Scanner.cs b/Source/Dafny/Scanner.cs
index ae887c47..634abf45 100644
--- a/Source/Dafny/Scanner.cs
+++ b/Source/Dafny/Scanner.cs
@@ -19,7 +19,7 @@ public class Buffer {
// a) whole stream in buffer
// b) part of stream in buffer
// 2) non seekable stream (network, console)
-
+
public const int EOF = 65535 + 1; // char.MaxValue + 1;
const int MIN_BUFFER_LENGTH = 1024; // 1KB
const int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
@@ -31,15 +31,17 @@ public class Buffer {
Stream/*!*/ stream; // input stream (seekable)
bool isUserStream; // was the stream opened by the user?
-[ContractInvariantMethod]
-void ObjectInvariant(){
- Contract.Invariant(buf != null);
- Contract.Invariant(stream != null);}
- [NotDelayed]
- public Buffer (Stream/*!*/ s, bool isUserStream) :base() {
+ [ContractInvariantMethod]
+ void ObjectInvariant(){
+ Contract.Invariant(buf != null);
+ Contract.Invariant(stream != null);
+ }
+
+// [NotDelayed]
+ public Buffer (Stream/*!*/ s, bool isUserStream) : base() {
Contract.Requires(s != null);
stream = s; this.isUserStream = isUserStream;
-
+
int fl, bl;
if (s.CanSeek) {
fl = (int) s.Length;
@@ -51,12 +53,12 @@ void ObjectInvariant(){
buf = new byte[(bl>0) ? bl : MIN_BUFFER_LENGTH];
fileLen = fl; bufLen = bl;
-
+
if (fileLen > 0) Pos = 0; // setup buffer to position 0 (start)
else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
if (bufLen == fileLen && s.CanSeek) Close();
}
-
+
protected Buffer(Buffer/*!*/ b) { // called in UTF8Buffer constructor
Contract.Requires(b != null);
buf = b.buf;
@@ -73,14 +75,14 @@ void ObjectInvariant(){
}
~Buffer() { Close(); }
-
+
protected void Close() {
if (!isUserStream && stream != null) {
stream.Close();
//stream = null;
}
}
-
+
public virtual int Read () {
if (bufPos < bufLen) {
return buf[bufPos++];
@@ -100,7 +102,7 @@ void ObjectInvariant(){
Pos = curPos;
return ch;
}
-
+
public string/*!*/ GetString (int beg, int end) {
Contract.Ensures(Contract.Result<string>() != null);
int len = 0;
@@ -139,7 +141,7 @@ void ObjectInvariant(){
}
}
}
-
+
// Read the next chunk of bytes from the stream, increases the buffer
// if needed and updates the fields fileLen and bufLen.
// Returns the number of bytes read.
@@ -209,23 +211,24 @@ public class UTF8Buffer: Buffer {
public class Scanner {
const char EOL = '\n';
const int eofSym = 0; /* pdt */
- const int maxT = 105;
- const int noSym = 105;
-
-
-[ContractInvariantMethod]
-void objectInvariant(){
- Contract.Invariant(buffer!=null);
- Contract.Invariant(t != null);
- Contract.Invariant(start != null);
- Contract.Invariant(tokens != null);
- Contract.Invariant(pt != null);
- Contract.Invariant(tval != null);
- Contract.Invariant(Filename != null);
- Contract.Invariant(errorHandler != null);
-}
+ const int maxT = 104;
+ const int noSym = 104;
+
+
+ [ContractInvariantMethod]
+ void objectInvariant(){
+ Contract.Invariant(buffer!=null);
+ Contract.Invariant(t != null);
+ Contract.Invariant(start != null);
+ Contract.Invariant(tokens != null);
+ Contract.Invariant(pt != null);
+ Contract.Invariant(tval != null);
+ Contract.Invariant(Filename != null);
+ Contract.Invariant(errorHandler != null);
+ }
+
public Buffer/*!*/ buffer; // scanner buffer
-
+
Token/*!*/ t; // current token
int ch; // current input character
int pos; // byte position of current character
@@ -236,13 +239,13 @@ void objectInvariant(){
Token/*!*/ tokens; // list of tokens already peeked (first token is a dummy)
Token/*!*/ pt; // current peek token
-
+
char[]/*!*/ tval = new char[128]; // text of current token
int tlen; // length of current token
-
+
private string/*!*/ Filename;
private Errors/*!*/ errorHandler;
-
+
static Scanner() {
start = new Hashtable(128);
for (int i = 39; i <= 39; ++i) start[i] = 1;
@@ -290,9 +293,9 @@ void objectInvariant(){
start[Buffer.EOF] = -1;
}
-
- [NotDelayed]
- public Scanner (string/*!*/ fileName, Errors/*!*/ errorHandler) :base(){
+
+// [NotDelayed]
+ public Scanner (string/*!*/ fileName, Errors/*!*/ errorHandler) : base() {
Contract.Requires(fileName != null);
Contract.Requires(errorHandler != null);
this.errorHandler = errorHandler;
@@ -302,15 +305,14 @@ void objectInvariant(){
Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
buffer = new Buffer(stream, false);
Filename = fileName;
-
Init();
} catch (IOException) {
throw new FatalError("Cannot open file " + fileName);
}
}
-
- [NotDelayed]
- public Scanner (Stream/*!*/ s, Errors/*!*/ errorHandler, string/*!*/ fileName) :base(){
+
+// [NotDelayed]
+ public Scanner (Stream/*!*/ s, Errors/*!*/ errorHandler, string/*!*/ fileName) : base() {
Contract.Requires(s != null);
Contract.Requires(errorHandler != null);
Contract.Requires(fileName != null);
@@ -319,10 +321,9 @@ void objectInvariant(){
buffer = new Buffer(s, true);
this.errorHandler = errorHandler;
this.Filename = fileName;
-
Init();
}
-
+
void Init() {
pos = -1; line = 1; col = 0;
oldEols = 0;
@@ -343,11 +344,11 @@ void objectInvariant(){
Contract.Ensures(Contract.Result<string>() != null);
int p = buffer.Pos;
int ch = buffer.Read();
- // replace isolated '\r' by '\n' in order to make
+ // replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
while (ch != EOL && ch != Buffer.EOF){
- ch = buffer.Read();
+ ch = buffer.Read();
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
@@ -358,7 +359,7 @@ void objectInvariant(){
}
void NextCh() {
- if (oldEols > 0) { ch = EOL; oldEols--; }
+ if (oldEols > 0) { ch = EOL; oldEols--; }
else {
// pos = buffer.Pos;
// ch = buffer.Read(); col++;
@@ -366,9 +367,9 @@ void objectInvariant(){
// // eol handling uniform across Windows, Unix and Mac
// if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
// if (ch == EOL) { line++; col = 0; }
-
+
while (true) {
- pos = buffer.Pos;
+ pos = buffer.Pos;
ch = buffer.Read(); col++;
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
@@ -418,7 +419,7 @@ void objectInvariant(){
return;
}
-
+
}
}
@@ -525,22 +526,21 @@ void objectInvariant(){
case "while": t.kind = 59; break;
case "invariant": t.kind = 60; break;
case "match": t.kind = 61; break;
- case "foreach": t.kind = 62; break;
- case "in": t.kind = 63; break;
- case "assert": t.kind = 64; break;
- case "assume": t.kind = 65; break;
- case "print": t.kind = 66; break;
- case "parallel": t.kind = 67; break;
- case "false": t.kind = 90; break;
- case "true": t.kind = 91; break;
- case "null": t.kind = 92; break;
- case "this": t.kind = 93; break;
- case "fresh": t.kind = 94; break;
- case "allocated": t.kind = 95; break;
- case "old": t.kind = 96; break;
- case "then": t.kind = 97; break;
- case "forall": t.kind = 99; break;
- case "exists": t.kind = 101; break;
+ case "assert": t.kind = 62; break;
+ case "assume": t.kind = 63; break;
+ case "print": t.kind = 64; break;
+ case "parallel": t.kind = 65; break;
+ case "in": t.kind = 79; break;
+ case "false": t.kind = 89; break;
+ case "true": t.kind = 90; break;
+ case "null": t.kind = 91; break;
+ case "this": t.kind = 92; break;
+ case "fresh": t.kind = 93; break;
+ case "allocated": t.kind = 94; break;
+ case "old": t.kind = 95; break;
+ case "then": t.kind = 96; break;
+ case "forall": t.kind = 98; break;
+ case "exists": t.kind = 100; break;
default: break;
}
}
@@ -557,10 +557,13 @@ void objectInvariant(){
t.pos = pos; t.col = col; t.line = line;
t.filename = this.Filename;
int state;
- if (start.ContainsKey(ch)) { state = (int) cce.NonNull( start[ch]); }
+ if (start.ContainsKey(ch)) {
+ Contract.Assert(start[ch] != null);
+ state = (int) start[ch];
+ }
else { state = 0; }
tlen = 0; AddCh();
-
+
switch (state) {
case -1: { t.kind = eofSym; break; } // NextCh already done
case 0: {
@@ -666,56 +669,56 @@ void objectInvariant(){
if (ch == '>') {AddCh(); goto case 30;}
else {goto case 0;}
case 30:
- {t.kind = 68; break;}
+ {t.kind = 66; break;}
case 31:
- {t.kind = 69; break;}
+ {t.kind = 67; break;}
case 32:
- {t.kind = 70; break;}
+ {t.kind = 68; break;}
case 33:
- {t.kind = 71; break;}
+ {t.kind = 69; break;}
case 34:
if (ch == '&') {AddCh(); goto case 35;}
else {goto case 0;}
case 35:
- {t.kind = 72; break;}
+ {t.kind = 70; break;}
case 36:
- {t.kind = 73; break;}
+ {t.kind = 71; break;}
case 37:
- {t.kind = 74; break;}
+ {t.kind = 72; break;}
case 38:
- {t.kind = 75; break;}
+ {t.kind = 73; break;}
case 39:
- {t.kind = 78; break;}
+ {t.kind = 76; break;}
case 40:
- {t.kind = 79; break;}
+ {t.kind = 77; break;}
case 41:
- {t.kind = 80; break;}
+ {t.kind = 78; break;}
case 42:
- {t.kind = 82; break;}
+ {t.kind = 81; break;}
case 43:
- {t.kind = 83; break;}
+ {t.kind = 82; break;}
case 44:
- {t.kind = 84; break;}
+ {t.kind = 83; break;}
case 45:
- {t.kind = 85; break;}
+ {t.kind = 84; break;}
case 46:
- {t.kind = 86; break;}
+ {t.kind = 85; break;}
case 47:
- {t.kind = 87; break;}
+ {t.kind = 86; break;}
case 48:
- {t.kind = 88; break;}
+ {t.kind = 87; break;}
case 49:
- {t.kind = 89; break;}
+ {t.kind = 88; break;}
case 50:
- {t.kind = 98; break;}
+ {t.kind = 97; break;}
case 51:
- {t.kind = 100; break;}
+ {t.kind = 99; break;}
case 52:
- {t.kind = 102; break;}
+ {t.kind = 101; break;}
case 53:
- {t.kind = 103; break;}
+ {t.kind = 102; break;}
case 54:
- {t.kind = 104; break;}
+ {t.kind = 103; break;}
case 55:
recEnd = pos; recKind = 15;
if (ch == '>') {AddCh(); goto case 28;}
@@ -743,31 +746,31 @@ void objectInvariant(){
if (ch == '.') {AddCh(); goto case 50;}
else {t.kind = 53; break;}
case 61:
- recEnd = pos; recKind = 81;
+ recEnd = pos; recKind = 80;
if (ch == '=') {AddCh(); goto case 40;}
else if (ch == '!') {AddCh(); goto case 41;}
- else {t.kind = 81; break;}
+ else {t.kind = 80; break;}
case 62:
- recEnd = pos; recKind = 76;
+ recEnd = pos; recKind = 74;
if (ch == '>') {AddCh(); goto case 32;}
- else {t.kind = 76; break;}
+ else {t.kind = 74; break;}
case 63:
- recEnd = pos; recKind = 77;
+ recEnd = pos; recKind = 75;
if (ch == '=') {AddCh(); goto case 29;}
- else {t.kind = 77; break;}
+ else {t.kind = 75; break;}
}
t.val = new String(tval, 0, tlen);
return t;
}
-
+
private void SetScannerBehindT() {
buffer.Pos = t.pos;
NextCh();
line = t.line; col = t.col;
for (int i = 0; i < tlen; i++) NextCh();
}
-
+
// get the next token (possibly a token already seen during peeking)
public Token/*!*/ Scan () {
Contract.Ensures(Contract.Result<Token>() != null);
@@ -788,7 +791,7 @@ void objectInvariant(){
}
pt = pt.next;
} while (pt.kind > maxT); // skip pragmas
-
+
return pt;
}
diff --git a/Source/Dafny/Translator.cs b/Source/Dafny/Translator.cs
index 52449d81..28146a7f 100644
--- a/Source/Dafny/Translator.cs
+++ b/Source/Dafny/Translator.cs
@@ -479,6 +479,22 @@ namespace Microsoft.Dafny {
i++;
}
}
+
+ // Add:
+ // function $IsA#Dt(d: DatatypeType): bool {
+ // Dt.Ctor0?(d) || Dt.Ctor1?(d) || ...
+ // }
+ var cases_dBv = new Bpl.Formal(dt.tok, new Bpl.TypedIdent(dt.tok, "d", predef.DatatypeType), true);
+ var cases_dId = new Bpl.IdentifierExpr(dt.tok, cases_dBv.Name, predef.DatatypeType);
+ Bpl.Expr cases_body = null;
+ foreach (DatatypeCtor ctor in dt.Ctors) {
+ var disj = FunctionCall(ctor.tok, ctor.QueryField.FullName, Bpl.Type.Bool, cases_dId);
+ cases_body = cases_body == null ? disj : Bpl.Expr.Or(cases_body, disj);
+ }
+ var cases_resType = new Bpl.Formal(dt.tok, new Bpl.TypedIdent(dt.tok, Bpl.TypedIdent.NoName, Bpl.Type.Bool), false);
+ var cases_fn = new Bpl.Function(dt.tok, "$IsA#" + dt.Name, new Bpl.VariableSeq(cases_dBv), cases_resType);
+ cases_fn.Body = cases_body;
+ sink.TopLevelDeclarations.Add(cases_fn);
}
void CreateBoundVariables(List<Formal/*!*/>/*!*/ formals, out Bpl.VariableSeq/*!*/ bvs, out List<Bpl.Expr/*!*/>/*!*/ args)
@@ -1022,8 +1038,124 @@ namespace Microsoft.Dafny {
ExpressionTranslator etran = new ExpressionTranslator(this, predef, m.tok);
Bpl.VariableSeq localVariables = new Bpl.VariableSeq();
GenerateImplPrelude(m, inParams, outParams, builder, localVariables);
+
Bpl.StmtList stmts;
if (!wellformednessProc) {
+ if (3 <= CommandLineOptions.Clo.DafnyInduction && m.IsGhost && m.Mod.Count == 0 && m.Outs.Count == 0) {
+ var posts = new List<Expression>();
+ m.Ens.ForEach(mfe => posts.Add(mfe.E));
+ var allIns = new List<Formal>();
+ if (!m.IsStatic) {
+ allIns.Add(new ThisSurrogate(m.tok, Resolver.GetThisType(m.tok, (ClassDecl)m.EnclosingClass)));
+ }
+ allIns.AddRange(m.Ins);
+ var inductionVars = ApplyInduction(allIns, m.Attributes, posts, delegate(System.IO.TextWriter wr) { wr.Write(m.FullName); });
+ if (inductionVars.Count != 0) {
+ // Let the parameters be this,x,y of the method M and suppose ApplyInduction returns this,y.
+ // Also, let Pre be the precondition and VF be the decreases clause.
+ // Then, insert into the method body what amounts to:
+ // assume case-analysis-on-parameter[[ y' ]];
+ // parallel (this', y' | Pre(this', x, y') && VF(this', x, y') << VF(this, x, y)) {
+ // this'.M(x, y');
+ // }
+ // Generate bound variables for the parallel statement, and a substitution for the Pre and VF
+
+ // assume case-analysis-on-parameter[[ y' ]];
+ foreach (var inFormal in m.Ins) {
+ var dt = inFormal.Type.AsDatatype;
+ if (dt != null) {
+ var funcID = new Bpl.FunctionCall(new Bpl.IdentifierExpr(inFormal.tok, "$IsA#" + dt.Name, Bpl.Type.Bool));
+ var f = new Bpl.IdentifierExpr(inFormal.tok, inFormal.UniqueName, TrType(inFormal.Type));
+ builder.Add(new Bpl.AssumeCmd(inFormal.tok, new Bpl.NAryExpr(inFormal.tok, funcID, new Bpl.ExprSeq(f))));
+ }
+ }
+
+ var parBoundVars = new List<BoundVar>();
+ Expression receiverReplacement = null;
+ var substMap = new Dictionary<IVariable, Expression>();
+ foreach (var iv in inductionVars) {
+ BoundVar bv;
+ IdentifierExpr ie;
+ CloneVariableAsBoundVar(iv.tok, iv, "$ih#" + iv.Name, out bv, out ie);
+ parBoundVars.Add(bv);
+ if (iv is ThisSurrogate) {
+ Contract.Assert(receiverReplacement == null && substMap.Count == 0); // the receiver comes first, if at all
+ receiverReplacement = ie;
+ } else {
+ substMap.Add(iv, ie);
+ }
+ }
+
+ // Generate a CallStmt for the recursive call
+ Expression recursiveCallReceiver;
+ if (receiverReplacement != null) {
+ recursiveCallReceiver = receiverReplacement;
+ } else if (m.IsStatic) {
+ recursiveCallReceiver = new StaticReceiverExpr(m.tok, (ClassDecl)m.EnclosingClass); // this also resolves it
+ } else {
+ recursiveCallReceiver = new ImplicitThisExpr(m.tok);
+ recursiveCallReceiver.Type = Resolver.GetThisType(m.tok, (ClassDecl)m.EnclosingClass); // resolve here
+ }
+ var recursiveCallArgs = new List<Expression>();
+ foreach (var inFormal in m.Ins) {
+ Expression inE;
+ if (substMap.TryGetValue(inFormal, out inE)) {
+ recursiveCallArgs.Add(inE);
+ } else {
+ var ie = new IdentifierExpr(inFormal.tok, inFormal.Name);
+ ie.Var = inFormal; // resolve here
+ ie.Type = inFormal.Type; // resolve here
+ recursiveCallArgs.Add(ie);
+ }
+ }
+ var recursiveCall = new CallStmt(m.tok, new List<Expression>(), recursiveCallReceiver, m.Name, recursiveCallArgs);
+ recursiveCall.Method = m; // resolve here
+
+ Expression parRange = new LiteralExpr(m.tok, true);
+ parRange.Type = Type.Bool; // resolve here
+ if (receiverReplacement != null) {
+ // add "this' != null" to the range
+ var nil = new LiteralExpr(receiverReplacement.tok);
+ nil.Type = receiverReplacement.Type; // resolve here
+ var neqNull = new BinaryExpr(receiverReplacement.tok, BinaryExpr.Opcode.Neq, receiverReplacement, nil);
+ neqNull.ResolvedOp = BinaryExpr.ResolvedOpcode.NeqCommon; // resolve here
+ neqNull.Type = Type.Bool; // resolve here
+ parRange = DafnyAnd(parRange, neqNull);
+ }
+ foreach (var pre in m.Req) {
+ if (!pre.IsFree) {
+ parRange = DafnyAnd(parRange, Substitute(pre.E, receiverReplacement, substMap));
+ }
+ }
+ // construct an expression (generator) for: VF' << VF
+ ExpressionConverter decrCheck = delegate(Dictionary<IVariable, Expression> decrSubstMap) {
+ var decrToks = new List<IToken>();
+ var decrTypes = new List<Type>();
+ var decrCallee = new List<Bpl.Expr>();
+ var decrCaller = new List<Bpl.Expr>();
+ bool decrInferred; // we don't actually care
+ foreach (var ee in MethodDecreasesWithDefault(m, out decrInferred)) {
+ decrToks.Add(ee.tok);
+ decrTypes.Add(ee.Type);
+ decrCaller.Add(etran.TrExpr(ee));
+ Expression es = Substitute(ee, receiverReplacement, substMap);
+ es = Substitute(es, null, decrSubstMap);
+ decrCallee.Add(etran.TrExpr(es));
+ }
+ return DecreasesCheck(decrToks, decrTypes, decrCallee, decrCaller, etran, null, null, false, true);
+ };
+
+#if VERIFY_CORRECTNESS_OF_TRANSLATION_PARALLEL_RANGE
+ var definedness = new Bpl.StmtListBuilder();
+ var exporter = new Bpl.StmtListBuilder();
+ TrParallelCall(m.tok, parBoundVars, parRange, decrCheck, recursiveCall, definedness, exporter, localVariables, etran);
+ // All done, so put the two pieces together
+ builder.Add(new Bpl.IfCmd(m.tok, null, definedness.Collect(m.tok), null, exporter.Collect(m.tok)));
+#else
+ TrParallelCall(m.tok, parBoundVars, parRange, decrCheck, recursiveCall, null, builder, localVariables, etran);
+#endif
+ }
+ }
// translate the body of the method
Contract.Assert(m.Body != null); // follows from method precondition and the if guard
stmts = TrStmt2StmtList(builder, m.Body, localVariables, etran);
@@ -1555,6 +1687,7 @@ namespace Microsoft.Dafny {
Expression precond = Substitute(p, e.Receiver, substMap);
r = BplAnd(r, etran.TrExpr(precond));
}
+ // TODO: if this is a recursive call, also conjoin the well-ordering predicate
return r;
} else if (expr is DatatypeValue) {
DatatypeValue dtv = (DatatypeValue)expr;
@@ -1788,6 +1921,23 @@ namespace Microsoft.Dafny {
return total;
}
+ Expression DafnyAnd(Expression a, Expression b) {
+ Contract.Requires(a != null);
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<Expression>() != null);
+
+ if (LiteralExpr.IsTrue(a)) {
+ return b;
+ } else if (LiteralExpr.IsTrue(b)) {
+ return a;
+ } else {
+ BinaryExpr and = new BinaryExpr(a.tok, BinaryExpr.Opcode.And, a, b);
+ and.ResolvedOp = BinaryExpr.ResolvedOpcode.And; // resolve here
+ and.Type = Type.Bool; // resolve here
+ return and;
+ }
+ }
+
Bpl.Expr BplAnd(Bpl.Expr a, Bpl.Expr b) {
Contract.Requires(a != null);
Contract.Requires(b != null);
@@ -2282,10 +2432,7 @@ namespace Microsoft.Dafny {
if (prefix == null) {
prefix = guardConjunct;
} else {
- BinaryExpr and = new BinaryExpr(tok, BinaryExpr.Opcode.And, prefix, guardConjunct);
- and.ResolvedOp = BinaryExpr.ResolvedOpcode.And; // resolve here
- and.Type = Type.Bool; // resolve here
- prefix = and;
+ prefix = DafnyAnd(prefix, guardConjunct);
}
}
}
@@ -2353,6 +2500,20 @@ namespace Microsoft.Dafny {
}
}
+ void CloneVariableAsBoundVar(IToken tok, IVariable iv, string prefix, out BoundVar bv, out IdentifierExpr ie) {
+ Contract.Requires(tok != null);
+ Contract.Requires(iv != null);
+ Contract.Requires(prefix != null);
+ Contract.Ensures(Contract.ValueAtReturn(out bv) != null);
+ Contract.Ensures(Contract.ValueAtReturn(out ie) != null);
+
+ bv = new BoundVar(tok, prefix + otherTmpVarCount, iv.Type);
+ otherTmpVarCount++; // use this counter, but for a Dafny name (the idea being that the number and the initial "_" in the name might avoid name conflicts)
+ ie = new IdentifierExpr(tok, bv.Name);
+ ie.Var = bv; // resolve here
+ ie.Type = bv.Type; // resolve here
+ }
+
Bpl.Constant GetClass(TopLevelDecl cl)
{
Contract.Requires(cl != null);
@@ -3118,33 +3279,7 @@ namespace Microsoft.Dafny {
} else if (stmt is AssignStmt) {
AddComment(builder, stmt, "assignment statement");
AssignStmt s = (AssignStmt)stmt;
- var sel = s.Lhs.Resolved as SeqSelectExpr;
- if (sel != null && !sel.SelectOne) {
- // check LHS for definedness
- TrStmt_CheckWellformed(sel, builder, locals, etran, true);
- // array-range assignment
- var obj = etran.TrExpr(sel.Seq);
- Bpl.Expr low = sel.E0 == null ? Bpl.Expr.Literal(0) : etran.TrExpr(sel.E0);
- Bpl.Expr high = sel.E1 == null ? ArrayLength(s.Tok, obj, 1, 0) : etran.TrExpr(sel.E1);
- // check frame:
- // assert (forall i: int :: low <= i && i < high ==> $_Frame[arr,i]);
- Bpl.Variable iVar = new Bpl.BoundVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$i", Bpl.Type.Int));
- Bpl.IdentifierExpr ie = new Bpl.IdentifierExpr(s.Tok, iVar);
- Bpl.Expr ante = Bpl.Expr.And(Bpl.Expr.Le(low, ie), Bpl.Expr.Lt(ie, high));
- Bpl.Expr fieldName = FunctionCall(s.Tok, BuiltinFunction.IndexField, null, ie);
- Bpl.Expr cons = Bpl.Expr.SelectTok(s.Tok, etran.TheFrame(s.Tok), obj, fieldName);
- Bpl.Expr q = new Bpl.ForallExpr(s.Tok, new Bpl.VariableSeq(iVar), Bpl.Expr.Imp(ante, cons));
- builder.Add(Assert(s.Tok, q, "assignment may update an array element not in the enclosing method's modifies clause"));
- // compute the RHS
- Bpl.Expr bRhs = TrAssignmentRhs(s.Tok, null, null, s.Rhs, sel.Type, builder, locals, etran);
- // do the update: call UpdateArrayRange(arr, low, high, rhs);
- builder.Add(new Bpl.CallCmd(s.Tok, "UpdateArrayRange",
- new Bpl.ExprSeq(obj, low, high, bRhs),
- new Bpl.IdentifierExprSeq()));
- builder.Add(CaptureState(s.Tok));
- } else {
- TrAssignment(stmt.Tok, s.Lhs.Resolved, s.Rhs, builder, locals, etran);
- }
+ TrAssignment(stmt.Tok, s.Lhs.Resolved, s.Rhs, builder, locals, etran);
} else if (stmt is VarDecl) {
AddComment(builder, stmt, "var-declaration statement");
VarDecl s = (VarDecl)stmt;
@@ -3216,132 +3351,6 @@ namespace Microsoft.Dafny {
delegate(Bpl.StmtListBuilder bld, ExpressionTranslator e) { TrAlternatives(s.Alternatives, null, new Bpl.BreakCmd(s.Tok, null), bld, locals, e); },
builder, locals, etran);
- } else if (stmt is ForeachStmt) {
- AddComment(builder, stmt, "foreach statement");
- ForeachStmt s = (ForeachStmt)stmt;
- // assert/assume (forall o: ref :: o != null && o in S && Range(o) ==> Expr);
- // assert (forall o: ref :: o != null && o in S && Range(o) ==> IsTotal(RHS));
- // assert (forall o: ref :: o != null && o in S && Range(o) ==> $_Frame[o,F]); // this checks the enclosing modifies clause
- // var oldHeap := $Heap;
- // havoc $Heap;
- // assume $HeapSucc(oldHeap, $Heap);
- // assume (forall<alpha> o: ref, f: Field alpha :: $Heap[o,f] = oldHeap[o,f] || (f = F && o != null && o in S && Range(o)));
- // assume (forall o: ref :: o != null && o in S && Range(o) ==> $Heap[o,F] = RHS[$Heap := oldHeap]);
- // Note, $Heap[o,alloc] is intentionally omitted from the antecedent of the quantifier in the previous line. That
- // allocatedness property should hold automatically, because the set/seq quantified is a program expression, which
- // will have been constructed from allocated objects.
- // For sets, "o in S" means just that. For sequences, "o in S" is:
- // (exists i :: { Seq#Index(S,i) } 0 <= i && i < Seq#Length(S) && Seq#Index(S,i) == o)
-
- Bpl.BoundVariable oVar = new Bpl.BoundVariable(stmt.Tok, new Bpl.TypedIdent(stmt.Tok, s.BoundVar.UniqueName, TrType(s.BoundVar.Type)));
- Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(stmt.Tok, oVar);
-
- // colection
- TrStmt_CheckWellformed(s.Collection, builder, locals, etran, true);
- Bpl.Expr oInS;
- if (s.Collection.Type is SetType) {
- oInS = etran.TrInSet(stmt.Tok, o, s.Collection, ((SetType)s.Collection.Type).Arg);
- } else if (s.Collection.Type is MultiSetType) {
- // should not be reached.
- Contract.Assert(false);
- throw new cce.UnreachableException();
- } else {
- Bpl.BoundVariable iVar = new Bpl.BoundVariable(stmt.Tok, new Bpl.TypedIdent(stmt.Tok, "$i", Bpl.Type.Int));
- Bpl.IdentifierExpr i = new Bpl.IdentifierExpr(stmt.Tok, iVar);
- Bpl.Expr S = etran.TrExpr(s.Collection);
- Bpl.Expr range = InSeqRange(stmt.Tok, i, S, true, null, false);
- Bpl.Expr Si = FunctionCall(stmt.Tok, BuiltinFunction.SeqIndex, predef.BoxType, S, i);
- Bpl.Trigger tr = new Bpl.Trigger(stmt.Tok, true, new Bpl.ExprSeq(Si));
- // TODO: in the next line, the == should be replaced by something that understands extensionality, for sets and sequences
- var boxO = etran.BoxIfNecessary(stmt.Tok, o, ((SeqType)s.Collection.Type).Arg);
- oInS = new Bpl.ExistsExpr(stmt.Tok, new Bpl.VariableSeq(iVar), tr, Bpl.Expr.And(range, Bpl.Expr.Eq(Si, boxO)));
- }
- oInS = Bpl.Expr.And(Bpl.Expr.Neq(o, predef.Null), oInS);
-
- // range
- Bpl.Expr qr = new Bpl.ForallExpr(s.Range.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, IsTotal(s.Range, etran)));
- builder.Add(AssertNS(s.Range.tok, qr, "range expression must be well defined"));
- oInS = Bpl.Expr.And(oInS, etran.TrExpr(s.Range));
-
- // sequence of asserts and assumes and uses
- foreach (PredicateStmt ps in s.BodyPrefix) {
- if (ps is AssertStmt || CommandLineOptions.Clo.DisallowSoundnessCheating) {
- Bpl.Expr q = new Bpl.ForallExpr(ps.Expr.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, IsTotal(ps.Expr, etran)));
- builder.Add(AssertNS(ps.Expr.tok, q, "assert condition must be well defined")); // totality check
- bool splitHappened;
- var ss = TrSplitExpr(ps.Expr, etran, out splitHappened);
- if (!splitHappened) {
- Bpl.Expr e = etran.TrExpr(ps.Expr);
- q = new Bpl.ForallExpr(ps.Expr.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, e));
- builder.Add(Assert(ps.Expr.tok, q, "assertion violation"));
- } else {
- foreach (var split in ss) {
- if (!split.IsFree) {
- q = new Bpl.ForallExpr(split.E.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, split.E));
- builder.Add(AssertNS(split.E.tok, q, "assertion violation"));
- }
- }
- Bpl.Expr e = etran.TrExpr(ps.Expr);
- q = new Bpl.ForallExpr(ps.Expr.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, e));
- builder.Add(new Bpl.AssumeCmd(ps.Expr.tok, q));
- }
- } else if (ps is AssumeStmt) {
- Bpl.Expr eIsTotal = IsTotal(ps.Expr, etran);
- Bpl.Expr q = new Bpl.ForallExpr(ps.Expr.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, eIsTotal));
- builder.Add(AssertNS(ps.Expr.tok, q, "assume condition must be well defined")); // totality check
- } else {
- Contract.Assert(false);
- }
- Bpl.Expr enchilada = etran.TrExpr(ps.Expr); // the whole enchilada
- Bpl.Expr qEnchilada = new Bpl.ForallExpr(ps.Expr.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, enchilada));
- builder.Add(new Bpl.AssumeCmd(ps.Expr.tok, qEnchilada));
- }
-
- // Check RHS of assignment to be well defined
- ExprRhs rhsExpr = s.BodyAssign.Rhs as ExprRhs;
- if (rhsExpr != null) {
- // assert (forall o: ref :: o != null && o in S && Range(o) ==> IsTotal(RHS));
- Bpl.Expr bbb = Bpl.Expr.Imp(oInS, IsTotal(rhsExpr.Expr, etran));
- Bpl.Expr qqq = new Bpl.ForallExpr(stmt.Tok, new Bpl.VariableSeq(oVar), bbb);
- builder.Add(AssertNS(rhsExpr.Expr.tok, qqq, "RHS of assignment must be well defined")); // totality check
- }
-
- // Here comes: assert (forall o: ref :: o != null && o in S && Range(o) ==> $_Frame[o,F]);
- Bpl.Expr body = Bpl.Expr.Imp(oInS, Bpl.Expr.Select(etran.TheFrame(stmt.Tok), o, GetField((FieldSelectExpr)s.BodyAssign.Lhs)));
- Bpl.Expr qq = new Bpl.ForallExpr(stmt.Tok, new Bpl.VariableSeq(oVar), body);
- builder.Add(Assert(s.BodyAssign.Tok, qq, "foreach assignment may update an object not in the enclosing method's modifies clause"));
-
- // Set up prevHeap
- Bpl.IdentifierExpr prevHeap = GetPrevHeapVar_IdExpr(stmt.Tok, locals);
- builder.Add(Bpl.Cmd.SimpleAssign(stmt.Tok, prevHeap, etran.HeapExpr));
- builder.Add(new Bpl.HavocCmd(stmt.Tok, new Bpl.IdentifierExprSeq((Bpl.IdentifierExpr/*TODO: this cast is rather dubious*/)etran.HeapExpr)));
- builder.Add(new Bpl.AssumeCmd(stmt.Tok, FunctionCall(stmt.Tok, BuiltinFunction.HeapSucc, null, prevHeap, etran.HeapExpr)));
-
- // Here comes: assume (forall<alpha> o: ref, f: Field alpha :: $Heap[o,f] = oldHeap[o,f] || (f = F && o != null && o in S && Range(o)));
- Bpl.TypeVariable alpha = new Bpl.TypeVariable(stmt.Tok, "alpha");
- Bpl.BoundVariable fVar = new Bpl.BoundVariable(stmt.Tok, new Bpl.TypedIdent(stmt.Tok, "$f", predef.FieldName(stmt.Tok, alpha)));
- Bpl.IdentifierExpr f = new Bpl.IdentifierExpr(stmt.Tok, fVar);
- Bpl.Expr heapOF = ExpressionTranslator.ReadHeap(stmt.Tok, etran.HeapExpr, o, f);
- Bpl.Expr oldHeapOF = ExpressionTranslator.ReadHeap(stmt.Tok, prevHeap, o, f);
- body = Bpl.Expr.Or(
- Bpl.Expr.Eq(heapOF, oldHeapOF),
- Bpl.Expr.And(
- Bpl.Expr.Eq(f, GetField((FieldSelectExpr)s.BodyAssign.Lhs)),
- oInS));
- qq = new Bpl.ForallExpr(stmt.Tok, new Bpl.TypeVariableSeq(alpha), new Bpl.VariableSeq(oVar, fVar), body);
- builder.Add(new Bpl.AssumeCmd(stmt.Tok, qq));
-
- // Here comes: assume (forall o: ref :: o != null && o in S && Range(o) ==> $Heap[o,F] = RHS[$Heap := oldHeap]);
- if (rhsExpr != null) {
- Bpl.Expr heapOField = ExpressionTranslator.ReadHeap(stmt.Tok, etran.HeapExpr, o, GetField((FieldSelectExpr)(s.BodyAssign).Lhs));
- ExpressionTranslator oldEtran = new ExpressionTranslator(this, predef, prevHeap);
- body = Bpl.Expr.Imp(oInS, Bpl.Expr.Eq(heapOField, oldEtran.TrExpr(rhsExpr.Expr)));
- qq = new Bpl.ForallExpr(stmt.Tok, new Bpl.VariableSeq(oVar), body);
- builder.Add(new Bpl.AssumeCmd(stmt.Tok, qq));
- }
-
- builder.Add(CaptureState(stmt.Tok));
-
} else if (stmt is ParallelStmt) {
AddComment(builder, stmt, "parallel statement");
var s = (ParallelStmt)stmt;
@@ -3356,7 +3365,14 @@ namespace Microsoft.Dafny {
builder.Add(CaptureState(stmt.Tok));
} else if (s.Kind == ParallelStmt.ParBodyKind.Call) {
- // TODO: call forall
+ Contract.Assert(s.Ens.Count == 0);
+ var s0 = (CallStmt)s.S0;
+ var definedness = new Bpl.StmtListBuilder();
+ var exporter = new Bpl.StmtListBuilder();
+ TrParallelCall(s.Tok, s.BoundVars, s.Range, null, s0, definedness, exporter, locals, etran);
+ // All done, so put the two pieces together
+ builder.Add(new Bpl.IfCmd(s.Tok, null, definedness.Collect(s.Tok), null, exporter.Collect(s.Tok)));
+ builder.Add(CaptureState(stmt.Tok));
} else if (s.Kind == ParallelStmt.ParBodyKind.Proof) {
var definedness = new Bpl.StmtListBuilder();
@@ -3450,18 +3466,18 @@ namespace Microsoft.Dafny {
// // check definedness of Range
// var x,y;
// havoc x,y;
- // CheckWellDefined( Range );
+ // CheckWellformed( Range );
// assume Range;
// // check definedness of the other expressions
// (a)
- // CheckWellDefined( E.F );
+ // CheckWellformed( E.F );
// check that E.f is in the modifies frame;
- // CheckWellDefined( G );
+ // CheckWellformed( G );
// check nat restrictions for the RHS
// (b)
- // CheckWellDefined( A[I0,I1,...] );
+ // CheckWellformed( A[I0,I1,...] );
// check that A[I0,I1,...] is in the modifies frame;
- // CheckWellDefined( G );
+ // CheckWellformed( G );
// check nat restrictions for the RHS
// // check for duplicate LHSs
// var x', y';
@@ -3492,11 +3508,9 @@ namespace Microsoft.Dafny {
// }
var substMap = SetupBoundVarsAsLocals(s.BoundVars, definedness, locals, etran);
- if (s.Range != null) {
- Expression range = Substitute(s.Range, null, substMap);
- TrStmt_CheckWellformed(range, definedness, locals, etran, false);
- definedness.Add(new Bpl.AssumeCmd(s.Range.tok, etran.TrExpr(range)));
- }
+ Expression range = Substitute(s.Range, null, substMap);
+ TrStmt_CheckWellformed(range, definedness, locals, etran, false);
+ definedness.Add(new Bpl.AssumeCmd(s.Range.tok, etran.TrExpr(range)));
var lhs = Substitute(s0.Lhs.Resolved, null, substMap);
TrStmt_CheckWellformed(lhs, definedness, locals, etran, false);
@@ -3508,17 +3522,23 @@ namespace Microsoft.Dafny {
var r = (ExprRhs)s0.Rhs;
var rhs = Substitute(r.Expr, null, substMap);
TrStmt_CheckWellformed(rhs, definedness, locals, etran, false);
- // TODO: check nat restrictions for the RHS
- // CheckSubrange(rhs.tok, bRhs, checkSubrangeType, definedness);
+ // check nat restrictions for the RHS
+ Type lhsType;
+ if (lhs is FieldSelectExpr) {
+ lhsType = ((FieldSelectExpr)lhs).Type;
+ } else if (lhs is SeqSelectExpr) {
+ lhsType = ((SeqSelectExpr)lhs).Type;
+ } else {
+ lhsType = ((MultiSelectExpr)lhs).Type;
+ }
+ CheckSubrange(r.Tok, etran.TrExpr(rhs), lhsType, definedness);
}
// check for duplicate LHSs
var substMapPrime = SetupBoundVarsAsLocals(s.BoundVars, definedness, locals, etran);
var lhsPrime = Substitute(s0.Lhs.Resolved, null, substMapPrime);
- if (s.Range != null) {
- Expression range = Substitute(s.Range, null, substMapPrime);
- definedness.Add(new Bpl.AssumeCmd(range.tok, etran.TrExpr(range)));
- }
+ range = Substitute(s.Range, null, substMapPrime);
+ definedness.Add(new Bpl.AssumeCmd(range.tok, etran.TrExpr(range)));
// assume !(x == x' && y == y');
Bpl.Expr eqs = Bpl.Expr.True;
foreach (var bv in s.BoundVars) {
@@ -3558,9 +3578,7 @@ namespace Microsoft.Dafny {
Bpl.Expr oldHeapOF = ExpressionTranslator.ReadHeap(s.Tok, prevHeap, o, f);
Bpl.VariableSeq xBvars = new Bpl.VariableSeq();
var xBody = etran.TrBoundVariables(s.BoundVars, xBvars);
- if (s.Range != null) {
- xBody = BplAnd(xBody, prevEtran.TrExpr(s.Range));
- }
+ xBody = BplAnd(xBody, prevEtran.TrExpr(s.Range));
Bpl.Expr xObj, xField;
GetObjFieldDetails(s0.Lhs.Resolved, prevEtran, out xObj, out xField);
xBody = BplAnd(xBody, Bpl.Expr.Eq(o, xObj));
@@ -3575,9 +3593,7 @@ namespace Microsoft.Dafny {
// $Heap[ Object(x,y)[$Heap:=oldHeap], Field(x,y)[$Heap:=oldHeap] ] == G[$Heap:=oldHeap] ));
xBvars = new Bpl.VariableSeq();
Bpl.Expr xAnte = etran.TrBoundVariables(s.BoundVars, xBvars);
- if (s.Range != null) {
- xAnte = BplAnd(xAnte, prevEtran.TrExpr(s.Range));
- }
+ xAnte = BplAnd(xAnte, prevEtran.TrExpr(s.Range));
var rhs = ((ExprRhs)s0.Rhs).Expr;
var g = prevEtran.TrExpr(rhs);
GetObjFieldDetails(s0.Lhs.Resolved, prevEtran, out xObj, out xField);
@@ -3596,6 +3612,90 @@ namespace Microsoft.Dafny {
}
}
+ delegate Bpl.Expr ExpressionConverter(Dictionary<IVariable, Expression> substMap);
+
+ void TrParallelCall(IToken tok, List<BoundVar> boundVars, Expression range, ExpressionConverter additionalRange, CallStmt s0,
+ Bpl.StmtListBuilder definedness, Bpl.StmtListBuilder exporter, Bpl.VariableSeq locals, ExpressionTranslator etran) {
+ Contract.Requires(tok != null);
+ Contract.Requires(boundVars != null);
+ Contract.Requires(range != null);
+ // additionalRange is allowed to be null
+ Contract.Requires(s0 != null);
+ // definedness is allowed to be null
+ Contract.Requires(exporter != null);
+ Contract.Requires(locals != null);
+ Contract.Requires(etran != null);
+
+ // Translate:
+ // parallel (x,y | Range(x,y)) {
+ // E(x,y) . M( Args(x,y) );
+ // }
+ // as:
+ // if (*) {
+ // var x,y;
+ // havoc x,y;
+ // CheckWellformed( Range );
+ // assume Range(x,y);
+ // assume additionalRange;
+ // Tr( Call );
+ // assume false;
+ // } else {
+ // assume (forall x,y :: Range(x,y) && additionalRange ==> Post( E(x,y), Args(x,y) ));
+ // }
+ // where Post(this,args) is the postcondition of method M.
+
+ if (definedness != null) {
+ // Note, it would be nicer (and arguably more appropriate) to do a SetupBoundVarsAsLocals
+ // here (rather than a TrBoundVariables). However, there is currently no way to apply
+ // a substMap to a statement (in particular, to s.Body), so that doesn't work here.
+ Bpl.VariableSeq bvars = new Bpl.VariableSeq();
+ var ante = etran.TrBoundVariables(boundVars, bvars, true);
+ locals.AddRange(bvars);
+ var havocIds = new Bpl.IdentifierExprSeq();
+ foreach (Bpl.Variable bv in bvars) {
+ havocIds.Add(new Bpl.IdentifierExpr(tok, bv));
+ }
+ definedness.Add(new Bpl.HavocCmd(tok, havocIds));
+ definedness.Add(new Bpl.AssumeCmd(tok, ante));
+ TrStmt_CheckWellformed(range, definedness, locals, etran, false);
+ definedness.Add(new Bpl.AssumeCmd(range.tok, etran.TrExpr(range)));
+ if (additionalRange != null) {
+ var es = additionalRange(new Dictionary<IVariable, Expression>());
+ definedness.Add(new Bpl.AssumeCmd(es.tok, es));
+ }
+
+ TrStmt(s0, definedness, locals, etran);
+
+ definedness.Add(new Bpl.AssumeCmd(tok, Bpl.Expr.False));
+ }
+
+ // Now for the other branch, where the postcondition of the call is exported.
+ {
+ var bvars = new Bpl.VariableSeq();
+ Dictionary<IVariable, Expression> substMap;
+ var ante = etran.TrBoundVariablesRename(boundVars, bvars, out substMap);
+ ante = BplAnd(ante, etran.TrExpr(Substitute(range, null, substMap)));
+ if (additionalRange != null) {
+ ante = BplAnd(ante, additionalRange(substMap));
+ }
+
+ var argsSubstMap = new Dictionary<IVariable, Expression>(); // maps formal arguments to actuals
+ Contract.Assert(s0.Method.Ins.Count == s0.Args.Count);
+ for (int i = 0; i < s0.Method.Ins.Count; i++) {
+ argsSubstMap.Add(s0.Method.Ins[i], s0.Args[i]);
+ }
+ Bpl.Expr post = Bpl.Expr.True;
+ foreach (var ens in s0.Method.Ens) {
+ var p = Substitute(ens.E, s0.Receiver, argsSubstMap); // substitute the call's actuals for the method's formals
+ p = Substitute(p, null, substMap); // substitute the renamed bound variables for the declared ones
+ post = BplAnd(post, etran.TrExpr(p));
+ }
+
+ Bpl.Expr qq = new Bpl.ForallExpr(tok, bvars, Bpl.Expr.Imp(ante, post));
+ exporter.Add(new Bpl.AssumeCmd(tok, qq));
+ }
+ }
+
void TrParallelProof(ParallelStmt s, Bpl.StmtListBuilder definedness, Bpl.StmtListBuilder exporter, Bpl.VariableSeq locals, ExpressionTranslator etran) {
// Translate:
// parallel (x,y | Range(x,y))
@@ -3607,10 +3707,10 @@ namespace Microsoft.Dafny {
// if (*) {
// var x,y;
// havoc x,y;
- // CheckWellDefined( Range );
+ // CheckWellformed( Range );
// assume Range(x,y);
// Tr( Body );
- // CheckWellDefined( Post );
+ // CheckWellformed( Post );
// assert Post;
// assume false;
// } else {
@@ -3629,10 +3729,8 @@ namespace Microsoft.Dafny {
}
definedness.Add(new Bpl.HavocCmd(s.Tok, havocIds));
definedness.Add(new Bpl.AssumeCmd(s.Tok, ante));
- if (s.Range != null) {
- TrStmt_CheckWellformed(s.Range, definedness, locals, etran, false);
- definedness.Add(new Bpl.AssumeCmd(s.Range.tok, etran.TrExpr(s.Range)));
- }
+ TrStmt_CheckWellformed(s.Range, definedness, locals, etran, false);
+ definedness.Add(new Bpl.AssumeCmd(s.Range.tok, etran.TrExpr(s.Range)));
TrStmt(s.Body, definedness, locals, etran);
@@ -3656,11 +3754,8 @@ namespace Microsoft.Dafny {
bvars = new Bpl.VariableSeq();
Dictionary<IVariable, Expression> substMap;
ante = etran.TrBoundVariablesRename(s.BoundVars, bvars, out substMap);
- if (s.Range != null) {
- var range = Substitute(s.Range, null, substMap);
- TrStmt_CheckWellformed(range, definedness, locals, etran, false);
- ante = BplAnd(ante, etran.TrExpr(range));
- }
+ var range = Substitute(s.Range, null, substMap);
+ ante = BplAnd(ante, etran.TrExpr(range));
Bpl.Expr post = Bpl.Expr.True;
foreach (var ens in s.Ens) {
@@ -3908,7 +4003,7 @@ namespace Microsoft.Dafny {
lhsTypes.Add(lhs.Type);
if (bLhss[i] == null) { // (in the current implementation, the second parameter "true" to ProcessLhss implies that all bLhss[*] will be null)
// create temporary local and assign it to bLhss[i]
- string nm = "$rhs#" + otherTmpVarCount;
+ string nm = "$rhs##" + otherTmpVarCount;
otherTmpVarCount++;
var ty = TrType(lhs.Type);
Bpl.Expr wh = GetWhereClause(lhs.tok, new Bpl.IdentifierExpr(lhs.tok, nm, ty), lhs.Type, etran);
@@ -3960,6 +4055,11 @@ namespace Microsoft.Dafny {
Expression receiver = bReceiver == null ? dafnyReceiver : new BoogieWrapper(bReceiver);
Bpl.ExprSeq ins = new Bpl.ExprSeq();
if (!method.IsStatic) {
+ if (bReceiver == null) {
+ if (!(dafnyReceiver is ThisExpr)) {
+ CheckNonNull(dafnyReceiver.tok, dafnyReceiver, builder, etran, null);
+ }
+ }
ins.Add(etran.TrExpr(receiver));
}
@@ -3970,7 +4070,7 @@ namespace Microsoft.Dafny {
Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
for (int i = 0; i < method.Ins.Count; i++) {
Formal p = method.Ins[i];
- VarDecl local = new VarDecl(p.tok, p.Name, p.Type, p.IsGhost);
+ VarDecl local = new VarDecl(p.tok, p.Name + "#", p.Type, p.IsGhost);
local.type = local.OptionalType; // resolve local here
IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
@@ -4008,7 +4108,7 @@ namespace Microsoft.Dafny {
var bLhs = Lhss[i];
if (ExpressionTranslator.ModeledAsBoxType(method.Outs[i].Type) && !ExpressionTranslator.ModeledAsBoxType(LhsTypes[i])) {
// we need an Unbox
- Bpl.LocalVariable var = new Bpl.LocalVariable(bLhs.tok, new Bpl.TypedIdent(bLhs.tok, "$tmp#" + otherTmpVarCount, predef.BoxType));
+ Bpl.LocalVariable var = new Bpl.LocalVariable(bLhs.tok, new Bpl.TypedIdent(bLhs.tok, "$tmp##" + otherTmpVarCount, predef.BoxType));
otherTmpVarCount++;
locals.Add(var);
Bpl.IdentifierExpr varIdE = new Bpl.IdentifierExpr(bLhs.tok, var.Name, predef.BoxType);
@@ -4215,7 +4315,7 @@ namespace Microsoft.Dafny {
Contract.Requires(etran != null);
Contract.Requires(predef != null);
Contract.Requires(types.Count == ee0.Count && ee0.Count == ee1.Count);
- Contract.Requires((builder != null) == (suffixMsg != null));
+ Contract.Requires(builder == null || suffixMsg != null);
Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
int N = types.Count;
@@ -4471,7 +4571,7 @@ namespace Microsoft.Dafny {
Contract.Requires(tok != null);
Contract.Requires(lhs != null);
Contract.Requires(!(lhs is ConcreteSyntaxExpression));
- Contract.Requires(!(lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne)); // array-range assignments are handled elsewhere
+ Contract.Requires(!(lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne)); // these were once allowed, but their functionality is now provided by 'parallel' statements
Contract.Requires(rhs != null);
Contract.Requires(builder != null);
Contract.Requires(cce.NonNullElements(locals));
@@ -4507,7 +4607,7 @@ namespace Microsoft.Dafny {
var lhs = lhss[i];
// the following assumes are part of the precondition, really
Contract.Assume(!(lhs is ConcreteSyntaxExpression));
- Contract.Assume(!(lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne)); // array-range assignments are handled elsewhere
+ Contract.Assume(!(lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne)); // array-range assignments are not allowed
Type lhsType = null;
if (lhs is IdentifierExpr) {
@@ -4599,7 +4699,7 @@ namespace Microsoft.Dafny {
} else if (lhs is SeqSelectExpr) {
SeqSelectExpr sel = (SeqSelectExpr)lhs;
- Contract.Assert(sel.SelectOne); // array-range assignments are handled elsewhere, see precondition
+ Contract.Assert(sel.SelectOne); // array-range assignments are not allowed
Contract.Assert(sel.Seq.Type != null && sel.Seq.Type.IsArrayType);
Contract.Assert(sel.E0 != null);
var obj = SaveInTemp(etran.TrExpr(sel.Seq), rhsCanAffectPreviouslyKnownExpressions,
@@ -6335,7 +6435,7 @@ namespace Microsoft.Dafny {
} else if ((position && expr is ForallExpr) || (!position && expr is ExistsExpr)) {
var e = (QuantifierExpr)expr;
var inductionVariables = ApplyInduction(e);
- if (inductionVariables.Count != 0) {
+ if (2 <= CommandLineOptions.Clo.DafnyInduction && inductionVariables.Count != 0) {
// From the given quantifier (forall n :: P(n)), generate the seemingly weaker proof obligation
// (forall n :: (forall k :: k < n ==> P(k)) ==> P(n))
// For an existential (exists n :: P(n)), it is
@@ -6427,12 +6527,30 @@ namespace Microsoft.Dafny {
}
}
- List<BoundVar> ApplyInduction(QuantifierExpr e)
+ List<BoundVar> ApplyInduction(QuantifierExpr e) {
+ return ApplyInduction(e.BoundVars, e.Attributes, new List<Expression>() { e.LogicalBody() },
+ delegate(System.IO.TextWriter wr) { new Printer(Console.Out).PrintExpression(e); });
+ }
+
+ delegate void TracePrinter(System.IO.TextWriter wr);
+
+ /// <summary>
+ /// Return a subset of "boundVars" (in the order giving in "boundVars") to which to apply induction to,
+ /// according to :induction attributes in "attributes" and heuristically interesting subexpressions of
+ /// "searchExprs".
+ /// </summary>
+ List<VarType> ApplyInduction<VarType>(List<VarType> boundVars, Attributes attributes, List<Expression> searchExprs, TracePrinter tracePrinter) where VarType : class, IVariable
{
- Contract.Requires(e != null);
- Contract.Ensures(Contract.Result<List<BoundVar>>() != null);
+ Contract.Requires(boundVars != null);
+ Contract.Requires(searchExprs != null);
+ Contract.Requires(tracePrinter != null);
+ Contract.Ensures(Contract.Result<List<VarType>>() != null);
- for (var a = e.Attributes; a != null; a = a.Prev) {
+ if (CommandLineOptions.Clo.DafnyInduction == 0) {
+ return new List<VarType>(); // don't apply induction
+ }
+
+ for (var a = attributes; a != null; a = a.Prev) {
if (a.Name == "induction") {
// Here are the supported forms of the :induction attribute.
// :induction -- apply induction to all bound variables
@@ -6449,26 +6567,44 @@ namespace Microsoft.Dafny {
if (arg != null && arg.Value is bool && !(bool)arg.Value) {
if (CommandLineOptions.Clo.Trace) {
Console.Write("Suppressing automatic induction for: ");
- new Printer(Console.Out).PrintExpression(e);
+ tracePrinter(Console.Out);
Console.WriteLine();
}
- return new List<BoundVar>();
+ return new List<VarType>();
}
}
// Handle {:induction L}
if (a.Args.Count != 0) {
- var L = new List<BoundVar>();
+ // check that all attribute arguments refer to bound variables; otherwise, go to default_form
+ var argsAsVars = new List<VarType>();
foreach (var arg in a.Args) {
- var id = arg.E.Resolved as IdentifierExpr;
- var bv = id == null ? null : id.Var as BoundVar;
- if (bv != null && e.BoundVars.Contains(bv)) {
- // add to L, but don't add duplicates
- if (!L.Contains(bv)) {
- L.Add(bv);
+ var theArg = arg.E.Resolved;
+ if (theArg is ThisExpr) {
+ foreach (var bv in boundVars) {
+ if (bv is ThisSurrogate) {
+ argsAsVars.Add(bv);
+ goto TRY_NEXT_ATTRIBUTE_ARGUMENT;
+ }
+ }
+ } else if (theArg is IdentifierExpr) {
+ var id = (IdentifierExpr)theArg;
+ var bv = id.Var as VarType;
+ if (bv != null && boundVars.Contains(bv)) {
+ argsAsVars.Add(bv);
+ goto TRY_NEXT_ATTRIBUTE_ARGUMENT;
}
- } else {
- goto USE_DEFAULT_FORM;
+ }
+ // the attribute argument was not one of the possible induction variables
+ goto USE_DEFAULT_FORM;
+ TRY_NEXT_ATTRIBUTE_ARGUMENT:
+ ;
+ }
+ // so, all attribute arguments are variables; add them to L in the order of the bound variables (not necessarily the order in the attribute)
+ var L = new List<VarType>();
+ foreach (var bv in boundVars) {
+ if (argsAsVars.Contains(bv)) {
+ L.Add(bv);
}
}
if (CommandLineOptions.Clo.Trace) {
@@ -6478,7 +6614,7 @@ namespace Microsoft.Dafny {
sep = ", ";
}
Console.Write(" of: ");
- new Printer(Console.Out).PrintExpression(e);
+ tracePrinter(Console.Out);
Console.WriteLine();
}
return L;
@@ -6488,20 +6624,24 @@ namespace Microsoft.Dafny {
// We have the {:induction} case, or something to be treated in the same way
if (CommandLineOptions.Clo.Trace) {
Console.Write("Applying requested induction on all bound variables of: ");
- new Printer(Console.Out).PrintExpression(e);
+ tracePrinter(Console.Out);
Console.WriteLine();
}
- return e.BoundVars;
+ return boundVars;
}
}
+ if (CommandLineOptions.Clo.DafnyInduction < 2) {
+ return new List<VarType>(); // don't apply induction
+ }
+
// consider automatically applying induction
- var inductionVariables = new List<BoundVar>();
- foreach (var n in e.BoundVars) {
- if (!n.Type.IsTypeParameter && VarOccursInArgumentToRecursiveFunction(e.LogicalBody(), n, null)) {
+ var inductionVariables = new List<VarType>();
+ foreach (var n in boundVars) {
+ if (!n.Type.IsTypeParameter && searchExprs.Exists(expr => VarOccursInArgumentToRecursiveFunction(expr, n))) {
if (CommandLineOptions.Clo.Trace) {
Console.Write("Applying automatic induction on variable '{0}' of: ", n.Name);
- new Printer(Console.Out).PrintExpression(e);
+ tracePrinter(Console.Out);
Console.WriteLine();
}
inductionVariables.Add(n);
@@ -6512,77 +6652,106 @@ namespace Microsoft.Dafny {
}
/// <summary>
- /// Returns 'true' iff
- /// there is a subexpression of 'expr' of the form 'F(...n...)' where 'F' is a recursive function
- /// and 'n' appears in an "elevated" subexpression of some argument to 'F',
- /// or
- /// 'p' is non-null and 'p' appears in an "elevated" subexpression of 'expr'.
- /// Requires that 'p' is either 'null' of 'n'.
+ /// Returns 'true' iff by looking at 'expr' the Induction Heuristic determines that induction should be applied to 'n'.
+ /// More precisely:
+ /// DafnyInductionHeuristic Return 'true'
+ /// ----------------------- -------------
+ /// 0 always
+ /// 1 if 'n' occurs as any subexpression (of 'expr')
+ /// 2 if 'n' occurs as any subexpression of any index argument of an array/sequence select expression or any argument to a recursive function
+ /// 3 if 'n' occurs as a prominent subexpression of any index argument of an array/sequence select expression or any argument to a recursive function
+ /// 4 if 'n' occurs as any subexpression of any argument to a recursive function
+ /// 5 if 'n' occurs as a prominent subexpression of any argument to a recursive function
+ /// 6 if 'n' occurs as a prominent subexpression of any decreases-influencing argument to a recursive function
+ /// Parameter 'n' is allowed to be a ThisSurrogate.
+ /// </summary>
+ bool VarOccursInArgumentToRecursiveFunction(Expression expr, IVariable n) {
+ switch (CommandLineOptions.Clo.DafnyInductionHeuristic) {
+ case 0: return true;
+ case 1: return ContainsFreeVariable(expr, false, n);
+ default: return VarOccursInArgumentToRecursiveFunction(expr, n, false);
+ }
+ }
+
+ /// <summary>
+ /// Worker routine for VarOccursInArgumentToRecursiveFunction(expr,n), where the additional parameter 'exprIsProminent' says whether or
+ /// not 'expr' prominent status in its context.
+ /// DafnyInductionHeuristic cases 0 and 1 are assumed to be handled elsewhere (i.e., a precondition of this method is DafnyInductionHeuristic is at least 2).
+ /// Parameter 'n' is allowed to be a ThisSurrogate.
/// </summary>
- static bool VarOccursInArgumentToRecursiveFunction(Expression expr, BoundVar n, BoundVar p) {
+ bool VarOccursInArgumentToRecursiveFunction(Expression expr, IVariable n, bool exprIsProminent) {
Contract.Requires(expr != null);
Contract.Requires(n != null);
- if (expr is LiteralExpr || expr is WildcardExpr || expr is ThisExpr || expr is BoogieWrapper) {
- return false;
+ // The following variable is what gets passed down to recursive calls if the subexpression does not itself acquire prominent status.
+ var subExprIsProminent = CommandLineOptions.Clo.DafnyInductionHeuristic == 2 || CommandLineOptions.Clo.DafnyInductionHeuristic == 4 ? /*once prominent, always prominent*/exprIsProminent : /*reset the prominent status*/false;
+
+ if (expr is ThisExpr) {
+ return exprIsProminent && n is ThisSurrogate;
} else if (expr is IdentifierExpr) {
var e = (IdentifierExpr)expr;
- return p != null && e.Var == p;
- } else if (expr is DisplayExpression) {
- var e = (DisplayExpression)expr;
- return e.Elements.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, null)); // subexpressions are not "elevated"
- } else if (expr is FieldSelectExpr) {
- var e = (FieldSelectExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.Obj, n, null); // subexpressions are not "elevated"
+ return exprIsProminent && e.Var == n;
} else if (expr is SeqSelectExpr) {
var e = (SeqSelectExpr)expr;
- p = e.SelectOne ? null : p;
- return VarOccursInArgumentToRecursiveFunction(e.Seq, n, null) || // this subexpression is not "elevated"
- (e.E0 != null && VarOccursInArgumentToRecursiveFunction(e.E0, n, p)) || // this one is, if the SeqSelectExpr denotes a range
- (e.E1 != null && VarOccursInArgumentToRecursiveFunction(e.E1, n, p)); // ditto
- } else if (expr is SeqUpdateExpr) {
- var e = (SeqUpdateExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.Seq, n, p) || // this subexpression is "elevated"
- VarOccursInArgumentToRecursiveFunction(e.Index, n, null) || // but this one
- VarOccursInArgumentToRecursiveFunction(e.Value, n, null); // and this one are not
+ var q = CommandLineOptions.Clo.DafnyInductionHeuristic < 4 || subExprIsProminent;
+ return VarOccursInArgumentToRecursiveFunction(e.Seq, n, subExprIsProminent) || // this subexpression does not acquire "prominent" status
+ (e.E0 != null && VarOccursInArgumentToRecursiveFunction(e.E0, n, q)) || // this one does (unless arrays/sequences are excluded)
+ (e.E1 != null && VarOccursInArgumentToRecursiveFunction(e.E1, n, q)); // ditto
} else if (expr is MultiSelectExpr) {
var e = (MultiSelectExpr)expr;
- // subexpressions are not "elevated"
- return VarOccursInArgumentToRecursiveFunction(e.Array, n, null) ||
- e.Indices.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, null));
+ var q = CommandLineOptions.Clo.DafnyInductionHeuristic < 4 || subExprIsProminent;
+ return VarOccursInArgumentToRecursiveFunction(e.Array, n, subExprIsProminent) ||
+ e.Indices.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, q));
} else if (expr is FunctionCallExpr) {
var e = (FunctionCallExpr)expr;
- // For recursive functions: arguments are "elevated"
- // For non-recursive function: arguments are "elevated" if the call is
- if (e.Function.IsRecursive) {
- p = n;
+ // For recursive functions: arguments are "prominent"
+ // For non-recursive function: arguments are "prominent" if the call is
+ var rec = e.Function.IsRecursive;
+ bool inferredDecreases; // we don't actually care
+ var decr = FunctionDecreasesWithDefault(e.Function, out inferredDecreases);
+ bool variantArgument;
+ if (CommandLineOptions.Clo.DafnyInductionHeuristic < 6) {
+ variantArgument = rec;
+ } else {
+ // The receiver is considered to be "variant" if the function is recursive and the receiver participates
+ // in the effective decreases clause of the function. The receiver participates if it's a free variable
+ // of a term in the explicit decreases clause.
+ variantArgument = rec && decr.Exists(ee => ContainsFreeVariable(ee, true, null));
+ }
+ if (VarOccursInArgumentToRecursiveFunction(e.Receiver, n, variantArgument || subExprIsProminent)) {
+ return true;
}
- return VarOccursInArgumentToRecursiveFunction(e.Receiver, n, p) ||
- e.Args.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, p));
+ Contract.Assert(e.Function.Formals.Count == e.Args.Count);
+ for (int i = 0; i < e.Function.Formals.Count; i++) {
+ var f = e.Function.Formals[i];
+ var exp = e.Args[i];
+ if (CommandLineOptions.Clo.DafnyInductionHeuristic < 6) {
+ variantArgument = rec;
+ } else {
+ // The argument position is considered to be "variant" if the function is recursive and the argument participates
+ // in the effective decreases clause of the function. The argument participates if it's a free variable
+ // of a term in the explicit decreases clause.
+ variantArgument = rec && decr.Exists(ee => ContainsFreeVariable(ee, false, f));
+ }
+ if (VarOccursInArgumentToRecursiveFunction(exp, n, variantArgument || subExprIsProminent)) {
+ return true;
+ }
+ }
+ return false;
} else if (expr is DatatypeValue) {
var e = (DatatypeValue)expr;
- if (!n.Type.IsDatatype) {
- p = null;
- }
- return e.Arguments.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, p));
+ var q = n.Type.IsDatatype ? exprIsProminent : subExprIsProminent; // prominent status continues, if we're looking for a variable whose type is a datatype
+ return e.Arguments.Exists(exp => VarOccursInArgumentToRecursiveFunction(exp, n, q));
} else if (expr is OldExpr) {
var e = (OldExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.E, n, p);
- } else if (expr is MultiSetFormingExpr) {
- var e = (MultiSetFormingExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.E, n, p);
- } else if (expr is FreshExpr) {
- var e = (FreshExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.E, n, null);
- } else if (expr is AllocatedExpr) {
- var e = (AllocatedExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.E, n, null);
+ return VarOccursInArgumentToRecursiveFunction(e.E, n, exprIsProminent); // prominent status continues
} else if (expr is UnaryExpr) {
var e = (UnaryExpr)expr;
- // arguments to both Not and SeqLength are "elevated"
- return VarOccursInArgumentToRecursiveFunction(e.E, n, p);
+ // both Not and SeqLength preserve prominence
+ return VarOccursInArgumentToRecursiveFunction(e.E, n, exprIsProminent);
} else if (expr is BinaryExpr) {
var e = (BinaryExpr)expr;
+ bool q;
switch (e.ResolvedOp) {
case BinaryExpr.ResolvedOpcode.Add:
case BinaryExpr.ResolvedOpcode.Sub:
@@ -6593,35 +6762,39 @@ namespace Microsoft.Dafny {
case BinaryExpr.ResolvedOpcode.Intersection:
case BinaryExpr.ResolvedOpcode.SetDifference:
case BinaryExpr.ResolvedOpcode.Concat:
- // these operators have "elevated" arguments
+ // these operators preserve prominence
+ q = exprIsProminent;
break;
default:
// whereas all other binary operators do not
- p = null;
+ q = subExprIsProminent;
break;
}
- return VarOccursInArgumentToRecursiveFunction(e.E0, n, p) ||
- VarOccursInArgumentToRecursiveFunction(e.E1, n, p);
- } else if (expr is ComprehensionExpr) {
- var e = (ComprehensionExpr)expr;
- return (e.Range != null && VarOccursInArgumentToRecursiveFunction(e.Range, n, null)) ||
- VarOccursInArgumentToRecursiveFunction(e.Term, n, null);
+ return VarOccursInArgumentToRecursiveFunction(e.E0, n, q) ||
+ VarOccursInArgumentToRecursiveFunction(e.E1, n, q);
} else if (expr is ITEExpr) {
var e = (ITEExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.Test, n, null) || // test is not "elevated"
- VarOccursInArgumentToRecursiveFunction(e.Thn, n, p) || // but the two branches are
- VarOccursInArgumentToRecursiveFunction(e.Els, n, p);
- } else if (expr is ConcreteSyntaxExpression) {
- var e = (ConcreteSyntaxExpression)expr;
- return VarOccursInArgumentToRecursiveFunction(e.ResolvedExpression, n, p);
- } else if (expr is BoxingCastExpr) {
- var e = (BoxingCastExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.E, n, p);
- } else if (expr is UnboxingCastExpr) {
- var e = (UnboxingCastExpr)expr;
- return VarOccursInArgumentToRecursiveFunction(e.E, n, p);
+ return VarOccursInArgumentToRecursiveFunction(e.Test, n, subExprIsProminent) || // test is not "prominent"
+ VarOccursInArgumentToRecursiveFunction(e.Thn, n, exprIsProminent) || // but the two branches are
+ VarOccursInArgumentToRecursiveFunction(e.Els, n, exprIsProminent);
+ } else if (expr is OldExpr ||
+ expr is ConcreteSyntaxExpression ||
+ expr is BoxingCastExpr ||
+ expr is UnboxingCastExpr) {
+ foreach (var exp in expr.SubExpressions) {
+ if (VarOccursInArgumentToRecursiveFunction(exp, n, exprIsProminent)) { // maintain prominence
+ return true;
+ }
+ }
+ return false;
} else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member
+ // in all other cases, reset the prominence status and recurse on the subexpressions
+ foreach (var exp in expr.SubExpressions) {
+ if (VarOccursInArgumentToRecursiveFunction(exp, n, subExprIsProminent)) {
+ return true;
+ }
+ }
+ return false;
}
}
@@ -6660,7 +6833,31 @@ namespace Microsoft.Dafny {
}
}
- static Expression Substitute(Expression expr, Expression receiverReplacement, Dictionary<IVariable,Expression/*!*/>/*!*/ substMap) {
+ /// <summary>
+ /// Returns true iff 'v' occurs as a free variable in 'expr'.
+ /// Parameter 'v' is allowed to be a ThisSurrogate, in which case the method return true iff 'this'
+ /// occurs in 'expr'.
+ /// </summary>
+ static bool ContainsFreeVariable(Expression expr, bool lookForReceiver, IVariable v) {
+ Contract.Requires(expr != null);
+ Contract.Requires(lookForReceiver || v != null);
+
+ if (expr is ThisExpr) {
+ return lookForReceiver || v is ThisSurrogate;
+ } else if (expr is IdentifierExpr) {
+ IdentifierExpr e = (IdentifierExpr)expr;
+ return e.Var == v;
+ } else {
+ foreach (var ee in expr.SubExpressions) {
+ if (ContainsFreeVariable(ee, lookForReceiver, v)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ static Expression Substitute(Expression expr, Expression receiverReplacement, Dictionary<IVariable, Expression/*!*/>/*!*/ substMap) {
Contract.Requires(expr != null);
Contract.Requires(cce.NonNullDictionaryAndValues(substMap));
Contract.Ensures(Contract.Result<Expression>() != null);
@@ -6746,7 +6943,7 @@ namespace Microsoft.Dafny {
} else if (expr is OldExpr) {
OldExpr e = (OldExpr)expr;
- Expression se = Substitute(e.E, receiverReplacement, substMap);
+ Expression se = Substitute(e.E, receiverReplacement, substMap); // TODO: whoa, won't this do improper variable capture?
if (se != e.E) {
newExpr = new OldExpr(expr.tok, se);
}
diff --git a/Source/Model/Model.cs b/Source/Model/Model.cs
index 643a6b03..c725c96a 100644
--- a/Source/Model/Model.cs
+++ b/Source/Model/Model.cs
@@ -34,6 +34,7 @@ using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
+using System.Diagnostics;
namespace Microsoft.Boogie
{
@@ -46,7 +47,8 @@ namespace Microsoft.Boogie
BitVector,
Boolean,
Uninterpreted,
- Array
+ Array,
+ DataValue
}
abstract public class Element
@@ -120,6 +122,30 @@ namespace Microsoft.Boogie
public override ElementKind Kind { get { return ElementKind.Array; } }
public override string ToString() { return string.Format("as-array[{0}]", Value.Name); }
}
+
+ public class DatatypeValue : Element
+ {
+ public readonly string ConstructorName;
+ public readonly Element[] Arguments;
+ internal DatatypeValue(Model p, string name, List<Element> args) : base(p) {
+ ConstructorName = name;
+ Arguments = args.ToArray();
+ }
+ public override ElementKind Kind { get { return ElementKind.DataValue; } }
+ public override string ToString() {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(ConstructorName + "(");
+ int count = 0;
+ foreach (DatatypeValue arg in Arguments) {
+ count++;
+ builder.Append(arg);
+ if (count < Arguments.Length)
+ builder.Append(", ");
+ }
+ builder.Append(")");
+ return builder.ToString();
+ }
+ }
#endregion
public class Func
@@ -416,7 +442,7 @@ namespace Microsoft.Boogie
var fnName = name.Substring(9, name.Length - 10);
return new Array(this, MkFunc(fnName, 1));
} else {
- return null;
+ return new DatatypeValue(this, name, new List<Element>());
}
}
@@ -666,6 +692,66 @@ namespace Microsoft.Boogie
static char[] seps = new char[] { ' ' };
+ int CountOpenParentheses(string s, int n) {
+ int f = n;
+ foreach (char c in s) {
+ if (c == '(')
+ f++;
+ else if (c == ')')
+ f--;
+ }
+ if (f < 0) BadModel("mismatched parentheses in datatype term");
+ return f;
+ }
+
+ List<object> GetFunctionTuple() {
+ string newLine = ReadLine();
+ if (newLine == null)
+ return null;
+ string line = newLine;
+ int openParenCounter = CountOpenParentheses(newLine, 0);
+ if (!newLine.Contains("}")) {
+ while (openParenCounter > 0) {
+ newLine = ReadLine();
+ if (newLine == null) {
+ return null;
+ }
+ line += newLine;
+ openParenCounter = CountOpenParentheses(newLine, openParenCounter);
+ }
+ }
+
+ line = line.Replace("(", " ( ");
+ line = line.Replace(")", " ) ");
+ var tuple = line.Split(seps, StringSplitOptions.RemoveEmptyEntries);
+
+ List<object> newTuple = new List<object>();
+ Stack<List<object>> wordStack = new Stack<List<object>>();
+ for (int i = 0; i < tuple.Length; i++) {
+ string elem = tuple[i];
+ if (elem == "(") {
+ List<object> ls = new List<object>();
+ wordStack.Push(ls);
+ }
+ else if (elem == ")") {
+ List<object> ls = wordStack.Pop();
+ if (wordStack.Count > 0) {
+ wordStack.Peek().Add(ls);
+ }
+ else {
+ newTuple.Add(ls);
+ }
+ }
+ else if (wordStack.Count > 0) {
+ wordStack.Peek().Add(elem);
+ }
+ else {
+ newTuple.Add(elem);
+ }
+ }
+ return newTuple;
+ }
+
string[] GetWords(string line)
{
if (line == null)
@@ -684,6 +770,18 @@ namespace Microsoft.Boogie
return l;
}
+ Element GetElt(object o) {
+ string s = o as string;
+ if (s != null)
+ return GetElt(s);
+ List<object> os = (List<object>)o;
+ List<Element> args = new List<Element>();
+ for (int i = 1; i < os.Count; i++) {
+ args.Add(GetElt(os[i]));
+ }
+ return new DatatypeValue(currModel, (string)os[0], args);
+ }
+
Element GetElt(string name)
{
Element ret;
@@ -782,43 +880,36 @@ namespace Microsoft.Boogie
var funName = words[0];
if (lastWord == "{") {
- for (; ; ) {
- var tuple = GetWords(ReadLine());
+ for ( ; ; ) {
+ var tuple = GetFunctionTuple();
if (tuple == null) BadModel("EOF in function table");
- if (tuple.Length == 0) continue;
- if (tuple.Length == 1 && tuple[0] == "}") break;
-
- var resultName = tuple[tuple.Length - 1];
- var isElse = false;
-
- if (tuple.Length == 1 && fn == null)
- isElse = true;
-
- if (!isElse && (tuple.Length < 3 || tuple[tuple.Length - 2] != "->")) BadModel("invalid function tuple definition");
-
- if (isElse || tuple[0] == "else") {
- var hasBrace = false;
- if (resultName.EndsWith("}")) {
- hasBrace = true;
- resultName = resultName.Substring(0, resultName.Length - 1);
+ if (tuple.Count == 0) continue;
+ string tuple0 = tuple[0] as string;
+ if (tuple.Count == 1) {
+ if (fn != null) {
+ if (tuple0 != "}") BadModel("invalid function tuple definition");
+ break;
}
- if (!resultName.StartsWith("#unspec")) {
+ else {
+ fn = currModel.TryGetFunc(funName);
if (fn == null)
- fn = currModel.TryGetFunc(funName);
- // if it's still null, we don't know the arity, so just skip it
- if (fn != null) {
- fn.Else = GetElt(resultName);
- }
- }
-
- if (hasBrace)
- break;
- else
+ fn = currModel.MkFunc(funName, 1);
+ fn.Else = GetElt(tuple0);
continue;
+ }
+ }
+ string tuplePenultimate = tuple[tuple.Count - 2] as string;
+ if (tuplePenultimate != "->") BadModel("invalid function tuple definition");
+ var resultName = tuple[tuple.Count - 1];
+ if (tuple0 == "else") {
+ if (fn != null && !(resultName is string && ((string)resultName) == "#unspecified")) {
+ fn.Else = GetElt(resultName);
+ }
+ continue;
}
if (fn == null)
- fn = currModel.MkFunc(funName, tuple.Length - 2);
+ fn = currModel.MkFunc(funName, tuple.Count - 2);
var args = new Element[fn.Arity];
for (int i = 0; i < fn.Arity; ++i)
args[i] = GetElt(tuple[i]);
diff --git a/Source/ModelViewer/DafnyProvider.cs b/Source/ModelViewer/DafnyProvider.cs
index 32912113..328bbb26 100644
--- a/Source/ModelViewer/DafnyProvider.cs
+++ b/Source/ModelViewer/DafnyProvider.cs
@@ -92,9 +92,13 @@ namespace Microsoft.Boogie.ModelViewer.Dafny
{
if (name.StartsWith("$")) // this covers $Heap and $_Frame and $nw...
return null;
+ if (name.Contains("##")) // a temporary variable of the translation
+ return null;
+#if SOMETIME_AGAIN
var hash = name.IndexOf('#');
if (0 < hash)
return name.Substring(0, hash);
+#endif
return name;
}
diff --git a/Source/ModelViewer/Namer.cs b/Source/ModelViewer/Namer.cs
index 49ff93ea..c1d7fcd3 100644
--- a/Source/ModelViewer/Namer.cs
+++ b/Source/ModelViewer/Namer.cs
@@ -231,7 +231,7 @@ namespace Microsoft.Boogie.ModelViewer
for (int i = 0; i < len; ++i) {
var c1 = f1[i];
var c2 = f2[i];
- if ('0' <= c1 && c1 <= '9' && '0' <= c2 && c2 <= '9') {
+ if ('0' <= c1 && c1 <= '9' && '0' <= c2 && c2 <= '9') {
numberPos = i;
break;
}
@@ -531,7 +531,7 @@ namespace Microsoft.Boogie.ModelViewer
protected virtual string Format()
{
- if (args.Length == 0)
+ if (args == null || args.Length == 0)
return format;
var res = new StringBuilder(format.Length);
diff --git a/Source/ModelViewer/VccProvider.cs b/Source/ModelViewer/VccProvider.cs
index b5ba6c22..ede520cb 100644
--- a/Source/ModelViewer/VccProvider.cs
+++ b/Source/ModelViewer/VccProvider.cs
@@ -135,7 +135,11 @@ namespace Microsoft.Boogie.ModelViewer.Vcc
sn.SetupVars();
states.Add(sn);
}
+
var allStates = states.ToArray();
+ if (allStates.Length == 1 && allStates[0].vars.Count == 0) {
+ throw new Exception("This VCC model doesn't contain any variables. Was it saved with the -bvd option?");
+ }
states.Clear();
var i = 0;
while (i < allStates.Length) {
diff --git a/Source/Provers/Isabelle/Prover.cs b/Source/Provers/Isabelle/Prover.cs
index 60a8de22..35913019 100644
--- a/Source/Provers/Isabelle/Prover.cs
+++ b/Source/Provers/Isabelle/Prover.cs
@@ -192,7 +192,7 @@ namespace Microsoft.Boogie.Isabelle {
public readonly bool AllTypes;
public IsabelleContext(string outputFilename, bool allTypes)
- : base(new VCExpressionGenerator(), new VCGenerationOptions(new List<string/*!*/>(new string/*!*/[] { "bvInt", "bvDefSem", "bvint", "bvz", "external" }))) {
+ : base(new VCExpressionGenerator(), new VCGenerationOptions(new List<string/*!*/> { "isabelle", "external" })) {
Contract.Requires(outputFilename != null);
this.OutputFilename = outputFilename;
diff --git a/Source/Provers/SMTLib/ProverInterface.cs b/Source/Provers/SMTLib/ProverInterface.cs
index e70f2bae..0c9a7513 100644
--- a/Source/Provers/SMTLib/ProverInterface.cs
+++ b/Source/Provers/SMTLib/ProverInterface.cs
@@ -75,14 +75,7 @@ namespace Microsoft.Boogie.SMTLib
ctx.parent = this;
this.DeclCollector = new TypeDeclCollector((SMTLibProverOptions)options, Namer);
- if (this.options.UseZ3) {
- var path = this.options.ProverPath;
- if (path == null)
- path = Z3.ExecutablePath();
- var psi = SMTLibProcess.ComputerProcessStartInfo(path, "AUTO_CONFIG=false -smt2 -in");
- Process = new SMTLibProcess(psi, this.options);
- Process.ErrorHandler += this.HandleProverError;
- }
+ SetupProcess();
if (CommandLineOptions.Clo.StratifiedInlining > 0)
{
@@ -98,6 +91,32 @@ namespace Microsoft.Boogie.SMTLib
pendingPop = false;
}
+ void SetupProcess()
+ {
+ if (!this.options.UseZ3)
+ return;
+
+ if (Process != null) return;
+
+ var path = this.options.ProverPath;
+ if (path == null)
+ path = Z3.ExecutablePath();
+ var psi = SMTLibProcess.ComputerProcessStartInfo(path, "AUTO_CONFIG=false -smt2 -in");
+ Process = new SMTLibProcess(psi, this.options);
+ Process.ErrorHandler += this.HandleProverError;
+ }
+
+
+ void PossiblyRestart()
+ {
+ if (Process != null && Process.NeedsRestart) {
+ Process.Close();
+ Process = null;
+ SetupProcess();
+ Process.Send(common.ToString());
+ }
+ }
+
public override ProverContext Context
{
get
@@ -111,7 +130,7 @@ namespace Microsoft.Boogie.SMTLib
internal readonly TypeAxiomBuilder AxBuilder;
internal readonly UniqueNamer Namer;
readonly TypeDeclCollector DeclCollector;
- readonly SMTLibProcess Process;
+ SMTLibProcess Process;
readonly List<string> proverErrors = new List<string>();
readonly List<string> proverWarnings = new List<string>();
readonly StringBuilder common = new StringBuilder();
@@ -182,10 +201,10 @@ namespace Microsoft.Boogie.SMTLib
datatypeString += "(" + SMTLibExprLineariser.TypeToString(datatype) + " ";
foreach (Function f in ctx.KnownDatatypeConstructors[datatype]) {
if (f.InParams.Length == 0) {
- datatypeString += f.Name + " ";
+ datatypeString += Namer.GetQuotedName(f, f.Name) + " ";
}
else {
- datatypeString += "(" + f.Name + " ";
+ datatypeString += "(" + Namer.GetQuotedName(f, f.Name) + " ";
foreach (Variable v in f.InParams) {
datatypeString += "(" + v.Name + " " + DeclCollector.TypeToStringReg(v.TypedIdent.Type) + ") ";
}
@@ -275,6 +294,8 @@ namespace Microsoft.Boogie.SMTLib
string vcString = "(assert (not\n" + VCExpr2String(vc, 1) + "\n))";
FlushAxioms();
+ PossiblyRestart();
+
SendThisVC("(push 1)");
SendThisVC("(set-info :boogie-vc-id " + SMTLibNamer.QuoteId(descriptiveName) + ")");
SendThisVC(vcString);
@@ -410,6 +431,9 @@ namespace Microsoft.Boogie.SMTLib
FlushLogFile();
+ if (CommandLineOptions.Clo.RestartProverPerVC && Process != null)
+ Process.NeedsRestart = true;
+
return globalResult;
} finally {
@@ -527,6 +551,7 @@ namespace Microsoft.Boogie.SMTLib
case "memout":
currentErrorHandler.OnResourceExceeded("memory");
result = Outcome.OutOfMemory;
+ Process.NeedsRestart = true;
break;
case "timeout":
currentErrorHandler.OnResourceExceeded("timeout");
@@ -838,11 +863,12 @@ namespace Microsoft.Boogie.SMTLib
VCExpressionGenerator gen = new VCExpressionGenerator();
List<string>/*!>!*/ proverCommands = new List<string/*!*/>();
- proverCommands.Add("all");
proverCommands.Add("smtlib");
var opts = (SMTLibProverOptions)options ;
if (opts.UseZ3)
proverCommands.Add("z3");
+ else
+ proverCommands.Add("external");
VCGenerationOptions genOptions = new VCGenerationOptions(proverCommands);
return new SMTLibProverContext(gen, genOptions);
}
diff --git a/Source/Provers/SMTLib/SMTLibLineariser.cs b/Source/Provers/SMTLib/SMTLibLineariser.cs
index f4973efd..8d4a4256 100644
--- a/Source/Provers/SMTLib/SMTLibLineariser.cs
+++ b/Source/Provers/SMTLib/SMTLibLineariser.cs
@@ -483,23 +483,27 @@ namespace Microsoft.Boogie.SMTLib
ExprLineariser.Linearise(VCExpressionGenerator.True, options);
} else {
var groupings = node.GroupBy(e => e.Type).Where(g => g.Count() > 1).ToArray();
+ if (groupings.Length == 0) {
+ ExprLineariser.Linearise(VCExpressionGenerator.True, options);
+ } else {
+ if (groupings.Length > 1)
+ wr.Write("(and ");
+
+ foreach (var g in groupings) {
+ wr.Write("(distinct");
+ foreach (VCExpr e in g) {
+ Contract.Assert(e != null);
+ wr.Write(" ");
+ ExprLineariser.Linearise(e, options);
+ }
+ wr.Write(")");
+ }
- if (groupings.Length > 1)
- wr.Write("(and ");
+ if (groupings.Length > 1)
+ wr.Write(")");
- foreach (var g in groupings) {
- wr.Write("(distinct");
- foreach (VCExpr e in g) {
- Contract.Assert(e != null);
- wr.Write(" ");
- ExprLineariser.Linearise(e, options);
- }
- wr.Write(")");
+ wr.Write("\n");
}
-
- if (groupings.Length > 1)
- wr.Write(")");
- wr.Write("\n");
}
return true;
diff --git a/Source/Provers/SMTLib/SMTLibProcess.cs b/Source/Provers/SMTLib/SMTLibProcess.cs
index 2b2d3f94..1dcfdbff 100644
--- a/Source/Provers/SMTLib/SMTLibProcess.cs
+++ b/Source/Provers/SMTLib/SMTLibProcess.cs
@@ -26,6 +26,7 @@ namespace Microsoft.Boogie.SMTLib
readonly int smtProcessId;
static int smtProcessIdSeq = 0;
ConsoleCancelEventHandler cancelEvent;
+ public bool NeedsRestart;
public static ProcessStartInfo ComputerProcessStartInfo(string executable, string options)
{
@@ -110,6 +111,7 @@ namespace Microsoft.Boogie.SMTLib
while (true) {
var sx = GetProverResponse();
if (sx == null) {
+ this.NeedsRestart = true;
HandleError("Prover died");
return;
}
diff --git a/Source/Provers/SMTLib/Z3.cs b/Source/Provers/SMTLib/Z3.cs
index f9e90427..2b426f0b 100644
--- a/Source/Provers/SMTLib/Z3.cs
+++ b/Source/Provers/SMTLib/Z3.cs
@@ -33,7 +33,7 @@ namespace Microsoft.Boogie.SMTLib
static void FindExecutable()
// throws ProverException, System.IO.FileNotFoundException;
- {
+ {
Contract.Ensures(_proverPath != null);
var proverExe = "z3.exe";
@@ -65,6 +65,8 @@ namespace Microsoft.Boogie.SMTLib
z3Dirs.AddRange(Directory.GetDirectories(msrDir, "Z3-*"));
}
+ int minMajor = 3, minMinor = 2;
+
// Look for the most recent version of Z3.
int minor = 0, major = 0;
string winner = null;
@@ -86,6 +88,7 @@ namespace Microsoft.Boogie.SMTLib
if (major == 0 && minor == 0) {
throw new ProverException("Cannot find executable: " + firstTry);
}
+
Contract.Assert(winner != null);
_proverPath = Path.Combine(Path.Combine(winner, "bin"), proverExe);
@@ -96,6 +99,12 @@ namespace Microsoft.Boogie.SMTLib
if (CommandLineOptions.Clo.Trace) {
Console.WriteLine("[TRACE] Using prover: " + _proverPath);
}
+
+ if (major < minMajor || (major == minMajor && minor < minMinor)) {
+ throw new ProverException(string.Format("Found version {0}.{1} of Z3. Please install version {2}.{3} or later. " +
+ "(More conservative users might opt to supply -prover:Z3 option instead to get the historic Simplify back-end)",
+ major, minor, minMajor, minMinor));
+ }
}
}
@@ -137,7 +146,7 @@ namespace Microsoft.Boogie.SMTLib
options.AddWeakSmtOption("NNF_SK_HACK", "true");
// don't use model-based quantifier instantiation; it never finishes on non-trivial Boogie problems
- options.AddWeakSmtOption("MBQI", "false");
+ options.AddWeakSmtOption("MBQI", "false");
// More or less like MAM=0.
options.AddWeakSmtOption("QI_EAGER_THRESHOLD", "100");
diff --git a/Source/Provers/Simplify/ProverInterface.cs b/Source/Provers/Simplify/ProverInterface.cs
index 497911ab..4584b2e7 100644
--- a/Source/Provers/Simplify/ProverInterface.cs
+++ b/Source/Provers/Simplify/ProverInterface.cs
@@ -848,9 +848,7 @@ namespace Microsoft.Boogie.Simplify {
Contract.Assert(gen != null);
List<string>/*!>!*/ proverCommands = new List<string> ();
Contract.Assert(cce.NonNullElements(proverCommands));
- proverCommands.Add("all");
proverCommands.Add("simplify");
- proverCommands.Add("simplifyLike");
return new DeclFreeProverContext(gen, new VCGenerationOptions(proverCommands));
}
diff --git a/Source/Provers/TPTP/ProverInterface.cs b/Source/Provers/TPTP/ProverInterface.cs
index d18535e2..424e36ac 100644
--- a/Source/Provers/TPTP/ProverInterface.cs
+++ b/Source/Provers/TPTP/ProverInterface.cs
@@ -323,10 +323,8 @@ USE_PREDICATES=<bool> Try to use SMT predicates for functions returning bool
VCExpressionGenerator gen = new VCExpressionGenerator();
List<string>/*!>!*/ proverCommands = new List<string/*!*/>();
- // TODO: what is supported?
- // proverCommands.Add("all");
- // proverCommands.Add("simplify");
- // proverCommands.Add("simplifyLike");
+ proverCommands.Add("tptp");
+ proverCommands.Add("external");
VCGenerationOptions genOptions = new VCGenerationOptions(proverCommands);
Contract.Assert(genOptions != null);
diff --git a/Source/Provers/Z3/Prover.cs b/Source/Provers/Z3/Prover.cs
index 8929e732..6a066f1f 100644
--- a/Source/Provers/Z3/Prover.cs
+++ b/Source/Provers/Z3/Prover.cs
@@ -156,11 +156,8 @@ namespace Microsoft.Boogie.Z3
if (opts.Inspector != null)
AddOption(result, "PROGRESS_SAMPLING_FREQ", "100");
- if (opts.Typed) {
- AddOption(result, "TYPE_CHECK", "true");
- if (opts.BitVectors == CommandLineOptions.BvHandling.Z3Native)
- AddOption(result, "BV_REFLECT", "true");
- }
+ AddOption(result, "TYPE_CHECK", "true");
+ AddOption(result, "BV_REFLECT", "true");
foreach (string opt in CommandLineOptions.Clo.Z3Options) {
Contract.Assert(opt != null);
diff --git a/Source/Provers/Z3/ProverInterface.cs b/Source/Provers/Z3/ProverInterface.cs
index 19097f8c..388cf91b 100644
--- a/Source/Provers/Z3/ProverInterface.cs
+++ b/Source/Provers/Z3/ProverInterface.cs
@@ -35,7 +35,7 @@ void ObjectInvariant()
[NotDelayed]
public Z3ProcessTheoremProver(VCExpressionGenerator gen,
- DeclFreeProverContext ctx, Z3InstanceOptions opts):base(opts, gen, ctx, opts.ExeName,opts.Typed ? "TypedUnivBackPred2.sx" : "UnivBackPred2.sx")
+ DeclFreeProverContext ctx, Z3InstanceOptions opts):base(opts, gen, ctx, opts.ExeName, "TypedUnivBackPred2.sx")
{
Contract.Requires(gen != null);
Contract.Requires(ctx != null);
@@ -88,11 +88,6 @@ void ObjectInvariant()
public class Z3InstanceOptions : ProverOptions
{
public int Timeout { get { return TimeLimit / 1000; } }
- public bool Typed {
- get {
- return CommandLineOptions.Clo.Z3types || BitVectors == CommandLineOptions.BvHandling.Z3Native;
- }
- }
public int Lets {
get
{
@@ -164,10 +159,6 @@ REVERSE_IMPLIES=<bool> Encode P==>Q as Q||!P.
}
- public override CommandLineOptions.BvHandling Bitvectors { get {
- return opts.BitVectors;
- } }
-
public Z3LineariserOptions(bool asTerm, Z3InstanceOptions opts, List<VCExprVar/*!>!*/> letVariables):base(asTerm) {
Contract.Requires(opts != null);
Contract.Requires(cce.NonNullElements(letVariables));
@@ -181,7 +172,7 @@ REVERSE_IMPLIES=<bool> Encode P==>Q as Q||!P.
} }
public override bool UseTypes { get {
- return opts.Typed;
+ return true;
} }
public override bool QuantifierIds { get {
@@ -254,7 +245,7 @@ REVERSE_IMPLIES=<bool> Encode P==>Q as Q||!P.
UniqueNamer namer = new UniqueNamer ();
Namer = namer;
this.DeclCollector =
- new TypeDeclCollector (namer, opts.BitVectors == CommandLineOptions.BvHandling.Z3Native);
+ new TypeDeclCollector (namer, true);
}
private Z3VCExprTranslator(Z3VCExprTranslator tl) :base(tl){
@@ -332,16 +323,9 @@ REVERSE_IMPLIES=<bool> Encode P==>Q as Q||!P.
VCExpr sortedAxioms = letSorter.Mutate(AxBuilder.GetNewAxioms(), true);
Contract.Assert(sortedAxioms!=null);
- if (Opts.Typed) {
- DeclCollector.Collect(sortedAxioms);
- DeclCollector.Collect(sortedExpr);
- FeedTypeDeclsToProver();
- } else {
- TermFormulaFlattener flattener = new TermFormulaFlattener (Gen);
- Contract.Assert(flattener!=null);
- sortedExpr = flattener.Flatten(sortedExpr);
- sortedAxioms = flattener.Flatten(sortedAxioms);
- }
+ DeclCollector.Collect(sortedAxioms);
+ DeclCollector.Collect(sortedExpr);
+ FeedTypeDeclsToProver();
if (Opts.Lets != 3) {
// replace let expressions with implies
Let2ImpliesMutator letImplier = new Let2ImpliesMutator(Gen, Opts.Lets == 1, Opts.Lets == 2);
@@ -409,13 +393,8 @@ REVERSE_IMPLIES=<bool> Encode P==>Q as Q||!P.
Z3InstanceOptions opts = cce.NonNull((Z3InstanceOptions)options);
VCExpressionGenerator gen = new VCExpressionGenerator ();
List<string/*!>!*/> proverCommands = new List<string/*!*/> ();
- proverCommands.Add("all");
proverCommands.Add("z3");
proverCommands.Add("simplifyLike");
- if (opts.BitVectors == CommandLineOptions.BvHandling.Z3Native)
- proverCommands.Add("bvDefSem");
- if (opts.BitVectors == CommandLineOptions.BvHandling.ToInt)
- proverCommands.Add("bvInt");
VCGenerationOptions genOptions = new VCGenerationOptions(proverCommands);
return NewProverContext(gen, genOptions, opts);
diff --git a/Source/VCExpr/Boogie2VCExpr.cs b/Source/VCExpr/Boogie2VCExpr.cs
index 4d8fed6a..4e9c5c10 100644
--- a/Source/VCExpr/Boogie2VCExpr.cs
+++ b/Source/VCExpr/Boogie2VCExpr.cs
@@ -17,6 +17,7 @@ using Microsoft.Basetypes;
namespace Microsoft.Boogie.VCExprAST {
using Microsoft.Boogie;
+ // TODO: in future we might use that for defining symbols for Boogie's conditional compilation
public class VCGenerationOptions {
private readonly List<string/*!*/>/*!*/ SupportedProverCommands;
[ContractInvariantMethod]
@@ -1085,7 +1086,7 @@ namespace Microsoft.Boogie.VCExprAST {
return null;
}
- Expansion exp = FindExpansion(app.Func);
+ var exp = app.Func.Body;
if (exp == null)
return null;
@@ -1098,11 +1099,12 @@ namespace Microsoft.Boogie.VCExprAST {
// first bind the formals to VCExpr variables, which are later
// substituted with the actual parameters
- for (int i = 0; i < exp.formals.Length; ++i)
- subst[BaseTranslator.BindVariable(cce.NonNull(exp.formals)[i])] = args[i];
+ var inParams = app.Func.InParams;
+ for (int i = 0; i < inParams.Length; ++i)
+ subst[BaseTranslator.BindVariable(inParams[i])] = args[i];
// recursively translate the body of the expansion
- translatedBody = BaseTranslator.Translate(exp.body);
+ translatedBody = BaseTranslator.Translate(exp);
} finally {
BaseTranslator.PopFormalsScope();
BaseTranslator.PopBoundVariableScope();
@@ -1110,32 +1112,12 @@ namespace Microsoft.Boogie.VCExprAST {
}
// substitute the formals with the actual parameters in the body
- Contract.Assert(typeArgs.Count == exp.TypeParameters.Length);
+ var tparms = app.Func.TypeParameters;
+ Contract.Assert(typeArgs.Count == tparms.Length);
for (int i = 0; i < typeArgs.Count; ++i)
- subst[exp.TypeParameters[i]] = typeArgs[i];
+ subst[tparms[i]] = typeArgs[i];
SubstitutingVCExprVisitor/*!*/ substituter = new SubstitutingVCExprVisitor(Gen);
return substituter.Mutate(translatedBody, subst);
}
-
- private Expansion FindExpansion(Function func) {
- Contract.Requires(func != null);
- if (func.expansions == null)
- return null;
-
- Expansion exp = null;
- foreach (Expansion e in func.expansions) {
- Contract.Assert(e != null);
- if (e.ignore == null || !GenerationOptions.IsAnyProverCommandSupported(e.ignore)) {
- if (exp == null) {
- exp = e;
- } else {
- System.Console.WriteLine("*** more than one possible expansion for {0}", func);
- return null;
- }
- }
- }
-
- return exp;
- }
}
}
diff --git a/Source/VCExpr/SimplifyLikeLineariser.cs b/Source/VCExpr/SimplifyLikeLineariser.cs
index 58c6ad7a..848fafcb 100644
--- a/Source/VCExpr/SimplifyLikeLineariser.cs
+++ b/Source/VCExpr/SimplifyLikeLineariser.cs
@@ -56,12 +56,6 @@ namespace Microsoft.Boogie.VCExprAST {
get;
}
- public virtual CommandLineOptions.BvHandling Bitvectors {
- get {
- return CommandLineOptions.BvHandling.None;
- }
- }
-
// variables representing formulas in let-bindings have to be
// printed in a different way than other variables
public virtual List<VCExprVar/*!*/>/*!*/ LetVariables {
@@ -89,19 +83,6 @@ namespace Microsoft.Boogie.VCExprAST {
Contract.Invariant(EmptyList != null);
}
-
- public bool NativeBv {
- get {
- return Bitvectors == CommandLineOptions.BvHandling.Z3Native;
- }
- }
-
- public bool IntBv {
- get {
- return Bitvectors == CommandLineOptions.BvHandling.ToInt;
- }
- }
-
////////////////////////////////////////////////////////////////////////////////////////
protected LineariserOptions(bool asTerm) {
diff --git a/Source/VCGeneration/Check.cs b/Source/VCGeneration/Check.cs
index 134cff4c..7b623bce 100644
--- a/Source/VCGeneration/Check.cs
+++ b/Source/VCGeneration/Check.cs
@@ -33,7 +33,6 @@ namespace Microsoft.Boogie {
private readonly VCExpressionGenerator gen;
private ProverInterface thmProver;
- private CommandLineOptions.BvHandling bitvectors;
private int timeout;
// state for the async interface
@@ -48,24 +47,8 @@ namespace Microsoft.Boogie {
public readonly AutoResetEvent ProverDone = new AutoResetEvent(false);
- private static CommandLineOptions.BvHandling BvHandlingForImpl(Implementation impl) {
- if (impl == null)
- return CommandLineOptions.Clo.Bitvectors;
- bool force_int = false;
- bool force_native = false;
- cce.NonNull(impl.Proc).CheckBooleanAttribute("forceBvInt", ref force_int);
- impl.Proc.CheckBooleanAttribute("forceBvZ3Native", ref force_native);
- impl.CheckBooleanAttribute("forceBvInt", ref force_int);
- impl.CheckBooleanAttribute("forceBvZ3Native", ref force_native);
- if (force_native)
- return CommandLineOptions.BvHandling.Z3Native;
- if (force_int)
- return CommandLineOptions.BvHandling.ToInt;
- return CommandLineOptions.Clo.Bitvectors;
- }
-
public bool WillingToHandle(Implementation impl, int timeout) {
- return !closed && timeout == this.timeout && bitvectors == BvHandlingForImpl(impl);
+ return !closed && timeout == this.timeout;
}
public VCExpressionGenerator VCExprGen {
@@ -91,13 +74,10 @@ namespace Microsoft.Boogie {
}
public readonly Program program;
- public readonly CommandLineOptions.BvHandling bitvectors;
- public ContextCacheKey(Program prog,
- CommandLineOptions.BvHandling bitvectors) {
+ public ContextCacheKey(Program prog) {
Contract.Requires(prog != null);
this.program = prog;
- this.bitvectors = bitvectors;
}
[Pure]
@@ -105,15 +85,14 @@ namespace Microsoft.Boogie {
public override bool Equals(object that) {
if (that is ContextCacheKey) {
ContextCacheKey thatKey = (ContextCacheKey)that;
- return this.program.Equals(thatKey.program) &&
- this.bitvectors.Equals(thatKey.bitvectors);
+ return this.program.Equals(thatKey.program);
}
return false;
}
[Pure]
public override int GetHashCode() {
- return this.program.GetHashCode() + this.bitvectors.GetHashCode();
+ return this.program.GetHashCode();
}
}
@@ -125,7 +104,6 @@ namespace Microsoft.Boogie {
public Checker(VC.ConditionGeneration vcgen, Program prog, string/*?*/ logFilePath, bool appendLogFile, Implementation impl, int timeout) {
Contract.Requires(vcgen != null);
Contract.Requires(prog != null);
- this.bitvectors = BvHandlingForImpl(impl);
this.timeout = timeout;
ProverOptions options = cce.NonNull(CommandLineOptions.Clo.TheProverFactory).BlankProverOptions();
@@ -139,11 +117,10 @@ namespace Microsoft.Boogie {
if (timeout > 0) {
options.TimeLimit = timeout * 1000;
}
- options.BitVectors = this.bitvectors;
options.Parse(CommandLineOptions.Clo.ProverOptions);
- ContextCacheKey key = new ContextCacheKey(prog, this.bitvectors);
+ ContextCacheKey key = new ContextCacheKey(prog);
ProverContext ctx;
ProverInterface prover;
@@ -183,8 +160,7 @@ namespace Microsoft.Boogie {
Contract.Assert(decl != null);
bool expand = false;
Axiom ax = decl as Axiom;
- decl.CheckBooleanAttribute("inline", ref expand);
- if (!expand && ax != null) {
+ if (ax != null) {
ctx.AddAxiom(ax, null);
}
}
@@ -389,6 +365,9 @@ namespace Microsoft.Boogie {
case Model.ElementKind.Array:
val = null;
break;
+ case Model.ElementKind.DataValue:
+ val = null;
+ break;
default:
Contract.Assert(false);
val = null;
diff --git a/Source/VCGeneration/Context.cs b/Source/VCGeneration/Context.cs
index 7cb9a404..bf27144b 100644
--- a/Source/VCGeneration/Context.cs
+++ b/Source/VCGeneration/Context.cs
@@ -158,11 +158,6 @@ public abstract class ProverContextContracts:ProverContext{
public override void AddAxiom(Axiom ax, string attributes) {//Contract.Requires(ax != null);
base.AddAxiom(ax, attributes);
- string ignore = ax.FindStringAttribute("ignore");
- if (ignore != null && genOptions.IsAnyProverCommandSupported(ignore)) {
- return;
- }
-
axiomConjuncts.Add(translator.Translate(ax.Expr));
}
diff --git a/Source/VCGeneration/StratifiedVC.cs b/Source/VCGeneration/StratifiedVC.cs
index 92e3fa01..2f7f120d 100644
--- a/Source/VCGeneration/StratifiedVC.cs
+++ b/Source/VCGeneration/StratifiedVC.cs
@@ -1630,6 +1630,7 @@ namespace VC
var Gen = checker.underlyingChecker.VCExprGen;
var callee = cs.calleeName;
var caller = cs.callerName;
+ Helpers.ExtraTraceInformation("inlining call from " + caller + "to " + callee);
var expr = cs.callExpr;
VCExpr expansion = procVcCopies[callee];
List<VCExprVar> interfaceExprVars = interfaceVarCopies[callee];
@@ -1685,138 +1686,123 @@ namespace VC
calleeToCallSites[callee].Remove(cs);
}
- private Outcome FindUnsatCore(Implementation impl, StratifiedCheckerInterface checker, VCExpressionGenerator Gen, PCBErrorReporter reporter, List<VCExpr> assumptions, out HashSet<VCExprVar> unsatCore) {
- Helpers.ExtraTraceInformation("Number of assumptions = " + assumptions.Count);
-
- if (checker is NormalChecker) {
- Outcome ret;
- unsatCore = null;
- for (int i = 0; i < assumptions.Count; i++) {
- checker.Push();
- checker.AddAxiom(assumptions[i]);
- }
-
- ret = checker.CheckVC();
- if (ret == Outcome.Errors) {
- for (int i = 0; i < assumptions.Count; i++) {
- checker.Pop();
- }
- return ret;
+ private Outcome FindUnsatCoreInMainCallees(Implementation impl, StratifiedCheckerInterface checker, VCExpressionGenerator Gen, PCBErrorReporter reporter, List<VCExpr> assumptions, out HashSet<VCExprVar> unsatCore) {
+ Debug.Assert(checker is ApiChecker);
+ unsatCore = null;
+ List<int> unsatCoreIndices;
+ Outcome ret;
+ ret = checker.CheckAssumptions(assumptions, out unsatCoreIndices);
+ if (ret == Outcome.Errors) return ret;
+ unsatCore = new HashSet<VCExprVar>();
+ HashSet<VCExprVar> implCallees = new HashSet<VCExprVar>();
+ foreach (CallSite cs in callerToCallSites[impl.Name]) {
+ implCallees.Add(cs.callSiteConstant);
+ }
+ for (int i = 0; i < unsatCoreIndices.Count; i++) {
+ VCExprVar assumption = (VCExprVar)assumptions[unsatCoreIndices[i]];
+ if (implCallees.Contains(assumption)) {
+ unsatCore.Add(assumption);
}
+ }
+ return Outcome.Correct;
+ }
- Helpers.ExtraTraceInformation("VC checked");
-
- reporter.unsatCoreMode = true;
- VCExpr curr = VCExpressionGenerator.True;
- unsatCore = new HashSet<VCExprVar>();
- int index = assumptions.Count;
- while (index > 0) {
- checker.Pop();
+ private Outcome FindUnsatCore(Implementation impl, StratifiedCheckerInterface checker, VCExpressionGenerator Gen, PCBErrorReporter reporter, List<VCExpr> assumptions, out HashSet<VCExprVar> unsatCore) {
+ Helpers.ExtraTraceInformation("Number of assumptions = " + assumptions.Count);
+ unsatCore = null;
+ List<int> unsatCoreIndices;
+ Outcome ret;
+ ret = checker.CheckAssumptions(assumptions, out unsatCoreIndices);
+ if (ret == Outcome.Errors) return ret;
+ unsatCore = new HashSet<VCExprVar>();
+ for (int i = 0; i < unsatCoreIndices.Count; i++) {
+ unsatCore.Add((VCExprVar)assumptions[unsatCoreIndices[i]]);
+ }
- checker.Push();
- checker.AddAxiom(curr);
- ret = checker.CheckVC();
- checker.Pop();
+ Helpers.ExtraTraceInformation("Number of elements in unsat core = " + unsatCore.Count);
- if (ret == Outcome.Errors) {
- VCExprVar assumption = (VCExprVar)assumptions[index - 1];
- curr = Gen.And(assumption, curr);
- unsatCore.Add(assumption);
+ HashSet<CallSite> reachableCallSites = new HashSet<CallSite>();
+ Stack<string> stack = new Stack<string>();
+ HashSet<string> set = new HashSet<string>();
+ stack.Push(impl.Name);
+ while (stack.Count > 0) {
+ string caller = stack.Peek();
+ stack.Pop();
+ if (set.Contains(caller)) continue;
+ set.Add(caller);
+ foreach (CallSite cs in callerToCallSites[caller]) {
+ if (unsatCore.Contains(cs.callSiteConstant)) {
+ reachableCallSites.Add(cs);
+ stack.Push(cs.calleeName);
}
- index--;
}
- reporter.unsatCoreMode = false;
- Helpers.ExtraTraceInformation("Number of elements in unsat core = " + unsatCore.Count);
- return Outcome.Correct;
}
- else {
- Debug.Assert(checker is ApiChecker);
- unsatCore = null;
- List<int> unsatCoreIndices;
- Outcome ret;
- ret = checker.CheckAssumptions(assumptions, out unsatCoreIndices);
- if (ret == Outcome.Errors) return ret;
- unsatCore = new HashSet<VCExprVar>();
- for (int i = 0; i < unsatCoreIndices.Count; i++) {
- unsatCore.Add((VCExprVar)assumptions[unsatCoreIndices[i]]);
- }
- Helpers.ExtraTraceInformation("Number of elements in unsat core = " + unsatCore.Count);
-
- HashSet<CallSite> reachableCallSites = new HashSet<CallSite>();
- Stack<string> stack = new Stack<string>();
- HashSet<string> set = new HashSet<string>();
- stack.Push(impl.Name);
- while (stack.Count > 0) {
- string caller = stack.Peek();
- stack.Pop();
- if (set.Contains(caller)) continue;
- set.Add(caller);
- foreach (CallSite cs in callerToCallSites[caller]) {
- if (unsatCore.Contains(cs.callSiteConstant)) {
- reachableCallSites.Add(cs);
- stack.Push(cs.calleeName);
- }
+ Graph<CallSite> callGraph = new Graph<CallSite>();
+ foreach (CallSite cs1 in reachableCallSites) {
+ callGraph.AddSource(cs1);
+ foreach (CallSite cs2 in calleeToCallSites[cs1.callerName]) {
+ if (reachableCallSites.Contains(cs2)) {
+ callGraph.AddEdge(cs1, cs2);
}
}
+ }
- Graph<CallSite> callGraph = new Graph<CallSite>();
- foreach (CallSite cs1 in reachableCallSites) {
- callGraph.AddSource(cs1);
- foreach (CallSite cs2 in calleeToCallSites[cs1.callerName]) {
- if (reachableCallSites.Contains(cs2)) {
- callGraph.AddEdge(cs1, cs2);
- }
- }
- }
+ List<CallSite> sortedCallSites = new List<CallSite>();
+ foreach (CallSite cs in callGraph.TopologicalSort()) {
+ checker.Push();
+ checker.AddAxiom(cs.callSiteConstant);
+ sortedCallSites.Add(cs);
+ }
- List<CallSite> sortedCallSites = new List<CallSite>();
- foreach (CallSite cs in callGraph.TopologicalSort()) {
- checker.Push();
- checker.AddAxiom(cs.callSiteConstant);
- sortedCallSites.Add(cs);
- }
+ ret = checker.CheckVC();
+ Debug.Assert(ret == Outcome.Correct);
+ reporter.unsatCoreMode = true;
+ VCExpr curr = VCExpressionGenerator.True;
+ HashSet<CallSite> relevantCallSites = new HashSet<CallSite>();
+ HashSet<VCExprVar> relevantUnsatCore = new HashSet<VCExprVar>();
+ int index = sortedCallSites.Count;
+ int queries = 0;
+ while (index > 0) {
+ checker.Pop();
+ index--;
+ CallSite cs = sortedCallSites[index];
+ bool check = (cs.callerName == impl.Name);
+ foreach (CallSite x in calleeToCallSites[cs.callerName]) {
+ check = check || relevantCallSites.Contains(x);
+ }
+ if (!check) continue;
+ bool relevant = (cs.callerName != impl.Name);
+ foreach (CallSite x in calleeToCallSites[cs.calleeName]) {
+ if (x.callSiteConstant == cs.callSiteConstant) continue;
+ relevant = relevant && !reachableCallSites.Contains(x);
+ }
+ if (relevant) {
+ curr = Gen.And(cs.callSiteConstant, curr);
+ relevantCallSites.Add(cs);
+ relevantUnsatCore.Add(cs.callSiteConstant);
+ continue;
+ }
+
+ queries++;
+ checker.Push();
+ checker.AddAxiom(curr);
ret = checker.CheckVC();
- Debug.Assert(ret == Outcome.Correct);
-
- reporter.unsatCoreMode = true;
- VCExpr curr = VCExpressionGenerator.True;
- HashSet<CallSite> relevantCallSites = new HashSet<CallSite>();
- HashSet<VCExprVar> relevantUnsatCore = new HashSet<VCExprVar>();
- int index = sortedCallSites.Count;
- int queries = 0;
- while (index > 0) {
- checker.Pop();
- CallSite cs = sortedCallSites[index - 1];
- //Helpers.ExtraTraceInformation("Examining callsite: " + "caller = " + cs.callerName + ", callee = " + cs.calleeName);
-
- bool check = (cs.callerName == impl.Name);
- foreach (CallSite x in calleeToCallSites[cs.callerName]) {
- check = check || relevantCallSites.Contains(x);
- }
- if (check) {
- queries++;
- checker.Push();
- checker.AddAxiom(curr);
- ret = checker.CheckVC();
- checker.Pop();
-
- if (ret == Outcome.Errors || ret == Outcome.TimedOut) {
- curr = Gen.And(cs.callSiteConstant, curr);
- relevantCallSites.Add(cs);
- relevantUnsatCore.Add(cs.callSiteConstant);
- }
- }
- index--;
- }
- reporter.unsatCoreMode = false;
+ checker.Pop();
- unsatCore = relevantUnsatCore;
- Helpers.ExtraTraceInformation("Number of queries = " + queries);
- Helpers.ExtraTraceInformation("Unsat core after pruning = " + unsatCore.Count);
- return Outcome.Correct;
+ if (ret == Outcome.Errors || ret == Outcome.TimedOut) {
+ curr = Gen.And(cs.callSiteConstant, curr);
+ relevantCallSites.Add(cs);
+ relevantUnsatCore.Add(cs.callSiteConstant);
+ }
}
+ reporter.unsatCoreMode = false;
+
+ unsatCore = relevantUnsatCore;
+ Helpers.ExtraTraceInformation("Number of queries = " + queries);
+ Helpers.ExtraTraceInformation("Unsat core after pruning = " + unsatCore.Count);
+ return Outcome.Correct;
}
HashSet<string> ComputeReachableImplementations(Implementation impl) {
@@ -1835,6 +1821,57 @@ namespace VC
return set;
}
+ private bool Verified(HashSet<VCExprVar> unsatCore) {
+ bool verified = true;
+ foreach (string name in calleeToCallSites.Keys) {
+ int numInlined = 0;
+ foreach (CallSite cs in calleeToCallSites[name]) {
+ if (unsatCore.Contains(cs.callSiteConstant))
+ numInlined++;
+ }
+ if (numInlined > 1) {
+ Helpers.ExtraTraceInformation("callee name = " + name);
+ Helpers.ExtraTraceInformation("number of inlines = " + numInlined);
+ verified = false;
+ }
+ }
+ return verified;
+ }
+
+ private void InlineBottomUp(StratifiedCheckerInterface checker, HashSet<VCExprVar> unsatCore) {
+ Graph<string> callGraph = new Graph<string>();
+ foreach (string name in calleeToCallSites.Keys) {
+ callGraph.AddSource(name);
+ foreach (CallSite cs in calleeToCallSites[name]) {
+ callGraph.AddEdge(name, cs.callerName);
+ }
+ }
+ foreach (string name in callGraph.TopologicalSort()) {
+ HashSet<CallSite> toBeInlined = new HashSet<CallSite>();
+ foreach (CallSite cs in calleeToCallSites[name]) {
+ if (unsatCore.Contains(cs.callSiteConstant)) {
+ Debug.Assert(name == cs.calleeName);
+ toBeInlined.Add(cs);
+ }
+ }
+ foreach (CallSite cs in toBeInlined) {
+ InlineCallSite(cs, checker);
+ }
+ }
+ }
+
+ private void InlineIntoMain(StratifiedCheckerInterface checker, Implementation impl, HashSet<VCExprVar> unsatCore) {
+ HashSet<CallSite> toBeInlined = new HashSet<CallSite>();
+ foreach (CallSite cs in callerToCallSites[impl.Name]) {
+ if (unsatCore.Contains(cs.callSiteConstant)) {
+ toBeInlined.Add(cs);
+ }
+ }
+ foreach (CallSite cs in toBeInlined) {
+ InlineCallSite(cs, checker);
+ }
+ }
+
private Outcome SuperAwesomeMethod(Checker underlyingChecker, Implementation impl, VCExpr vcMain) {
// Create the call graph
// while (true)
@@ -1847,22 +1884,13 @@ namespace VC
var Gen = underlyingChecker.VCExprGen;
PCBErrorReporter reporter = new PCBErrorReporter(impl);
StratifiedCheckerInterface checker;
- if (underlyingChecker.TheoremProver is ApiProverInterface) {
- checker = new ApiChecker(VCExpressionGenerator.False, reporter, underlyingChecker);
- }
- else {
- checker = new NormalChecker(null, reporter, underlyingChecker);
- }
+ checker = new ApiChecker(VCExpressionGenerator.False, reporter, underlyingChecker);
CreateProcedureCopies(impl, program, checker, vcMain);
int iter = 0;
while (true) {
Helpers.ExtraTraceInformation("Iteration number " + iter++);
-
Outcome ret;
- if (checker is NormalChecker) {
- checker.updateMainVC(procVcCopies[impl.Name]);
- }
checker.Push();
@@ -1871,9 +1899,7 @@ namespace VC
foreach (string name in reachableImpls) {
VCExpr expr = procVcCopies[name];
if (name == impl.Name) {
- if (checker is ApiChecker) {
- checker.AddAxiom(Gen.Not(expr));
- }
+ checker.AddAxiom(Gen.Not(expr));
continue;
}
var cscExpr = VCExpressionGenerator.False;
@@ -1891,32 +1917,14 @@ namespace VC
checker.Pop();
- if (ret == Outcome.Errors) return ret;
-
- Graph<string> callGraph = new Graph<string>();
- foreach (string name in calleeToCallSites.Keys) {
- callGraph.AddSource(name);
- foreach (CallSite cs in calleeToCallSites[name]) {
- callGraph.AddEdge(name, cs.callerName);
- }
- }
+ if (ret == Outcome.Errors)
+ return ret;
- bool verified = true;
- foreach (string name in callGraph.TopologicalSort()) {
- HashSet<CallSite> toBeInlined = new HashSet<CallSite>();
- foreach (CallSite cs in calleeToCallSites[name]) {
- if (unsatCore.Contains(cs.callSiteConstant)) {
- Debug.Assert(name == cs.calleeName);
- toBeInlined.Add(cs);
- }
- }
- verified = verified && toBeInlined.Count <= 1;
- foreach (CallSite cs in toBeInlined) {
- InlineCallSite(cs, checker);
- }
- }
+ if (Verified(unsatCore))
+ return Outcome.Correct;
- if (verified) return Outcome.Correct;
+ //InlineBottomUp(checker, unsatCore);
+ InlineIntoMain(checker, impl, unsatCore);
}
}
diff --git a/Test/bitvectors/Answer b/Test/bitvectors/Answer
index f0f65b04..e20474d9 100644
--- a/Test/bitvectors/Answer
+++ b/Test/bitvectors/Answer
@@ -28,12 +28,6 @@ Boogie program verifier finished with 1 verified, 0 errors
bv7.bpl(4,14): error: arguments of extract need to be integer literals
bv7.bpl(5,15): error: parentheses around bitvector bounds are not allowed
2 parse errors detected in bv7.bpl
--------------------- bv4.bpl - /bv:n --------------------
-bv4.bpl(3,6): Error: no bitvector handling specified, please use /bv:i or /bv:z flag
-bv4.bpl(3,13): Error: no bitvector handling specified, please use /bv:i or /bv:z flag
-bv4.bpl(5,6): Error: no bitvector handling specified, please use /bv:i or /bv:z flag
-bv4.bpl(5,14): Error: no bitvector handling specified, please use /bv:i or /bv:z flag
-4 type checking errors detected in bv4.bpl
-------------------- bv5.bpl --------------------
bv5.bpl(10,3): Error BP5001: This assertion might not hold.
Execution trace:
@@ -52,6 +46,6 @@ Boogie program verifier finished with 2 verified, 0 errors
-------------------- bv10.bpl --------------------
Boogie program verifier finished with 1 verified, 0 errors
--------------------- bv9.bpl /bv:z /proverOpt:OPTIMIZE_FOR_BV=true --------------------
+-------------------- bv9.bpl /proverOpt:OPTIMIZE_FOR_BV=true --------------------
Boogie program verifier finished with 1 verified, 0 errors
diff --git a/Test/bitvectors/runtest.bat b/Test/bitvectors/runtest.bat
index a0480645..2a140368 100644
--- a/Test/bitvectors/runtest.bat
+++ b/Test/bitvectors/runtest.bat
@@ -5,16 +5,13 @@ set BGEXE=..\..\Binaries\Boogie.exe
for %%f in (arrays.bpl bv0.bpl bv1.bpl bv2.bpl bv3.bpl bv4.bpl bv7.bpl) do (
echo -------------------- %%f --------------------
- %BGEXE% /proverWarnings:1 /bv:z %* /logPrefix:-0 %%f
+ %BGEXE% /proverWarnings:1 %* %%f
)
-echo -------------------- bv4.bpl - /bv:n --------------------
-%BGEXE% /bv:n %* /logPrefix:-1 bv4.bpl
-
for %%f in (bv5.bpl bv6.bpl bv8.bpl bv10.bpl) do (
echo -------------------- %%f --------------------
%BGEXE% %* %%f
)
-echo -------------------- bv9.bpl /bv:z /proverOpt:OPTIMIZE_FOR_BV=true --------------------
-%BGEXE% /bv:z /proverOpt:OPTIMIZE_FOR_BV=true %* bv9.bpl
+echo -------------------- bv9.bpl /proverOpt:OPTIMIZE_FOR_BV=true --------------------
+%BGEXE% /proverOpt:OPTIMIZE_FOR_BV=true %* bv9.bpl
diff --git a/Test/dafny0/Answer b/Test/dafny0/Answer
index 4b3d9814..b2914776 100644
--- a/Test/dafny0/Answer
+++ b/Test/dafny0/Answer
@@ -58,7 +58,7 @@ class C {
Dafny program verifier finished with 0 verified, 0 errors
-------------------- TypeTests.dfy --------------------
-TypeTests.dfy(84,9): Error: sorry, cannot instantiate collection type with a subrange type
+TypeTests.dfy(89,9): Error: sorry, cannot instantiate collection type with a subrange type
TypeTests.dfy(4,13): Error: incorrect type of function argument 0 (expected C, got D)
TypeTests.dfy(4,13): Error: incorrect type of function argument 1 (expected D, got C)
TypeTests.dfy(5,13): Error: incorrect type of function argument 0 (expected C, got int)
@@ -74,14 +74,25 @@ TypeTests.dfy(58,8): Error: Duplicate local-variable name: x
TypeTests.dfy(61,6): Error: Duplicate local-variable name: y
TypeTests.dfy(68,17): Error: member F in type C does not refer to a method
TypeTests.dfy(69,17): Error: a method called as an initialization method must not have any result arguments
-TypeTests.dfy(78,10): Error: cannot assign to multiple array elements (try a foreach).
-TypeTests.dfy(78,10): Error: cannot assign to multiple array elements (try a foreach).
-TypeTests.dfy(79,10): Error: cannot assign to multiple array elements (try a foreach).
-TypeTests.dfy(79,10): Error: cannot assign to multiple array elements (try a foreach).
-TypeTests.dfy(85,9): Error: sorry, cannot instantiate type parameter with a subrange type
-TypeTests.dfy(86,8): Error: sorry, cannot instantiate 'array' type with a subrange type
-TypeTests.dfy(87,8): Error: sorry, cannot instantiate 'array' type with a subrange type
-23 resolution/type errors detected in TypeTests.dfy
+TypeTests.dfy(78,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(78,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(79,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(79,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(80,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(80,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(82,2): Error: LHS of array assignment must denote an array element (found seq<C>)
+TypeTests.dfy(82,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(82,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(83,2): Error: LHS of array assignment must denote an array element (found seq<C>)
+TypeTests.dfy(83,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(83,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(84,2): Error: LHS of array assignment must denote an array element (found seq<C>)
+TypeTests.dfy(84,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(84,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
+TypeTests.dfy(90,9): Error: sorry, cannot instantiate type parameter with a subrange type
+TypeTests.dfy(91,8): Error: sorry, cannot instantiate 'array' type with a subrange type
+TypeTests.dfy(92,8): Error: sorry, cannot instantiate 'array' type with a subrange type
+34 resolution/type errors detected in TypeTests.dfy
-------------------- NatTypes.dfy --------------------
NatTypes.dfy(7,5): Error: value assigned to a nat must be non-negative
@@ -162,11 +173,18 @@ SmallTests.dfy(131,9): Error: call may violate context's modifies clause
Execution trace:
(0,0): anon0
(0,0): anon3_Else
-SmallTests.dfy(171,11): Error: foreach assignment may update an object not in the enclosing method's modifies clause
+SmallTests.dfy(171,9): Error: assignment may update an object field not in the enclosing context's modifies clause
Execution trace:
(0,0): anon0
- (0,0): anon4_Else
- (0,0): anon3
+ (0,0): anon22_Else
+ (0,0): anon5
+ (0,0): anon24_Else
+ (0,0): anon11
+ (0,0): anon26_Else
+ (0,0): anon16
+ (0,0): anon28_Then
+ (0,0): anon29_Then
+ (0,0): anon19
SmallTests.dfy(199,14): Error: assertion violation
Execution trace:
(0,0): anon0
@@ -363,46 +381,37 @@ Execution trace:
(0,0): anon23_Then
(0,0): anon24_Then
(0,0): anon11
-Definedness.dfy(199,24): Error: possible violation of function precondition
+Definedness.dfy(193,19): Error: possible division by zero
Execution trace:
(0,0): anon0
-Definedness.dfy(201,11): Error: foreach assignment may update an object not in the enclosing method's modifies clause
-Execution trace:
- (0,0): anon0
-Definedness.dfy(203,33): Error: range expression must be well defined
-Execution trace:
- (0,0): anon0
-Definedness.dfy(218,19): Error: possible division by zero
-Execution trace:
- (0,0): anon0
- Definedness.dfy(216,5): anon7_LoopHead
+ Definedness.dfy(191,5): anon7_LoopHead
(0,0): anon7_LoopBody
(0,0): anon8_Then
-Definedness.dfy(218,23): Error BP5004: This loop invariant might not hold on entry.
+Definedness.dfy(193,23): Error BP5004: This loop invariant might not hold on entry.
Execution trace:
(0,0): anon0
-Definedness.dfy(218,28): Error: possible division by zero
+Definedness.dfy(193,28): Error: possible division by zero
Execution trace:
(0,0): anon0
- Definedness.dfy(216,5): anon7_LoopHead
+ Definedness.dfy(191,5): anon7_LoopHead
(0,0): anon7_LoopBody
(0,0): anon8_Then
-Definedness.dfy(239,46): Error: possible violation of function postcondition
+Definedness.dfy(214,46): Error: possible violation of function postcondition
Execution trace:
(0,0): anon0
(0,0): anon5_Else
-Definedness.dfy(246,22): Error: target object may be null
+Definedness.dfy(221,22): Error: target object may be null
Execution trace:
(0,0): anon5_Then
(0,0): anon2
(0,0): anon6_Then
-Definedness.dfy(262,24): Error: possible violation of function postcondition
+Definedness.dfy(237,24): Error: possible violation of function postcondition
Execution trace:
(0,0): anon7_Then
(0,0): anon2
(0,0): anon8_Else
-Dafny program verifier finished with 23 verified, 39 errors
+Dafny program verifier finished with 22 verified, 36 errors
-------------------- FunctionSpecifications.dfy --------------------
FunctionSpecifications.dfy(28,13): Error: possible violation of function postcondition
@@ -947,41 +956,106 @@ Execution trace:
Dafny program verifier finished with 27 verified, 6 errors
+-------------------- ParallelResolveErrors.dfy --------------------
+ParallelResolveErrors.dfy(8,6): Error: LHS of assignment must denote a mutable variable or field
+ParallelResolveErrors.dfy(13,6): Error: body of parallel statement is attempting to update a variable declared outside the parallel statement
+ParallelResolveErrors.dfy(31,6): Error: Assignment to non-ghost variable is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
+ParallelResolveErrors.dfy(43,13): Error: set choose operator not supported inside parallel statement
+ParallelResolveErrors.dfy(48,13): Error: new allocation not supported in parallel statements
+ParallelResolveErrors.dfy(53,13): Error: new allocation not supported in parallel statements
+ParallelResolveErrors.dfy(60,19): Error: trying to break out of more loop levels than there are enclosing loops
+ParallelResolveErrors.dfy(64,18): Error: return statement is not allowed inside a parallel statement
+ParallelResolveErrors.dfy(71,21): Error: trying to break out of more loop levels than there are enclosing loops
+ParallelResolveErrors.dfy(72,20): Error: trying to break out of more loop levels than there are enclosing loops
+ParallelResolveErrors.dfy(73,20): Error: break label is undefined or not in scope: OutsideLoop
+ParallelResolveErrors.dfy(82,24): Error: trying to break out of more loop levels than there are enclosing loops
+ParallelResolveErrors.dfy(83,24): Error: break label is undefined or not in scope: OutsideLoop
+ParallelResolveErrors.dfy(94,43): Error: fresh expressions are not allowed in this context
+ParallelResolveErrors.dfy(101,50): Error: old expressions are not allowed in this context
+ParallelResolveErrors.dfy(124,12): Error: old expressions are not allowed in this context
+ParallelResolveErrors.dfy(144,45): Error: fresh expressions are not allowed in this context
+17 resolution/type errors detected in ParallelResolveErrors.dfy
+
-------------------- Parallel.dfy --------------------
-Parallel.dfy(29,18): Error: possible violation of postcondition of parallel statement
+Parallel.dfy(31,5): Error BP5002: A precondition for this call might not hold.
+Parallel.dfy(57,14): Related location: This is the precondition that might not hold.
Execution trace:
(0,0): anon0
- (0,0): anon17_Else
+ (0,0): anon29_Else
(0,0): anon7
- (0,0): anon20_Else
+ (0,0): anon32_Else
(0,0): anon10
- (0,0): anon21_Then
- (0,0): anon22_Then
+ (0,0): anon33_Then
+ (0,0): anon34_Then
+ (0,0): anon35_Then
(0,0): anon14
-Parallel.dfy(34,19): Error: assertion violation
+Parallel.dfy(35,5): Error: target object may be null
Execution trace:
(0,0): anon0
- (0,0): anon17_Else
+ (0,0): anon29_Else
(0,0): anon7
- (0,0): anon20_Else
+ (0,0): anon32_Else
(0,0): anon10
- (0,0): anon21_Then
- (0,0): anon22_Then
-Parallel.dfy(76,19): Error: assertion violation
+ (0,0): anon33_Else
+ (0,0): anon16
+ (0,0): anon36_Then
+ (0,0): anon37_Then
+ (0,0): anon38_Then
+ (0,0): anon20
+Parallel.dfy(39,18): Error: possible violation of postcondition of parallel statement
+Execution trace:
+ (0,0): anon0
+ (0,0): anon29_Else
+ (0,0): anon7
+ (0,0): anon32_Else
+ (0,0): anon10
+ (0,0): anon33_Else
+ (0,0): anon16
+ (0,0): anon36_Else
+ (0,0): anon22
+ (0,0): anon39_Then
+ (0,0): anon40_Then
+ (0,0): anon26
+Parallel.dfy(44,19): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon29_Else
+ (0,0): anon7
+ (0,0): anon32_Else
+ (0,0): anon10
+ (0,0): anon33_Else
+ (0,0): anon16
+ (0,0): anon36_Else
+ (0,0): anon22
+ (0,0): anon39_Then
+ (0,0): anon40_Then
+Parallel.dfy(90,19): Error: assertion violation
Execution trace:
(0,0): anon0
(0,0): anon10_Else
(0,0): anon3
(0,0): anon11_Then
-Parallel.dfy(82,20): Error: possible violation of postcondition of parallel statement
+Parallel.dfy(96,20): Error: possible violation of postcondition of parallel statement
Execution trace:
(0,0): anon0
(0,0): anon10_Else
(0,0): anon3
(0,0): anon11_Then
(0,0): anon12_Then
+Parallel.dfy(119,12): Error: value assigned to a nat must be non-negative
+Execution trace:
+ (0,0): anon0
+ (0,0): anon6_Then
+ (0,0): anon7_Then
+ (0,0): anon3
+Parallel.dfy(182,12): Error: left-hand sides for different parallel-statement bound variables may refer to the same location
+Execution trace:
+ (0,0): anon0
+ (0,0): anon19_Then
+ (0,0): anon20_Then
+ (0,0): anon5
-Dafny program verifier finished with 12 verified, 4 errors
+Dafny program verifier finished with 24 verified, 8 errors
-------------------- TypeParameters.dfy --------------------
TypeParameters.dfy(44,22): Error: assertion violation
@@ -1056,21 +1130,25 @@ TypeAntecedents.dfy(55,1): Error BP5003: A postcondition might not hold on this
TypeAntecedents.dfy(54,15): Related location: This is the postcondition that might not hold.
Execution trace:
(0,0): anon0
- (0,0): anon15_Then
+ (0,0): anon25_Then
(0,0): anon6
- (0,0): anon18_Then
+ (0,0): anon28_Then
(0,0): anon8
- (0,0): anon19_Then
- (0,0): anon10
- (0,0): anon20_Then
- (0,0): anon21_Then
- (0,0): anon14
+ (0,0): anon29_Else
+ (0,0): anon13
+ (0,0): anon31_Else
+ (0,0): anon18
+ (0,0): anon33_Then
+ (0,0): anon20
+ (0,0): anon34_Then
+ (0,0): anon35_Then
+ (0,0): anon24
TypeAntecedents.dfy(63,16): Error: assertion violation
Execution trace:
(0,0): anon0
- (0,0): anon15_Else
- (0,0): anon16_Then
- (0,0): anon17_Else
+ (0,0): anon25_Else
+ (0,0): anon26_Then
+ (0,0): anon27_Else
Dafny program verifier finished with 12 verified, 3 errors
diff --git a/Test/dafny0/Definedness.dfy b/Test/dafny0/Definedness.dfy
index 44b54f3d..f99d1503 100644
--- a/Test/dafny0/Definedness.dfy
+++ b/Test/dafny0/Definedness.dfy
@@ -185,31 +185,6 @@ class StatementTwoShoes {
function G(w: int): int { 5 }
function method H(x: int): int { -x }
- method V(s: set<StatementTwoShoes>, a: int, b: int)
- modifies s;
- {
-
- foreach (m in s | m.x < 200) // s may contain null, but the foreach excludes null
- {
- assume 0 <= m.x;
- assert m.x < 1000;
-
- m.x := m.x + 1;
- }
- foreach (m in s + {F(a)}) // error: collection expression may not be well defined (fn precondition)
- {
- m.x := 5; // error: possible modifies clause violation
- }
- foreach (m in s | F(H(m.x)) == this) // error: range expression may not be well defined
- {
- m.x := H(m.x);
- }
- foreach (m in s)
- {
- m.x := 100 / m.x; // error: RhS may not be well defined
- }
- }
-
method W(x: int)
{
var i := 0;
diff --git a/Test/dafny0/Parallel.dfy b/Test/dafny0/Parallel.dfy
index 88a67957..539974fd 100644
--- a/Test/dafny0/Parallel.dfy
+++ b/Test/dafny0/Parallel.dfy
@@ -1,6 +1,11 @@
class C {
var data: int;
+ var n: nat;
var st: set<object>;
+
+ ghost method CLemma(k: int)
+ requires k != -23;
+ ensures data < k; // magic, isn't it (or bogus, some would say)
}
// This method more or less just tests the syntax, resolution, and basic verification
@@ -8,7 +13,8 @@ method ParallelStatement_Resolve(
a: array<int>,
spine: set<C>,
Repr: set<object>,
- S: set<int>
+ S: set<int>,
+ clx: C, cly: C, clk: int
)
requires a != null && null !in spine;
modifies a, spine;
@@ -22,17 +28,21 @@ method ParallelStatement_Resolve(
}
parallel (x, y | x in S && 0 <= y+x < 100) {
- Lemma(x, y);
+ Lemma(clx, x, y); // error: precondition does not hold (clx may be null)
+ }
+
+ parallel (x, y | x in S && 0 <= y+x < 100) {
+ cly.CLemma(x + y); // error: receiver might be null
}
parallel (p | 0 <= p)
- ensures F(p) <= Sum(p) * (p-1) + 100; // error (no connection is known between F and Sum)
+ ensures F(p) <= Sum(p) + p - 1; // error (no connection is known between F and Sum)
{
assert 0 <= G(p);
ghost var t;
if (p % 2 == 0) {
assert G(p) == F(p+2); // error (there's nothing that gives any relation between F and G)
- t := p*p;
+ t := p+p;
} else {
assume H(p, 20) < 100; // don't know how to justify this
t := p;
@@ -43,13 +53,17 @@ method ParallelStatement_Resolve(
}
}
-method Lemma(x: int, y: int)
+method Lemma(c: C, x: int, y: int)
+ requires c != null;
+ ensures c.data <= x+y;
ghost method PowerLemma(x: int, y: int)
+ ensures Pred(x, y);
function F(x: int): int
function G(x: int): nat
function H(x: int, y: int): int
function Sum(x: int): int
+function Pred(x: int, y: int): bool
// ---------------------------------------------------------------------
@@ -97,3 +111,90 @@ method M2() returns (a: array<int>)
a[i] := 300 + i;
}
}
+
+method M4(S: set<C>, k: int)
+ modifies S;
+{
+ parallel (s | s in S && s != null) {
+ s.n := k; // error: k might be negative
+ }
+}
+
+method M5()
+{
+ if {
+ case true =>
+ parallel (x | 0 <= x < 100) {
+ PowerLemma(x, x);
+ }
+ assert Pred(34, 34);
+
+ case true =>
+ parallel (x,y | 0 <= x < 100 && y == x+1) {
+ PowerLemma(x, y);
+ }
+ assert Pred(34, 35);
+
+ case true =>
+ parallel (x,y | 0 <= x < y < 100) {
+ PowerLemma(x, y);
+ }
+ assert Pred(34, 35);
+
+ case true =>
+ parallel (x | x in set k | 0 <= k < 100) {
+ PowerLemma(x, x);
+ }
+ assert Pred(34, 34);
+ }
+}
+
+method Main()
+{
+ var a := new int[180];
+ parallel (i | 0 <= i < 180) {
+ a[i] := 2*i + 100;
+ }
+ var sq := [0, 0, 0, 2, 2, 2, 5, 5, 5];
+ parallel (i | 0 <= i < |sq|) {
+ a[20+i] := sq[i];
+ }
+ parallel (t | t in sq) {
+ a[t] := 1000;
+ }
+ parallel (t,u | t in sq && t < 4 && 10 <= u < 10+t) {
+ a[u] := 6000 + t;
+ }
+ var k := 0;
+ while (k < 180) {
+ if (k != 0) { print ", "; }
+ print a[k];
+ k := k + 1;
+ }
+ print "\n";
+}
+
+method DuplicateUpdate() {
+ var a := new int[180];
+ var sq := [0, 0, 0, 2, 2, 2, 5, 5, 5];
+ if (*) {
+ parallel (t,u | t in sq && 10 <= u < 10+t) {
+ a[u] := 6000 + t; // error: a[10] (and a[11]) are assigned more than once
+ }
+ } else {
+ parallel (t,u | t in sq && t < 4 && 10 <= u < 10+t) {
+ a[u] := 6000 + t; // with the 't < 4' conjunct in the line above, this is fine
+ }
+ }
+}
+
+ghost method DontDoMuch(x: int)
+{
+}
+
+method OmittedRange() {
+ parallel (x) { }
+ parallel (x) {
+ DontDoMuch(x);
+ }
+}
diff --git a/Test/dafny0/ParallelResolveErrors.dfy b/Test/dafny0/ParallelResolveErrors.dfy
new file mode 100644
index 00000000..9afa311a
--- /dev/null
+++ b/Test/dafny0/ParallelResolveErrors.dfy
@@ -0,0 +1,151 @@
+class C {
+ var data: int;
+}
+
+method M0(IS: set<int>)
+{
+ parallel (i | 0 <= i < 20) {
+ i := i + 1; // error: not allowed to assign to bound variable
+ }
+
+ var k := 0;
+ parallel (i | 0 <= i < 20) {
+ k := k + i; // error: not allowed to assign to local k, since k is not declared inside parallel block
+ }
+
+ parallel (i | 0 <= i < 20)
+ ensures true;
+ {
+ var x := i;
+ x := x + 1;
+ }
+
+ ghost var y;
+ var z;
+ parallel (i | 0 <= i)
+ ensures true;
+ {
+ var x := i;
+ x := x + 1;
+ y := 18; // (this statement is not allowed, since y is declared outside the parallel, but that check happens only if the first resolution pass of the parallel statement passes, which it doesn't in this case because of the next line)
+ z := 20; // error: assigning to a non-ghost variable inside a ghost parallel block
+ }
+
+ parallel (i | 0 <= i)
+ ensures true;
+ {
+ ghost var x := i;
+ x := x + 1; // cool
+ }
+
+ var ia := new int[20];
+ parallel (i | 0 <= i < 20) {
+ ia[i] := choose IS; // error: set choose not allowed
+ }
+
+ var ca := new C[20];
+ parallel (i | 0 <= i < 20) {
+ ca[i] := new C; // error: new allocation not allowed
+ }
+ parallel (i | 0 <= i < 20)
+ ensures true;
+ {
+ var c := new C; // error: new allocation not allowed
+ }
+}
+
+method M1() {
+ parallel (i | 0 <= i < 20) {
+ assert i < 100;
+ if (i == 17) { break; } // error: nothing to break out of
+ }
+
+ parallel (i | 0 <= i < 20) ensures true; {
+ if (i == 8) { return; } // error: return not allowed inside parallel block
+ }
+
+ var m := 0;
+ label OutsideLoop:
+ while (m < 20) {
+ parallel (i | 0 <= i < 20) {
+ if (i == 17) { break; } // error: not allowed to break out of loop that sits outside parallel
+ if (i == 8) { break break; } // error: ditto (also: attempt to break too far)
+ if (i == 9) { break OutsideLoop; } // error: ditto
+ }
+ m := m + 1;
+ }
+
+ parallel (i | 0 <= i < 20) {
+ var j := 0;
+ while (j < i) {
+ if (j == 6) { break; } // fine
+ if (j % 7 == 4) { break break; } // error: attempt to break out too far
+ if (j % 7 == 4) { break OutsideLoop; } // error: attempt to break to place not in enclosing scope
+ j := j + 1;
+ }
+ }
+}
+
+// -------------------------------------------------------------------------------------
+// Some soundness considerations
+// -------------------------------------------------------------------------------------
+
+ghost static method X_M0(y: int)
+ ensures exists o: object :: o != null && fresh(o); // error: not allowed 'fresh' here
+{
+ var p := new object;
+}
+
+class X_C { ghost var data: int; }
+ghost static method X_M1(y: int)
+ ensures exists c: X_C :: c != null && c.data != old(c.data); // error: not allowed 'old' here
+{
+ var c := new X_C;
+ c.data := c.data + 1;
+}
+
+method X_Main() {
+ if (*) {
+ parallel (x) { X_M0(x); }
+ } else {
+ parallel (x) { X_M1(x); }
+ }
+ assert false;
+}
+
+
+// The following seems to be a legitimate use of a two-state predicate in the postcondition of the parallel statement
+method X_Legit(c: X_C)
+ requires c != null;
+ modifies c;
+{
+ c.data := c.data + 1;
+ parallel (x | c.data <= x)
+ ensures old(c.data) < x; // error: not allowed 'old' here
+ {
+ }
+}
+
+// X_M2 is like X_M0, but with an out-parameter
+ghost static method X_M2(y: int) returns (r: int)
+ ensures exists o: object :: o != null && fresh(o); // 'fresh' is allowed here (because there's something coming "out" of this ghost method, namely 'r'
+{
+ var p := new object;
+}
+
+// The following method exhibits a case where M2 and a two-state parallel ensures would lead to an unsoundness
+// with the current translation.
+method X_AnotherMain(c: X_C)
+ requires c != null;
+ modifies c;
+{
+ c.data := c.data + 1;
+ parallel (x: int)
+ ensures exists o: object :: o != null && fresh(o); // error: not allowed 'fresh' here
+ {
+ var s := X_M2(x);
+ }
+ assert false;
+}
+
+// -------------------------------------------------------------------------------------
diff --git a/Test/dafny0/SmallTests.dfy b/Test/dafny0/SmallTests.dfy
index 439930b5..d4a0ad9a 100644
--- a/Test/dafny0/SmallTests.dfy
+++ b/Test/dafny0/SmallTests.dfy
@@ -144,7 +144,7 @@ class Modifies {
method F(s: set<Modifies>)
modifies s;
{
- foreach (m in s | 2 <= m.x) {
+ parallel (m | m in s && m != null && 2 <= m.x) {
m.x := m.x + 1;
}
if (this in s) {
@@ -157,17 +157,17 @@ class Modifies {
{
var m := 3; // this is a different m
- foreach (m in s | m == this) {
+ parallel (m | m in s && m == this) {
m.x := m.x + 1;
}
if (s <= {this}) {
- foreach (m in s) {
+ parallel (m | m in s) {
m.x := m.x + 1;
}
F(s);
}
- foreach (m in s) {
- assert m.x < m.x + 10; // nothing wrong with asserting something
+ parallel (m | m in s) ensures true; { assert m == null || m.x < m.x + 10; }
+ parallel (m | m != null && m in s) {
m.x := m.x + 1; // error: may violate modifies clause
}
}
@@ -322,10 +322,10 @@ class SomeType
{
var x: int;
method DoIt(stack: seq<SomeType>)
+ requires null !in stack;
modifies stack;
{
- // the following line once gave rise to a crash in the translation
- foreach (n in stack) {
+ parallel (n | n in stack) {
n.x := 10;
}
}
diff --git a/Test/dafny0/TypeAntecedents.dfy b/Test/dafny0/TypeAntecedents.dfy
index 5982a9e6..b6ef0d68 100644
--- a/Test/dafny0/TypeAntecedents.dfy
+++ b/Test/dafny0/TypeAntecedents.dfy
@@ -68,8 +68,8 @@ method M(list: List, S: set<MyClass>) returns (ret: int)
ghost var l := NF();
assert l != null ==> l.H() == 5;
- foreach (s in S) {
- assert s == null || s.H() == 5;
+ parallel (s | s in S) ensures true; { assert s == null || s.H() == 5; }
+ parallel (s | s != null && s in S) {
s.x := 0;
}
diff --git a/Test/dafny0/TypeTests.dfy b/Test/dafny0/TypeTests.dfy
index 2208051d..29274381 100644
--- a/Test/dafny0/TypeTests.dfy
+++ b/Test/dafny0/TypeTests.dfy
@@ -72,11 +72,16 @@ method InitCalls() {
// ---------------------
-method ArrayRangeAssignments(a: array<C>)
+method ArrayRangeAssignments(a: array<C>, c: C)
requires a != null && 10 <= a.Length;
{
- a[0..5] := new C; // this is not allowed
- a[1..4] := *; // this is not allowed
+ a[0..5] := new C; // error: this is not allowed
+ a[1..4] := *; // error: this is not allowed
+ a[2..3] := c; // error: this is not allowed
+ var s: seq<C> := [null,null,null,null,null];
+ s[0..5] := new C; // error: this is not allowed
+ s[1..4] := *; // error: this is not allowed
+ s[2..3] := c; // error: this is not allowed
}
// --------------------- tests of restrictions on subranges (nat)
diff --git a/Test/dafny0/runtest.bat b/Test/dafny0/runtest.bat
index a670ced5..c30ec3a5 100644
--- a/Test/dafny0/runtest.bat
+++ b/Test/dafny0/runtest.bat
@@ -16,7 +16,7 @@ for %%f in (TypeTests.dfy NatTypes.dfy SmallTests.dfy Definedness.dfy
Array.dfy MultiDimArray.dfy NonGhostQuantifiers.dfy AdvancedLHS.dfy
Modules0.dfy Modules1.dfy BadFunction.dfy
Comprehensions.dfy Basics.dfy ControlStructures.dfy
- Termination.dfy DTypes.dfy Parallel.dfy
+ Termination.dfy DTypes.dfy ParallelResolveErrors.dfy Parallel.dfy
TypeParameters.dfy Datatypes.dfy TypeAntecedents.dfy SplitExpr.dfy
Refinement.dfy RefinementErrors.dfy LoopModifies.dfy
ReturnErrors.dfy ReturnTests.dfy ChainingDisjointTests.dfy
diff --git a/Test/dafny1/Answer b/Test/dafny1/Answer
index 0a99ca95..ab10d944 100644
--- a/Test/dafny1/Answer
+++ b/Test/dafny1/Answer
@@ -81,15 +81,31 @@ Dafny program verifier finished with 6 verified, 0 errors
-------------------- Induction.dfy --------------------
-Dafny program verifier finished with 29 verified, 0 errors
+Dafny program verifier finished with 33 verified, 0 errors
-------------------- Rippling.dfy --------------------
-Dafny program verifier finished with 137 verified, 0 errors
+Dafny program verifier finished with 141 verified, 0 errors
-------------------- MoreInduction.dfy --------------------
-
-Dafny program verifier finished with 8 verified, 0 errors
+MoreInduction.dfy(75,1): Error BP5003: A postcondition might not hold on this return path.
+MoreInduction.dfy(74,11): Related location: This is the postcondition that might not hold.
+Execution trace:
+ (0,0): anon0
+MoreInduction.dfy(80,1): Error BP5003: A postcondition might not hold on this return path.
+MoreInduction.dfy(79,21): Related location: This is the postcondition that might not hold.
+Execution trace:
+ (0,0): anon0
+MoreInduction.dfy(85,1): Error BP5003: A postcondition might not hold on this return path.
+MoreInduction.dfy(84,11): Related location: This is the postcondition that might not hold.
+Execution trace:
+ (0,0): anon0
+MoreInduction.dfy(90,1): Error BP5003: A postcondition might not hold on this return path.
+MoreInduction.dfy(89,22): Related location: This is the postcondition that might not hold.
+Execution trace:
+ (0,0): anon0
+
+Dafny program verifier finished with 15 verified, 4 errors
-------------------- Celebrity.dfy --------------------
diff --git a/Test/dafny1/Induction.dfy b/Test/dafny1/Induction.dfy
index 15cc1ffe..3585dde6 100644
--- a/Test/dafny1/Induction.dfy
+++ b/Test/dafny1/Induction.dfy
@@ -56,6 +56,23 @@ class IntegerInduction {
{
}
+ // The following two ghost methods are the same as the previous two, but
+ // here no body is given--and the proof still goes through (thanks to
+ // Dafny's ghost-method induction tactic).
+
+ ghost method Lemma_Auto(n: int)
+ requires 0 <= n;
+ ensures 2 * Gauss(n) == n*(n+1);
+ {
+ }
+
+ ghost method Theorem1_Auto(n: int)
+ requires 0 <= n;
+ ensures SumOfCubes(n) == Gauss(n) * Gauss(n);
+ ensures 2 * Gauss(n) == n*(n+1);
+ {
+ }
+
// Here is another proof. It makes use of Dafny's induction heuristics to
// prove the lemma.
diff --git a/Test/dafny1/MoreInduction.dfy b/Test/dafny1/MoreInduction.dfy
index efba0963..84c32fb3 100644
--- a/Test/dafny1/MoreInduction.dfy
+++ b/Test/dafny1/MoreInduction.dfy
@@ -61,3 +61,37 @@ ghost method Lemma<X>(list: List<X>, ext: List<X>)
}
}
}
+
+// ---------------------------------------------
+
+function NegFac(n: int): int
+ decreases -n;
+{
+ if -1 <= n then -1 else - NegFac(n+1) * n
+}
+
+ghost method LemmaAll()
+ ensures forall n :: NegFac(n) <= -1; // error: induction heuristic does not give a useful well-founded order, and thus this fails to verify
+{
+}
+
+ghost method LemmaOne(n: int)
+ ensures NegFac(n) <= -1; // error: induction heuristic does not give a useful well-founded order, and thus this fails to verify
+{
+}
+
+ghost method LemmaAll_Neg()
+ ensures forall n :: NegFac(-n) <= -1; // error: fails to verify because of the minus in the trigger
+{
+}
+
+ghost method LemmaOne_Neg(n: int)
+ ensures NegFac(-n) <= -1; // error: fails to verify because of the minus in the trigger
+{
+}
+
+ghost method LemmaOneWithDecreases(n: int)
+ ensures NegFac(n) <= -1; // here, the programmer gives a good well-founded order, so this verifies
+ decreases -n;
+{
+}
diff --git a/Test/dafny1/Rippling.dfy b/Test/dafny1/Rippling.dfy
index 6f6a7ba7..c9a9f3b7 100644
--- a/Test/dafny1/Rippling.dfy
+++ b/Test/dafny1/Rippling.dfy
@@ -298,248 +298,247 @@ function AlwaysTrueFunction(): FunctionValue
// -----------------------------------------------------------------------------------
ghost method P1()
- ensures (forall n, xs :: concat(take(n, xs), drop(n, xs)) == xs);
+ ensures forall n, xs :: concat(take(n, xs), drop(n, xs)) == xs;
{
}
ghost method P2()
- ensures (forall n, xs, ys :: add(count(n, xs), count(n, ys)) == count(n, (concat(xs, ys))));
+ ensures forall n, xs, ys :: add(count(n, xs), count(n, ys)) == count(n, (concat(xs, ys)));
{
}
ghost method P3()
- ensures (forall n, xs, ys :: leq(count(n, xs), count(n, concat(xs, ys))) == True);
+ ensures forall n, xs, ys :: leq(count(n, xs), count(n, concat(xs, ys))) == True;
{
}
ghost method P4()
- ensures (forall n, xs :: add(Suc(Zero), count(n, xs)) == count(n, Cons(n, xs)));
+ ensures forall n, xs :: add(Suc(Zero), count(n, xs)) == count(n, Cons(n, xs));
{
}
ghost method P5()
- ensures (forall n, xs, x ::
+ ensures forall n, xs, x ::
add(Suc(Zero), count(n, xs)) == count(n, Cons(x, xs))
- ==> n == x);
+ ==> n == x;
{
}
ghost method P6()
- ensures (forall m, n :: minus(n, add(n, m)) == Zero);
+ ensures forall m, n :: minus(n, add(n, m)) == Zero;
{
}
ghost method P7()
- ensures (forall m, n :: minus(add(n, m), n) == m);
+ ensures forall m, n :: minus(add(n, m), n) == m;
{
}
ghost method P8()
- ensures (forall k, m, n :: minus(add(k, m), add(k, n)) == minus(m, n));
+ ensures forall k, m, n :: minus(add(k, m), add(k, n)) == minus(m, n);
{
}
ghost method P9()
- ensures (forall i, j, k :: minus(minus(i, j), k) == minus(i, add(j, k)));
+ ensures forall i, j, k :: minus(minus(i, j), k) == minus(i, add(j, k));
{
}
ghost method P10()
- ensures (forall m :: minus(m, m) == Zero);
+ ensures forall m :: minus(m, m) == Zero;
{
}
ghost method P11()
- ensures (forall xs :: drop(Zero, xs) == xs);
+ ensures forall xs :: drop(Zero, xs) == xs;
{
}
ghost method P12()
- ensures (forall n, xs, f :: drop(n, map(f, xs)) == map(f, drop(n, xs)));
+ ensures forall n, xs, f :: drop(n, map(f, xs)) == map(f, drop(n, xs));
{
}
ghost method P13()
- ensures (forall n, x, xs :: drop(Suc(n), Cons(x, xs)) == drop(n, xs));
+ ensures forall n, x, xs :: drop(Suc(n), Cons(x, xs)) == drop(n, xs);
{
}
ghost method P14()
- ensures (forall xs, ys, p :: filter(p, concat(xs, ys)) == concat(filter(p, xs), filter(p, ys)));
+ ensures forall xs, ys, p :: filter(p, concat(xs, ys)) == concat(filter(p, xs), filter(p, ys));
{
}
ghost method P15()
- ensures (forall x, xs :: len(ins(x, xs)) == Suc(len(xs)));
+ ensures forall x, xs :: len(ins(x, xs)) == Suc(len(xs));
{
}
ghost method P16()
- ensures (forall x, xs :: xs == Nil ==> last(Cons(x, xs)) == x);
+ ensures forall x, xs :: xs == Nil ==> last(Cons(x, xs)) == x;
{
}
ghost method P17()
- ensures (forall n :: leq(n, Zero) == True <==> n == Zero);
+ ensures forall n :: leq(n, Zero) == True <==> n == Zero;
{
}
ghost method P18()
- ensures (forall i, m :: less(i, Suc(add(i, m))) == True);
+ ensures forall i, m :: less(i, Suc(add(i, m))) == True;
{
}
ghost method P19()
- ensures (forall n, xs :: len(drop(n, xs)) == minus(len(xs), n));
+ ensures forall n, xs :: len(drop(n, xs)) == minus(len(xs), n);
{
}
ghost method P20()
- ensures (forall xs :: len(sort(xs)) == len(xs));
+ ensures forall xs :: len(sort(xs)) == len(xs);
{
- // proving this theorem requires an additional lemma:
- assert (forall k, ks :: len(ins(k, ks)) == len(Cons(k, ks)));
- // ...and one manually introduced case study:
- assert (forall ys ::
+ P15(); // use the statement of problem 15 as a lemma
+ // ... and manually introduce a case distinction:
+ assert forall ys ::
sort(ys) == Nil ||
- (exists z, zs :: sort(ys) == Cons(z, zs)));
+ exists z, zs :: sort(ys) == Cons(z, zs);
}
ghost method P21()
- ensures (forall n, m :: leq(n, add(n, m)) == True);
+ ensures forall n, m :: leq(n, add(n, m)) == True;
{
}
ghost method P22()
- ensures (forall a, b, c :: max(max(a, b), c) == max(a, max(b, c)));
+ ensures forall a, b, c :: max(max(a, b), c) == max(a, max(b, c));
{
}
ghost method P23()
- ensures (forall a, b :: max(a, b) == max(b, a));
+ ensures forall a, b :: max(a, b) == max(b, a);
{
}
ghost method P24()
- ensures (forall a, b :: max(a, b) == a <==> leq(b, a) == True);
+ ensures forall a, b :: max(a, b) == a <==> leq(b, a) == True;
{
}
ghost method P25()
- ensures (forall a, b :: max(a, b) == b <==> leq(a, b) == True);
+ ensures forall a, b :: max(a, b) == b <==> leq(a, b) == True;
{
}
ghost method P26()
- ensures (forall x, xs, ys :: mem(x, xs) == True ==> mem(x, concat(xs, ys)) == True);
+ ensures forall x, xs, ys :: mem(x, xs) == True ==> mem(x, concat(xs, ys)) == True;
{
}
ghost method P27()
- ensures (forall x, xs, ys :: mem(x, ys) == True ==> mem(x, concat(xs, ys)) == True);
+ ensures forall x, xs, ys :: mem(x, ys) == True ==> mem(x, concat(xs, ys)) == True;
{
}
ghost method P28()
- ensures (forall x, xs :: mem(x, concat(xs, Cons(x, Nil))) == True);
+ ensures forall x, xs :: mem(x, concat(xs, Cons(x, Nil))) == True;
{
}
ghost method P29()
- ensures (forall x, xs :: mem(x, ins1(x, xs)) == True);
+ ensures forall x, xs :: mem(x, ins1(x, xs)) == True;
{
}
ghost method P30()
- ensures (forall x, xs :: mem(x, ins(x, xs)) == True);
+ ensures forall x, xs :: mem(x, ins(x, xs)) == True;
{
}
ghost method P31()
- ensures (forall a, b, c :: min(min(a, b), c) == min(a, min(b, c)));
+ ensures forall a, b, c :: min(min(a, b), c) == min(a, min(b, c));
{
}
ghost method P32()
- ensures (forall a, b :: min(a, b) == min(b, a));
+ ensures forall a, b :: min(a, b) == min(b, a);
{
}
ghost method P33()
- ensures (forall a, b :: min(a, b) == a <==> leq(a, b) == True);
+ ensures forall a, b :: min(a, b) == a <==> leq(a, b) == True;
{
}
ghost method P34()
- ensures (forall a, b :: min(a, b) == b <==> leq(b, a) == True);
+ ensures forall a, b :: min(a, b) == b <==> leq(b, a) == True;
{
}
ghost method P35()
- ensures (forall xs :: dropWhileAlways(AlwaysFalseFunction(), xs) == xs);
+ ensures forall xs :: dropWhileAlways(AlwaysFalseFunction(), xs) == xs;
{
}
ghost method P36()
- ensures (forall xs :: takeWhileAlways(AlwaysTrueFunction(), xs) == xs);
+ ensures forall xs :: takeWhileAlways(AlwaysTrueFunction(), xs) == xs;
{
}
ghost method P37()
- ensures (forall x, xs :: not(mem(x, delete(x, xs))) == True);
+ ensures forall x, xs :: not(mem(x, delete(x, xs))) == True;
{
}
ghost method P38()
- ensures (forall n, xs :: count(n, concat(xs, Cons(n, Nil))) == Suc(count(n, xs)));
+ ensures forall n, xs :: count(n, concat(xs, Cons(n, Nil))) == Suc(count(n, xs));
{
}
ghost method P39()
- ensures (forall n, x, xs ::
- add(count(n, Cons(x, Nil)), count(n, xs)) == count(n, Cons(x, xs)));
+ ensures forall n, x, xs ::
+ add(count(n, Cons(x, Nil)), count(n, xs)) == count(n, Cons(x, xs));
{
}
ghost method P40()
- ensures (forall xs :: take(Zero, xs) == Nil);
+ ensures forall xs :: take(Zero, xs) == Nil;
{
}
ghost method P41()
- ensures (forall n, xs, f :: take(n, map(f, xs)) == map(f, take(n, xs)));
+ ensures forall n, xs, f :: take(n, map(f, xs)) == map(f, take(n, xs));
{
}
ghost method P42()
- ensures (forall n, x, xs :: take(Suc(n), Cons(x, xs)) == Cons(x, take(n, xs)));
+ ensures forall n, x, xs :: take(Suc(n), Cons(x, xs)) == Cons(x, take(n, xs));
{
}
ghost method P43(p: FunctionValue)
- ensures (forall xs :: concat(takeWhileAlways(p, xs), dropWhileAlways(p, xs)) == xs);
+ ensures forall xs :: concat(takeWhileAlways(p, xs), dropWhileAlways(p, xs)) == xs;
{
}
ghost method P44()
- ensures (forall x, xs, ys :: zip(Cons(x, xs), ys) == zipConcat(x, xs, ys));
+ ensures forall x, xs, ys :: zip(Cons(x, xs), ys) == zipConcat(x, xs, ys);
{
}
ghost method P45()
- ensures (forall x, xs, y, ys ::
+ ensures forall x, xs, y, ys ::
zip(Cons(x, xs), Cons(y, ys)) ==
- PCons(Pair.Pair(x, y), zip(xs, ys)));
+ PCons(Pair.Pair(x, y), zip(xs, ys));
{
}
ghost method P46()
- ensures (forall ys :: zip(Nil, ys) == PNil);
+ ensures forall ys :: zip(Nil, ys) == PNil;
{
}
ghost method P47()
- ensures (forall a :: height(mirror(a)) == height(a));
+ ensures forall a :: height(mirror(a)) == height(a);
{
// proving this theorem requires a previously proved lemma:
P23();
@@ -548,40 +547,53 @@ ghost method P47()
// ...
ghost method P54()
- ensures (forall m, n :: minus(add(m, n), n) == m);
+ ensures forall m, n :: minus(add(m, n), n) == m;
{
// the proof of this theorem follows from two lemmas:
- assert (forall m, n :: minus(add(n, m), n) == m);
- assert (forall m, n :: add(m, n) == add(n, m));
+ assert forall m, n :: minus(add(n, m), n) == m;
+ assert forall m, n :: add(m, n) == add(n, m);
}
ghost method P65()
- ensures (forall i, m :: less(i, Suc(add(m, i))) == True);
+ ensures forall i, m :: less(i, Suc(add(m, i))) == True;
{
if (*) {
// the proof of this theorem follows from two lemmas:
- assert (forall i, m :: less(i, Suc(add(i, m))) == True);
- assert (forall m, n :: add(m, n) == add(n, m));
+ assert forall i, m :: less(i, Suc(add(i, m))) == True;
+ assert forall m, n :: add(m, n) == add(n, m);
} else {
// a different way to prove it uses the following lemma:
- assert (forall x,y :: add(x, Suc(y)) == Suc(add(x,y)));
+ assert forall x,y :: add(x, Suc(y)) == Suc(add(x,y));
}
}
ghost method P67()
- ensures (forall m, n :: leq(n, add(m, n)) == True);
+ ensures forall m, n :: leq(n, add(m, n)) == True;
{
if (*) {
// the proof of this theorem follows from two lemmas:
- assert (forall m, n :: leq(n, add(n, m)) == True);
- assert (forall m, n :: add(m, n) == add(n, m));
+ assert forall m, n :: leq(n, add(n, m)) == True;
+ assert forall m, n :: add(m, n) == add(n, m);
} else {
// a different way to prove it uses the following lemma:
- assert (forall x,y :: add(x, Suc(y)) == Suc(add(x,y)));
+ assert forall x,y :: add(x, Suc(y)) == Suc(add(x,y));
}
}
// ---------
+// Here is a alternate way of writing down the proof obligations:
+
+ghost method P1_alt(n: Nat, xs: List)
+ ensures concat(take(n, xs), drop(n, xs)) == xs;
+{
+}
+
+ghost method P2_alt(n: Nat, xs: List, ys: List)
+ ensures add(count(n, xs), count(n, ys)) == count(n, (concat(xs, ys)));
+{
+}
+
+// ---------
ghost method Lemma_RevConcat(xs: List, ys: List)
ensures reverse(concat(xs, ys)) == concat(reverse(ys), reverse(xs));
diff --git a/Test/dafny2/Answer b/Test/dafny2/Answer
index 81db547b..eed3eaa0 100644
--- a/Test/dafny2/Answer
+++ b/Test/dafny2/Answer
@@ -1,7 +1,11 @@
+-------------------- Classics.dfy --------------------
+
+Dafny program verifier finished with 5 verified, 0 errors
+
-------------------- SnapshotableTrees.dfy --------------------
-Dafny program verifier finished with 37 verified, 0 errors
+Dafny program verifier finished with 36 verified, 0 errors
-------------------- TreeBarrier.dfy --------------------
diff --git a/Test/dafny2/Classics.dfy b/Test/dafny2/Classics.dfy
new file mode 100644
index 00000000..68d9bf79
--- /dev/null
+++ b/Test/dafny2/Classics.dfy
@@ -0,0 +1,103 @@
+// A version of Turing's additive factorial program [Dr. A. Turing, "Checking a large routine",
+// In "Report of a Conference of High Speed Automatic Calculating Machines", pp. 67-69, 1949].
+
+function Factorial(n: nat): nat
+{
+ if n == 0 then 1 else n * Factorial(n-1)
+}
+
+method AdditiveFactorial(n: nat) returns (u: nat)
+ ensures u == Factorial(n);
+{
+ u := 1;
+ var r := 0;
+ while (r < n)
+ invariant 0 <= r <= n;
+ invariant u == Factorial(r);
+ {
+ var v := u;
+ var s := 1;
+ while (s <= r)
+ invariant 1 <= s <= r+1;
+ invariant u == s * Factorial(r);
+ {
+ u := u + v;
+ s := s + 1;
+ }
+ r := r + 1;
+ }
+}
+
+// Hoare's FIND program [C.A.R. Hoare, "Proof of a program: FIND", CACM 14(1): 39-45, 1971].
+// The proof annotations here are not the same as in Hoare's article.
+
+// In Hoare's words:
+// This program operates on an array A[1:N], and a value of f (1 <= f <= N).
+// Its effect is to rearrange the elements of A in such a way that:
+// forall p,q (1 <= p <= f <= q <= N ==> A[p] <= A[f] <= A[q]).
+//
+// Here, we use 0-based indices, so we would say:
+// This method operates on an array A[0..N], and a value of f (0 <= f < N).
+// Its effect is to rearrange the elements of A in such a way that:
+// forall p,q :: 0 <= p <= f <= q < N ==> A[p] <= A[f] <= A[q]).
+
+method FIND(A: array<int>, N: int, f: int)
+ requires A != null && A.Length == N;
+ requires 0 <= f < N;
+ modifies A;
+ ensures forall p,q :: 0 <= p <= f <= q < N ==> A[p] <= A[q];
+{
+ var m, n := 0, N-1;
+ while (m < n)
+ invariant 0 <= m <= f <= n < N;
+ invariant forall p,q :: 0 <= p < m <= q < N ==> A[p] <= A[q];
+ invariant forall p,q :: 0 <= p <= n < q < N ==> A[p] <= A[q];
+ {
+ var r, i, j := A[f], m, n;
+ while (i <= j)
+ invariant m <= i && j <= n;
+ invariant -1 <= j && i <= N;
+ invariant i <= j ==> exists g :: i <= g < N && r <= A[g];
+ invariant i <= j ==> exists g :: 0 <= g <= j && A[g] <= r;
+ invariant forall p :: 0 <= p < i ==> A[p] <= r;
+ invariant forall q :: j < q < N ==> r <= A[q];
+ // the following two invariants capture (and follow from) the fact that the array is not modified outside the [m:n] range
+ invariant forall p,q :: 0 <= p < m <= q < N ==> A[p] <= A[q];
+ invariant forall p,q :: 0 <= p <= n < q < N ==> A[p] <= A[q];
+ // the following invariant is used to prove progress of the outer loop
+ invariant (i==m && j==n && r==A[f]) || (m<i && j<n);
+ {
+ ghost var firstIteration := i==m && j==n;
+ while (A[i] < r)
+ invariant m <= i <= N && (firstIteration ==> i <= f);
+ invariant exists g :: i <= g < N && r <= A[g];
+ invariant exists g :: 0 <= g <= j && A[g] <= r;
+ invariant forall p :: 0 <= p < i ==> A[p] <= r;
+ decreases j - i;
+ { i := i + 1; }
+
+ while (r < A[j])
+ invariant 0 <= j <= n && (firstIteration ==> f <= j);
+ invariant exists g :: i <= g < N && r <= A[g];
+ invariant exists g :: 0 <= g <= j && A[g] <= r;
+ invariant forall q :: j < q < N ==> r <= A[q];
+ decreases j;
+ { j := j - 1; }
+
+ assert A[j] <= r <= A[i];
+ if (i <= j) {
+ var w := A[i]; A[i] := A[j]; A[j] := w; // swap A[i] and A[j] (which may be referring to the same location)
+ assert A[i] <= r <= A[j];
+ i, j := i + 1, j - 1;
+ }
+ }
+
+ if (f <= j) {
+ n := j;
+ } else if (i <= f) {
+ m := i;
+ } else {
+ break; // Hoare used a goto
+ }
+ }
+}
diff --git a/Test/dafny2/SnapshotableTrees.dfy b/Test/dafny2/SnapshotableTrees.dfy
index 3386b123..f711e758 100644
--- a/Test/dafny2/SnapshotableTrees.dfy
+++ b/Test/dafny2/SnapshotableTrees.dfy
@@ -250,6 +250,7 @@ class Node
0 <= pos < |r.Contents| == |n.Contents| + 1 &&
r.Contents == n.Contents[..pos] + [x] + n.Contents[pos..];
decreases if n == null then {} else n.Repr;
+/* Commented out while performance issues with the prover and going into SMTLib2 mode are being investigated.
{
if (n == null) {
r := new Node.Init(x);
@@ -259,11 +260,12 @@ class Node
assert n.left != null ==> n.data == n.Contents[|n.left.Contents|];
assert n.left == null ==> n.data == n.Contents[0];
left, pos := FunctionalInsert(n.left, x);
+ assert n.left == old(n.left);
if (left == n.left) {
r, pos := n, -1;
} else {
+ assert n.left != null ==> forall i :: 0 <= i < |n.left.Contents| ==> n.Contents[i] < n.data;
assert forall i :: 0 <= i < |left.Contents| ==> left.Contents[i] < n.data;
- assert n.right != null ==> forall i :: 0 <= i < |n.right.Contents| ==> n.data < n.right.Contents[i];
r := new Node.Build(left, n.data, n.right);
}
} else if (n.data < x) {
@@ -285,7 +287,7 @@ class Node
r, pos := n, -1;
}
}
-
+*/
method MutatingInsert(x: int) returns (ghost pos: int)
requires Valid();
modifies Repr;
diff --git a/Test/dafny2/runtest.bat b/Test/dafny2/runtest.bat
index f6f25429..50b4ca18 100644
--- a/Test/dafny2/runtest.bat
+++ b/Test/dafny2/runtest.bat
@@ -5,7 +5,9 @@ set BOOGIEDIR=..\..\Binaries
set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
set CSC=c:/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe
-for %%f in (SnapshotableTrees.dfy TreeBarrier.dfy
+for %%f in (
+ Classics.dfy
+ SnapshotableTrees.dfy TreeBarrier.dfy
COST-verif-comp-2011-1-MaxArray.dfy
COST-verif-comp-2011-2-MaxTree-class.dfy
COST-verif-comp-2011-2-MaxTree-datatype.dfy
diff --git a/Test/datatypes/runtest.bat b/Test/datatypes/runtest.bat
new file mode 100644
index 00000000..e796c905
--- /dev/null
+++ b/Test/datatypes/runtest.bat
@@ -0,0 +1,12 @@
+@echo off
+setlocal
+
+set BOOGIEDIR=..\..\Binaries
+set BPLEXE=%BOOGIEDIR%\Boogie.exe
+
+for %%f in (t1.bpl) do (
+ echo.
+ echo -------------------- %%f --------------------
+ %BPLEXE% %* /typeEncoding:m %%f
+)
+
diff --git a/Test/datatypes/t2.bpl b/Test/datatypes/t2.bpl
new file mode 100644
index 00000000..2bca4e83
--- /dev/null
+++ b/Test/datatypes/t2.bpl
@@ -0,0 +1,54 @@
+
+type {:datatype} DotNetType;
+
+/*\
+ * Subtype Axioms
+\*/
+function $Subtype(DotNetType, DotNetType) : bool;
+// reflexive
+axiom (forall t: DotNetType :: $Subtype(t, t));
+// anti-symmetric
+axiom (forall t0: DotNetType, t1: DotNetType :: { $Subtype(t0, t1), $Subtype(t1, t0) } $Subtype(t0, t1) && $Subtype(t1, t0) ==> t0 == t1);
+// transitive
+axiom (forall t0: DotNetType, t1: DotNetType, t2: DotNetType :: { $Subtype(t0, t1), $Subtype(t1, t2) } $Subtype(t0, t1) && $Subtype(t1, t2) ==> $Subtype(t0, t2));
+
+/*\
+ * Type Declarations
+\*/
+// class System.Object { ... }
+function {:constructor} System.Object() : DotNetType;
+
+// class B : System.Object { ... }
+function {:constructor} B() : DotNetType;
+axiom $Subtype(B(), System.Object());
+
+// class GenericType1<T> : System.Object { ... }
+function {:constructor} GenericType1(T:DotNetType) : DotNetType;
+axiom (forall t : DotNetType :: $Subtype(GenericType1(t), System.Object()));
+
+// class C : GenericType1<object>
+function {:constructor} C() : DotNetType;
+axiom $Subtype(C(), GenericType1(System.Object()));
+
+// class D<U> : GenericType1<U>
+function {:constructor} D(U:DotNetType) : DotNetType;
+axiom (forall u : DotNetType :: $Subtype(D(u), GenericType1(u)));
+
+// class GenericType2<T,U> : System.Object { ... }
+function {:constructor} GenericType2(T:DotNetType, U:DotNetType) : DotNetType;
+axiom (forall t : DotNetType, u : DotNetType :: $Subtype(GenericType2(t,u), System.Object()));
+
+procedure foo(t : DotNetType)
+{
+ assert System.Object() != GenericType1(t);
+ assert System.Object() != B();
+}
+
+procedure bar(t : DotNetType, u : DotNetType)
+ requires t != u;
+{
+ assert System.Object() != GenericType1(t);
+ assert System.Object() != B();
+ assert GenericType1(t) != GenericType1(u);
+}
+
diff --git a/Test/extractloops/Answer b/Test/extractloops/Answer
index 9a6c95a3..954ea799 100644
--- a/Test/extractloops/Answer
+++ b/Test/extractloops/Answer
@@ -64,6 +64,10 @@ Boogie program verifier finished with 1 verified, 0 errors
t3.bpl(38,5): Error BP5001: This assertion might not hold.
Execution trace:
t3.bpl(19,3): anon0
+ t3.bpl(23,3): anon3_LoopHead
+ Inlined call to procedure foo begins
+ t3.bpl(11,5): anon0
+ Inlined call to procedure foo ends
t3.bpl(27,3): anon3_LoopBody
t3.bpl(23,3): anon3_LoopHead
Inlined call to procedure foo begins
diff --git a/Test/inline/Answer b/Test/inline/Answer
index 72ba1170..ae632f79 100644
--- a/Test/inline/Answer
+++ b/Test/inline/Answer
@@ -1448,26 +1448,15 @@ Execution trace:
test5.bpl(34,10): anon0$2
Boogie program verifier finished with 4 verified, 1 error
--------------------- expansion.bpl --------------------
-expansion.bpl(29,14): Error: invalid type for argument 0 in application of foo1: bool (expected: int)
-expansion.bpl(13,16): Error: expansion: {:inline ...} expects either true or false as the argument
-expansion.bpl(14,22): Error: expansion: identifier was not quantified over
-expansion.bpl(15,22): Error: expansion: identifier was not quantified over
-expansion.bpl(16,22): Error: expansion: more variables quantified over, than used in function
-expansion.bpl(18,21): Error: expansion: axiom to be expanded must have form (forall VARS :: f(VARS) == expr(VARS))
-expansion.bpl(19,53): Error: expansion: only identifiers supported as function arguments
-expansion.bpl(33,22): Error: expansion: an identifier was used more than once
-8 type checking errors detected in expansion.bpl
-------------------- expansion3.bpl --------------------
*** detected expansion loop on foo3
*** detected expansion loop on foo3
*** detected expansion loop on foo3
-*** more than one possible expansion for x1
-expansion3.bpl(18,3): Error BP5001: This assertion might not hold.
-Execution trace:
- expansion3.bpl(18,3): anon0
-Boogie program verifier finished with 1 verified, 1 error
+Boogie program verifier finished with 1 verified, 0 errors
+-------------------- expansion4.bpl --------------------
+
+Boogie program verifier finished with 1 verified, 0 errors
-------------------- Elevator.bpl --------------------
Elevator.bpl(17,5): Error BP5005: This loop invariant might not be maintained by the loop.
Execution trace:
diff --git a/Test/inline/expansion.bpl b/Test/inline/expansion.bpl
deleted file mode 100644
index 41acfb44..00000000
--- a/Test/inline/expansion.bpl
+++ /dev/null
@@ -1,33 +0,0 @@
-const q : int;
-const p : bool;
-function foo(x:int, y:bool) returns(bool);
-function foo1(x:int, y:bool) returns(bool);
-function foo2(x:int, y:bool) returns(bool);
-function foo3(x:int, y:bool) returns(bool);
-// OK
-axiom {:inline false} (forall x:int, y:bool :: foo(x,p) <==> x > 10 && y);
-axiom {:inline true} (forall x:int, y:bool :: foo1(x,y) == (x > 10 && y));
-axiom {:inline true} (forall x:int, y:bool :: foo2(x,y) == (q > 10 && y));
-axiom {:inline true} (forall y:bool, x:int :: foo3(x,y) == foo3(x,y));
-// fail
-axiom {:inline 1} (forall x:int, y:bool :: foo(x,y) <==> x > 10 && y);
-axiom {:inline true} (forall x:int, y:bool :: foo(x,p) <==> x > 10 && y);
-axiom {:inline true} (forall y:bool :: foo(q,y) == (q > 10 && y));
-axiom {:inline true} (forall x:int, y:bool, z:int :: foo(x,y) == (q > 10 && y));
-axiom {:inline true} (forall y:bool, x:int :: foo3(x,y) == (q > 10 && y));
-axiom {:inline true} true;
-axiom {:inline true} (forall y:bool, x:int :: foo3(x,true) == (q > 10 && y));
-
-
-procedure baz1()
-{
- assert foo3(1,true);
-}
-
-procedure baz2()
-{
- assert foo1(true,true);
-}
-
-function foo4(x:int, y:int) returns(bool);
-axiom {:inline true} (forall x:int,z:int :: foo4(x,x) == (x > 0));
diff --git a/Test/inline/expansion2.bpl b/Test/inline/expansion2.bpl
index fc14a0eb..b6ed19ed 100644
--- a/Test/inline/expansion2.bpl
+++ b/Test/inline/expansion2.bpl
@@ -1,7 +1,7 @@
-function xxgz(x:int) returns(bool);
-function xxf1(x:int,y:bool) returns(int);
-axiom {:inline true} (forall x:int :: xxgz(x) <==> x > 0);
-axiom {:inline true} (forall x:int, y:bool :: xxf1(x,y) == x+1);
+function {:inline true} xxgz(x:int) returns(bool)
+ { x > 0 }
+function {:inline true} xxf1(x:int,y:bool) returns(int)
+ { x + 1 }
axiom (forall z:int :: z>12 ==> xxgz(z));
axiom (forall y:int, x:bool :: xxf1(y, x) > 1 ==> y > 0);
diff --git a/Test/inline/expansion3.bpl b/Test/inline/expansion3.bpl
index 1fd3d853..2b1f0caa 100644
--- a/Test/inline/expansion3.bpl
+++ b/Test/inline/expansion3.bpl
@@ -1,5 +1,5 @@
-function foo3(x:int, y:bool) returns(bool);
-axiom {:inline true} (forall y:bool, x:int :: foo3(x,y) == foo3(x,y));
+function {:inline true} foo3(x:int, y:bool) returns(bool)
+ { foo3(x,y) }
axiom foo3(1,false);
@@ -9,11 +9,3 @@ procedure baz1()
assume foo3(1,true);
}
-function x1(x:int) returns(bool);
-axiom {:inline true} (forall x:int :: x1(x) <==> x > 0);
-axiom {:inline true} (forall x:int :: x1(x) <==> x >= 1);
-
-procedure bar()
-{
- assert x1(3);
-}
diff --git a/Test/inline/expansion4.bpl b/Test/inline/expansion4.bpl
new file mode 100644
index 00000000..be11a391
--- /dev/null
+++ b/Test/inline/expansion4.bpl
@@ -0,0 +1,9 @@
+function foo(x:int) : int
+ { if x <= 0 then 1 else foo(x - 1) + 2 }
+
+procedure bar()
+{
+ assert foo(0) == 1;
+ assert foo(1) == 3;
+ assert foo(2) == 5;
+}
diff --git a/Test/inline/runtest.bat b/Test/inline/runtest.bat
index f04b84da..f56d55a0 100644
--- a/Test/inline/runtest.bat
+++ b/Test/inline/runtest.bat
@@ -13,7 +13,7 @@ for %%f in (test1.bpl test2.bpl test3.bpl test4.bpl test6.bpl) do (
%BGEXE% %* /inline:spec /print:- /env:0 /printInlined /noinfer %%f
)
-for %%f in (test5.bpl expansion.bpl expansion3.bpl Elevator.bpl) do (
+for %%f in (test5.bpl expansion3.bpl expansion4.bpl Elevator.bpl) do (
echo -------------------- %%f --------------------
%BGEXE% %* %%f
)
diff --git a/Test/stratifiedinline/Answer b/Test/stratifiedinline/Answer
index 290059d6..aee2722e 100644
--- a/Test/stratifiedinline/Answer
+++ b/Test/stratifiedinline/Answer
@@ -2,31 +2,31 @@
bar1.bpl(25,1): Error BP5003: A postcondition might not hold on this return path.
bar1.bpl(21,1): Related location: This is the postcondition that might not hold.
Execution trace:
- bar1.bpl(24,3): anon0
- Inlined call to procedure foo begins
- bar1.bpl(13,5): anon0
- Inlined call to procedure bar begins
- bar1.bpl(7,5): anon0
- Inlined call to procedure bar ends
- Inlined call to procedure bar begins
- bar1.bpl(7,5): anon0
- Inlined call to procedure bar ends
- Inlined call to procedure foo ends
+ bar1.bpl(24,3): anon0
+ Inlined call to procedure foo begins
+ bar1.bpl(13,5): anon0
+ Inlined call to procedure bar begins
+ bar1.bpl(7,5): anon0
+ Inlined call to procedure bar ends
+ Inlined call to procedure bar begins
+ bar1.bpl(7,5): anon0
+ Inlined call to procedure bar ends
+ Inlined call to procedure foo ends
Boogie program verifier finished with 0 verified, 1 error
-----
----- Running regression test bar2.bpl
bar2.bpl(21,3): Error BP5001: This assertion might not hold.
Execution trace:
- bar2.bpl(19,3): anon0
- Inlined call to procedure foo begins
- bar2.bpl(5,3): anon0
- bar2.bpl(6,7): anon3_Then
- Inlined call to procedure foo ends
- Inlined call to procedure foo begins
- bar2.bpl(5,3): anon0
- bar2.bpl(9,7): anon3_Else
- Inlined call to procedure foo ends
+ bar2.bpl(19,3): anon0
+ Inlined call to procedure foo begins
+ bar2.bpl(5,3): anon0
+ bar2.bpl(9,7): anon3_Else
+ Inlined call to procedure foo ends
+ Inlined call to procedure foo begins
+ bar2.bpl(5,3): anon0
+ bar2.bpl(6,7): anon3_Then
+ Inlined call to procedure foo ends
Boogie program verifier finished with 0 verified, 1 error
-----
@@ -34,23 +34,23 @@ Boogie program verifier finished with 0 verified, 1 error
bar3.bpl(41,1): Error BP5003: A postcondition might not hold on this return path.
bar3.bpl(34,1): Related location: This is the postcondition that might not hold.
Execution trace:
- bar3.bpl(38,3): anon0
- Inlined call to procedure foo begins
- bar3.bpl(18,3): anon0
- bar3.bpl(19,7): anon3_Then
- Inlined call to procedure bar begins
- bar3.bpl(7,3): anon0
- bar3.bpl(8,7): anon3_Then
- Inlined call to procedure bar ends
- Inlined call to procedure bar begins
- bar3.bpl(7,3): anon0
- bar3.bpl(8,7): anon3_Then
- Inlined call to procedure bar ends
- Inlined call to procedure foo ends
+ bar3.bpl(38,3): anon0
+ Inlined call to procedure foo begins
+ bar3.bpl(18,3): anon0
+ bar3.bpl(19,7): anon3_Then
+ Inlined call to procedure bar begins
+ bar3.bpl(7,3): anon0
+ bar3.bpl(8,7): anon3_Then
+ Inlined call to procedure bar ends
Inlined call to procedure bar begins
bar3.bpl(7,3): anon0
- bar3.bpl(10,7): anon3_Else
+ bar3.bpl(8,7): anon3_Then
Inlined call to procedure bar ends
+ Inlined call to procedure foo ends
+ Inlined call to procedure bar begins
+ bar3.bpl(7,3): anon0
+ bar3.bpl(10,7): anon3_Else
+ Inlined call to procedure bar ends
Boogie program verifier finished with 0 verified, 1 error
-----
diff --git a/Test/test15/Answer b/Test/test15/Answer
index 11f0e658..4e3886aa 100644
--- a/Test/test15/Answer
+++ b/Test/test15/Answer
@@ -2,56 +2,49 @@
-------------------- NullInModel --------------------
Z3 error model:
partitions:
-*0 -> true
-*1 -> false
-*2 {@true} -> 3:int
-*3 {@false} -> 4:int
+*0 {%lbl%+24 %lbl%+37} -> true
+*1 {%lbl%@47} -> false
+*2 {s null}
+*3 {refType}
*4 {intType}
*5 {boolType}
-*6 {refType}
-*7 {s null}
-*8 -> 0:int
-*9 -> 1:int
-*10 -> 2:int
-*11
+*6 -> 0:int
+*7 -> 1:int
+*8 -> 2:int
+*9
function interpretations:
-$pow2 -> {
- *8 -> *9
- else -> #unspecified
-}
tickleBool -> {
- *1 -> *0
*0 -> *0
+ *1 -> *0
else -> #unspecified
}
-Ctor -> {
- *4 -> *8
- *5 -> *9
- *6 -> *10
+type -> {
+ *2 -> *3
else -> #unspecified
}
-type -> {
- *7 -> *6
+Ctor -> {
+ *4 -> *6
+ *5 -> *7
+ *3 -> *8
else -> #unspecified
}
END_OF_MODEL
.
identifierToPartition:
-@true : *2
-@false : *3
+%lbl%+24 : *0
+%lbl%+37 : *0
+%lbl%@47 : *1
+s : *2
+null : *2
+refType : *3
intType : *4
boolType : *5
-refType : *6
-s : *7
-null : *7
valueToPartition:
True : *0
False : *1
-3 : *2
-4 : *3
-0 : *8
-1 : *9
-2 : *10
+0 : *6
+1 : *7
+2 : *8
End of model.
NullInModel.bpl(2,3): Error BP5001: This assertion might not hold.
Execution trace:
@@ -62,45 +55,38 @@ Boogie program verifier finished with 0 verified, 1 error
-------------------- IntInModel --------------------
Z3 error model:
partitions:
-*0 -> true
-*1 -> false
-*2 {@true} -> 2:int
-*3 {@false} -> 3:int
-*4 {intType}
-*5 {boolType}
-*6 {i} -> 0:int
-*7 -> 1:int
-*8
+*0 {%lbl%+29 %lbl%+23} -> true
+*1 {%lbl%@39} -> false
+*2 {intType}
+*3 {boolType}
+*4 {i} -> 0:int
+*5 -> 1:int
+*6
function interpretations:
-$pow2 -> {
- *6 -> *7
- else -> #unspecified
-}
tickleBool -> {
- *1 -> *0
*0 -> *0
+ *1 -> *0
else -> #unspecified
}
Ctor -> {
- *4 -> *6
- *5 -> *7
+ *2 -> *4
+ *3 -> *5
else -> #unspecified
}
END_OF_MODEL
.
identifierToPartition:
-@true : *2
-@false : *3
-intType : *4
-boolType : *5
-i : *6
+%lbl%+29 : *0
+%lbl%+23 : *0
+%lbl%@39 : *1
+intType : *2
+boolType : *3
+i : *4
valueToPartition:
True : *0
False : *1
-2 : *2
-3 : *3
-0 : *6
-1 : *7
+0 : *4
+1 : *5
End of model.
IntInModel.bpl(2,3): Error BP5001: This assertion might not hold.
Execution trace:
@@ -111,66 +97,59 @@ Boogie program verifier finished with 0 verified, 1 error
-------------------- ModelTest --------------------
Z3 error model:
partitions:
-*0 -> true
-*1 -> false
-*2 {@true} -> 5:int
-*3 {@false} -> 6:int
-*4 {intType}
-*5 {boolType}
+*0 {%lbl%+64 %lbl%+119} -> true
+*1 {%lbl%@182} -> false
+*2 {s}
+*3 {j@2} -> 4:int
+*4 {boolType}
+*5 {intType}
*6 {refType}
-*7 {s}
-*8 {r}
-*9 {i@0} -> 1:int
-*10 {j@0} -> 2:int
-*11 {j@1} -> 3:int
-*12 {j@2} -> 4:int
-*13 -> 0:int
-*14
+*7 {i@0} -> 1:int
+*8 {j@0} -> 2:int
+*9 {j@1} -> 3:int
+*10 {r}
+*11 -> 0:int
+*12
function interpretations:
-$pow2 -> {
- *13 -> *9
- else -> #unspecified
-}
tickleBool -> {
- *1 -> *0
*0 -> *0
+ *1 -> *0
else -> #unspecified
}
-Ctor -> {
- *4 -> *13
- *5 -> *9
- *6 -> *10
+type -> {
+ *2 -> *6
+ *10 -> *6
else -> #unspecified
}
-type -> {
- *7 -> *6
- *8 -> *6
+Ctor -> {
+ *5 -> *11
+ *4 -> *7
+ *6 -> *8
else -> #unspecified
}
END_OF_MODEL
.
identifierToPartition:
-@true : *2
-@false : *3
-intType : *4
-boolType : *5
+%lbl%+64 : *0
+%lbl%+119 : *0
+%lbl%@182 : *1
+s : *2
+j@2 : *3
+boolType : *4
+intType : *5
refType : *6
-s : *7
-r : *8
-i@0 : *9
-j@0 : *10
-j@1 : *11
-j@2 : *12
+i@0 : *7
+j@0 : *8
+j@1 : *9
+r : *10
valueToPartition:
True : *0
False : *1
-5 : *2
-6 : *3
-1 : *9
-2 : *10
-3 : *11
-4 : *12
-0 : *13
+4 : *3
+1 : *7
+2 : *8
+3 : *9
+0 : *11
End of model.
ModelTest.bpl(7,3): Error BP5001: This assertion might not hold.
Execution trace:
@@ -199,86 +178,85 @@ Execution trace:
CaptureState.bpl(16,5): anon4_Then
CaptureState.bpl(24,5): anon3
*** MODEL
-@true -> 6
-@false -> 7
+%lbl%+112 -> true
+%lbl%+116 -> true
+%lbl%+110 -> true
+%lbl%+189 -> true
+%lbl%@334 -> false
+m@3 -> -1
+m@2 -> -1
+this -> *3
intType -> *4
-boolType -> *5
-RefType -> *6
-FieldNameType -> *7
-Heap -> *8
-this -> *9
-F -> *10
-@MV_state_const -> 8
+Heap -> *5
+FieldNameType -> *6
m@0 -> -2
r@0 -> -2
+boolType -> *8
+RefType -> *9
+F -> *10
+@MV_state_const -> 6
x@@4 -> 797
-m@2 -> -1
-m@3 -> -1
y@@1 -> **y@@1
r -> **r
m -> **m
-$pow2 -> {
- 0 -> 1
- else -> *23
-}
tickleBool -> {
- false -> true
true -> true
- else -> *23
-}
-Ctor -> {
- *4 -> 0
- *5 -> 1
- *6 -> 3
- *7 -> 4
- *19 -> 2
- else -> *23
+ false -> true
+ else -> true
}
type -> {
- *8 -> *19
- *9 -> *6
- *10 -> *7
+ *5 -> *13
+ *3 -> *9
+ *10 -> *6
-2 -> *4
- else -> *23
+ else -> *13
}
-MapType0Type -> {
- *6 *7 *4 -> *19
- else -> *23
-}
-MapType0TypeInv2 -> {
- *19 -> *4
- else -> *23
-}
-MapType0TypeInv1 -> {
- *19 -> *7
- else -> *23
-}
-MapType0TypeInv0 -> {
- *19 -> *6
- else -> *23
+Ctor -> {
+ *4 -> 0
+ *8 -> 1
+ *9 -> 3
+ *6 -> 4
+ *13 -> 2
+ else -> 0
}
@MV_state -> {
- 8 0 -> true
- 8 3 -> true
- 8 4 -> true
- 8 5 -> true
- else -> *23
+ 6 0 -> true
+ 6 3 -> true
+ 6 4 -> true
+ 6 5 -> true
+ else -> true
}
[3] -> {
- *8 *9 *10 -> -2
- else -> *23
+ *5 *3 *10 -> -2
+ else -> -2
}
U_2_int -> {
-2 -> -2
- else -> *23
+ else -> -2
+}
+MapType0TypeInv1 -> {
+ *13 -> *6
+ else -> *6
+}
+MapType0Type -> {
+ *9 *6 *4 -> *13
+ else -> *13
+}
+MapType0TypeInv2 -> {
+ *13 -> *4
+ else -> *4
+}
+MapType0TypeInv0 -> {
+ *13 -> *9
+ else -> *9
}
int_2_U -> {
-2 -> -2
- else -> *23
+ else -> -2
}
*** STATE <initial>
- Heap -> *8
- this -> *9
+ Heap -> *5
+ this -> *3
x -> 797
y -> **y@@1
r -> **r
diff --git a/Test/test2/runtest.bat b/Test/test2/runtest.bat
index 3dc7d0c3..8ce2f66e 100644
--- a/Test/test2/runtest.bat
+++ b/Test/test2/runtest.bat
@@ -24,7 +24,7 @@ for %%f in (Arrays.bpl Lambda.bpl TypeEncodingM.bpl ) do (
)
echo -------------------- sk_hack.bpl --------------------
-%BGEXE% %* /noinfer /bv:z sk_hack.bpl
+%BGEXE% %* /noinfer sk_hack.bpl
for %%f in (CallForall.bpl ContractEvaluationOrder.bpl) do (
echo.
diff --git a/Test/textbook/Answer b/Test/textbook/Answer
index 50e96aca..dace3eb3 100644
--- a/Test/textbook/Answer
+++ b/Test/textbook/Answer
@@ -18,3 +18,7 @@ Boogie program verifier finished with 2 verified, 0 errors
------------------------------ McCarthy-91.bpl ---------------------
Boogie program verifier finished with 1 verified, 0 errors
+
+------------------------------ TuringFactorial.bpl ---------------------
+
+Boogie program verifier finished with 1 verified, 0 errors
diff --git a/Test/textbook/TuringFactorial.bpl b/Test/textbook/TuringFactorial.bpl
new file mode 100644
index 00000000..37a3cb46
--- /dev/null
+++ b/Test/textbook/TuringFactorial.bpl
@@ -0,0 +1,33 @@
+// A Boogie version of Turing's additive factorial program, from "Checking a large routine"
+// published in the "Report of a Conference of High Speed Automatic Calculating Machines",
+// pp. 67-69, 1949.
+
+procedure ComputeFactorial(n: int) returns (u: int)
+ requires 1 <= n;
+ ensures u == Factorial(n);
+{
+ var r, v, s: int;
+ r, u := 1, 1;
+TOP: // B
+ assert r <= n;
+ assert u == Factorial(r);
+ v := u;
+ if (n <= r) { return; }
+ s := 1;
+INNER: // E
+ assert s <= r;
+ assert v == Factorial(r) && u == s * Factorial(r);
+ u := u + v;
+ s := s + 1;
+ assert s - 1 <= r;
+ if (s <= r) { goto INNER; }
+ r := r + 1;
+ goto TOP;
+}
+
+function Factorial(int): int;
+axiom Factorial(0) == 1;
+axiom (forall n: int :: {Factorial(n)} 1 <= n ==> Factorial(n) == n * Factorial_Aux(n-1));
+
+function Factorial_Aux(int): int;
+axiom (forall n: int :: {Factorial(n)} Factorial(n) == Factorial_Aux(n));
diff --git a/Test/textbook/runtest.bat b/Test/textbook/runtest.bat
index 265aa071..b747312d 100644
--- a/Test/textbook/runtest.bat
+++ b/Test/textbook/runtest.bat
@@ -6,7 +6,8 @@ set BPLEXE=%BOOGIEDIR%\Boogie.exe
REM ======================
REM ====================== Examples written in Boogie
REM ======================
-for %%f in (Find.bpl DutchFlag.bpl Bubble.bpl DivMod.bpl McCarthy-91.bpl) do (
+for %%f in (Find.bpl DutchFlag.bpl Bubble.bpl DivMod.bpl McCarthy-91.bpl
+ TuringFactorial.bpl) do (
echo.
echo ------------------------------ %%f ---------------------
%BPLEXE% %* %%f
diff --git a/Util/Emacs/dafny-mode.el b/Util/Emacs/dafny-mode.el
index 98006cca..cf603751 100644
--- a/Util/Emacs/dafny-mode.el
+++ b/Util/Emacs/dafny-mode.el
@@ -37,7 +37,7 @@
)) . font-lock-builtin-face)
`(,(dafny-regexp-opt '(
"assert" "assume" "break" "choose" "then" "else" "havoc" "if" "label" "return" "while" "print"
- "old" "forall" "exists" "new" "foreach" "parallel" "in" "this" "fresh" "allocated"
+ "old" "forall" "exists" "new" "parallel" "in" "this" "fresh" "allocated"
"match" "case" "false" "true" "null")) . font-lock-keyword-face)
`(,(dafny-regexp-opt '("array" "array2" "array3" "bool" "nat" "int" "object" "set" "seq")) . font-lock-type-face)
)
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs b/Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs
index 8fc8bf4e..6f9ec810 100644
--- a/Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs
+++ b/Util/VS2010/Dafny/DafnyLanguageService/Grammar.cs
@@ -20,7 +20,7 @@ namespace Demo
"assert", "assume", "new", "this", "object", "refines", "replaces", "by",
"unlimited", "module", "imports",
"if", "then", "else", "while", "invariant",
- "break", "label", "return", "foreach", "parallel", "havoc", "print",
+ "break", "label", "return", "parallel", "havoc", "print",
"returns", "requires", "ensures", "modifies", "reads", "decreases",
"bool", "nat", "int", "false", "true", "null",
"function", "free",
@@ -238,7 +238,6 @@ namespace Demo
| "if" + Condition + Statement + PreferShiftHere() + "else" + Statement
| "while" + Condition + loopSpec.Star() + Statement
| "for" + LParen + expression.Q() + Semi + expression.Q() + Semi + expression.Q() + RParen + Statement
- | "foreach" + LParen + ident + "in" + expression + RParen + Statement
| blockStatement
| expression + Semi
| "break" + Semi
@@ -286,7 +285,6 @@ namespace Demo
| "break"
| "label"
| "return"
- | "foreach"
| "parallel"
| "havoc"
| "print"
diff --git a/Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs b/Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs
index 5e61d2d6..f80acc26 100644
--- a/Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs
+++ b/Util/VS2010/DafnyExtension/DafnyExtension/TokenTagger.cs
@@ -251,7 +251,6 @@ namespace DafnyLanguage
case "exists":
case "false":
case "forall":
- case "foreach":
case "free":
case "fresh":
case "function":
diff --git a/Util/latex/dafny.sty b/Util/latex/dafny.sty
index 809c6fc4..1bbab1b7 100644
--- a/Util/latex/dafny.sty
+++ b/Util/latex/dafny.sty
@@ -13,7 +13,7 @@
% expressions
match,case,false,true,null,old,fresh,allocated,choose,this,
% statements
- assert,assume,print,new,havoc,if,then,else,while,invariant,break,label,return,foreach,parallel,
+ assert,assume,print,new,havoc,if,then,else,while,invariant,break,label,return,parallel,
},
literate=%
{:}{$\colon$}1
diff --git a/Util/vim/syntax/dafny.vim b/Util/vim/syntax/dafny.vim
index 4014e427..2d0aeab3 100644
--- a/Util/vim/syntax/dafny.vim
+++ b/Util/vim/syntax/dafny.vim
@@ -8,7 +8,7 @@ syntax case match
syntax keyword dafnyFunction function method constructor
syntax keyword dafnyTypeDef class datatype
syntax keyword dafnyConditional if then else match case
-syntax keyword dafnyRepeat foreach while parallel
+syntax keyword dafnyRepeat while parallel
syntax keyword dafnyStatement havoc assume assert return new print break label
syntax keyword dafnyKeyword var ghost returns null static this refines replaces by
syntax keyword dafnyType bool nat int seq set object array array2 array3
diff --git a/_admin/Boogie/aste/summary.log b/_admin/Boogie/aste/summary.log
index 71d3896a..e1ff7176 100644
--- a/_admin/Boogie/aste/summary.log
+++ b/_admin/Boogie/aste/summary.log
@@ -1,37 +1,37 @@
-# Aste started: 2011-10-20 07:00:04
+# Aste started: 2011-11-01 07:00:10
# Host id: Boogiebox
# Configuration: boogie.cfg
# Task: aste.tasks.boogie.FullBuild
-# [2011-10-20 07:03:18] SpecSharp revision: 435d3b691ea1
-# [2011-10-20 07:03:18] SscBoogie revision: 435d3b691ea1
-# [2011-10-20 07:04:52] Boogie revision: 77f2ac339c61
-[2011-10-20 07:06:25] C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com SpecSharp.sln /Project "Checkin Tests" /Build
+# [2011-11-01 07:03:36] SpecSharp revision: 979f82b8db6c
+# [2011-11-01 07:03:36] SscBoogie revision: 979f82b8db6c
+# [2011-11-01 07:05:13] Boogie revision: f402d8e0fc1b
+[2011-11-01 07:06:40] C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com SpecSharp.sln /Project "Checkin Tests" /Build
1>corflags : warning CF011: The specified file is strong name signed. Using /Force will invalidate the signature of this image and will require the assembly to be resigned.
warning CF011: The specified file is strong name signed. Using /Force will invalidate the signature of this image and will require the assembly to be resigned.
-[2011-10-20 07:07:35] C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com Boogie.sln /Rebuild Checked
+[2011-11-01 07:08:09] C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com Boogie.sln /Rebuild Checked
D:\Temp\aste\Boogie\Source\Core\AbsyType.cs(823,16): warning CS0659: 'Microsoft.Boogie.BasicType' overrides Object.Equals(object o) but does not override Object.GetHashCode()
D:\Temp\aste\Boogie\Source\Core\AbsyType.cs(2802,16): warning CS0659: 'Microsoft.Boogie.CtorType' overrides Object.Equals(object o) but does not override Object.GetHashCode()
- D:\Temp\aste\Boogie\Source\Core\Absy.cs(713,9): warning CS0162: Unreachable code detected
- D:\Temp\aste\Boogie\Source\Core\Absy.cs(764,49): warning CS0168: The variable 'e' is declared but never used
+ D:\Temp\aste\Boogie\Source\Core\Absy.cs(710,9): warning CS0162: Unreachable code detected
D:\Temp\aste\Boogie\Source\Core\OOLongUtil.cs(109,7): warning CS0162: Unreachable code detected
- D:\Temp\aste\Boogie\Source\Core\Absy.cs(682,7): warning CC1036: Detected call to method 'Graphing.Graph`1<Microsoft.Boogie.Block>.TopologicalSort' without [Pure] in contracts of method 'Microsoft.Boogie.Program.GraphFromImpl(Microsoft.Boogie.Implementation)'.
+ D:\Temp\aste\Boogie\Source\Core\Absy.cs(679,7): warning CC1036: Detected call to method 'Graphing.Graph`1<Microsoft.Boogie.Block>.TopologicalSort' without [Pure] in contracts of method 'Microsoft.Boogie.Program.GraphFromImpl(Microsoft.Boogie.Implementation)'.
+ EXEC : warning CC1079: Type Microsoft.Boogie.Variable implements Microsoft.AbstractInterpretationFramework.IVariable.get_Name by inheriting Microsoft.Boogie.NamedDeclaration.get_Name causing the interface contract to not be checked at runtime. Consider adding a wrapper method.
D:\Temp\aste\Boogie\Source\Core\Parser.cs(111,3): warning CC1032: Method 'Microsoft.Boogie.Parser+BvBounds.Resolve(Microsoft.Boogie.ResolutionContext)' overrides 'Microsoft.Boogie.Absy.Resolve(Microsoft.Boogie.ResolutionContext)', thus cannot add Requires.
D:\Temp\aste\Boogie\Source\Core\Parser.cs(116,5): warning CC1032: Method 'Microsoft.Boogie.Parser+BvBounds.Emit(Microsoft.Boogie.TokenTextWriter,System.Int32,System.Boolean)' overrides 'Microsoft.Boogie.Expr.Emit(Microsoft.Boogie.TokenTextWriter,System.Int32,System.Boolean)', thus cannot add Requires.
D:\Temp\aste\Boogie\Source\Core\Parser.cs(119,65): warning CC1032: Method 'Microsoft.Boogie.Parser+BvBounds.ComputeFreeVariables(Microsoft.Boogie.Set)' overrides 'Microsoft.Boogie.Expr.ComputeFreeVariables(Microsoft.Boogie.Set)', thus cannot add Requires.
- D:\Temp\aste\Boogie\Source\AbsInt\ExprFactories.cs(111,7): warning CS0162: Unreachable code detected
- D:\Temp\aste\Boogie\Source\AbsInt\ExprFactories.cs(290,7): warning CS0162: Unreachable code detected
- D:\Temp\aste\Boogie\Source\AbsInt\ExprFactories.cs(309,7): warning CS0162: Unreachable code detected
+ D:\Temp\aste\Boogie\Source\AbsInt\ExprFactories.cs(247,7): warning CS0162: Unreachable code detected
+ D:\Temp\aste\Boogie\Source\AbsInt\ExprFactories.cs(266,7): warning CS0162: Unreachable code detected
D:\Temp\aste\Boogie\Source\VCGeneration\VC.cs(1695,11): warning CS0162: Unreachable code detected
D:\Temp\aste\Boogie\Source\VCGeneration\VC.cs(1855,11): warning CS0162: Unreachable code detected
+ D:\Temp\aste\Boogie\Source\VCGeneration\Check.cs(161,16): warning CS0219: The variable 'expand' is assigned but its value is never used
D:\Temp\aste\Boogie\Source\VCGeneration\StratifiedVC.cs(849,17): warning CC1032: Method 'VC.StratifiedVCGen+NormalChecker.CheckVC' overrides 'VC.StratifiedVCGen+StratifiedCheckerInterface.CheckVC', thus cannot add Requires.
warning CS0659: 'Microsoft.Boogie.BasicType' overrides Object.Equals(object o) but does not override Object.GetHashCode()
warning CS0659: 'Microsoft.Boogie.CtorType' overrides Object.Equals(object o) but does not override Object.GetHashCode()
warning CS0162: Unreachable code detected
- warning CS0168: The variable 'e' is declared but never used
warning CS0162: Unreachable code detected
warning CC1036: Detected call to method 'Graphing.Graph`1<Microsoft.Boogie.Block>.TopologicalSort' without [Pure] in contracts of method 'Microsoft.Boogie.Program.GraphFromImpl(Microsoft.Boogie.Implementation)'.
+ warning CC1079: Type Microsoft.Boogie.Variable implements Microsoft.AbstractInterpretationFramework.IVariable.get_Name by inheriting Microsoft.Boogie.NamedDeclaration.get_Name causing the interface contract to not be checked at runtime. Consider adding a wrapper method.
warning CC1032: Method 'Microsoft.Boogie.Parser+BvBounds.Resolve(Microsoft.Boogie.ResolutionContext)' overrides 'Microsoft.Boogie.Absy.Resolve(Microsoft.Boogie.ResolutionContext)', thus cannot add Requires.
warning CC1032: Method 'Microsoft.Boogie.Parser+BvBounds.Emit(Microsoft.Boogie.TokenTextWriter,System.Int32,System.Boolean)' overrides 'Microsoft.Boogie.Expr.Emit(Microsoft.Boogie.TokenTextWriter,System.Int32,System.Boolean)', thus cannot add Requires.
warning CC1032: Method 'Microsoft.Boogie.Parser+BvBounds.ComputeFreeVariables(Microsoft.Boogie.Set)' overrides 'Microsoft.Boogie.Expr.ComputeFreeVariables(Microsoft.Boogie.Set)', thus cannot add Requires.
@@ -39,7 +39,7 @@
warning CS0162: Unreachable code detected
warning CS0162: Unreachable code detected
warning CS0162: Unreachable code detected
- warning CS0162: Unreachable code detected
+ warning CS0219: The variable 'expand' is assigned but its value is never used
warning CC1032: Method 'VC.StratifiedVCGen+NormalChecker.CheckVC' overrides 'VC.StratifiedVCGen+StratifiedCheckerInterface.CheckVC', thus cannot add Requires.
-[2011-10-20 07:55:56] 0 out of 31 test(s) in D:\Temp\aste\Boogie\Test\alltests.txt failed
-# [2011-10-20 07:57:01] Released nightly of Boogie
+[2011-11-01 08:02:30] 0 out of 31 test(s) in D:\Temp\aste\Boogie\Test\alltests.txt failed
+# [2011-11-01 08:02:53] Released nightly of Boogie