summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/Core/AbsyCmd.cs25
-rw-r--r--Source/Core/AbsyExpr.cs5
-rw-r--r--Source/VCGeneration/ConditionGeneration.cs3
-rw-r--r--Source/VCGeneration/Wlp.cs30
4 files changed, 53 insertions, 10 deletions
diff --git a/Source/Core/AbsyCmd.cs b/Source/Core/AbsyCmd.cs
index 231ae272..746e70c0 100644
--- a/Source/Core/AbsyCmd.cs
+++ b/Source/Core/AbsyCmd.cs
@@ -2664,11 +2664,6 @@ namespace Microsoft.Boogie {
{
result = LiteralExpr.And(result, c);
result.Type = Type.Bool;
- var nAryExpr = result as NAryExpr;
- if (nAryExpr != null)
- {
- nAryExpr.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
- }
}
else
{
@@ -2757,6 +2752,26 @@ namespace Microsoft.Boogie {
public Expr OrigExpr;
public Dictionary<Variable, Expr> IncarnationMap;
+ Expr verifiedUnder;
+ public Expr VerifiedUnder
+ {
+ get
+ {
+ if (verifiedUnder != null)
+ {
+ return verifiedUnder;
+ }
+ verifiedUnder = QKeyValue.FindExprAttribute(Attributes, "verified_under");
+ return verifiedUnder;
+ }
+ }
+
+ public void MarkAsVerifiedUnder(Expr expr)
+ {
+ Attributes = new QKeyValue(tok, "verified_under", new List<object> { expr }, Attributes);
+ verifiedUnder = expr;
+ }
+
// TODO: convert to use generics
private object errorData;
public object ErrorData {
diff --git a/Source/Core/AbsyExpr.cs b/Source/Core/AbsyExpr.cs
index 880c2155..8918115b 100644
--- a/Source/Core/AbsyExpr.cs
+++ b/Source/Core/AbsyExpr.cs
@@ -155,7 +155,10 @@ namespace Microsoft.Boogie {
} else if (e1 == false_ || e2 == false_) {
return false_;
} else {
- return Binary(BinaryOperator.Opcode.And, e1, e2);
+ var res = Binary(BinaryOperator.Opcode.And, e1, e2);
+ res.Type = Microsoft.Boogie.Type.Bool;
+ res.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
+ return res;
}
}
public static Expr Or(Expr e1, Expr e2) {
diff --git a/Source/VCGeneration/ConditionGeneration.cs b/Source/VCGeneration/ConditionGeneration.cs
index aca9d3f8..3311e6b4 100644
--- a/Source/VCGeneration/ConditionGeneration.cs
+++ b/Source/VCGeneration/ConditionGeneration.cs
@@ -1587,6 +1587,9 @@ namespace VC {
passiveCmds.Add(new AssumeCmd(Token.NoToken, LiteralExpr.Eq(identExpr, copy)));
copy = identExpr;
passiveCmds.Add(new AssumeCmd(Token.NoToken, LiteralExpr.Imp(assmVars, identExpr)));
+
+ // TODO(wuestholz): Try to use this instead:
+ // ac.MarkAsVerifiedUnder(assmVars);
}
else
{
diff --git a/Source/VCGeneration/Wlp.cs b/Source/VCGeneration/Wlp.cs
index c6cebdab..24c36e3b 100644
--- a/Source/VCGeneration/Wlp.cs
+++ b/Source/VCGeneration/Wlp.cs
@@ -26,6 +26,13 @@ namespace VC {
public int AssertionCount; // counts the number of assertions for which Wlp has been computed
public bool isPositiveContext;
+ int letBindingCount;
+ public string FreshLetBindingName()
+ {
+ var c = System.Threading.Interlocked.Increment(ref letBindingCount);
+ return string.Format("v##let##{0}", c);
+ }
+
public VCContext(Dictionary<int, Absy> label2absy, ProverContext ctxt, bool isPositiveContext = true)
{
Contract.Requires(ctxt != null);
@@ -100,8 +107,20 @@ namespace VC {
ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
VCExpr C = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);
ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
+
+ VCExprLetBinding LB = null;
+ VCExpr A = null;
+ if (ac.VerifiedUnder != null)
+ {
+ var V = gen.Variable(ctxt.FreshLetBindingName(), Microsoft.Boogie.Type.Bool);
+ LB = gen.LetBinding(V, C);
+ C = V;
+ A = gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.VerifiedUnder), V);
+ }
+
if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed) {
- return gen.Implies(C, N);
+ var res = gen.Implies(C, N);
+ return A != null ? gen.Let(gen.ImpliesSimp(A, res), LB) : res;
} else {
int id = ac.UniqueId;
if (ctxt.Label2absy != null) {
@@ -131,15 +150,18 @@ namespace VC {
ctxt.AssertionCount++;
if (ctxt.ControlFlowVariableExpr == null) {
Contract.Assert(ctxt.Label2absy != null);
- return gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), C), N);
+ var res = gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), C), N);
+ return A != null ? gen.Let(gen.ImpliesSimp(A, res), LB) : res;
} else {
VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(ctxt.ControlFlowVariableExpr, gen.Integer(BigNum.FromInt(b.UniqueId)));
Contract.Assert(controlFlowFunctionAppl != null);
VCExpr assertFailure = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(-ac.UniqueId)));
if (ctxt.Label2absy == null) {
- return gen.AndSimp(gen.Implies(assertFailure, C), N);
+ var res = gen.AndSimp(gen.Implies(assertFailure, C), N);
+ return A != null ? gen.Let(gen.ImpliesSimp(A, res), LB) : res;
} else {
- return gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), gen.Implies(assertFailure, C)), N);
+ var res = gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), gen.Implies(assertFailure, C)), N);
+ return A != null ? gen.Let(gen.ImpliesSimp(A, res), LB) : res;
}
}
}