summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar tabarbe <unknown>2010-07-28 22:20:18 +0000
committerGravatar tabarbe <unknown>2010-07-28 22:20:18 +0000
commita8c8ffb249d39f2e2a29d3e26888e269019d6fe2 (patch)
treecb84bcd131894005141e6b2e4f6e46e4e2d2cd1d
parent1f7016e583f2264340385b480a4507e35133669d (diff)
Boogie: VCGeneration port part 1/3: Replacing old source files with ported version
-rw-r--r--Source/VCGeneration/Check.cs271
-rw-r--r--Source/VCGeneration/ConditionGeneration.cs1239
-rw-r--r--Source/VCGeneration/Context.cs194
-rw-r--r--Source/VCGeneration/DoomCheck.cs381
-rw-r--r--Source/VCGeneration/DoomErrorHandler.cs57
-rw-r--r--Source/VCGeneration/OrderingAxioms.cs288
-rw-r--r--Source/VCGeneration/VC.cs3037
-rw-r--r--Source/VCGeneration/VCDoomed.cs2223
-rw-r--r--Source/VCGeneration/VCGeneration.csproj282
-rw-r--r--Source/VCGeneration/Wlp.cs94
10 files changed, 4603 insertions, 3463 deletions
diff --git a/Source/VCGeneration/Check.cs b/Source/VCGeneration/Check.cs
index 4bd6edea..20f4035b 100644
--- a/Source/VCGeneration/Check.cs
+++ b/Source/VCGeneration/Check.cs
@@ -9,7 +9,7 @@ using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Diagnostics;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Boogie.AbstractInterpretation;
using Microsoft.Boogie.VCExprAST;
using Microsoft.Basetypes;
@@ -24,9 +24,17 @@ namespace Microsoft.Boogie
/// </summary>
public sealed class Checker
{
- private readonly VCExpressionGenerator! gen;
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(gen!=null);
+ Contract.Invariant(thmProver != null);
+ Contract.Invariant(ProverDone != null);
+}
+
+ private readonly VCExpressionGenerator gen;
- private ProverInterface! thmProver;
+ private ProverInterface thmProver;
private CommandLineOptions.BvHandling bitvectors;
private int timeout;
@@ -40,14 +48,14 @@ namespace Microsoft.Boogie
private volatile ProverInterface.ErrorHandler handler;
private volatile bool closed;
- public readonly AutoResetEvent! ProverDone = new AutoResetEvent(false);
+ 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;
- ((!)impl.Proc).CheckBooleanAttribute("forceBvInt", ref force_int);
+ 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);
@@ -61,24 +69,33 @@ namespace Microsoft.Boogie
return !closed && timeout == this.timeout && bitvectors == BvHandlingForImpl(impl);
}
- public VCExpressionGenerator! VCExprGen
+ public VCExpressionGenerator VCExprGen
{
- get { return this.gen; }
+ get {Contract.Ensures(Contract.Result<VCExpressionGenerator>() != null);
+ return this.gen; }
}
- public ProverInterface! TheoremProver
+ public ProverInterface TheoremProver
{
- get { return this.thmProver; }
+ get {Contract.Ensures(Contract.Result<ProverInterface>() != null);
+ return this.thmProver; }
}
/////////////////////////////////////////////////////////////////////////////////
// We share context information for the same program between different Checkers
private struct ContextCacheKey {
- public readonly Program! program;
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(program!=null);
+}
+
+ public readonly Program program;
public readonly CommandLineOptions.BvHandling bitvectors;
- public ContextCacheKey(Program! prog,
+ public ContextCacheKey(Program prog,
CommandLineOptions.BvHandling bitvectors) {
+ Contract.Requires(prog != null);
this.program = prog;
this.bitvectors = bitvectors;
}
@@ -104,12 +121,14 @@ namespace Microsoft.Boogie
/// <summary>
/// Constructor. Initialize a checker with the program and log file.
/// </summary>
- public Checker(VC.ConditionGeneration! vcgen, Program! prog, string/*?*/ logFilePath, bool appendLogFile, Implementation impl, int timeout)
+ 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 = ((!)CommandLineOptions.Clo.TheProverFactory).BlankProverOptions();
+ ProverOptions options = cce.NonNull(CommandLineOptions.Clo.TheProverFactory).BlankProverOptions();
if (logFilePath != null) {
options.LogFilename = logFilePath;
@@ -129,25 +148,27 @@ namespace Microsoft.Boogie
ProverInterface prover;
if (vcgen.CheckerCommonState == null) {
- vcgen.CheckerCommonState = new Dictionary<ContextCacheKey, ProverContext!> ();
+ vcgen.CheckerCommonState = new Dictionary<ContextCacheKey, ProverContext> ();
}
- IDictionary<ContextCacheKey, ProverContext!>! cachedContexts = (IDictionary<ContextCacheKey, ProverContext!>) vcgen.CheckerCommonState;
+ IDictionary<ContextCacheKey, ProverContext>/*!>!*/ cachedContexts = (IDictionary<ContextCacheKey, ProverContext/*!*/>) vcgen.CheckerCommonState;
if (cachedContexts.TryGetValue(key, out ctx)) {
- ctx = (ProverContext!)((!)ctx).Clone();
+ ctx = (ProverContext)cce.NonNull(ctx).Clone();
prover = (ProverInterface)
CommandLineOptions.Clo.TheProverFactory.SpawnProver(options, ctx);
} else {
- ctx = (ProverContext!)CommandLineOptions.Clo.TheProverFactory.NewProverContext(options);
+ ctx = (ProverContext)CommandLineOptions.Clo.TheProverFactory.NewProverContext(options);
// set up the context
- foreach (Declaration! decl in prog.TopLevelDeclarations) {
+ foreach (Declaration decl in prog.TopLevelDeclarations) {
+ Contract.Assert(decl != null);
TypeCtorDecl t = decl as TypeCtorDecl;
if (t != null) {
ctx.DeclareType(t, null);
}
}
- foreach (Declaration! decl in prog.TopLevelDeclarations) {
+ foreach (Declaration decl in prog.TopLevelDeclarations) {
+ Contract.Assert(decl != null);
Constant c = decl as Constant;
if (c != null) {
ctx.DeclareConstant(c, c.Unique, null);
@@ -158,7 +179,8 @@ namespace Microsoft.Boogie
}
}
}
- foreach (Declaration! decl in prog.TopLevelDeclarations) {
+ foreach (Declaration decl in prog.TopLevelDeclarations) {
+ Contract.Assert(decl != null);
bool expand = false;
Axiom ax = decl as Axiom;
decl.CheckBooleanAttribute("inline", ref expand);
@@ -166,7 +188,8 @@ namespace Microsoft.Boogie
ctx.AddAxiom(ax, null);
}
}
- foreach (Declaration! decl in prog.TopLevelDeclarations) {
+ foreach (Declaration decl in prog.TopLevelDeclarations) {
+ Contract.Assert(decl != null);
GlobalVariable v = decl as GlobalVariable;
if (v != null) {
ctx.DeclareGlobalVariable(v, null);
@@ -178,7 +201,7 @@ namespace Microsoft.Boogie
// the context to be cached
prover = (ProverInterface)
CommandLineOptions.Clo.TheProverFactory.SpawnProver(options, ctx);
- cachedContexts.Add(key, (ProverContext!)ctx.Clone());
+ cachedContexts.Add(key, cce.NonNull((ProverContext)ctx.Clone()));
}
this.thmProver = prover;
@@ -201,8 +224,9 @@ namespace Microsoft.Boogie
/// Push a Verification Condition as an Axiom
/// (Required for Doomed Program Point detection)
/// </summary>
- public void PushVCExpr(VCExpr! vc)
+ public void PushVCExpr(VCExpr vc)
{
+ Contract.Requires(vc != null);
//thmProver.Context.AddAxiom(vc);
thmProver.PushVCExpression(vc);
}
@@ -230,7 +254,7 @@ namespace Microsoft.Boogie
private void WaitForOutput(object dummy)
{
try {
- outcome = thmProver.CheckOutcome((!)handler);
+ outcome = thmProver.CheckOutcome(cce.NonNull(handler));
} catch (UnexpectedProverOutputException e) {
outputExn = e;
}
@@ -253,17 +277,20 @@ namespace Microsoft.Boogie
break;
}
- assert busy;
+ Contract.Assert( busy);
hasOutput = true;
proverRunTime = DateTime.Now - proverStart;
ProverDone.Set();
}
- public void BeginCheck(string! descriptiveName, VCExpr! vc, ProverInterface.ErrorHandler! handler)
- requires !IsBusy;
- {
- assert !busy;
+ public void BeginCheck(string descriptiveName, VCExpr vc, ProverInterface.ErrorHandler handler){
+ Contract.Requires(descriptiveName != null);
+ Contract.Requires(vc != null);
+ Contract.Requires(handler != null);
+
+ Contract.Requires( !IsBusy);
+ Contract.Assert( !busy);
busy = true;
hasOutput = false;
outputExn = null;
@@ -276,11 +303,11 @@ namespace Microsoft.Boogie
ThreadPool.QueueUserWorkItem(WaitForOutput);
}
- public ProverInterface.Outcome ReadOutcome()
- throws UnexpectedProverOutputException;
- requires IsBusy;
- requires HasOutput;
- {
+ public ProverInterface.Outcome ReadOutcome(){
+
+ Contract.Requires( IsBusy);
+ Contract.Requires( HasOutput);
+ Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);
hasOutput = false;
busy = false;
@@ -297,13 +324,31 @@ namespace Microsoft.Boogie
// -----------------------------------------------------------------------------------------------
public class ErrorModel {
- public Dictionary<string!, int>! identifierToPartition;
- public List<List<string!>>! partitionToIdentifiers;
- public List<Object>! partitionToValue;
- public Dictionary<object, int>! valueToPartition;
- public Dictionary<string!, List<List<int>>!>! definedFunctions;
+ public Dictionary<string/*!*/, int>/*!*/ identifierToPartition;
+ public List<List<string/*!>>!*/>> partitionToIdentifiers;
+ public List<Object>/*!*/ partitionToValue;
+ public Dictionary<object, int>/*!*/ valueToPartition;
+ public Dictionary<string/*!*/, List<List<int>>/*!*/>/*!*/ definedFunctions;
+
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(cce.NonNullElements(identifierToPartition));
+ Contract.Invariant(partitionToIdentifiers != null);
+ Contract.Invariant(Contract.ForAll(partitionToIdentifiers,i=>cce.NonNullElements(i)));
+ Contract.Invariant(partitionToValue != null);
+ Contract.Invariant(valueToPartition != null);
+ Contract.Invariant(cce.NonNullElements(definedFunctions));
+}
+
- public ErrorModel(Dictionary<string!, int>! identifierToPartition, List<List<string!>>! partitionToIdentifiers, List<Object>! partitionToValue, Dictionary<object, int>! valueToPartition, Dictionary<string!, List<List<int>>!>! definedFunctions) {
+ public ErrorModel(Dictionary<string, int> identifierToPartition, List<List<string>> partitionToIdentifiers, List<Object> partitionToValue, Dictionary<object, int> valueToPartition, Dictionary<string, List<List<int>>> definedFunctions) {
+ Contract.Requires(cce.NonNullElements(identifierToPartition));
+ Contract.Requires(partitionToIdentifiers != null);
+ Contract.Requires(Contract.ForAll(partitionToIdentifiers,i=>cce.NonNullElements(i)));
+ Contract.Requires(partitionToValue != null);
+ Contract.Requires(valueToPartition != null);
+ Contract.Requires(cce.NonNullElements(definedFunctions));
this.identifierToPartition = identifierToPartition;
this.partitionToIdentifiers = partitionToIdentifiers;
this.partitionToValue = partitionToValue;
@@ -311,17 +356,18 @@ namespace Microsoft.Boogie
this.definedFunctions = definedFunctions;
}
- public virtual void Print(TextWriter! writer) { }
+ public virtual void Print(TextWriter writer) {Contract.Requires(writer != null); }
public int LookupPartitionValue(int partition)
{
- BigNum bignum = (BigNum) (!)partitionToValue[partition];
+ BigNum bignum = (BigNum) cce.NonNull(partitionToValue)[partition];
return bignum.ToInt;
}
public int LookupControlFlowFunctionAt(int cfc, int id)
{
- List<List<int>>! tuples = this.definedFunctions["ControlFlow"];
+ List<List<int>> tuples = this.definedFunctions["ControlFlow"];
+ Contract.Assert(tuples != null);
foreach (List<int> tuple in tuples)
{
if (tuple == null) continue;
@@ -329,49 +375,63 @@ namespace Microsoft.Boogie
if (LookupPartitionValue(tuple[0]) == cfc && LookupPartitionValue(tuple[1]) == id)
return LookupPartitionValue(tuple[2]);
}
- assert false;
+ Contract.Assert(false);throw new cce.UnreachableException();
return 0;
}
- private string! LookupSkolemConstant(string! name) {
- foreach (string! functionName in identifierToPartition.Keys)
+ private string LookupSkolemConstant(string name) {
+ Contract.Requires(name != null);
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ foreach (string functionName in identifierToPartition.Keys)
{
+ Contract.Assert(functionName != null);
+
int index = functionName.LastIndexOf("!");
if (index == -1) continue;
- string! newFunctionName = (!)functionName.Remove(index);
+ string newFunctionName = cce.NonNull(functionName.Remove(index));
if (newFunctionName.Equals(name))
return functionName;
}
return "";
}
- private string! LookupSkolemFunction(string! name) {
- foreach (string! functionName in definedFunctions.Keys)
+ private string LookupSkolemFunction(string name) {
+ Contract.Requires(name != null);
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ foreach (string functionName in definedFunctions.Keys)
{
+ Contract.Assert(functionName != null);
int index = functionName.LastIndexOf("!");
if (index == -1) continue;
- string! newFunctionName = (!)functionName.Remove(index);
+ string newFunctionName = cce.NonNull(functionName.Remove(index));
if (newFunctionName.Equals(name))
return functionName;
}
return "";
}
- public int LookupSkolemFunctionAt(string! functionName, List<int>! values)
+ public int LookupSkolemFunctionAt(string functionName, List<int> values)
+
{
- string! actualFunctionName = LookupSkolemFunction(functionName);
+ Contract.Requires(functionName!= null);
+ Contract.Requires(values != null);
+
+ string actualFunctionName = LookupSkolemFunction(functionName);
+ Contract.Assert(actualFunctionName != null);
if (actualFunctionName.Equals(""))
{
// The skolem function is actually a skolem constant
actualFunctionName = LookupSkolemConstant(functionName);
- assert !actualFunctionName.Equals("");
+ Contract.Assert( !actualFunctionName.Equals(""));
return identifierToPartition[actualFunctionName];
}
- List<List<int>>! tuples = this.definedFunctions[actualFunctionName];
- assert tuples.Count > 0;
+ List<List<int>> tuples = this.definedFunctions[actualFunctionName];
+ Contract.Assert( tuples.Count > 0);
// the last tuple is a dummy tuple
for (int n = 0; n < tuples.Count - 1; n++)
{
- List<int>! tuple = (!)tuples[n];
- assert tuple.Count - 1 <= values.Count;
+ List<int> tuple = cce.NonNull(tuples[n]);
+ Contract.Assert( tuple.Count - 1 <= values.Count);
for (int i = 0, j = 0; i < values.Count; i++)
{
if (values[i] == tuple[j]) {
@@ -381,33 +441,38 @@ namespace Microsoft.Boogie
}
}
}
- assert false;
+ Contract.Assert(false);throw new cce.UnreachableException();
return 0;
}
- public List<object!>! PartitionsToValues(List<int>! args)
+ public List<object>/*!>!*/ PartitionsToValues(List<int> args)
{
- List<object!>! vals = new List<object!>();
+ Contract.Requires(args != null);
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<object>>()));
+
+ List<object> vals = new List<object>();
foreach(int i in args)
{
- object! o = (!)partitionToValue[i];
+ object o = cce.NonNull(partitionToValue[i]);
if (o is bool) {
vals.Add(o);
} else if (o is BigNum) {
vals.Add(o);
- } else if (o is List<List<int>!>) {
- List<List<int>!> array = (List<List<int>!>) o;
- List<List<object!>!> arrayVal = new List<List<object!>!>();
- foreach (List<int>! tuple in array) {
- List<object!> tupleVal = new List<object!>();
- foreach (int i in tuple) {
- tupleVal.Add((!)partitionToValue[i]);
+ } else if (o is List<List<int>>) {
+ List<List<int>> array = (List<List<int>>) o;
+ List<List<object>> arrayVal = new List<List<object>>();
+ foreach (List<int> tuple in array) {
+ Contract.Assert(Contract.Result<List<int>>() != null);
+
+ List<object> tupleVal = new List<object>();
+ foreach (int j in tuple) {
+ tupleVal.Add(cce.NonNull(partitionToValue[i]));
}
arrayVal.Add(tupleVal);
}
vals.Add(arrayVal);
} else {
- assert false;
+ Contract.Assert(false);throw new cce.UnreachableException();
}
}
return vals;
@@ -417,20 +482,22 @@ namespace Microsoft.Boogie
public abstract class ProverInterface
{
public enum Outcome { Valid, Invalid, TimeOut, OutOfMemory, Undetermined }
-
public class ErrorHandler
{
- public virtual void OnModel(IList<string!>! labels, ErrorModel errModel)
+ public virtual void OnModel(IList<string>/*!>!*/ labels, ErrorModel errModel)
{
+ Contract.Requires(cce.NonNullElements(labels));
}
- public virtual void OnResourceExceeded(string! message)
+ public virtual void OnResourceExceeded(string message)
{
+ Contract.Requires(message!=null);
}
- public virtual void OnProverWarning(string! message)
- modifies Console.Out.*, Console.Error.*;
+ public virtual void OnProverWarning(string message)
+ //modifies Console.Out.*, Console.Error.*;
{
+ Contract.Requires(message != null);
switch (CommandLineOptions.Clo.PrintProverWarnings) {
case CommandLineOptions.ProverWarnings.None:
break;
@@ -441,25 +508,25 @@ namespace Microsoft.Boogie
Console.Error.WriteLine("Prover warning: " + message);
break;
default:
- assume false; // unexpected case
+ Contract.Assume( false);throw new cce.UnreachableException(); // unexpected case
}
}
- public virtual Absy! Label2Absy(string! label)
+ public virtual Absy Label2Absy(string label)
{
+ Contract.Requires(label != null);
+ Contract.Ensures(Contract.Result<Absy>() != null);
+
throw new System.NotImplementedException();
}
}
-
- public abstract void BeginCheck(string! descriptiveName, VCExpr! vc, ErrorHandler! handler);
+ public abstract void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler);
[NoDefaultContract]
- public abstract Outcome CheckOutcome(ErrorHandler! handler);
- throws UnexpectedProverOutputException;
-
- public virtual void LogComment(string! comment) {
+ public abstract Outcome CheckOutcome(ErrorHandler handler);
+ public virtual void LogComment(string comment) {
+ Contract.Requires(comment != null);
}
-
public virtual void Close() {
}
@@ -468,21 +535,39 @@ namespace Microsoft.Boogie
/// for now it is only implemented by ProcessTheoremProver and still requires some
/// testing
/// </summary>
- public virtual void PushVCExpression(VCExpr! vc) {}
- public virtual string! VCExpressionToString(VCExpr! vc) { return ""; }
- public virtual void Pop()
- throws UnexpectedProverOutputException;
- {}
+ public virtual void PushVCExpression(VCExpr vc) {Contract.Requires(vc != null);}
+ public virtual string VCExpressionToString(VCExpr vc) {Contract.Requires(vc != null);Contract.Ensures(Contract.Result<string>() != null); return ""; }
+ public virtual void Pop()
+ {Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);}
public virtual int NumAxiomsPushed()
{ return 0; }
public virtual int FlushAxiomsToTheoremProver()
- throws UnexpectedProverOutputException;
- { return 0; }
+ { Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);return 0; }
- public abstract ProverContext! Context { get; }
- public abstract VCExpressionGenerator! VCExprGen { get; }
+ public abstract ProverContext Context { get; }
+public abstract VCExpressionGenerator VCExprGen { get; }
}
+ public class ProverInterfaceContracts:ProverInterface{//TODO Contracts class
+ public override ProverContext Context {
+ get {
+ throw new NotImplementedException();
+ }
+ }
+ public override VCExpressionGenerator VCExprGen {
+ get {
+ throw new NotImplementedException();
+ }
+ }
+ public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler){Contract.Requires(descriptiveName != null); Contract.Requires(vc != null);Contract.Requires(handler != null);throw new NotImplementedException();}
+ [NoDefaultContract]
+ public override Outcome CheckOutcome(ErrorHandler handler){
+ Contract.Requires(handler != null);
+ Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);
+ throw new NotImplementedException();}
+ }
+
+
public class ProverException : Exception
{
@@ -490,7 +575,7 @@ namespace Microsoft.Boogie
{
}
}
- public class UnexpectedProverOutputException : ProverException, ICheckedException
+ public class UnexpectedProverOutputException : ProverException, Microsoft.Contracts.ICheckedException
{
public UnexpectedProverOutputException(string s) : base(s)
{
diff --git a/Source/VCGeneration/ConditionGeneration.cs b/Source/VCGeneration/ConditionGeneration.cs
index a2db980d..6b831baa 100644
--- a/Source/VCGeneration/ConditionGeneration.cs
+++ b/Source/VCGeneration/ConditionGeneration.cs
@@ -12,70 +12,90 @@ using System.IO;
using Microsoft.Boogie;
using Graphing;
using AI = Microsoft.AbstractInterpretationFramework;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Basetypes;
using Microsoft.Boogie.VCExprAST;
-namespace Microsoft.Boogie
-{
+namespace Microsoft.Boogie {
public class CalleeCounterexampleInfo {
- public Counterexample! counterexample;
- public List<object!>! args;
-
- public CalleeCounterexampleInfo(Counterexample! cex, List<object!>! x) {
+ public Counterexample counterexample;
+ public List<object>/*!>!*/ args;
+
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(counterexample != null);
+ Contract.Invariant(cce.NonNullElements(args));
+ }
+
+
+ public CalleeCounterexampleInfo(Counterexample cex, List<object/*!>!*/> x) {
+ Contract.Requires(cex != null);
+ Contract.Requires(cce.NonNullElements(x));
counterexample = cex;
args = x;
- }
+ }
}
-
- public abstract class Counterexample
- {
- [Peer] public BlockSeq! Trace;
- [Peer] public List<string!>! relatedInformation;
-
- public Dictionary<Absy!, CalleeCounterexampleInfo!>! calleeCounterexamples;
-
- internal Counterexample(BlockSeq! trace)
- {
+
+ public abstract class Counterexample {
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(Trace != null);
+ Contract.Invariant(cce.NonNullElements(relatedInformation));
+ Contract.Invariant(cce.NonNullElements(calleeCounterexamples));
+ }
+
+ [Peer]
+ public BlockSeq Trace;
+ [Peer]
+ public List<string>/*!>!*/ relatedInformation;
+
+ public Dictionary<Absy, CalleeCounterexampleInfo> calleeCounterexamples;
+
+ internal Counterexample(BlockSeq trace) {
+ Contract.Requires(trace != null);
this.Trace = trace;
- this.relatedInformation = new List<string!>();
- this.calleeCounterexamples = new Dictionary<Absy!, CalleeCounterexampleInfo!>();
+ this.relatedInformation = new List<string>();
+ this.calleeCounterexamples = new Dictionary<Absy, CalleeCounterexampleInfo>();
// base();
}
-
- public void AddCalleeCounterexample(Absy! absy, CalleeCounterexampleInfo! cex)
- {
+
+ public void AddCalleeCounterexample(Absy absy, CalleeCounterexampleInfo cex) {
+ Contract.Requires(absy != null);
+ Contract.Requires(cex != null);
calleeCounterexamples[absy] = cex;
}
-
- public void AddCalleeCounterexample(Dictionary<Absy!, CalleeCounterexampleInfo!>! cs)
- {
- foreach (Absy! absy in cs.Keys)
- {
+
+ public void AddCalleeCounterexample(Dictionary<Absy, CalleeCounterexampleInfo> cs) {
+ Contract.Requires(cce.NonNullElements(cs));
+ foreach (Absy absy in cs.Keys) {
AddCalleeCounterexample(absy, cs[absy]);
}
}
-
- public void Print(int spaces)
- {
- foreach (Block! b in Trace) {
+
+ public void Print(int spaces) {
+ foreach (Block b in Trace) {
+ Contract.Assert(b != null);
if (b.tok == null) {
- Console.WriteLine(" <intermediate block>");
+ Console.WriteLine(" <intermediate block>");
} else {
// for ErrorTrace == 1 restrict the output;
// do not print tokens with -17:-4 as their location because they have been
// introduced in the translation and do not give any useful feedback to the user
if (!(CommandLineOptions.Clo.ErrorTrace == 1 && b.tok.line == -17 && b.tok.col == -4)) {
- for (int i = 0; i < spaces+4; i++) Console.Write(" ");
+ for (int i = 0; i < spaces + 4; i++)
+ Console.Write(" ");
Console.WriteLine("{0}({1},{2}): {3}", b.tok.filename, b.tok.line, b.tok.col, b.Label);
- foreach (Cmd! cmd in b.Cmds) {
+ foreach (Cmd cmd in b.Cmds) {
+ Contract.Assert(cmd != null);
if (calleeCounterexamples.ContainsKey(cmd)) {
- AssumeCmd! assumeCmd = (AssumeCmd!) cmd;
- NAryExpr! naryExpr = (NAryExpr!) assumeCmd.Expr;
- for (int i = 0; i < spaces+4; i++) Console.Write(" ");
+ AssumeCmd assumeCmd = cce.NonNull((AssumeCmd)cmd);
+ NAryExpr naryExpr = (NAryExpr)cce.NonNull(assumeCmd.Expr);
+ for (int i = 0; i < spaces + 4; i++)
+ Console.Write(" ");
Console.WriteLine("Inlined call to procedure {0} begins", naryExpr.Fun.FunctionName);
- calleeCounterexamples[cmd].counterexample.Print(spaces+4);
- for (int i = 0; i < spaces+4; i++) Console.Write(" ");
+ calleeCounterexamples[cmd].counterexample.Print(spaces + 4);
+ for (int i = 0; i < spaces + 4; i++)
+ Console.Write(" ");
Console.WriteLine("Inlined call to procedure {0} ends", naryExpr.Fun.FunctionName);
}
}
@@ -83,44 +103,60 @@ namespace Microsoft.Boogie
}
}
}
-
+
public abstract int GetLocation();
}
- public class CounterexampleComparer : IComparer<Counterexample!>
- {
- public int Compare(Counterexample! c1, Counterexample! c2) {
- if (c1.GetLocation() == c2.GetLocation()) return 0;
- if (c1.GetLocation() > c2.GetLocation()) return 1;
+ public class CounterexampleComparer : IComparer<Counterexample> {
+ public int Compare(Counterexample c1, Counterexample c2) {
+ Contract.Requires(c1 != null);
+ Contract.Requires(c2 != null);
+ if (c1.GetLocation() == c2.GetLocation())
+ return 0;
+ if (c1.GetLocation() > c2.GetLocation())
+ return 1;
return -1;
}
}
-
- public class AssertCounterexample : Counterexample
- {
- [Peer] public AssertCmd! FailingAssert;
-
- public AssertCounterexample(BlockSeq! trace, AssertCmd! failingAssert)
- : base(trace)
- {
+
+ public class AssertCounterexample : Counterexample {
+ [Peer]
+ public AssertCmd FailingAssert;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(FailingAssert != null);
+ }
+
+
+ public AssertCounterexample(BlockSeq trace, AssertCmd failingAssert)
+ : base(trace) {
+ Contract.Requires(trace != null);
+ Contract.Requires(failingAssert != null);
this.FailingAssert = failingAssert;
// base(trace);
}
-
+
public override int GetLocation() {
return FailingAssert.tok.line * 1000 + FailingAssert.tok.col;
}
}
-
- public class CallCounterexample : Counterexample
- {
- public CallCmd! FailingCall;
- public Requires! FailingRequires;
-
- public CallCounterexample(BlockSeq! trace, CallCmd! failingCall, Requires! failingRequires)
- : base(trace)
- requires !failingRequires.Free;
- {
+
+ public class CallCounterexample : Counterexample {
+ public CallCmd FailingCall;
+ public Requires FailingRequires;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(FailingCall != null);
+ Contract.Invariant(FailingRequires != null);
+ }
+
+
+ public CallCounterexample(BlockSeq trace, CallCmd failingCall, Requires failingRequires)
+ : base(trace) {
+ Contract.Requires(!failingRequires.Free);
+ Contract.Requires(trace != null);
+ Contract.Requires(failingCall != null);
+ Contract.Requires(failingRequires != null);
this.FailingCall = failingCall;
this.FailingRequires = failingRequires;
// base(trace);
@@ -130,16 +166,23 @@ namespace Microsoft.Boogie
return FailingCall.tok.line * 1000 + FailingCall.tok.col;
}
}
-
- public class ReturnCounterexample : Counterexample
- {
- public TransferCmd! FailingReturn;
- public Ensures! FailingEnsures;
-
- public ReturnCounterexample(BlockSeq! trace, TransferCmd! failingReturn, Ensures! failingEnsures)
- : base(trace)
- requires !failingEnsures.Free;
- {
+
+ public class ReturnCounterexample : Counterexample {
+ public TransferCmd FailingReturn;
+ public Ensures FailingEnsures;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(FailingEnsures != null);
+ Contract.Invariant(FailingReturn != null);
+ }
+
+
+ public ReturnCounterexample(BlockSeq trace, TransferCmd failingReturn, Ensures failingEnsures)
+ : base(trace) {
+ Contract.Requires(trace != null);
+ Contract.Requires(failingReturn != null);
+ Contract.Requires(failingEnsures != null);
+ Contract.Requires(!failingEnsures.Free);
this.FailingReturn = failingReturn;
this.FailingEnsures = failingEnsures;
// base(trace);
@@ -150,33 +193,31 @@ namespace Microsoft.Boogie
}
}
- public class VerifierCallback
- {
+ public class VerifierCallback {
// reason == null means this is genuine counterexample returned by the prover
// other reason means it's time out/memory out/crash
- public virtual void OnCounterexample(Counterexample! ce, string? reason)
- {
+ public virtual void OnCounterexample(Counterexample ce, string/*?*/ reason) {
+ Contract.Requires(ce != null);
}
// called in case resource is exceeded and we don't have counterexample
- public virtual void OnTimeout(string! reason)
- {
+ public virtual void OnTimeout(string reason) {
+ Contract.Requires(reason != null);
}
- public virtual void OnOutOfMemory(string! reason)
- {
+ public virtual void OnOutOfMemory(string reason) {
+ Contract.Requires(reason != null);
}
- public virtual void OnProgress(string phase, int step, int totalSteps, double progressEstimate)
- {
+ public virtual void OnProgress(string phase, int step, int totalSteps, double progressEstimate) {
}
- public virtual void OnUnreachableCode(Implementation! impl)
- {
+ public virtual void OnUnreachableCode(Implementation impl) {
+ Contract.Requires(impl != null);
}
-
- public virtual void OnWarning(string! msg)
- {
+
+ public virtual void OnWarning(string msg) {
+ Contract.Requires(msg != null);
switch (CommandLineOptions.Clo.PrintProverWarnings) {
case CommandLineOptions.ProverWarnings.None:
break;
@@ -187,7 +228,8 @@ namespace Microsoft.Boogie
Console.Error.WriteLine("Prover warning: " + msg);
break;
default:
- assume false; // unexpected case
+ Contract.Assume(false);
+ throw new cce.UnreachableException(); // unexpected case
}
}
}
@@ -195,40 +237,63 @@ namespace Microsoft.Boogie
////////////////////////////////////////////
-namespace VC
-{
+namespace VC {
using Bpl = Microsoft.Boogie;
- public class VCGenException : Exception
- {
- public VCGenException(string s) : base(s)
- {
+ public class VCGenException : Exception {
+ public VCGenException(string s)
+ : base(s) {
+ }
+ }
+ [ContractClassFor(typeof(ConditionGeneration))]
+ public class ConditionGenerationContracts : ConditionGeneration {
+ public override Outcome VerifyImplementation(Implementation impl, Program program, VerifierCallback callback) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(callback != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
+ throw new NotImplementedException();
+ }
+ public ConditionGenerationContracts(Program p) : base(p) {
}
}
- public abstract class ConditionGeneration
- {
+ [ContractClass(typeof(ConditionGenerationContracts))]
+ public abstract class ConditionGeneration {
protected internal object CheckerCommonState;
- public enum Outcome { Correct, Errors, TimedOut, OutOfMemory, Inconclusive }
-
- protected readonly List<Checker!>! checkers = new List<Checker!>();
+ public enum Outcome {
+ Correct,
+ Errors,
+ TimedOut,
+ OutOfMemory,
+ Inconclusive
+ }
+
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(checkers));
+ Contract.Invariant(cce.NonNullElements(incarnationOriginMap));
+ Contract.Invariant(program != null);
+ }
+
+ protected readonly List<Checker>/*!>!*/ checkers = new List<Checker>();
protected Implementation current_impl = null;
// shared across each implementation; created anew for each implementation
protected Hashtable /*Variable -> int*/ variable2SequenceNumber;
- public Dictionary<Incarnation, Absy!>! incarnationOriginMap = new Dictionary<Incarnation, Absy!>();
+ public Dictionary<Incarnation, Absy>/*!>!*/ incarnationOriginMap = new Dictionary<Incarnation, Absy>();
// used only by FindCheckerFor
- public Program! program;
+ public Program program;
protected string/*?*/ logFilePath;
protected bool appendLogFile;
-
- public ConditionGeneration(Program! p)
- {
+
+ public ConditionGeneration(Program p) {
+ Contract.Requires(p != null);
program = p;
}
-
+
/// <summary>
/// Takes an implementation and constructs a verification condition and sends
/// it to the theorem prover.
@@ -236,10 +301,13 @@ namespace VC
/// each counterexample consisting of an array of labels.
/// </summary>
/// <param name="impl"></param>
- public Outcome VerifyImplementation(Implementation! impl, Program! program, out List<Counterexample!>? errors)
- ensures result == Outcome.Errors ==> errors != null;
- throws UnexpectedProverOutputException;
- {
+ public Outcome VerifyImplementation(Implementation impl, Program program, out List<Counterexample>/*?*/ errors) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(Contract.ForAll(Contract.ValueAtReturn(out errors),i=>i!=null));
+
+ Contract.Ensures(Contract.Result<Outcome>() != Outcome.Errors || errors != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
Helpers.ExtraTraceInformation("Starting implementation verification");
CounterexampleCollector collector = new CounterexampleCollector();
@@ -254,10 +322,12 @@ namespace VC
return outcome;
}
- public Outcome StratifiedVerifyImplementation(Implementation! impl, Program! program, out List<Counterexample!>? errors)
- ensures result == Outcome.Errors ==> errors != null;
- throws UnexpectedProverOutputException;
- {
+ public Outcome StratifiedVerifyImplementation(Implementation impl, Program program, out List<Counterexample>/*?*/ errors) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(Contract.ForAll(Contract.ValueAtReturn(out errors),i=>i!=null));
+ Contract.Ensures(Contract.Result<Outcome>() != Outcome.Errors || errors != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
Helpers.ExtraTraceInformation("Starting implementation verification");
CounterexampleCollector collector = new CounterexampleCollector();
@@ -271,38 +341,46 @@ namespace VC
Helpers.ExtraTraceInformation("Finished implementation verification");
return outcome;
}
+
+ public abstract Outcome VerifyImplementation(Implementation impl, Program program, VerifierCallback callback);
+
+ public virtual Outcome StratifiedVerifyImplementation(Implementation impl, Program program, VerifierCallback callback) {
- public abstract Outcome VerifyImplementation(Implementation! impl, Program! program, VerifierCallback! callback)
- throws UnexpectedProverOutputException;
-
- public virtual Outcome StratifiedVerifyImplementation(Implementation! impl, Program! program, VerifierCallback! callback)
- throws UnexpectedProverOutputException;
- {
- return VerifyImplementation(impl, program, callback);
- }
-
-/////////////////////////////////// Common Methods and Classes //////////////////////////////////////////
-
-#region Methods for injecting pre- and postconditions
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(callback != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
+ return VerifyImplementation(impl, program, callback);
+ }
+
+ /////////////////////////////////// Common Methods and Classes //////////////////////////////////////////
+
+ #region Methods for injecting pre- and postconditions
private static void
- ThreadInBlockExpr(Implementation! impl,
- Block! targetBlock,
- BlockExpr! blockExpr,
+ ThreadInBlockExpr(Implementation impl,
+ Block targetBlock,
+ BlockExpr blockExpr,
bool replaceWithAssert,
- TokenTextWriter debugWriter){
+ TokenTextWriter debugWriter) {
+ Contract.Requires(impl != null);
+ Contract.Requires(blockExpr != null);
+ Contract.Requires(targetBlock != null);
// Go through blockExpr and for all blocks that have a "return e"
// as their transfer command:
// Replace all "return e" with "assert/assume e"
// Change the transfer command to "goto targetBlock"
// Then add all of the blocks in blockExpr to the implementation (at the end)
- foreach (Block! b in blockExpr.Blocks){
+ foreach (Block b in blockExpr.Blocks) {
+ Contract.Assert(b != null);
ReturnExprCmd rec = b.TransferCmd as ReturnExprCmd;
- if (rec != null){ // otherwise it is a goto command
- if (replaceWithAssert){
- Ensures! ens = new Ensures(rec.tok, false, rec.Expr, null);
- Cmd! c = new AssertEnsuresCmd(ens);
+ if (rec != null) { // otherwise it is a goto command
+ if (replaceWithAssert) {
+ Ensures ens = new Ensures(rec.tok, false, rec.Expr, null);
+ Contract.Assert(ens != null);
+ Cmd c = new AssertEnsuresCmd(ens);
+ Contract.Assert(c != null);
b.Cmds.Add(c);
- }else{
+ } else {
b.Cmds.Add(new AssumeCmd(rec.tok, rec.Expr));
}
b.TransferCmd = new GotoCmd(Token.NoToken,
@@ -312,19 +390,21 @@ namespace VC
}
impl.Blocks.Add(b);
}
- if (debugWriter != null){
- blockExpr.Emit(debugWriter, 1,false);
+ if (debugWriter != null) {
+ blockExpr.Emit(debugWriter, 1, false);
}
return;
}
-
- private static void AddAsPrefix(Block! b, CmdSeq! cs){
+
+ private static void AddAsPrefix(Block b, CmdSeq cs) {
+ Contract.Requires(b != null);
+ Contract.Requires(cs != null);
CmdSeq newCommands = new CmdSeq();
newCommands.AddRange(cs);
newCommands.AddRange(b.Cmds);
b.Cmds = newCommands;
}
-
+
/// <summary>
/// Modifies an implementation by prepending it with startCmds and then, as assume
@@ -333,19 +413,21 @@ namespace VC
/// </summary>
/// <param name="impl"></param>
/// <param name="startCmds"></param>
- protected static void InjectPreconditions(Implementation! impl, [Captured] CmdSeq! startCmds)
- requires impl.Proc != null;
- {
+ protected static void InjectPreconditions(Implementation impl, [Captured] CmdSeq startCmds) {
+ Contract.Requires(impl != null);
+ Contract.Requires(startCmds != null);
+ Contract.Requires(impl.Proc != null);
+
TokenTextWriter debugWriter = null;
if (CommandLineOptions.Clo.PrintWithUniqueASTIds) {
debugWriter = new TokenTextWriter("<console>", Console.Out, false);
debugWriter.WriteLine("Effective precondition:");
}
-
+
Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap());
string LabelPrefix = "PreconditionGeneratedEntry";
int k = 0;
-
+
Block origStartBlock = impl.Blocks[0];
Block insertionPoint = new Block(
new Token(-17, -4), LabelPrefix + k, startCmds,
@@ -355,16 +437,19 @@ namespace VC
impl.Blocks.Add(origStartBlock); // and put the previous start block at the end of the list
// (free and checked) requires clauses
- foreach (Requires! req in impl.Proc.Requires)
- // invariant: insertionPoint.TransferCmd is "goto origStartBlock;", but origStartBlock.Predecessors has not yet been updated
+ foreach (Requires req in impl.Proc.Requires)
+ // invariant: insertionPoint.TransferCmd is "goto origStartBlock;", but origStartBlock.Predecessors has not yet been updated
{
+ Contract.Assert(req != null);
Expr e = Substituter.Apply(formalProcImplSubst, req.Condition);
BlockExpr be = e as BlockExpr;
if (be == null) {
// This is the normal case, where the precondition is an ordinary expression
Cmd c = new AssumeCmd(req.tok, e);
insertionPoint.Cmds.Add(c);
- if (debugWriter != null) { c.Emit(debugWriter, 1); }
+ if (debugWriter != null) {
+ c.Emit(debugWriter, 1);
+ }
} else {
// This is a BlockExpr, so append all of its blocks (changing return expressions
// to assume statements), make the insertion-point block goto the head block of the
@@ -377,7 +462,7 @@ namespace VC
// Second, append the BlockExpr blocks to the implementation's blocks
ThreadInBlockExpr(impl, nextIP, be, false, debugWriter);
// Third, make the old insertion-point block goto the entry block of the BlockExpr
- Block beEntry = (!)be.Blocks[0];
+ Block beEntry = cce.NonNull(be.Blocks[0]);
insertionPoint.TransferCmd = new GotoCmd(Token.NoToken, new StringSeq(beEntry.Label), new BlockSeq(beEntry));
beEntry.Predecessors.Add(insertionPoint);
// Fourth, update the insertion point
@@ -385,8 +470,10 @@ namespace VC
}
}
origStartBlock.Predecessors.Add(insertionPoint);
-
- if (debugWriter != null) { debugWriter.WriteLine(); }
+
+ if (debugWriter != null) {
+ debugWriter.WriteLine();
+ }
}
/// <summary>
/// Modifies an implementation by inserting all postconditions
@@ -398,37 +485,44 @@ namespace VC
/// already been constructed for the implementation (and so
/// is already an element of impl.Blocks)
/// </param>
- protected static Block! InjectPostConditions(Implementation! impl, Block! unifiedExitBlock, Hashtable/*TransferCmd->ReturnCmd*/! gotoCmdOrigins)
- requires impl.Proc != null;
- requires unifiedExitBlock.TransferCmd is ReturnCmd;
- ensures result.TransferCmd is ReturnCmd;
- {
+ protected static Block InjectPostConditions(Implementation impl, Block unifiedExitBlock, Hashtable/*TransferCmd->ReturnCmd*/ gotoCmdOrigins) {
+ Contract.Requires(impl != null);
+ Contract.Requires(unifiedExitBlock != null);
+ Contract.Requires(gotoCmdOrigins != null);
+ Contract.Requires(impl.Proc != null);
+ Contract.Requires(unifiedExitBlock.TransferCmd is ReturnCmd);
+ Contract.Ensures(Contract.Result<Block>() != null);
+ Contract.Ensures(Contract.Result<Block>().TransferCmd is ReturnCmd);
+
TokenTextWriter debugWriter = null;
if (CommandLineOptions.Clo.PrintWithUniqueASTIds) {
debugWriter = new TokenTextWriter("<console>", Console.Out, false);
debugWriter.WriteLine("Effective postcondition:");
}
-
+
Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap());
Block insertionPoint = unifiedExitBlock;
string LabelPrefix = "ReallyLastGeneratedExit";
int k = 0;
// (free and checked) ensures clauses
- foreach (Ensures! ens in impl.Proc.Ensures)
- invariant insertionPoint.TransferCmd is ReturnCmd;
- {
+ foreach (Ensures ens in impl.Proc.Ensures) {
+ cce.LoopInvariant(insertionPoint.TransferCmd is ReturnCmd);
+
+ Contract.Assert(ens != null);
if (!ens.Free) { // skip free ensures clauses
Expr e = Substituter.Apply(formalProcImplSubst, ens.Condition);
BlockExpr be = ens.Condition as BlockExpr;
if (be == null) {
// This is the normal case, where the postcondition is an ordinary expression
- Ensures ensCopy = (Ensures!) ens.Clone();
+ Ensures ensCopy = (Ensures)cce.NonNull(ens.Clone());
ensCopy.Condition = e;
AssertEnsuresCmd c = new AssertEnsuresCmd(ensCopy);
c.ErrorDataEnhanced = ensCopy.ErrorDataEnhanced;
insertionPoint.Cmds.Add(c);
- if (debugWriter != null) { c.Emit(debugWriter, 1); }
+ if (debugWriter != null) {
+ c.Emit(debugWriter, 1);
+ }
} else {
// This is a BlockExpr, so append all of its blocks (changing return expressions
// to assert statements), insert a goto to its head block from the current insertion
@@ -441,7 +535,7 @@ namespace VC
// Second, append the BlockExpr blocks to the implementation's blocks
ThreadInBlockExpr(impl, nextIP, be, true, debugWriter);
// Third, make the old insertion-point block goto the entry block of the BlockExpr
- Block beEntry = (!)be.Blocks[0];
+ Block beEntry = cce.NonNull(be.Blocks[0]);
insertionPoint.TransferCmd = new GotoCmd(Token.NoToken, new StringSeq(beEntry.Label), new BlockSeq(beEntry));
beEntry.Predecessors.Add(insertionPoint);
// Fourth, update the insertion point
@@ -449,8 +543,10 @@ namespace VC
}
}
}
-
- if (debugWriter != null) { debugWriter.WriteLine(); }
+
+ if (debugWriter != null) {
+ debugWriter.WriteLine();
+ }
return insertionPoint;
}
@@ -459,30 +555,39 @@ namespace VC
/// Get the pre-condition of an implementation, including the where clauses from the in-parameters.
/// </summary>
/// <param name="impl"></param>
- protected static CmdSeq! GetPre(Implementation! impl)
- requires impl.Proc != null;
- {
+ protected static CmdSeq GetPre(Implementation impl) {
+ Contract.Requires(impl != null);
+ Contract.Requires(impl.Proc != null);
+ Contract.Ensures(Contract.Result<CmdSeq>() != null);
+
+
TokenTextWriter debugWriter = null;
if (CommandLineOptions.Clo.PrintWithUniqueASTIds) {
debugWriter = new TokenTextWriter("<console>", Console.Out, false);
debugWriter.WriteLine("Effective precondition:");
}
-
+
Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap());
- CmdSeq! pre = new CmdSeq();
+ CmdSeq pre = new CmdSeq();
// (free and checked) requires clauses
- foreach (Requires! req in impl.Proc.Requires)
- {
- Expr! e = Substituter.Apply(formalProcImplSubst, req.Condition);
- Cmd! c = new AssumeCmd(req.tok, e);
+ foreach (Requires req in impl.Proc.Requires) {
+ Contract.Assert(req != null);
+ Expr e = Substituter.Apply(formalProcImplSubst, req.Condition);
+ Contract.Assert(e != null);
+ Cmd c = new AssumeCmd(req.tok, e);
+ Contract.Assert(c != null);
pre.Add(c);
- if (debugWriter != null) { c.Emit(debugWriter, 1); }
+ if (debugWriter != null) {
+ c.Emit(debugWriter, 1);
+ }
}
-
- if (debugWriter != null) { debugWriter.WriteLine(); }
-
+
+ if (debugWriter != null) {
+ debugWriter.WriteLine();
+ }
+
return pre;
}
@@ -490,129 +595,159 @@ namespace VC
/// Get the post-condition of an implementation.
/// </summary>
/// <param name="impl"></param>
- protected static CmdSeq! GetPost(Implementation! impl)
- requires impl.Proc != null;
- {
- if (CommandLineOptions.Clo.PrintWithUniqueASTIds) { Console.WriteLine("Effective postcondition:"); }
-
+ protected static CmdSeq GetPost(Implementation impl) {
+
+
+ Contract.Requires(impl != null);
+ Contract.Requires(impl.Proc != null);
+ Contract.Ensures(Contract.Result<CmdSeq>() != null);
+ if (CommandLineOptions.Clo.PrintWithUniqueASTIds) {
+ Console.WriteLine("Effective postcondition:");
+ }
+
// Construct an Expr for the post-condition
- Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap());
- CmdSeq! post = new CmdSeq();
- foreach (Ensures! ens in impl.Proc.Ensures)
- {
+ Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap());
+ CmdSeq post = new CmdSeq();
+ foreach (Ensures ens in impl.Proc.Ensures) {
+ Contract.Assert(ens != null);
if (!ens.Free) {
- Expr! e = Substituter.Apply(formalProcImplSubst, ens.Condition);
- Ensures! ensCopy = (Ensures!) ens.Clone();
+ Expr e = Substituter.Apply(formalProcImplSubst, ens.Condition);
+ Contract.Assert(e != null);
+ Ensures ensCopy = cce.NonNull((Ensures)ens.Clone());
ensCopy.Condition = e;
- Cmd! c = new AssertEnsuresCmd(ensCopy);
- ((AssertEnsuresCmd) c).ErrorDataEnhanced = ensCopy.ErrorDataEnhanced;
+ Cmd c = new AssertEnsuresCmd(ensCopy);
+ ((AssertEnsuresCmd)c).ErrorDataEnhanced = ensCopy.ErrorDataEnhanced;
post.Add(c);
-
- if (CommandLineOptions.Clo.PrintWithUniqueASTIds) { c.Emit(new TokenTextWriter("<console>", Console.Out, false), 1); }
+
+ if (CommandLineOptions.Clo.PrintWithUniqueASTIds) {
+ c.Emit(new TokenTextWriter("<console>", Console.Out, false), 1);
+ }
}
}
- if (CommandLineOptions.Clo.PrintWithUniqueASTIds) { Console.WriteLine(); }
-
+ if (CommandLineOptions.Clo.PrintWithUniqueASTIds) {
+ Console.WriteLine();
+ }
+
return post;
}
-
+
/// <summary>
/// Get the where clauses from the in- and out-parameters as
/// a sequence of assume commands.
/// As a side effect, this method adds these where clauses to the out parameters.
/// </summary>
/// <param name="impl"></param>
- protected static CmdSeq! GetParamWhereClauses(Implementation! impl)
- requires impl.Proc != null;
- {
+ protected static CmdSeq GetParamWhereClauses(Implementation impl) {
+ Contract.Requires(impl != null);
+ Contract.Requires(impl.Proc != null);
+ Contract.Ensures(Contract.Result<CmdSeq>() != null);
TokenTextWriter debugWriter = null;
if (CommandLineOptions.Clo.PrintWithUniqueASTIds) {
debugWriter = new TokenTextWriter("<console>", Console.Out, false);
debugWriter.WriteLine("Effective precondition from where-clauses:");
}
-
+
Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap());
- CmdSeq! whereClauses = new CmdSeq();
+ CmdSeq whereClauses = new CmdSeq();
// where clauses of in-parameters
- foreach (Formal! f in impl.Proc.InParams)
- {
+ foreach (Formal f in impl.Proc.InParams) {
+ Contract.Assert(f != null);
if (f.TypedIdent.WhereExpr != null) {
Expr e = Substituter.Apply(formalProcImplSubst, f.TypedIdent.WhereExpr);
Cmd c = new AssumeCmd(f.tok, e);
whereClauses.Add(c);
-
- if (debugWriter != null) { c.Emit(debugWriter, 1); }
+
+ if (debugWriter != null) {
+ c.Emit(debugWriter, 1);
+ }
}
}
// where clauses of out-parameters
- assert impl.OutParams.Length == impl.Proc.OutParams.Length;
+ Contract.Assert(impl.OutParams.Length == impl.Proc.OutParams.Length);
for (int i = 0; i < impl.OutParams.Length; i++) {
- Variable f = (!)impl.Proc.OutParams[i];
+ Variable f = cce.NonNull(impl.Proc.OutParams[i]);
if (f.TypedIdent.WhereExpr != null) {
Expr e = Substituter.Apply(formalProcImplSubst, f.TypedIdent.WhereExpr);
Cmd c = new AssumeCmd(f.tok, e);
whereClauses.Add(c);
-
- Variable fi = (!)impl.OutParams[i];
- assume fi.TypedIdent.WhereExpr == null;
+
+ Variable fi = cce.NonNull(impl.OutParams[i]);
+ Contract.Assume(fi.TypedIdent.WhereExpr == null);
fi.TypedIdent.WhereExpr = e;
-
- if (debugWriter != null) { c.Emit(debugWriter, 1); }
+
+ if (debugWriter != null) {
+ c.Emit(debugWriter, 1);
+ }
}
}
- if (debugWriter != null) { debugWriter.WriteLine(); }
-
+ if (debugWriter != null) {
+ debugWriter.WriteLine();
+ }
+
return whereClauses;
}
-#endregion
+ #endregion
+
+
+ protected Checker FindCheckerFor(Implementation impl, int timeout) {
+ Contract.Ensures(Contract.Result<Checker>() != null);
-
- protected Checker! FindCheckerFor(Implementation impl, int timeout)
- {
int i = 0;
while (i < checkers.Count) {
if (checkers[i].Closed) {
checkers.RemoveAt(i);
continue;
} else {
- if (!checkers[i].IsBusy && checkers[i].WillingToHandle(impl, timeout)) return checkers[i];
+ if (!checkers[i].IsBusy && checkers[i].WillingToHandle(impl, timeout))
+ return checkers[i];
}
++i;
}
- string? log = logFilePath;
+ string log = logFilePath;
if (log != null && !log.Contains("@PROC@") && checkers.Count > 0)
log = log + "." + checkers.Count;
- Checker! ch = new Checker(this, program, log, appendLogFile, impl, timeout);
+ Checker ch = new Checker(this, program, log, appendLogFile, impl, timeout);
+ Contract.Assert(ch != null);
checkers.Add(ch);
return ch;
}
-
- public void Close() { foreach (Checker! checker in checkers) checker.Close(); }
+ public void Close() {
+ foreach (Checker checker in checkers) {
+ Contract.Assert(checker != null);
+ checker.Close();
+ }
+ }
- protected class CounterexampleCollector : VerifierCallback
- {
- public readonly List<Counterexample!>! examples = new List<Counterexample!>();
- public override void OnCounterexample(Counterexample! ce, string? reason)
- {
+
+ protected class CounterexampleCollector : VerifierCallback {
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(examples));
+ }
+
+ public readonly List<Counterexample>/*!>!*/ examples = new List<Counterexample>();
+ public override void OnCounterexample(Counterexample ce, string/*?*/ reason) {
+ Contract.Requires(ce != null);
examples.Add(ce);
}
- public override void OnUnreachableCode(Implementation! impl)
- {
+ public override void OnUnreachableCode(Implementation impl) {
+ Contract.Requires(impl != null);
System.Console.WriteLine("found unreachable code:");
EmitImpl(impl, false);
// TODO report error about next to last in seq
}
}
-
- protected static void EmitImpl(Implementation! impl, bool printDesugarings) {
+
+ protected static void EmitImpl(Implementation impl, bool printDesugarings) {
+ Contract.Requires(impl != null);
int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured;
CommandLineOptions.Clo.PrintUnstructured = 2; // print only the unstructured program
bool oldPrintDesugaringSetting = CommandLineOptions.Clo.PrintDesugarings;
@@ -623,114 +758,116 @@ namespace VC
}
- protected Block! GenerateUnifiedExit(Implementation! impl, Hashtable! gotoCmdOrigins)
- ensures result.TransferCmd is ReturnCmd;
- {
+ protected Block GenerateUnifiedExit(Implementation impl, Hashtable gotoCmdOrigins) {
+ Contract.Requires(impl != null);
+ Contract.Requires(gotoCmdOrigins != null);
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ Contract.Ensures(Contract.Result<Block>().TransferCmd is ReturnCmd);
Block/*?*/ exitBlock = null;
#region Create a unified exit block, if there's more than one
{
int returnBlocks = 0;
- foreach ( Block b in impl.Blocks )
- {
- if ( b.TransferCmd is ReturnCmd )
- {
+ foreach (Block b in impl.Blocks) {
+ if (b.TransferCmd is ReturnCmd) {
exitBlock = b;
returnBlocks++;
}
}
- if ( returnBlocks > 1 )
- {
+ if (returnBlocks > 1) {
string unifiedExitLabel = "GeneratedUnifiedExit";
- Block! unifiedExit = new Block(new Token(-17, -4),unifiedExitLabel,new CmdSeq(),new ReturnCmd(Token.NoToken));
-
- foreach ( Block b in impl.Blocks )
- {
- if ( b.TransferCmd is ReturnCmd )
- {
+ Block unifiedExit = new Block(new Token(-17, -4), unifiedExitLabel, new CmdSeq(), new ReturnCmd(Token.NoToken));
+ Contract.Assert(unifiedExit != null);
+ foreach (Block b in impl.Blocks) {
+ if (b.TransferCmd is ReturnCmd) {
StringSeq labels = new StringSeq();
labels.Add(unifiedExitLabel);
BlockSeq bs = new BlockSeq();
bs.Add(unifiedExit);
- GotoCmd go = new GotoCmd(Token.NoToken,labels,bs);
+ GotoCmd go = new GotoCmd(Token.NoToken, labels, bs);
gotoCmdOrigins[go] = b.TransferCmd;
b.TransferCmd = go;
unifiedExit.Predecessors.Add(b);
}
}
-
+
exitBlock = unifiedExit;
impl.Blocks.Add(unifiedExit);
}
- assert exitBlock != null;
+ Contract.Assert(exitBlock != null);
}
return exitBlock;
- #endregion
+ #endregion
}
/// <summary>
/// Helperfunction to restore the predecessor relations after loop unrolling
/// </summary>
- protected void ComputePredecessors(List<Block!>! blocks)
- {
- #region Compute and store the Predecessor Relation on the blocks
- // This code just here to try things out.
- // Compute the predecessor relation for each block
- // Store it in the Predecessors field within each block
- foreach (Block b in blocks)
- {
- GotoCmd gtc = b.TransferCmd as GotoCmd;
- if (gtc != null)
- {
- assume gtc.labelTargets != null;
- foreach (Block! dest in gtc.labelTargets)
- {
- dest.Predecessors.Add(b);
- }
- }
- }
- #endregion Compute and store the Predecessor Relation on the blocks
- }
-
- protected static void ResetPredecessors(List<Block!>! blocks)
- {
- foreach (Block! b in blocks) {
+ protected void ComputePredecessors(List<Block>/*!>!*/ blocks) {
+ Contract.Requires(cce.NonNullElements(blocks));
+ #region Compute and store the Predecessor Relation on the blocks
+ // This code just here to try things out.
+ // Compute the predecessor relation for each block
+ // Store it in the Predecessors field within each block
+ foreach (Block b in blocks) {
+ GotoCmd gtc = b.TransferCmd as GotoCmd;
+ if (gtc != null) {
+ Contract.Assume(gtc.labelTargets != null);
+ foreach (Block dest in gtc.labelTargets) {
+ Contract.Assert(dest != null);
+ dest.Predecessors.Add(b);
+ }
+ }
+ }
+ #endregion Compute and store the Predecessor Relation on the blocks
+ }
+
+ protected static void ResetPredecessors(List<Block/*!>!*/> blocks) {
+ Contract.Requires(blocks != null);
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
b.Predecessors = new BlockSeq();
}
- foreach (Block! b in blocks) {
- foreach (Block! ch in Exits(b)) {
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
+ foreach (Block ch in Exits(b)) {
+ Contract.Assert(ch != null);
ch.Predecessors.Add(b);
}
}
}
- protected static IEnumerable! Exits(Block! b)
- {
+ protected static IEnumerable Exits(Block b) {
+ Contract.Requires(b != null);
GotoCmd g = b.TransferCmd as GotoCmd;
if (g != null) {
- return (!)g.labelTargets;
+ return cce.NonNull(g.labelTargets);
}
- return new List<Block!>();
+ return new List<Block>();
}
- protected Variable! CreateIncarnation(Variable! x, Absy a)
- requires this.variable2SequenceNumber != null;
- requires this.current_impl != null;
- requires a is Block || a is AssignCmd || a is HavocCmd;
- {
+ protected Variable CreateIncarnation(Variable x, Absy a) {
+ Contract.Requires(this.variable2SequenceNumber != null);
+ Contract.Requires(this.current_impl != null);
+ Contract.Requires(a is Block || a is AssignCmd || a is HavocCmd);
+
+ Contract.Requires(x != null);
+ Contract.Ensures(Contract.Result<Variable>() != null);
+
int currentIncarnationNumber =
- variable2SequenceNumber.ContainsKey(x)
+ variable2SequenceNumber.ContainsKey(x)
?
- (int) ((!)variable2SequenceNumber[x])
+ (int)cce.NonNull(variable2SequenceNumber[x])
:
-1;
- Variable v = new Incarnation(x,currentIncarnationNumber + 1);
+ Variable v = new Incarnation(x, currentIncarnationNumber + 1);
variable2SequenceNumber[x] = currentIncarnationNumber + 1;
- assert current_impl != null; // otherwise, the field current_impl wasn't set
+ Contract.Assert(current_impl != null); // otherwise, the field current_impl wasn't set
current_impl.LocVars.Add(v);
- incarnationOriginMap.Add((Incarnation) v, a);
+ incarnationOriginMap.Add((Incarnation)v, a);
return v;
}
-
+
/// <summary>
/// Compute the incarnation map at the beginning of block "b" from the incarnation blocks of the
/// predecessors of "b".
@@ -746,52 +883,49 @@ namespace VC
/// <param name="b"></param>
/// <param name="block2Incarnation">Gives incarnation maps for b's predecessors.</param>
/// <returns></returns>
- protected Hashtable! /*Variable -> Expr*/ ComputeIncarnationMap(Block! b, Hashtable! /*Variable -> Expr*/ block2Incarnation)
- {
- if (b.Predecessors.Length == 0)
- {
+ protected Hashtable /*Variable -> Expr*/ ComputeIncarnationMap(Block b, Hashtable /*Variable -> Expr*/ block2Incarnation) {
+ Contract.Requires(b != null);
+ Contract.Requires(block2Incarnation != null);
+ Contract.Ensures(Contract.Result<Hashtable>() != null);
+
+ if (b.Predecessors.Length == 0) {
return new Hashtable();
}
Hashtable /*Variable -> Expr*/ incarnationMap = null;
Set /*Variable*/ fixUps = new Set /*Variable*/ ();
- foreach (Block! pred in b.Predecessors)
- {
- assert block2Incarnation.Contains(pred); // otherwise, Passive Transformation found a block whose predecessors have not been processed yet
- Hashtable /*Variable -> Expr*/ predMap = (Hashtable! /*Variable -> Expr*/) block2Incarnation[pred];
- if (incarnationMap == null)
- {
+ foreach (Block pred in b.Predecessors) {
+ Contract.Assert(pred != null);
+ Contract.Assert(block2Incarnation.Contains(pred)); // otherwise, Passive Transformation found a block whose predecessors have not been processed yet
+ Hashtable /*Variable -> Expr*/ predMap = (Hashtable /*Variable -> Expr*/)block2Incarnation[pred];
+ Contract.Assert(predMap != null);
+ if (incarnationMap == null) {
incarnationMap = (Hashtable /*Variable -> Expr*/)predMap.Clone();
continue;
}
ArrayList /*Variable*/ conflicts = new ArrayList /*Variable*/ ();
- foreach (Variable! v in incarnationMap.Keys)
- {
- if (!predMap.Contains(v))
- {
+ foreach (Variable v in incarnationMap.Keys) {
+ Contract.Assert(v != null);
+ if (!predMap.Contains(v)) {
// conflict!!
conflicts.Add(v);
fixUps.Add(v);
}
}
// Now that we're done with enumeration, we'll do all the removes
- foreach (Variable! v in conflicts)
- {
+ foreach (Variable v in conflicts) {
+ Contract.Assert(v != null);
incarnationMap.Remove(v);
}
- foreach (Variable! v in predMap.Keys)
- {
- if (!incarnationMap.Contains(v))
- {
+ foreach (Variable v in predMap.Keys) {
+ Contract.Assert(v != null);
+ if (!incarnationMap.Contains(v)) {
// v was not in the domain of the predecessors seen so far, so it needs to be fixed up
fixUps.Add(v);
- }
- else
- {
+ } else {
// v in incarnationMap ==> all pred blocks (up to now) all agree on its incarnation
- if (predMap[v] != incarnationMap[v])
- {
+ if (predMap[v] != incarnationMap[v]) {
// conflict!!
incarnationMap.Remove(v);
fixUps.Add(v);
@@ -801,28 +935,26 @@ namespace VC
}
#region Second, for all variables in the fixups list, introduce a new incarnation and push it back into the preds.
- foreach (Variable! v in fixUps)
- {
- if (!b.IsLive(v)) continue;
+ foreach (Variable v in fixUps) {
+ Contract.Assert(v != null);
+ if (!b.IsLive(v))
+ continue;
Variable v_prime = CreateIncarnation(v, b);
IdentifierExpr ie = new IdentifierExpr(v_prime.tok, v_prime);
- assert incarnationMap != null;
+ Contract.Assert(incarnationMap != null);
incarnationMap[v] = ie;
- foreach (Block! pred in b.Predecessors )
- {
+ foreach (Block pred in b.Predecessors) {
+ Contract.Assert(pred != null);
#region Create an assume command equating v_prime with its last incarnation in pred
#region Create an identifier expression for the last incarnation in pred
- Hashtable /*Variable -> Expr*/ predMap = (Hashtable! /*Variable -> Expr*/) block2Incarnation[pred];
+ Hashtable /*Variable -> Expr*/ predMap = (Hashtable /*Variable -> Expr*/)cce.NonNull(block2Incarnation[pred]);
Expr pred_incarnation_exp;
- Expr o = (Expr) predMap[v];
- if (o == null)
- {
+ Expr o = (Expr)predMap[v];
+ if (o == null) {
Variable predIncarnation = v;
IdentifierExpr ie2 = new IdentifierExpr(predIncarnation.tok, predIncarnation);
pred_incarnation_exp = ie2;
- }
- else
- {
+ } else {
pred_incarnation_exp = o;
}
#endregion
@@ -835,7 +967,7 @@ namespace VC
v_prime_exp,
pred_incarnation_exp
);
- AssumeCmd ac = new AssumeCmd(v.tok,e);
+ AssumeCmd ac = new AssumeCmd(v.tok, e);
pred.Cmds.Add(ac);
#endregion
#endregion
@@ -843,272 +975,287 @@ namespace VC
}
#endregion
- assert incarnationMap != null;
+ Contract.Assert(incarnationMap != null);
return incarnationMap;
}
Hashtable preHavocIncarnationMap = null; // null = the previous command was not an HashCmd. Otherwise, a *copy* of the map before the havoc statement
- protected void TurnIntoPassiveBlock(Block! b, Hashtable! /*Variable -> Expr*/ incarnationMap, Substitution! oldFrameSubst)
- {
+ protected void TurnIntoPassiveBlock(Block b, Hashtable /*Variable -> Expr*/ incarnationMap, Substitution oldFrameSubst) {
+ Contract.Requires(b != null);
+ Contract.Requires(incarnationMap != null);
+ Contract.Requires(oldFrameSubst != null);
#region Walk forward over the commands in this block and convert them to passive commands
CmdSeq passiveCmds = new CmdSeq();
- foreach (Cmd! c in b.Cmds)
- { // walk forward over the commands because the map gets modified in a forward direction
- TurnIntoPassiveCmd(c, incarnationMap, oldFrameSubst, passiveCmds);
+ foreach (Cmd c in b.Cmds) {
+ Contract.Assert(b != null); // walk forward over the commands because the map gets modified in a forward direction
+ TurnIntoPassiveCmd(c, incarnationMap, oldFrameSubst, passiveCmds);
}
b.Cmds = passiveCmds;
#endregion
}
- protected Hashtable /*Variable -> Expr*/ Convert2PassiveCmd(Implementation! impl)
- {
+ protected Hashtable /*Variable -> Expr*/ Convert2PassiveCmd(Implementation impl) {
+ Contract.Requires(impl != null);
#region Convert to Passive Commands
#region Topological sort -- need to process in a linearization of the partial order
Graph<Block> dag = new Graph<Block>();
- dag.AddSource((!)impl.Blocks[0]); // there is always at least one node in the graph
- foreach (Block b in impl.Blocks)
- {
+ dag.AddSource(cce.NonNull(impl.Blocks[0])); // there is always at least one node in the graph
+ foreach (Block b in impl.Blocks) {
GotoCmd gtc = b.TransferCmd as GotoCmd;
- if (gtc != null)
- {
- assume gtc.labelTargets != null;
- foreach (Block! dest in gtc.labelTargets)
- {
- dag.AddEdge(b,dest);
+ if (gtc != null) {
+ Contract.Assume(gtc.labelTargets != null);
+ foreach (Block dest in gtc.labelTargets) {
+ Contract.Assert(dest != null);
+ dag.AddEdge(b, dest);
}
}
}
- IEnumerable! sortedNodes = dag.TopologicalSort();
+ IEnumerable sortedNodes = dag.TopologicalSort();
+ Contract.Assert(sortedNodes != null);
// assume sortedNodes != null;
#endregion
-
+
// Create substitution for old expressions
Hashtable/*Variable!->Expr!*/ oldFrameMap = new Hashtable();
- assume impl.Proc != null;
- foreach (IdentifierExpr! ie in impl.Proc.Modifies) {
- if (!oldFrameMap.Contains((!)ie.Decl))
+ Contract.Assume(impl.Proc != null);
+ foreach (IdentifierExpr ie in impl.Proc.Modifies) {
+ Contract.Assert(ie != null);
+ if (!oldFrameMap.Contains(cce.NonNull(ie.Decl)))
oldFrameMap.Add(ie.Decl, ie);
}
Substitution oldFrameSubst = Substituter.SubstitutionFromHashtable(oldFrameMap);
-
+
// Now we can process the nodes in an order so that we're guaranteed to have
// processed all of a node's predecessors before we process the node.
Hashtable /*Block -> IncarnationMap*/ block2Incarnation = new Hashtable/*Block -> IncarnationMap*/();
Block exitBlock = null;
- foreach (Block! b in sortedNodes )
- {
- assert !block2Incarnation.Contains(b);
+ foreach (Block b in sortedNodes) {
+ Contract.Assert(b != null);
+ Contract.Assert(!block2Incarnation.Contains(b));
Hashtable /*Variable -> Expr*/ incarnationMap = ComputeIncarnationMap(b, block2Incarnation);
-
+
#region Each block's map needs to be available to successor blocks
- block2Incarnation.Add(b,incarnationMap);
+ block2Incarnation.Add(b, incarnationMap);
#endregion Each block's map needs to be available to successor blocks
TurnIntoPassiveBlock(b, incarnationMap, oldFrameSubst);
exitBlock = b;
}
-
+
// Verify that exitBlock is indeed the unique exit block
- assert exitBlock != null;
- assert exitBlock.TransferCmd is ReturnCmd;
-
+ Contract.Assert(exitBlock != null);
+ Contract.Assert(exitBlock.TransferCmd is ReturnCmd);
+
// We no longer need the where clauses on the out parameters, so we remove them to restore the situation from before VC generation
- foreach (Formal! f in impl.OutParams) {
+ foreach (Formal f in impl.OutParams) {
+ Contract.Assert(f != null);
f.TypedIdent.WhereExpr = null;
}
#endregion Convert to Passive Commands
#region Debug Tracing
- if (CommandLineOptions.Clo.TraceVerify)
- {
+ if (CommandLineOptions.Clo.TraceVerify) {
Console.WriteLine("after conversion to passive commands");
EmitImpl(impl, true);
}
- #endregion
-
- return (Hashtable) block2Incarnation[exitBlock];
+ #endregion
+
+ return (Hashtable)block2Incarnation[exitBlock];
}
-
+
/// <summary>
/// Turn a command into a passive command, and it remembers the previous step, to see if it is a havoc or not. In the case, it remebers the incarnation map BEFORE the havoc
/// </summary>
- protected void TurnIntoPassiveCmd(Cmd! c, Hashtable /*Variable -> Expr*/! incarnationMap, Substitution! oldFrameSubst, CmdSeq! passiveCmds)
- {
- Substitution incarnationSubst = Substituter.SubstitutionFromHashtable(incarnationMap);
- #region assert/assume P |--> assert/assume P[x := in(x)], out := in
- if ( c is PredicateCmd )
- {
- assert c is AssertCmd || c is AssumeCmd; // otherwise, unexpected PredicateCmd type
-
- PredicateCmd! pc = (PredicateCmd) c.Clone();
-
- Expr! copy = Substituter.ApplyReplacingOldExprs(incarnationSubst, oldFrameSubst, pc.Expr);
- if (pc is AssertCmd) {
- ((AssertCmd) pc).OrigExpr = pc.Expr;
- assert ((AssertCmd) pc).IncarnationMap == null;
- ((AssertCmd) pc).IncarnationMap = (Hashtable /*Variable -> Expr*/!) incarnationMap.Clone();
- }
- pc.Expr = copy;
- passiveCmds.Add(pc);
+ protected void TurnIntoPassiveCmd(Cmd c, Hashtable /*Variable -> Expr*/ incarnationMap, Substitution oldFrameSubst, CmdSeq passiveCmds) {
+ Contract.Requires(c != null);
+ Contract.Requires(incarnationMap != null);
+ Contract.Requires(oldFrameSubst != null);
+ Contract.Requires(passiveCmds != null);
+ Substitution incarnationSubst = Substituter.SubstitutionFromHashtable(incarnationMap);
+ #region assert/assume P |--> assert/assume P[x := in(x)], out := in
+ if (c is PredicateCmd) {
+ Contract.Assert(c is AssertCmd || c is AssumeCmd); // otherwise, unexpected PredicateCmd type
+
+ PredicateCmd pc = (PredicateCmd)c.Clone();
+ Contract.Assert(pc != null);
+
+ Expr copy = Substituter.ApplyReplacingOldExprs(incarnationSubst, oldFrameSubst, pc.Expr);
+ Contract.Assert(copy != null);
+ if (pc is AssertCmd) {
+ ((AssertCmd)pc).OrigExpr = pc.Expr;
+ Contract.Assert(((AssertCmd)pc).IncarnationMap == null);
+ ((AssertCmd)pc).IncarnationMap = (Hashtable /*Variable -> Expr*/)cce.NonNull(incarnationMap.Clone());
}
- #endregion
- #region x1 := E1, x2 := E2, ... |--> assume x1' = E1[in] & x2' = E2[in], out := in( x |-> x' ) [except as noted below]
- else if ( c is AssignCmd )
- {
- AssignCmd! assign = ((AssignCmd)c).AsSimpleAssignCmd; // first remove map assignments
- #region Substitute all variables in E with the current map
- List<Expr!> copies = new List<Expr!> ();
- foreach (Expr! e in assign.Rhss)
- copies.Add(Substituter.ApplyReplacingOldExprs(incarnationSubst,
- oldFrameSubst,
- e));
- #endregion
-
- List<Expr!>! assumptions = new List<Expr!> ();
- // it might be too slow to create a new dictionary each time ...
- IDictionary<Variable!, Expr!>! newIncarnationMappings =
- new Dictionary<Variable!, Expr!> ();
-
- for (int i = 0; i < assign.Lhss.Count; ++i) {
- IdentifierExpr! lhsIdExpr =
- ((SimpleAssignLhs!)assign.Lhss[i]).AssignedVariable;
- Variable! lhs = (!)lhsIdExpr.Decl;
- Expr! rhs = assign.Rhss[i];
-
- // don't create incarnations for assignments of literals or single variables.
- if (rhs is LiteralExpr) {
- incarnationMap[lhs] = rhs;
- } else if (rhs is IdentifierExpr) {
- IdentifierExpr! ie = (IdentifierExpr) rhs;
- if ( incarnationMap.ContainsKey((!)ie.Decl) )
- newIncarnationMappings[lhs] = (Expr!)incarnationMap[ie.Decl];
- else
- newIncarnationMappings[lhs] = ie;
+ pc.Expr = copy;
+ passiveCmds.Add(pc);
+ }
+ #endregion
+ #region x1 := E1, x2 := E2, ... |--> assume x1' = E1[in] & x2' = E2[in], out := in( x |-> x' ) [except as noted below]
+ else if (c is AssignCmd) {
+ AssignCmd assign = ((AssignCmd)c).AsSimpleAssignCmd; // first remove map assignments
+ Contract.Assert(assign != null);
+ #region Substitute all variables in E with the current map
+ List<Expr> copies = new List<Expr>();
+ foreach (Expr e in assign.Rhss) {
+ Contract.Assert(e != null);
+ copies.Add(Substituter.ApplyReplacingOldExprs(incarnationSubst,
+ oldFrameSubst,
+ e));
+ }
+ #endregion
+
+ List<Expr/*!>!*/> assumptions = new List<Expr>();
+ // it might be too slow to create a new dictionary each time ...
+ IDictionary<Variable, Expr> newIncarnationMappings =
+ new Dictionary<Variable, Expr>();
+
+ for (int i = 0; i < assign.Lhss.Count; ++i) {
+ IdentifierExpr lhsIdExpr =
+ cce.NonNull((SimpleAssignLhs)assign.Lhss[i]).AssignedVariable;
+ Variable lhs = cce.NonNull(lhsIdExpr.Decl);
+ Contract.Assert(lhs != null);
+ Expr rhs = assign.Rhss[i];
+ Contract.Assert(rhs != null);
+
+ // don't create incarnations for assignments of literals or single variables.
+ if (rhs is LiteralExpr) {
+ incarnationMap[lhs] = rhs;
+ } else if (rhs is IdentifierExpr) {
+ IdentifierExpr ie = (IdentifierExpr)rhs;
+ if (incarnationMap.ContainsKey(cce.NonNull(ie.Decl)))
+ newIncarnationMappings[lhs] = cce.NonNull((Expr)incarnationMap[ie.Decl]);
+ else
+ newIncarnationMappings[lhs] = ie;
+ } else {
+ IdentifierExpr x_prime_exp = null;
+ #region Make a new incarnation, x', for variable x, but only if x is *not* already an incarnation
+ if (lhs is Incarnation) {
+ // incarnations are already written only once, no need to make an incarnation of an incarnation
+ x_prime_exp = lhsIdExpr;
} else {
- IdentifierExpr x_prime_exp = null;
- #region Make a new incarnation, x', for variable x, but only if x is *not* already an incarnation
- if ( lhs is Incarnation ) {
- // incarnations are already written only once, no need to make an incarnation of an incarnation
- x_prime_exp = lhsIdExpr;
- }
- else
- {
- Variable v = CreateIncarnation(lhs, c);
- x_prime_exp = new IdentifierExpr(lhsIdExpr.tok, v);
- newIncarnationMappings[lhs] = x_prime_exp;
- }
- #endregion
- #region Create an assume command with the new variable
- assumptions.Add(Expr.Eq(x_prime_exp, copies[i]));
- #endregion
+ Variable v = CreateIncarnation(lhs, c);
+ x_prime_exp = new IdentifierExpr(lhsIdExpr.tok, v);
+ newIncarnationMappings[lhs] = x_prime_exp;
}
+ #endregion
+ #region Create an assume command with the new variable
+ assumptions.Add(Expr.Eq(x_prime_exp, copies[i]));
+ #endregion
}
+ }
+
+ foreach (KeyValuePair<Variable, Expr> pair in newIncarnationMappings) {
+ Contract.Assert(pair.Key != null && pair.Value != null);
+ incarnationMap[pair.Key] = pair.Value;
+ }
- foreach (KeyValuePair<Variable!, Expr!> pair in newIncarnationMappings)
- incarnationMap[pair.Key] = pair.Value;
+ if (assumptions.Count > 0) {
+ Expr assumption = assumptions[0];
- if (assumptions.Count > 0) {
- Expr! assumption = assumptions[0];
- for (int i = 1; i < assumptions.Count; ++i)
- assumption = Expr.And(assumption, assumptions[i]);
- passiveCmds.Add(new AssumeCmd(c.tok, assumption));
+ for (int i = 1; i < assumptions.Count; ++i) {
+ Contract.Assert(assumption != null);
+ assumption = Expr.And(assumption, assumptions[i]);
}
+ passiveCmds.Add(new AssumeCmd(c.tok, assumption));
}
- #endregion
- #region havoc w |--> assume whereClauses, out := in( w |-> w' )
- else if ( c is HavocCmd )
- {
- if(this.preHavocIncarnationMap == null) // Save a copy of the incarnation map (at the top of a sequence of havoc statements)
- this.preHavocIncarnationMap = (Hashtable) incarnationMap.Clone();
-
- HavocCmd! hc = (HavocCmd) c;
- IdentifierExprSeq havocVars = hc.Vars;
- // First, compute the new incarnations
- foreach (IdentifierExpr! ie in havocVars)
- {
- if ( !(ie.Decl is Incarnation) )
- {
- Variable x = (!)ie.Decl;
- Variable x_prime = CreateIncarnation(x, c);
- incarnationMap[x] = new IdentifierExpr(x_prime.tok, x_prime);
- }
+ }
+ #endregion
+ #region havoc w |--> assume whereClauses, out := in( w |-> w' )
+ else if (c is HavocCmd) {
+ if (this.preHavocIncarnationMap == null) // Save a copy of the incarnation map (at the top of a sequence of havoc statements)
+ this.preHavocIncarnationMap = (Hashtable)incarnationMap.Clone();
+
+ HavocCmd hc = (HavocCmd)c;
+ Contract.Assert(c != null);
+ IdentifierExprSeq havocVars = hc.Vars;
+ // First, compute the new incarnations
+ foreach (IdentifierExpr ie in havocVars) {
+ Contract.Assert(ie != null);
+ if (!(ie.Decl is Incarnation)) {
+ Variable x = cce.NonNull(ie.Decl);
+ Variable x_prime = CreateIncarnation(x, c);
+ incarnationMap[x] = new IdentifierExpr(x_prime.tok, x_prime);
}
- // Then, perform the assume of the where clauses, using the updated incarnations
- Substitution updatedIncarnationSubst = Substituter.SubstitutionFromHashtable(incarnationMap);
- foreach (IdentifierExpr! ie in havocVars)
- {
- if ( !(ie.Decl is Incarnation) )
- {
- Variable x = (!)ie.Decl;
- Bpl.Expr w = x.TypedIdent.WhereExpr;
- if (w != null) {
- Expr copy = Substituter.ApplyReplacingOldExprs(updatedIncarnationSubst, oldFrameSubst, w);
- passiveCmds.Add(new AssumeCmd(c.tok, copy));
- }
+ }
+ // Then, perform the assume of the where clauses, using the updated incarnations
+ Substitution updatedIncarnationSubst = Substituter.SubstitutionFromHashtable(incarnationMap);
+ foreach (IdentifierExpr ie in havocVars) {
+ Contract.Assert(ie != null);
+ if (!(ie.Decl is Incarnation)) {
+ Variable x = cce.NonNull(ie.Decl);
+ Bpl.Expr w = x.TypedIdent.WhereExpr;
+ if (w != null) {
+ Expr copy = Substituter.ApplyReplacingOldExprs(updatedIncarnationSubst, oldFrameSubst, w);
+ passiveCmds.Add(new AssumeCmd(c.tok, copy));
}
}
}
- #endregion
- else if (c is CommentCmd)
- {
- // comments are just for debugging and don't affect verification
+ }
+ #endregion
+ else if (c is CommentCmd) {
+ // comments are just for debugging and don't affect verification
+ } else if (c is SugaredCmd) {
+ SugaredCmd sug = (SugaredCmd)c;
+ Contract.Assert(sug != null);
+ Cmd cmd = sug.Desugaring;
+ Contract.Assert(cmd != null);
+ TurnIntoPassiveCmd(cmd, incarnationMap, oldFrameSubst, passiveCmds);
+ } else if (c is StateCmd) {
+ this.preHavocIncarnationMap = null; // we do not need to remeber the previous incarnations
+ StateCmd st = (StateCmd)c;
+ Contract.Assert(st != null);
+ // account for any where clauses among the local variables
+ foreach (Variable v in st.Locals) {
+ Contract.Assert(v != null);
+ Expr w = v.TypedIdent.WhereExpr;
+ if (w != null) {
+ passiveCmds.Add(new AssumeCmd(v.tok, w));
+ }
}
- else if (c is SugaredCmd)
- {
- SugaredCmd! sug = (SugaredCmd)c;
- Cmd! cmd = sug.Desugaring;
- TurnIntoPassiveCmd(cmd, incarnationMap, oldFrameSubst, passiveCmds);
+ // do the sub-commands
+ foreach (Cmd s in st.Cmds) {
+ Contract.Assert(s != null);
+ TurnIntoPassiveCmd(s, incarnationMap, oldFrameSubst, passiveCmds);
}
- else if (c is StateCmd)
- {
- this.preHavocIncarnationMap = null; // we do not need to remeber the previous incarnations
- StateCmd! st = (StateCmd)c;
- // account for any where clauses among the local variables
- foreach (Variable! v in st.Locals) {
- Expr w = v.TypedIdent.WhereExpr;
- if (w != null) {
- passiveCmds.Add(new AssumeCmd(v.tok, w));
- }
- }
- // do the sub-commands
- foreach (Cmd! s in st.Cmds) {
- TurnIntoPassiveCmd(s, incarnationMap, oldFrameSubst, passiveCmds);
- }
- // remove the local variables from the incarnation map
- foreach (Variable! v in st.Locals) {
- incarnationMap.Remove(v);
- }
- }
- #region There shouldn't be any other types of commands at this point
- else
- {
- Debug.Fail("Internal Error: Passive transformation handed a command that is not one of assert,assume,havoc,assign." );
+ // remove the local variables from the incarnation map
+ foreach (Variable v in st.Locals) {
+ Contract.Assert(v != null);
+ incarnationMap.Remove(v);
}
- #endregion
+ }
+ #region There shouldn't be any other types of commands at this point
+ else {
+ Debug.Fail("Internal Error: Passive transformation handed a command that is not one of assert,assume,havoc,assign.");
+ }
+ #endregion
- #region We rember if we have put an havoc statement into a passive form
-
- if(! (c is HavocCmd) )
- this.preHavocIncarnationMap = null;
- // else: it has already been set by the case for the HavocCmd
- #endregion
+ #region We rember if we have put an havoc statement into a passive form
+
+ if (!(c is HavocCmd))
+ this.preHavocIncarnationMap = null;
+ // else: it has already been set by the case for the HavocCmd
+ #endregion
}
/// <summary>
/// Creates a new block to add to impl.Blocks, where impl is the implementation that contains
/// succ. Caller must do the add to impl.Blocks.
/// </summary>
- protected Block! CreateBlockBetween(int predIndex, Block! succ)
- requires 0 <= predIndex && predIndex < succ.Predecessors.Length;
- {
- Block! pred = (!) succ.Predecessors[predIndex];
-
- string! newBlockLabel = pred.Label + "_@2_" + succ.Label;
+ protected Block CreateBlockBetween(int predIndex, Block succ) {
+ Contract.Requires(0 <= predIndex && predIndex < succ.Predecessors.Length);
+
+
+ Contract.Requires(succ != null);
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ Block pred = cce.NonNull(succ.Predecessors[predIndex]);
+
+ string newBlockLabel = pred.Label + "_@2_" + succ.Label;
// successor of newBlock list
StringSeq ls = new StringSeq();
@@ -1120,7 +1267,7 @@ namespace VC
new Token(-17, -4),
newBlockLabel,
new CmdSeq(),
- new GotoCmd(Token.NoToken,ls,bs)
+ new GotoCmd(Token.NoToken, ls, bs)
);
// predecessors of newBlock
@@ -1130,49 +1277,43 @@ namespace VC
// fix successors of pred
#region Change the edge "pred->succ" to "pred->newBlock"
- GotoCmd gtc = (GotoCmd!) pred.TransferCmd;
- assume gtc.labelTargets != null;
- assume gtc.labelNames != null;
- for ( int i = 0, n = gtc.labelTargets.Length; i < n; i++ )
- {
- if ( gtc.labelTargets[i] == succ )
- {
+ GotoCmd gtc = (GotoCmd)cce.NonNull(pred.TransferCmd);
+ Contract.Assume(gtc.labelTargets != null);
+ Contract.Assume(gtc.labelNames != null);
+ for (int i = 0, n = gtc.labelTargets.Length; i < n; i++) {
+ if (gtc.labelTargets[i] == succ) {
gtc.labelTargets[i] = newBlock;
gtc.labelNames[i] = newBlockLabel;
break;
}
}
#endregion Change the edge "pred->succ" to "pred->newBlock"
-
+
// fix predecessors of succ
succ.Predecessors[predIndex] = newBlock;
-
+
return newBlock;
}
-
- protected void AddBlocksBetween(Implementation! impl)
- {
+
+ protected void AddBlocksBetween(Implementation impl) {
+ Contract.Requires(impl != null);
#region Introduce empty blocks between join points and their multi-successor predecessors
- List<Block!> tweens = new List<Block!>();
- foreach ( Block b in impl.Blocks )
- {
+ List<Block> tweens = new List<Block>();
+ foreach (Block b in impl.Blocks) {
int nPreds = b.Predecessors.Length;
- if ( nPreds > 1 )
- {
+ if (nPreds > 1) {
// b is a join point (i.e., it has more than one predecessor)
- for (int i = 0; i < nPreds; i++ )
- {
- GotoCmd gotocmd = (GotoCmd!)((!)b.Predecessors[i]).TransferCmd;
- if (gotocmd.labelNames != null && gotocmd.labelNames.Length > 1)
- {
+ for (int i = 0; i < nPreds; i++) {
+ GotoCmd gotocmd = (GotoCmd)(cce.NonNull(b.Predecessors[i]).TransferCmd);
+ if (gotocmd.labelNames != null && gotocmd.labelNames.Length > 1) {
tweens.Add(CreateBlockBetween(i, b));
}
}
}
}
impl.Blocks.AddRange(tweens); // must wait until iteration is done before changing the list
- #endregion
- }
-
+ #endregion
+ }
+
}
} \ No newline at end of file
diff --git a/Source/VCGeneration/Context.cs b/Source/VCGeneration/Context.cs
index 2db00964..07ee1eeb 100644
--- a/Source/VCGeneration/Context.cs
+++ b/Source/VCGeneration/Context.cs
@@ -7,7 +7,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Boogie.VCExprAST;
namespace Microsoft.Boogie
@@ -20,22 +20,50 @@ namespace Microsoft.Boogie
/// DeclareGlobalVariable*
/// At this time, all "attributes" are passed in as null.
/// </summary>
+ [ContractClass(typeof(ProverContextContracts))]
public abstract class ProverContext : ICloneable {
- protected virtual void ProcessDeclaration(Declaration! decl) {}
- public virtual void DeclareType(TypeCtorDecl! t, string attributes) { ProcessDeclaration(t); }
- public virtual void DeclareConstant(Constant! c, bool uniq, string attributes) { ProcessDeclaration(c); }
- public virtual void DeclareFunction(Function! f, string attributes) { ProcessDeclaration(f); }
- public virtual void AddAxiom(Axiom! a, string attributes) { ProcessDeclaration(a); }
- public abstract void AddAxiom(VCExpr! vc);
- public virtual void DeclareGlobalVariable(GlobalVariable! v, string attributes) { ProcessDeclaration(v); }
-
- public abstract VCExpressionGenerator! ExprGen { get; }
- public abstract Boogie2VCExprTranslator! BoogieExprTranslator { get; }
- public abstract VCGenerationOptions! VCGenOptions { get; }
-
- public abstract object! Clone();
+ protected virtual void ProcessDeclaration(Declaration decl) {Contract.Requires(decl != null);}
+ public virtual void DeclareType(TypeCtorDecl t, string attributes) {Contract.Requires(t != null); ProcessDeclaration(t); }
+ public virtual void DeclareConstant(Constant c, bool uniq, string attributes) {Contract.Requires(c != null); ProcessDeclaration(c); }
+ public virtual void DeclareFunction(Function f, string attributes) {Contract.Requires(f != null); ProcessDeclaration(f); }
+ public virtual void AddAxiom(Axiom a, string attributes) {Contract.Requires(a != null); ProcessDeclaration(a); }
+ public virtual void DeclareGlobalVariable(GlobalVariable v, string attributes) {Contract.Requires(v != null); ProcessDeclaration(v); }
+ public abstract void AddAxiom(VCExpr vc);
+ public abstract VCExpressionGenerator ExprGen { get; }
+ public abstract Boogie2VCExprTranslator BoogieExprTranslator { get; }
+ public abstract VCGenerationOptions VCGenOptions { get; }
+ public abstract object Clone();
}
+[ContractClassFor(typeof(ProverContext))]
+public class ProverContextContracts:ProverContext{
+ public override void AddAxiom(VCExpr vc) {
+ }
+ public override void AddAxiom(Axiom a, string attributes)
+{
+}
+ public override VCExpressionGenerator ExprGen
+{
+ get { Contract.Ensures(Contract.Result<VCExpressionGenerator>() != null);
+ throw new NotImplementedException(); }
+}
+ public override Boogie2VCExprTranslator BoogieExprTranslator
+{
+ get { Contract.Ensures(Contract.Result<Boogie2VCExprTranslator>() != null);
+ throw new NotImplementedException(); }
+}
+ public override VCGenerationOptions VCGenOptions
+{
+ get {Contract.Ensures(Contract.Result<VCGenerationOptions>() != null);
+ throw new NotImplementedException(); }
+}
+ public override object Clone()
+{
+ Contract.Ensures(Contract.Result<object>() != null);
+ throw new NotImplementedException();
+}
+}
+
// -----------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------
@@ -45,75 +73,98 @@ namespace Microsoft.Boogie
/// to be declared before use. It constructs its context from unique constants and given axioms.
/// </summary>
public class DeclFreeProverContext : ProverContext {
- protected VCExpressionGenerator! gen;
- protected VCGenerationOptions! genOptions;
- protected Boogie2VCExprTranslator! translator;
+ protected VCExpressionGenerator gen;
+ protected VCGenerationOptions genOptions;
+ protected Boogie2VCExprTranslator translator;
- protected OrderingAxiomBuilder! orderingAxiomBuilder;
+ protected OrderingAxiomBuilder orderingAxiomBuilder;
- StringBuilder! proverCommands;
- StringBuilder! incrementalProverCommands;
+ StringBuilder proverCommands;
+ StringBuilder incrementalProverCommands;
- protected List<Variable!>! distincts;
- protected List<VCExpr!>! axiomConjuncts;
+ protected List<Variable> distincts;
+ protected List<VCExpr> axiomConjuncts;
+
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(gen!=null);
+ Contract.Invariant(genOptions != null);
+ Contract.Invariant(translator != null);
+ Contract.Invariant(orderingAxiomBuilder != null);
+ Contract.Invariant(proverCommands != null);
+ Contract.Invariant(incrementalProverCommands != null);
+ Contract.Invariant(cce.NonNullElements(distincts));
+ Contract.Invariant(cce.NonNullElements(axiomConjuncts));
+}
- public VCExprTranslator exprTranslator;
+ public VCExprTranslator/*?*/ exprTranslator;
- public DeclFreeProverContext(VCExpressionGenerator! gen,
- VCGenerationOptions! genOptions) {
+ public DeclFreeProverContext(VCExpressionGenerator gen,
+ VCGenerationOptions genOptions) {
+ Contract.Requires(gen != null);
+ Contract.Requires(genOptions != null);
this.gen = gen;
this.genOptions = genOptions;
- Boogie2VCExprTranslator! t = new Boogie2VCExprTranslator (gen, genOptions);
+ Boogie2VCExprTranslator t = new Boogie2VCExprTranslator (gen, genOptions);
this.translator = t;
- OrderingAxiomBuilder! oab = new OrderingAxiomBuilder(gen, t);
+ OrderingAxiomBuilder oab = new OrderingAxiomBuilder(gen, t);
+ Contract.Assert(oab != null);
oab.Setup();
this.orderingAxiomBuilder = oab;
proverCommands = new StringBuilder();
incrementalProverCommands = new StringBuilder();
- distincts = new List<Variable!>();
- axiomConjuncts = new List<VCExpr!>();
+ distincts = new List<Variable>();
+ axiomConjuncts = new List<VCExpr>();
exprTranslator = null;
}
- private DeclFreeProverContext(DeclFreeProverContext! ctxt) {
+ private DeclFreeProverContext(DeclFreeProverContext ctxt) {
+ Contract.Requires(ctxt != null);
this.gen = ctxt.gen;
this.genOptions = ctxt.genOptions;
- Boogie2VCExprTranslator! t = (Boogie2VCExprTranslator)ctxt.translator.Clone();
+ Boogie2VCExprTranslator t = (Boogie2VCExprTranslator)ctxt.translator.Clone();
+ Contract.Assert(t != null);
this.translator = t;
this.orderingAxiomBuilder = new OrderingAxiomBuilder(ctxt.gen, t, ctxt.orderingAxiomBuilder);
- StringBuilder! cmds = new StringBuilder ();
+ StringBuilder cmds = new StringBuilder ();
+
cmds.Append(ctxt.proverCommands);
proverCommands = cmds;
- StringBuilder! incCmds = new StringBuilder ();
+ StringBuilder incCmds = new StringBuilder ();
incCmds.Append(ctxt.incrementalProverCommands);
incrementalProverCommands = incCmds;
- distincts = new List<Variable!>(ctxt.distincts);
- axiomConjuncts = new List<VCExpr!>(ctxt.axiomConjuncts);
+ distincts = new List<Variable>(ctxt.distincts);
+ axiomConjuncts = new List<VCExpr>(ctxt.axiomConjuncts);
if (ctxt.exprTranslator == null)
exprTranslator = null;
else
- exprTranslator = (VCExprTranslator!)ctxt.exprTranslator.Clone();
+ exprTranslator = (VCExprTranslator)cce.NonNull(ctxt.exprTranslator.Clone());
}
- public override object! Clone() {
+ public override object Clone() {
+ Contract.Ensures(Contract.Result<object>() != null);
+
return new DeclFreeProverContext(this);
}
- internal protected void SayToProver(string! msg)
+ internal protected void SayToProver(string msg)
{
+ Contract.Requires(msg != null);
msg = msg + "\r\n";
proverCommands.Append(msg);
incrementalProverCommands.Append(msg);
}
- protected override void ProcessDeclaration(Declaration! decl)
+ protected override void ProcessDeclaration(Declaration decl)
{
+ Contract.Requires(decl != null);
for (QKeyValue a = decl.Attributes; a != null; a = a.Next) {
if (a.Key == "prover" && a.Params.Count == 1) {
string cmd = a.Params[0] as string;
@@ -129,11 +180,11 @@ namespace Microsoft.Boogie
}
}
- public override void DeclareFunction(Function! f, string attributes) {
+ public override void DeclareFunction(Function f, string attributes) {Contract.Requires(f != null);
base.ProcessDeclaration(f);
}
- public override void DeclareConstant(Constant! c, bool uniq, string attributes) {
+ public override void DeclareConstant(Constant c, bool uniq, string attributes) {Contract.Requires(c != null);
base.DeclareConstant(c, uniq, attributes);
orderingAxiomBuilder.AddConstant(c);
@@ -144,7 +195,7 @@ namespace Microsoft.Boogie
}
}
- public override void AddAxiom(Axiom! ax, string attributes) {
+ public override void AddAxiom(Axiom ax, string attributes) {Contract.Requires(ax != null);
base.AddAxiom(ax, attributes);
string ignore = ax.FindStringAttribute("ignore");
@@ -155,17 +206,18 @@ namespace Microsoft.Boogie
axiomConjuncts.Add(translator.Translate(ax.Expr));
}
- public override void AddAxiom(VCExpr! vc)
- {
+ public override void AddAxiom(VCExpr vc)
+ {Contract.Requires(vc != null);
axiomConjuncts.Add(vc);
}
- public VCExpr! Axioms {
- get {
+ public VCExpr Axioms {
+ get {Contract.Ensures(Contract.Result<VCExpr>() != null);
VCExpr axioms = gen.NAry(VCExpressionGenerator.AndOp, axiomConjuncts);
- List<VCExpr!>! distinctVars = new List<VCExpr!> ();
- foreach (Variable! v in distincts)
- distinctVars.Add(translator.LookupVariable(v));
+ List<VCExpr>/*!>!*/ distinctVars = new List<VCExpr> ();
+ foreach (Variable v in distincts){
+ Contract.Assert(v != null);
+ distinctVars.Add(translator.LookupVariable(v));}
axioms = gen.AndSimp(gen.Distinct(distinctVars), axioms);
if (CommandLineOptions.Clo.TypeEncodingMethod != CommandLineOptions.TypeEncoding.Monomorphic)
axioms = gen.AndSimp(orderingAxiomBuilder.Axioms, axioms);
@@ -173,28 +225,56 @@ namespace Microsoft.Boogie
}
}
- public string! GetProverCommands(bool full) {
- string! res = (full ? proverCommands : incrementalProverCommands).ToString();
+ public string GetProverCommands(bool full) {Contract.Ensures(Contract.Result<string>() != null);
+
+ string res = (full ? proverCommands : incrementalProverCommands).ToString();
incrementalProverCommands.Length = 0;
return res;
}
- public override VCExpressionGenerator! ExprGen { get {
+ public override VCExpressionGenerator ExprGen { get {Contract.Ensures(Contract.Result<VCExpressionGenerator>() != null);
+
return gen;
} }
- public override Boogie2VCExprTranslator! BoogieExprTranslator { get {
+ public override Boogie2VCExprTranslator BoogieExprTranslator { get {Contract.Ensures(Contract.Result<Boogie2VCExprTranslator>() != null);
+
return translator;
} }
- public override VCGenerationOptions! VCGenOptions { get {
+ public override VCGenerationOptions VCGenOptions { get {Contract.Ensures(Contract.Result<VCGenerationOptions>() != null);
+
return genOptions;
} }
}
// Translator from VCExpressions to strings, which are implemented
// by the various provers
+ [ContractClass(typeof(VCExprTranslatorContracts))]
public abstract class VCExprTranslator : ICloneable {
- public abstract string! translate(VCExpr! expr, int polarity);
- public abstract string! Lookup(VCExprVar! var);
- public abstract Object! Clone();
+ public abstract string translate(VCExpr expr, int polarity);
+ public abstract string Lookup(VCExprVar var);
+ public abstract Object Clone();
+ }
+
+ [ContractClassFor(typeof(VCExprTranslator))]
+
+ public class VCExprTranslatorContracts : VCExprTranslator {
+ public override object Clone() {
+ Contract.Ensures(Contract.Result<object>() != null);
+ throw new NotImplementedException();
+ }
+ public override string Lookup(VCExprVar var) {
+ Contract.Requires(var != null);
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ throw new NotImplementedException();
+ }
+ public override string translate(VCExpr expr, int polarity) {
+
+ Contract.Requires(expr != null);
+
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ throw new NotImplementedException();
+ }
}
}
diff --git a/Source/VCGeneration/DoomCheck.cs b/Source/VCGeneration/DoomCheck.cs
index b65f7f24..76035577 100644
--- a/Source/VCGeneration/DoomCheck.cs
+++ b/Source/VCGeneration/DoomCheck.cs
@@ -18,7 +18,7 @@ using System.IO;
using Microsoft.Boogie;
using Graphing;
using AI = Microsoft.AbstractInterpretationFramework;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Basetypes;
using Microsoft.Boogie.VCExprAST;
@@ -32,25 +32,35 @@ namespace VC
}
}
- private Checker! m_Checker;
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(m_Checker!=null);
+}
+
+ private Checker m_Checker;
private DoomErrorHandler m_ErrorHandler;
[NotDelayed]
- public Evc(Checker! check) {
+ public Evc(Checker check) {
+ Contract.Requires(check != null);
m_Checker = check;
- base();
+
}
- public void Initialize(VCExpr! evc) {
+ public void Initialize(VCExpr evc) {
+ Contract.Requires(evc != null);
m_Checker.PushVCExpr(evc);
}
- public bool CheckReachvar(Variable! reachvar, out ProverInterface.Outcome outcome) {
- VCExpr! vc = m_Checker.TheoremProver.Context.BoogieExprTranslator.LookupVariable(reachvar);
+ public bool CheckReachvar(Variable reachvar, out ProverInterface.Outcome outcome) {
+ Contract.Requires(reachvar != null);
+ VCExpr vc = m_Checker.TheoremProver.Context.BoogieExprTranslator.LookupVariable(reachvar);
+ Contract.Assert(vc != null);
// Todo: Check if vc is trivial true or false
outcome = ProverInterface.Outcome.Undetermined;
- assert m_ErrorHandler !=null;
+ Contract.Assert( m_ErrorHandler !=null);
m_Checker.BeginCheck(reachvar.Name, vc, m_ErrorHandler);
m_Checker.ProverDone.WaitOne();
@@ -70,8 +80,17 @@ namespace VC
internal class DoomCheck {
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(Label2Absy!=null);
+ Contract.Invariant(m_Check != null);
+ Contract.Invariant(m_Evc != null);
+ Contract.Invariant(m_Order != null);
+}
+
#region Attributes
- public Hashtable! Label2Absy;
+ public Hashtable Label2Absy;
public DoomErrorHandler ErrorHandler {
set {
m_ErrHandler = value;
@@ -84,25 +103,27 @@ namespace VC
}
private DoomErrorHandler m_ErrHandler;
- private Checker! m_Check;
- private InclusionOrder! m_Order;
- private Evc! m_Evc;
+ private Checker m_Check;
+ private InclusionOrder m_Order;
+ private Evc m_Evc;
#endregion
[NotDelayed]
- public DoomCheck (Implementation! passive_impl, Checker! check) {
+ public DoomCheck (Implementation passive_impl, Checker check) {
+ Contract.Requires(passive_impl != null);
+ Contract.Requires(check != null);
m_Check = check;
if (!VC.DCGen.UseItAsDebugger ) {
m_Order = new InclusionOrder(passive_impl.Blocks[0]);
} else {
- m_Order = new InclusionOrder((!)VC.DCGen.firstNonDebugBlock );
+ m_Order = new InclusionOrder(cce.NonNull(VC.DCGen.firstNonDebugBlock) );
}
Label2Absy = new Hashtable(); // This is only a dummy
m_Evc = new Evc(check);
- base();
Hashtable l2a = null;
- VCExpr! vce = this.GenerateEVC(passive_impl, out l2a, check);
- assert l2a!=null;
+ VCExpr vce = this.GenerateEVC(passive_impl, out l2a, check);
+ Contract.Assert(vce != null);
+ Contract.Assert( l2a!=null);
Label2Absy = l2a;
// vce = check.VCExprGen.Implies(vce, vce);
m_Evc.Initialize(vce);
@@ -120,8 +141,8 @@ namespace VC
- outcome is set to Outcome.Invalid if the Block denoted by reachvar is doomed.
- returns false if the theorem prover throws an exception, otherwise true.
*/
- public bool CheckLabel(Variable! reachvar, out ProverInterface.Outcome outcome) {
-
+ public bool CheckLabel(Variable reachvar, out ProverInterface.Outcome outcome) {
+ Contract.Requires(reachvar != null);
outcome = ProverInterface.Outcome.Undetermined;
if (m_Evc.CheckReachvar(reachvar, out outcome) ) {
if (!m_Order.SetCurrentResult(reachvar, outcome, m_ErrHandler)) {
@@ -134,8 +155,10 @@ namespace VC
}
}
- public List<List<Block!>!>! DoomedSequences {
+ public List<List<Block/*!>!>!*/>> DoomedSequences {
get {
+ Contract.Ensures(Contract.ForAll(Contract.Result<List<List<Block>>>(), i=> cce.NonNullElements(i)));
+
return m_Order.DetectedBlock;
}
}
@@ -153,29 +176,34 @@ namespace VC
*/
private bool _tmpUseFreshBVars;
- VCExpr! GenerateEVC(Implementation! impl, out Hashtable label2absy, Checker! ch)
+ VCExpr GenerateEVC(Implementation impl, out Hashtable label2absy, Checker ch)
{
+ Contract.Requires(impl != null);
+ Contract.Requires(ch != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
TypecheckingContext tc = new TypecheckingContext(null);
impl.Typecheck(tc);
label2absy = new Hashtable/*<int, Absy!>*/();
- VCExpr! vc;
+ VCExpr vc;
switch (CommandLineOptions.Clo.vcVariety) {
case CommandLineOptions.VCVariety.Doomed:
if (!VC.DCGen.UseItAsDebugger ) {
- vc = LetVC((!)impl.Blocks[0], label2absy, ch.TheoremProver.Context);
+ vc = LetVC(cce.NonNull(impl.Blocks[0]), label2absy, ch.TheoremProver.Context);
}
#region _TESTING_NEW_STUFF_
else {
CommandLineOptions.Clo.vcVariety = CommandLineOptions.VCVariety.Block;
- assert VC.DCGen.firstDebugBlock != null;
- VCExpr! a = LetVC(VC.DCGen.firstDebugBlock, label2absy, ch.TheoremProver.Context);
+ Contract.Assert( VC.DCGen.firstDebugBlock != null);
+ VCExpr a = LetVC(VC.DCGen.firstDebugBlock, label2absy, ch.TheoremProver.Context);
+ Contract.Assert(a != null);
CommandLineOptions.Clo.vcVariety = CommandLineOptions.VCVariety.Doomed;
- VCExpr! b = LetVC((!)VC.DCGen.firstNonDebugBlock, label2absy, ch.TheoremProver.Context);
+ VCExpr b = LetVC(cce.NonNull(VC.DCGen.firstNonDebugBlock), label2absy, ch.TheoremProver.Context);
//_tmpUseFreshBVars=false;
//vc = ch.VCExprGen.Not(ch.VCExprGen.Implies( wp, ch.VCExprGen.Not(vc)));
@@ -197,17 +225,21 @@ namespace VC
break;
default:
- assert false; // unexpected enumeration value
+ Contract.Assert(false);throw new cce.UnreachableException(); // unexpected enumeration value
}
return vc;
}
- public VCExpr! LetVC(Block! startBlock,
- Hashtable/*<int, Absy!>*/! label2absy,
- ProverContext! proverCtxt)
- {
- Hashtable/*<Block, LetVariable!>*/! blockVariables = new Hashtable/*<Block, LetVariable!!>*/();
- List<VCExprLetBinding!>! bindings = new List<VCExprLetBinding!>();
+ public VCExpr LetVC(Block startBlock,
+ Hashtable/*<int, Absy!>*/ label2absy,
+ ProverContext proverCtxt)
+ {Contract.Requires(startBlock != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(proverCtxt != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ Hashtable/*<Block, LetVariable!>*/ blockVariables = new Hashtable/*<Block, LetVariable!!>*/();
+ List<VCExprLetBinding> bindings = new List<VCExprLetBinding>();
VCExpr startCorrect = LetVC(startBlock, label2absy, blockVariables, bindings, proverCtxt);
if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed) {
return proverCtxt.ExprGen.Let(bindings, proverCtxt.ExprGen.Not(startCorrect) );
@@ -216,13 +248,20 @@ namespace VC
}
}
- VCExpr! LetVC(Block! block,
- Hashtable/*<int, Absy!>*/! label2absy,
- Hashtable/*<Block, VCExprVar!>*/! blockVariables,
- List<VCExprLetBinding!>! bindings,
- ProverContext! proverCtxt)
+ VCExpr LetVC(Block block,
+ Hashtable/*<int, Absy!>*/ label2absy,
+ Hashtable/*<Block, VCExprVar!>*/ blockVariables,
+ List<VCExprLetBinding> bindings,
+ ProverContext proverCtxt)
{
- VCExpressionGenerator! gen = proverCtxt.ExprGen;
+ Contract.Requires(label2absy != null);
+ Contract.Requires(blockVariables != null);
+ Contract.Requires(proverCtxt != null);
+ Contract.Requires(cce.NonNullElements(bindings));
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpressionGenerator gen = proverCtxt.ExprGen;
+ Contract.Assert(gen != null);
VCExprVar v = (VCExprVar)blockVariables[block];
if (v == null) {
/*
@@ -240,9 +279,10 @@ namespace VC
SuccCorrect = VCExpressionGenerator.True;
}
} else {
- assert gotocmd.labelTargets != null;
- List<VCExpr!> SuccCorrectVars = new List<VCExpr!>(gotocmd.labelTargets.Length);
- foreach (Block! successor in gotocmd.labelTargets) {
+ Contract.Assert( gotocmd.labelTargets != null);
+ List<VCExpr> SuccCorrectVars = new List<VCExpr>(gotocmd.labelTargets.Length);
+ foreach (Block successor in gotocmd.labelTargets) {
+ Contract.Assert(successor != null);
VCExpr s = LetVC(successor, label2absy, blockVariables, bindings, proverCtxt);
SuccCorrectVars.Add(s);
}
@@ -271,15 +311,22 @@ namespace VC
{
#region Attributes
- public List<List<Block!>!>! DetectedBlock = new List<List<Block!>!>();
+ public List<List<Block/*!*/>/*!*/>/*!*/ DetectedBlock = new List<List<Block/*!*/>/*!*/>();
+
- InclusionTree! RootNode = new InclusionTree(null);
+ InclusionTree RootNode = new InclusionTree(null);
InclusionTree currentNode = null;
-
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(DetectedBlock!=null);
+ Contract.Invariant(RootNode != null);
+}
+
#endregion
[NotDelayed]
- public InclusionOrder(Block! rootblock) {
+ public InclusionOrder(Block rootblock) {Contract.Requires(rootblock != null);
/*
We now compute for each block the set of blocks that
are reached on every execution reaching this block (dominator).
@@ -287,28 +334,29 @@ namespace VC
block and second from the Term block to the current one.
Finally we build the union.
*/
+ Dictionary<Block,TraceNode> map2 = new Dictionary<Block,TraceNode>();
+ Dictionary<Block,TraceNode> map = new Dictionary<Block,TraceNode>();
- base();
- Dictionary<Block!,TraceNode!>! map2 = new Dictionary<Block!,TraceNode!>();
- Dictionary<Block!,TraceNode!>! map = new Dictionary<Block!,TraceNode!>();
-
- Dictionary<Block!, List<Block!>!>! unavoidablemap = new Dictionary<Block!, List<Block!>!>();
+ Dictionary<Block, List<Block>> unavoidablemap = new Dictionary<Block, List<Block>>();
- Block! exitblock = BreadthFirst(rootblock, map2);
+ Block exitblock = BreadthFirst(rootblock, map2);Contract.Assert(exitblock != null);
BreadthFirstBwd(exitblock, map);
- foreach (KeyValuePair<Block!, TraceNode!> kvp in map) {
- List<Block!>! blist = new List<Block!>();
+ foreach (KeyValuePair<Block, TraceNode> kvp in map) {
+ Contract.Assert(kvp.Key != null);Contract.Assert(kvp.Value != null);
+ List<Block/*!*/>/*!*/ blist = new List<Block/*!*/>();
foreach (TraceNode tn in kvp.Value.Unavoidables ) {
blist.Add(tn.block);
}
unavoidablemap.Add(kvp.Key, blist);
}
- foreach (KeyValuePair<Block!, List<Block!>!> kvp in unavoidablemap) {
+ foreach (KeyValuePair<Block, List<Block>> kvp in unavoidablemap) {
+ Contract.Assert(kvp.Key != null);
+ Contract.Assert(cce.NonNullElements(kvp.Value));
TraceNode tn = null;
if (map2.TryGetValue(kvp.Key, out tn) ) {
- assert tn!=null;
- foreach (TraceNode! t0 in tn.Unavoidables) {
+ Contract.Assert( tn!=null);
+ foreach (TraceNode t0 in tn.Unavoidables) {Contract.Assert(t0 != null);
if (!kvp.Value.Contains(t0.block))
kvp.Value.Add(t0.block);
}
@@ -316,15 +364,17 @@ namespace VC
//assert false;
}
}
-
- foreach (KeyValuePair<Block!, List<Block!>!> kvp in unavoidablemap) {
+
+ foreach (KeyValuePair<Block, List<Block>> kvp in unavoidablemap) {
+ Contract.Assert(kvp.Key != null);
+ Contract.Assert(cce.NonNullElements(kvp.Value));
Insert2Tree(RootNode,kvp);
}
InitCurrentNode(RootNode);
//printtree(RootNode, "",0);
}
- void InitCurrentNode(InclusionTree! n) {
+ void InitCurrentNode(InclusionTree n) {Contract.Requires(n != null);
if (n.Children.Count>0) {
InitCurrentNode(n.Children[0]);
} else {
@@ -347,8 +397,8 @@ namespace VC
a map from Block to InclusionTree to prevent running through
the tree over and over again.
*/
- private void MarkUndoomedFromCE(Block! b, InclusionTree! node)
- {
+ private void MarkUndoomedFromCE(Block b, InclusionTree node)
+ {Contract.Requires(b != null);Contract.Requires(node != null);
if (node.EquivBlock.Contains(b) ) {
//Console.WriteLine("Block {0} does not need to be checked - appears in CE", b.Label);
node.HasBeenChecked = true;
@@ -357,8 +407,8 @@ namespace VC
return;
} else
{
- foreach (InclusionTree! c in node.Children)
- {
+ foreach (InclusionTree c in node.Children) {
+ Contract.Assert(c != null);
MarkUndoomedFromCE(b, c);
}
}
@@ -369,7 +419,7 @@ namespace VC
// desteny
// returns false if an explicite assert false was found.
// Warning: Still slow; we do not need to do this while constructing the error report!
- public bool SetCurrentResult(Variable! reachvar, ProverInterface.Outcome outcome, DoomErrorHandler cb) {
+ public bool SetCurrentResult(Variable reachvar, ProverInterface.Outcome outcome, DoomErrorHandler cb) {Contract.Requires(reachvar != null);
if (outcome!=ProverInterface.Outcome.Valid) {
if (currentNode != null) {
currentNode.IsDoomed = false;
@@ -377,8 +427,8 @@ namespace VC
MarkUndoomedParents(currentNode);
if (cb != null) {
//Console.WriteLine("CE contains: ");
- foreach (Block! b in cb.TraceNodes)
- {
+ foreach (Block b in cb.TraceNodes)
+ {Contract.Assert(b != null);
//Console.Write("{0}, ", b.Label);
MarkUndoomedFromCE(b, RootNode);
}
@@ -407,7 +457,7 @@ namespace VC
// return false;
// }
- List<Block!>! traceblocks = new List<Block!>();
+ List<Block> traceblocks = new List<Block>();
TracedChildern(currentNode, traceblocks);
TracedParents(currentNode, traceblocks);
@@ -419,7 +469,7 @@ namespace VC
if (currentNode.EquivBlock.Count>0) {
- foreach (InclusionTree! n in currentNode.Children) {
+ foreach (InclusionTree n in currentNode.Children) {Contract.Assert(n != null);
if (DetectedBlock.Contains(n.EquivBlock) ) {
DetectedBlock.Remove(n.EquivBlock);
}
@@ -429,7 +479,7 @@ namespace VC
} else {
Console.WriteLine("An empty equivalence class has been detected");
- assert false;
+ Contract.Assert(false);throw new cce.UnreachableException();
}
currentNode.IsDoomed = true;
@@ -437,7 +487,8 @@ namespace VC
MarkDoomedChildren(currentNode);
currentNode = currentNode.Parent;
if (currentNode!=null) {
- foreach (InclusionTree! it in currentNode.Children) {
+ foreach (InclusionTree it in currentNode.Children) {
+ Contract.Assert(it != null);
if (!it.HasBeenChecked) {
currentNode = DescendToDeepestUnchecked(it);
break;
@@ -449,9 +500,12 @@ namespace VC
return true;
}
- private InclusionTree! DescendToDeepestUnchecked(InclusionTree! node)
+ private InclusionTree DescendToDeepestUnchecked(InclusionTree node)
{
- foreach (InclusionTree! it in node.Children) {
+ Contract.Requires(node != null);
+ Contract.Ensures(Contract.Result<InclusionTree>() != null);
+
+ foreach (InclusionTree it in node.Children) {Contract.Assert(it != null);
if (!it.HasBeenChecked) {
return DescendToDeepestUnchecked(it);
}
@@ -459,15 +513,16 @@ namespace VC
return node;
}
- private bool ECContainsAssertFalse(List<Block!>! equiv) {
- foreach (Block! b in equiv) {
+ private bool ECContainsAssertFalse(List<Block> equiv) {
+ Contract.Requires(cce.NonNullElements(equiv));
+ foreach (Block b in equiv) {Contract.Assert(b != null);
if (BlockContainsAssertFalse(b)) return true;
}
return false;
}
- private bool BlockContainsAssertFalse(Block! b) {
- foreach (Cmd! c in b.Cmds) {
+ private bool BlockContainsAssertFalse(Block b) {Contract.Requires(b != null);
+ foreach (Cmd c in b.Cmds) {Contract.Assert(c != null);
AssertCmd ac = c as AssertCmd;
if (ac!=null) {
if (IsFalse(ac.Expr) || QKeyValue.FindBoolAttribute(ac.Attributes, "PossiblyUnreachable") ) {
@@ -480,8 +535,9 @@ namespace VC
// check if e is true, false, !true, !false
// if so return true and the value of the expression in val
- bool BooleanEval(Expr! e, ref bool val)
+ bool BooleanEval(Expr e, ref bool val)
{
+ Contract.Requires(e != null);
LiteralExpr lit = e as LiteralExpr;
NAryExpr call = e as NAryExpr;
@@ -491,7 +547,7 @@ namespace VC
} else if (call != null &&
call.Fun is UnaryOperator &&
((UnaryOperator)call.Fun).Op == UnaryOperator.Opcode.Not &&
- BooleanEval((!)call.Args[0], ref val)) {
+ BooleanEval(cce.NonNull(call.Args[0]), ref val)) {
val = !val;
return true;
}
@@ -500,7 +556,7 @@ namespace VC
call.Fun is BinaryOperator &&
((BinaryOperator)call.Fun).Op == BinaryOperator.Opcode.Neq &&
call.Args[0] is LiteralExpr &&
- ((!)call.Args[0]).Equals(call.Args[1]))
+ cce.NonNull(call.Args[0]).Equals(call.Args[1]))
{
val = false;
return true;
@@ -509,23 +565,28 @@ namespace VC
return false;
}
- bool IsFalse(Expr! e)
- {
+ bool IsFalse(Expr e)
+ {Contract.Requires(e != null);
bool val = false;
return BooleanEval(e, ref val) && !val;
}
- private void TracedChildern(InclusionTree! node, List<Block!>! blist) {
- foreach (Block! b in node.EquivBlock) {
+ private void TracedChildern(InclusionTree node, List<Block/*!*/>/*!*/ blist) {
+ Contract.Requires(node != null);
+ Contract.Requires(cce.NonNullElements(blist));
+ foreach (Block b in node.EquivBlock) {Contract.Assert(b != null);
if (!blist.Contains(b)) blist.Add(b);
}
- foreach (InclusionTree! n in node.Children) {
+ foreach (InclusionTree n in node.Children) {
+ Contract.Assert(n != null);
TracedChildern(n, blist);
}
}
- private void TracedParents(InclusionTree! node, List<Block!>! blist) {
- foreach (Block! b in node.EquivBlock) {
+ private void TracedParents(InclusionTree node, List<Block> blist) {
+ Contract.Requires(node != null);
+ Contract.Requires(cce.NonNullElements(blist));
+ foreach (Block b in node.EquivBlock) {Contract.Assert(b != null);
if (!blist.Contains(b)) blist.Add(b);
}
if (node.Parent!=null) {
@@ -533,11 +594,12 @@ namespace VC
}
}
- InclusionTree FindNextNode(InclusionTree! n) {
- assert n!=n.Parent;
+ InclusionTree FindNextNode(InclusionTree n) {Contract.Requires(n != null);
+ Contract.Assert( n!=n.Parent);
InclusionTree next = n.Parent;
if (next!=null) {
- foreach (InclusionTree! n0 in next.Children) {
+ foreach (InclusionTree n0 in next.Children) {
+ Contract.Assert(n0 != null);
if (!n0.HasBeenChecked) {
return n0;
}
@@ -547,7 +609,7 @@ namespace VC
return next;
}
- void MarkUndoomedParents(InclusionTree! n) {
+ void MarkUndoomedParents(InclusionTree n) {Contract.Requires(n != null);
if (n.Parent != null) {
n.Parent.HasBeenChecked = true;
n.Parent.IsDoomed = false;
@@ -555,15 +617,19 @@ namespace VC
}
}
- void MarkDoomedChildren(InclusionTree! n) {
- foreach (InclusionTree! t in n.Children) {
+ void MarkDoomedChildren(InclusionTree n) {Contract.Requires(n != null);
+ foreach (InclusionTree t in n.Children) {
+ Contract.Assert(t != null);
t.IsDoomed = true;
t.HasBeenChecked = true;
MarkDoomedChildren(t);
}
}
- bool Insert2Tree(InclusionTree! node, KeyValuePair<Block!, List<Block!>!> kvp) {
+ bool Insert2Tree(InclusionTree node, KeyValuePair<Block, List<Block>> kvp) {
+ Contract.Requires(node != null);
+ Contract.Requires(kvp.Key != null);
+ Contract.Requires(cce.NonNullElements(kvp.Value));
if (IsSubset(node.PathBlocks, kvp.Value) ) {
if (IsSubset(kvp.Value, node.PathBlocks) ) {
// The set of unavoidable blocks is equal, so
@@ -571,14 +637,15 @@ namespace VC
node.EquivBlock.Add(kvp.Key);
return true;
} else {
- foreach (InclusionTree! n in node.Children) {
+ foreach (InclusionTree n in node.Children) {Contract.Assert(n != null);
if (Insert2Tree(n,kvp) ) {
return true;
}
}
// we have not been able to add the block to one of
// the children, so we have to create a new child.
- InclusionTree! it = new InclusionTree(node);
+ InclusionTree it = new InclusionTree(node);
+ Contract.Assert(it != null);
it.EquivBlock.Add(kvp.Key);
it.PathBlocks.AddRange(kvp.Value);
node.Children.Add(it);
@@ -592,21 +659,23 @@ namespace VC
return false;
}
- bool IsSubset(List<Block!>! sub, List<Block!>! super ) {
- foreach (Block! b in sub) {
+ bool IsSubset(List<Block> sub, List<Block> super ) {Contract.Requires(sub!=null);Contract.Requires(cce.NonNullElements(super));
+ foreach (Block b in sub) {
+ Contract.Assert(b != null);
if (!super.Contains(b) ) return false;
}
return true;
}
- void printtree(InclusionTree! n, string indent, int level) {
+ void printtree(InclusionTree n, string indent, int level) {Contract.Requires(n != null);
Console.Write("{0}Level {1}: Blocks ", indent, level);
- foreach (Block! b in n.EquivBlock) {
+ foreach (Block b in n.EquivBlock) {Contract.Assert(b != null);
Console.Write("{0}, ", b.Label);
}
Console.WriteLine();
-
- foreach (InclusionTree! t in n.Children) {
+
+ foreach (InclusionTree t in n.Children) {
+ Contract.Assert(t != null);
printtree(t, indent+" ", level+1);
}
}
@@ -621,41 +690,55 @@ namespace VC
public bool HasBeenChecked;
public bool IsDoomed;
public InclusionTree Parent;
- public List<Block!>! EquivBlock = new List<Block!>();
- public List<Block!>! PathBlocks = new List<Block!>();
- public List<InclusionTree!>! Children = new List<InclusionTree!>();
+ public List<Block/*!*/>/*!*/ EquivBlock = new List<Block>();
+ public List<Block/*!*/>/*!*/ PathBlocks = new List<Block>();
+ public List<InclusionTree/*!*/>/*!*/ Children = new List<InclusionTree>();
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(Parent!=null);
+ Contract.Invariant(cce.NonNullElements(EquivBlock));
+ Contract.Invariant(cce.NonNullElements(PathBlocks));
+ Contract.Invariant(cce.NonNullElements(Children));
+}
+
}
#region Collect Unavoidable Blocks
- private Block! BreadthFirst(Block! start, Dictionary<Block!, TraceNode!>! blockmap) {
- List<Block!>! JobList = new List<Block!>();
- List<Block!>! DoneList = new List<Block!>();
+ private Block BreadthFirst(Block start, Dictionary<Block, TraceNode> blockmap) {
+ Contract.Requires(start != null);
+ Contract.Requires(cce.NonNullElements(blockmap));
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ List<Block> JobList = new List<Block>();
+ List<Block> DoneList = new List<Block>();
Block exitblock=null;
JobList.Add(start);
- Block! currentBlock = JobList[0];
+ Block currentBlock = JobList[0];
// Travers the Graph Breadth First and collect all
// predecessors of each node that are reached on any
// path to this node
while (JobList.Count>0)
{
currentBlock = JobList[0];
- TraceNode! tn = new TraceNode(currentBlock);
+ TraceNode tn = new TraceNode(currentBlock);
+ Contract.Assert(tn != null);
if (currentBlock.Predecessors.Length>0 ) {
TraceNode t0 =null;
Block firstpred = currentBlock.Predecessors[0];
- assert firstpred!=null;
+ Contract.Assert( firstpred!=null);
if (blockmap.TryGetValue(firstpred, out t0)) {
- assert t0 !=null;
+ Contract.Assert( t0 !=null);
tn.Unavoidables.AddRange(t0.Unavoidables);
}
}
- foreach (Block! b0 in currentBlock.Predecessors) {
+ foreach (Block b0 in currentBlock.Predecessors) {Contract.Assert(b0 != null);
TraceNode t = null;
if (blockmap.TryGetValue(b0, out t)) {
- assert t!=null;
+ Contract.Assert( t!=null);
tn.Predecessors.Add(t);
IntersectUnavoidables(t,tn);
if (!t.Successors.Contains(tn)) t.Successors.Add(tn);
@@ -666,7 +749,7 @@ namespace VC
tn.Unavoidables.Add(tn);
} else
{
- assert false;
+ Contract.Assert(false);throw new cce.UnreachableException();
}
@@ -674,8 +757,8 @@ namespace VC
GotoCmd gc = currentBlock.TransferCmd as GotoCmd;
if (gc!=null) {
- assert gc.labelTargets!=null;
- foreach (Block! b0 in gc.labelTargets) {
+ Contract.Assert( gc.labelTargets!=null);
+ foreach (Block b0 in gc.labelTargets) {Contract.Assert(b0 != null);
if (!JobList.Contains(b0) && !DoneList.Contains(b0)) {
JobList.Add(b0);
@@ -687,25 +770,28 @@ namespace VC
DoneList.Add(currentBlock);
JobList.RemoveAt(0);
}
- assert exitblock!=null;
+ Contract.Assert( exitblock!=null);
return exitblock;
}
// WARNING: It is only for testing reasons that
// BreadthFirstBwd and BreadthFirst and separat functions
// it should be implemented using one function later on.
- private void BreadthFirstBwd(Block! start, Dictionary<Block!, TraceNode!>! blockmap) {
- List<Block!>! JobList = new List<Block!>();
- List<Block!>! DoneList = new List<Block!>();
+ private void BreadthFirstBwd(Block start, Dictionary<Block, TraceNode> blockmap) {
+ Contract.Requires(start != null);
+ Contract.Requires(cce.NonNullElements(blockmap));
+
+ List<Block> JobList = new List<Block>();
+ List<Block> DoneList = new List<Block>();
JobList.Add(start);
- Block! currentBlock = JobList[0];
+ Block currentBlock = JobList[0];
// Travers the Graph Breadth First and collect all
// predecessors of each node that are reached on any
// path to this node
while (JobList.Count>0)
{
currentBlock = JobList[0];
- TraceNode! tn = new TraceNode(currentBlock);
+ TraceNode tn = new TraceNode(currentBlock);Contract.Assert(tn != null);
GotoCmd gc = currentBlock.TransferCmd as GotoCmd;
BlockSeq preds = null;
@@ -718,17 +804,17 @@ namespace VC
TraceNode t0 =null;
Block firstpred = preds[0];
- assert firstpred!=null;
+ Contract.Assert( firstpred!=null);
if (blockmap.TryGetValue(firstpred, out t0)) {
- assert t0 !=null;
+ Contract.Assert( t0 !=null);
tn.Unavoidables.AddRange(t0.Unavoidables);
}
- foreach (Block! b0 in preds) {
+ foreach (Block b0 in preds) {Contract.Assert(b0 != null);
TraceNode t = null;
if (blockmap.TryGetValue(b0, out t)) {
- assert t!=null;
+ Contract.Assert( t!=null);
tn.Successors.Add(t);
IntersectUnavoidables(t,tn);
if (!t.Predecessors.Contains(tn)) t.Predecessors.Add(tn);
@@ -740,12 +826,13 @@ namespace VC
tn.Unavoidables.Add(tn);
} else
{
- assert false;
+ Contract.Assert(false);throw new cce.UnreachableException();
}
blockmap.Add(currentBlock, tn);
- if (currentBlock.Predecessors.Length>0) {
- foreach (Block! b0 in currentBlock.Predecessors) {
+ if (currentBlock.Predecessors.Length>0) {
+ foreach (Block b0 in currentBlock.Predecessors) {
+ Contract.Assert(b0 != null);
if (!JobList.Contains(b0) && !DoneList.Contains(b0) )
JobList.Add(b0);
}
@@ -755,19 +842,21 @@ namespace VC
}
}
- private void IntersectUnavoidables(TraceNode! parent, TraceNode! child) {
- List<TraceNode!>! ret = new List<TraceNode!>();
- List<TraceNode!>! tmp = new List<TraceNode!>();
+ private void IntersectUnavoidables(TraceNode parent, TraceNode child) {
+ Contract.Requires(parent != null);
+ Contract.Requires(child != null);
+ List<TraceNode/*!*/>/*!*/ ret = new List<TraceNode>();
+ List<TraceNode/*!*/>/*!*/ tmp = new List<TraceNode>();
tmp.AddRange(parent.Unavoidables);
tmp.AddRange(child.Unavoidables);
- foreach (TraceNode! tn in tmp) {
+ foreach (TraceNode tn in tmp) {Contract.Assert(tn != null);
if (parent.Unavoidables.Contains(tn) && child.Unavoidables.Contains(tn)
&& !ret.Contains(tn) ) {
ret.Add(tn);
}
}
- assert ret.Count <= parent.Unavoidables.Count && ret.Count <= child.Unavoidables.Count;
+ Contract.Assert( ret.Count <= parent.Unavoidables.Count && ret.Count <= child.Unavoidables.Count);
child.Unavoidables = ret;
}
@@ -776,13 +865,21 @@ namespace VC
// We assume that the program is already loopfree, otherwise we will
// not terminate
private class TraceNode {
- public List<TraceNode!>! Predecessors = new List<TraceNode!>();
- public List<TraceNode!>! Successors = new List<TraceNode!>();
- public List<TraceNode!>! Unavoidables = new List<TraceNode!>();
- public Block! block;
-
-
- public TraceNode(Block! b) {
+ public List<TraceNode/*!*/>/*!*/ Predecessors = new List<TraceNode>();
+ public List<TraceNode/*!*/>/*!*/ Successors = new List<TraceNode>();
+ public List<TraceNode/*!*/>/*!*/ Unavoidables = new List<TraceNode>();
+ public Block/*!*/ block;
+
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(block != null);
+ Contract.Invariant(cce.NonNullElements(Predecessors));
+ Contract.Invariant(cce.NonNullElements(Successors));
+ Contract.Invariant(cce.NonNullElements(Unavoidables));
+ }
+
+ public TraceNode(Block b) {
+ Contract.Requires(b != null);
block=b;
}
diff --git a/Source/VCGeneration/DoomErrorHandler.cs b/Source/VCGeneration/DoomErrorHandler.cs
index 860f5334..010fce95 100644
--- a/Source/VCGeneration/DoomErrorHandler.cs
+++ b/Source/VCGeneration/DoomErrorHandler.cs
@@ -7,7 +7,7 @@ using System.IO;
using Microsoft.Boogie;
using Graphing;
using AI = Microsoft.AbstractInterpretationFramework;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Basetypes;
using Microsoft.Boogie.VCExprAST;
@@ -15,49 +15,74 @@ namespace VC
{
internal class DoomErrorHandler : ProverInterface.ErrorHandler {
- protected Hashtable! label2Absy;
- protected VerifierCallback! callback;
-
+ protected Hashtable label2Absy;
+ protected VerifierCallback callback;
+ private List<Block> m_CurrentTrace = new List<Block>();
public Variable m_Reachvar;
- public List<Block!> m_DoomedBlocks, m_TraceBlocks;
+ public List<Block> m_DoomedBlocks, m_TraceBlocks;
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(label2Absy!=null);
+ Contract.Invariant(callback != null);
+ Contract.Invariant(cce.NonNullElements(m_CurrentTrace));
+ Contract.Invariant(m_Reachvar != null);
+ Contract.Invariant(m_DoomedBlocks != null);
+ Contract.Invariant(m_TraceBlocks != null);
+}
+
- public DoomErrorHandler(Hashtable! label2Absy, VerifierCallback! callback) {
+ public DoomErrorHandler(Hashtable label2Absy, VerifierCallback callback) {
+ Contract.Requires(label2Absy != null);
+ Contract.Requires(callback != null);
this.label2Absy = label2Absy;
this.callback = callback;
}
- public override Absy! Label2Absy(string! label) {
+ public override Absy Label2Absy(string label) {
+ Contract.Requires(label != null);
+ Contract.Ensures(Contract.Result<Absy>() != null);
+
int id = int.Parse(label);
- return (Absy!) label2Absy[id];
+ return cce.NonNull((Absy) label2Absy[id]);
}
- public override void OnProverWarning(string! msg) {
+ public override void OnProverWarning(string msg) {
+ Contract.Requires(msg != null);
this.callback.OnWarning(msg);
}
- public void OnDoom(Variable! reachvar, List<Block!>! doomedblocks, List<Block!>! traceblocks) {
+ public void OnDoom(Variable reachvar, List<Block>/*!>!*/ doomedblocks, List<Block>/*!>!*/ traceblocks) {
+ Contract.Requires(reachvar != null);
+ Contract.Requires(cce.NonNullElements(doomedblocks));
+ Contract.Requires(cce.NonNullElements(traceblocks));
m_Reachvar = reachvar;
m_DoomedBlocks = doomedblocks;
m_TraceBlocks = traceblocks;
}
- private List<Block!>! m_CurrentTrace = new List<Block!>();
- public List<Block!>! TraceNodes
+
+ public List<Block>/*!>!*/ TraceNodes
{
get
{
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>()));
+
return m_CurrentTrace;
}
}
- public override void OnModel(IList<string!>! labels, ErrorModel errModel) {
+ public override void OnModel(IList<string>/*!>!*/ labels, ErrorModel errModel) {
+ Contract.Requires(labels != null);
+
m_CurrentTrace.Clear();
//Console.Write("Used Blocks: ");
- List<Block!> traceNodes = new List<Block!>();
- List<AssertCmd!> assertNodes = new List<AssertCmd!>();
- foreach (string! s in labels) {
+ List<Block> traceNodes = new List<Block>();
+ List<AssertCmd> assertNodes = new List<AssertCmd>();
+ foreach (string s in labels) {
+ Contract.Assert(s != null);
Absy node = Label2Absy(s);
if (node is Block) {
Block b = (Block)node;
diff --git a/Source/VCGeneration/OrderingAxioms.cs b/Source/VCGeneration/OrderingAxioms.cs
index e4fc54f8..877fba13 100644
--- a/Source/VCGeneration/OrderingAxioms.cs
+++ b/Source/VCGeneration/OrderingAxioms.cs
@@ -7,7 +7,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Boogie.VCExprAST;
// Class for constructing and collecting the axioms of the partial
@@ -17,81 +17,95 @@ using Microsoft.Boogie.VCExprAST;
// TODO: there should be an interface so that different ways to handle
// ordering relations can be accessed uniformly
-namespace Microsoft.Boogie
-{
+namespace Microsoft.Boogie {
public class OrderingAxiomBuilder {
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(Gen != null);
+ Contract.Invariant(Translator != null);
+ Contract.Invariant(cce.NonNullElements(OneStepFuns));
+ Contract.Invariant(cce.NonNullElements(Constants));
+ Contract.Invariant(cce.NonNullElements(CompleteConstantsOpen));
+ Contract.Invariant(cce.NonNullElements(AllAxioms));
+ Contract.Invariant(cce.NonNullElements(IncAxioms));
+ }
+
+
+ private readonly VCExpressionGenerator Gen;
+ private readonly Boogie2VCExprTranslator Translator;
+ private readonly IDictionary<Type, Function> OneStepFuns;
+ private readonly List<Constant> Constants = new List<Constant>();
+
+ // A list to handle constants whose direct children are fully
+ // specified (the "complete" keyword). Constants are removed from
+ // the list as soon as the corresponding axiom has been generated,
+ // which means that from this point on no further children can be
+ // added
+ private readonly List<Constant> CompleteConstantsOpen = new List<Constant>();
- private readonly VCExpressionGenerator! Gen;
- private readonly Boogie2VCExprTranslator! Translator;
+ // list in which all axioms are collected
+ private readonly List<VCExpr> AllAxioms = new List<VCExpr>();
+
+ // list in which axioms are incrementally collected
+ private readonly List<VCExpr> IncAxioms = new List<VCExpr>();
- public OrderingAxiomBuilder(VCExpressionGenerator! gen,
- Boogie2VCExprTranslator! translator) {
+
+ public OrderingAxiomBuilder(VCExpressionGenerator gen,
+ Boogie2VCExprTranslator translator) {
+ Contract.Requires(gen != null);
+ Contract.Requires(translator != null);
this.Gen = gen;
this.Translator = translator;
- OneStepFuns = new Dictionary<Type!, Function!> ();
- Constants = new List<Constant!> ();
- CompleteConstantsOpen = new List<Constant!> ();
- AllAxioms = new List<VCExpr!> ();
- IncAxioms = new List<VCExpr!> ();
+ OneStepFuns = new Dictionary<Type, Function>();
+ Constants = new List<Constant>();
+ CompleteConstantsOpen = new List<Constant>();
+ AllAxioms = new List<VCExpr>();
+ IncAxioms = new List<VCExpr>();
}
- public OrderingAxiomBuilder(VCExpressionGenerator! gen,
- Boogie2VCExprTranslator! translator,
- OrderingAxiomBuilder! builder) {
+ public OrderingAxiomBuilder(VCExpressionGenerator gen,
+ Boogie2VCExprTranslator translator,
+ OrderingAxiomBuilder builder) {
+ Contract.Requires(gen != null);
+ Contract.Requires(translator != null);
+ Contract.Requires(builder != null);
this.Gen = gen;
this.Translator = translator;
- OneStepFuns = new Dictionary<Type!, Function!> (builder.OneStepFuns);
- Constants = new List<Constant!> (builder.Constants);
- CompleteConstantsOpen = new List<Constant!> (builder.CompleteConstantsOpen);
- AllAxioms = new List<VCExpr!> (builder.AllAxioms);
- IncAxioms = new List<VCExpr!> (builder.IncAxioms);
+ OneStepFuns = new Dictionary<Type, Function>(builder.OneStepFuns);
+ Constants = new List<Constant>(builder.Constants);
+ CompleteConstantsOpen = new List<Constant>(builder.CompleteConstantsOpen);
+ AllAxioms = new List<VCExpr>(builder.AllAxioms);
+ IncAxioms = new List<VCExpr>(builder.IncAxioms);
}
////////////////////////////////////////////////////////////////////////////
// Used to axiomatise the disjoint-sub-dag specs that are
// described by parents with the "unique" flag
- private readonly IDictionary<Type!, Function!>! OneStepFuns;
- private Function! OneStepFunFor(Type! t) {
+
+ private Function OneStepFunFor(Type t) {
+ Contract.Requires(t != null);
+ Contract.Ensures(Contract.Result<Function>() != null);
+
Function res;
if (!OneStepFuns.TryGetValue(t, out res)) {
- VariableSeq! args = new VariableSeq ();
- args.Add(new Formal (Token.NoToken,
- new TypedIdent (Token.NoToken, "arg0", t),
- true));
- args.Add(new Formal (Token.NoToken,
- new TypedIdent (Token.NoToken, "arg1", t),
- true));
- Formal! result = new Formal (Token.NoToken,
- new TypedIdent (Token.NoToken, "res", t),
- false);
- res = new Function (Token.NoToken, "oneStep",
- new TypeVariableSeq (), args, result);
+ VariableSeq args = new VariableSeq();
+ args.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "arg0", t), true));
+ args.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "arg1", t), true));
+ Formal result = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "res", t), false);
+ res = new Function(Token.NoToken, "oneStep", new TypeVariableSeq(), args, result);
OneStepFuns.Add(t, res);
}
- return (!)res;
+ return cce.NonNull(res);
}
////////////////////////////////////////////////////////////////////////////
- private readonly List<Constant!>! Constants = new List<Constant!> ();
-
- // A list to handle constants whose direct children are fully
- // specified (the "complete" keyword). Constants are removed from
- // the list as soon as the corresponding axiom has been generated,
- // which means that from this point on no further children can be
- // added
- private readonly List<Constant!>! CompleteConstantsOpen = new List<Constant!> ();
-
- // list in which all axioms are collected
- private readonly List<VCExpr!>! AllAxioms = new List<VCExpr!> ();
- // list in which axioms are incrementally collected
- private readonly List<VCExpr!>! IncAxioms = new List<VCExpr!> ();
-
- private void AddAxiom(VCExpr! axiom) {
+ private void AddAxiom(VCExpr axiom) {
+ Contract.Requires(axiom != null);
if (axiom.Equals(VCExpressionGenerator.True))
return;
AllAxioms.Add(axiom);
@@ -100,67 +114,82 @@ namespace Microsoft.Boogie
// Return all axioms that were added since the last time NewAxioms
// was called
- public VCExpr! GetNewAxioms() {
+ public VCExpr GetNewAxioms() {
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
CloseChildrenCompleteConstants();
- VCExpr! res = Gen.NAry(VCExpressionGenerator.AndOp, IncAxioms);
+ VCExpr res = Gen.NAry(VCExpressionGenerator.AndOp, IncAxioms);
IncAxioms.Clear();
return res;
}
// return all axioms
- public VCExpr! Axioms { get {
- CloseChildrenCompleteConstants();
- return Gen.NAry(VCExpressionGenerator.AndOp, AllAxioms);
- } }
+ public VCExpr Axioms {
+ get {
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ CloseChildrenCompleteConstants();
+ return Gen.NAry(VCExpressionGenerator.AndOp, AllAxioms);
+ }
+ }
////////////////////////////////////////////////////////////////////////////
-
+
// Generate the normal axioms for a partial order relation
public void Setup() {
- TypeVariable! alpha = new TypeVariable(Token.NoToken, "alpha");
- List<TypeVariable!>! typeParams = new List<TypeVariable!> ();
+ TypeVariable alpha = new TypeVariable(Token.NoToken, "alpha");
+ Contract.Assert(alpha != null);
+ List<TypeVariable> typeParams = new List<TypeVariable>();
typeParams.Add(alpha);
- List<VCTrigger!>! triggers = new List<VCTrigger!> ();
+ List<VCTrigger> triggers = new List<VCTrigger>();
+
+ VCExprVar x = Gen.Variable("x", alpha);
+ Contract.Assert(x != null);
+ VCExprVar y = Gen.Variable("y", alpha);
+ Contract.Assert(y != null);
+ VCExprVar z = Gen.Variable("z", alpha);
+ Contract.Assert(z != null);
- VCExprVar! x = Gen.Variable("x", alpha);
- VCExprVar! y = Gen.Variable("y", alpha);
- VCExprVar! z = Gen.Variable("z", alpha);
-
- List<VCExprVar!>! boundVars = new List<VCExprVar!> ();
+ List<VCExprVar> boundVars = new List<VCExprVar>();
// reflexivity
boundVars.Add(x);
AddAxiom(Gen.Forall(typeParams, boundVars, triggers,
- new VCQuantifierInfos ("bg:subtype-refl", -1, false, null),
+ new VCQuantifierInfos("bg:subtype-refl", -1, false, null),
Gen.AtMost(x, x)));
// transitivity
- boundVars = new List<VCExprVar!> ();
- boundVars.Add(x); boundVars.Add(y); boundVars.Add(z);
- triggers = new List<VCTrigger!> ();
+ boundVars = new List<VCExprVar>();
+ boundVars.Add(x);
+ boundVars.Add(y);
+ boundVars.Add(z);
+ triggers = new List<VCTrigger>();
triggers.Add(Gen.Trigger(true, Gen.AtMost(x, y), Gen.AtMost(y, z)));
- VCExpr! body = Gen.Implies(Gen.And(Gen.AtMost(x, y), Gen.AtMost(y, z)),
+ VCExpr body = Gen.Implies(Gen.And(Gen.AtMost(x, y), Gen.AtMost(y, z)),
Gen.AtMost(x, z));
+ Contract.Assert(body != null);
AddAxiom(Gen.Forall(typeParams, boundVars, triggers,
- new VCQuantifierInfos ("bg:subtype-trans", -1, false, null),
+ new VCQuantifierInfos("bg:subtype-trans", -1, false, null),
body));
// anti-symmetry
- boundVars = new List<VCExprVar!> ();
- boundVars.Add(x); boundVars.Add(y);
- triggers = new List<VCTrigger!> ();
+ boundVars = new List<VCExprVar>();
+ boundVars.Add(x);
+ boundVars.Add(y);
+ triggers = new List<VCTrigger>();
triggers.Add(Gen.Trigger(true, Gen.AtMost(x, y), Gen.AtMost(y, x)));
body = Gen.Implies(Gen.And(Gen.AtMost(x, y), Gen.AtMost(y, x)),
Gen.Eq(x, y));
AddAxiom(Gen.Forall(typeParams, boundVars, triggers,
- new VCQuantifierInfos ("bg:subtype-antisymm", -1, false, null),
+ new VCQuantifierInfos("bg:subtype-antisymm", -1, false, null),
body));
}
-
+
////////////////////////////////////////////////////////////////////////////
- public void AddConstant(Constant! c) {
+ public void AddConstant(Constant c) {
+ Contract.Requires(c != null);
AddAxiom(GenParentConstraints(c));
Constants.Add(c);
if (c.ChildrenComplete)
@@ -168,39 +197,45 @@ namespace Microsoft.Boogie
// ensure that no further children are added to closed
// children-complete constants
- assert !(c.Parents != null &&
- exists{ConstantParent! p in c.Parents;
- ((Constant!)p.Parent.Decl).ChildrenComplete &&
- !CompleteConstantsOpen.Contains((Constant)p.Parent.Decl)});
+ Contract.Assert(!(c.Parents != null && Contract.Exists(c.Parents, p => cce.NonNull((Constant)p.Parent.Decl).ChildrenComplete && !CompleteConstantsOpen.Contains((Constant)p.Parent.Decl))));
}
// Generate the constraints telling that parents of a constant are
// strictly greater than the constant itself, and are the minimal
// elements with this property
- private VCExpr! GenParentConstraints(Constant! c) {
- VCExpr! res = VCExpressionGenerator.True;
+ private VCExpr GenParentConstraints(Constant c) {
+ Contract.Requires(c != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpr res = VCExpressionGenerator.True;
if (c.Parents == null)
return res;
- VCExprVar! cAsVar = Translator.LookupVariable(c);
- VCExprVar! w = Gen.Variable("w", c.TypedIdent.Type);
+ VCExprVar cAsVar = Translator.LookupVariable(c);
+ VCExprVar w = Gen.Variable("w", c.TypedIdent.Type);
// Parents of c are proper ancestors of c
- foreach (ConstantParent! p in c.Parents) {
- VCExprVar! par = Translator.LookupVariable((!)p.Parent.Decl);
+ foreach (ConstantParent p in c.Parents) {
+ Contract.Assert(p != null);
+ VCExprVar par = Translator.LookupVariable(cce.NonNull(p.Parent.Decl));
res = Gen.AndSimp(res, Gen.Neq(cAsVar, par));
res = Gen.AndSimp(res, Gen.AtMost(cAsVar, par));
- }
+ }
// Parents are direct ancestors of c (no other elements are in
// between c and a parent)
- foreach (ConstantParent! p in c.Parents) {
- VCExprVar! par = Translator.LookupVariable((!)p.Parent.Decl);
- VCExpr! antecedent1 = Gen.AtMost(cAsVar, w);
- VCExpr! antecedent2 = Gen.AtMost(w, par);
- VCExpr! body = Gen.Implies(Gen.And(antecedent1, antecedent2),
+ foreach (ConstantParent p in c.Parents) {
+ Contract.Assert(p != null);
+ VCExprVar par = Translator.LookupVariable(cce.NonNull(p.Parent.Decl));
+ Contract.Assert(par != null);
+ VCExpr antecedent1 = Gen.AtMost(cAsVar, w);
+ Contract.Assert(antecedent1 != null);
+ VCExpr antecedent2 = Gen.AtMost(w, par);
+ Contract.Assert(antecedent2 != null);
+ VCExpr body = Gen.Implies(Gen.And(antecedent1, antecedent2),
Gen.Or(Gen.Eq(cAsVar, w), Gen.Eq(par, w)));
+ Contract.Assert(body != null);
res = Gen.AndSimp(res,
Gen.Forall(w,
Gen.Trigger(true, antecedent1, antecedent2),
@@ -209,24 +244,28 @@ namespace Microsoft.Boogie
// Ancestors of c are only c itself and the ancestors of the
// parents of c
- VCExpr! minAncestors = Gen.Eq(cAsVar, w);
- foreach (ConstantParent! p in c.Parents)
+ VCExpr minAncestors = Gen.Eq(cAsVar, w);
+ Contract.Assert(minAncestors != null);
+ foreach (ConstantParent p in c.Parents) {
+ Contract.Assert(p != null);
minAncestors =
Gen.Or(minAncestors,
- Gen.AtMost(Translator.LookupVariable((!)p.Parent.Decl), w));
-
- VCExpr! antecedent = Gen.AtMost(cAsVar, w);
+ Gen.AtMost(Translator.LookupVariable(cce.NonNull(p.Parent.Decl)), w));
+ }
+ VCExpr antecedent = Gen.AtMost(cAsVar, w);
+ Contract.Assert(antecedent != null);
res = Gen.AndSimp(res,
Gen.Forall(w,
Gen.Trigger(true, antecedent),
Gen.Implies(antecedent, minAncestors)));
// Constraints for unique child-parent edges
- foreach (ConstantParent! p in c.Parents) {
+ foreach (ConstantParent p in c.Parents) {
+ Contract.Assert(p != null);
if (p.Unique)
res =
Gen.AndSimp(res,
- GenUniqueParentConstraint(c, (Constant!)p.Parent.Decl));
+ GenUniqueParentConstraint(c, cce.NonNull((Constant)p.Parent.Decl)));
}
return res;
@@ -235,45 +274,58 @@ namespace Microsoft.Boogie
// Generate axioms that state that all direct children of c are
// specified; this is the dual of the axiom stating that all direct
// ancestors of a constant are known
- private VCExpr! GenCompleteChildrenConstraints(Constant! c)
- requires c.ChildrenComplete; {
-
- VCExprVar! cAsVar = Translator.LookupVariable(c);
- VCExprVar! w = Gen.Variable("w", c.TypedIdent.Type);
-
- VCExpr! maxDescendants = Gen.Eq(cAsVar, w);
- foreach (Constant! d in Constants) {
- if (d.Parents != null &&
- exists{ConstantParent! p in d.Parents; c.Equals(p.Parent.Decl)})
+ private VCExpr GenCompleteChildrenConstraints(Constant c) {
+ Contract.Requires(c != null);
+ Contract.Requires(c.ChildrenComplete);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+
+ VCExprVar cAsVar = Translator.LookupVariable(c);
+ VCExprVar w = Gen.Variable("w", c.TypedIdent.Type);
+
+ VCExpr maxDescendants = Gen.Eq(cAsVar, w);
+ foreach (Constant d in Constants) {
+ Contract.Assert(d != null);
+ if (d.Parents != null && Contract.Exists(d.Parents, p => c.Equals(p.Parent.Decl)))
maxDescendants = Gen.Or(maxDescendants,
Gen.AtMost(w, Translator.LookupVariable(d)));
}
- VCExpr! antecedent = Gen.AtMost(w, cAsVar);
+ VCExpr antecedent = Gen.AtMost(w, cAsVar);
+ Contract.Assert(antecedent != null);
return Gen.Forall(w,
Gen.Trigger(true, antecedent),
Gen.Implies(antecedent, maxDescendants));
}
-
+
private void CloseChildrenCompleteConstants() {
- foreach (Constant! c in CompleteConstantsOpen)
+ foreach (Constant c in CompleteConstantsOpen) {
+ Contract.Assert(c != null);
AddAxiom(GenCompleteChildrenConstraints(c));
+ }
CompleteConstantsOpen.Clear();
}
// Generate the axiom ensuring that the sub-dags underneath unique
// child-parent edges are all disjoint
- private VCExpr! GenUniqueParentConstraint(Constant! child, Constant! parent)
- requires child.TypedIdent.Type.Equals(parent.TypedIdent.Type); {
+ private VCExpr GenUniqueParentConstraint(Constant child, Constant parent) {
+ Contract.Requires(child != null);
+ Contract.Requires(parent != null);
+ Contract.Requires(child.TypedIdent.Type.Equals(parent.TypedIdent.Type));
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
- VCExprVar! w = Gen.Variable("w", child.TypedIdent.Type);
- VCExpr! antecedent =
+ VCExprVar w = Gen.Variable("w", child.TypedIdent.Type);
+ Contract.Assert(w != null);
+ VCExpr antecedent =
Gen.AtMost(w, Translator.LookupVariable(child));
- VCExpr! succedent =
+ Contract.Assert(antecedent != null);
+ VCExpr succedent =
Gen.Eq(Gen.Function(OneStepFunFor(child.TypedIdent.Type),
Translator.LookupVariable(parent), w),
Translator.LookupVariable(child));
+ Contract.Assert(succedent != null);
return Gen.Forall(w,
Gen.Trigger(true, antecedent),
diff --git a/Source/VCGeneration/VC.cs b/Source/VCGeneration/VC.cs
index 0f42939d..36e9d40e 100644
--- a/Source/VCGeneration/VC.cs
+++ b/Source/VCGeneration/VC.cs
@@ -12,47 +12,47 @@ using System.IO;
using Microsoft.Boogie;
using Graphing;
using AI = Microsoft.AbstractInterpretationFramework;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Basetypes;
using Microsoft.Boogie.VCExprAST;
-namespace VC
-{
+namespace VC {
using Bpl = Microsoft.Boogie;
-
- public class VCGen : ConditionGeneration
- {
+
+ public class VCGen : ConditionGeneration {
/// <summary>
/// Constructor. Initializes the theorem prover.
/// </summary>
[NotDelayed]
- public VCGen(Program! program, string/*?*/ logFilePath, bool appendLogFile)
+ public VCGen(Program program, string/*?*/ logFilePath, bool appendLogFile)
+ : base(program)
// throws ProverException
{
+ Contract.Requires(program != null);
this.appendLogFile = appendLogFile;
this.logFilePath = logFilePath;
- implName2LazyInliningInfo = new Dictionary<string!, LazyInliningInfo!>();
- implName2StratifiedInliningInfo = new Dictionary<string!, StratifiedInliningInfo!>();
- base(program);
- if (CommandLineOptions.Clo.LazyInlining > 0)
- {
+ implName2LazyInliningInfo = new Dictionary<string, LazyInliningInfo>();
+ implName2StratifiedInliningInfo = new Dictionary<string, StratifiedInliningInfo>();
+
+ if (CommandLineOptions.Clo.LazyInlining > 0) {
this.GenerateVCsForLazyInlining(program);
}
- if (CommandLineOptions.Clo.StratifiedInlining > 0)
- {
-
+ if (CommandLineOptions.Clo.StratifiedInlining > 0) {
+
this.GenerateVCsForStratifiedInlining(program);
-
+
}
// base();
}
- private static AssumeCmd! AssertTurnedIntoAssume(AssertCmd! assrt)
- {
- Expr! expr = assrt.Expr;
+ private static AssumeCmd AssertTurnedIntoAssume(AssertCmd assrt) {
+ Contract.Requires(assrt != null);
+ Contract.Ensures(Contract.Result<AssumeCmd>() != null);
+ Expr expr = assrt.Expr;
+ Contract.Assert(expr != null);
switch (Wlp.Subsumption(assrt)) {
case CommandLineOptions.SubsumptionOption.Never:
expr = Expr.True;
@@ -65,233 +65,274 @@ namespace VC
}
break;
default:
- assert false; // unexpected case
+ Contract.Assert(false);
+ throw new cce.UnreachableException(); // unexpected case
}
return new AssumeCmd(assrt.tok, expr);
}
-
+
#region LazyInlining
public class LazyInliningInfo {
- public Implementation! impl;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(impl != null);
+ Contract.Invariant(function != null);
+ Contract.Invariant(controlFlowVariable != null);
+ Contract.Invariant(assertExpr != null);
+ Contract.Invariant(cce.NonNullElements(interfaceVars));
+ Contract.Invariant(cce.NonNullElements(incarnationOriginMap));
+ }
+
+ public Implementation impl;
public int uniqueId;
- public Function! function;
- public Variable! controlFlowVariable;
- public List<Variable!>! interfaceVars;
- public Expr! assertExpr;
+ public Function function;
+ public Variable controlFlowVariable;
+ public List<Variable> interfaceVars;
+ public Expr assertExpr;
public VCExpr vcexpr;
- public Dictionary<Incarnation, Absy!> incarnationOriginMap;
+ public Dictionary<Incarnation, Absy> incarnationOriginMap;
public Hashtable /*Variable->Expr*/ exitIncarnationMap;
public Hashtable /*GotoCmd->returnCmd*/ gotoCmdOrigins;
public Hashtable/*<int, Absy!>*/ label2absy;
-
- public LazyInliningInfo(Implementation! impl, Program! program, int uniqueId)
- {
+
+ public LazyInliningInfo(Implementation impl, Program program, int uniqueId) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
this.impl = impl;
this.uniqueId = uniqueId;
this.controlFlowVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "cfc", Microsoft.Boogie.Type.Int));
-
- Procedure! proc = (!)impl.Proc;
- List<Variable!>! interfaceVars = new List<Variable!>();
- Expr! assertExpr = new LiteralExpr(Token.NoToken, true);
- foreach (Variable! v in program.GlobalVariables())
- {
+
+ Procedure proc = cce.NonNull(impl.Proc);
+ List<Variable> interfaceVars = new List<Variable>();
+ Expr assertExpr = new LiteralExpr(Token.NoToken, true);
+ Contract.Assert(assertExpr != null);
+ foreach (Variable v in program.GlobalVariables()) {
+ Contract.Assert(v != null);
interfaceVars.Add(v);
}
// InParams must be obtained from impl and not proc
- foreach (Variable! v in impl.InParams)
- {
+ foreach (Variable v in impl.InParams) {
+ Contract.Assert(v != null);
interfaceVars.Add(v);
}
// OutParams must be obtained from impl and not proc
- foreach (Variable! v in impl.OutParams)
- {
- Constant c = new Constant(Token.NoToken,
+ foreach (Variable v in impl.OutParams) {
+ Contract.Assert(v != null);
+ Constant c = new Constant(Token.NoToken,
new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
interfaceVars.Add(c);
- Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
+ Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
assertExpr = Expr.And(assertExpr, eqExpr);
}
- foreach (IdentifierExpr! e in proc.Modifies)
- {
- if (e.Decl == null) continue;
- Variable! v = e.Decl;
- Constant c = new Constant(Token.NoToken,
+ foreach (IdentifierExpr e in proc.Modifies) {
+ Contract.Assert(e != null);
+ if (e.Decl == null)
+ continue;
+ Variable v = e.Decl;
+ Constant c = new Constant(Token.NoToken,
new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
interfaceVars.Add(c);
- Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
+ Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
assertExpr = Expr.And(assertExpr, eqExpr);
}
this.interfaceVars = interfaceVars;
this.assertExpr = Expr.Not(assertExpr);
- VariableSeq! functionInterfaceVars = new VariableSeq();
- foreach (Variable! v in interfaceVars)
- {
+ VariableSeq functionInterfaceVars = new VariableSeq();
+ foreach (Variable v in interfaceVars) {
+ Contract.Assert(v != null);
functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, v.Name, v.TypedIdent.Type), true));
}
- TypedIdent! ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool);
- Formal! returnVar = new Formal(Token.NoToken, ti, false);
+ TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool);
+ Contract.Assert(ti != null);
+ Formal returnVar = new Formal(Token.NoToken, ti, false);
+ Contract.Assert(returnVar != null);
this.function = new Function(Token.NoToken, proc.Name, functionInterfaceVars, returnVar);
}
}
-
- private Dictionary<string!, LazyInliningInfo!>! implName2LazyInliningInfo;
-
- public void GenerateVCsForLazyInlining(Program! program)
- {
- Checker! checker = FindCheckerFor(null, CommandLineOptions.Clo.ProverKillTime);
- foreach (Declaration! decl in program.TopLevelDeclarations)
- {
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(implName2LazyInliningInfo));
+ Contract.Invariant(cce.NonNullElements(implName2StratifiedInliningInfo));
+ }
+
+ private Dictionary<string, LazyInliningInfo> implName2LazyInliningInfo;
+
+ public void GenerateVCsForLazyInlining(Program program) {
+ Contract.Requires(program != null);
+ Checker checker = FindCheckerFor(null, CommandLineOptions.Clo.ProverKillTime);
+ Contract.Assert(checker != null);
+ foreach (Declaration decl in program.TopLevelDeclarations) {
+ Contract.Assert(decl != null);
Implementation impl = decl as Implementation;
- if (impl == null) continue;
- Procedure! proc = (!)impl.Proc;
+ if (impl == null)
+ continue;
+ Procedure proc = cce.NonNull(impl.Proc);
if (proc.FindExprAttribute("inline") != null) {
LazyInliningInfo info = new LazyInliningInfo(impl, program, QuantifierExpr.GetNextSkolemId());
implName2LazyInliningInfo[impl.Name] = info;
impl.LocVars.Add(info.controlFlowVariable);
- ExprSeq! exprs = new ExprSeq();
- foreach (Variable! v in program.GlobalVariables())
- {
+ ExprSeq exprs = new ExprSeq();
+ foreach (Variable v in program.GlobalVariables()) {
+ Contract.Assert(v != null);
exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
}
- foreach (Variable! v in proc.InParams)
- {
+ foreach (Variable v in proc.InParams) {
+ Contract.Assert(v != null);
exprs.Add(new IdentifierExpr(Token.NoToken, v));
}
- foreach (Variable! v in proc.OutParams)
- {
- exprs.Add(new IdentifierExpr(Token.NoToken, v));
+ foreach (Variable v in proc.OutParams) {
+ Contract.Assert(v != null);
+ exprs.Add(new IdentifierExpr(Token.NoToken, v));
}
- foreach (IdentifierExpr! ie in proc.Modifies)
- {
- if (ie.Decl == null) continue;
+ foreach (IdentifierExpr ie in proc.Modifies) {
+ Contract.Assert(ie != null);
+ if (ie.Decl == null)
+ continue;
exprs.Add(ie);
}
Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs);
proc.Ensures.Add(new Ensures(true, freePostExpr));
}
}
-
- foreach (LazyInliningInfo! info in implName2LazyInliningInfo.Values)
- {
+
+ foreach (LazyInliningInfo info in implName2LazyInliningInfo.Values) {
+ Contract.Assert(info != null);
GenerateVCForLazyInlining(program, info, checker);
}
}
-
- private void GenerateVCForLazyInlining(Program! program, LazyInliningInfo! info, Checker! checker)
- requires info.impl != null;
- requires info.impl.Proc != null;
- {
- Implementation! impl = info.impl;
+
+ private void GenerateVCForLazyInlining(Program program, LazyInliningInfo info, Checker checker) {
+ Contract.Requires(program != null);
+ Contract.Requires(info != null);
+ Contract.Requires(checker != null);
+ Contract.Requires(info.impl != null);
+ Contract.Requires(info.impl.Proc != null);
+
+ Implementation impl = info.impl;
ConvertCFG2DAG(impl, program);
info.gotoCmdOrigins = PassifyImpl(impl, program);
- assert info.exitIncarnationMap != null;
- Hashtable/*<int, Absy!>*/! label2absy;
- VCExpressionGenerator! gen = checker.VCExprGen;
- VCExpr! vcexpr = gen.Not(GenerateVC(impl, info.controlFlowVariable, out label2absy, checker));
+ Contract.Assert(info.exitIncarnationMap != null);
+ Hashtable/*<int, Absy!>*/ label2absy;
+ VCExpressionGenerator gen = checker.VCExprGen;
+ Contract.Assert(gen != null);
+ VCExpr vcexpr = gen.Not(GenerateVC(impl, info.controlFlowVariable, out label2absy, checker));
+ Contract.Assert(vcexpr != null);
info.label2absy = label2absy;
-
- Boogie2VCExprTranslator! translator = checker.TheoremProver.Context.BoogieExprTranslator;
- List<VCExprVar!> privateVars = new List<VCExprVar!>();
- foreach (Variable! v in impl.LocVars)
- {
+
+ Boogie2VCExprTranslator translator = checker.TheoremProver.Context.BoogieExprTranslator;
+ Contract.Assert(translator != null);
+ List<VCExprVar> privateVars = new List<VCExprVar>();
+ foreach (Variable v in impl.LocVars) {
+ Contract.Assert(v != null);
privateVars.Add(translator.LookupVariable(v));
}
- foreach (Variable! v in impl.OutParams)
- {
+ foreach (Variable v in impl.OutParams) {
+ Contract.Assert(v != null);
privateVars.Add(translator.LookupVariable(v));
}
- if (privateVars.Count > 0)
- {
- vcexpr = gen.Exists(new List<TypeVariable!>(), privateVars, new List<VCTrigger!>(),
+ if (privateVars.Count > 0) {
+ vcexpr = gen.Exists(new List<TypeVariable>(), privateVars, new List<VCTrigger>(),
new VCQuantifierInfos(impl.Name, info.uniqueId, false, null), vcexpr);
}
-
- List<VCExprVar!> interfaceExprVars = new List<VCExprVar!>();
- List<VCExpr!> interfaceExprs = new List<VCExpr!>();
- foreach (Variable! v in info.interfaceVars)
- {
- VCExprVar! ev = translator.LookupVariable(v);
+
+ List<VCExprVar> interfaceExprVars = new List<VCExprVar>();
+ List<VCExpr> interfaceExprs = new List<VCExpr>();
+ foreach (Variable v in info.interfaceVars) {
+ Contract.Assert(v != null);
+ VCExprVar ev = translator.LookupVariable(v);
+ Contract.Assert(ev != null);
interfaceExprVars.Add(ev);
interfaceExprs.Add(ev);
}
-
- Function! function = (!)info.function;
- VCExpr! expr = gen.Function(function, interfaceExprs);
+
+ Function function = cce.NonNull(info.function);
+ VCExpr expr = gen.Function(function, interfaceExprs);
+ Contract.Assert(expr != null);
if (CommandLineOptions.Clo.LazyInlining == 1) {
vcexpr = gen.Implies(expr, vcexpr);
} else {
- assert CommandLineOptions.Clo.LazyInlining == 2;
+ Contract.Assert(CommandLineOptions.Clo.LazyInlining == 2);
vcexpr = gen.Eq(expr, vcexpr);
}
-
- List<VCTrigger!> triggers = new List<VCTrigger!>();
- List<VCExpr!> exprs = new List<VCExpr!>();
+
+ List<VCTrigger> triggers = new List<VCTrigger>();
+ List<VCExpr> exprs = new List<VCExpr>();
exprs.Add(expr);
- VCTrigger! trigger = new VCTrigger(true, exprs);
+ VCTrigger trigger = new VCTrigger(true, exprs);
+ Contract.Assert(trigger != null);
triggers.Add(trigger);
-
+
Expr e = new LiteralExpr(Token.NoToken, BigNum.FromInt(1));
- QKeyValue q = new QKeyValue(Token.NoToken, "weight", new List<object!>(new object![] { e }), null);
+ QKeyValue q = new QKeyValue(Token.NoToken, "weight", new List<object>(new object[] { e }), null);
interfaceExprVars.Reverse();
- vcexpr = gen.Forall(new List<TypeVariable!>(), interfaceExprVars, triggers,
+ vcexpr = gen.Forall(new List<TypeVariable>(), interfaceExprVars, triggers,
new VCQuantifierInfos(impl.Name, QuantifierExpr.GetNextSkolemId(), false, q), vcexpr);
-
- info.vcexpr = vcexpr;
+
+ info.vcexpr = vcexpr;
checker.TheoremProver.PushVCExpression(vcexpr);
}
#endregion
#region StratifiedInlining
- public class StratifiedInliningInfo : LazyInliningInfo
- {
+ public class StratifiedInliningInfo : LazyInliningInfo {
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(privateVars));
+ Contract.Invariant(cce.NonNullElements(interfaceExprVars));
+ Contract.Invariant(cce.NonNullElements(interfaceExprVars));
+ }
+
public int inline_cnt;
- public List<VCExprVar!>! privateVars;
- public List<VCExprVar!>! interfaceExprVars;
+ public List<VCExprVar> privateVars;
+ public List<VCExprVar> interfaceExprVars;
public VCExpr funcExpr;
public VCExpr falseExpr;
-
- public StratifiedInliningInfo(Implementation! impl, Program! program, int uniqueid)
- : base(impl, program, uniqueid)
- {
- inline_cnt = 0;
- privateVars = new List<VCExprVar!>();
- interfaceExprVars = new List<VCExprVar!>();
+
+ public StratifiedInliningInfo(Implementation impl, Program program, int uniqueid)
+ : base(impl, program, uniqueid) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ inline_cnt = 0;
+ privateVars = new List<VCExprVar>();
+ interfaceExprVars = new List<VCExprVar>();
}
-
+
}
-
- private Dictionary<string!, StratifiedInliningInfo!>! implName2StratifiedInliningInfo;
-
- public void GenerateVCsForStratifiedInlining(Program! program)
- {
+
+ private Dictionary<string, StratifiedInliningInfo> implName2StratifiedInliningInfo;
+
+ public void GenerateVCsForStratifiedInlining(Program program) {
+ Contract.Requires(program != null);
//Checker! checker = FindCheckerFor(null, CommandLineOptions.Clo.ProverKillTime);
- foreach (Declaration! decl in program.TopLevelDeclarations)
- {
+ foreach (Declaration decl in program.TopLevelDeclarations) {
+ Contract.Assert(decl != null);
Implementation impl = decl as Implementation;
- if (impl == null) continue;
- Procedure! proc = (!)impl.Proc;
+ if (impl == null)
+ continue;
+ Procedure proc = cce.NonNull(impl.Proc);
if (proc.FindExprAttribute("inline") != null) {
StratifiedInliningInfo info = new StratifiedInliningInfo(impl, program, QuantifierExpr.GetNextSkolemId());
implName2StratifiedInliningInfo[impl.Name] = info;
// We don't need controlFlowVariable for stratified Inlining
//impl.LocVars.Add(info.controlFlowVariable);
- ExprSeq! exprs = new ExprSeq();
- foreach (Variable! v in program.GlobalVariables())
- {
+ ExprSeq exprs = new ExprSeq();
+ foreach (Variable v in program.GlobalVariables()) {
+ Contract.Assert(v != null);
exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
}
- foreach (Variable! v in proc.InParams)
- {
+ foreach (Variable v in proc.InParams) {
+ Contract.Assert(v != null);
exprs.Add(new IdentifierExpr(Token.NoToken, v));
}
- foreach (Variable! v in proc.OutParams)
- {
- exprs.Add(new IdentifierExpr(Token.NoToken, v));
+ foreach (Variable v in proc.OutParams) {
+ Contract.Assert(v != null);
+ exprs.Add(new IdentifierExpr(Token.NoToken, v));
}
- foreach (IdentifierExpr! ie in proc.Modifies)
- {
- if (ie.Decl == null) continue;
+ foreach (IdentifierExpr ie in proc.Modifies) {
+ Contract.Assert(ie != null);
+ if (ie.Decl == null)
+ continue;
exprs.Add(ie);
}
Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs);
@@ -300,60 +341,69 @@ namespace VC
}
}
-
- private void GenerateVCForStratifiedInlining(Program! program, StratifiedInliningInfo! info, Checker! checker)
- requires info.impl != null;
- requires info.impl.Proc != null;
- {
- Implementation! impl = info.impl;
+
+ private void GenerateVCForStratifiedInlining(Program program, StratifiedInliningInfo info, Checker checker) {
+ Contract.Requires(program != null);
+ Contract.Requires(info != null);
+ Contract.Requires(checker != null);
+ Contract.Requires(info.impl != null);
+ Contract.Requires(info.impl.Proc != null);
+ Implementation impl = info.impl;
+ Contract.Assert(impl != null);
ConvertCFG2DAG(impl, program);
info.gotoCmdOrigins = PassifyImpl(impl, program);
- assert info.exitIncarnationMap != null;
- Hashtable/*<int, Absy!>*/! label2absy;
- VCExpressionGenerator! gen = checker.VCExprGen;
- VCExpr! vcexpr = gen.Not(GenerateVC(impl, null, out label2absy, checker));
+ Contract.Assert(info.exitIncarnationMap != null);
+ Hashtable/*<int, Absy!>*/ label2absy;
+ VCExpressionGenerator gen = checker.VCExprGen;
+ Contract.Assert(gen != null);
+ VCExpr vcexpr = gen.Not(GenerateVC(impl, null, out label2absy, checker));
+ Contract.Assert(vcexpr != null);
info.label2absy = label2absy;
-
- Boogie2VCExprTranslator! translator = checker.TheoremProver.Context.BoogieExprTranslator;
- info.privateVars = new List<VCExprVar!>();
- foreach (Variable! v in impl.LocVars)
- {
+
+ Boogie2VCExprTranslator translator = checker.TheoremProver.Context.BoogieExprTranslator;
+ Contract.Assert(translator != null);
+ info.privateVars = new List<VCExprVar>();
+ foreach (Variable v in impl.LocVars) {
+ Contract.Assert(v != null);
info.privateVars.Add(translator.LookupVariable(v));
}
- foreach (Variable! v in impl.OutParams)
- {
+ foreach (Variable v in impl.OutParams) {
+ Contract.Assert(v != null);
info.privateVars.Add(translator.LookupVariable(v));
}
-
- info.interfaceExprVars = new List<VCExprVar!>();
- List<VCExpr!> interfaceExprs = new List<VCExpr!>();
- foreach (Variable! v in info.interfaceVars)
- {
- VCExprVar! ev = translator.LookupVariable(v);
+
+ info.interfaceExprVars = new List<VCExprVar>();
+ List<VCExpr> interfaceExprs = new List<VCExpr>();
+ foreach (Variable v in info.interfaceVars) {
+ Contract.Assert(v != null);
+ VCExprVar ev = translator.LookupVariable(v);
+ Contract.Assert(ev != null);
info.interfaceExprVars.Add(ev);
interfaceExprs.Add(ev);
}
-
- Function! function = (!)info.function;
+
+ Function function = cce.NonNull(info.function);
+ Contract.Assert(function != null);
info.funcExpr = gen.Function(function, interfaceExprs);
- info.vcexpr = vcexpr;
-
+ info.vcexpr = vcexpr;
+
// Build the "false" expression: forall a b c: foo(a,b,c) <==> false
-
+
info.falseExpr = gen.Eq(info.funcExpr, VCExpressionGenerator.False);
-
- List<VCTrigger!> triggers = new List<VCTrigger!>();
- List<VCExpr!> exprs = new List<VCExpr!>();
+
+ List<VCTrigger> triggers = new List<VCTrigger>();
+ List<VCExpr> exprs = new List<VCExpr>();
exprs.Add(info.funcExpr);
- VCTrigger! trigger = new VCTrigger(true, exprs);
+ VCTrigger trigger = new VCTrigger(true, exprs);
+ Contract.Assert(trigger != null);
triggers.Add(trigger);
-
+
Expr e = new LiteralExpr(Token.NoToken, BigNum.FromInt(1));
- QKeyValue q = new QKeyValue(Token.NoToken, "weight", new List<object!>(new object![] { e }), null);
+ QKeyValue q = new QKeyValue(Token.NoToken, "weight", new List<object>(new object[] { e }), null);
//info.interfaceExprVars.Reverse();
- info.falseExpr = gen.Forall(new List<TypeVariable!>(), info.interfaceExprVars, triggers,
+ info.falseExpr = gen.Forall(new List<TypeVariable>(), info.interfaceExprVars, triggers,
new VCQuantifierInfos(impl.Name, QuantifierExpr.GetNextSkolemId(), false, q), info.falseExpr);
-
+
//checker.TheoremProver.PushVCExpression(vcexpr);
/*
Console.WriteLine("Procedure: {0}", info.impl.Name);
@@ -369,23 +419,36 @@ namespace VC
Console.WriteLine();
Console.WriteLine(vcexpr.ToString());
*/
- }
+ }
#endregion
-
+
#region Soundness smoke tester
- class SmokeTester
- {
- VCGen! parent;
- Implementation! impl;
- Block! initial;
- Program! program;
+ class SmokeTester {
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(parent != null);
+ Contract.Invariant(impl != null);
+ Contract.Invariant(initial != null);
+ Contract.Invariant(program != null);
+ Contract.Invariant(cce.NonNullElements(copies));
+ Contract.Invariant(cce.NonNullElements(visited));
+ Contract.Invariant(callback != null);
+ }
+
+ VCGen parent;
+ Implementation impl;
+ Block initial;
+ Program program;
int id;
- Dictionary<Block!, Block!>! copies = new Dictionary<Block!, Block!>();
- Dictionary<Block!, bool>! visited = new Dictionary<Block!, bool>();
- VerifierCallback! callback;
-
- internal SmokeTester(VCGen! par, Implementation! i, Program! prog, VerifierCallback! callback)
- {
+ Dictionary<Block, Block> copies = new Dictionary<Block, Block>();
+ Dictionary<Block, bool> visited = new Dictionary<Block, bool>();
+ VerifierCallback callback;
+
+ internal SmokeTester(VCGen par, Implementation i, Program prog, VerifierCallback callback) {
+ Contract.Requires(par != null);
+ Contract.Requires(i != null);
+ Contract.Requires(prog != null);
+ Contract.Requires(callback != null);
parent = par;
impl = i;
initial = i.Blocks[0];
@@ -393,78 +456,80 @@ namespace VC
this.callback = callback;
}
- internal void Copy()
- {
+ internal void Copy() {
CloneBlock(impl.Blocks[0]);
initial = GetCopiedBlocks()[0];
}
- internal void Test()
- throws UnexpectedProverOutputException;
- {
+ internal void Test() {
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
+
DFS(initial);
}
- void TopologicalSortImpl()
- {
+ void TopologicalSortImpl() {
Graph<Block> dag = new Graph<Block>();
- dag.AddSource((!)impl.Blocks[0]); // there is always at least one node in the graph
- foreach (Block b in impl.Blocks)
- {
+ dag.AddSource(cce.NonNull(impl.Blocks[0])); // there is always at least one node in the graph
+ foreach (Block b in impl.Blocks) {
GotoCmd gtc = b.TransferCmd as GotoCmd;
- if (gtc != null)
- {
- assume gtc.labelTargets != null;
- foreach (Block! dest in gtc.labelTargets)
- {
- dag.AddEdge(b,dest);
+ if (gtc != null) {
+ Contract.Assume(gtc.labelTargets != null);
+ foreach (Block dest in gtc.labelTargets) {
+ Contract.Assert(dest != null);
+ dag.AddEdge(b, dest);
}
}
}
- impl.Blocks = new List<Block!>();
- foreach (Block! b in dag.TopologicalSort()) {
+ impl.Blocks = new List<Block>();
+ foreach (Block b in dag.TopologicalSort()) {
+ Contract.Assert(b != null);
impl.Blocks.Add(b);
}
}
- void Emit()
- {
+ void Emit() {
TopologicalSortImpl();
EmitImpl(impl, false);
}
// this one copies forward
- Block! CloneBlock(Block! b)
- {
+ Block CloneBlock(Block b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<Block>() != null);
+
Block fake_res;
if (copies.TryGetValue(b, out fake_res)) {
- return (!)fake_res;
+ return cce.NonNull(fake_res);
}
- Block! res;
- res = new Block(b.tok, b.Label, new CmdSeq(b.Cmds), null);
+ Block res = new Block(b.tok, b.Label, new CmdSeq(b.Cmds), null);
copies[b] = res;
if (b.TransferCmd is GotoCmd) {
- foreach (Block! ch in (!)((GotoCmd)b.TransferCmd).labelTargets) {
+ foreach (Block ch in cce.NonNull((GotoCmd)b.TransferCmd).labelTargets) {
+ Contract.Assert(ch != null);
CloneBlock(ch);
}
}
- foreach (Block! p in b.Predecessors) {
+ foreach (Block p in b.Predecessors) {
+ Contract.Assert(p != null);
res.Predecessors.Add(CloneBlock(p));
}
return res;
}
// this one copies backwards
- Block! CopyBlock(Block! b)
- {
+ Block CopyBlock(Block b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<Block>() != null);
+
Block fake_res;
if (copies.TryGetValue(b, out fake_res)) {
// fake_res should be Block! but the compiler fails
- return (!)fake_res;
+ return cce.NonNull(fake_res);
}
- Block! res;
+ Block res;
CmdSeq seq = new CmdSeq();
- foreach (Cmd! c in b.Cmds) {
+ foreach (Cmd c in b.Cmds) {
+ Contract.Assert(c != null);
AssertCmd turn = c as AssertCmd;
if (!turnAssertIntoAssumes || turn == null) {
seq.Add(c);
@@ -474,19 +539,22 @@ namespace VC
}
res = new Block(b.tok, b.Label, seq, null);
copies[b] = res;
- foreach (Block! p in b.Predecessors) {
+ foreach (Block p in b.Predecessors) {
+ Contract.Assert(p != null);
res.Predecessors.Add(CopyBlock(p));
}
return res;
}
- List<Block!>! GetCopiedBlocks()
- {
+ List<Block> GetCopiedBlocks() {
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>()));
+
// the order of nodes in res is random (except for the first one, being the entry)
- List<Block!> res = new List<Block!>();
+ List<Block> res = new List<Block>();
res.Add(copies[initial]);
- foreach (KeyValuePair<Block!,Block!> kv in copies) {
+ foreach (KeyValuePair<Block, Block> kv in copies) {
+ Contract.Assert(kv.Key != null&&kv.Value!=null);
GotoCmd go = kv.Key.TransferCmd as GotoCmd;
ReturnCmd ret = kv.Key.TransferCmd as ReturnCmd;
if (kv.Key != initial) {
@@ -495,16 +563,18 @@ namespace VC
if (go != null) {
GotoCmd copy = new GotoCmd(go.tok, new StringSeq(), new BlockSeq());
kv.Value.TransferCmd = copy;
- foreach (Block! b in (!)go.labelTargets) {
+ foreach (Block b in cce.NonNull(go.labelTargets)) {
+ Contract.Assert(b != null);
Block c;
if (copies.TryGetValue(b, out c)) {
- copy.AddTarget((!)c);
+ copy.AddTarget(cce.NonNull(c));
}
}
} else if (ret != null) {
kv.Value.TransferCmd = ret;
} else {
- assume false;
+ Contract.Assume(false);
+ throw new cce.UnreachableException();
}
}
@@ -515,28 +585,27 @@ namespace VC
// check if e is true, false, !true, !false
// if so return true and the value of the expression in val
- bool BooleanEval(Expr! e, ref bool val)
- {
+ bool BooleanEval(Expr e, ref bool val) {
+ Contract.Requires(e != null);
LiteralExpr lit = e as LiteralExpr;
NAryExpr call = e as NAryExpr;
if (lit != null && lit.isBool) {
val = lit.asBool;
return true;
- } else if (call != null &&
- call.Fun is UnaryOperator &&
+ } else if (call != null &&
+ call.Fun is UnaryOperator &&
((UnaryOperator)call.Fun).Op == UnaryOperator.Opcode.Not &&
- BooleanEval((!)call.Args[0], ref val)) {
+ BooleanEval(cce.NonNull(call.Args[0]), ref val)) {
val = !val;
return true;
- }
- // this is for the 0bv32 != 0bv32 generated by vcc
- else if (call != null &&
- call.Fun is BinaryOperator &&
+ }
+ // this is for the 0bv32 != 0bv32 generated by vcc
+ else if (call != null &&
+ call.Fun is BinaryOperator &&
((BinaryOperator)call.Fun).Op == BinaryOperator.Opcode.Neq &&
call.Args[0] is LiteralExpr &&
- ((!)call.Args[0]).Equals(call.Args[1]))
- {
+ cce.NonNull(call.Args[0]).Equals(call.Args[1])) {
val = false;
return true;
}
@@ -544,15 +613,16 @@ namespace VC
return false;
}
- bool IsFalse(Expr! e)
- {
+ bool IsFalse(Expr e) {
+ Contract.Requires(e != null);
bool val = false;
return BooleanEval(e, ref val) && !val;
}
- bool CheckUnreachable(Block! cur, CmdSeq! seq)
- throws UnexpectedProverOutputException;
- {
+ bool CheckUnreachable(Block cur, CmdSeq seq) {
+ Contract.Requires(cur != null);
+ Contract.Requires(seq != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
foreach (Cmd cmd in seq) {
AssertCmd assrt = cmd as AssertCmd;
if (assrt != null && QKeyValue.FindBoolAttribute(assrt.Attributes, "PossiblyUnreachable"))
@@ -568,9 +638,11 @@ namespace VC
Token tok = new Token();
tok.val = "soundness smoke test assertion";
seq.Add(new AssertCmd(tok, Expr.False));
- Block! copy = CopyBlock(cur);
+ Block copy = CopyBlock(cur);
+ Contract.Assert(copy != null);
copy.Cmds = seq;
- List<Block!>! backup = impl.Blocks;
+ List<Block> backup = impl.Blocks;
+ Contract.Assert(backup != null);
impl.Blocks = GetCopiedBlocks();
copy.TransferCmd = new ReturnCmd(Token.NoToken);
if (CommandLineOptions.Clo.TraceVerify) {
@@ -580,16 +652,18 @@ namespace VC
}
parent.current_impl = impl;
parent.PassifyImpl(impl, program);
- Hashtable! label2Absy;
- Checker! ch = parent.FindCheckerFor(impl, CommandLineOptions.Clo.SmokeTimeout);
- VCExpr! vc = parent.GenerateVC(impl, null, out label2Absy, ch);
+ Hashtable label2Absy;
+ Checker ch = parent.FindCheckerFor(impl, CommandLineOptions.Clo.SmokeTimeout);
+ Contract.Assert(ch != null);
+ VCExpr vc = parent.GenerateVC(impl, null, out label2Absy, ch);
+ Contract.Assert(vc != null);
impl.Blocks = backup;
if (CommandLineOptions.Clo.TraceVerify) {
System.Console.WriteLine(" --- smoke #{0}, after passify", id);
Emit();
}
- ch.BeginCheck((!) impl.Name + "_smoke" + id++, vc, new ErrorHandler(label2Absy, this.callback));
+ ch.BeginCheck(cce.NonNull(impl.Name + "_smoke" + id++), vc, new ErrorHandler(label2Absy, this.callback));
ch.ProverDone.WaitOne();
ProverInterface.Outcome outcome = ch.ReadOutcome();
parent.current_impl = null;
@@ -597,8 +671,8 @@ namespace VC
DateTime end = DateTime.Now;
TimeSpan elapsed = end - start;
if (CommandLineOptions.Clo.Trace) {
- System.Console.WriteLine(" [{0} s] {1}", elapsed.TotalSeconds,
- outcome == ProverInterface.Outcome.Valid ? "OOPS" :
+ System.Console.WriteLine(" [{0} s] {1}", elapsed.TotalSeconds,
+ outcome == ProverInterface.Outcome.Valid ? "OOPS" :
"OK" + (outcome == ProverInterface.Outcome.Invalid ? "" : " (" + outcome + ")"));
}
@@ -617,15 +691,17 @@ namespace VC
const bool turnAssertIntoAssumes = false;
- void DFS(Block! cur)
- throws UnexpectedProverOutputException;
- {
- if (visited.ContainsKey(cur)) return;
+ void DFS(Block cur) {
+ Contract.Requires(cur != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
+ if (visited.ContainsKey(cur))
+ return;
visited[cur] = true;
- CmdSeq! seq = new CmdSeq();
- foreach (Cmd! cmd_ in cur.Cmds) {
- Cmd! cmd = cmd_;
+ CmdSeq seq = new CmdSeq();
+ foreach (Cmd cmd_ in cur.Cmds) {
+ Cmd cmd = cmd_;
+ Contract.Assert(cmd != null);
AssertCmd assrt = cmd as AssertCmd;
AssumeCmd assm = cmd as AssumeCmd;
CallCmd call = cmd as CallCmd;
@@ -637,16 +713,20 @@ namespace VC
// it's clear the user expected unreachable code here
// it's not clear where did he expect it, maybe it would be right to insert
// a check just one command before
- if (IsFalse(assrt.Expr)) return;
+ if (IsFalse(assrt.Expr))
+ return;
if (turnAssertIntoAssumes) {
cmd = AssertTurnedIntoAssume(assrt);
}
} else if (assm != null) {
- if (IsFalse(assm.Expr)) assumeFalse = true;
+ if (IsFalse(assm.Expr))
+ assumeFalse = true;
} else if (call != null) {
- foreach (Ensures! e in ((!)call.Proc).Ensures) {
- if (IsFalse(e.Condition)) assumeFalse = true;
+ foreach (Ensures e in (cce.NonNull(call.Proc)).Ensures) {
+ Contract.Assert(e != null);
+ if (IsFalse(e.Condition))
+ assumeFalse = true;
}
}
@@ -658,20 +738,21 @@ namespace VC
seq.Add(cmd);
}
-
+
GotoCmd go = cur.TransferCmd as GotoCmd;
ReturnCmd ret = cur.TransferCmd as ReturnCmd;
- assume !(go!= null&&go.labelTargets==null&&go.labelNames!=null&&go.labelNames.Length>0) ;
+ Contract.Assume(!(go != null && go.labelTargets == null && go.labelNames != null && go.labelNames.Length > 0));
- if (ret != null || (go != null && ((!)go.labelTargets).Length == 0)) {
+ if (ret != null || (go != null && cce.NonNull(go.labelTargets).Length == 0)) {
// we end in return, so there will be no more places to check
CheckUnreachable(cur, seq);
} else if (go != null) {
bool needToCheck = true;
// if all of our children have more than one parent, then
// we're in the right place to check
- foreach (Block! target in (!)go.labelTargets) {
+ foreach (Block target in cce.NonNull(go.labelTargets)) {
+ Contract.Assert(target != null);
if (target.Predecessors.Length == 1) {
needToCheck = false;
}
@@ -679,91 +760,128 @@ namespace VC
if (needToCheck) {
CheckUnreachable(cur, seq);
}
- foreach (Block! target in go.labelTargets) {
+ foreach (Block target in go.labelTargets) {
+ Contract.Assert(target != null);
DFS(target);
}
}
}
-
+
class ErrorHandler : ProverInterface.ErrorHandler {
- Hashtable! label2Absy;
- VerifierCallback! callback;
-
- public ErrorHandler(Hashtable! label2Absy, VerifierCallback! callback) {
+ Hashtable label2Absy;
+ VerifierCallback callback;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(label2Absy != null);
+ Contract.Invariant(callback != null);
+ }
+
+
+ public ErrorHandler(Hashtable label2Absy, VerifierCallback callback) {
+ Contract.Requires(label2Absy != null);
+ Contract.Requires(callback != null);
this.label2Absy = label2Absy;
this.callback = callback;
}
-
- public override Absy! Label2Absy(string! label) {
+
+ public override Absy Label2Absy(string label) {
+ Contract.Requires(label != null);
+ Contract.Ensures(Contract.Result<Absy>() != null);
+
int id = int.Parse(label);
- return (Absy!) label2Absy[id];
+ return cce.NonNull((Absy)label2Absy[id]);
}
-
- public override void OnProverWarning(string! msg) {
+
+ public override void OnProverWarning(string msg) {
+ Contract.Requires(msg != null);
this.callback.OnWarning(msg);
}
}
}
-
-
+
+
#endregion
#region Splitter
- class Split
- {
+ class Split {
class BlockStats {
public bool big_block;
public int id;
public double assertion_cost;
public double assumption_cost; // before multiplier
public double incomming_paths;
- public List<Block!>! virtual_successors = new List<Block!>();
- public List<Block!>! virtual_predecesors = new List<Block!>();
- public Dictionary<Block!,bool>? reachable_blocks;
- public readonly Block! block;
+ public List<Block>/*!>!*/ virtual_successors = new List<Block>();
+ public List<Block>/*!>!*/ virtual_predecesors = new List<Block>();
+ public Dictionary<Block, bool> reachable_blocks;
+ public readonly Block block;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(virtual_successors));
+ Contract.Invariant(cce.NonNullElements(virtual_predecesors));
+ Contract.Invariant(cce.NonNullElements(reachable_blocks.Keys));
+ Contract.Invariant(block != null);
+ }
- public BlockStats(Block! b, int i)
- {
+
+ public BlockStats(Block b, int i) {
+ Contract.Requires(b != null);
block = b;
assertion_cost = -1;
id = i;
}
}
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(blocks));
+ Contract.Invariant(cce.NonNullElements(big_blocks));
+ Contract.Invariant(cce.NonNullElements(stats));
+ Contract.Invariant(cce.NonNullElements(assumized_branches));
+ Contract.Invariant(gotoCmdOrigins != null);
+ Contract.Invariant(parent != null);
+ Contract.Invariant(impl != null);
+ Contract.Invariant(copies != null);
+ Contract.Invariant(cce.NonNullElements(protected_from_assert_to_assume));
+ Contract.Invariant(cce.NonNullElements(keep_at_all));
+ }
- readonly List<Block!>! blocks;
- readonly List<Block!>! big_blocks = new List<Block!>();
- readonly Dictionary<Block!, BlockStats!>! stats = new Dictionary<Block!, BlockStats!>();
+
+ readonly List<Block> blocks;
+ readonly List<Block> big_blocks = new List<Block>();
+ readonly Dictionary<Block/*!*/, BlockStats/*!*/>/*!*/ stats = new Dictionary<Block/*!*/, BlockStats/*!*/>();
readonly int id;
static int current_id;
- Block? split_block;
+ Block split_block;
bool assert_to_assume;
- List<Block!>! assumized_branches = new List<Block!>();
- public AssertCmd? first_assert;
+ List<Block/*!*/>/*!*/ assumized_branches = new List<Block/*!*/>();
+ public AssertCmd/*?*/ first_assert;
double score;
bool score_computed;
double total_cost;
int assertion_count;
double assertion_cost; // without multiplication by paths
- Hashtable/*TransferCmd->ReturnCmd*/! gotoCmdOrigins;
- VCGen! parent;
- Implementation! impl;
+ Hashtable/*TransferCmd->ReturnCmd*//*!*/ gotoCmdOrigins;
+ VCGen/*!*/ parent;
+ Implementation/*!*/ impl;
- Dictionary<Block!, Block!>! copies = new Dictionary<Block!, Block!>();
+ Dictionary<Block/*!*/, Block/*!*/>/*!*/ copies = new Dictionary<Block/*!*/, Block/*!*/>();
bool doing_slice;
double slice_initial_limit;
double slice_limit;
bool slice_pos;
- Dictionary<Block!, bool>! protected_from_assert_to_assume = new Dictionary<Block!,bool>();
- Dictionary<Block!, bool>! keep_at_all = new Dictionary<Block!,bool>();
+ Dictionary<Block/*!*/, bool>/*!*/ protected_from_assert_to_assume = new Dictionary<Block/*!*/, bool>();
+ Dictionary<Block/*!*/, bool>/*!*/ keep_at_all = new Dictionary<Block/*!*/, bool>();
// async interface
private Checker checker;
private int splitNo;
internal ErrorReporter reporter;
- public Split(List<Block!>! blocks, Hashtable/*TransferCmd->ReturnCmd*/! gotoCmdOrigins, VCGen! par, Implementation! impl)
- {
+ public Split(List<Block/*!*/>/*!*/ blocks, Hashtable/*TransferCmd->ReturnCmd*//*!*/ gotoCmdOrigins, VCGen/*!*/ par, Implementation/*!*/ impl) {
+ Contract.Requires(cce.NonNullElements(blocks));
+ Contract.Requires(gotoCmdOrigins != null);
+ Contract.Requires(par != null);
+ Contract.Requires(impl != null);
this.blocks = blocks;
this.gotoCmdOrigins = gotoCmdOrigins;
this.parent = par;
@@ -771,51 +889,50 @@ namespace VC
this.id = current_id++;
}
- public double Cost
- {
+ public double Cost {
get {
ComputeBestSplit();
return total_cost;
}
}
- public bool LastChance
- {
+ public bool LastChance {
get {
ComputeBestSplit();
return assertion_count == 1 && score < 0;
}
}
- public string Stats
- {
+ public string Stats {
get {
ComputeBestSplit();
return string.Format("(cost:{0:0}/{1:0}{2})", total_cost, assertion_cost, LastChance ? " last" : "");
}
}
- public void DumpDot(int no)
- {
+ public void DumpDot(int no) {
using (System.IO.StreamWriter sw = System.IO.File.CreateText(string.Format("split.{0}.dot", no))) {
sw.WriteLine("digraph G {");
ComputeBestSplit();
- List<Block!> saved = assumized_branches;
- assumized_branches = new List<Block!>();
+ List<Block> saved = assumized_branches;
+ Contract.Assert(saved != null);
+ assumized_branches = new List<Block>();
DoComputeScore(false);
assumized_branches = saved;
- foreach (Block! b in big_blocks) {
+ foreach (Block b in big_blocks) {
+ Contract.Assert(b != null);
BlockStats s = GetBlockStats(b);
- foreach (Block! t in s.virtual_successors) {
+ foreach (Block t in s.virtual_successors) {
+ Contract.Assert(t != null);
sw.WriteLine("n{0} -> n{1};", s.id, GetBlockStats(t).id);
}
- sw.WriteLine("n{0} [label=\"{1}:\\n({2:0.0}+{3:0.0})*{4:0.0}\"{5}];",
- s.id, b.Label,
+ sw.WriteLine("n{0} [label=\"{1}:\\n({2:0.0}+{3:0.0})*{4:0.0}\"{5}];",
+ s.id, b.Label,
s.assertion_cost, s.assumption_cost, s.incomming_paths,
s.assertion_cost > 0 ? ",shape=box" : "");
-
+
}
sw.WriteLine("}");
sw.Close();
@@ -827,7 +944,8 @@ namespace VC
CommandLineOptions.Clo.PrintUnstructured = 2; // print only the unstructured program
bool oldPrintDesugaringSetting = CommandLineOptions.Clo.PrintDesugarings;
CommandLineOptions.Clo.PrintDesugarings = false;
- List<Block!> backup = impl.Blocks;
+ List<Block> backup = impl.Blocks;
+ Contract.Assert(backup != null);
impl.Blocks = blocks;
impl.Emit(new TokenTextWriter(filename, sw, false), 0);
impl.Blocks = backup;
@@ -837,25 +955,27 @@ namespace VC
}
int bsid;
- BlockStats! GetBlockStats(Block! b)
- {
+ BlockStats GetBlockStats(Block b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<BlockStats>() != null);
+
BlockStats s;
if (!stats.TryGetValue(b, out s)) {
s = new BlockStats(b, bsid++);
stats[b] = s;
}
- return (!)s;
+ return cce.NonNull(s);
}
- double AssertionCost(PredicateCmd c)
- {
+ double AssertionCost(PredicateCmd c) {
return 1.0;
}
- void CountAssertions(Block! b)
- {
+ void CountAssertions(Block b) {
+ Contract.Requires(b != null);
BlockStats s = GetBlockStats(b);
- if (s.assertion_cost >= 0) return; // already done
+ if (s.assertion_cost >= 0)
+ return; // already done
s.big_block = true;
s.assertion_cost = 0;
s.assumption_cost = 0;
@@ -869,14 +989,16 @@ namespace VC
s.assumption_cost += AssertionCost((AssumeCmd)c);
}
}
- foreach (Block! b in Exits(b)) {
+ foreach (Block c in Exits(b)) {
+ Contract.Assert(c != null);
s.virtual_successors.Add(b);
}
if (s.virtual_successors.Count == 1) {
Block next = s.virtual_successors[0];
BlockStats se = GetBlockStats(next);
CountAssertions(next);
- if (next.Predecessors.Length > 1 || se.virtual_successors.Count != 1) return;
+ if (next.Predecessors.Length > 1 || se.virtual_successors.Count != 1)
+ return;
s.virtual_successors[0] = se.virtual_successors[0];
s.assertion_cost += se.assertion_cost;
s.assumption_cost += se.assumption_cost;
@@ -884,49 +1006,55 @@ namespace VC
}
}
- Dictionary<Block!,bool>! ComputeReachableNodes(Block! b)
- {
+ Dictionary<Block/*!*/, bool>/*!*/ ComputeReachableNodes(Block/*!*/ b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(cce.NonNullElements(Contract.Result<Dictionary<Block, bool>>()));
BlockStats s = GetBlockStats(b);
if (s.reachable_blocks != null) {
return s.reachable_blocks;
}
- Dictionary<Block!, bool> blocks = new Dictionary<Block!, bool>();
+ Dictionary<Block/*!*/, bool> blocks = new Dictionary<Block/*!*/, bool>();
s.reachable_blocks = blocks;
blocks[b] = true;
- foreach (Block! succ in Exits(b)) {
- foreach (Block! r in ComputeReachableNodes(succ).Keys) {
+ foreach (Block/*!*/ succ in Exits(b)) {
+ Contract.Assert(succ != null);
+ foreach (Block r in ComputeReachableNodes(succ).Keys) {
+ Contract.Assert(r != null);
blocks[r] = true;
}
}
return blocks;
}
- double ProverCost(double vc_cost)
- {
+ double ProverCost(double vc_cost) {
return vc_cost * vc_cost;
}
- void ComputeBestSplit()
- {
- if (score_computed) return;
+ void ComputeBestSplit() {
+ if (score_computed)
+ return;
score_computed = true;
assertion_count = 0;
-
- foreach (Block! b in blocks) {
+
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
CountAssertions(b);
}
- foreach (Block! b in blocks) {
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
BlockStats bs = GetBlockStats(b);
if (bs.big_block) {
big_blocks.Add(b);
- foreach (Block! ch in bs.virtual_successors) {
+ foreach (Block ch in bs.virtual_successors) {
+ Contract.Assert(ch != null);
BlockStats chs = GetBlockStats(ch);
if (!chs.big_block) {
Console.WriteLine("non-big {0} accessed from {1}", ch, b);
DumpDot(-1);
- assert false;
+ Contract.Assert(false);
+ throw new cce.UnreachableException();
}
chs.virtual_predecesors.Add(b);
}
@@ -937,27 +1065,30 @@ namespace VC
total_cost = ProverCost(DoComputeScore(false));
score = double.PositiveInfinity;
- Block? best_split = null;
- List<Block!>! saved_branches = new List<Block!>();
+ Block best_split = null;
+ List<Block> saved_branches = new List<Block>();
- foreach (Block! b in big_blocks) {
+ foreach (Block b in big_blocks) {
+ Contract.Assert(b != null);
GotoCmd gt = b.TransferCmd as GotoCmd;
- if (gt == null) continue;
- BlockSeq targ = (!)gt.labelTargets;
- if (targ.Length < 2) continue;
+ if (gt == null)
+ continue;
+ BlockSeq targ = cce.NonNull(gt.labelTargets);
+ if (targ.Length < 2)
+ continue;
// caution, we only consider two first exits
double left0, right0, left1, right1;
split_block = b;
assumized_branches.Clear();
- assumized_branches.Add((!)targ[0]);
+ assumized_branches.Add(cce.NonNull(targ[0]));
left0 = DoComputeScore(true);
right0 = DoComputeScore(false);
assumized_branches.Clear();
for (int idx = 1; idx < targ.Length; idx++) {
- assumized_branches.Add((!)targ[idx]);
+ assumized_branches.Add(cce.NonNull(targ[idx]));
}
left1 = DoComputeScore(true);
right1 = DoComputeScore(false);
@@ -968,7 +1099,7 @@ namespace VC
if (other_score < current_score) {
current_score = other_score;
assumized_branches.Clear();
- assumized_branches.Add((!)targ[0]);
+ assumized_branches.Add(cce.NonNull(targ[0]));
}
if (current_score < score) {
@@ -988,14 +1119,17 @@ namespace VC
}
}
- void UpdateIncommingPaths(BlockStats! s)
- {
+ void UpdateIncommingPaths(BlockStats s) {
+ Contract.Requires(s != null);
if (s.incomming_paths < 0.0) {
int count = 0;
s.incomming_paths = 0.0;
- if (!keep_at_all.ContainsKey(s.block)) return;
- foreach (Block! b in s.virtual_predecesors) {
- BlockStats! ch = GetBlockStats(b);
+ if (!keep_at_all.ContainsKey(s.block))
+ return;
+ foreach (Block b in s.virtual_predecesors) {
+ Contract.Assert(b != null);
+ BlockStats ch = GetBlockStats(b);
+ Contract.Assert(ch != null);
UpdateIncommingPaths(ch);
if (ch.incomming_paths > 0.0) {
s.incomming_paths += ch.incomming_paths;
@@ -1008,26 +1142,30 @@ namespace VC
}
}
- void ComputeBlockSetsHelper(Block! b, bool allow_small)
- {
- if (keep_at_all.ContainsKey(b)) return;
+ void ComputeBlockSetsHelper(Block b, bool allow_small) {
+ Contract.Requires(b != null);
+ if (keep_at_all.ContainsKey(b))
+ return;
keep_at_all[b] = true;
if (allow_small) {
- foreach (Block! ch in Exits(b)) {
- if (b == split_block && assumized_branches.Contains(ch)) continue;
+ foreach (Block ch in Exits(b)) {
+ Contract.Assert(b != null);
+ if (b == split_block && assumized_branches.Contains(ch))
+ continue;
ComputeBlockSetsHelper(ch, allow_small);
}
} else {
- foreach (Block! ch in GetBlockStats(b).virtual_successors) {
- if (b == split_block && assumized_branches.Contains(ch)) continue;
+ foreach (Block ch in GetBlockStats(b).virtual_successors) {
+ Contract.Assert(ch != null);
+ if (b == split_block && assumized_branches.Contains(ch))
+ continue;
ComputeBlockSetsHelper(ch, allow_small);
}
}
}
- void ComputeBlockSets(bool allow_small)
- {
+ void ComputeBlockSets(bool allow_small) {
protected_from_assert_to_assume.Clear();
keep_at_all.Clear();
@@ -1035,14 +1173,17 @@ namespace VC
Debug.Assert(GetBlockStats(blocks[0]).big_block);
if (assert_to_assume) {
- foreach (Block! b in allow_small ? blocks : big_blocks) {
- if (ComputeReachableNodes(b).ContainsKey((!)split_block)) {
+ foreach (Block b in allow_small ? blocks : big_blocks) {
+ Contract.Assert(b != null);
+ if (ComputeReachableNodes(b).ContainsKey(cce.NonNull(split_block))) {
keep_at_all[b] = true;
}
}
- foreach (Block! b in assumized_branches) {
- foreach (Block! r in ComputeReachableNodes(b).Keys) {
+ foreach (Block b in assumized_branches) {
+ Contract.Assert(b != null);
+ foreach (Block r in ComputeReachableNodes(b).Keys) {
+ Contract.Assert(r != null);
if (allow_small || GetBlockStats(r).big_block) {
keep_at_all[r] = true;
protected_from_assert_to_assume[r] = true;
@@ -1054,24 +1195,25 @@ namespace VC
}
}
- bool ShouldAssumize(Block! b)
- {
- return assert_to_assume && !protected_from_assert_to_assume.ContainsKey(b);
+ bool ShouldAssumize(Block b) {
+ Contract.Requires(b != null);
+ return assert_to_assume && !protected_from_assert_to_assume.ContainsKey(b);
}
- double DoComputeScore(bool aa)
- {
+ double DoComputeScore(bool aa) {
assert_to_assume = aa;
ComputeBlockSets(false);
- foreach (Block! b in big_blocks) {
+ foreach (Block b in big_blocks) {
+ Contract.Assert(b != null);
GetBlockStats(b).incomming_paths = -1.0;
}
GetBlockStats(blocks[0]).incomming_paths = 1.0;
double cost = 0.0;
- foreach (Block! b in big_blocks) {
+ foreach (Block b in big_blocks) {
+ Contract.Assert(b != null);
if (keep_at_all.ContainsKey(b)) {
BlockStats s = GetBlockStats(b);
UpdateIncommingPaths(s);
@@ -1085,18 +1227,23 @@ namespace VC
cost += local;
}
}
-
+
return cost;
}
- CmdSeq! SliceCmds(Block! b)
- {
- CmdSeq! seq = b.Cmds;
- if (!doing_slice && !ShouldAssumize(b)) return seq;
- CmdSeq! res = new CmdSeq();
- foreach (Cmd! c in seq) {
+ CmdSeq SliceCmds(Block b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<CmdSeq>() != null);
+
+ CmdSeq seq = b.Cmds;
+ Contract.Assert(seq != null);
+ if (!doing_slice && !ShouldAssumize(b))
+ return seq;
+ CmdSeq res = new CmdSeq();
+ foreach (Cmd c in seq) {
+ Contract.Assert(c != null);
AssertCmd a = c as AssertCmd;
- Cmd! the_new = c;
+ Cmd the_new = c;
bool swap = false;
if (a != null) {
if (doing_slice) {
@@ -1107,7 +1254,8 @@ namespace VC
} else if (assert_to_assume) {
swap = true;
} else {
- assert false;
+ Contract.Assert(false);
+ throw new cce.UnreachableException();
}
if (swap) {
@@ -1119,11 +1267,13 @@ namespace VC
return res;
}
- Block! CloneBlock(Block! b)
- {
+ Block CloneBlock(Block b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<Block>() != null);
+
Block res;
if (copies.TryGetValue(b, out res)) {
- return (!)res;
+ return cce.NonNull(res);
}
res = new Block(b.tok, b.Label, SliceCmds(b), b.TransferCmd);
GotoCmd gt = b.TransferCmd as GotoCmd;
@@ -1132,10 +1282,11 @@ namespace VC
GotoCmd newGoto = new GotoCmd(gt.tok, new StringSeq(), new BlockSeq());
res.TransferCmd = newGoto;
int pos = 0;
- foreach (Block! ch in (!)gt.labelTargets) {
- assert doing_slice ||
- (!assert_to_assume ==> (keep_at_all.ContainsKey(ch) || assumized_branches.Contains(ch)));
- if (doing_slice ||
+ foreach (Block ch in cce.NonNull(gt.labelTargets)) {
+ Contract.Assert(ch != null);
+ Contract.Assert(doing_slice ||
+ (assert_to_assume || (keep_at_all.ContainsKey(ch) || assumized_branches.Contains(ch))));
+ if (doing_slice ||
((b != split_block || assumized_branches.Contains(ch) == assert_to_assume) &&
keep_at_all.ContainsKey(ch))) {
newGoto.AddTarget(CloneBlock(ch));
@@ -1146,21 +1297,24 @@ namespace VC
return res;
}
- Split! DoSplit()
- {
+ Split DoSplit() {
+ Contract.Ensures(Contract.Result<Split>() != null);
+
copies.Clear();
CloneBlock(blocks[0]);
- List<Block!> newBlocks = new List<Block!>();
+ List<Block> newBlocks = new List<Block>();
Hashtable newGotoCmdOrigins = new Hashtable();
- foreach (Block! b in blocks) {
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
Block tmp;
if (copies.TryGetValue(b, out tmp)) {
- newBlocks.Add((!)tmp);
+ newBlocks.Add(cce.NonNull(tmp));
if (gotoCmdOrigins.ContainsKey(b)) {
newGotoCmdOrigins[tmp] = gotoCmdOrigins[b];
}
- foreach (Block! p in b.Predecessors) {
+ foreach (Block p in b.Predecessors) {
+ Contract.Assert(p != null);
Block tmp2;
if (copies.TryGetValue(p, out tmp2)) {
tmp.Predecessors.Add(tmp2);
@@ -1172,8 +1326,9 @@ namespace VC
return new Split(newBlocks, newGotoCmdOrigins, parent, impl);
}
- Split! SplitAt(int idx)
- {
+ Split SplitAt(int idx) {
+ Contract.Ensures(Contract.Result<Split>() != null);
+
assert_to_assume = idx == 0;
doing_slice = false;
ComputeBlockSets(true);
@@ -1181,14 +1336,14 @@ namespace VC
return DoSplit();
}
- Split! SliceAsserts(double limit, bool pos)
- {
+ Split SliceAsserts(double limit, bool pos) {
+ Contract.Ensures(Contract.Result<Split>() != null);
+
slice_pos = pos;
slice_limit = limit;
slice_initial_limit = limit;
doing_slice = true;
- Split! r = DoSplit();
-
+ Split r = DoSplit();
/*
Console.WriteLine("split {0} / {1} -->", limit, pos);
List<Block!> tmp = impl.Blocks;
@@ -1200,41 +1355,49 @@ namespace VC
return r;
}
- void Print()
- {
- List<Block!> tmp = impl.Blocks;
+ void Print() {
+ List<Block> tmp = impl.Blocks;
+ Contract.Assert(tmp != null);
impl.Blocks = blocks;
EmitImpl(impl, false);
impl.Blocks = tmp;
}
- public Counterexample! ToCounterexample()
- {
+ public Counterexample ToCounterexample() {
+ Contract.Ensures(Contract.Result<Counterexample>() != null);
+
BlockSeq trace = new BlockSeq();
- foreach (Block! b in blocks) {
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
trace.Add(b);
}
- foreach (Block! b in blocks) {
- foreach (Cmd! c in b.Cmds) {
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
+ foreach (Cmd c in b.Cmds) {
+ Contract.Assert(c != null);
if (c is AssertCmd) {
- return AssertCmdToCounterexample((AssertCmd)c, (!)b.TransferCmd, trace, null, new Dictionary<Incarnation, Absy!>());
+ return AssertCmdToCounterexample((AssertCmd)c, cce.NonNull(b.TransferCmd), trace, null, new Dictionary<Incarnation, Absy>());
}
}
}
- assume false;
+ Contract.Assume(false);
+ throw new cce.UnreachableException();
}
- public static List<Split!>! DoSplit(Split! initial, double max_cost, int max)
- {
- List<Split!> res = new List<Split!>();
+ public static List<Split/*!*/>/*!*/ DoSplit(Split initial, double max_cost, int max) {
+ Contract.Requires(initial != null);
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<Split>>()));
+
+ List<Split> res = new List<Split>();
res.Add(initial);
while (res.Count < max) {
Split best = null;
int best_idx = 0, pos = 0;
- foreach (Split! s in res) {
+ foreach (Split s in res) {
+ Contract.Assert(s != null);
s.ComputeBestSplit(); // TODO check total_cost first
- if (s.total_cost > max_cost &&
+ if (s.total_cost > max_cost &&
(best == null || best.total_cost < s.total_cost) &&
(s.assertion_count > 1 || s.split_block != null)) {
best = s;
@@ -1243,9 +1406,10 @@ namespace VC
pos++;
}
- if (best == null) break; // no split found
+ if (best == null)
+ break; // no split found
- Split! s0, s1;
+ Split s0, s1;
bool split_stats = CommandLineOptions.Clo.TraceVerify;
@@ -1255,12 +1419,14 @@ namespace VC
GotoCmd g = best.split_block.TransferCmd as GotoCmd;
if (g != null) {
Console.Write(" exits: ");
- foreach (Block! b in (!)g.labelTargets) {
+ foreach (Block b in cce.NonNull(g.labelTargets)) {
+ Contract.Assert(b != null);
Console.Write("{0} ", b.Label);
}
Console.WriteLine("");
Console.Write(" assumized: ");
- foreach (Block! b in best.assumized_branches) {
+ foreach (Block b in best.assumized_branches) {
+ Contract.Assert(b != null);
Console.Write("{0} ", b.Label);
}
Console.WriteLine("");
@@ -1278,17 +1444,18 @@ namespace VC
}
if (true) {
- List<Block!> ss = new List<Block!>();
+ List<Block> ss = new List<Block>();
ss.Add(s0.blocks[0]);
ss.Add(s1.blocks[0]);
try {
- best.SoundnessCheck(new Dictionary<PureCollections.Tuple!, bool>(), best.blocks[0], ss);
+ best.SoundnessCheck(new Dictionary<PureCollections.Tuple, bool>(), best.blocks[0], ss);
} catch (System.Exception e) {
Console.WriteLine(e);
best.DumpDot(-1);
s0.DumpDot(-2);
s1.DumpDot(-3);
- assert false;
+ Contract.Assert(false);
+ throw new cce.UnreachableException();
}
}
@@ -1310,26 +1477,25 @@ namespace VC
return res;
}
- public Checker! Checker
- {
+ public Checker Checker {
get {
- assert checker != null;
+ Contract.Ensures(Contract.Result<Checker>() != null);
+
+ Contract.Assert(checker != null);
return checker;
}
}
- public WaitHandle ProverDone
- {
- get {
- assert checker != null;
+ public WaitHandle ProverDone {
+ get {
+ Contract.Assert(checker != null);
return checker.ProverDone;
}
}
- public void ReadOutcome(ref Outcome cur_outcome, out bool prover_failed)
- throws UnexpectedProverOutputException;
- {
- ProverInterface.Outcome outcome = ((!)checker).ReadOutcome();
+ public void ReadOutcome(ref Outcome cur_outcome, out bool prover_failed) {
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
+ ProverInterface.Outcome outcome = cce.NonNull(checker).ReadOutcome();
if (CommandLineOptions.Clo.Trace && splitNo >= 0) {
System.Console.WriteLine(" --> split #{0} done, [{1} s] {2}", splitNo, checker.ProverRunTime.TotalSeconds, outcome);
@@ -1363,49 +1529,55 @@ namespace VC
cur_outcome = Outcome.Inconclusive;
return;
default:
- assert false;
+ Contract.Assert(false);
+ throw new cce.UnreachableException();
}
}
- public void BeginCheck(VerifierCallback! callback, int no, int timeout)
- {
+ public void BeginCheck(VerifierCallback callback, int no, int timeout) {
+ Contract.Requires(callback != null);
splitNo = no;
impl.Blocks = blocks;
checker = parent.FindCheckerFor(impl, timeout);
- Hashtable/*<int, Absy!>*/! label2absy;
- VCExpr! vc = parent.GenerateVC(impl, null, out label2absy, checker);
-
+ Hashtable/*<int, Absy!>*/ label2absy;
+ VCExpr vc = parent.GenerateVC(impl, null, out label2absy, checker);
+ Contract.Assert(vc != null);
+
if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Local) {
- reporter = new ErrorReporterLocal(gotoCmdOrigins, label2absy, impl.Blocks, parent.incarnationOriginMap, callback, parent.implName2LazyInliningInfo, (DeclFreeProverContext!) this.Checker.TheoremProver.Context, parent.program);
+ reporter = new ErrorReporterLocal(gotoCmdOrigins, label2absy, impl.Blocks, parent.incarnationOriginMap, callback, parent.implName2LazyInliningInfo, cce.NonNull((DeclFreeProverContext)this.Checker.TheoremProver.Context), parent.program);
} else {
- reporter = new ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, parent.incarnationOriginMap, callback, parent.implName2LazyInliningInfo, (DeclFreeProverContext!) this.Checker.TheoremProver.Context, parent.program);
+ reporter = new ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, parent.incarnationOriginMap, callback, parent.implName2LazyInliningInfo, (DeclFreeProverContext)this.Checker.TheoremProver.Context, parent.program);
}
-
- if (CommandLineOptions.Clo.TraceVerify && no >= 0)
- {
+
+ if (CommandLineOptions.Clo.TraceVerify && no >= 0) {
Console.WriteLine("-- after split #{0}", no);
Print();
}
- string! desc = (!) impl.Name;
+ string desc = cce.NonNull(impl.Name);
if (no >= 0)
desc += "_split" + no;
checker.BeginCheck(desc, vc, reporter);
}
- private void SoundnessCheck(Dictionary<PureCollections.Tuple!, bool>! cache, Block! orig, List<Block!>! copies)
- {
+ private void SoundnessCheck(Dictionary<PureCollections.Tuple/*!*/, bool>/*!*/ cache, Block/*!*/ orig, List<Block/*!*/>/*!*/ copies) {
+ Contract.Requires(cce.NonNullElements(cache));
+ Contract.Requires(orig != null);
+ Contract.Requires(copies != null);
{
PureCollections.Tuple t = new PureCollections.Tuple(new PureCollections.Capacity(1 + copies.Count));
int i = 0;
t[i++] = orig;
- foreach (Block! b in copies) {
+ foreach (Block b in copies) {
+ Contract.Assert(b != null);
t[i++] = b;
}
- if (cache.ContainsKey(t)) { return; }
+ if (cache.ContainsKey(t)) {
+ return;
+ }
cache[t] = true;
}
@@ -1413,7 +1585,8 @@ namespace VC
Cmd cmd = orig.Cmds[i];
if (cmd is AssertCmd) {
int found = 0;
- foreach (Block! c in copies) {
+ foreach (Block c in copies) {
+ Contract.Assert(c != null);
if (c.Cmds[i] == cmd) {
found++;
}
@@ -1424,10 +1597,12 @@ namespace VC
}
}
- foreach (Block! exit in Exits(orig)) {
- List<Block!>! newcopies = new List<Block!>();
- foreach (Block! c in copies) {
- foreach (Block! cexit in Exits(c)) {
+ foreach (Block exit in Exits(orig)) {
+ Contract.Assert(exit != null);
+ List<Block> newcopies = new List<Block>();
+ foreach (Block c in copies) {
+ foreach (Block cexit in Exits(c)) {
+ Contract.Assert(cexit != null);
if (cexit.Label == exit.Label) {
newcopies.Add(cexit);
}
@@ -1443,58 +1618,67 @@ namespace VC
#endregion
- protected VCExpr! GenerateVC(Implementation! impl, Variable controlFlowVariable, out Hashtable/*<int, Absy!>*/! label2absy, Checker! ch)
- {
+ protected VCExpr GenerateVC(Implementation/*!*/ impl, Variable controlFlowVariable, out Hashtable/*<int, Absy!>*//*!*/ label2absy, Checker/*!*/ ch) {
+ Contract.Requires(impl != null);
+ Contract.Requires(ch != null);
+ Contract.Ensures(Contract.ValueAtReturn(out label2absy) != null);
+
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
TypecheckingContext tc = new TypecheckingContext(null);
impl.Typecheck(tc);
label2absy = new Hashtable/*<int, Absy!>*/();
- VCExpr! vc;
+ VCExpr vc;
switch (CommandLineOptions.Clo.vcVariety) {
- case CommandLineOptions.VCVariety.Structured:
- vc = VCViaStructuredProgram(impl, label2absy, ch.TheoremProver.Context);
- break;
- case CommandLineOptions.VCVariety.Block:
- vc = FlatBlockVC(impl, label2absy, false, false, false, ch.TheoremProver.Context);
- break;
- case CommandLineOptions.VCVariety.BlockReach:
- vc = FlatBlockVC(impl, label2absy, false, true, false, ch.TheoremProver.Context);
- break;
- case CommandLineOptions.VCVariety.Local:
- vc = FlatBlockVC(impl, label2absy, true, false, false, ch.TheoremProver.Context);
- break;
- case CommandLineOptions.VCVariety.BlockNested:
- vc = NestedBlockVC(impl, label2absy, false, ch.TheoremProver.Context);
- break;
- case CommandLineOptions.VCVariety.BlockNestedReach:
- vc = NestedBlockVC(impl, label2absy, true, ch.TheoremProver.Context);
- break;
- case CommandLineOptions.VCVariety.Dag:
- if (((!)CommandLineOptions.Clo.TheProverFactory).SupportsDags) {
- vc = DagVC((!)impl.Blocks[0], label2absy, new Hashtable/*<Block, VCExpr!>*/(), ch.TheoremProver.Context);
- } else {
- vc = LetVC((!)impl.Blocks[0], controlFlowVariable, label2absy, ch.TheoremProver.Context);
- }
- break;
- case CommandLineOptions.VCVariety.Doomed:
- vc = FlatBlockVC(impl, label2absy, false, false, true, ch.TheoremProver.Context);
- break;
- default:
- assert false; // unexpected enumeration value
+ case CommandLineOptions.VCVariety.Structured:
+ vc = VCViaStructuredProgram(impl, label2absy, ch.TheoremProver.Context);
+ break;
+ case CommandLineOptions.VCVariety.Block:
+ vc = FlatBlockVC(impl, label2absy, false, false, false, ch.TheoremProver.Context);
+ break;
+ case CommandLineOptions.VCVariety.BlockReach:
+ vc = FlatBlockVC(impl, label2absy, false, true, false, ch.TheoremProver.Context);
+ break;
+ case CommandLineOptions.VCVariety.Local:
+ vc = FlatBlockVC(impl, label2absy, true, false, false, ch.TheoremProver.Context);
+ break;
+ case CommandLineOptions.VCVariety.BlockNested:
+ vc = NestedBlockVC(impl, label2absy, false, ch.TheoremProver.Context);
+ break;
+ case CommandLineOptions.VCVariety.BlockNestedReach:
+ vc = NestedBlockVC(impl, label2absy, true, ch.TheoremProver.Context);
+ break;
+ case CommandLineOptions.VCVariety.Dag:
+ if (cce.NonNull(CommandLineOptions.Clo.TheProverFactory).SupportsDags) {
+ vc = DagVC(cce.NonNull(impl.Blocks[0]), label2absy, new Hashtable/*<Block, VCExpr!>*/(), ch.TheoremProver.Context);
+ } else {
+ vc = LetVC(cce.NonNull(impl.Blocks[0]), controlFlowVariable, label2absy, ch.TheoremProver.Context);
+ }
+ break;
+ case CommandLineOptions.VCVariety.Doomed:
+ vc = FlatBlockVC(impl, label2absy, false, false, true, ch.TheoremProver.Context);
+ break;
+ default:
+ Contract.Assert(false);
+ throw new cce.UnreachableException(); // unexpected enumeration value
}
return vc;
}
- void CheckIntAttributeOnImpl(Implementation! impl, string! name, ref int val)
- {
- if (!((!)impl.Proc).CheckIntAttribute(name, ref val) || !impl.CheckIntAttribute(name, ref val)) {
+ void CheckIntAttributeOnImpl(Implementation impl, string name, ref int val) {
+ Contract.Requires(impl != null);
+ Contract.Requires(name != null);
+ if (!(cce.NonNull(impl.Proc).CheckIntAttribute(name, ref val) || !impl.CheckIntAttribute(name, ref val))) {
Console.WriteLine("ignoring ill-formed {:{0} ...} attribute on {1}, parameter should be an int", name, impl.Name);
}
}
-
- public override Outcome VerifyImplementation(Implementation! impl, Program! program, VerifierCallback! callback)
- throws UnexpectedProverOutputException;
- {
+
+ public override Outcome VerifyImplementation(Implementation/*!*/ impl, Program/*!*/ program, VerifierCallback/*!*/ callback){
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(callback != null);
+ Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);
if (impl.SkipVerification) {
return Outcome.Inconclusive; // not sure about this one
}
@@ -1528,8 +1712,8 @@ namespace VC
Outcome outcome = Outcome.Correct;
int cores = CommandLineOptions.Clo.VcsCores;
- Stack<Split!> work = new Stack<Split!>();
- List<Split!> currently_running = new List<Split!>();
+ Stack<Split> work = new Stack<Split>();
+ List<Split> currently_running = new List<Split>();
ResetPredecessors(impl.Blocks);
work.Push(new Split(impl.Blocks, gotoCmdOrigins, this, impl));
@@ -1546,7 +1730,7 @@ namespace VC
while (work.Count > 0 || currently_running.Count > 0) {
bool prover_failed = false;
- Split! s;
+ Split s;
if (work.Count > 0 && currently_running.Count < cores) {
s = work.Pop();
@@ -1597,7 +1781,7 @@ namespace VC
callback.OnProgress("VCprove", no < 0 ? 0 : no, total, proven_cost / (remaining_cost + proven_cost));
if (prover_failed && !first_round && s.LastChance) {
- string! msg = "some timeout";
+ string msg = "some timeout";
if (s.reporter != null && s.reporter.resourceExceededMessage != null) {
msg = s.reporter.resourceExceededMessage;
}
@@ -1606,18 +1790,20 @@ namespace VC
break;
}
- assert prover_failed || outcome == Outcome.Correct || outcome == Outcome.Errors;
+ Contract.Assert( prover_failed || outcome == Outcome.Correct || outcome == Outcome.Errors);
}
if (prover_failed) {
int splits = first_round && max_splits > 1 ? max_splits : max_kg_splits;
if (splits > 1) {
- List<Split!> tmp = Split.DoSplit(s, max_vc_cost, splits);
+ List<Split> tmp = Split.DoSplit(s, max_vc_cost, splits);
+ Contract.Assert(tmp != null);
max_vc_cost = 1.0; // for future
first_round = false;
//tmp.Sort(new Comparison<Split!>(Split.Compare));
- foreach (Split! a in tmp) {
+ foreach (Split a in tmp) {
+ Contract.Assert(a != null);
work.Push(a);
total++;
remaining_cost += a.Cost;
@@ -1626,15 +1812,15 @@ namespace VC
outcome = Outcome.Correct;
}
} else {
- assert outcome != Outcome.Correct;
+ Contract.Assert( outcome != Outcome.Correct);
if (outcome == Outcome.TimedOut) {
- string! msg = "some timeout";
+ string msg = "some timeout";
if (s.reporter != null && s.reporter.resourceExceededMessage != null) {
msg = s.reporter.resourceExceededMessage;
}
callback.OnTimeout(msg);
} else if (outcome == Outcome.OutOfMemory) {
- string! msg = "out of memory";
+ string msg = "out of memory";
if (s.reporter != null && s.reporter.resourceExceededMessage != null) {
msg = s.reporter.resourceExceededMessage;
}
@@ -1655,15 +1841,17 @@ namespace VC
return outcome;
}
- public override Outcome StratifiedVerifyImplementation(Implementation! impl, Program! program, VerifierCallback! callback)
- throws UnexpectedProverOutputException;
- {
+ public override Outcome StratifiedVerifyImplementation(Implementation/*!*/ impl, Program/*!*/ program, VerifierCallback/*!*/ callback){
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(callback != null);
+ Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);
// This flag control the nature of queries made by StratifiedVerifyImplementation
// true: incremental search; false: in-place inlining
bool incrementalSearch = true;
// Get the checker
- Checker! checker = FindCheckerFor(null, CommandLineOptions.Clo.ProverKillTime);
+ Checker checker = FindCheckerFor(null, CommandLineOptions.Clo.ProverKillTime);Contract.Assert(checker != null);
// Run live variable analysis
if(CommandLineOptions.Clo.LiveVariableAnalysis == 2) {
@@ -1671,16 +1859,17 @@ namespace VC
}
// Build VCs for all procedures
- assert implName2StratifiedInliningInfo != null;
- foreach(StratifiedInliningInfo! info in implName2StratifiedInliningInfo.Values)
+ Contract.Assert( implName2StratifiedInliningInfo != null);
+ foreach(StratifiedInliningInfo info in implName2StratifiedInliningInfo.Values)
{
+ Contract.Assert(info != null);
GenerateVCForStratifiedInlining(program, info, checker);
}
// Get the VC of the current procedure
- VCExpr! vc;
- StratifiedInliningErrorReporter! reporter;
- Hashtable/*<int, Absy!>*/! mainLabel2absy;
+ VCExpr vc;
+ StratifiedInliningErrorReporter reporter;
+ Hashtable/*<int, Absy!>*/ mainLabel2absy;
GetVC(impl, program, callback, out vc, out mainLabel2absy, out reporter);
// Find all procedure calls in vc and put labels on them
@@ -1697,7 +1886,7 @@ namespace VC
// Do eager inlining
for(int i = 1; i < CommandLineOptions.Clo.StratifiedInlining && calls.currCandidates.Count > 0; i ++)
{
- List<int>! toExpand = new List<int>();
+ List<int> toExpand = new List<int>();
foreach(int id in calls.currCandidates) {
toExpand.Add(id);
}
@@ -1722,8 +1911,10 @@ namespace VC
int prev_axioms_pushed = checker.TheoremProver.NumAxiomsPushed();
foreach(int id in calls.currCandidates) {
- VCExprNAry! vce = calls.id2Candidate[id];
- VCExpr! falseExpr = checker.VCExprGen.Eq(vce, VCExpressionGenerator.False);
+ VCExprNAry vce = calls.id2Candidate[id];
+ Contract.Assert(vce != null);
+ VCExpr falseExpr = checker.VCExprGen.Eq(vce, VCExpressionGenerator.False);
+ Contract.Assert(falseExpr != null);
checker.TheoremProver.PushVCExpression(falseExpr);
}
int axioms_pushed = checker.TheoremProver.NumAxiomsPushed();
@@ -1773,7 +1964,7 @@ namespace VC
checker.TheoremProver.LogComment(";;;;;;;;;;;; Expansion begin ;;;;;;;;;;");
// Look at the errors to see what to inline
- assert reporter.candidatesToExpand.Count != 0;
+ Contract.Assert( reporter.candidatesToExpand.Count != 0);
expansionCount += reporter.candidatesToExpand.Count;
@@ -1806,49 +1997,54 @@ namespace VC
return ret;
}
-
+
// A counter for adding new variables
- static int newVarCnt = 0;
-
+ static int newVarCnt = 0;
+
// Does on-demand inlining -- pushes procedure bodies on the theorem prover stack.
// Returns the number of axioms pushed.
- private int DoExpansion(List<int>! candidates,
- FCallHandler! calls, Checker! checker)
- throws UnexpectedProverOutputException;
- {
+ private int DoExpansion(List<int>/*!*/ candidates,
+ FCallHandler/*!*/ calls, Checker/*!*/ checker){
+ Contract.Requires(candidates != null);
+ Contract.Requires(calls != null);
+ Contract.Requires(checker != null);
+ Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);
int old_axioms_pushed = checker.TheoremProver.NumAxiomsPushed();
- VCExpr! exprToPush = VCExpressionGenerator.True;
+ VCExpr exprToPush = VCExpressionGenerator.True;
+ Contract.Assert(exprToPush != null);
foreach(int id in candidates) {
- VCExprNAry! expr = calls.id2Candidate[id];
- string procName = ((!)(expr.Op as VCExprBoogieFunctionOp)).Func.Name;
+ VCExprNAry expr = calls.id2Candidate[id];
+ Contract.Assert(expr != null);
+ string procName = cce.NonNull(expr.Op as VCExprBoogieFunctionOp).Func.Name;
if(!implName2StratifiedInliningInfo.ContainsKey(procName)) continue;
//Console.WriteLine("Expanding: {0}", expr.ToString());
StratifiedInliningInfo info = implName2StratifiedInliningInfo[procName];
- VCExpr! expansion = (!)info.vcexpr;
+ VCExpr expansion = cce.NonNull(info.vcexpr);
// Instantiate the "forall" variables
- Dictionary<VCExprVar!, VCExpr!>! substForallDict = new Dictionary<VCExprVar!, VCExpr!>();
- assert info.interfaceExprVars.Count == expr.Length;
+ Dictionary<VCExprVar, VCExpr> substForallDict = new Dictionary<VCExprVar, VCExpr>();
+ Contract.Assert( info.interfaceExprVars.Count == expr.Length);
for(int i = 0; i < info.interfaceExprVars.Count; i++) {
substForallDict.Add(info.interfaceExprVars[i], expr[i]);
}
- VCExprSubstitution substForall = new VCExprSubstitution(substForallDict, new Dictionary<TypeVariable!, Microsoft.Boogie.Type!>());
+ VCExprSubstitution substForall = new VCExprSubstitution(substForallDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>());
- SubstitutingVCExprVisitor! subst = new SubstitutingVCExprVisitor(checker.VCExprGen);
+ SubstitutingVCExprVisitor subst = new SubstitutingVCExprVisitor(checker.VCExprGen);
+ Contract.Assert(subst != null);
expansion = subst.Mutate(expansion, substForall);
// Instantiate and declare the "exists" variables
- Dictionary<VCExprVar!, VCExpr!>! substExistsDict = new Dictionary<VCExprVar!, VCExpr!>();
- for(int i = 0; i < info.privateVars.Count; i++) {
- VCExprVar! v = info.privateVars[i];
+ Dictionary<VCExprVar, VCExpr> substExistsDict = new Dictionary<VCExprVar, VCExpr>();
+ foreach(VCExprVar v in info.privateVars) {
+ Contract.Assert(v != null);
string newName = v.Name + "_si_" + newVarCnt.ToString();
newVarCnt ++;
checker.TheoremProver.Context.DeclareConstant(new Constant(Token.NoToken, new TypedIdent(Token.NoToken, newName, v.Type)), false, null);
substExistsDict.Add(v, checker.VCExprGen.Variable(newName, v.Type));
}
- VCExprSubstitution substExists = new VCExprSubstitution(substExistsDict, new Dictionary<TypeVariable!, Microsoft.Boogie.Type!>());
+ VCExprSubstitution substExists = new VCExprSubstitution(substExistsDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>());
subst = new SubstitutingVCExprVisitor(checker.VCExprGen);
expansion = subst.Mutate(expansion, substExists);
@@ -1878,42 +2074,49 @@ namespace VC
// Does on-demand inlining -- pushes procedure bodies on the theorem prover stack.
// Returns the number of axioms pushed.
- private VCExpr! DoExpansionAndInline(
- VCExpr! mainVC, List<int>! candidates,
- FCallHandler! calls, Checker! checker)
- throws UnexpectedProverOutputException;
- {
- FCallInliner! inliner = new FCallInliner(checker.VCExprGen);
+ private VCExpr DoExpansionAndInline(
+ VCExpr/*!*/ mainVC, List<int>/*!*/ candidates,
+ FCallHandler/*!*/ calls, Checker/*!*/ checker){
+ Contract.Requires(mainVC != null);
+ Contract.Requires(candidates != null);
+ Contract.Requires(calls != null);
+ Contract.Requires(checker != null);
+ Contract.EnsuresOnThrow< UnexpectedProverOutputException>(true);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ FCallInliner inliner = new FCallInliner(checker.VCExprGen);
+ Contract.Assert(inliner != null);
foreach(int id in candidates) {
- VCExprNAry! expr = calls.id2Candidate[id];
+ VCExprNAry expr = calls.id2Candidate[id];
+ Contract.Assert(expr != null);
- string procName = ((!)(expr.Op as VCExprBoogieFunctionOp)).Func.Name;
+ string procName = (cce.NonNull(expr.Op as VCExprBoogieFunctionOp)).Func.Name;
if(!implName2StratifiedInliningInfo.ContainsKey(procName)) continue;
StratifiedInliningInfo info = implName2StratifiedInliningInfo[procName];
- VCExpr! expansion = (!)info.vcexpr;
+ VCExpr expansion = cce.NonNull(info.vcexpr);
// Instantiate the "forall" variables
- Dictionary<VCExprVar!, VCExpr!>! substForallDict = new Dictionary<VCExprVar!, VCExpr!>();
- assert info.interfaceExprVars.Count == expr.Length;
+ Dictionary<VCExprVar, VCExpr> substForallDict = new Dictionary<VCExprVar, VCExpr>();
+ Contract.Assert( info.interfaceExprVars.Count == expr.Length);
for(int i = 0; i < info.interfaceExprVars.Count; i++) {
substForallDict.Add(info.interfaceExprVars[i], expr[i]);
}
- VCExprSubstitution substForall = new VCExprSubstitution(substForallDict, new Dictionary<TypeVariable!, Microsoft.Boogie.Type!>());
+ VCExprSubstitution substForall = new VCExprSubstitution(substForallDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>());
- SubstitutingVCExprVisitor! subst = new SubstitutingVCExprVisitor(checker.VCExprGen);
+ SubstitutingVCExprVisitor subst = new SubstitutingVCExprVisitor(checker.VCExprGen);Contract.Assert(subst != null);
expansion = subst.Mutate(expansion, substForall);
// Instantiate and declare the "exists" variables
- Dictionary<VCExprVar!, VCExpr!>! substExistsDict = new Dictionary<VCExprVar!, VCExpr!>();
+ Dictionary<VCExprVar, VCExpr> substExistsDict = new Dictionary<VCExprVar, VCExpr>();
for(int i = 0; i < info.privateVars.Count; i++) {
- VCExprVar! v = info.privateVars[i];
+ VCExprVar v = info.privateVars[i];
string newName = v.Name + "_si_" + newVarCnt.ToString();
newVarCnt ++;
checker.TheoremProver.Context.DeclareConstant(new Constant(Token.NoToken, new TypedIdent(Token.NoToken, newName, v.Type)), false, null);
substExistsDict.Add(v, checker.VCExprGen.Variable(newName, v.Type));
}
- VCExprSubstitution substExists = new VCExprSubstitution(substExistsDict, new Dictionary<TypeVariable!, Microsoft.Boogie.Type!>());
+ VCExprSubstitution substExists = new VCExprSubstitution(substExistsDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>());
subst = new SubstitutingVCExprVisitor(checker.VCExprGen);
expansion = subst.Mutate(expansion, substExists);
@@ -1935,17 +2138,24 @@ namespace VC
return inliner.Mutate(mainVC, true);
}
-
+
// Return the VC for the impl (don't pass it to the theorem prover).
// GetVC is a cheap imitation of VerifyImplementatio, except that the VC is not passed to the theorem prover.
- private void GetVC(Implementation! impl, Program! program, VerifierCallback! callback, out VCExpr! vc, out Hashtable/*<int, Absy!>*/! label2absy, out StratifiedInliningErrorReporter! reporter)
- {
+ private void GetVC(Implementation/*!*/ impl, Program/*!*/ program, VerifierCallback/*!*/ callback, out VCExpr/*!*/ vc, out Hashtable/*<int, Absy!>*//*!*/ label2absy, out StratifiedInliningErrorReporter/*!*/ reporter) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(callback != null);
+ Contract.Ensures(Contract.ValueAtReturn(out vc) != null);
+ Contract.Ensures(Contract.ValueAtReturn(out label2absy) != null);
+ Contract.Ensures(Contract.ValueAtReturn(out reporter) != null);
+
ConvertCFG2DAG(impl, program);
Hashtable/*TransferCmd->ReturnCmd*/ gotoCmdOrigins = PassifyImpl(impl, program);
- Checker! checker = FindCheckerFor(impl, CommandLineOptions.Clo.ProverKillTime);
-
+ Checker checker = FindCheckerFor(impl, CommandLineOptions.Clo.ProverKillTime);
+ Contract.Assert(checker != null);
+
vc = GenerateVC(impl, null, out label2absy, checker);
-
+
/*
ErrorReporter errReporter;
if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Local) {
@@ -1954,41 +2164,45 @@ namespace VC
errReporter = new ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, incarnationOriginMap, callback, implName2LazyInliningInfo, (DeclFreeProverContext!) checker.TheoremProver.Context, program);
}
*/
-
+
reporter = new StratifiedInliningErrorReporter(
- (!)implName2StratifiedInliningInfo, checker.TheoremProver, callback,
+ cce.NonNull(implName2StratifiedInliningInfo), checker.TheoremProver, callback,
(DeclFreeProverContext)checker.TheoremProver.Context, gotoCmdOrigins, program, impl);
}
-
- private Outcome CheckVC(VCExpr! vc, StratifiedInliningErrorReporter! reporter, Checker! checker, string! implName)
- throws UnexpectedProverOutputException;
- {
- checker.TheoremProver.FlushAxiomsToTheoremProver();
- checker.BeginCheck(implName, vc, reporter);
- checker.ProverDone.WaitOne();
-
- ProverInterface.Outcome outcome = (checker).ReadOutcome();
-
- //checker.BeginCheck(implName, vc, reporter);
- //checker.ProverDone.WaitOne();
- //outcome = (checker).ReadOutcome();
-
- switch (outcome) {
- case ProverInterface.Outcome.Valid:
- return Outcome.Correct;
- case ProverInterface.Outcome.Invalid:
- return Outcome.Errors;
- case ProverInterface.Outcome.OutOfMemory:
- return Outcome.OutOfMemory;
- case ProverInterface.Outcome.TimeOut:
- return Outcome.TimedOut;
- case ProverInterface.Outcome.Undetermined:
- return Outcome.Inconclusive;
- default:
- assert false;
- }
-
+
+ private Outcome CheckVC(VCExpr/*!*/ vc, StratifiedInliningErrorReporter/*!*/ reporter, Checker/*!*/ checker, string/*!*/ implName) {
+ Contract.Requires(vc != null);
+ Contract.Requires(reporter != null);
+ Contract.Requires(checker != null);
+ Contract.Requires(implName != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
+ checker.TheoremProver.FlushAxiomsToTheoremProver();
+ checker.BeginCheck(implName, vc, reporter);
+ checker.ProverDone.WaitOne();
+
+ ProverInterface.Outcome outcome = (checker).ReadOutcome();
+
+ //checker.BeginCheck(implName, vc, reporter);
+ //checker.ProverDone.WaitOne();
+ //outcome = (checker).ReadOutcome();
+
+ switch (outcome) {
+ case ProverInterface.Outcome.Valid:
+ return Outcome.Correct;
+ case ProverInterface.Outcome.Invalid:
+ return Outcome.Errors;
+ case ProverInterface.Outcome.OutOfMemory:
+ return Outcome.OutOfMemory;
+ case ProverInterface.Outcome.TimeOut:
+ return Outcome.TimedOut;
+ case ProverInterface.Outcome.Undetermined:
+ return Outcome.Inconclusive;
+ default:
+ Contract.Assert(false);
+ throw new cce.UnreachableException();
+ }
+
}
/*
@@ -2021,109 +2235,125 @@ namespace VC
// -- Rename all other labels (so that calling this on the same VC results in
// VCs with different labels each time)
public class FCallHandler : MutatingVCExprVisitor<bool> {
- Dictionary<string!, StratifiedInliningInfo!>! implName2StratifiedInliningInfo;
- public readonly Hashtable/*<int, Absy!>*/! mainLabel2absy;
- public Dictionary<NAryExpr!, int>! boogieExpr2Id;
- public Dictionary<int, VCExprNAry!>! id2Candidate;
- public Dictionary<VCExprNAry!, int>! candidate2Id;
- public Dictionary<string!, int>! label2Id;
+ Dictionary<string/*!*/, StratifiedInliningInfo/*!*/>/*!*/ implName2StratifiedInliningInfo;
+ public readonly Hashtable/*<int, Absy!>*//*!*/ mainLabel2absy;
+ public Dictionary<NAryExpr/*!*/, int>/*!*/ boogieExpr2Id;
+ public Dictionary<int, VCExprNAry/*!*/>/*!*/ id2Candidate;
+ public Dictionary<VCExprNAry/*!*/, int>/*!*/ candidate2Id;
+ public Dictionary<string/*!*/, int>/*!*/ label2Id;
public Microsoft.SpecSharp.Collections.Set<int> currCandidates;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(implName2StratifiedInliningInfo));
+ Contract.Invariant(mainLabel2absy != null);
+ Contract.Invariant(cce.NonNullElements(boogieExpr2Id));
+ Contract.Invariant(cce.NonNullElements(id2Candidate));
+ Contract.Invariant(cce.NonNullElements(candidate2Id));
+ Contract.Invariant(cce.NonNullElements(label2Id));
+ }
- // Name of the procedure who's VC we're mutating
+ // Name of the procedure whose VC we're mutating
string currProc;
-
+
// The 0^th candidate is main
static int candidateCount = 1;
public int currInlineCount;
-
- public FCallHandler(VCExpressionGenerator! gen,
- Dictionary<string!, StratifiedInliningInfo!>! implName2StratifiedInliningInfo,
- Hashtable/*<int, Absy!>*/! mainLabel2absy)
- : base(gen)
- {
+
+ public FCallHandler(VCExpressionGenerator/*!*/ gen,
+ Dictionary<string/*!*/, StratifiedInliningInfo/*!*/>/*!*/ implName2StratifiedInliningInfo,
+ Hashtable/*<int, Absy!>*//*!*/ mainLabel2absy)
+ : base(gen) {
+ Contract.Requires(gen != null);
+ Contract.Requires(cce.NonNullElements(implName2StratifiedInliningInfo));
+ Contract.Requires(mainLabel2absy != null);
this.implName2StratifiedInliningInfo = implName2StratifiedInliningInfo;
this.mainLabel2absy = mainLabel2absy;
- id2Candidate = new Dictionary<int, VCExprNAry!>();
- candidate2Id = new Dictionary<VCExprNAry!, int>();
- boogieExpr2Id = new Dictionary<NAryExpr!, int>();
- label2Id = new Dictionary<string!, int>();
+ id2Candidate = new Dictionary<int, VCExprNAry>();
+ candidate2Id = new Dictionary<VCExprNAry, int>();
+ boogieExpr2Id = new Dictionary<NAryExpr, int>();
+ label2Id = new Dictionary<string, int>();
currCandidates = new Microsoft.SpecSharp.Collections.Set<int>();
currInlineCount = 0;
currProc = null;
}
-
- public void Clear()
- {
+
+ public void Clear() {
currCandidates = new Microsoft.SpecSharp.Collections.Set<int>();
}
-
- private int GetId(VCExprNAry! vc)
- {
- if(candidate2Id.ContainsKey(vc))
- return candidate2Id[vc];
-
-
- int id = candidateCount;
- candidate2Id[vc] = id;
- id2Candidate[id] = vc;
-
- candidateCount ++;
- currCandidates.Add(id);
-
- return id;
+
+ private int GetId(VCExprNAry vc) {
+ Contract.Requires(vc != null);
+ if (candidate2Id.ContainsKey(vc))
+ return candidate2Id[vc];
+
+
+ int id = candidateCount;
+ candidate2Id[vc] = id;
+ id2Candidate[id] = vc;
+
+ candidateCount++;
+ currCandidates.Add(id);
+
+ return id;
}
-
- private string! GetLabel(int id)
- {
- string! ret = "si_fcall_" + id.ToString();
- if(!label2Id.ContainsKey(ret))
- label2Id[ret] = id;
-
- return ret;
+
+ private string GetLabel(int id) {
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ string ret = "si_fcall_" + id.ToString();
+ if (!label2Id.ContainsKey(ret))
+ label2Id[ret] = id;
+
+ return ret;
}
-
- public int GetId(string! label)
- {
- if(!label2Id.ContainsKey(label)) return -1;
- return label2Id[label];
+
+ public int GetId(string label) {
+ Contract.Requires(label != null);
+ if (!label2Id.ContainsKey(label))
+ return -1;
+ return label2Id[label];
}
-
- public string! RenameAbsyLabel(string !label)
- requires label.Length >= 1;
- {
- // Remove the sign from the label
- string! nosign = label.Substring(1);
- return "si_inline_" + currInlineCount.ToString() + "_" + nosign;
+
+ public string RenameAbsyLabel(string label) {
+ Contract.Requires(label != null);
+ Contract.Requires(label.Length >= 1);
+ Contract.Ensures(Contract.Result<string>() != null);
+
+
+ // Remove the sign from the label
+ string nosign = label.Substring(1);
+ return "si_inline_" + currInlineCount.ToString() + "_" + nosign;
}
-
- public string ParseRenamedAbsyLabel(string! label)
- {
- string! prefix = RenameAbsyLabel("+");
- if(!label.StartsWith(prefix))
- return null;
- return label.Substring(prefix.Length);
+
+ public string ParseRenamedAbsyLabel(string label) {
+ Contract.Requires(label != null);
+ string prefix = RenameAbsyLabel("+");
+ Contract.Assert(prefix != null);
+ if (!label.StartsWith(prefix))
+ return null;
+ return label.Substring(prefix.Length);
}
-
- public void setCurrProc(string! name)
- {
+
+ public void setCurrProc(string name) {
+ Contract.Requires(name != null);
currProc = name;
- assert implName2StratifiedInliningInfo.ContainsKey(name);
+ Contract.Assert(implName2StratifiedInliningInfo.ContainsKey(name));
}
-
- public void setCurrProcAsMain()
- {
+
+ public void setCurrProcAsMain() {
currProc = "";
}
-
- private Hashtable/*<int,absy>*/! getLabel2absy()
- {
- assert currProc != null;
- if(currProc == "") {
- return mainLabel2absy;
- }
- return (!)implName2StratifiedInliningInfo[currProc].label2absy;
+
+ private Hashtable/*<int,absy>*/ getLabel2absy() {
+ Contract.Ensures(Contract.Result<Hashtable>() != null);
+
+ Contract.Assert(currProc != null);
+ if (currProc == "") {
+ return mainLabel2absy;
+ }
+ return cce.NonNull(implName2StratifiedInliningInfo[currProc].label2absy);
}
-
+
// Finds labels and changes them:
// si_fcall_id: if "id" corresponds to a tracked procedure call, then
// si_fcall_candidateId
@@ -2131,13 +2361,17 @@ namespace VC
// delete
// num: si_inline_num
//
- protected override VCExpr! UpdateModifiedNode(VCExprNAry! originalNode,
- List<VCExpr!>! newSubExprs,
- // has any of the subexpressions changed?
+ protected override VCExpr/*!*/ UpdateModifiedNode(VCExprNAry/*!*/ originalNode,
+ List<VCExpr/*!*/>/*!*/ newSubExprs,
+ // has any of the subexpressions changed?
bool changed,
bool arg)
{
- VCExpr! ret;
+ Contract.Requires(originalNode != null);
+ Contract.Requires(cce.NonNullElements(newSubExprs));
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpr ret;
if (changed)
ret = Gen.Function(originalNode.Op,
newSubExprs, originalNode.TypeArguments);
@@ -2146,31 +2380,32 @@ namespace VC
VCExprLabelOp lop = originalNode.Op as VCExprLabelOp;
if(lop == null) return ret;
- if(!(ret is VCExprNAry!)) return ret;
+ if(!(ret is VCExprNAry)) return ret;
- VCExprNAry! retnary = (VCExprNAry!)ret;
- string! prefix = "si_fcall_"; // from Wlp.ssc::Cmd(...)
+ VCExprNAry retnary = (VCExprNAry)ret;
+ Contract.Assert(retnary != null);
+ string prefix = "si_fcall_"; // from Wlp.ssc::Cmd(...)
if(lop.label.Substring(1).StartsWith(prefix)) {
int id = Int32.Parse(lop.label.Substring(prefix.Length + 1));
- Hashtable! label2absy = getLabel2absy();
+ Hashtable label2absy = getLabel2absy();
Absy cmd = label2absy[id] as Absy;
//label2absy.Remove(id);
- assert cmd != null;
+ Contract.Assert( cmd != null);
AssumeCmd acmd = cmd as AssumeCmd;
- assert acmd != null;
+ Contract.Assert( acmd != null);
NAryExpr naryExpr = acmd.Expr as NAryExpr;
- assert naryExpr != null;
+ Contract.Assert( naryExpr != null);
- string! calleeName = naryExpr.Fun.FunctionName;
+ string calleeName = naryExpr.Fun.FunctionName;
VCExprNAry callExpr = retnary[0] as VCExprNAry;
- assert callExpr != null;
+ Contract.Assert( callExpr != null);
if(implName2StratifiedInliningInfo.ContainsKey(calleeName)) {
int candidateId = GetId(callExpr);
boogieExpr2Id[naryExpr] = candidateId;
- string! label = GetLabel(candidateId);
+ string label = GetLabel(candidateId);
return Gen.LabelPos(label, callExpr);
} else {
return callExpr;
@@ -2178,7 +2413,7 @@ namespace VC
}
// Else, rename label
- string! newLabel = RenameAbsyLabel(lop.label);
+ string newLabel = RenameAbsyLabel(lop.label);
if(lop.pos) {
return Gen.LabelPos(newLabel, retnary[0]);
} else {
@@ -2186,31 +2421,38 @@ namespace VC
}
}
-
+
} // end FCallHandler
public class FCallInliner : MutatingVCExprVisitor<bool> {
- public Dictionary<int, VCExpr!>! subst;
+ public Dictionary<int, VCExpr/*!*/>/*!*/ subst;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(subst));
+ }
- public FCallInliner(VCExpressionGenerator! gen)
- : base(gen)
- {
- subst = new Dictionary<int, VCExpr!>();
+
+ public FCallInliner(VCExpressionGenerator gen)
+ : base(gen) {
+ Contract.Requires(gen != null);
+ subst = new Dictionary<int, VCExpr>();
}
-
- public void Clear()
- {
- subst = new Dictionary<int, VCExpr!>();
+
+ public void Clear() {
+ subst = new Dictionary<int, VCExpr>();
}
-
- protected override VCExpr! UpdateModifiedNode(VCExprNAry! originalNode,
- List<VCExpr!>! newSubExprs,
- // has any of the subexpressions changed?
+
+ protected override VCExpr/*!*/ UpdateModifiedNode(VCExprNAry/*!*/ originalNode,
+ List<VCExpr/*!*/>/*!*/ newSubExprs,
+ // has any of the subexpressions changed?
bool changed,
bool arg)
{
- VCExpr! ret;
+ Contract.Requires(originalNode != null);Contract.Requires(newSubExprs != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpr ret;
if (changed)
ret = Gen.Function(originalNode.Op,
newSubExprs, originalNode.TypeArguments);
@@ -2219,9 +2461,9 @@ namespace VC
VCExprLabelOp lop = originalNode.Op as VCExprLabelOp;
if(lop == null) return ret;
- if(!(ret is VCExprNAry!)) return ret;
+ if(!(ret is VCExprNAry)) return ret;
- string! prefix = "si_fcall_"; // from FCallHandler::GetLabel
+ string prefix = "si_fcall_"; // from FCallHandler::GetLabel
if(lop.label.Substring(1).StartsWith(prefix)) {
int id = Int32.Parse(lop.label.Substring(prefix.Length + 1));
if(subst.ContainsKey(id)) {
@@ -2230,83 +2472,107 @@ namespace VC
}
return ret;
}
-
+
} // end FCallInliner
-
+
public class ErrorReporter : ProverInterface.ErrorHandler {
- Hashtable/*TransferCmd->ReturnCmd*/! gotoCmdOrigins;
- Hashtable/*<int, Absy!>*/! label2absy;
- List<Block!>! blocks;
- protected Dictionary<Incarnation, Absy!>! incarnationOriginMap;
- protected VerifierCallback! callback;
- internal string? resourceExceededMessage;
- static System.IO.TextWriter? modelWriter;
-
- public static TextWriter! ModelWriter {
+ Hashtable/*TransferCmd->ReturnCmd*//*!*/ gotoCmdOrigins;
+ Hashtable/*<int, Absy!>*//*!*/ label2absy;
+ List<Block/*!*/>/*!*/ blocks;
+ protected Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap;
+ protected VerifierCallback/*!*/ callback;
+ internal string resourceExceededMessage;
+ static System.IO.TextWriter modelWriter;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(gotoCmdOrigins != null);
+ Contract.Invariant(label2absy != null);
+ Contract.Invariant(cce.NonNullElements(blocks));
+ Contract.Invariant(cce.NonNullElements(incarnationOriginMap));
+ Contract.Invariant(callback != null);
+ Contract.Invariant(cce.NonNullElements(implName2LazyInliningInfo));
+ Contract.Invariant(context != null);
+ Contract.Invariant(program != null);
+ }
+
+
+ public static TextWriter ModelWriter {
get {
+ Contract.Ensures(Contract.Result<TextWriter>() != null);
+
if (ErrorReporter.modelWriter == null)
ErrorReporter.modelWriter = CommandLineOptions.Clo.PrintErrorModelFile == null ? Console.Out : new StreamWriter(CommandLineOptions.Clo.PrintErrorModelFile, false);
return ErrorReporter.modelWriter;
}
- }
-
- Dictionary<string!, LazyInliningInfo!>! implName2LazyInliningInfo;
- DeclFreeProverContext! context;
- Program! program;
-
- public ErrorReporter(Hashtable/*TransferCmd->ReturnCmd*/! gotoCmdOrigins,
- Hashtable/*<int, Absy!>*/! label2absy,
- List<Block!>! blocks,
- Dictionary<Incarnation, Absy!>! incarnationOriginMap,
- VerifierCallback! callback,
- Dictionary<string!, LazyInliningInfo!>! implName2LazyInliningInfo,
- DeclFreeProverContext! context,
- Program! program)
- {
+ }
+
+ Dictionary<string/*!*/, LazyInliningInfo/*!*/>/*!*/ implName2LazyInliningInfo;
+ DeclFreeProverContext/*!*/ context;
+ Program/*!*/ program;
+
+ public ErrorReporter(Hashtable/*TransferCmd->ReturnCmd*//*!*/ gotoCmdOrigins,
+ Hashtable/*<int, Absy!>*//*!*/ label2absy,
+ List<Block/*!*/>/*!*/ blocks,
+ Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap,
+ VerifierCallback/*!*/ callback,
+ Dictionary<string/*!*/, LazyInliningInfo/*!*/>/*!*/ implName2LazyInliningInfo,
+ DeclFreeProverContext/*!*/ context,
+ Program/*!*/ program) {
+ Contract.Requires(gotoCmdOrigins != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(cce.NonNullElements(blocks));
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
+ Contract.Requires(callback != null);
+ Contract.Requires(cce.NonNullElements(implName2LazyInliningInfo));
+ Contract.Requires(context!=null);
+ Contract.Requires(program!=null);
this.gotoCmdOrigins = gotoCmdOrigins;
this.label2absy = label2absy;
this.blocks = blocks;
this.incarnationOriginMap = incarnationOriginMap;
this.callback = callback;
-
+
this.implName2LazyInliningInfo = implName2LazyInliningInfo;
this.context = context;
this.program = program;
// base();
}
- public override void OnModel(IList<string!>! labels, ErrorModel errModel) {
+ public override void OnModel(IList<string/*!*/>/*!*/ labels, ErrorModel errModel) {
+ Contract.Requires(cce.NonNullElements(labels));
if (CommandLineOptions.Clo.PrintErrorModel >= 1 && errModel != null) {
- errModel.Print(ErrorReporter.ModelWriter);
- ErrorReporter.ModelWriter.Flush();
+ errModel.Print(ErrorReporter.ModelWriter);
+ ErrorReporter.ModelWriter.Flush();
}
Hashtable traceNodes = new Hashtable();
- foreach (string! s in labels) {
- Absy! absy = Label2Absy(s);
+ foreach (string s in labels) {
+ Contract.Assert(s != null);
+ Absy absy = Label2Absy(s);
+ Contract.Assert(absy != null);
if (traceNodes.ContainsKey(absy))
System.Console.WriteLine("Warning: duplicate label: " + s + " read while tracing nodes");
else
traceNodes.Add(absy, null);
}
- BlockSeq! trace = new BlockSeq();
- Block! entryBlock = (!) this.blocks[0];
- assert traceNodes.Contains(entryBlock);
+ BlockSeq trace = new BlockSeq();
+ Block entryBlock = cce.NonNull(this.blocks[0]);
+ Contract.Assert(traceNodes.Contains(entryBlock));
trace.Add(entryBlock);
- Counterexample newCounterexample = TraceCounterexample(entryBlock, traceNodes, trace, errModel, incarnationOriginMap, implName2LazyInliningInfo, context, program, new Dictionary<Absy!, CalleeCounterexampleInfo!>());
+ Counterexample newCounterexample = TraceCounterexample(entryBlock, traceNodes, trace, errModel, incarnationOriginMap, implName2LazyInliningInfo, context, program, new Dictionary<Absy, CalleeCounterexampleInfo>());
+
+ if (newCounterexample == null)
+ return;
- if (newCounterexample == null) return;
-
#region Map passive program errors back to original program errors
ReturnCounterexample returnExample = newCounterexample as ReturnCounterexample;
- if (returnExample != null)
- {
- foreach (Block! b in returnExample.Trace) {
- assume b.TransferCmd != null;
- ReturnCmd cmd = (ReturnCmd) gotoCmdOrigins[b.TransferCmd];
- if (cmd != null)
- {
+ if (returnExample != null) {
+ foreach (Block b in returnExample.Trace) {
+ Contract.Assert(b != null);
+ Contract.Assume(b.TransferCmd != null);
+ ReturnCmd cmd = (ReturnCmd)gotoCmdOrigins[b.TransferCmd];
+ if (cmd != null) {
returnExample.FailingReturn = cmd;
break;
}
@@ -2316,37 +2582,49 @@ namespace VC
callback.OnCounterexample(newCounterexample, null);
}
- public override Absy! Label2Absy(string! label)
- {
+ public override Absy Label2Absy(string label) {
+ Contract.Requires(label != null);
+ Contract.Ensures(Contract.Result<Absy>() != null);
+
int id = int.Parse(label);
- return (Absy!) label2absy[id];
+ return cce.NonNull((Absy)label2absy[id]);
}
- public override void OnResourceExceeded(string! msg)
- {
+ public override void OnResourceExceeded(string msg) {
+ Contract.Requires(msg != null);
resourceExceededMessage = msg;
}
-
- public override void OnProverWarning(string! msg)
- {
+
+ public override void OnProverWarning(string msg) {
+ Contract.Requires(msg != null);
callback.OnWarning(msg);
}
}
-
+
public class ErrorReporterLocal : ErrorReporter {
- public ErrorReporterLocal(Hashtable/*TransferCmd->ReturnCmd*/! gotoCmdOrigins,
- Hashtable/*<int, Absy!>*/! label2absy,
- List<Block!>! blocks,
- Dictionary<Incarnation, Absy!>! incarnationOriginMap,
- VerifierCallback! callback,
- Dictionary<string!, LazyInliningInfo!>! implName2LazyInliningInfo,
- DeclFreeProverContext! context,
- Program! program)
+ public ErrorReporterLocal(Hashtable/*TransferCmd->ReturnCmd*//*!*/ gotoCmdOrigins,
+ Hashtable/*<int, Absy!>*//*!*/ label2absy,
+ List<Block/*!*/>/*!*/ blocks,
+ Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap,
+ VerifierCallback/*!*/ callback,
+ Dictionary<string/*!*/, LazyInliningInfo/*!*/>/*!*/ implName2LazyInliningInfo,
+ DeclFreeProverContext/*!*/ context,
+ Program/*!*/ program)
+ : base(gotoCmdOrigins, label2absy, blocks, incarnationOriginMap, callback, implName2LazyInliningInfo, context, program) // here for aesthetic purposes //TODO: Maybe nix?
{
- base(gotoCmdOrigins, label2absy, blocks, incarnationOriginMap, callback, implName2LazyInliningInfo, context, program); // here for aesthetic purposes
+ Contract.Requires(gotoCmdOrigins != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(cce.NonNullElements(blocks));
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
+ Contract.Requires(callback != null);
+ Contract.Requires(cce.NonNullElements(implName2LazyInliningInfo));
+ Contract.Requires(context != null);
+ Contract.Requires(program != null);
+
}
- public override void OnModel(IList<string!>! labels, ErrorModel errModel) {
+ public override void OnModel(IList<string/*!*/>/*!*/ labels, ErrorModel errModel) {
+ Contract.Requires(cce.NonNullElements(labels));
// We ignore the error model here for enhanced error message purposes.
// It is only printed to the command line.
if (CommandLineOptions.Clo.PrintErrorModel >= 1 && errModel != null) {
@@ -2355,9 +2633,10 @@ namespace VC
ErrorReporter.ModelWriter.Flush();
}
}
- List<Block!> traceNodes = new List<Block!>();
- List<AssertCmd!> assertNodes = new List<AssertCmd!>();
- foreach (string! s in labels) {
+ List<Block> traceNodes = new List<Block>();
+ List<AssertCmd> assertNodes = new List<AssertCmd>();
+ foreach (string s in labels) {
+ Contract.Assert(s != null);
Absy node = Label2Absy(s);
if (node is Block) {
Block b = (Block)node;
@@ -2367,8 +2646,8 @@ namespace VC
assertNodes.Add(a);
}
}
- assert assertNodes.Count > 0;
- assert traceNodes.Count == assertNodes.Count;
+ Contract.Assert(assertNodes.Count > 0);
+ Contract.Assert(traceNodes.Count == assertNodes.Count);
foreach (AssertCmd a in assertNodes) {
// find the corresponding Block (assertNodes.Count is likely to be 1, or small in any case, so just do a linear search here)
@@ -2376,34 +2655,53 @@ namespace VC
if (b.Cmds.Has(a)) {
BlockSeq trace = new BlockSeq();
trace.Add(b);
- Counterexample newCounterexample = AssertCmdToCounterexample(a, (!)b.TransferCmd, trace, errModel, incarnationOriginMap);
+ Counterexample newCounterexample = AssertCmdToCounterexample(a, cce.NonNull(b.TransferCmd), trace, errModel, incarnationOriginMap);
callback.OnCounterexample(newCounterexample, null);
goto NEXT_ASSERT;
}
}
- assert false; // there was no block that contains the assert
- NEXT_ASSERT: {}
+ Contract.Assert(false);
+ throw new cce.UnreachableException(); // there was no block that contains the assert
+ NEXT_ASSERT: {
+ }
}
}
}
public class StratifiedInliningErrorReporter : ProverInterface.ErrorHandler {
- Dictionary<string!, StratifiedInliningInfo!>! implName2StratifiedInliningInfo;
- ProverInterface! theoremProver;
- VerifierCallback! callback;
+ Dictionary<string/*!*/, StratifiedInliningInfo/*!*/>/*!*/ implName2StratifiedInliningInfo;
+ ProverInterface/*!*/ theoremProver;
+ VerifierCallback/*!*/ callback;
FCallHandler calls;
- Program! program;
- Implementation! mainImpl;
- DeclFreeProverContext! context;
+ Program/*!*/ program;
+ Implementation/*!*/ mainImpl;
+ DeclFreeProverContext/*!*/ context;
Hashtable/*TransferCmd->ReturnCmd*/ gotoCmdOrigins;
-
+
public bool underapproximationMode;
- public List<int>! candidatesToExpand;
-
- public StratifiedInliningErrorReporter(Dictionary<string!, StratifiedInliningInfo!>! implName2StratifiedInliningInfo,
- ProverInterface! theoremProver, VerifierCallback! callback, DeclFreeProverContext! context,
+ public List<int>/*!*/ candidatesToExpand;
+
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(candidatesToExpand != null);
+ Contract.Invariant(context != null);
+ Contract.Invariant(mainImpl != null);
+ Contract.Invariant(program != null);
+ Contract.Invariant(callback != null);
+ Contract.Invariant(theoremProver != null);
+ Contract.Invariant(cce.NonNullElements(implName2StratifiedInliningInfo));
+ }
+
+
+ public StratifiedInliningErrorReporter(Dictionary<string/*!*/, StratifiedInliningInfo/*!*/>/*!*/ implName2StratifiedInliningInfo,
+ ProverInterface/*!*/ theoremProver, VerifierCallback/*!*/ callback, DeclFreeProverContext/*!*/ context,
Hashtable/*TransferCmd->ReturnCmd*/ gotoCmdOrigins,
- Program! program, Implementation! mainImpl) {
+ Program/*!*/ program, Implementation/*!*/ mainImpl) {
+ Contract.Requires(cce.NonNullElements(implName2StratifiedInliningInfo));
+ Contract.Requires(theoremProver != null);
+ Contract.Requires(callback != null);
+ Contract.Requires(context != null);
+ Contract.Requires(mainImpl != null);
this.implName2StratifiedInliningInfo = implName2StratifiedInliningInfo;
this.theoremProver = theoremProver;
this.callback = callback;
@@ -2416,185 +2714,209 @@ namespace VC
this.gotoCmdOrigins = gotoCmdOrigins;
}
- public void SetCandidateHandler(FCallHandler! calls)
- {
+ public void SetCandidateHandler(FCallHandler calls) {
+ Contract.Requires(calls != null);
this.calls = calls;
}
-
- public override void OnModel(IList<string!>! labels, ErrorModel errModel) {
- if(underapproximationMode) {
- if(errModel == null) return;
+
+ public override void OnModel(IList<string/*!*/>/*!*/ labels, ErrorModel errModel) {
+ Contract.Requires(cce.NonNullElements(labels));
+ if (underapproximationMode) {
+ if (errModel == null)
+ return;
GenerateTraceMain(labels, errModel);
return;
}
-
- assert calls != null;
- assert errModel != null;
-
+
+ Contract.Assert(calls != null);
+ Contract.Assert(errModel != null);
+
candidatesToExpand = new List<int>();
- foreach(string! lab in labels)
- {
- int id = calls.GetId(lab);
- if(id < 0) continue;
- if(!calls.currCandidates.Contains(id)) continue;
- candidatesToExpand.Add(id);
+ foreach (string lab in labels) {
+ Contract.Assert(lab != null);
+ int id = calls.GetId(lab);
+ if (id < 0)
+ continue;
+ if (!calls.currCandidates.Contains(id))
+ continue;
+ candidatesToExpand.Add(id);
}
-
+
}
-
+
// Construct the interprocedural trace
- private void GenerateTraceMain(IList<string!>! labels, ErrorModel! errModel) {
+ private void GenerateTraceMain(IList<string/*!*/>/*!*/ labels, ErrorModel/*!*/ errModel) {
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(labels));
if (CommandLineOptions.Clo.PrintErrorModel >= 1 && errModel != null) {
- errModel.Print(ErrorReporter.ModelWriter);
- ErrorReporter.ModelWriter.Flush();
+ errModel.Print(ErrorReporter.ModelWriter);
+ ErrorReporter.ModelWriter.Flush();
}
-
- Counterexample newCounterexample =
+
+ Counterexample newCounterexample =
GenerateTrace(labels, errModel, 0, mainImpl);
- if(newCounterexample == null) return;
-
+ if (newCounterexample == null)
+ return;
+
#region Map passive program errors back to original program errors
ReturnCounterexample returnExample = newCounterexample as ReturnCounterexample;
- if (returnExample != null && gotoCmdOrigins != null)
- {
- foreach (Block! b in returnExample.Trace) {
- assume b.TransferCmd != null;
- ReturnCmd cmd = (ReturnCmd) gotoCmdOrigins[b.TransferCmd];
- if (cmd != null)
- {
+ if (returnExample != null && gotoCmdOrigins != null) {
+ foreach (Block b in returnExample.Trace) {
+ Contract.Assert(b != null);
+ Contract.Assume(b.TransferCmd != null);
+ ReturnCmd cmd = (ReturnCmd)gotoCmdOrigins[b.TransferCmd];
+ if (cmd != null) {
returnExample.FailingReturn = cmd;
break;
}
}
}
#endregion
-
+
callback.OnCounterexample(newCounterexample, null);
}
-
- private Counterexample GenerateTrace(IList<string!>! labels, ErrorModel! errModel,
- int candidateId, Implementation! procImpl) {
+
+ private Counterexample GenerateTrace(IList<string/*!*/>/*!*/ labels, ErrorModel/*!*/ errModel,
+ int candidateId, Implementation procImpl) {
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(labels));
+ Contract.Requires(procImpl != null);
Hashtable traceNodes = new Hashtable();
- string! procPrefix = "si_inline_" + candidateId.ToString() + "_";
+ string procPrefix = "si_inline_" + candidateId.ToString() + "_";
- foreach (string! s in labels) {
- if(!s.StartsWith(procPrefix))
+ foreach (string s in labels) {
+ Contract.Assert(s != null);
+ if (!s.StartsWith(procPrefix))
continue;
-
- Absy! absy;
-
- if(candidateId == 0) {
- absy = Label2Absy(s.Substring(procPrefix.Length));
+
+ Absy absy;
+
+ if (candidateId == 0) {
+ absy = Label2Absy(s.Substring(procPrefix.Length));
} else {
- absy = Label2Absy(procImpl.Name, s.Substring(procPrefix.Length));
+ absy = Label2Absy(procImpl.Name, s.Substring(procPrefix.Length));
}
-
+
if (traceNodes.ContainsKey(absy))
System.Console.WriteLine("Warning: duplicate label: " + s + " read while tracing nodes");
else
traceNodes.Add(absy, null);
}
- BlockSeq! trace = new BlockSeq();
- Block! entryBlock = (!) procImpl.Blocks[0];
- assert traceNodes.Contains(entryBlock);
+ BlockSeq trace = new BlockSeq();
+ Block entryBlock = cce.NonNull(procImpl.Blocks[0]);
+ Contract.Assert(entryBlock != null);
+ Contract.Assert(traceNodes.Contains(entryBlock));
trace.Add(entryBlock);
- Dictionary<Absy!, CalleeCounterexampleInfo!>! calleeCounterexamples = new Dictionary<Absy!, CalleeCounterexampleInfo!>();
+ Dictionary<Absy, CalleeCounterexampleInfo> calleeCounterexamples = new Dictionary<Absy, CalleeCounterexampleInfo>();
Counterexample newCounterexample = GenerateTraceRec(labels, errModel, entryBlock, traceNodes, trace, calleeCounterexamples);
return newCounterexample;
}
-
- private Counterexample GenerateTraceRec(
- IList<string!>! labels, ErrorModel! errModel,
- Block! b, Hashtable! traceNodes, BlockSeq! trace,
- Dictionary<Absy!, CalleeCounterexampleInfo!>! calleeCounterexamples)
- {
- // After translation, all potential errors come from asserts.
- CmdSeq! cmds = b.Cmds;
- TransferCmd! transferCmd = (!)b.TransferCmd;
- for (int i = 0; i < cmds.Length; i++)
- {
- Cmd! cmd = (!) cmds[i];
-
- // Skip if 'cmd' not contained in the trace or not an assert
- if (cmd is AssertCmd && traceNodes.Contains(cmd))
- {
- Counterexample! newCounterexample = AssertCmdToCounterexample((AssertCmd)cmd, transferCmd, trace, errModel, new Dictionary<Incarnation, Absy!>());
- newCounterexample.AddCalleeCounterexample(calleeCounterexamples);
- return newCounterexample;
+
+ private Counterexample GenerateTraceRec(
+ IList<string/*!*/>/*!*/ labels, ErrorModel/*!*/ errModel,
+ Block/*!*/ b, Hashtable/*!*/ traceNodes, BlockSeq/*!*/ trace,
+ Dictionary<Absy/*!*/, CalleeCounterexampleInfo/*!*/>/*!*/ calleeCounterexamples) {
+ Contract.Requires(cce.NonNullElements(labels));
+ Contract.Requires(errModel != null);
+ Contract.Requires(b != null);
+ Contract.Requires(traceNodes != null);
+ Contract.Requires(trace != null);
+ Contract.Requires(cce.NonNullElements(calleeCounterexamples));
+ // After translation, all potential errors come from asserts.
+ CmdSeq cmds = b.Cmds;
+ TransferCmd transferCmd = cce.NonNull(b.TransferCmd);
+ for (int i = 0; i < cmds.Length; i++) {
+ Cmd cmd = cce.NonNull(cmds[i]);
+
+ // Skip if 'cmd' not contained in the trace or not an assert
+ if (cmd is AssertCmd && traceNodes.Contains(cmd)) {
+ Counterexample newCounterexample = AssertCmdToCounterexample((AssertCmd)cmd, transferCmd, trace, errModel, new Dictionary<Incarnation, Absy/*!*/>());
+ newCounterexample.AddCalleeCounterexample(calleeCounterexamples);
+ return newCounterexample;
+ }
+
+ // Counterexample generation for inlined procedures
+ AssumeCmd assumeCmd = cmd as AssumeCmd;
+ if (assumeCmd == null)
+ continue;
+ NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
+ if (naryExpr == null)
+ continue;
+ string calleeName = naryExpr.Fun.FunctionName;
+ Contract.Assert(calleeName != null);
+ if (!implName2StratifiedInliningInfo.ContainsKey(calleeName))
+ continue;
+
+ Contract.Assert(calls != null);
+ int calleeId = calls.boogieExpr2Id[naryExpr];
+
+ calleeCounterexamples[assumeCmd] =
+ new CalleeCounterexampleInfo(
+ cce.NonNull(GenerateTrace(labels, errModel, calleeId, implName2StratifiedInliningInfo[calleeName].impl)),
+ new List<object>());
+
}
-
- // Counterexample generation for inlined procedures
- AssumeCmd assumeCmd = cmd as AssumeCmd;
- if (assumeCmd == null) continue;
- NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
- if (naryExpr == null) continue;
- string! calleeName = naryExpr.Fun.FunctionName;
- if (!implName2StratifiedInliningInfo.ContainsKey(calleeName)) continue;
-
- assert calls != null;
- int calleeId = calls.boogieExpr2Id[naryExpr];
-
- calleeCounterexamples[assumeCmd] =
- new CalleeCounterexampleInfo(
- (!)GenerateTrace(labels, errModel, calleeId, implName2StratifiedInliningInfo[calleeName].impl),
- new List<object!>());
- }
-
- GotoCmd gotoCmd = transferCmd as GotoCmd;
- if (gotoCmd != null)
- {
- foreach (Block! bb in (!)gotoCmd.labelTargets)
- {
- if (traceNodes.Contains(bb)){
- trace.Add(bb);
- return GenerateTraceRec(labels, errModel, bb, traceNodes, trace, calleeCounterexamples);
+ GotoCmd gotoCmd = transferCmd as GotoCmd;
+ if (gotoCmd != null) {
+ foreach (Block bb in cce.NonNull(gotoCmd.labelTargets)) {
+ Contract.Assert(bb != null);
+ if (traceNodes.Contains(bb)) {
+ trace.Add(bb);
+ return GenerateTraceRec(labels, errModel, bb, traceNodes, trace, calleeCounterexamples);
+ }
}
}
+
+ return null;
+
}
- return null;
+ public override Absy Label2Absy(string label) {
+ Contract.Requires(label != null);
+ Contract.Ensures(Contract.Result<Absy>() != null);
- }
-
- public override Absy! Label2Absy(string! label)
- {
int id = int.Parse(label);
- assert calls != null;
- return (Absy!) calls.mainLabel2absy[id];
+ Contract.Assert(calls != null);
+ return cce.NonNull((Absy)calls.mainLabel2absy[id]);
}
- public Absy! Label2Absy(string! procName, string! label)
- {
+ public Absy Label2Absy(string procName, string label) {
+ Contract.Requires(label != null);
+ Contract.Requires(procName != null);
+ Contract.Ensures(Contract.Result<Absy>() != null);
+
int id = int.Parse(label);
- Hashtable! l2a = (!)implName2StratifiedInliningInfo[procName].label2absy;
- return (Absy!) l2a[id];
+ Hashtable l2a = cce.NonNull(implName2StratifiedInliningInfo[procName]).label2absy;
+ return cce.NonNull((Absy)l2a[id]);
}
-
- public override void OnResourceExceeded(string! msg)
- {
+
+ public override void OnResourceExceeded(string msg) {
+ Contract.Requires(msg != null);
//resourceExceededMessage = msg;
}
-
- public override void OnProverWarning(string! msg)
- {
+
+ public override void OnProverWarning(string msg) {
+ Contract.Requires(msg != null);
callback.OnWarning(msg);
}
}
- protected void ConvertCFG2DAG(Implementation! impl, Program! program)
+ protected void ConvertCFG2DAG(Implementation impl, Program program)
{
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
impl.PruneUnreachableBlocks(); // This is needed for VCVariety.BlockNested, and is otherwise just an optimization
current_impl = impl;
variable2SequenceNumber = new Hashtable/*Variable -> int*/();
- incarnationOriginMap = new Dictionary<Incarnation, Absy!>();
+ incarnationOriginMap = new Dictionary<Incarnation, Absy>();
#region Debug Tracing
if (CommandLineOptions.Clo.TraceVerify)
@@ -2619,7 +2941,7 @@ namespace VC
#region Use the graph library to figure out where the (natural) loops are
#region Create the graph by adding the source node and each edge
- Graph<Block>! g = GraphFromImpl(impl);
+ Graph<Block> g = GraphFromImpl(impl);
#endregion
g.ComputeLoops(); // this is the call that does all of the processing
@@ -2631,10 +2953,11 @@ namespace VC
#endregion
#region Cut the backedges, push assert/assume statements from loop header into predecessors, change them all into assume statements at top of loop, introduce havoc statements
- foreach (Block! header in (!) g.Headers)
+ foreach (Block header in cce.NonNull( g.Headers))
{
- IDictionary<Block!,object> backEdgeNodes = new Dictionary<Block!,object>();
- foreach (Block! b in (!) g.BackEdgeNodes(header)) { backEdgeNodes.Add(b, null); }
+ Contract.Assert(header != null);
+ IDictionary<Block,object> backEdgeNodes = new Dictionary<Block,object>();
+ foreach (Block b in cce.NonNull( g.BackEdgeNodes(header))) {Contract.Assert(b != null); backEdgeNodes.Add(b, null); }
#region Find the (possibly empty) prefix of assert commands in the header, replace each assert with an assume of the same condition
CmdSeq prefixOfPredicateCmdsInit = new CmdSeq();
@@ -2654,7 +2977,7 @@ namespace VC
prefixOfPredicateCmdsMaintained.Add(b);
header.Cmds[i] = new AssumeCmd(c.tok,c.Expr);
} else {
- assert a is AssumeCmd;
+ Contract.Assert( a is AssumeCmd);
if (Bpl.CommandLineOptions.Clo.AlwaysAssumeFreeLoopInvariants) {
// Usually, "free" stuff, like free loop invariants (and the assume statements
// that stand for such loop invariants) are ignored on the checking side. This
@@ -2678,14 +3001,14 @@ namespace VC
#region Copy the prefix of predicate commands into each predecessor. Do this *before* cutting the backedge!!
for ( int predIndex = 0, n = header.Predecessors.Length; predIndex < n; predIndex++ )
{
- Block! pred = (!)header.Predecessors[predIndex];
+ Block pred = cce.NonNull(header.Predecessors[predIndex]);
// Create a block between header and pred for the predicate commands if pred has more than one successor
- GotoCmd gotocmd = (GotoCmd!)pred.TransferCmd;
- assert gotocmd.labelNames != null; // if "pred" is really a predecessor, it may be a GotoCmd with at least one label
+ GotoCmd gotocmd = cce.NonNull((GotoCmd)pred.TransferCmd);
+ Contract.Assert( gotocmd.labelNames != null); // if "pred" is really a predecessor, it may be a GotoCmd with at least one label
if (gotocmd.labelNames.Length > 1)
{
- Block! newBlock = CreateBlockBetween(predIndex, header);
+ Block newBlock = CreateBlockBetween(predIndex, header);
impl.Blocks.Add(newBlock);
// if pred is a back edge node, then now newBlock is the back edge node
@@ -2708,8 +3031,8 @@ namespace VC
#endregion
#region Cut the back edge
- foreach (Block! backEdgeNode in (!)backEdgeNodes.Keys)
- {
+ foreach (Block backEdgeNode in cce.NonNull(backEdgeNodes.Keys))
+ {Contract.Assert(backEdgeNode != null);
Debug.Assert(backEdgeNode.TransferCmd is GotoCmd,"An node was identified as the source for a backedge, but it does not have a goto command.");
GotoCmd gtc = backEdgeNode.TransferCmd as GotoCmd;
if (gtc != null && gtc.labelTargets != null && gtc.labelTargets.Length > 1 )
@@ -2717,7 +3040,7 @@ namespace VC
// then remove the backedge by removing the target block from the list of gotos
BlockSeq remainingTargets = new BlockSeq();
StringSeq remainingLabels = new StringSeq();
- assume gtc.labelNames != null;
+ Contract.Assume( gtc.labelNames != null);
for (int i = 0, n = gtc.labelTargets.Length; i < n; i++)
{
if ( gtc.labelTargets[i] != header )
@@ -2752,19 +3075,23 @@ namespace VC
#region Collect all variables that are assigned to in all of the natural loops for which this is the header
VariableSeq varsToHavoc = new VariableSeq();
- foreach (Block! backEdgeNode in (!) g.BackEdgeNodes(header))
+ foreach (Block backEdgeNode in cce.NonNull( g.BackEdgeNodes(header)))
{
- foreach ( Block! b in g.NaturalLoops(header,backEdgeNode) )
+ Contract.Assert(backEdgeNode != null);
+ foreach ( Block b in g.NaturalLoops(header,backEdgeNode) )
{
- foreach ( Cmd! c in b.Cmds )
+ Contract.Assert(b != null);
+ foreach ( Cmd c in b.Cmds )
{
+ Contract.Assert(c != null);
c.AddAssignedVariables(varsToHavoc);
}
}
}
IdentifierExprSeq havocExprs = new IdentifierExprSeq();
- foreach ( Variable! v in varsToHavoc )
+ foreach ( Variable v in varsToHavoc )
{
+ Contract.Assert(v != null);
IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v);
if(!havocExprs.Has(ie))
havocExprs.Add(ie);
@@ -2793,8 +3120,12 @@ namespace VC
#endregion
}
- protected Hashtable/*TransferCmd->ReturnCmd*/! PassifyImpl(Implementation! impl, Program! program)
+ protected Hashtable/*TransferCmd->ReturnCmd*/ PassifyImpl(Implementation impl, Program program)
{
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Ensures(Contract.Result<Hashtable>() != null);
+
Hashtable/*TransferCmd->ReturnCmd*/ gotoCmdOrigins = new Hashtable/*TransferCmd->ReturnCmd*/();
Block exitBlock = GenerateUnifiedExit(impl, gotoCmdOrigins);
@@ -2820,7 +3151,7 @@ namespace VC
// where clauses of in- and out-parameters
cc.AddRange(GetParamWhereClauses(impl));
// where clauses of local variables
- foreach (Variable! lvar in impl.LocVars) {
+ foreach (Variable lvar in impl.LocVars) {Contract.Assert(lvar != null);
if (lvar.TypedIdent.WhereExpr != null) {
Cmd c = new AssumeCmd(lvar.tok, lvar.TypedIdent.WhereExpr);
cc.Add(c);
@@ -2838,7 +3169,8 @@ namespace VC
#region Support for lazy inlining
if (implName2LazyInliningInfo != null && implName2LazyInliningInfo.ContainsKey(impl.Name))
{
- Expr! assertExpr = implName2LazyInliningInfo[impl.Name].assertExpr;
+ Expr assertExpr = implName2LazyInliningInfo[impl.Name].assertExpr;
+ Contract.Assert(assertExpr != null);
exitBlock.Cmds.Add(new AssertCmd(Token.NoToken, assertExpr));
}
#endregion
@@ -2846,7 +3178,8 @@ namespace VC
#region Support for lazy inlining
if (implName2StratifiedInliningInfo != null && implName2StratifiedInliningInfo.ContainsKey(impl.Name))
{
- Expr! assertExpr = implName2StratifiedInliningInfo[impl.Name].assertExpr;
+ Expr assertExpr = implName2StratifiedInliningInfo[impl.Name].assertExpr;
+ Contract.Assert(assertExpr != null);
exitBlock.Cmds.Add(new AssertCmd(Token.NoToken, assertExpr));
}
#endregion
@@ -2876,13 +3209,15 @@ namespace VC
Hashtable exitIncarnationMap = Convert2PassiveCmd(impl);
if (implName2LazyInliningInfo != null && implName2LazyInliningInfo.ContainsKey(impl.Name))
{
- LazyInliningInfo! info = implName2LazyInliningInfo[impl.Name];
+ LazyInliningInfo info = implName2LazyInliningInfo[impl.Name];
+ Contract.Assert(info != null);
info.exitIncarnationMap = exitIncarnationMap;
info.incarnationOriginMap = this.incarnationOriginMap;
}
if (implName2StratifiedInliningInfo != null && implName2StratifiedInliningInfo.ContainsKey(impl.Name))
{
- StratifiedInliningInfo! info = implName2StratifiedInliningInfo[impl.Name];
+ StratifiedInliningInfo info = implName2StratifiedInliningInfo[impl.Name];
+ Contract.Assert(info != null);
info.exitIncarnationMap = exitIncarnationMap;
info.incarnationOriginMap = this.incarnationOriginMap;
}
@@ -2899,7 +3234,7 @@ namespace VC
if (CommandLineOptions.Clo.RemoveEmptyBlocks){
#region Get rid of empty blocks
{
- Block! entryBlock = (!) impl.Blocks[0];
+ Block entryBlock = cce.NonNull( impl.Blocks[0]);
RemoveEmptyBlocks(entryBlock);
impl.PruneUnreachableBlocks();
}
@@ -2917,17 +3252,17 @@ namespace VC
if (CommandLineOptions.Clo.ExpandLambdas)
{
- List<Expr!>! axioms;
- List<Function!>! functions;
+ List<Expr> axioms;
+ List<Function> functions;
LambdaHelper.Desugar(impl, out axioms, out functions);
// TODO: do something with functions (Z3 currently doesn't need them)
if (axioms.Count > 0) {
CmdSeq cmds = new CmdSeq();
- foreach (Expr! ax in axioms) {
+ foreach (Expr ax in axioms) {Contract.Assert(ax != null);
cmds.Add(new AssumeCmd(ax.tok, ax));
}
- Block! entryBlock = (!) impl.Blocks[0];
+ Block entryBlock = cce.NonNull( impl.Blocks[0]);
cmds.AddRange(entryBlock.Cmds);
entryBlock.Cmds = cmds;
}
@@ -2948,36 +3283,46 @@ namespace VC
return gotoCmdOrigins;
}
- private static Counterexample! LazyCounterexample(
- ErrorModel! errModel,
- Dictionary<string!, LazyInliningInfo!>! implName2LazyInliningInfo,
- DeclFreeProverContext! context,
- Program! program,
- string! implName, List<int>! values)
- {
- VCExprTranslator! vcExprTranslator = (!)context.exprTranslator;
- Boogie2VCExprTranslator! boogieExprTranslator = context.BoogieExprTranslator;
- LazyInliningInfo! info = implName2LazyInliningInfo[implName];
- BlockSeq! trace = new BlockSeq();
- Block! b = ((!) info.impl).Blocks[0];
+ private static Counterexample LazyCounterexample(
+ ErrorModel/*!*/ errModel,
+ Dictionary<string/*!*/, LazyInliningInfo/*!*/>/*!*/ implName2LazyInliningInfo,
+ DeclFreeProverContext/*!*/ context,
+ Program/*!*/ program,
+ string/*!*/ implName, List<int>/*!*/ values)
+ {
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(implName2LazyInliningInfo));
+ Contract.Requires(context != null);
+ Contract.Requires(program != null);
+ Contract.Requires(implName != null);
+ Contract.Requires(values != null);
+ Contract.Ensures(Contract.Result<Counterexample>() != null);
+
+ VCExprTranslator vcExprTranslator = cce.NonNull(context.exprTranslator);
+ Boogie2VCExprTranslator boogieExprTranslator = context.BoogieExprTranslator;
+ Contract.Assert(boogieExprTranslator != null);
+ LazyInliningInfo info = implName2LazyInliningInfo[implName];
+ Contract.Assert(info != null);
+ BlockSeq trace = new BlockSeq();
+ Block b = cce.NonNull( info.impl).Blocks[0];
trace.Add(b);
- VCExprVar! cfcVar = boogieExprTranslator.LookupVariable(info.controlFlowVariable);
- string! cfcName = vcExprTranslator.Lookup(cfcVar);
+ VCExprVar cfcVar = boogieExprTranslator.LookupVariable(info.controlFlowVariable);
+ string cfcName = vcExprTranslator.Lookup(cfcVar);
int cfcPartition = errModel.LookupSkolemFunctionAt(cfcName + "!" + info.uniqueId, values);
int cfcValue = errModel.LookupPartitionValue(cfcPartition);
- Dictionary<Absy!, CalleeCounterexampleInfo!> calleeCounterexamples = new Dictionary<Absy!, CalleeCounterexampleInfo!>();
+ Dictionary<Absy, CalleeCounterexampleInfo> calleeCounterexamples = new Dictionary<Absy, CalleeCounterexampleInfo>();
while (true) {
- CmdSeq! cmds = b.Cmds;
- TransferCmd! transferCmd = (!)b.TransferCmd;
+ CmdSeq cmds = b.Cmds;Contract.Assert(cmds != null);
+ TransferCmd transferCmd = cce.NonNull(b.TransferCmd);
for (int i = 0; i < cmds.Length; i++)
{
- Cmd! cmd = (!) cmds[i];
+ Cmd cmd = cce.NonNull( cmds[i]);
AssertCmd assertCmd = cmd as AssertCmd;
if (assertCmd != null && errModel.LookupControlFlowFunctionAt(cfcValue, assertCmd.UniqueId) == 0)
{
Counterexample newCounterexample;
- newCounterexample = AssertCmdToCounterexample(assertCmd, transferCmd, trace, errModel, (!)info.incarnationOriginMap);
+ newCounterexample = AssertCmdToCounterexample(assertCmd, transferCmd, trace, errModel, cce.NonNull(info.incarnationOriginMap));
newCounterexample.AddCalleeCounterexample(calleeCounterexamples);
return newCounterexample;
}
@@ -2986,12 +3331,13 @@ namespace VC
if (assumeCmd == null) continue;
NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
if (naryExpr == null) continue;
- string! calleeName = naryExpr.Fun.FunctionName;
+ string calleeName = naryExpr.Fun.FunctionName;
+ Contract.Assert(calleeName != null);
if (!implName2LazyInliningInfo.ContainsKey(calleeName)) continue;
- List<int>! args = new List<int>();
- foreach (Expr! expr in naryExpr.Args)
- {
+ List<int> args = new List<int>();
+ foreach (Expr expr in naryExpr.Args)
+ {Contract.Assert(expr != null);
VCExprVar exprVar;
string name;
LiteralExpr litExpr = expr as LiteralExpr;
@@ -3002,8 +3348,8 @@ namespace VC
}
IdentifierExpr idExpr = expr as IdentifierExpr;
- assert idExpr != null;
- Variable! var = (!)idExpr.Decl;
+ Contract.Assert( idExpr != null);
+ Variable var = cce.NonNull(idExpr.Decl);
if (var is Constant)
{
@@ -3014,9 +3360,10 @@ namespace VC
}
int index = 0;
- List<GlobalVariable!> globalVars = program.GlobalVariables();
- foreach (Variable! global in globalVars)
+ List<GlobalVariable> globalVars = program.GlobalVariables();
+ foreach (Variable global in globalVars)
{
+ Contract.Assert(global != null);
if (global == var) break;
index++;
}
@@ -3026,8 +3373,9 @@ namespace VC
continue;
}
- foreach (Variable! input in info.impl.InParams)
+ foreach (Variable input in info.impl.InParams)
{
+ Contract.Assert(input != null);
if (input == var) break;
index++;
}
@@ -3037,8 +3385,9 @@ namespace VC
continue;
}
- foreach (Variable! output in info.impl.OutParams)
+ foreach (Variable output in info.impl.OutParams)
{
+ Contract.Assert(output != null);
if (output == var) break;
index++;
}
@@ -3061,37 +3410,51 @@ namespace VC
GotoCmd gotoCmd = transferCmd as GotoCmd;
if (gotoCmd == null) break;
int nextBlockId = errModel.LookupControlFlowFunctionAt(cfcValue, b.UniqueId);
- b = (Block!) ((!)info.label2absy)[nextBlockId];
+ b = (Block)cce.NonNull(info.label2absy)[nextBlockId];
trace.Add(b);
}
- assert false;
+ Contract.Assert(false);throw new cce.UnreachableException();
}
-
- static Counterexample TraceCounterexample(Block! b, BlockSeq! trace, ErrorModel errModel, Dictionary<Incarnation, Absy!>! incarnationOriginMap)
- {
+
+ static Counterexample TraceCounterexample(Block b, BlockSeq trace, ErrorModel errModel, Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap) {
+ Contract.Requires(b != null);
+ Contract.Requires(trace != null);
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
// After translation, all potential errors come from asserts.
-
+
return null;
}
-
+
static Counterexample TraceCounterexample(
- Block! b, Hashtable! traceNodes, BlockSeq! trace, ErrorModel errModel,
- Dictionary<Incarnation, Absy!>! incarnationOriginMap,
- Dictionary<string!, LazyInliningInfo!>! implName2LazyInliningInfo,
- DeclFreeProverContext! context, Program! program,
- Dictionary<Absy!, CalleeCounterexampleInfo!>! calleeCounterexamples)
+ Block/*!*/ b, Hashtable/*!*/ traceNodes, BlockSeq/*!*/ trace, ErrorModel errModel,
+ Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap,
+ Dictionary<string/*!*/, LazyInliningInfo/*!*/>/*!*/ implName2LazyInliningInfo,
+ DeclFreeProverContext/*!*/ context, Program/*!*/ program,
+ Dictionary<Absy/*!*/, CalleeCounterexampleInfo/*!*/>/*!*/ calleeCounterexamples)
{
+ Contract.Requires(b != null);
+ Contract.Requires(traceNodes != null);
+ Contract.Requires(trace != null);
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
+ Contract.Requires(cce.NonNullElements(implName2LazyInliningInfo));
+ Contract.Requires(context != null);
+ Contract.Requires(program != null);
+ Contract.Requires(cce.NonNullElements(calleeCounterexamples));
// After translation, all potential errors come from asserts.
- CmdSeq! cmds = b.Cmds;
- TransferCmd! transferCmd = (!)b.TransferCmd;
+ CmdSeq cmds = b.Cmds;
+ Contract.Assert(cmds != null);
+ TransferCmd transferCmd = cce.NonNull(b.TransferCmd);
for (int i = 0; i < cmds.Length; i++)
{
- Cmd! cmd = (!) cmds[i];
+ Cmd cmd = cce.NonNull( cmds[i]);
// Skip if 'cmd' not contained in the trace or not an assert
if (cmd is AssertCmd && traceNodes.Contains(cmd))
{
- Counterexample! newCounterexample = AssertCmdToCounterexample((AssertCmd)cmd, transferCmd, trace, errModel, incarnationOriginMap);
+ Counterexample newCounterexample = AssertCmdToCounterexample((AssertCmd)cmd, transferCmd, trace, errModel, incarnationOriginMap);
+ Contract.Assert(newCounterexample != null);
newCounterexample.AddCalleeCounterexample(calleeCounterexamples);
return newCounterexample;
}
@@ -3102,13 +3465,14 @@ namespace VC
if (assumeCmd == null) continue;
NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
if (naryExpr == null) continue;
- string! calleeName = naryExpr.Fun.FunctionName;
+ string calleeName = naryExpr.Fun.FunctionName;
if (!implName2LazyInliningInfo.ContainsKey(calleeName)) continue;
- VCExprTranslator! vcExprTranslator = (!)context.exprTranslator;
- Boogie2VCExprTranslator! boogieExprTranslator = context.BoogieExprTranslator;
- List<int>! args = new List<int>();
- foreach (Expr! expr in naryExpr.Args)
- {
+ VCExprTranslator vcExprTranslator = cce.NonNull(context.exprTranslator);
+ Boogie2VCExprTranslator boogieExprTranslator = context.BoogieExprTranslator;
+ Contract.Assert(boogieExprTranslator != null);
+ List<int> args = new List<int>();
+ foreach (Expr expr in naryExpr.Args)
+ {Contract.Assert(expr != null);
LiteralExpr litExpr = expr as LiteralExpr;
if (litExpr != null)
{
@@ -3117,10 +3481,12 @@ namespace VC
}
IdentifierExpr idExpr = expr as IdentifierExpr;
- assert idExpr != null;
- assert idExpr.Decl != null;
- VCExprVar! var = boogieExprTranslator.LookupVariable(idExpr.Decl);
- string! name = vcExprTranslator.Lookup(var);
+ Contract.Assert( idExpr != null);
+ Contract.Assert( idExpr.Decl != null);
+ VCExprVar var = boogieExprTranslator.LookupVariable(idExpr.Decl);
+ Contract.Assert(var != null);
+ string name = vcExprTranslator.Lookup(var);
+ Contract.Assert(name != null);
args.Add(errModel.identifierToPartition[name]);
}
calleeCounterexamples[assumeCmd] =
@@ -3133,8 +3499,9 @@ namespace VC
GotoCmd gotoCmd = transferCmd as GotoCmd;
if (gotoCmd != null)
{
- foreach (Block! bb in (!)gotoCmd.labelTargets)
+ foreach (Block bb in cce.NonNull(gotoCmd.labelTargets))
{
+ Contract.Assert(bb != null);
if (traceNodes.Contains(bb)){
trace.Add(bb);
return TraceCounterexample(bb, traceNodes, trace, errModel, incarnationOriginMap, implName2LazyInliningInfo, context, program, calleeCounterexamples);
@@ -3147,30 +3514,39 @@ namespace VC
// Debug.Fail("Could not find failing node.");
// throw new Microsoft.Contracts.AssertException();
}
-
-
- static void /*return printable error!*/ ApplyEnhancedErrorPrintingStrategy (Bpl.Expr! expr, Hashtable /*Variable -> Expr*/! incarnationMap, MiningStrategy errorDataEnhanced, ErrorModel! errModel, Dictionary<Expr!, object>! exprToPrintableValue, List<string!>! relatedInformation, bool printInternalStateDumpOnce, Dictionary<Incarnation, Absy!>! incarnationOriginMap) {
+
+
+ static void /*return printable error!*/ ApplyEnhancedErrorPrintingStrategy(Bpl.Expr/*!*/ expr, Hashtable /*Variable -> Expr*//*!*/ incarnationMap,
+ MiningStrategy errorDataEnhanced, ErrorModel/*!*/ errModel, Dictionary<Expr/*!*/, object>/*!*/ exprToPrintableValue,
+ List<string/*!*/>/*!*/ relatedInformation, bool printInternalStateDumpOnce, Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap) {
+ Contract.Requires(expr != null);
+ Contract.Requires(incarnationMap != null);
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(exprToPrintableValue));
+ Contract.Requires(cce.NonNullElements(relatedInformation));
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
if (errorDataEnhanced is ListOfMiningStrategies) {
- ListOfMiningStrategies loms = (ListOfMiningStrategies) errorDataEnhanced;
- List<MiningStrategy>! l = loms.msList;
+ ListOfMiningStrategies loms = (ListOfMiningStrategies)errorDataEnhanced;
+ List < MiningStrategy > l = loms.msList;
for (int i = 0; i < l.Count; i++) {
MiningStrategy ms = l[i];
if (ms != null) {
ApplyEnhancedErrorPrintingStrategy(expr, incarnationMap, l[i], errModel, exprToPrintableValue, relatedInformation, false, incarnationOriginMap);
}
}
- }
- else if (errorDataEnhanced is EEDTemplate /*EDEverySubExpr*/) {
- EEDTemplate eedT = (EEDTemplate) errorDataEnhanced;
+ } else if (errorDataEnhanced is EEDTemplate /*EDEverySubExpr*/) {
+ EEDTemplate eedT = (EEDTemplate)errorDataEnhanced;
string reason = eedT.reason;
- List<Bpl.Expr!> listOfExprs = eedT.exprList;
+ List<Bpl.Expr> listOfExprs = eedT.exprList;
+ Contract.Assert(cce.NonNullElements(listOfExprs));
if (listOfExprs != null) {
List<string> holeFillers = new List<string>();
for (int i = 0; i < listOfExprs.Count; i++) {
bool alreadySet = false;
- foreach (KeyValuePair<Bpl.Expr!, object> kvp in exprToPrintableValue) {
- Bpl.Expr! e = kvp.Key;
- Bpl.Expr! f = listOfExprs[i];
+ foreach (KeyValuePair<Bpl.Expr, object> kvp in exprToPrintableValue) {
+ Contract.Assert(kvp.Key != null);
+ Bpl.Expr e = kvp.Key;
+ Bpl.Expr f = listOfExprs[i];
// the strings are compared instead of the actual expressions because
// the expressions might not be identical, but their print-out strings will be
if (e.ToString() == f.ToString()) {
@@ -3179,7 +3555,7 @@ namespace VC
holeFillers.Add(o.ToString());
alreadySet = true;
break;
- }
+ }
}
}
if (!alreadySet) {
@@ -3190,23 +3566,24 @@ namespace VC
reason = FormatReasonString(reason, holeFillers);
}
if (reason != null) {
- relatedInformation.Add("(related information): "+reason);
+ relatedInformation.Add("(related information): " + reason);
}
- } else {
+ } else {
// define new templates here!
- }
-
+ }
+
if (printInternalStateDumpOnce) {
ComputeAndTreatHeapSuccessions(incarnationMap, errModel, incarnationOriginMap, relatedInformation);
// default action: print all values!
- foreach (KeyValuePair<Bpl.Expr!, object> kvp in exprToPrintableValue) {
+ foreach (KeyValuePair<Bpl.Expr, object> kvp in exprToPrintableValue) {
+ Contract.Assert(kvp.Key != null);
object o = kvp.Value;
if (o != null) {
// We do not want to print LiteralExprs because that gives things like 0 == 0.
// If both arguments to the string.Format are the same it is also useless,
// as that would print e.g. $a == $a.
- if (!(kvp.Key is LiteralExpr)&& kvp.Key.ToString() != o.ToString()) {
+ if (!(kvp.Key is LiteralExpr) && kvp.Key.ToString() != o.ToString()) {
string boogieExpr;
// check whether we are handling BPL or SSC input
if (CommandLineOptions.Clo.RunningBoogieOnSsc) {
@@ -3214,25 +3591,32 @@ namespace VC
} else {
boogieExpr = kvp.Key.ToString();
}
- relatedInformation.Add("(internal state dump): "+string.Format("{0} == {1}", boogieExpr, o));
+ relatedInformation.Add("(internal state dump): " + string.Format("{0} == {1}", boogieExpr, o));
}
}
}
}
}
-
- static void ComputeAndTreatHeapSuccessions(System.Collections.Hashtable! incarnationMap, ErrorModel! errModel, Dictionary<Incarnation, Absy!>! incarnationOriginMap, List<string!>! relatedInformation) {
+
+ static void ComputeAndTreatHeapSuccessions(System.Collections.Hashtable/*!*/ incarnationMap, ErrorModel/*!*/ errModel,
+ Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap, List<string/*!*/>/*!*/ relatedInformation) {
+ Contract.Requires(incarnationMap != null);
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
+ Contract.Requires(cce.NonNullElements(relatedInformation));
List<int> heapSuccList = ComputeHeapSuccessions(incarnationMap, errModel);
TreatHeapSuccessions(heapSuccList, incarnationMap, errModel, incarnationOriginMap, relatedInformation);
}
-
- static List<int> ComputeHeapSuccessions(System.Collections.Hashtable! incarnationMap, ErrorModel! errModel) {
+
+ static List<int> ComputeHeapSuccessions(System.Collections.Hashtable incarnationMap, ErrorModel errModel) {
+ Contract.Requires(incarnationMap != null);
+ Contract.Requires(errModel != null);
// find the heap variable
Variable heap = null;
ICollection ic = incarnationMap.Keys;
foreach (object o in ic) {
if (o is GlobalVariable) {
- GlobalVariable gv = (GlobalVariable) o;
+ GlobalVariable gv = (GlobalVariable)o;
if (gv.Name == "$Heap") {
heap = gv;
}
@@ -3260,8 +3644,9 @@ namespace VC
}
}
if (heapIdSuccession.Count > 0) {
- int heapId = heapIdSuccession[heapIdSuccession.Count-1];
- List<string!> strl = errModel.partitionToIdentifiers[heapId];
+ int heapId = heapIdSuccession[heapIdSuccession.Count - 1];
+ List<string> strl = errModel.partitionToIdentifiers[heapId];
+ Contract.Assert(strl != null);
if (strl != null && strl.Contains("$Heap")) {
// we have a proper succession of heaps that starts with $Heap
return heapIdSuccession;
@@ -3275,8 +3660,9 @@ namespace VC
return null;
}
}
-
- static int ComputePredecessorHeapId(int id, ErrorModel! errModel) {
+
+ static int ComputePredecessorHeapId(int id, ErrorModel errModel) {
+ Contract.Requires(errModel != null);
//check "$HeapSucc" and "store2" functions:
List<int> heapSuccPredIdList = new List<int>();
List<List<int>> heapSuccFunc;
@@ -3292,7 +3678,8 @@ namespace VC
}
}
}
- List<int> store2PredIdList = new List<int>();;
+ List<int> store2PredIdList = new List<int>();
+ ;
List<List<int>> store2Func;
errModel.definedFunctions.TryGetValue("store2", out store2Func);
if (store2Func != null) {
@@ -3328,8 +3715,8 @@ namespace VC
// we cannot choose between the other 2 (or more) candidates
return -1;
}
- }
- } else {
+ }
+ } else {
// more than one result in the succession coming from store2, no way
// to decide which is right, end here
return -1;
@@ -3339,8 +3726,13 @@ namespace VC
return -1;
}
}
-
- static void TreatHeapSuccessions (List<int> heapSuccessionList, System.Collections.Hashtable! incarnationMap, ErrorModel! errModel, Dictionary<Incarnation, Absy!>! incarnationOriginMap, List<string!>! relatedInformation) {
+
+ static void TreatHeapSuccessions(List<int> heapSuccessionList, System.Collections.Hashtable incarnationMap, ErrorModel errModel,
+ Dictionary<Incarnation, Absy/*!*/>/*!*/ incarnationOriginMap, List<string/*!*/>/*!*/ relatedInformation) {
+ Contract.Requires(incarnationMap != null);
+ Contract.Requires(errModel != null);
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
+ Contract.Requires(cce.NonNullElements(relatedInformation));
if (heapSuccessionList == null) {
// empty list of heap successions, nothing we can do!
return;
@@ -3352,11 +3744,10 @@ namespace VC
ICollection ic = incarnationMap.Keys;
foreach (object o in ic) {
if (o is BoundVariable) {
- BoundVariable bv = (BoundVariable) o;
+ BoundVariable bv = (BoundVariable)o;
if (bv.Name == "$o") {
dollarO = bv;
- }
- else if (bv.Name == "$f") {
+ } else if (bv.Name == "$f") {
dollarF = bv;
}
}
@@ -3376,7 +3767,7 @@ namespace VC
List<int> heapsChangedOFZid = new List<int>();
int oldValueZid = -1;
int newValueZid = -1;
-
+
for (int i = 0; i < heapSuccessionList.Count; i++) {
bool foundValue = false;
foreach (List<int> f in select2Func) {
@@ -3393,23 +3784,24 @@ namespace VC
// newValueZid = (select2Func[select2Func.Count-1])[0];
newValueZid = -1;
}
-
+
if (oldValueZid != newValueZid) {
// there was a change here, record that in the list:
if (oldValueZid != -1) {
// don't record a change at the "initial" location, which refers to the $Heap in
// its current incarnation, and is marked by the oldValueZid being uninitialized
- heapsChangedOFZid.Add(heapSuccessionList[i-1]);
+ heapsChangedOFZid.Add(heapSuccessionList[i - 1]);
}
oldValueZid = newValueZid;
- }
+ }
}
-
+
foreach (int id in heapsChangedOFZid) {
//get the heap name out of the errModel for this zid:
- List<string!> l = errModel.partitionToIdentifiers[id];
- List<string!> heaps = new List<string!>();
- if (l!=null) {
+ List<string> l = errModel.partitionToIdentifiers[id];
+ Contract.Assert(l != null);
+ List<string> heaps = new List<string>();
+ if (l != null) {
foreach (string s in l) {
if (s.StartsWith("$Heap")) {
heaps.Add(s);
@@ -3421,30 +3813,31 @@ namespace VC
string heapName = heaps[0];
// we have a string with the name of the heap, but we need to get the
// source location out of a map that uses Incarnations!
-
+
ICollection incOrgMKeys = incarnationOriginMap.Keys;
foreach (Incarnation inc in incOrgMKeys) {
- if (inc!= null) {
+ if (inc != null) {
if (inc.Name == heapName) {
Absy source = null;
incarnationOriginMap.TryGetValue(inc, out source);
if (source != null) {
if (source is Block) {
- Block b = (Block) source;
+ Block b = (Block)source;
string fileName = b.tok.filename;
if (fileName != null) {
fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
}
relatedInformation.Add("(related information): Changed $o.$f here: " + fileName + "(" + b.tok.line + "," + b.tok.col + ")");
} else if (source is Cmd) {
- Cmd c = (Cmd) source;
+ Cmd c = (Cmd)source;
string fileName = c.tok.filename;
if (fileName != null) {
fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
}
relatedInformation.Add("(related information) Changed $o.$f here: " + fileName + "(" + c.tok.line + "," + c.tok.col + ")");
} else {
- assert false;
+ Contract.Assert(false);
+ throw new cce.UnreachableException();
}
}
}
@@ -3455,14 +3848,14 @@ namespace VC
// here there is more than one "$Heap@i" in the partition, check if they all agree on one
// source location or maybe if some of them are joins (i.e. blocks) that should be ignored
}
-
+
}
- }
+ }
}
}
}
-
- static string FormatReasonString (string reason, List<string> holeFillers) {
+
+ static string FormatReasonString(string reason, List<string> holeFillers) {
if (holeFillers != null) {
// in case all elements of holeFillers are "<unknown>" we can not say anything useful
// so just say nothing and return null
@@ -3481,32 +3874,35 @@ namespace VC
}
return reason;
}
-
- static object ValueFromZID (ErrorModel! errModel, int id) {
+
+ static object ValueFromZID(ErrorModel errModel, int id) {
+ Contract.Requires(errModel != null);
return ValueFromZID(errModel, id, null);
}
- static object ValueFromZID (ErrorModel! errModel, int id, string searchForAlternate) {
+ static object ValueFromZID(ErrorModel errModel, int id, string searchForAlternate) {
+ Contract.Requires(errModel != null);
object o = errModel.partitionToValue[id];
if (o != null) {
return o;
} else {
// more elaborate scheme to find something better, as in: look at the identifiers that
// this partition maps to, or similar things!
-
+
//treatment for 'null':
int idForNull = -1;
if (errModel.valueToPartition.TryGetValue("nullObject", out idForNull) && idForNull == id) {
return "nullObject";
}
-
+
string returnStr = null;
-
+
// "good identifiers" if there is no value found are 'unique consts' or
// '$in' parameters; '$in' parameters are treated, unclear how to get 'unique const' info
- List<string!> identifiers = errModel.partitionToIdentifiers[id];
+ List<string> identifiers = errModel.partitionToIdentifiers[id];
if (identifiers != null) {
- foreach (string s in identifiers) {
+ foreach (string s in identifiers) {
+ Contract.Assert(s != null);
//$in parameters are (more) interesting than other identifiers, return the
// first one found
if (s.EndsWith("$in")) {
@@ -3515,7 +3911,7 @@ namespace VC
}
}
}
-
+
// try to get mappings from one identifier to another if there are exactly
// two identifiers in the partition, where one of them is the identifier for which
// we search for alternate encodings (third parameter of the method) [or an incarnation
@@ -3527,22 +3923,24 @@ namespace VC
returnStr = identifiers[0];
}
}
-
+
if (returnStr != null) {
return Helpers.BeautifyBplString(returnStr);
}
-
+
return null;
}
}
-
- static int TreatInterpretedFunction(string! functionName, List<int>! zargs, ErrorModel! errModel) {
+
+ static int TreatInterpretedFunction(string functionName, List<int> zargs, ErrorModel errModel) {
+ Contract.Requires(functionName != null);
+ Contract.Requires(zargs != null);
+ Contract.Requires(errModel != null);
if (zargs.Count != 2) {
//all interpreted functions are binary, so there have to be exactly two arguments
return -1;
- }
- else {
- object arg0 = ValueFromZID(errModel, zargs[0]);
+ } else {
+ object arg0 = ValueFromZID(errModel, zargs[0]);
object arg1 = ValueFromZID(errModel, zargs[1]);
if (arg0 is BigNum && arg1 is BigNum) {
BigNum arg0i = (BigNum)arg0;
@@ -3561,46 +3959,54 @@ namespace VC
} else {
return -1;
}
- }
- else {
+ } else {
//both arguments need to be integers for this to work!
return -1;
}
}
}
-
- static int TreatFunction (string! functionName, List<int>! zargs, bool undefined, ErrorModel! errModel) {
+
+ static int TreatFunction(string functionName, List<int> zargs, bool undefined, ErrorModel errModel) {
+ Contract.Requires(functionName != null);
+ Contract.Requires(zargs != null);
+ Contract.Requires(errModel != null);
List<List<int>> functionDef;
- if ((!errModel.definedFunctions.TryGetValue(functionName, out functionDef) && functionName != "+" && functionName != "-" && functionName != "*") || undefined) {
+ if ((!errModel.definedFunctions.TryGetValue(functionName, out functionDef) && functionName != "+" && functionName != "-" && functionName != "*") || undefined) {
// no fitting function found or one of the arguments is undefined
return -1;
} else {
if (functionName == "+" || functionName == "-" || functionName == "*") {
return TreatInterpretedFunction(functionName, zargs, errModel);
}
- assert functionDef != null;
+ Contract.Assert(functionDef != null);
foreach (List<int> pWiseF in functionDef) {
- assert pWiseF != null;
+ Contract.Assert(pWiseF != null);
// else case in the function definition:
if (pWiseF.Count == 1) {
return pWiseF[0];
}
// number of arguments is exactly the right number
- assert zargs.Count == pWiseF.Count - 1;
- if (forall{int i in (0: zargs.Count); zargs[i] == pWiseF[i]}) {
+ Contract.Assert(zargs.Count == pWiseF.Count - 1);
+ if (Contract.ForAll(zargs, i => i == pWiseF[i])) {
return pWiseF[pWiseF.Count - 1];
}
}
// all functions should have an 'else ->' case defined, therefore this should be
// unreachable code!
- assert false;
+ Contract.Assert(false);
+ throw new cce.UnreachableException();
}
}
-
+
//returned int is zID
- static int GetValuesFromModel (Bpl.Expr! expr, Hashtable /*Variable -> Expr*/! incarnationMap, ErrorModel! errModel, Dictionary<Bpl.Expr!, object>! exprToPrintableValue)
- modifies exprToPrintableValue.*;
+ static int GetValuesFromModel(Bpl.Expr expr, Hashtable /*Variable -> Expr*/ incarnationMap, ErrorModel errModel,
+ Dictionary<Bpl.Expr/*!*/, object>/*!*/ exprToPrintableValue)
+ //modifies exprToPrintableValue.*;
{
+ Contract.Requires(expr != null);
+ Contract.Requires(incarnationMap != null);
+ Contract.Requires(errModel != null);
+ Contract.Requires(exprToPrintableValue != null);
// call GetValuesFromModel on all proper subexpressions, returning their value,
// so they only have to be computed once!
if (expr is LiteralExpr) {
@@ -3623,10 +4029,10 @@ namespace VC
object o = null;
Variable v = ((IdentifierExpr) expr).Decl;
if (v != null && incarnationMap.ContainsKey(v)) {
- if (incarnationMap[v] is IdentifierExpr!) {
- s = ((IdentifierExpr!) incarnationMap[v]).Name;
- } else if (incarnationMap[v] is LiteralExpr!) {
- o = ((LiteralExpr!) incarnationMap[v]).Val;
+ if (incarnationMap[v] is IdentifierExpr) {
+ s = ((IdentifierExpr) incarnationMap[v]).Name;
+ } else if (incarnationMap[v] is LiteralExpr) {
+ o = ((LiteralExpr) incarnationMap[v]).Val;
}
}
// if o is not null, then we got a LiteralExpression, that needs separate treatment
@@ -3670,7 +4076,8 @@ namespace VC
}
zargs.Add(zid);
}
- IAppliable! fun = e.Fun;
+ IAppliable fun = e.Fun;
+ Contract.Assert(fun != null);
string functionName = fun.FunctionName; // PR: convert to select1, select2, etc in case of a map?
// same as IndexedExpr:
int id = TreatFunction(functionName, zargs, undefined, errModel);
@@ -3698,11 +4105,12 @@ namespace VC
// could be used without actually having a value, but it seems better to pick those
// with a value, that is they are more likely to contribute useful information to
// the output
- List<Bpl.IdentifierExpr!> quantVarIncarnationList = new List<Bpl.IdentifierExpr!>();
+ List<Bpl.IdentifierExpr> quantVarIncarnationList = new List<Bpl.IdentifierExpr>();
List<int> incarnationZidList = new List<int>();
int numberOfNonNullValueIncarnations = 0;
for (int j = 0; j < errModel.partitionToIdentifiers.Count; j++){
- List<string!> pti = errModel.partitionToIdentifiers[j];
+ List<string> pti = errModel.partitionToIdentifiers[j];
+ Contract.Assert(pti != null);
if (pti != null) {
for (int k = 0; k < pti.Count; k++) {
// look for v.sk.(q.SkolemId)
@@ -3810,18 +4218,26 @@ namespace VC
return id;
}
else {
- assert false; // unexpected Bpl.Expr
+ Contract.Assert(false);throw new cce.UnreachableException(); // unexpected Bpl.Expr
}
return -1;
}
- static Counterexample! AssertCmdToCounterexample (AssertCmd! cmd, TransferCmd! transferCmd, BlockSeq! trace, ErrorModel errModel, Dictionary<Incarnation, Absy!>! incarnationOriginMap) {
- List<string!>! relatedInformation = new List<string!>();
+ static Counterexample AssertCmdToCounterexample(AssertCmd cmd, TransferCmd transferCmd, BlockSeq trace, ErrorModel errModel,
+ Dictionary<Incarnation, Absy> incarnationOriginMap)
+ {
+ Contract.Requires(cmd != null);
+ Contract.Requires(transferCmd != null);
+ Contract.Requires(trace != null);
+ Contract.Requires(cce.NonNullElements(incarnationOriginMap));
+ Contract.Ensures(Contract.Result<Counterexample>() != null);
+
+ List<string> relatedInformation = new List<string>();
if (CommandLineOptions.Clo.EnhancedErrorMessages == 1) {
if (cmd.OrigExpr != null && cmd.IncarnationMap != null && errModel != null) {
// get all possible information first
- Dictionary<Expr!, object> exprToPrintableValue = new Dictionary<Expr!, object>();
+ Dictionary<Expr, object> exprToPrintableValue = new Dictionary<Expr, object>();
GetValuesFromModel(cmd.OrigExpr, cmd.IncarnationMap, errModel, exprToPrintableValue);
// then apply the strategies
ApplyEnhancedErrorPrintingStrategy(cmd.OrigExpr, cmd.IncarnationMap, cmd.ErrorDataEnhanced, errModel, exprToPrintableValue, relatedInformation, true, incarnationOriginMap);
@@ -3831,14 +4247,16 @@ namespace VC
// See if it is a special assert inserted in translation
if (cmd is AssertRequiresCmd)
{
- AssertRequiresCmd! assertCmd = (AssertRequiresCmd)cmd;
+ AssertRequiresCmd assertCmd = (AssertRequiresCmd)cmd;
+ Contract.Assert(assertCmd != null);
CallCounterexample cc = new CallCounterexample(trace, assertCmd.Call, assertCmd.Requires);
cc.relatedInformation = relatedInformation;
return cc;
}
else if (cmd is AssertEnsuresCmd)
{
- AssertEnsuresCmd! assertCmd = (AssertEnsuresCmd)cmd;
+ AssertEnsuresCmd assertCmd = (AssertEnsuresCmd)cmd;
+ Contract.Assert(assertCmd != null);
ReturnCounterexample rc = new ReturnCounterexample(trace, transferCmd, assertCmd.Ensures);
rc.relatedInformation = relatedInformation;
return rc;
@@ -3850,36 +4268,53 @@ namespace VC
return ac;
}
}
-
-// static void EmitImpl(Implementation! impl, bool printDesugarings) {
-// int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured;
-// CommandLineOptions.Clo.PrintUnstructured = 2; // print only the unstructured program
-// bool oldPrintDesugaringSetting = CommandLineOptions.Clo.PrintDesugarings;
-// CommandLineOptions.Clo.PrintDesugarings = printDesugarings;
-// impl.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
-// CommandLineOptions.Clo.PrintDesugarings = oldPrintDesugaringSetting;
-// CommandLineOptions.Clo.PrintUnstructured = oldPrintUnstructured;
-// }
-
- static VCExpr! LetVC(Block! startBlock,
+
+ // static void EmitImpl(Implementation! impl, bool printDesugarings) {
+ // int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured;
+ // CommandLineOptions.Clo.PrintUnstructured = 2; // print only the unstructured program
+ // bool oldPrintDesugaringSetting = CommandLineOptions.Clo.PrintDesugarings;
+ // CommandLineOptions.Clo.PrintDesugarings = printDesugarings;
+ // impl.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
+ // CommandLineOptions.Clo.PrintDesugarings = oldPrintDesugaringSetting;
+ // CommandLineOptions.Clo.PrintUnstructured = oldPrintUnstructured;
+ // }
+
+ static VCExpr LetVC(Block startBlock,
Variable controlFlowVariable,
- Hashtable/*<int, Absy!>*/! label2absy,
- ProverContext! proverCtxt)
- {
- Hashtable/*<Block, LetVariable!>*/! blockVariables = new Hashtable/*<Block, LetVariable!!>*/();
- List<VCExprLetBinding!>! bindings = new List<VCExprLetBinding!>();
+ Hashtable/*<int, Absy!>*/ label2absy,
+ ProverContext proverCtxt) {
+ Contract.Requires(startBlock != null);
+ Contract.Requires(controlFlowVariable != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(proverCtxt != null);
+
+
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ Hashtable/*<Block, LetVariable!>*/ blockVariables = new Hashtable/*<Block, LetVariable!!>*/();
+ List<VCExprLetBinding> bindings = new List<VCExprLetBinding>();
VCExpr startCorrect = LetVC(startBlock, controlFlowVariable, label2absy, blockVariables, bindings, proverCtxt);
return proverCtxt.ExprGen.Let(bindings, startCorrect);
}
- static VCExpr! LetVC(Block! block,
+ static VCExpr LetVC(Block block,
Variable controlFlowVariable,
- Hashtable/*<int, Absy!>*/! label2absy,
- Hashtable/*<Block, VCExprVar!>*/! blockVariables,
- List<VCExprLetBinding!>! bindings,
- ProverContext! proverCtxt)
+ Hashtable/*<int, Absy!>*/ label2absy,
+ Hashtable/*<Block, VCExprVar!>*/ blockVariables,
+ List<VCExprLetBinding/*!*/>/*!*/ bindings,
+ ProverContext proverCtxt)
{
- VCExpressionGenerator! gen = proverCtxt.ExprGen;
+ Contract.Requires(block != null);
+ Contract.Requires(controlFlowVariable != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(blockVariables!= null);
+ Contract.Requires(cce.NonNullElements(bindings));
+ Contract.Requires(proverCtxt != null);
+
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpressionGenerator gen = proverCtxt.ExprGen;
+ Contract.Assert(gen != null);
VCExprVar v = (VCExprVar)blockVariables[block];
if (v == null) {
/*
@@ -3893,9 +4328,9 @@ namespace VC
if (gotocmd == null) {
SuccCorrect = VCExpressionGenerator.True;
} else {
- assert gotocmd.labelTargets != null;
- List<VCExpr!> SuccCorrectVars = new List<VCExpr!>(gotocmd.labelTargets.Length);
- foreach (Block! successor in gotocmd.labelTargets) {
+ Contract.Assert( gotocmd.labelTargets != null);
+ List<VCExpr> SuccCorrectVars = new List<VCExpr>(gotocmd.labelTargets.Length);
+ foreach (Block successor in gotocmd.labelTargets) {Contract.Assert(successor != null);
VCExpr s = LetVC(successor, controlFlowVariable, label2absy, blockVariables, bindings, proverCtxt);
if (controlFlowVariable != null)
{
@@ -3920,12 +4355,19 @@ namespace VC
return v;
}
- static VCExpr! DagVC(Block! block,
- Hashtable/*<int, Absy!>*/! label2absy,
- Hashtable/*<Block, VCExpr!>*/! blockEquations,
- ProverContext! proverCtxt)
+ static VCExpr DagVC(Block block,
+ Hashtable/*<int, Absy!>*/ label2absy,
+ Hashtable/*<Block, VCExpr!>*/ blockEquations,
+ ProverContext proverCtxt)
{
- VCExpressionGenerator! gen = proverCtxt.ExprGen;
+ Contract.Requires(block != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(blockEquations != null);
+ Contract.Requires(proverCtxt != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpressionGenerator gen = proverCtxt.ExprGen;
+ Contract.Assert(gen != null);
VCExpr vc = (VCExpr)blockEquations[block];
if (vc != null) {
return vc;
@@ -3939,7 +4381,8 @@ namespace VC
GotoCmd gotocmd = block.TransferCmd as GotoCmd;
if (gotocmd != null)
{
- foreach (Block! successor in (!)gotocmd.labelTargets) {
+ foreach (Block successor in cce.NonNull(gotocmd.labelTargets)) {
+ Contract.Assert(successor != null);
VCExpr c = DagVC(successor, label2absy, blockEquations, proverCtxt);
SuccCorrect = SuccCorrect == null ? c : gen.And(SuccCorrect, c);
}
@@ -3957,38 +4400,45 @@ namespace VC
return vc;
}
- static VCExpr! FlatBlockVC(Implementation! impl,
- Hashtable/*<int, Absy!>*/! label2absy,
+ static VCExpr FlatBlockVC(Implementation impl,
+ Hashtable/*<int, Absy!>*/ label2absy,
bool local, bool reach, bool doomed,
- ProverContext! proverCtxt)
- requires local ==> !reach; // "reach" must be false for local
+ ProverContext proverCtxt)
{
- VCExpressionGenerator! gen = proverCtxt.ExprGen;
+ Contract.Requires(impl != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(proverCtxt != null);
+ Contract.Requires( !local || !reach); // "reach" must be false for local
+
+ VCExpressionGenerator gen = proverCtxt.ExprGen;
+ Contract.Assert(gen != null);
Hashtable/* Block --> VCExprVar */ BlkCorrect = BlockVariableMap(impl.Blocks, "_correct", gen);
Hashtable/* Block --> VCExprVar */ BlkReached = reach ? BlockVariableMap(impl.Blocks, "_reached", gen) : null;
- List<Block!> blocks = impl.Blocks;
+ List<Block> blocks = impl.Blocks;
+ Contract.Assert(blocks != null);
// block sorting is now done on the VCExpr
- // if (!local && ((!)CommandLineOptions.Clo.TheProverFactory).NeedsBlockSorting) {
+ // if (!local && (cce.NonNull(CommandLineOptions.Clo.TheProverFactory).NeedsBlockSorting) {
// blocks = SortBlocks(blocks);
// }
VCExpr proofObligation;
if (!local) {
- proofObligation = (VCExprVar!)BlkCorrect[impl.Blocks[0]];
+ proofObligation = cce.NonNull((VCExprVar)BlkCorrect[impl.Blocks[0]]);
} else {
- List<VCExpr!> conjuncts = new List<VCExpr!>(blocks.Count);
- foreach (Block! b in blocks) {
- VCExpr v = (VCExprVar!)BlkCorrect[b];
+ List<VCExpr> conjuncts = new List<VCExpr>(blocks.Count);
+ foreach (Block b in blocks) {Contract.Assert(b != null);
+ VCExpr v = cce.NonNull((VCExprVar)BlkCorrect[b]);
conjuncts.Add(v);
}
proofObligation = gen.NAry(VCExpressionGenerator.AndOp, conjuncts);
}
- VCContext! context = new VCContext(label2absy, proverCtxt);
+ VCContext context = new VCContext(label2absy, proverCtxt);
+ Contract.Assert(context != null);
- List<VCExprLetBinding!> programSemantics = new List<VCExprLetBinding!>(blocks.Count);
- foreach (Block! b in blocks) {
+ List<VCExprLetBinding> programSemantics = new List<VCExprLetBinding>(blocks.Count);
+ foreach (Block b in blocks) {Contract.Assert(b != null);
/*
* In block mode,
* For a return block A, generate:
@@ -4007,7 +4457,7 @@ namespace VC
* In local mode, generate:
* A_correct <== wp(A_body, true)
*/
- VCExpr! SuccCorrect;
+ VCExpr SuccCorrect;
if (local) {
SuccCorrect = VCExpressionGenerator.True;
} else {
@@ -4016,173 +4466,212 @@ namespace VC
VCExpr wlp = Wlp.Block(b, SuccCorrect, context);
if (BlkReached != null) {
- wlp = gen.Implies((VCExprVar!)BlkReached[b], wlp);
+ wlp = gen.Implies(cce.NonNull((VCExprVar)BlkReached[b]), wlp);
}
- VCExprVar okVar = (VCExprVar!)BlkCorrect[b];
+ VCExprVar okVar = cce.NonNull((VCExprVar)BlkCorrect[b]);
VCExprLetBinding binding = gen.LetBinding(okVar, wlp);
programSemantics.Add(binding);
}
return gen.Let(programSemantics, proofObligation);
}
-
- private static Hashtable/* Block --> VCExprVar */! BlockVariableMap(List<Block!>! blocks, string! suffix,
- Microsoft.Boogie.VCExpressionGenerator! gen)
- {
+
+ private static Hashtable/* Block --> VCExprVar */ BlockVariableMap(List<Block/*!*/>/*!*/ blocks, string suffix,
+ Microsoft.Boogie.VCExpressionGenerator gen) {
+ Contract.Requires(cce.NonNullElements(blocks));
+ Contract.Requires(suffix != null);
+ Contract.Requires(gen != null);
+ Contract.Ensures(Contract.Result<Hashtable>() != null);
+
Hashtable/* Block --> VCExprVar */ map = new Hashtable/* Block --> (Let)Variable */();
- foreach (Block! b in blocks)
- {
- VCExprVar! v = gen.Variable(b.Label+suffix, Bpl.Type.Bool);
+ foreach (Block b in blocks) {
+ Contract.Assert(b != null);
+ VCExprVar v = gen.Variable(b.Label + suffix, Bpl.Type.Bool);
+ Contract.Assert(v != null);
map.Add(b, v);
}
return map;
}
- private static VCExpr! SuccessorsCorrect(
- Block! b,
- Hashtable/* Block --> VCExprVar */! BlkCorrect,
+ private static VCExpr SuccessorsCorrect(
+ Block b,
+ Hashtable/* Block --> VCExprVar */ BlkCorrect,
Hashtable/* Block --> VCExprVar */ BlkReached,
bool doomed,
- Microsoft.Boogie.VCExpressionGenerator! gen)
- {
- VCExpr SuccCorrect = null;
- GotoCmd gotocmd = b.TransferCmd as GotoCmd;
- if (gotocmd != null)
- {
- foreach (Block! successor in (!)gotocmd.labelTargets)
- {
- // c := S_correct
- VCExpr c = (VCExprVar!)BlkCorrect[successor];
- if (BlkReached != null)
- {
- // c := S_correct \/ Sibling0_reached \/ Sibling1_reached \/ ...;
- foreach (Block! successorSibling in gotocmd.labelTargets)
- {
- if (successorSibling != successor)
- {
- c = gen.Or(c, (VCExprVar!)BlkReached[successorSibling]);
- }
- }
- }
- SuccCorrect = SuccCorrect == null ? c : gen.And(SuccCorrect, c);
+ Microsoft.Boogie.VCExpressionGenerator gen) {
+ Contract.Requires(b != null);
+ Contract.Requires(BlkCorrect != null);
+ Contract.Requires(gen != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpr SuccCorrect = null;
+ GotoCmd gotocmd = b.TransferCmd as GotoCmd;
+ if (gotocmd != null) {
+ foreach (Block successor in cce.NonNull(gotocmd.labelTargets)) {
+ Contract.Assert(successor != null);
+ // c := S_correct
+ VCExpr c = (VCExprVar)BlkCorrect[successor];
+ Contract.Assert(c != null);
+ if (BlkReached != null) {
+ // c := S_correct \/ Sibling0_reached \/ Sibling1_reached \/ ...;
+ foreach (Block successorSibling in gotocmd.labelTargets) {
+ Contract.Assert(successorSibling != null);
+ if (successorSibling != successor) {
+ c = gen.Or(c, cce.NonNull((VCExprVar)BlkReached[successorSibling]));
+ }
}
+ }
+ SuccCorrect = SuccCorrect == null ? c : gen.And(SuccCorrect, c);
}
- if (SuccCorrect == null) {
- return VCExpressionGenerator.True;
- } else if (doomed) {
- return VCExpressionGenerator.False;
- } else {
- return SuccCorrect;
- }
+ }
+ if (SuccCorrect == null) {
+ return VCExpressionGenerator.True;
+ } else if (doomed) {
+ return VCExpressionGenerator.False;
+ } else {
+ return SuccCorrect;
+ }
}
- static VCExpr! NestedBlockVC(Implementation! impl,
- Hashtable/*<int, Absy!>*/! label2absy,
+ static VCExpr NestedBlockVC(Implementation impl,
+ Hashtable/*<int, Absy!>*/ label2absy,
bool reach,
- ProverContext! proverCtxt)
- requires impl.Blocks.Count != 0;
- {
- VCExpressionGenerator! gen = proverCtxt.ExprGen;
- Graph<Block>! g = GraphFromImpl(impl);
+ ProverContext proverCtxt){
+ Contract.Requires(impl != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(proverCtxt != null);
+ Contract.Requires( impl.Blocks.Count != 0);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpressionGenerator gen = proverCtxt.ExprGen;
+ Contract.Assert(gen != null);
+ Graph<Block> g = GraphFromImpl(impl);
Hashtable/* Block --> VCExprVar */ BlkCorrect = BlockVariableMap(impl.Blocks, "_correct", gen);
Hashtable/* Block --> VCExprVar */ BlkReached = reach ? BlockVariableMap(impl.Blocks, "_reached", gen) : null;
- Block! startBlock = (!) impl.Blocks[0];
- VCExpr proofObligation = (VCExprVar!)BlkCorrect[startBlock];
-
- VCContext! context = new VCContext(label2absy, proverCtxt);
+ Block startBlock = cce.NonNull( impl.Blocks[0]);
+ VCExpr proofObligation = (VCExprVar)BlkCorrect[startBlock];
+ Contract.Assert(proofObligation != null);
+ VCContext context = new VCContext(label2absy, proverCtxt);
Hashtable/*Block->int*/ totalOrder = new Hashtable/*Block->int*/();
{
- List<Block!> blocks = impl.Blocks;
+ List<Block> blocks = impl.Blocks;
+
// block sorting is now done on the VCExpr
// if (((!)CommandLineOptions.Clo.TheProverFactory).NeedsBlockSorting) {
// blocks = SortBlocks(blocks);
// }
int i = 0;
foreach (Block b in blocks) {
+ Contract.Assert(b != null);
totalOrder[b] = i;
i++;
}
}
- VCExprLetBinding programSemantics = NestedBlockEquation((!)impl.Blocks[0], BlkCorrect, BlkReached, totalOrder, context, g, gen);
- List<VCExprLetBinding!> ps = new List<VCExprLetBinding!>(1);
+ VCExprLetBinding programSemantics = NestedBlockEquation(cce.NonNull(impl.Blocks[0]), BlkCorrect, BlkReached, totalOrder, context, g, gen);
+ List<VCExprLetBinding> ps = new List<VCExprLetBinding>(1);
ps.Add(programSemantics);
return gen.Let(ps, proofObligation);
}
- private static VCExprLetBinding! NestedBlockEquation(Block! b,
- Hashtable/*Block-->VCExprVar*/! BlkCorrect,
+ private static VCExprLetBinding NestedBlockEquation(Block b,
+ Hashtable/*Block-->VCExprVar*/ BlkCorrect,
Hashtable/*Block-->VCExprVar*/ BlkReached,
- Hashtable/*Block->int*/! totalOrder,
- VCContext! context,
- Graph<Block>! g,
- Microsoft.Boogie.VCExpressionGenerator! gen)
- {
- /*
- * For a block b, return:
- * LET_BINDING b_correct = wp(b_body, X)
- * where X is:
- * LET (THOSE d \in DirectDominates(b) :: BlockEquation(d))
- * IN (/\ s \in Successors(b) :: s_correct)
- *
- * When the VC-expression generator does not support LET expresions, this
- * will eventually turn into:
- * b_correct <== wp(b_body, X)
- * where X is:
- * (/\ s \in Successors(b) :: s_correct)
- * <==
- * (/\ d \in DirectDominatees(b) :: BlockEquation(d))
- *
- * In both cases above, if BlkReached is non-null, then the wp expression
- * is instead:
- * b_reached ==> wp(b_body, X)
- */
+ Hashtable/*Block->int*/ totalOrder,
+ VCContext context,
+ Graph<Block> g,
+ Microsoft.Boogie.VCExpressionGenerator gen) {
+ Contract.Requires(b != null);
+ Contract.Requires(BlkCorrect != null);
+ Contract.Requires(BlkReached != null);
+ Contract.Requires(totalOrder != null);
+ Contract.Requires(g != null);
+ Contract.Requires(context != null);
+
+ Contract.Ensures(Contract.Result<VCExprLetBinding>() != null);
- VCExpr! SuccCorrect = SuccessorsCorrect(b, BlkCorrect, null, false, gen);
+ /*
+ * For a block b, return:
+ * LET_BINDING b_correct = wp(b_body, X)
+ * where X is:
+ * LET (THOSE d \in DirectDominates(b) :: BlockEquation(d))
+ * IN (/\ s \in Successors(b) :: s_correct)
+ *
+ * When the VC-expression generator does not support LET expresions, this
+ * will eventually turn into:
+ * b_correct <== wp(b_body, X)
+ * where X is:
+ * (/\ s \in Successors(b) :: s_correct)
+ * <==
+ * (/\ d \in DirectDominatees(b) :: BlockEquation(d))
+ *
+ * In both cases above, if BlkReached is non-null, then the wp expression
+ * is instead:
+ * b_reached ==> wp(b_body, X)
+ */
- List<VCExprLetBinding!> bindings = new List<VCExprLetBinding!>();
- foreach (Block! dominee in GetSortedBlocksImmediatelyDominatedBy(g, b, totalOrder))
- {
- VCExprLetBinding c = NestedBlockEquation(dominee, BlkCorrect, BlkReached, totalOrder, context, g, gen);
- bindings.Add(c);
- }
+ VCExpr SuccCorrect = SuccessorsCorrect(b, BlkCorrect, null, false, gen);
+ Contract.Assert(SuccCorrect != null);
- VCExpr X = gen.Let(bindings, SuccCorrect);
- VCExpr wlp = Wlp.Block(b, X, context);
- if (BlkReached != null) {
- wlp = gen.Implies((VCExprVar!)BlkReached[b], wlp);
- }
- VCExprVar okVar = (VCExprVar!)BlkCorrect[b];
- return gen.LetBinding(okVar, wlp);
+ List<VCExprLetBinding> bindings = new List<VCExprLetBinding>();
+ foreach (Block dominee in GetSortedBlocksImmediatelyDominatedBy(g, b, totalOrder)) {
+ Contract.Assert(dominee != null);
+ VCExprLetBinding c = NestedBlockEquation(dominee, BlkCorrect, BlkReached, totalOrder, context, g, gen);
+ bindings.Add(c);
+ }
+
+ VCExpr X = gen.Let(bindings, SuccCorrect);
+ VCExpr wlp = Wlp.Block(b, X, context);
+ if (BlkReached != null) {
+ wlp = gen.Implies((VCExprVar)BlkReached[b], wlp);
+ Contract.Assert(wlp != null);
+ }
+ VCExprVar okVar = cce.NonNull((VCExprVar)BlkCorrect[b]);
+ return gen.LetBinding(okVar, wlp);
}
/// <summary>
/// Returns a list of g.ImmediatelyDominatedBy(b), but in a sorted order, hoping to steer around
/// the nondeterminism problems we've been seeing by using just this call.
/// </summary>
- static List<Block!>! GetSortedBlocksImmediatelyDominatedBy(Graph<Block>! g, Block! b, Hashtable/*Block->int*/! totalOrder) {
- List<Block!> list = new List<Block!>();
- foreach (Block! dominee in g.ImmediatelyDominatedBy(b)) {
+ static List<Block/*!*/>/*!*/ GetSortedBlocksImmediatelyDominatedBy(Graph<Block>/*!*/ g, Block/*!*/ b, Hashtable/*Block->int*//*!*/ totalOrder) {
+ Contract.Requires(g != null);
+ Contract.Requires(b != null);
+ Contract.Requires(totalOrder != null);
+ Contract.Ensures(Contract.Result<List<Block>>() != null);
+
+ List<Block> list = new List<Block>();
+ foreach (Block dominee in g.ImmediatelyDominatedBy(b)) {
+ Contract.Assert(dominee != null);
list.Add(dominee);
}
- list.Sort(new Comparison<Block!>(delegate (Block! x, Block! y) {return (int)(!)totalOrder[x] - (int)(!)totalOrder[y];} ));
+ list.Sort(new Comparison<Block>(delegate(Block x, Block y) {
+ return (int)cce.NonNull(totalOrder[x]) - (int)cce.NonNull(totalOrder[y]);
+ }));
return list;
}
-
- static VCExpr! VCViaStructuredProgram
- (Implementation! impl, Hashtable/*<int, Absy!>*/! label2absy,
- ProverContext! proverCtxt)
+
+ static VCExpr VCViaStructuredProgram
+ (Implementation impl, Hashtable/*<int, Absy!>*/ label2absy,
+ ProverContext proverCtxt)
{
+ Contract.Requires(impl != null);
+ Contract.Requires(label2absy != null);
+ Contract.Requires(proverCtxt != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
#region Convert block structure back to a "regular expression"
- RE! r = DAG2RE.Transform((!)impl.Blocks[0]);
+ RE r = DAG2RE.Transform(cce.NonNull(impl.Blocks[0]));
+ Contract.Assert(r != null);
#endregion
- VCContext! ctxt = new VCContext(label2absy, proverCtxt);
+ VCContext ctxt = new VCContext(label2absy, proverCtxt);
+ Contract.Assert(ctxt != null);
#region Send wlp(program,true) to Simplify
return Wlp.RegExpr(r, VCExpressionGenerator.True, ctxt);
#endregion
@@ -4192,9 +4681,11 @@ namespace VC
/// Remove the empty blocks reachable from the block.
/// It changes the visiting state of the blocks, so that if you want to visit again the blocks, you have to reset them...
/// </summary>
- static BlockSeq! RemoveEmptyBlocks(Block! b)
- {
- assert b.TraversingStatus == Block.VisitState.ToVisit;
+ static BlockSeq RemoveEmptyBlocks(Block b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<BlockSeq>() != null);
+
+ Contract.Assert(b.TraversingStatus == Block.VisitState.ToVisit);
Block renameInfo;
BlockSeq retVal = removeEmptyBlocksWorker(b, true, out renameInfo);
if (renameInfo != null && !b.tok.IsValid) {
@@ -4220,10 +4711,12 @@ namespace VC
/// If renameInfoForStartBlock is non-null, it denotes an empty block with location information, and that
/// information would be appropriate to display
/// </summary>
- private static BlockSeq! removeEmptyBlocksWorker(Block! b, bool startNode, out Block renameInfoForStartBlock)
- ensures renameInfoForStartBlock != null ==> renameInfoForStartBlock.tok.IsValid;
+ private static BlockSeq removeEmptyBlocksWorker(Block b, bool startNode, out Block renameInfoForStartBlock)
+ {
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.ValueAtReturn(out renameInfoForStartBlock) == null || Contract.ValueAtReturn(out renameInfoForStartBlock).tok.IsValid);
// ensures: b in result ==> renameInfoForStartBlock == null;
- {
+
renameInfoForStartBlock = null;
BlockSeq bs = new BlockSeq();
GotoCmd gtc = b.TransferCmd as GotoCmd;
@@ -4253,7 +4746,7 @@ namespace VC
if (b.Cmds.Length == 0 && !startNode) {
// b is about to become extinct; try to save its name and location, if possible
if (b.tok.IsValid && gtc.labelTargets.Length == 1) {
- Block succ = (!)gtc.labelTargets[0];
+ Block succ = cce.NonNull(gtc.labelTargets[0]);
if (!succ.tok.IsValid && succ.Predecessors.Length == 1) {
succ.tok = b.tok;
succ.Label = b.Label;
@@ -4265,9 +4758,10 @@ namespace VC
// merge result into a *set* of blocks
Dictionary<Block,bool> mergedSuccessors = new Dictionary<Block,bool>();
int m = 0; // in the following loop, set renameInfoForStartBlock to the value that all recursive calls agree on, if possible; otherwise, null
- foreach (Block! dest in gtc.labelTargets){
+ foreach (Block dest in gtc.labelTargets){Contract.Assert(dest != null);
Block renameInfo;
- BlockSeq! ys = removeEmptyBlocksWorker(dest, false, out renameInfo);
+ BlockSeq ys = removeEmptyBlocksWorker(dest, false, out renameInfo);
+ Contract.Assert(ys != null);
if (m == 0) {
renameInfoForStartBlock = renameInfo;
} else if (renameInfoForStartBlock != renameInfo) {
@@ -4294,8 +4788,9 @@ namespace VC
// otherwise, update the list of successors of b to be the blocks in setOfSuccessors
gtc.labelTargets = setOfSuccessors;
gtc.labelNames = new StringSeq();
- foreach (Block! d in setOfSuccessors)
- gtc.labelNames.Add(d.Label);
+ foreach (Block d in setOfSuccessors){
+ Contract.Assert(d != null);
+ gtc.labelNames.Add(d.Label);}
if (!startNode) {
renameInfoForStartBlock = null;
}
@@ -4307,17 +4802,20 @@ namespace VC
}
}
- static Graph<Block>! GraphFromImpl(Implementation! impl) {
- Graph<Block>! g = new Graph<Block>();
- g.AddSource((!)impl.Blocks[0]); // there is always at least one node in the graph
- foreach (Block! b in impl.Blocks)
- {
+ static Graph<Block> GraphFromImpl(Implementation impl) {
+ Contract.Requires(impl != null);
+
+ Contract.Ensures(Contract.Result<Graph<Block>>() != null);
+
+ Graph<Block> g = new Graph<Block>();
+ g.AddSource(cce.NonNull(impl.Blocks[0])); // there is always at least one node in the graph
+ foreach (Block b in impl.Blocks) {
+ Contract.Assert(b != null);
GotoCmd gtc = b.TransferCmd as GotoCmd;
- if (gtc != null)
- {
- foreach (Block! dest in (!)gtc.labelTargets)
- {
- g.AddEdge(b,dest);
+ if (gtc != null) {
+ foreach (Block dest in cce.NonNull(gtc.labelTargets)) {
+ Contract.Assert(dest != null);
+ g.AddEdge(b, dest);
}
}
}
@@ -4325,10 +4823,13 @@ namespace VC
}
- static void DumpMap(Hashtable /*Variable->Expr*/! map) {
+ static void DumpMap(Hashtable /*Variable->Expr*/ map) {
+ Contract.Requires(map != null);
foreach (DictionaryEntry de in map) {
- Variable! v = (Variable!)de.Key;
- Expr! e = (Expr!)de.Value;
+ Variable v = (Variable)de.Key;
+ Contract.Assert(v != null);
+ Expr e = (Expr)de.Value;
+ Contract.Assert(e != null);
Console.Write(" ");
v.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
Console.Write(" --> ");
diff --git a/Source/VCGeneration/VCDoomed.cs b/Source/VCGeneration/VCDoomed.cs
index 50307c0b..6001093d 100644
--- a/Source/VCGeneration/VCDoomed.cs
+++ b/Source/VCGeneration/VCDoomed.cs
@@ -12,155 +12,180 @@ using System.IO;
using Microsoft.Boogie;
using Graphing;
using AI = Microsoft.AbstractInterpretationFramework;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using Microsoft.Basetypes;
using Microsoft.Boogie.VCExprAST;
-namespace VC
-{
- public class DCGen : ConditionGeneration
- {
+namespace VC {
+ public class DCGen : ConditionGeneration {
#region Attributes
- private Dictionary<Block, Variable!>! m_BlockReachabilityMap;
- Dictionary<Block!, Block!>! m_copiedBlocks = new Dictionary<Block!, Block!>();
+ private Dictionary<Block, Variable/*!*/>/*!*/ m_BlockReachabilityMap;
+ Dictionary<Block/*!*/, Block/*!*/>/*!*/ m_copiedBlocks = new Dictionary<Block/*!*/, Block/*!*/>();
const string reachvarsuffix = "__ivebeenthere";
- List<Cmd!>! m_doomedCmds = new List<Cmd!>();
+ List<Cmd/*!*/>/*!*/ m_doomedCmds = new List<Cmd/*!*/>();
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(m_BlockReachabilityMap));
+ Contract.Invariant(cce.NonNullElements(m_copiedBlocks));
+ Contract.Invariant(cce.NonNullElements(m_doomedCmds));
+ Contract.Invariant(cce.NonNullElements(_copiedBlock));
+ }
+
#endregion
/// <summary>
/// Constructor. Initializes the theorem prover.
/// </summary>
- public DCGen(Program! program, string/*?*/ logFilePath, bool appendLogFile)
- {
- base(program);
+ public DCGen(Program program, string/*?*/ logFilePath, bool appendLogFile)
+ : base(program) {
+ Contract.Requires(program != null);
+
this.appendLogFile = appendLogFile;
this.logFilePath = logFilePath;
- m_BlockReachabilityMap = new Dictionary<Block, Variable!>();
+ m_BlockReachabilityMap = new Dictionary<Block, Variable>();
}
- private void Impl2Dot(Implementation! impl, string! filename) {
- List<string!>! nodes = new List<string!>();
- List<string!>! edges = new List<string!>();
-
- string nodestyle = "[shape=box];" ;
-
- foreach (Block! b in impl.Blocks) {
- nodes.Add(string.Format("\"{0}\" {1}", b.Label, nodestyle) );
- GotoCmd gc = b.TransferCmd as GotoCmd;
- if (gc!=null) {
- assert gc.labelTargets!=null;
- foreach (Block! b_ in gc.labelTargets) {
- edges.Add(String.Format("\"{0}\" -> \"{1}\";", b.Label, b_.Label ) );
- }
- }
+ private void Impl2Dot(Implementation impl, string filename) {
+ Contract.Requires(impl != null);
+ Contract.Requires(filename != null);
+ List<string> nodes = new List<string>();
+ List<string> edges = new List<string>();
+
+ string nodestyle = "[shape=box];";
+
+ foreach (Block b in impl.Blocks) {
+ Contract.Assert(b != null);
+ nodes.Add(string.Format("\"{0}\" {1}", b.Label, nodestyle));
+ GotoCmd gc = b.TransferCmd as GotoCmd;
+ if (gc != null) {
+ Contract.Assert(gc.labelTargets != null);
+ foreach (Block b_ in gc.labelTargets) {
+ Contract.Assert(b_ != null);
+ edges.Add(String.Format("\"{0}\" -> \"{1}\";", b.Label, b_.Label));
+ }
}
-
- using (StreamWriter sw = new StreamWriter(filename))
- {
- sw.WriteLine(String.Format("digraph {0} {{", impl.Name));
-// foreach (string! s in nodes) {
-// sw.WriteLine(s);
-// }
- foreach (string! s in edges) {
- sw.WriteLine(s);
- }
- sw.WriteLine("}}");
- sw.Close();
+ }
+
+ using (StreamWriter sw = new StreamWriter(filename)) {
+ sw.WriteLine(String.Format("digraph {0} {{", impl.Name));
+ // foreach (string! s in nodes) {
+ // sw.WriteLine(s);
+ // }
+ foreach (string s in edges) {
+ Contract.Assert(s != null);
+ sw.WriteLine(s);
}
+ sw.WriteLine("}}");
+ sw.Close();
+ }
}
-
+
private const string _copyPrefix = "Yeah";
-
- private Block! CopyImplBlocks(Block! b, ref List<Block!>! blocklist, Block! targetBlock, ref Dictionary<Block!, Block!>! alreadySeen) {
- Block seen;
- if (alreadySeen.TryGetValue(b, out seen) ) {
- assert seen!=null;
- return seen;
- }
-
- GotoCmd gc = b.TransferCmd as GotoCmd;
- TransferCmd tcmd = null;
- if (gc!=null) {
- BlockSeq! bseq = new BlockSeq();
- assert gc.labelTargets!=null;
- foreach (Block! c in gc.labelTargets) {
- bseq.Add(CopyImplBlocks(c, ref blocklist, targetBlock, ref alreadySeen));
- }
- tcmd = new GotoCmd(gc.tok, bseq);
- } else {
-// BlockSeq! bseq_ = new BlockSeq();
-// bseq_.Add(targetBlock);
- assert b.TransferCmd != null;
-// tcmd = new GotoCmd(b.TransferCmd.tok, bseq_);
- tcmd = new ReturnCmd(b.TransferCmd.tok);
+
+ private Block CopyImplBlocks(Block b, ref List<Block> blocklist, Block targetBlock, ref Dictionary<Block, Block> alreadySeen) {
+ Contract.Requires(b != null);
+ Contract.Requires(targetBlock != null);
+ Contract.Requires(cce.NonNullElements(alreadySeen));
+ Contract.Requires(blocklist != null);
+ Contract.Ensures(Contract.ValueAtReturn(out blocklist) != null);
+ Contract.Ensures(cce.NonNullElements(Contract.ValueAtReturn(out alreadySeen)));
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ Block seen;
+ if (alreadySeen.TryGetValue(b, out seen)) {
+ Contract.Assert(seen != null);
+ return seen;
+ }
+
+ GotoCmd gc = b.TransferCmd as GotoCmd;
+ TransferCmd tcmd = null;
+ if (gc != null) {
+ BlockSeq bseq = new BlockSeq();
+ Contract.Assert(gc.labelTargets != null);
+ foreach (Block c in gc.labelTargets) {
+ Contract.Assert(c != null);
+ bseq.Add(CopyImplBlocks(c, ref blocklist, targetBlock, ref alreadySeen));
}
-
- CodeCopier codeCopier = new CodeCopier();
- CmdSeq! cl = new CmdSeq();
- foreach (Cmd! _c in b.Cmds) {
- if (!ContainsReachVariable(_c))
- cl.Add( codeCopier.CopyCmd(_c));
- }
-
- Block! b_ = new Block(b.tok, b.Label+_copyPrefix, cl, tcmd);
- blocklist.Add(b_);
-
- alreadySeen[b] = b_;
-
- return b_;
+ tcmd = new GotoCmd(gc.tok, bseq);
+ } else {
+ // BlockSeq! bseq_ = new BlockSeq();
+ // bseq_.Add(targetBlock);
+ Contract.Assert(b.TransferCmd != null);
+ // tcmd = new GotoCmd(b.TransferCmd.tok, bseq_);
+ tcmd = new ReturnCmd(b.TransferCmd.tok);
+ }
+
+ CodeCopier codeCopier = new CodeCopier();
+ CmdSeq cl = new CmdSeq();
+ foreach (Cmd _c in b.Cmds) {
+ Contract.Assert(_c != null);
+ if (!ContainsReachVariable(_c))
+ cl.Add(codeCopier.CopyCmd(_c));
+ }
+
+ Block b_ = new Block(b.tok, b.Label + _copyPrefix, cl, tcmd);
+ Contract.Assert(b_ != null);
+ blocklist.Add(b_);
+
+ alreadySeen[b] = b_;
+
+ return b_;
}
-
+
/*
After adding a copy of the implementation in front of our code
we remove all the edges leading from the copy to the original code
*/
- private void RemoveArtificialGoto(Block! b, Block! target) {
- GotoCmd gc = b.TransferCmd as GotoCmd;
+ private void RemoveArtificialGoto(Block b, Block target) {
+ Contract.Requires(b != null);
+ Contract.Requires(target != null);
+ GotoCmd gc = b.TransferCmd as GotoCmd;
- if (gc!=null) {
- assert gc.labelTargets!=null;
- foreach (Block! gt in gc.labelTargets) {
- if (gt==target) {
- assert gc.labelTargets.Length==1;
- assert gc.labelTargets[0]!=null;
- b.TransferCmd = new ReturnCmd(gc.tok);
- return;
- } else {
- RemoveArtificialGoto(gt, target);
- }
- }
-
+ if (gc != null) {
+ Contract.Assert(gc.labelTargets != null);
+ foreach (Block gt in gc.labelTargets) {
+ Contract.Assert(gt != null);
+ if (gt == target) {
+ Contract.Assert(gc.labelTargets.Length == 1);
+ Contract.Assert(gc.labelTargets[0] != null);
+ b.TransferCmd = new ReturnCmd(gc.tok);
+ return;
+ } else {
+ RemoveArtificialGoto(gt, target);
+ }
}
+
+ }
}
-
- static public bool UseItAsDebugger = false;
-
-// public static Implementation _tmpImpl = null; // (MsSchaef) HACK!
-
+
+ static public bool UseItAsDebugger = false;
+
+ // public static Implementation _tmpImpl = null; // (MsSchaef) HACK!
+
public static Block firstNonDebugBlock = null;
public static Block firstDebugBlock = null;
-
- private void ModifyImplForDebugging(Implementation! impl)
- {
+
+ private void ModifyImplForDebugging(Implementation impl) {
+ Contract.Requires(impl != null);
//List<Block!> backup_blocks=null;
-
-
- if (UseItAsDebugger) {
- #region Copy the Implementation /////////////////////
-
+
+
+ if (UseItAsDebugger) {
+ #region Copy the Implementation /////////////////////
+
ConsoleColor col = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.Magenta;
+ Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("Warning you are using the Infinite Improbability Drive!");
- Console.ForegroundColor = col;
-
- List<Block!>! blist = new List<Block!>();
- Dictionary<Block!, Block!>! tmpdict = new Dictionary<Block!, Block!>();
- CopyImplBlocks(impl.Blocks[0], ref blist, impl.Blocks[0], ref tmpdict);
+ Console.ForegroundColor = col;
+
+ List<Block/*!*/>/*!*/ blist = new List<Block/*!*/>();
+ Dictionary<Block, Block> tmpdict = new Dictionary<Block, Block>();
+ CopyImplBlocks(impl.Blocks[0], ref blist, impl.Blocks[0], ref tmpdict);
blist.Reverse();
//_tmpImpl = new Implementation(impl.tok, impl.Name, impl.TypeParameters, impl.InParams, impl.OutParams, impl.LocVars, blist);
-
+
#endregion ////////////////////////////////////
-
+
#region Add implementation copy in front of implementation
// memorize where the original code starts
firstNonDebugBlock = impl.Blocks[0];
@@ -168,82 +193,87 @@ namespace VC
// now add the copied program in front of the original one
blist.AddRange(impl.Blocks);
//backup_blocks = new List<Block!>(impl.Blocks);
-
- BlockSeq! newbseq = new BlockSeq();
+
+ BlockSeq newbseq = new BlockSeq();
newbseq.Add(firstNonDebugBlock);
newbseq.Add(firstDebugBlock);
-
- GotoCmd! newtcmd = new GotoCmd(Token.NoToken, newbseq);
- Block! newfirst = new Block(Token.NoToken, "MySuperFirstBlock", new CmdSeq(), newtcmd);
-
-
- impl.Blocks = new List<Block!>();
+
+ GotoCmd newtcmd = new GotoCmd(Token.NoToken, newbseq);
+ Block newfirst = new Block(Token.NoToken, "MySuperFirstBlock", new CmdSeq(), newtcmd);
+
+
+ impl.Blocks = new List<Block>();
impl.Blocks.Add(newfirst);
impl.Blocks.AddRange(blist);
-
+
//Impl2Dot(impl, String.Format("c:/dot/{0}_copied.dot", impl.Name) );
#endregion
}
- }
-
- void RemoveReachVars(Block! b) {
- GotoCmd gc = b.TransferCmd as GotoCmd;
- if (gc!=null) {
- assert gc.labelTargets!=null;
-
- CmdSeq! cs = new CmdSeq();
- foreach (Cmd! c in b.Cmds) {
- if (!ContainsReachVariable(c)) cs.Add(c);
- }
- b.Cmds = cs;
-
- foreach (Block! c in gc.labelTargets) {
- if (c.Label != "GeneratedUnifiedExit") {
- RemoveReachVars(c);
- }
- }
- }
}
-
- void RemoveLastBlock(Block! b)
- {
- GotoCmd gc = b.TransferCmd as GotoCmd;
- if (gc==null) {
- //Console.WriteLine("WARNING: Check Node {0}", b.Label);
- return;
+
+ void RemoveReachVars(Block b) {
+ Contract.Requires(b != null);
+ GotoCmd gc = b.TransferCmd as GotoCmd;
+ if (gc != null) {
+ CmdSeq cs = new CmdSeq();
+ foreach (Cmd c in b.Cmds) {
+ Contract.Assert(c != null);
+ if (!ContainsReachVariable(c))
+ cs.Add(c);
}
- assert gc!=null;
- assert gc.labelTargets !=null;
- BlockSeq! tmp = new BlockSeq();
- foreach (Block! c in gc.labelTargets) {
- // Warning, we should not search by name!
- if (c.Label != "GeneratedUnifiedExit" ) {
- tmp.Add(c);
- RemoveLastBlock(c);
- } else {
- c.Predecessors.Remove(b);
- }
+ b.Cmds = cs;
+
+ foreach (Block c in gc.labelTargets) {
+ Contract.Assert(c != null);
+ if (c.Label != "GeneratedUnifiedExit") {
+ RemoveReachVars(c);
+ }
}
- if (tmp.Length==0) {
- b.TransferCmd = new ReturnCmd(gc.tok);
+ }
+ }
+
+ void RemoveLastBlock(Block b) {
+ Contract.Requires(b != null);
+ GotoCmd gc = b.TransferCmd as GotoCmd;
+ if (gc == null) {
+ //Console.WriteLine("WARNING: Check Node {0}", b.Label);
+ return;
+ }
+ Contract.Assert(gc != null);
+ Contract.Assert(gc.labelTargets != null);
+ BlockSeq tmp = new BlockSeq();
+ foreach (Block c in gc.labelTargets) {
+ Contract.Assert(c != null);
+ // Warning, we should not search by name!
+ if (c.Label != "GeneratedUnifiedExit") {
+ tmp.Add(c);
+ RemoveLastBlock(c);
} else {
- b.TransferCmd = new GotoCmd(gc.tok, tmp);
+ c.Predecessors.Remove(b);
}
+ }
+ if (tmp.Length == 0) {
+ b.TransferCmd = new ReturnCmd(gc.tok);
+ } else {
+ b.TransferCmd = new GotoCmd(gc.tok, tmp);
+ }
}
-
- void FindCopiedBlocks(Block! b) {
- _copiedBlock.Add(b);
- GotoCmd gc = b.TransferCmd as GotoCmd;
- if (gc!=null) {
- assert gc.labelTargets!=null;
- foreach (Block! c in gc.labelTargets) {
- FindCopiedBlocks(c);
- }
- }
+
+ void FindCopiedBlocks(Block b) {
+ Contract.Requires(b != null);
+ _copiedBlock.Add(b);
+ GotoCmd gc = b.TransferCmd as GotoCmd;
+ if (gc != null) {
+ Contract.Assert(gc.labelTargets != null);
+ foreach (Block c in gc.labelTargets) {
+ Contract.Assert(c != null);
+ FindCopiedBlocks(c);
+ }
+ }
}
-
- private List<Block!>! _copiedBlock = new List<Block!>();
-
+
+ private List<Block> _copiedBlock = new List<Block>();
+
/// <summary>
/// MSchaef:
/// - remove loops and add reach variables
@@ -252,473 +282,523 @@ namespace VC
/// - check if |= (reach=false) => wlp.S.false holds for each reach
///
/// </summary>
- public override Outcome VerifyImplementation(Implementation! impl, Program! program, VerifierCallback! callback)
- throws UnexpectedProverOutputException;
- {
-
- UseItAsDebugger = CommandLineOptions.Clo.useDoomDebug;
- Stopwatch watch = new Stopwatch();
-
+ public override Outcome VerifyImplementation(Implementation impl, Program program, VerifierCallback callback) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(callback != null);
+ Contract.EnsuresOnThrow<UnexpectedProverOutputException>(true);
+
+ UseItAsDebugger = CommandLineOptions.Clo.useDoomDebug;
+ Stopwatch watch = new Stopwatch();
+
//Impl2Dot(impl, String.Format("c:/dot/{0}_raw.dot", impl.Name) );
- if (CommandLineOptions.Clo.TraceVerify) {
+ if (CommandLineOptions.Clo.TraceVerify) {
Console.WriteLine(">>> Checking function {0} for doomed points.", impl.Name);
}
Console.WriteLine("Checking function {0} for doomed points:", impl.Name);
- callback.OnProgress("doomdetector",0,0,0);
+ callback.OnProgress("doomdetector", 0, 0, 0);
+
+ watch.Reset();
+ watch.Start();
+
- watch.Reset();
- watch.Start();
-
-
#region Transform the Program into loop-free passive form
variable2SequenceNumber = new Hashtable/*Variable -> int*/();
- incarnationOriginMap = new Dictionary<Incarnation, Absy!>();
- List<Block!>! cblocks = new List<Block!>();
-
+ incarnationOriginMap = new Dictionary<Incarnation, Absy>();
+ List<Block> cblocks = new List<Block>();
+
//List<Block!>! orig_blocks = new List<Block!>(impl.Blocks);
-
- Dictionary<Block!, Block!> copiedblocks;
+
+ Dictionary<Block, Block> copiedblocks;
impl.Blocks = DCProgramTransformer.Convert2Dag(impl, program, cblocks, out copiedblocks);
- assert copiedblocks!=null;
+ Contract.Assert(copiedblocks != null);
-// List<Block!>! blist = new List<Block!>();
-// blist.AddRange(impl.Blocks);
+ // List<Block!>! blist = new List<Block!>();
+ // blist.AddRange(impl.Blocks);
- if (UseItAsDebugger) ModifyImplForDebugging(impl);
+ if (UseItAsDebugger)
+ ModifyImplForDebugging(impl);
ComputePredecessors(impl.Blocks);
- m_BlockReachabilityMap = new Dictionary<Block, Variable!>();
+ m_BlockReachabilityMap = new Dictionary<Block, Variable>();
GenerateReachVars(impl);
- if (UseItAsDebugger) RemoveReachVars((!)firstDebugBlock);
-
+ if (UseItAsDebugger)
+ RemoveReachVars(cce.NonNull(firstDebugBlock));
+
PassifyProgram(impl);
-
-
+
+
#endregion
//EmitImpl(impl,false);
-
- //Impl2Dot(impl, String.Format("c:/dot/{0}_passive.dot", impl.Name) );
-// ---------------------------------------------------------------------------
- if (UseItAsDebugger) {
- assert firstNonDebugBlock != null && firstDebugBlock != null;
- firstNonDebugBlock.Predecessors.Remove(impl.Blocks[0]);
+ //Impl2Dot(impl, String.Format("c:/dot/{0}_passive.dot", impl.Name) );
+
+ // ---------------------------------------------------------------------------
+ if (UseItAsDebugger) {
+ Contract.Assert(firstNonDebugBlock != null && firstDebugBlock != null);
+ firstNonDebugBlock.Predecessors.Remove(impl.Blocks[0]);
firstDebugBlock.Predecessors.Remove(impl.Blocks[0]);
-// impl.Blocks.Remove(impl.Blocks[0]); // remove the artificial first block
+ // impl.Blocks.Remove(impl.Blocks[0]); // remove the artificial first block
RemoveLastBlock(firstDebugBlock); // remove the goto to the unified exit
_copiedBlock.Clear();
FindCopiedBlocks(firstDebugBlock);
}
-// ---------------------------------------------------------------------------
-
-// EmitImpl(impl,false);
-
+ // ---------------------------------------------------------------------------
+
+ // EmitImpl(impl,false);
+
//Impl2Dot(impl, String.Format("c:/dot/{0}_final.dot", impl.Name) );
-
+
bool __debug = false;
-
+
watch.Stop();
- if (__debug) Console.WriteLine("Transformation takes: {0}", watch.Elapsed.ToString() );
+ if (__debug)
+ Console.WriteLine("Transformation takes: {0}", watch.Elapsed.ToString());
watch.Reset();
-
- Checker! checker = FindCheckerFor(impl, 1000);
-
+
+ Checker checker = FindCheckerFor(impl, 1000);
+ Contract.Assert(checker != null);
+
DoomCheck dc = new DoomCheck(impl, checker);
-
+
int _totalchecks = 0;
Block b = null;
ProverInterface.Outcome outcome;
- dc.ErrorHandler = new DoomErrorHandler(dc.Label2Absy, callback);
-
- System.TimeSpan ts = watch.Elapsed;
-
- while (dc.GetNextBlock(out b) ) {
- assert b!=null;
+ dc.ErrorHandler = new DoomErrorHandler(dc.Label2Absy, callback);
+
+ System.TimeSpan ts = watch.Elapsed;
+
+ while (dc.GetNextBlock(out b)) {
+ Contract.Assert(b != null);
outcome = ProverInterface.Outcome.Undetermined;
//Console.WriteLine("Checking block {0} ...",b.Label);
Variable v = null;
m_BlockReachabilityMap.TryGetValue(b, out v);
- assert v!=null;
+ Contract.Assert(v != null);
_totalchecks++;
-
-
+
+
watch.Start();
- if (!dc.CheckLabel(v, out outcome) ) {
- return Outcome.Inconclusive;
+ if (!dc.CheckLabel(v, out outcome)) {
+ return Outcome.Inconclusive;
}
watch.Stop();
- ts+=watch.Elapsed;
- if (__debug) Console.WriteLine(" Time for Block {0}: {1} elapsed",b.Label, watch.Elapsed.ToString());
+ ts += watch.Elapsed;
+ if (__debug)
+ Console.WriteLine(" Time for Block {0}: {1} elapsed", b.Label, watch.Elapsed.ToString());
watch.Reset();
-
-
+
+
switch (outcome) {
- case ProverInterface.Outcome.Valid: {
- break;
+ case ProverInterface.Outcome.Valid: {
+ break;
}
- case ProverInterface.Outcome.Invalid: {
-
- break;
+ case ProverInterface.Outcome.Invalid: {
+
+ break;
}
- default: {
-
- break;
+ default: {
+
+ break;
}
}
-
+
}
checker.Close();
-
- if (__debug) Console.WriteLine("Number of Checked Blocks: {0} of {1}", _totalchecks, impl.Blocks.Count );
- if (__debug) Console.WriteLine("Total time for this method: {0}", ts.ToString());
-
+
+ if (__debug)
+ Console.WriteLine("Number of Checked Blocks: {0} of {1}", _totalchecks, impl.Blocks.Count);
+ if (__debug)
+ Console.WriteLine("Total time for this method: {0}", ts.ToString());
+
#region Try to produce a counter example (brute force)
- if (dc.DoomedSequences.Count>0 ) {
+ if (dc.DoomedSequences.Count > 0) {
ConsoleColor col = Console.ForegroundColor;
-// Console.ForegroundColor = ConsoleColor.Red;
-// Console.WriteLine(" {0} is DOOMED!", impl.Name);
-// foreach (List<Block!> bl in dc.DoomedSequences) {
-// Console.Write("Doomed Blocks: ");
-// foreach (Block! b_ in bl) {
-// Console.Write("{0}, ", b_.Label);
-// }
-// Console.WriteLine();
-// }
- Console.ForegroundColor = col;
-
- int counter=1;
- foreach (List<Block!>! bl in dc.DoomedSequences) {
- Console.WriteLine("Doomed program point {0} of {1}", counter++, dc.DoomedSequences.Count);
- dc.ErrorHandler.m_DoomedBlocks = bl;
- foreach (Block! b_ in bl) {
- if (m_BlockReachabilityMap.TryGetValue(b_, out dc.ErrorHandler.m_Reachvar) )break;
- }
- SearchCounterexample(impl, dc.ErrorHandler, callback);
+ // Console.ForegroundColor = ConsoleColor.Red;
+ // Console.WriteLine(" {0} is DOOMED!", impl.Name);
+ // foreach (List<Block!> bl in dc.DoomedSequences) {
+ // Console.Write("Doomed Blocks: ");
+ // foreach (Block! b_ in bl) {
+ // Console.Write("{0}, ", b_.Label);
+ // }
+ // Console.WriteLine();
+ // }
+ Console.ForegroundColor = col;
+
+ int counter = 1;
+ foreach (List<Block> bl in dc.DoomedSequences) {
+ Contract.Assert(bl != null);
+ Console.WriteLine("Doomed program point {0} of {1}", counter++, dc.DoomedSequences.Count);
+ dc.ErrorHandler.m_DoomedBlocks = bl;
+ foreach (Block b_ in bl) {
+ Contract.Assert(b_ != null);
+ if (m_BlockReachabilityMap.TryGetValue(b_, out dc.ErrorHandler.m_Reachvar))
+ break;
+ }
+ SearchCounterexample(impl, dc.ErrorHandler, callback);
}
-
+
//SearchCounterexample(impl, dc.ErrorHandler, callback);
Console.WriteLine("------------------------------ \n\n");
return Outcome.Errors;
}
#endregion
-
+
Console.WriteLine("------------------------------ \n\n");
-
+
return Outcome.Correct;
}
-
-
-
- private void SearchCounterexample(Implementation! impl, DoomErrorHandler! errh, VerifierCallback! callback) {
- if (errh.m_Reachvar==null) {
- assert false;
+
+
+
+ private void SearchCounterexample(Implementation impl, DoomErrorHandler errh, VerifierCallback callback) {
+ Contract.Requires(impl != null);
+ Contract.Requires(errh != null);
+ Contract.Requires(callback != null);
+ Contract.Requires(errh.m_Reachvar != null);
+ //if (errh.m_Reachvar==null) {
+ // Contract.Assert(false);throw new cce.UnreachableException();
+ //}
+ m_doomedCmds.Clear();
+
+ Dictionary<Block, CmdSeq> cmdbackup = new Dictionary<Block, CmdSeq>();
+
+ BruteForceCESearch(errh.m_Reachvar, impl, callback, cmdbackup, 0, impl.Blocks.Count / 2 - 1);
+ BruteForceCESearch(errh.m_Reachvar, impl, callback, cmdbackup, impl.Blocks.Count / 2, impl.Blocks.Count - 1);
+
+ List<Cmd> causals = CollectCausalStatements(impl.Blocks[0]);
+ foreach (Cmd c in causals) {
+ Contract.Assert(c != null);
+ GenerateErrorMessage(c, causals);
+ }
+
+ #region Undo all modifications
+ foreach (KeyValuePair<Block, CmdSeq> kvp in cmdbackup) {
+ Contract.Assert(kvp.Key != null);
+ Contract.Assert(kvp.Value != null);
+ kvp.Key.Cmds = kvp.Value;
+ }
+ #endregion
+ }
+
+ #region Causal Statement Tree
+
+ private void GenerateErrorMessage(Cmd causalStatement, List<Cmd> causals) {
+ Contract.Requires(causalStatement != null);
+ Contract.Requires(cce.NonNullElements(causals));
+ AssumeCmd uc = causalStatement as AssumeCmd;
+ AssertCmd ac = causalStatement as AssertCmd;
+ ConsoleColor col = Console.ForegroundColor;
+
+ // Trivial case. Must be either assume or assert false
+ if (m_doomedCmds.Count == 1) {
+ Console.WriteLine("Found a trivial error:");
+ if (uc != null) {
+ Console.Write("Trivial false assumption: ");
+ Console.Write("({0};{1}):", uc.tok.line, uc.tok.col);
}
- m_doomedCmds.Clear();
-
- Dictionary<Block!, CmdSeq!>! cmdbackup = new Dictionary<Block!, CmdSeq!>();
-
- BruteForceCESearch(errh.m_Reachvar, impl, callback, cmdbackup, 0, impl.Blocks.Count/2-1);
- BruteForceCESearch(errh.m_Reachvar, impl, callback, cmdbackup, impl.Blocks.Count/2,impl.Blocks.Count-1);
-
- List<Cmd!>! causals = CollectCausalStatements(impl.Blocks[0]);
- foreach (Cmd! c in causals ) {
- GenerateErrorMessage(c, causals);
+ if (ac != null) {
+ Console.Write("Trivial false assertion: ");
+ Console.Write("({0};{1}):", ac.tok.line, ac.tok.col);
}
-
- #region Undo all modifications
- foreach (KeyValuePair<Block!, CmdSeq!> kvp in cmdbackup) {
- kvp.Key.Cmds = kvp.Value;
- }
- #endregion
- }
-
-#region Causal Statement Tree
-
- private void GenerateErrorMessage(Cmd! causalStatement, List<Cmd!>! causals)
- {
- AssumeCmd uc = causalStatement as AssumeCmd;
- AssertCmd ac = causalStatement as AssertCmd;
- ConsoleColor col = Console.ForegroundColor;
-
- // Trivial case. Must be either assume or assert false
- if (m_doomedCmds.Count==1) {
- Console.WriteLine("Found a trivial error:" );
- if (uc!=null) {
- Console.Write("Trivial false assumption: " );
- Console.Write("({0};{1}):", uc.tok.line, uc.tok.col );
+ causalStatement.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
+ } else {
+ // Safety error
+ if (ac != null) {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine("Safety error:");
+ Console.ForegroundColor = col;
+ Console.Write("This assertion is violated: ");
+ Console.Write("({0};{1}):", ac.tok.line, ac.tok.col);
+ ac.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
+ }
+ if (uc != null) {
+ bool containsAssert = false;
+ foreach (Cmd c in m_doomedCmds) {
+ Contract.Assert(c != null);
+ if (causals.Contains(c)) {
+ continue;
}
- if (ac!=null) {
- Console.Write("Trivial false assertion: " );
- Console.Write("({0};{1}):", ac.tok.line, ac.tok.col );
- }
- causalStatement.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
- } else {
- // Safety error
- if (ac!=null) {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("Safety error:");
- Console.ForegroundColor = col;
- Console.Write("This assertion is violated: ");
- Console.Write("({0};{1}):", ac.tok.line, ac.tok.col );
- ac.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
+ AssertCmd asrt = c as AssertCmd;
+ if (asrt != null) {
+ containsAssert = true;
+ break;
}
- if (uc!=null) {
- bool containsAssert = false;
- foreach (Cmd! c in m_doomedCmds) {
- if (causals.Contains(c) ) {
- continue;
- }
- AssertCmd asrt = c as AssertCmd;
- if (asrt!=null) {
- containsAssert=true;
- break;
- }
- }
- // Plausibility error
- if (containsAssert) {
- Console.ForegroundColor = ConsoleColor.Yellow ;
- Console.WriteLine("Plausibility error:");
- Console.ForegroundColor = col;
- Console.Write("There is no legal exeuction passing: ");
- Console.Write("({0};{1})", uc.tok.line, uc.tok.col );
- uc.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
- } else { // Reachability error
- Console.ForegroundColor = ConsoleColor.DarkRed ;
- Console.WriteLine("Reachability error:");
- Console.ForegroundColor = col;
- Console.Write("No execution can reach: ");
- Console.Write("({0};{1})", uc.tok.line, uc.tok.col );
- uc.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
- }
-
- }
-
- Console.ForegroundColor = ConsoleColor.White;
- Console.WriteLine("...on any execution passing through:");
- foreach (Cmd! c in m_doomedCmds) {
- if (causals.Contains(c) ) {
- continue;
- }
- Console.ForegroundColor = col;
- Console.Write("In ({0};{1}): ", c.tok.line, c.tok.col );
- Console.ForegroundColor = ConsoleColor.DarkYellow ;
- c.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
- }
+ }
+ // Plausibility error
+ if (containsAssert) {
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine("Plausibility error:");
Console.ForegroundColor = col;
- Console.WriteLine("--");
-
- }
- }
+ Console.Write("There is no legal exeuction passing: ");
+ Console.Write("({0};{1})", uc.tok.line, uc.tok.col);
+ uc.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
+ } else { // Reachability error
+ Console.ForegroundColor = ConsoleColor.DarkRed;
+ Console.WriteLine("Reachability error:");
+ Console.ForegroundColor = col;
+ Console.Write("No execution can reach: ");
+ Console.Write("({0};{1})", uc.tok.line, uc.tok.col);
+ uc.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
+ }
- private List<Cmd!>! CollectCausalStatements(Block! b) {
- Cmd lastCausal=null;
- foreach (Cmd! c in b.Cmds) {
- AssertCmd ac = c as AssertCmd;
- AssumeCmd uc = c as AssumeCmd;
- if (ac!=null && !ContainsReachVariable(ac)) {
- if (ac.Expr!=Expr.True) {
- lastCausal = c;
- }
- } else if (uc!=null && !ContainsReachVariable(uc)) {
- lastCausal = c;
- }
}
-
- List<Cmd!> causals = new List<Cmd!>();
- GotoCmd gc = b.TransferCmd as GotoCmd;
- if (gc!=null && gc.labelTargets!=null) {
- List<Cmd!> tmp;
- //bool allcausal = true;
- foreach (Block! b_ in gc.labelTargets) {
- tmp = CollectCausalStatements(b_);
-
- foreach (Cmd cau in tmp) {
- if (!causals.Contains(cau)) causals.Add(cau);
- }
- }
- //if (allcausal)
- if (causals.Count>0) return causals;
+
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("...on any execution passing through:");
+ foreach (Cmd c in m_doomedCmds) {
+ Contract.Assert(c != null);
+ if (causals.Contains(c)) {
+ continue;
+ }
+ Console.ForegroundColor = col;
+ Console.Write("In ({0};{1}): ", c.tok.line, c.tok.col);
+ Console.ForegroundColor = ConsoleColor.DarkYellow;
+ c.Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
}
- if (lastCausal!=null) causals.Add( lastCausal);
- return causals;
+ Console.ForegroundColor = col;
+ Console.WriteLine("--");
+
+ }
}
-
-#endregion
-
- bool BruteForceCESearch(Variable! reachvar, Implementation! impl, VerifierCallback! callback,
- Dictionary<Block!, CmdSeq!>! cmdbackup, int startidx, int endidx) {
- #region Modify implementation
- for (int i=startidx; i<=endidx; i++) {
- if (_copiedBlock.Contains(impl.Blocks[i])) continue;
- CmdSeq! cs = new CmdSeq();
- cmdbackup.Add(impl.Blocks[i],impl.Blocks[i].Cmds);
- foreach (Cmd! c in impl.Blocks[i].Cmds) {
- if (ContainsReachVariable(c)) {
- cs.Add(c);
- continue;
- }
- AssertCmd ac = c as AssertCmd;
- AssumeCmd uc = c as AssumeCmd;
- if (ac!=null) {
- cs.Add(new AssertCmd(ac.tok, Expr.True) );
- } else if (uc!=null) {
- cs.Add(new AssertCmd(uc.tok, Expr.True) );
- } else {
- cs.Add(c);
- }
- }
- impl.Blocks[i].Cmds = cs;
+
+ private List<Cmd> CollectCausalStatements(Block b) {
+ Contract.Requires(b != null);
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<Cmd>>()));
+
+ Cmd lastCausal = null;
+ foreach (Cmd c in b.Cmds) {
+ Contract.Assert(c != null);
+ AssertCmd ac = c as AssertCmd;
+ AssumeCmd uc = c as AssumeCmd;
+ if (ac != null && !ContainsReachVariable(ac)) {
+ if (ac.Expr != Expr.True) {
+ lastCausal = c;
+ }
+ } else if (uc != null && !ContainsReachVariable(uc)) {
+ lastCausal = c;
}
- #endregion
-
- ProverInterface.Outcome outcome = ProverInterface.Outcome.Undetermined;
- if (!ReCheckImpl(reachvar, impl, callback, out outcome) ) {
- UndoBlockModifications(impl, cmdbackup, startidx, endidx);
- return false;
+ }
+
+ List<Cmd> causals = new List<Cmd>();
+ GotoCmd gc = b.TransferCmd as GotoCmd;
+ if (gc != null && gc.labelTargets != null) {
+ List<Cmd> tmp;
+ //bool allcausal = true;
+ foreach (Block b_ in gc.labelTargets) {
+ Contract.Assert(b_ != null);
+ tmp = CollectCausalStatements(b_);
+
+ foreach (Cmd cau in tmp) {
+ if (!causals.Contains(cau))
+ causals.Add(cau);
+ }
}
- if (outcome == ProverInterface.Outcome.Valid) {
- return true;
- } else if (outcome == ProverInterface.Outcome.Invalid) {
- UndoBlockModifications(impl, cmdbackup, startidx, endidx);
- int mid = startidx + (endidx-startidx)/2;
- if (startidx>=endidx) {
- // Now we found an interesting Block and we have to
- // search for the interesting statements.
- int cmdcount = impl.Blocks[endidx].Cmds.Length;
- BruteForceCmd(impl.Blocks[endidx],0,cmdcount/2 -1,reachvar, impl, callback);
- BruteForceCmd(impl.Blocks[endidx],cmdcount/2,cmdcount-1,reachvar, impl, callback);
- return true;
- } else {
- BruteForceCESearch(reachvar,impl, callback, cmdbackup, startidx, mid);
- BruteForceCESearch(reachvar,impl, callback, cmdbackup, mid+1, endidx);
- return true;
- }
- } else {
- UndoBlockModifications(impl, cmdbackup, startidx, endidx);
- return false;
- }
+ //if (allcausal)
+ if (causals.Count > 0)
+ return causals;
+ }
+ if (lastCausal != null)
+ causals.Add(lastCausal);
+ return causals;
}
-
- bool BruteForceCmd(Block! b, int startidx, int endidx, Variable! reachvar,
- Implementation! impl, VerifierCallback! callback) {
- #region Modify Cmds
- CmdSeq! backup = b.Cmds;
- CmdSeq! cs = new CmdSeq();
- for (int i=0;i<startidx;i++) {
- cs.Add(b.Cmds[i]);
+
+ #endregion
+
+ bool BruteForceCESearch(Variable reachvar, Implementation impl, VerifierCallback callback,
+ Dictionary<Block, CmdSeq> cmdbackup, int startidx, int endidx) {
+ Contract.Requires(reachvar != null);
+ Contract.Requires(impl != null);
+ Contract.Requires(callback != null);
+ Contract.Requires(cce.NonNullElements(cmdbackup));
+ #region Modify implementation
+ for (int i = startidx; i <= endidx; i++) {
+ if (_copiedBlock.Contains(impl.Blocks[i]))
+ continue;
+ CmdSeq cs = new CmdSeq();
+ cmdbackup.Add(impl.Blocks[i], impl.Blocks[i].Cmds);
+ foreach (Cmd c in impl.Blocks[i].Cmds) {
+ Contract.Assert(c != null);
+ if (ContainsReachVariable(c)) {
+ cs.Add(c);
+ continue;
+ }
+ AssertCmd ac = c as AssertCmd;
+ AssumeCmd uc = c as AssumeCmd;
+ if (ac != null) {
+ cs.Add(new AssertCmd(ac.tok, Expr.True));
+ } else if (uc != null) {
+ cs.Add(new AssertCmd(uc.tok, Expr.True));
+ } else {
+ cs.Add(c);
+ }
}
- for (int i=startidx; i<=endidx; i++) {
- Cmd! c = b.Cmds[i];
- if (ContainsReachVariable(c)) {
- cs.Add(c);
- continue;
- }
- cs.Add(new AssertCmd(c.tok, Expr.True));
- }
- for (int i=endidx+1; i<b.Cmds.Length;i++) {
- cs.Add(b.Cmds[i]);
+ impl.Blocks[i].Cmds = cs;
+ }
+ #endregion
+
+ ProverInterface.Outcome outcome = ProverInterface.Outcome.Undetermined;
+ if (!ReCheckImpl(reachvar, impl, callback, out outcome)) {
+ UndoBlockModifications(impl, cmdbackup, startidx, endidx);
+ return false;
+ }
+ if (outcome == ProverInterface.Outcome.Valid) {
+ return true;
+ } else if (outcome == ProverInterface.Outcome.Invalid) {
+ UndoBlockModifications(impl, cmdbackup, startidx, endidx);
+ int mid = startidx + (endidx - startidx) / 2;
+ if (startidx >= endidx) {
+ // Now we found an interesting Block and we have to
+ // search for the interesting statements.
+ int cmdcount = impl.Blocks[endidx].Cmds.Length;
+ BruteForceCmd(impl.Blocks[endidx], 0, cmdcount / 2 - 1, reachvar, impl, callback);
+ BruteForceCmd(impl.Blocks[endidx], cmdcount / 2, cmdcount - 1, reachvar, impl, callback);
+ return true;
+ } else {
+ BruteForceCESearch(reachvar, impl, callback, cmdbackup, startidx, mid);
+ BruteForceCESearch(reachvar, impl, callback, cmdbackup, mid + 1, endidx);
+ return true;
}
+ } else {
+ UndoBlockModifications(impl, cmdbackup, startidx, endidx);
+ return false;
+ }
+ }
- b.Cmds = cs;
- #endregion
-
- #region Recheck
- ProverInterface.Outcome outcome = ProverInterface.Outcome.Undetermined;
- if (!ReCheckImpl(reachvar, impl, callback, out outcome) ) {
- b.Cmds = backup;
- return false;
+ bool BruteForceCmd(Block b, int startidx, int endidx, Variable reachvar,
+ Implementation impl, VerifierCallback callback) {
+ Contract.Requires(b != null);
+ Contract.Requires(reachvar != null);
+ Contract.Requires(impl != null);
+ Contract.Requires(callback != null);
+ #region Modify Cmds
+ CmdSeq backup = b.Cmds;
+ Contract.Assert(backup != null);
+ CmdSeq cs = new CmdSeq();
+ for (int i = 0; i < startidx; i++) {
+ cs.Add(b.Cmds[i]);
+ }
+ for (int i = startidx; i <= endidx; i++) {
+ Cmd c = b.Cmds[i];
+ if (ContainsReachVariable(c)) {
+ cs.Add(c);
+ continue;
}
- #endregion
+ cs.Add(new AssertCmd(c.tok, Expr.True));
+ }
+ for (int i = endidx + 1; i < b.Cmds.Length; i++) {
+ cs.Add(b.Cmds[i]);
+ }
- if (outcome == ProverInterface.Outcome.Valid) {
- return true;
- } else if (outcome == ProverInterface.Outcome.Invalid) {
- b.Cmds = backup;
- if (startidx>=endidx) {
- if (!ContainsReachVariable(b.Cmds[endidx])) {
-// Console.Write(" Witness (");
-//
-// ConsoleColor col = Console.ForegroundColor;
-// Console.ForegroundColor = ConsoleColor.White;
-// Console.Write("{0};{1}", b.Cmds[endidx].tok.line, b.Cmds[endidx].tok.col );
-// Console.ForegroundColor = col;
-// Console.Write("): ");
-// Console.ForegroundColor = ConsoleColor.Yellow;
-// b.Cmds[endidx].Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
-// Console.ForegroundColor = col;
-
- m_doomedCmds.Add(b.Cmds[endidx]);
- return true;
- } else {
- return false;
- }
- } else {
- int mid = startidx + (endidx-startidx)/2;
- BruteForceCmd(b, startidx, mid, reachvar, impl, callback);
- BruteForceCmd(b, mid+1, endidx, reachvar, impl, callback);
- return false; // This is pure random
- }
- } else {
- b.Cmds = backup;
+ b.Cmds = cs;
+ #endregion
+
+ #region Recheck
+ ProverInterface.Outcome outcome = ProverInterface.Outcome.Undetermined;
+ if (!ReCheckImpl(reachvar, impl, callback, out outcome)) {
+ b.Cmds = backup;
+ return false;
+ }
+ #endregion
+
+ if (outcome == ProverInterface.Outcome.Valid) {
+ return true;
+ } else if (outcome == ProverInterface.Outcome.Invalid) {
+ b.Cmds = backup;
+ if (startidx >= endidx) {
+ if (!ContainsReachVariable(b.Cmds[endidx])) {
+ // Console.Write(" Witness (");
+ //
+ // ConsoleColor col = Console.ForegroundColor;
+ // Console.ForegroundColor = ConsoleColor.White;
+ // Console.Write("{0};{1}", b.Cmds[endidx].tok.line, b.Cmds[endidx].tok.col );
+ // Console.ForegroundColor = col;
+ // Console.Write("): ");
+ // Console.ForegroundColor = ConsoleColor.Yellow;
+ // b.Cmds[endidx].Emit(new TokenTextWriter("<console>", Console.Out, false), 0);
+ // Console.ForegroundColor = col;
+
+ m_doomedCmds.Add(b.Cmds[endidx]);
+ return true;
+ } else {
return false;
+ }
+ } else {
+ int mid = startidx + (endidx - startidx) / 2;
+ BruteForceCmd(b, startidx, mid, reachvar, impl, callback);
+ BruteForceCmd(b, mid + 1, endidx, reachvar, impl, callback);
+ return false; // This is pure random
}
-
+ } else {
+ b.Cmds = backup;
return false;
+ }
+
+ return false;
}
-
- void UndoBlockModifications(Implementation! impl, Dictionary<Block!, CmdSeq!>! cmdbackup,
+
+ void UndoBlockModifications(Implementation impl, Dictionary<Block/*!*/, CmdSeq/*!*/>/*!*/ cmdbackup,
int startidx, int endidx) {
- for (int i=startidx; i<=endidx; i++) {
- CmdSeq cs = null;
- if (cmdbackup.TryGetValue(impl.Blocks[i], out cs) ) {
- assert cs!=null;
- impl.Blocks[i].Cmds = cs;
- cmdbackup.Remove(impl.Blocks[i]);
- }
- }
+ Contract.Requires(cce.NonNullElements(cmdbackup));
+ Contract.Requires(impl != null);
+ for (int i = startidx; i <= endidx; i++) {
+ CmdSeq cs = null;
+ if (cmdbackup.TryGetValue(impl.Blocks[i], out cs)) {
+ Contract.Assert(cs != null);
+ impl.Blocks[i].Cmds = cs;
+ cmdbackup.Remove(impl.Blocks[i]);
+ }
+ }
}
-
- bool ReCheckImpl(Variable! reachvar, Implementation! impl, VerifierCallback! callback,
+
+ bool ReCheckImpl(Variable reachvar, Implementation impl, VerifierCallback callback,
out ProverInterface.Outcome outcome) {
- Checker! checker = FindCheckerFor(impl, 1000);
- DoomCheck dc = new DoomCheck(impl, checker);
- dc.ErrorHandler = new DoomErrorHandler(dc.Label2Absy, callback);
- outcome = ProverInterface.Outcome.Undetermined;
- if (!dc.CheckLabel(reachvar, out outcome)) {
- checker.Close();
- return false;
- }
+ Contract.Requires(reachvar != null);
+ Contract.Requires(impl != null);
+ Contract.Requires(callback != null);
+ Checker checker = FindCheckerFor(impl, 1000);
+ Contract.Assert(checker != null);
+ DoomCheck dc = new DoomCheck(impl, checker);
+ dc.ErrorHandler = new DoomErrorHandler(dc.Label2Absy, callback);
+ outcome = ProverInterface.Outcome.Undetermined;
+ if (!dc.CheckLabel(reachvar, out outcome)) {
checker.Close();
- return true;
+ return false;
+ }
+ checker.Close();
+ return true;
}
-
-
- bool ContainsReachVariable(Cmd! c) {
- AssertCmd artc = c as AssertCmd;
- AssumeCmd amec = c as AssumeCmd;
- Expr e;
- if (artc!=null) {
- e = artc.Expr;
- } else if (amec!=null) {
- e = amec.Expr;
- } else {
- return false;
- }
- Set! freevars = new Set();
- e.ComputeFreeVariables(freevars);
- foreach (Variable! v in freevars) {
- if (v.Name.Contains(reachvarsuffix)) return true;
- }
+
+
+ bool ContainsReachVariable(Cmd c) {
+ Contract.Requires(c != null);
+ AssertCmd artc = c as AssertCmd;
+ AssumeCmd amec = c as AssumeCmd;
+ Expr e;
+ if (artc != null) {
+ e = artc.Expr;
+ } else if (amec != null) {
+ e = amec.Expr;
+ } else {
return false;
+ }
+ Set freevars = new Set();
+ e.ComputeFreeVariables(freevars);
+ foreach (Variable v in freevars) {
+ Contract.Assert(v != null);
+ if (v.Name.Contains(reachvarsuffix))
+ return true;
+ }
+ return false;
}
-
-
+
+
#region Loop Removal
/// <summary>
/// This class is accessed only via the static method Convert2Dag
@@ -726,392 +806,463 @@ namespace VC
/// statements. The first and the last unrolling represent the first and last iteration of the loop. The second
/// unrolling stands for any other iteration.
/// </summary>
- private class DCProgramTransformer
- {
- private List<Block!>! Blocks;
- private List<Block!>! m_checkableBlocks;
- private Dictionary<Block!, Block!>! m_copyMap = new Dictionary<Block!, Block!>();
-
- public static List<Block!>! Convert2Dag(Implementation! impl, Program! program, List<Block!>! checkableBlocks,
- out Dictionary<Block!, Block!> copiedblocks)
- {
- Block! start = impl.Blocks[0];
- Dictionary<Block,GraphNode!> gd = new Dictionary<Block,GraphNode!>();
- Set/*Block*/! beingVisited = new Set/*Block*/();
- GraphNode gStart = GraphNode.ComputeGraphInfo(null, start, gd, beingVisited);
-
+ private class DCProgramTransformer {
+ private List<Block> Blocks;
+ private List<Block> m_checkableBlocks;
+ private Dictionary<Block, Block> m_copyMap = new Dictionary<Block, Block>();
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(Blocks));
+ Contract.Invariant(cce.NonNullElements(m_checkableBlocks));
+ Contract.Invariant(cce.NonNullElements(m_copyMap));
+ }
+
+
+ public static List<Block> Convert2Dag(Implementation impl, Program program, List<Block> checkableBlocks,
+ out Dictionary<Block, Block> copiedblocks) {
+ Contract.Requires(impl != null);
+ Contract.Requires(program != null);
+ Contract.Requires(cce.NonNullElements(checkableBlocks));
+ Contract.Requires(1 <= impl.Blocks.Count);
+ Contract.Ensures(cce.NonNullElements(Contract.ValueAtReturn(out copiedblocks)));
+
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>()));
+
+ Block start = impl.Blocks[0];
+ Contract.Assert(start != null);
+ Dictionary<Block, GraphNode> gd = new Dictionary<Block, GraphNode>();
+ Set/*Block*/ beingVisited = new Set/*Block*/();
+ GraphNode gStart = GraphNode.ComputeGraphInfo(null, start, gd, beingVisited);
+
DCProgramTransformer pt = new DCProgramTransformer(checkableBlocks);
- pt.LoopUnrolling(gStart, new Dictionary<GraphNode, Block!>(), true, "");
- pt.Blocks.Reverse();
+ pt.LoopUnrolling(gStart, new Dictionary<GraphNode, Block>(), true, "");
+ pt.Blocks.Reverse();
copiedblocks = pt.m_copyMap;
return pt.Blocks;
}
-
-
- DCProgramTransformer(List<Block!>! checkableBlocks)
- {
- Blocks = new List<Block!>();
+
+
+ DCProgramTransformer(List<Block> checkableBlocks) {
+ Contract.Requires(cce.NonNullElements(checkableBlocks));
+ Blocks = new List<Block>();
m_checkableBlocks = checkableBlocks;
}
-
-
-#region Loop Unrolling Methods
-
- private Block! LoopUnrolling(GraphNode! node, Dictionary<GraphNode, Block!>! visited, bool unrollable, String! prefix)
- {
- Block newb;
- if (visited.TryGetValue(node, out newb))
- {
- assert newb!=null;
- return newb;
- } else
- {
- if (node.IsCutPoint)
- {
- // compute the loop body and the blocks leaving the loop
-
- List<GraphNode!>! loopNodes = new List<GraphNode!>();
- GatherLoopBodyNodes(node, node, loopNodes);
-
- List<GraphNode!>! exitNodes = GatherLoopExitNodes(loopNodes);
-
- // Continue Unrolling after the current loop
- Dictionary<GraphNode, Block!>! _visited = new Dictionary<GraphNode, Block!>();
- foreach (GraphNode! g in exitNodes)
- {
- Block b = LoopUnrolling(g, visited, unrollable, prefix);
- _visited.Add(g,b);
- }
- newb = UnrollCurrentLoop(node, _visited, loopNodes,unrollable, prefix);
- visited.Add(node,newb);
- } else
- {
- BlockSeq! newSuccs = new BlockSeq();
- foreach(GraphNode! g in node.Succecessors)
- {
- newSuccs.Add( LoopUnrolling(g,visited,unrollable,prefix) );
- }
- newb = new Block(node.Block.tok, node.Block.Label + prefix , node.Body, node.Block.TransferCmd);
- Block b;
- if (m_copyMap.TryGetValue(node.Block, out b) ) {
- assert b!=null;
- m_copyMap.Add(newb, b);
- } else {
- m_copyMap.Add(newb, node.Block);
- }
-
-
- assert newb!=null; assert newb.TransferCmd!=null;
- if (newSuccs.Length == 0)
- newb.TransferCmd = new ReturnCmd(newb.TransferCmd.tok);
- else
- newb.TransferCmd = new GotoCmd(newb.TransferCmd.tok, newSuccs);
-
- visited.Add(node, newb);
- Blocks.Add(newb);
- if (unrollable)
- {
- m_checkableBlocks.Add(newb);
- }
- }
- }
- assert newb!=null;
- //newb.checkable = unrollable;
- return newb;
- }
-
- private Block! UnrollCurrentLoop(GraphNode! cutPoint, Dictionary<GraphNode, Block!>! visited,
- List<GraphNode!>! loopNodes, bool unrollable, String! prefix)
- {
- if (unrollable)
- {
- Dictionary<GraphNode, Block!>! visited1 = new Dictionary<GraphNode, Block!>(visited);
- Dictionary<GraphNode, Block!>! visited2 = new Dictionary<GraphNode, Block!>(visited);
- Dictionary<GraphNode, Block!>! visited3 = new Dictionary<GraphNode, Block!>(visited);
-
- Block! loopend = ConstructLoopExitBlock(cutPoint, loopNodes, visited, prefix+"#Last");
-
- Block! last = UnrollOnce(cutPoint, loopend,visited1,false, prefix+"#Last");
- AddHavocCmd(last,loopNodes);
-
- // You might use true for the unrollable flag as well.
- Block! arb = UnrollOnce(cutPoint, last,visited2,false, prefix+"#Arb");
- AddHavocCmd(arb,loopNodes);
-
-
- BlockSeq! succ = new BlockSeq();
- succ.Add(last); succ.Add(arb);
- assert arb.TransferCmd!=null;
- Block! tmp = new Block(arb.tok, arb.Label + prefix+"#Dummy" , new CmdSeq(), new GotoCmd(arb.TransferCmd.tok, succ));
- Blocks.Add(tmp);
- m_checkableBlocks.Add(tmp);
-
- // check if arb is already a copy of something else
- // if not then write to m_copyMap that tmp is a copy
- // of arb
- Block b = null;
- if (m_copyMap.TryGetValue(arb,out b) ) {
- assert b!=null;
- m_copyMap.Add(tmp, b);
- } else {
- m_copyMap.Add(tmp, arb);
- }
-
- Block! first = UnrollOnce(cutPoint, tmp,visited3,false, prefix+"#First");
-
- return first;
-
- } else
- {
- Dictionary<GraphNode, Block!>! visited_ = new Dictionary<GraphNode, Block!>(visited);
- Block! loopend = AbstractIteration(cutPoint, prefix+"#UR");
- Block! ret = UnrollOnce(cutPoint, loopend,visited_,false, prefix);
- AddHavocCmd(ret, loopNodes);
- return ret;
- }
- }
-
- private Block! UnrollOnce(GraphNode! node, Block! nextIter, Dictionary<GraphNode, Block!>! visited, bool unrollable, String! prefix)
- {
- visited.Add(node, nextIter);
- Block newb,b;
- BlockSeq! newSuccs = new BlockSeq();
- foreach(GraphNode! g in node.Succecessors)
- {
- newSuccs.Add( LoopUnrolling(g,visited,unrollable,prefix) );
- }
- newb = new Block(node.Block.tok, node.Block.Label + prefix , node.Body, node.Block.TransferCmd);
- if (m_copyMap.TryGetValue(node.Block, out b) ) {
- assert b!=null;
- m_copyMap.Add(newb, b);
- } else {
- m_copyMap.Add(newb, node.Block);
- }
-
- assert newb!=null; assert newb.TransferCmd!=null;
- if (newSuccs.Length == 0)
- newb.TransferCmd = new ReturnCmd(newb.TransferCmd.tok);
- else
- newb.TransferCmd = new GotoCmd(newb.TransferCmd.tok, newSuccs);
-
- Blocks.Add(newb);
- if (unrollable) m_checkableBlocks.Add(newb);
- return newb;
- }
-
- private Block! AbstractIteration(GraphNode! node, String! prefix)
- {
- CmdSeq body = new CmdSeq();
- foreach (Cmd! c in node.Body)
- {
- if (c is PredicateCmd || c is CommentCmd)
- body.Add(c );
- else
- break;
- }
- body.Add(new AssumeCmd(node.Block.tok, Expr.False) );
- TransferCmd! tcmd = new ReturnCmd(node.Block.tok);
- Block! b = new Block(node.Block.tok, node.Block.Label + prefix, body, tcmd);
- Blocks.Add(b);
- Block tmp;
- if (m_copyMap.TryGetValue(node.Block, out tmp) ) {
- assert tmp!=null;
- m_copyMap.Add(b, tmp);
- } else {
- m_copyMap.Add(b, node.Block);
- }
-
- return b;
- }
-
- private Block! ConstructLoopExitBlock(GraphNode! cutPoint, List<GraphNode!>! loopNodes,
- Dictionary<GraphNode, Block!>! visited, String! prefix)
- {
- BlockSeq! newSucc = new BlockSeq();
- Block! orig = cutPoint.Block;
-
- // detect the block after the loop
- // FixMe: What happens when using break commands?
- foreach (GraphNode! g in cutPoint.Succecessors)
- {
- if (!loopNodes.Contains(g))
- {
- Block b;
- if (visited.TryGetValue(g,out b) )
- newSucc.Add(b);
- }
- }
- TransferCmd tcmd;
- assert orig.TransferCmd!=null;
- if (newSucc.Length==0)
- tcmd = new ReturnCmd(orig.TransferCmd.tok);
- else
- tcmd = new GotoCmd(orig.TransferCmd.tok, newSucc);
- // FixMe: Genertate IToken for counterexample creation
- Block! newb = new Block(orig.tok, orig.Label+prefix+"#Leave", orig.Cmds, tcmd);
- Blocks.Add(newb);
- m_checkableBlocks.Add(newb);
- return newb;
- }
-
-
- private void GatherLoopBodyNodes(GraphNode! current, GraphNode! cutPoint, List<GraphNode!>! loopNodes)
- {
- loopNodes.Add(current);
- if (false) System.Diagnostics.Debugger.Break();
- foreach (GraphNode! g in current.Predecessors)
- {
- if (cutPoint.firstPredecessor == g || g == cutPoint || loopNodes.Contains(g) ) continue;
- GatherLoopBodyNodes(g, cutPoint, loopNodes);
- }
- }
-
- private List<GraphNode!>! GatherLoopExitNodes(List<GraphNode!>! loopNodes)
- {
- List<GraphNode!>! exitnodes = new List<GraphNode!>();
-
- foreach (GraphNode! g in loopNodes)
- {
- foreach (GraphNode! s in g.Succecessors)
- {
- if (!loopNodes.Contains(s) /*&& !exitnodes.Contains(s)*/ ) exitnodes.Add(s);
- }
- }
- return exitnodes;
- }
-
- private void AddHavocCmd(Block! b, List<GraphNode!>! loopNodes)
- {
- List<Block!>! loopBlocks = new List<Block!>();
- foreach (GraphNode! g in loopNodes) loopBlocks.Add(g.Block);
- HavocCmd! hcmd = HavocLoopTargets(loopBlocks,b.tok);
- CmdSeq! body = new CmdSeq();
- body.Add(hcmd);
- body.AddRange(b.Cmds);
- b.Cmds = body;
- }
-
- private HavocCmd! HavocLoopTargets(List<Block!>! bl, IToken! tok)
- {
- VariableSeq varsToHavoc = new VariableSeq();
- foreach ( Block! b in bl )
- {
- foreach ( Cmd! c in b.Cmds )
- {
- c.AddAssignedVariables(varsToHavoc);
- }
- }
- IdentifierExprSeq havocExprs = new IdentifierExprSeq();
- foreach ( Variable! v in varsToHavoc )
- {
- IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v);
- if(!havocExprs.Has(ie))
- havocExprs.Add(ie);
- }
- // pass the token of the enclosing loop header to the HavocCmd so we can reconstruct
- // the source location for this later on
- return new HavocCmd(tok,havocExprs);
- }
-
- #endregion
-
- #region GraphNode
- private class GraphNode
- {
- public readonly Block! Block;
- public readonly CmdSeq! Body;
- public bool IsCutPoint; // is set during ComputeGraphInfo
- [Rep] public readonly List<GraphNode!>! Predecessors = new List<GraphNode!>();
- [Rep] public readonly List<GraphNode!>! Succecessors = new List<GraphNode!>();
- public GraphNode firstPredecessor;
- public List<GraphNode!>! UnavoidableNodes = new List<GraphNode!>(); // should be done using a set
-
- GraphNode(Block! b, CmdSeq! body)
- {
- Block = b; Body = body;
- IsCutPoint = false;
-
- }
- static CmdSeq! GetOptimizedBody(CmdSeq! cmds)
- {
- int n = 0;
- foreach (Cmd c in cmds)
- {
- n++;
- PredicateCmd pc = c as PredicateCmd;
- if (pc != null && pc.Expr is LiteralExpr && ((LiteralExpr)pc.Expr).IsFalse)
- {
- // return a sequence consisting of the commands seen so far
- Cmd[] s = new Cmd[n];
- for (int i = 0; i < n; i++)
- {
- s[i] = cmds[i];
+ #region Loop Unrolling Methods
+
+ private Block LoopUnrolling(GraphNode node, Dictionary<GraphNode, Block> visited, bool unrollable, String prefix) {
+ Contract.Requires(node != null);
+ Contract.Requires(cce.NonNullElements(visited));
+ Contract.Requires(prefix != null);
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ Block newb;
+ if (visited.TryGetValue(node, out newb)) {
+ Contract.Assert(newb != null);
+ return newb;
+ } else {
+ if (node.IsCutPoint) {
+ // compute the loop body and the blocks leaving the loop
+
+ List<GraphNode> loopNodes = new List<GraphNode>();
+ GatherLoopBodyNodes(node, node, loopNodes);
+
+ List<GraphNode> exitNodes = GatherLoopExitNodes(loopNodes);
+
+ // Continue Unrolling after the current loop
+ Dictionary<GraphNode, Block> _visited = new Dictionary<GraphNode, Block>();
+ foreach (GraphNode g in exitNodes) {
+ Contract.Assert(g != null);
+ Block b = LoopUnrolling(g, visited, unrollable, prefix);
+ _visited.Add(g, b);
+ }
+ newb = UnrollCurrentLoop(node, _visited, loopNodes, unrollable, prefix);
+ visited.Add(node, newb);
+ } else {
+ BlockSeq newSuccs = new BlockSeq();
+ foreach (GraphNode g in node.Succecessors) {
+ Contract.Assert(g != null);
+ newSuccs.Add(LoopUnrolling(g, visited, unrollable, prefix));
+ }
+ newb = new Block(node.Block.tok, node.Block.Label + prefix, node.Body, node.Block.TransferCmd);
+ Block b;
+ if (m_copyMap.TryGetValue(node.Block, out b)) {
+ Contract.Assert(b != null);
+ m_copyMap.Add(newb, b);
+ } else {
+ m_copyMap.Add(newb, node.Block);
+ }
+
+
+ Contract.Assert(newb != null);
+ Contract.Assert(newb.TransferCmd != null);
+ if (newSuccs.Length == 0)
+ newb.TransferCmd = new ReturnCmd(newb.TransferCmd.tok);
+ else
+ newb.TransferCmd = new GotoCmd(newb.TransferCmd.tok, newSuccs);
+
+ visited.Add(node, newb);
+ Blocks.Add(newb);
+ if (unrollable) {
+ m_checkableBlocks.Add(newb);
}
- return new CmdSeq(s);
}
}
- return cmds;
+ Contract.Assert(newb != null);
+ //newb.checkable = unrollable;
+ return newb;
}
- private static List<GraphNode!>! Intersect(List<GraphNode!>! left, List<GraphNode!>! right)
- {
- List<GraphNode!>! ret = new List<GraphNode!>();
- List<GraphNode!>! tmp = left;
- tmp.AddRange(right);
- foreach (GraphNode! gn in tmp) {
- if (ret.Contains(gn) ) continue;
- if (left.Contains(gn) && right.Contains(gn)) ret.Add(gn);
+ private Block UnrollCurrentLoop(GraphNode/*!*/ cutPoint, Dictionary<GraphNode, Block/*!*/>/*!*/ visited,
+ List<GraphNode/*!*/>/*!*/ loopNodes, bool unrollable, String/*!*/ prefix) {
+ Contract.Requires(cutPoint != null);
+ Contract.Requires(cce.NonNullElements(visited));
+ Contract.Requires(cce.NonNullElements(loopNodes));
+ Contract.Requires(prefix != null);
+ if (unrollable) {
+ Dictionary<GraphNode, Block> visited1 = new Dictionary<GraphNode, Block>(visited);
+ Dictionary<GraphNode, Block> visited2 = new Dictionary<GraphNode, Block>(visited);
+ Dictionary<GraphNode, Block> visited3 = new Dictionary<GraphNode, Block>(visited);
+
+ Block loopend = ConstructLoopExitBlock(cutPoint, loopNodes, visited, prefix + "#Last");
+ Contract.Assert(loopend != null);
+ Block last = UnrollOnce(cutPoint, loopend, visited1, false, prefix + "#Last");
+ Contract.Assert(last != null);
+ AddHavocCmd(last, loopNodes);
+
+ // You might use true for the unrollable flag as well.
+ Block arb = UnrollOnce(cutPoint, last, visited2, false, prefix + "#Arb");
+ Contract.Assert(arb != null);
+ AddHavocCmd(arb, loopNodes);
+
+
+ BlockSeq succ = new BlockSeq();
+ succ.Add(last);
+ succ.Add(arb);
+ Contract.Assert(arb.TransferCmd != null);
+ Block tmp = new Block(arb.tok, arb.Label + prefix + "#Dummy", new CmdSeq(), new GotoCmd(arb.TransferCmd.tok, succ));
+ Contract.Assert(tmp != null);
+ Blocks.Add(tmp);
+ m_checkableBlocks.Add(tmp);
+
+ // check if arb is already a copy of something else
+ // if not then write to m_copyMap that tmp is a copy
+ // of arb
+ Block b = null;
+ if (m_copyMap.TryGetValue(arb, out b)) {
+ Contract.Assert(b != null);
+ m_copyMap.Add(tmp, b);
+ } else {
+ m_copyMap.Add(tmp, arb);
+ }
+
+ Block first = UnrollOnce(cutPoint, tmp, visited3, false, prefix + "#First");
+ Contract.Assert(first != null);
+
+ return first;
+
+ } else {
+ Dictionary<GraphNode, Block> visited_ = new Dictionary<GraphNode, Block>(visited);
+ Block loopend = AbstractIteration(cutPoint, prefix + "#UR");
+ Block ret = UnrollOnce(cutPoint, loopend, visited_, false, prefix);
+ AddHavocCmd(ret, loopNodes);
+ return ret;
}
- return ret;
}
-
- public static GraphNode! ComputeGraphInfo(GraphNode from, Block! b, Dictionary<Block,GraphNode!>! gd, Set /*Block*/! beingVisited)
- {
- GraphNode g;
- if (gd.TryGetValue(b, out g))
- {
- assume from != null;
- assert g != null;
-
- g.UnavoidableNodes = Intersect(g.UnavoidableNodes, from.UnavoidableNodes);
- if (!g.UnavoidableNodes.Contains(g)) g.UnavoidableNodes.Add(g);
-
- g.Predecessors.Add(from);
- if (g.firstPredecessor==null)
- g.firstPredecessor = from;
-
- if (beingVisited.Contains(b))
- g.IsCutPoint = true; // it's a cut point
- } else
- {
+
+ private Block UnrollOnce(GraphNode node, Block nextIter, Dictionary<GraphNode, Block> visited, bool unrollable, String prefix) {
+ Contract.Requires(node != null);
+ Contract.Requires(nextIter != null);
+ Contract.Requires(cce.NonNullElements(visited));
+ Contract.Requires(prefix != null);
+
+
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ visited.Add(node, nextIter);
+ Block newb, b;
+ BlockSeq newSuccs = new BlockSeq();
+ foreach (GraphNode g in node.Succecessors) {
+ Contract.Assert(g != null);
+ newSuccs.Add(LoopUnrolling(g, visited, unrollable, prefix));
+ }
+ newb = new Block(node.Block.tok, node.Block.Label + prefix, node.Body, node.Block.TransferCmd);
+ if (m_copyMap.TryGetValue(node.Block, out b)) {
+ Contract.Assert(b != null);
+ m_copyMap.Add(newb, b);
+ } else {
+ m_copyMap.Add(newb, node.Block);
+ }
+
+ Contract.Assert(newb != null);
+ Contract.Assert(newb.TransferCmd != null);
+ if (newSuccs.Length == 0)
+ newb.TransferCmd = new ReturnCmd(newb.TransferCmd.tok);
+ else
+ newb.TransferCmd = new GotoCmd(newb.TransferCmd.tok, newSuccs);
+
+ Blocks.Add(newb);
+ if (unrollable)
+ m_checkableBlocks.Add(newb);
+ return newb;
+ }
+
+ private Block AbstractIteration(GraphNode node, String prefix) {
+ Contract.Requires(node != null);
+ Contract.Requires(prefix != null);
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ CmdSeq body = new CmdSeq();
+ foreach (Cmd c in node.Body) {
+ Contract.Assert(c != null);
+ if (c is PredicateCmd || c is CommentCmd)
+ body.Add(c);
+ else
+ break;
+ }
+ body.Add(new AssumeCmd(node.Block.tok, Expr.False));
+ TransferCmd tcmd = new ReturnCmd(node.Block.tok);
+ Contract.Assert(tcmd != null);
+ Block b = new Block(node.Block.tok, node.Block.Label + prefix, body, tcmd);
+ Contract.Assert(b != null);
+ Blocks.Add(b);
+ Block tmp;
+ if (m_copyMap.TryGetValue(node.Block, out tmp)) {
+ Contract.Assert(tmp != null);
+ m_copyMap.Add(b, tmp);
+ } else {
+ m_copyMap.Add(b, node.Block);
+ }
+
+ return b;
+ }
+
+ private Block ConstructLoopExitBlock(GraphNode cutPoint, List<GraphNode> loopNodes,
+ Dictionary<GraphNode, Block> visited, String prefix) {
+ Contract.Requires(cutPoint != null);
+ Contract.Requires(cce.NonNullElements(loopNodes));
+ Contract.Requires(cce.NonNullElements(visited));
+ Contract.Requires(prefix != null);
+
+ Contract.Ensures(Contract.Result<Block>() != null);
+
+ BlockSeq newSucc = new BlockSeq();
+ Block orig = cutPoint.Block;
+
+ // detect the block after the loop
+ // FixMe: What happens when using break commands?
+ foreach (GraphNode g in cutPoint.Succecessors) {
+ Contract.Assert(g != null);
+ if (!loopNodes.Contains(g)) {
+ Block b;
+ if (visited.TryGetValue(g, out b))
+ newSucc.Add(b);
+ }
+ }
+ TransferCmd tcmd;
+ Contract.Assert(orig.TransferCmd != null);
+ if (newSucc.Length == 0)
+ tcmd = new ReturnCmd(orig.TransferCmd.tok);
+ else
+ tcmd = new GotoCmd(orig.TransferCmd.tok, newSucc);
+ // FixMe: Genertate IToken for counterexample creation
+ Block newb = new Block(orig.tok, orig.Label + prefix + "#Leave", orig.Cmds, tcmd);
+ Contract.Assert(newb != null);
+ Blocks.Add(newb);
+ m_checkableBlocks.Add(newb);
+ return newb;
+ }
+
+
+ private void GatherLoopBodyNodes(GraphNode current, GraphNode cutPoint, List<GraphNode> loopNodes) {
+ Contract.Requires(current != null);
+ Contract.Requires(cutPoint != null);
+ Contract.Requires(cce.NonNullElements(loopNodes));
+ loopNodes.Add(current);
+ if (false)
+ System.Diagnostics.Debugger.Break();
+ foreach (GraphNode g in current.Predecessors) {
+ Contract.Assert(g != null);
+ if (cutPoint.firstPredecessor == g || g == cutPoint || loopNodes.Contains(g))
+ continue;
+ GatherLoopBodyNodes(g, cutPoint, loopNodes);
+ }
+ }
+
+ private List<GraphNode> GatherLoopExitNodes(List<GraphNode> loopNodes) {
+ Contract.Requires(cce.NonNullElements(loopNodes));
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<GraphNode>>()));
+ List<GraphNode> exitnodes = new List<GraphNode>();
+
+ foreach (GraphNode g in loopNodes) {
+ Contract.Assert(g != null);
+ foreach (GraphNode s in g.Succecessors) {
+ Contract.Assert(s != null);
+ if (!loopNodes.Contains(s) /*&& !exitnodes.Contains(s)*/ )
+ exitnodes.Add(s);
+ }
+ }
+ return exitnodes;
+ }
+
+ private void AddHavocCmd(Block b, List<GraphNode> loopNodes) {
+ Contract.Requires(b != null);
+ Contract.Requires(loopNodes != null);
+ List<Block> loopBlocks = new List<Block>();
+ foreach (GraphNode g in loopNodes) {
+ Contract.Assert(g != null);
+ loopBlocks.Add(g.Block);
+ }
+ HavocCmd hcmd = HavocLoopTargets(loopBlocks, b.tok);
+ Contract.Assert(hcmd != null);
+ CmdSeq body = new CmdSeq();
+ body.Add(hcmd);
+ body.AddRange(b.Cmds);
+ b.Cmds = body;
+ }
+
+ private HavocCmd HavocLoopTargets(List<Block> bl, IToken tok) {
+ Contract.Requires(bl != null);
+ Contract.Requires(tok != null);
+ Contract.Ensures(Contract.Result<HavocCmd>() != null);
+
+ VariableSeq varsToHavoc = new VariableSeq();
+ foreach (Block b in bl) {
+ Contract.Assert(b != null);
+ foreach (Cmd c in b.Cmds) {
+ Contract.Assert(c != null);
+ c.AddAssignedVariables(varsToHavoc);
+ }
+ }
+ IdentifierExprSeq havocExprs = new IdentifierExprSeq();
+ foreach (Variable v in varsToHavoc) {
+ Contract.Assert(v != null);
+ IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v);
+ if (!havocExprs.Has(ie))
+ havocExprs.Add(ie);
+ }
+ // pass the token of the enclosing loop header to the HavocCmd so we can reconstruct
+ // the source location for this later on
+ return new HavocCmd(tok, havocExprs);
+ }
+
+ #endregion
+
+
+ #region GraphNode
+ private class GraphNode {
+ public readonly Block Block;
+ public readonly CmdSeq Body;
+ public bool IsCutPoint; // is set during ComputeGraphInfo
+ [Rep]
+ public readonly List<GraphNode/*!*/>/*!*/ Predecessors = new List<GraphNode>();
+ [Rep]
+ public readonly List<GraphNode/*!*/>/*!*/ Succecessors = new List<GraphNode>();
+ public GraphNode firstPredecessor;
+ public List<GraphNode/*!*/>/*!*/ UnavoidableNodes = new List<GraphNode/*!*/>(); // should be done using a set
+
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(Block != null);
+ Contract.Invariant(Body != null);
+ Contract.Invariant(cce.NonNullElements(Predecessors));
+ Contract.Invariant(cce.NonNullElements(Succecessors));
+ Contract.Invariant(cce.NonNullElements(UnavoidableNodes));
+ }
+
+
+ GraphNode(Block b, CmdSeq body) {
+ Contract.Requires(b != null);
+ Contract.Requires(body != null);
+ Block = b;
+ Body = body;
+ IsCutPoint = false;
+
+ }
+
+ static CmdSeq GetOptimizedBody(CmdSeq cmds) {
+ Contract.Requires(cmds != null);
+ Contract.Ensures(Contract.Result<CmdSeq>() != null);
+
+ int n = 0;
+ foreach (Cmd c in cmds) {
+ n++;
+ PredicateCmd pc = c as PredicateCmd;
+ if (pc != null && pc.Expr is LiteralExpr && ((LiteralExpr)pc.Expr).IsFalse) {
+ // return a sequence consisting of the commands seen so far
+ Cmd[] s = new Cmd[n];
+ for (int i = 0; i < n; i++) {
+ s[i] = cmds[i];
+ }
+ return new CmdSeq(s);
+ }
+ }
+ return cmds;
+ }
+
+ private static List<GraphNode> Intersect(List<GraphNode> left, List<GraphNode> right) {
+ Contract.Requires(left != null);
+ Contract.Requires(right != null);
+ Contract.Ensures(cce.NonNullElements(Contract.Result<List<GraphNode>>()));
+ List<GraphNode> ret = new List<GraphNode>();
+ List<GraphNode> tmp = left;
+ tmp.AddRange(right);
+ foreach (GraphNode gn in tmp) {
+ Contract.Assert(gn != null);
+ if (ret.Contains(gn))
+ continue;
+ if (left.Contains(gn) && right.Contains(gn))
+ ret.Add(gn);
+ }
+ return ret;
+ }
+
+ public static GraphNode ComputeGraphInfo(GraphNode from, Block b, Dictionary<Block, GraphNode> gd, Set /*Block*/ beingVisited) {
+ Contract.Requires(b != null);
+ Contract.Requires(beingVisited != null);
+ Contract.Requires(cce.NonNullElements(gd));
+
+ Contract.Ensures(Contract.Result<GraphNode>() != null);
+
+ GraphNode g;
+ if (gd.TryGetValue(b, out g)) {
+ Contract.Assume(from != null);
+ Contract.Assert(g != null);
+
+ g.UnavoidableNodes = Intersect(g.UnavoidableNodes, from.UnavoidableNodes);
+ if (!g.UnavoidableNodes.Contains(g))
+ g.UnavoidableNodes.Add(g);
+
+ g.Predecessors.Add(from);
+ if (g.firstPredecessor == null)
+ g.firstPredecessor = from;
+
+ if (beingVisited.Contains(b))
+ g.IsCutPoint = true; // it's a cut point
+ } else {
CmdSeq body = GetOptimizedBody(b.Cmds);
g = new GraphNode(b, body);
gd.Add(b, g);
- if (from != null)
- {
+ if (from != null) {
g.Predecessors.Add(from);
- if (from==null)
+ if (from == null)
g.firstPredecessor = g;
-
- if (g.firstPredecessor==null)
+
+ if (g.firstPredecessor == null)
g.firstPredecessor = from;
-
+
}
- if (body != b.Cmds)
- {
- // the body was optimized -- there is no way through this block
- } else
- {
+ if (body != b.Cmds) {
+ // the body was optimized -- there is no way through this block
+ } else {
beingVisited.Add(b);
GotoCmd gcmd = b.TransferCmd as GotoCmd;
- if (gcmd != null)
- {
- assume gcmd.labelTargets != null;
- foreach (Block! succ in gcmd.labelTargets)
- {
- g.Succecessors.Add( ComputeGraphInfo(g, succ, gd, beingVisited) );
+ if (gcmd != null) {
+ Contract.Assume(gcmd.labelTargets != null);
+ foreach (Block succ in gcmd.labelTargets) {
+ Contract.Assert(succ != null);
+ g.Succecessors.Add(ComputeGraphInfo(g, succ, gd, beingVisited));
}
}
beingVisited.Remove(b);
@@ -1120,139 +1271,141 @@ namespace VC
return g;
}
}
-
+
}
- #endregion
+ #endregion
+
+ #endregion
- #endregion
-
#region Program Passification
- private void GenerateReachVars(Implementation! impl)
+ private void GenerateReachVars(Implementation impl) {
+ Contract.Requires(impl != null);
+ Hashtable gotoCmdOrigins = new Hashtable();
+ Block exitBlock = GenerateUnifiedExit(impl, gotoCmdOrigins);
+ Contract.Assert(exitBlock != null);
+
+ AddBlocksBetween(impl);
+
+ #region Insert pre- and post-conditions and where clauses as assume and assert statements
{
- Hashtable gotoCmdOrigins = new Hashtable();
- Block! exitBlock = GenerateUnifiedExit(impl, gotoCmdOrigins);
- AddBlocksBetween(impl);
-
- #region Insert pre- and post-conditions and where clauses as assume and assert statements
- {
- CmdSeq cc = new CmdSeq();
- // where clauses of global variables
- foreach (Declaration d in program.TopLevelDeclarations) {
- GlobalVariable gvar = d as GlobalVariable;
- if (gvar != null && gvar.TypedIdent.WhereExpr != null) {
- Cmd c = new AssumeCmd(gvar.tok, gvar.TypedIdent.WhereExpr);
- cc.Add(c);
- }
+ CmdSeq cc = new CmdSeq();
+ // where clauses of global variables
+ foreach (Declaration d in program.TopLevelDeclarations) {
+ GlobalVariable gvar = d as GlobalVariable;
+ if (gvar != null && gvar.TypedIdent.WhereExpr != null) {
+ Cmd c = new AssumeCmd(gvar.tok, gvar.TypedIdent.WhereExpr);
+ cc.Add(c);
}
- // where clauses of in- and out-parameters
- cc.AddRange( GetParamWhereClauses(impl));
- // where clauses of local variables
- foreach (Variable! lvar in impl.LocVars) {
- if (lvar.TypedIdent.WhereExpr != null) {
- Cmd c = new AssumeCmd(lvar.tok, lvar.TypedIdent.WhereExpr);
- cc.Add(c);
- }
+ }
+ // where clauses of in- and out-parameters
+ cc.AddRange(GetParamWhereClauses(impl));
+ // where clauses of local variables
+ foreach (Variable lvar in impl.LocVars) {
+ Contract.Assert(lvar != null);
+ if (lvar.TypedIdent.WhereExpr != null) {
+ Cmd c = new AssumeCmd(lvar.tok, lvar.TypedIdent.WhereExpr);
+ cc.Add(c);
}
+ }
- // add cc and the preconditions to new blocks preceding impl.Blocks[0]
- InjectPreconditions(impl, cc);
+ // add cc and the preconditions to new blocks preceding impl.Blocks[0]
+ InjectPreconditions(impl, cc);
- // append postconditions, starting in exitBlock and continuing into other blocks, if needed
- exitBlock = InjectPostConditions(impl,exitBlock,gotoCmdOrigins);
- }
- #endregion
- GenerateReachabilityPredicates(impl, exitBlock);
+ // append postconditions, starting in exitBlock and continuing into other blocks, if needed
+ exitBlock = InjectPostConditions(impl, exitBlock, gotoCmdOrigins);
}
-
-
- private Hashtable/*TransferCmd->ReturnCmd*/! PassifyProgram(Implementation! impl)
- {
- current_impl = impl;
- Convert2PassiveCmd(impl);
- impl = current_impl;
- return new Hashtable();
+ #endregion
+ GenerateReachabilityPredicates(impl, exitBlock);
+ }
+
+
+ private Hashtable/*TransferCmd->ReturnCmd*/ PassifyProgram(Implementation impl) {
+ Contract.Requires(impl != null);
+ Contract.Ensures(Contract.Result<Hashtable>() != null);
+
+ current_impl = impl;
+ Convert2PassiveCmd(impl);
+ impl = current_impl;
+ return new Hashtable();
+ }
+
+ /// <summary>
+ /// Add additional variable to allow checking as described in the paper
+ /// "It's doomed; we can prove it"
+ /// </summary>
+ private void GenerateReachabilityPredicates(Implementation impl, Block exitBlock) {
+ Contract.Requires(impl != null);
+ Contract.Requires(exitBlock != null);
+ ExprSeq es = new ExprSeq();
+ Cmd eblockcond = null;
+
+ foreach (Block b in impl.Blocks) {
+ Contract.Assert(b != null);
+ //if (b.Predecessors.Length==0) continue;
+ //if (b.Cmds.Length == 0 ) continue;
+
+ Variable v_ = new LocalVariable(Token.NoToken,
+ new TypedIdent(b.tok, b.Label + reachvarsuffix, new BasicType(SimpleType.Bool)));
+
+ impl.LocVars.Add(v_);
+
+ m_BlockReachabilityMap[b] = v_;
+
+ IdentifierExpr lhs = new IdentifierExpr(b.tok, v_);
+ Contract.Assert(lhs != null);
+
+ es.Add(new IdentifierExpr(b.tok, v_));
+
+ List<AssignLhs> lhsl = new List<AssignLhs>();
+ lhsl.Add(new SimpleAssignLhs(Token.NoToken, lhs));
+ List<Expr> rhsl = new List<Expr>();
+ rhsl.Add(Expr.True);
+
+ if (b != exitBlock) {
+ CmdSeq cs = new CmdSeq(new AssignCmd(Token.NoToken, lhsl, rhsl));
+ cs.AddRange(b.Cmds);
+ b.Cmds = cs;
+ } else {
+ eblockcond = new AssignCmd(Token.NoToken, lhsl, rhsl);
+ }
+
+ //checkBlocks.Add(new CheckableBlock(v_,b));
}
-
- /// <summary>
- /// Add additional variable to allow checking as described in the paper
- /// "It's doomed; we can prove it"
- /// </summary>
- private void GenerateReachabilityPredicates(Implementation! impl, Block! exitBlock)
- {
- ExprSeq! es = new ExprSeq();
- Cmd eblockcond = null;
-
- foreach (Block! b in impl.Blocks)
- {
- //if (b.Predecessors.Length==0) continue;
- //if (b.Cmds.Length == 0 ) continue;
-
- Variable v_ = new LocalVariable(Token.NoToken,
- new TypedIdent(b.tok, b.Label+reachvarsuffix,new BasicType(SimpleType.Bool) ) );
-
- impl.LocVars.Add(v_);
-
- m_BlockReachabilityMap[b] = v_;
-
- IdentifierExpr! lhs = new IdentifierExpr(b.tok, v_);
-
- es.Add( new IdentifierExpr(b.tok, v_) );
-
- List<AssignLhs!>! lhsl = new List<AssignLhs!>();
- lhsl.Add(new SimpleAssignLhs(Token.NoToken, lhs) );
- List<Expr!>! rhsl = new List<Expr!>();
- rhsl.Add(Expr.True);
-
- if (b!=exitBlock)
- {
- CmdSeq cs = new CmdSeq(new AssignCmd(Token.NoToken, lhsl, rhsl));
- cs.AddRange(b.Cmds);
- b.Cmds = cs;
- } else
- {
- eblockcond = new AssignCmd(Token.NoToken, lhsl, rhsl);
- }
-
- //checkBlocks.Add(new CheckableBlock(v_,b));
- }
- if (es.Length==0) return;
-
- Expr aexp = null;
-
- if (es.Length==1)
- {
- aexp = es[0];
- } else if (es.Length==2)
- {
- aexp = Expr.Binary(Token.NoToken,
- BinaryOperator.Opcode.And,
- (!)es[0],
- (!)es[1]);
- } else
- {
- aexp = Expr.True;
- foreach (Expr e_ in es)
- {
- aexp = Expr.Binary(Token.NoToken,
- BinaryOperator.Opcode.And,
- (!)e_, aexp);
- }
- }
- assert (aexp!=null);
- assert (eblockcond!=null);
-
- AssumeCmd ac = new AssumeCmd(Token.NoToken, aexp);
-
- assert(exitBlock!=null);
-
- CmdSeq cseq = new CmdSeq(eblockcond);
- cseq.AddRange(exitBlock.Cmds);
- cseq.Add(ac);
-
- exitBlock.Cmds = cseq;
+ if (es.Length == 0)
+ return;
+
+ Expr aexp = null;
+
+ if (es.Length == 1) {
+ aexp = es[0];
+ } else if (es.Length == 2) {
+ aexp = Expr.Binary(Token.NoToken,
+ BinaryOperator.Opcode.And,
+ cce.NonNull(es[0]),
+ cce.NonNull(es[1]));
+ } else {
+ aexp = Expr.True;
+ foreach (Expr e_ in es) {
+ aexp = Expr.Binary(Token.NoToken,
+ BinaryOperator.Opcode.And,
+ cce.NonNull(e_), aexp);
+ }
}
-
+ Contract.Assert(aexp != null);
+ Contract.Assert(eblockcond != null);
+
+ AssumeCmd ac = new AssumeCmd(Token.NoToken, aexp);
+
+ Contract.Assert(exitBlock != null);
+
+ CmdSeq cseq = new CmdSeq(eblockcond);
+ cseq.AddRange(exitBlock.Cmds);
+ cseq.Add(ac);
+
+ exitBlock.Cmds = cseq;
+ }
+
#endregion
-
+
}
}
diff --git a/Source/VCGeneration/VCGeneration.csproj b/Source/VCGeneration/VCGeneration.csproj
index 768c44bc..f8210ceb 100644
--- a/Source/VCGeneration/VCGeneration.csproj
+++ b/Source/VCGeneration/VCGeneration.csproj
@@ -1,154 +1,128 @@
-<?xml version="1.0" encoding="utf-8"?>
-<VisualStudioProject>
- <XEN ProjectType="Local"
- SchemaVersion="1.0"
- Name="VCGeneration"
- ProjectGuid="f65666de-fb56-457c-8782-09be243450fc"
- >
- <Build>
- <Settings ApplicationIcon=""
- AssemblyName="VCGeneration"
- OutputType="Library"
- RootNamespace="VCGeneration"
- StartupObject=""
- StandardLibraryLocation=""
- TargetPlatform="v2"
- TargetPlatformLocation=""
- >
- <Config Name="Debug"
- AllowUnsafeBlocks="False"
- BaseAddress="285212672"
- CheckForOverflowUnderflow="False"
- ConfigurationOverrideFile=""
- DefineConstants="DEBUG;TRACE"
- DocumentationFile=""
- DebugSymbols="True"
- FileAlignment="4096"
- IncrementalBuild="True"
- Optimize="False"
- OutputPath="bin\debug"
- RegisterForComInterop="False"
- RemoveIntegerChecks="false"
- TreatWarningsAsErrors="False"
- WarningLevel="4"
- ReferenceTypesAreNonNullByDefault="False"
- RunProgramVerifier="False"
- RunProgramVerifierWhileEditing="False"
- ProgramVerifierCommandLineOptions=""
- AllowPointersToManagedStructures="False"
- CheckContractAdmissibility="True"
- CheckPurity="False"
- />
- <Config Name="Release"
- AllowUnsafeBlocks="false"
- BaseAddress="285212672"
- CheckForOverflowUnderflow="false"
- ConfigurationOverrideFile=""
- DefineConstants="TRACE"
- DocumentationFile=""
- DebugSymbols="false"
- FileAlignment="4096"
- IncrementalBuild="false"
- Optimize="true"
- OutputPath="bin\release"
- RegisterForComInterop="false"
- RemoveIntegerChecks="false"
- TreatWarningsAsErrors="false"
- WarningLevel="4"
- />
- </Settings>
- <References>
- <Reference Name="System"
- AssemblyName="System"
- Private="false"
- />
- <Reference Name="System.Data"
- AssemblyName="System.Data"
- Private="false"
- />
- <Reference Name="System.Xml"
- AssemblyName="System.Xml"
- Private="false"
- />
- <Reference Name="Core"
- Project="{47BC34F1-A173-40BE-84C2-9332B4418387}"
- Private="true"
- />
- <Reference Name="AIFramework"
- Project="{24B55172-AD8B-47D1-8952-5A95CFDB9B31}"
- Private="true"
- />
- <Reference Name="Graph"
- Project="{4C28FB90-630E-4B55-A937-11A011B79765}"
- Private="true"
- />
- <Reference Name="Mscorlib.Contracts"
- AssemblyName="Mscorlib.Contracts"
- Private="false"
- HintPath="../../Binaries/Mscorlib.Contracts.dll"
- />
- <Reference Name="System.Contracts"
- AssemblyName="System.Contracts"
- Private="false"
- HintPath="../../Binaries/System.Contracts.dll"
- />
- <Reference Name="Basetypes"
- Project="{0C692837-77EC-415F-BF04-395E3ED06E9A}"
- Private="true"
- />
- <Reference Name="VCExpr"
- Project="{CF42B700-10AA-4DA9-8992-48A800251C11}"
- Private="true"
- />
- </References>
- </Build>
- <Files>
- <Include>
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="Check.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="VC.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="Wlp.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="..\version.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="Context.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="OrderingAxioms.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="ConditionGeneration.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="VCDoomed.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="AssemblyInfo.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="DoomErrorHandler.ssc"
- />
- <File BuildAction="Compile"
- SubType="Code"
- RelPath="DoomCheck.ssc"
- />
- </Include>
- </Files>
- </XEN>
-</VisualStudioProject> \ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E1F10180-C7B9-4147-B51F-FA1B701966DC}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>VCGeneration</RootNamespace>
+ <AssemblyName>VCGeneration</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>InterimKey.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsPointerObligations>False</CodeContractsPointerObligations>
+ <CodeContractsContainerAnalysis>False</CodeContractsContainerAnalysis>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly>
+ </CodeContractsCustomRewriterAssembly>
+ <CodeContractsCustomRewriterClass>
+ </CodeContractsCustomRewriterClass>
+ <CodeContractsLibPaths>
+ </CodeContractsLibPaths>
+ <CodeContractsExtraRewriteOptions>
+ </CodeContractsExtraRewriteOptions>
+ <CodeContractsExtraAnalysisOptions>
+ </CodeContractsExtraAnalysisOptions>
+ <CodeContractsBaseLineFile>
+ </CodeContractsBaseLineFile>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.SpecSharp.Runtime, Version=1.0.21125.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\Binaries\Microsoft.SpecSharp.Runtime.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Compiler.Runtime, Version=1.0.21125.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\Binaries\System.Compiler.Runtime.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="cce.cs" />
+ <Compile Include="Check.cs" />
+ <Compile Include="ConditionGeneration.cs" />
+ <Compile Include="Context.cs" />
+ <Compile Include="DoomCheck.cs" />
+ <Compile Include="DoomErrorHandler.cs" />
+ <Compile Include="OrderingAxioms.cs" />
+ <Compile Include="VC.cs" />
+ <Compile Include="VCDoomed.cs" />
+ <Compile Include="version.cs" />
+ <Compile Include="Wlp.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\AIFramework\AIFramework.sscproj">
+ <Project>{24B55172-AD8B-47D1-8952-5A95CFDB9B31}</Project>
+ <Name>AIFramework</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Basetypes\Basetypes.sscproj">
+ <Project>{0C692837-77EC-415F-BF04-395E3ED06E9A}</Project>
+ <Name>Basetypes</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Core\Core.sscproj">
+ <Project>{47BC34F1-A173-40BE-84C2-9332B4418387}</Project>
+ <Name>Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Graph\Graph.sscproj">
+ <Project>{4C28FB90-630E-4B55-A937-11A011B79765}</Project>
+ <Name>Graph</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\VCExpr\VCExpr.sscproj">
+ <Project>{CF42B700-10AA-4DA9-8992-48A800251C11}</Project>
+ <Name>VCExpr</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="InterimKey.snk" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Properties\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/Source/VCGeneration/Wlp.cs b/Source/VCGeneration/Wlp.cs
index be99dd6d..64cc5c09 100644
--- a/Source/VCGeneration/Wlp.cs
+++ b/Source/VCGeneration/Wlp.cs
@@ -7,26 +7,37 @@ using System;
using System.Collections;
using Microsoft.Boogie;
using Microsoft.Boogie.VCExprAST;
-using Microsoft.Contracts;
+using System.Diagnostics.Contracts;
using System.Collections.Generic;
using Microsoft.Basetypes;
namespace VC {
public class VCContext
{
- [Rep] public readonly Hashtable/*<int, Absy!>*/! Label2absy;
- [Rep] public readonly ProverContext! Ctxt;
+ [ContractInvariantMethod]
+void ObjectInvariant()
+{
+ Contract.Invariant(Label2absy!=null);
+ Contract.Invariant(Ctxt != null);
+}
+
+ [Rep] public readonly Hashtable/*<int, Absy!>*/ Label2absy;
+ [Rep] public readonly ProverContext Ctxt;
public readonly Variable ControlFlowVariable;
- public VCContext(Hashtable/*<int, Absy!>*/! label2absy, ProverContext! ctxt)
+ public VCContext(Hashtable/*<int, Absy!>*/ label2absy, ProverContext ctxt)
{
+ Contract.Requires(label2absy != null);
+ Contract.Requires(ctxt != null);
this.Label2absy = label2absy;
this.Ctxt = ctxt;
// base();
}
- public VCContext(Hashtable/*<int, Absy!>*/! label2absy, ProverContext! ctxt, Variable controlFlowVariable)
+ public VCContext(Hashtable/*<int, Absy!>*/ label2absy, ProverContext ctxt, Variable controlFlowVariable)
{
+ Contract.Requires(label2absy != null);
+ Contract.Requires(ctxt != null);
this.Label2absy = label2absy;
this.Ctxt = ctxt;
this.ControlFlowVariable = controlFlowVariable;
@@ -38,33 +49,46 @@ namespace VC {
public class Wlp
{
- public static VCExpr! Block(Block! b, VCExpr! N, VCContext! ctxt)
- modifies ctxt.*;
+ public static VCExpr Block(Block b, VCExpr N, VCContext ctxt)
+ //modifies ctxt.*;
{
- VCExpressionGenerator! gen = ctxt.Ctxt.ExprGen;
- VCExpr! res = N;
+ Contract.Requires(b != null);
+ Contract.Requires(N != null);
+ Contract.Requires(ctxt != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpressionGenerator gen = ctxt.Ctxt.ExprGen;
+ Contract.Assert(gen != null);
- for (int i = b.Cmds.Length; --i>=0; )
+ VCExpr res = N;
+
+ for (int i = b.Cmds.Length; --i >= 0; )
{
- res = Cmd((!) b.Cmds[i], res, ctxt);
+ res = Cmd(cce.NonNull( b.Cmds[i]), res, ctxt);
}
int id = b.UniqueId;
- expose (ctxt) {
+ cce.BeginExpose(ctxt); {
ctxt.Label2absy[id] = b;
if (ctxt.ControlFlowVariable != null)
return res;
else
- return gen.Implies(gen.LabelPos((!)id.ToString(), VCExpressionGenerator.True), res);
- }
+ return gen.Implies(gen.LabelPos(cce.NonNull(id.ToString()), VCExpressionGenerator.True), res);
+ }cce.EndExpose();
}
/// <summary>
/// Computes the wlp for an assert or assume command "cmd".
/// </summary>
- public static VCExpr! Cmd(Cmd! cmd, VCExpr! N, VCContext! ctxt)
+ public static VCExpr Cmd(Cmd cmd, VCExpr N, VCContext ctxt)
{
- VCExpressionGenerator! gen = ctxt.Ctxt.ExprGen;
+ Contract.Requires(cmd!= null);
+ Contract.Requires(N != null);
+ Contract.Requires(ctxt != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
+ VCExpressionGenerator gen = ctxt.Ctxt.ExprGen;
+ Contract.Assert(gen != null);
if (cmd is AssertCmd) {
AssertCmd ac = (AssertCmd)cmd;
VCExpr C = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);
@@ -85,7 +109,7 @@ namespace VC {
}
break;
default:
- assert false; // unexpected case
+ Contract.Assert(false);throw new cce.UnreachableException(); // unexpected case
}
// (MSchaef) Hack: This line might be useless, but at least it is not harmfull
@@ -95,18 +119,20 @@ namespace VC {
if (ctxt.ControlFlowVariable != null)
{
- VCExpr! controlFlowVariableExpr =
+ VCExpr controlFlowVariableExpr =
ctxt.Ctxt.BoogieExprTranslator.LookupVariable(ctxt.ControlFlowVariable);
- VCExpr! controlFlowFunctionAppl1 =
+ Contract.Assert(controlFlowVariableExpr != null);
+ VCExpr controlFlowFunctionAppl1 =
gen.ControlFlowFunctionApplication(controlFlowVariableExpr, gen.Integer(BigNum.FromInt(id)));
- VCExpr! controlFlowFunctionAppl2 =
+ Contract.Assert(controlFlowFunctionAppl1 != null);
+ VCExpr controlFlowFunctionAppl2 =
gen.ControlFlowFunctionApplication(controlFlowVariableExpr, gen.Integer(BigNum.FromInt(id)));
- VCExpr! assertFailure = gen.Eq(controlFlowFunctionAppl1, gen.Integer(BigNum.FromInt(0)));
- VCExpr! assertSuccess = gen.Neq(controlFlowFunctionAppl2, gen.Integer(BigNum.FromInt(0)));
+ VCExpr assertFailure = gen.Eq(controlFlowFunctionAppl1, gen.Integer(BigNum.FromInt(0)));
+ VCExpr assertSuccess = gen.Neq(controlFlowFunctionAppl2, gen.Integer(BigNum.FromInt(0)));
return gen.And(gen.Implies(assertFailure, C), gen.Implies(assertSuccess, N));
}
else
- return gen.AndSimp(gen.LabelNeg((!)id.ToString(), C), N);
+ return gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), C), N);
}
} else if (cmd is AssumeCmd) {
@@ -119,7 +145,7 @@ namespace VC {
if (naryExpr.Fun is FunctionCall) {
int id = ac.UniqueId;
ctxt.Label2absy[id] = ac;
- return gen.ImpliesSimp(gen.LabelPos((!)"si_fcall_" + id.ToString(), ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr)), N);
+ return gen.ImpliesSimp(gen.LabelPos(cce.NonNull("si_fcall_" + id.ToString()), ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr)), N);
}
}
}
@@ -128,11 +154,12 @@ namespace VC {
} else {
Console.WriteLine(cmd.ToString());
- assert false; // unexpected command
+ Contract.Assert(false);throw new cce.UnreachableException(); // unexpected command
}
}
- public static CommandLineOptions.SubsumptionOption Subsumption(AssertCmd! ac) {
+ public static CommandLineOptions.SubsumptionOption Subsumption(AssertCmd ac) {
+ Contract.Requires(ac != null);
int n = QKeyValue.FindIntAttribute(ac.Attributes, "subsumption", -1);
switch (n) {
case 0: return CommandLineOptions.SubsumptionOption.Never;
@@ -142,8 +169,13 @@ namespace VC {
}
}
- public static VCExpr! RegExpr(RE! r, VCExpr! N, VCContext! ctxt)
+ public static VCExpr RegExpr(RE r, VCExpr N, VCContext ctxt)
{
+ Contract.Requires(r != null);
+ Contract.Requires(N != null);
+ Contract.Requires(ctxt != null);
+ Contract.Ensures(Contract.Result<VCExpr>() != null);
+
if ( r is AtomicRE )
{
AtomicRE ar = (AtomicRE) r;
@@ -157,17 +189,17 @@ namespace VC {
else if ( r is Choice )
{
Choice ch = (Choice) r;
- VCExpr! res;
+ VCExpr res;
if (ch.rs == null || ch.rs.Length==0)
{
res = N;
}
else
{
- VCExpr currentWLP = RegExpr((!)ch.rs[0], N, ctxt);
+ VCExpr currentWLP = RegExpr(cce.NonNull(ch.rs[0]), N, ctxt);
for (int i = 1, n = ch.rs.Length; i < n; i++)
{
- currentWLP = ctxt.Ctxt.ExprGen.And(currentWLP, RegExpr((!)ch.rs[i], N, ctxt));
+ currentWLP = ctxt.Ctxt.ExprGen.And(currentWLP, RegExpr(cce.NonNull(ch.rs[i]), N, ctxt));
}
res = currentWLP;
}
@@ -175,7 +207,7 @@ namespace VC {
}
else
{
- assert false; // unexpected RE subtype
+ Contract.Assert(false);throw new cce.UnreachableException(); // unexpected RE subtype
}
}
}