private static bool MatchPredicateCmd(PredicateCmd cmd, PredicateCmd toMatch, out List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > > substitutions) { var match = false; substitutions = null; if (!ExprMatchVisitor.AreAttributesASubset(toMatch.Attributes, cmd.Attributes)) { return(match); } var mv = new ExprMatchVisitor(toMatch.Expr); mv.VisitExpr(cmd.Expr); if (mv.Matches) { match = true; substitutions = new List <Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> > >() { new Tuple <Dictionary <Declaration, Expr>, Dictionary <string, IAppliable> >(mv.Substitution, mv.FunctionSubstitution) }; } return(match); }
static List <Cmd> GetOptimizedBody(List <Cmd> cmds) { Contract.Requires(cmds != null); Contract.Ensures(Contract.Result <List <Cmd> >() != 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 List <Cmd>(s)); } } return(cmds); }
private void TransformImplicationCandidates(IRegion region, List <PredicateCmd> oldCandidateInvariants) { IdentifierExpr antecedent = null; HashSet <IdentifierExpr> visited = new HashSet <IdentifierExpr>(); do { PredicateCmd current = null; foreach (var p in oldCandidateInvariants) { antecedent = TryGetNegatedBooleanFromCandidate(p, visited); if (antecedent != null) { visited.Add(antecedent); current = p; break; } } if (antecedent != null) { Debug.Assert(current != null); HashSet <PredicateCmd> toRemove = new HashSet <PredicateCmd>(); foreach (var p in oldCandidateInvariants) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); Debug.Assert(e != null); NAryExpr ne = e as NAryExpr; if (ne != null && ne.Fun is BinaryOperator && ((BinaryOperator)ne.Fun).Op == BinaryOperator.Opcode.Imp && ne.Args[0] is IdentifierExpr && ((IdentifierExpr)ne.Args[0]).Name.Equals(antecedent.Name)) { Expr consequent = ne.Args[1]; toRemove.Add(current); toRemove.Add(p); Function implicationExistentialFunction = CreateExistentialFunction( new List <TypedIdent> { new TypedIdent(Token.NoToken, "x", Type.Bool), new TypedIdent(Token.NoToken, "y", Type.Bool) }); implicationExistentialFunction.AddAttribute("absdomain", new object[] { "ImplicationDomain" }); existentialFunctions.Add(implicationExistentialFunction); region.AddInvariant(new AssertCmd( Token.NoToken, new NAryExpr(Token.NoToken, new FunctionCall(implicationExistentialFunction), new List <Expr> { antecedent, consequent }))); } } oldCandidateInvariants.RemoveAll(item => toRemove.Contains(item)); } }while (antecedent != null); }
private IdentifierExpr TryGetPow2VariableFromCandidate(PredicateCmd p) { IdentifierExpr v = null; string tag = QKeyValue.FindStringAttribute(p.Attributes, "tag"); if (tag != null && tag.Contains("pow2 less than")) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); v = (e as NAryExpr).Args[0] as IdentifierExpr; } return(v); }
private IdentifierExpr TryGetNegatedBooleanFromCandidate(PredicateCmd p, HashSet <IdentifierExpr> visited) { string tag = QKeyValue.FindStringAttribute(p.Attributes, "tag"); if (tag != null && (tag.Contains("no read") || tag.Contains("no write"))) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); IdentifierExpr possibleResult = (e as NAryExpr).Args[0] as IdentifierExpr; if (!visited.Contains(possibleResult)) { return(possibleResult); } } return(null); }
private static bool HasAssertFalse(Block b) { foreach (var cmd in b.Cmds) { PredicateCmd pred = cmd as PredicateCmd; if (pred != null) { LiteralExpr f = pred.Expr as LiteralExpr; if (f != null && f.IsFalse) { return(true); } } } return(false); }
///////////////////////////////////////////////////////////////////////////////////// private void addPredicate(BasicBlock current, PredicateCmd predicateCmd) { // ExpressionFactory file = new ExpressionFactory(procedure); Expression e = procedure.expressionFactory.makeExpression(predicateCmd.Expr); PredicateStatement p; if (predicateCmd is AssumeCmd) { p = new Programs.Statements.Boogie.Assume((AssumeCmd)predicateCmd, e); } else { var ac = predicateCmd as AssertCmd; string em = ac.ErrorMessage; if (em == null) { em = ""; } p = new Assert(ac, e, em); } current.appendStatement(p); }
public virtual List<Block /*!*/> /*!*/ DoInlineBlocks(List<Block /*!*/> /*!*/ blocks, ref bool inlinedSomething) { Contract.Requires(cce.NonNullElements(blocks)); Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>())); List<Block /*!*/> /*!*/ newBlocks = new List<Block /*!*/>(); foreach (Block block in blocks) { TransferCmd /*!*/ transferCmd = cce.NonNull(block.TransferCmd); List<Cmd> cmds = block.Cmds; List<Cmd> newCmds = new List<Cmd>(); int lblCount = 0; for (int i = 0; i < cmds.Count; ++i) { Cmd cmd = cmds[i]; if (cmd is CallCmd) { CallCmd callCmd = (CallCmd) cmd; Implementation impl = FindProcImpl(program, callCmd.Proc); if (impl == null) { newCmds.Add(codeCopier.CopyCmd(callCmd)); continue; } int inline = inlineDepth >= 0 ? inlineDepth : GetInlineCount(callCmd, impl); if (inline > 0) { inlinedSomething = true; lblCount = InlineCallCmd(block, callCmd, impl, newCmds, newBlocks, lblCount); newCmds = new List<Cmd>(); } else if (inline == 0) { inlinedSomething = true; if (CommandLineOptions.Clo.ProcedureInlining == CommandLineOptions.Inlining.Assert) { // add assert newCmds.Add(new AssertCmd(callCmd.tok, Expr.False)); } else if (CommandLineOptions.Clo.ProcedureInlining == CommandLineOptions.Inlining.Assume) { // add assume newCmds.Add(new AssumeCmd(callCmd.tok, Expr.False)); } else { // add call newCmds.Add(codeCopier.CopyCmd(callCmd)); } } else { newCmds.Add(codeCopier.CopyCmd(callCmd)); } } else if (cmd is PredicateCmd) { PredicateCmd predCmd = (PredicateCmd) cmd; this.inlinedSomething = false; Expr newExpr = this.VisitExpr(predCmd.Expr); if (this.inlinedSomething) { inlinedSomething = true; PredicateCmd newPredCmd = (PredicateCmd) codeCopier.CopyCmd(predCmd); newPredCmd.Expr = newExpr; newCmds.Add(newPredCmd); } else { newCmds.Add(codeCopier.CopyCmd(predCmd)); } } else if (cmd is AssignCmd) { AssignCmd assignCmd = (AssignCmd) cmd; this.inlinedSomething = false; List<Expr> newRhss = new List<Expr>(); foreach (Expr rhsExpr in assignCmd.Rhss) { newRhss.Add(this.VisitExpr(rhsExpr)); } if (this.inlinedSomething) { inlinedSomething = true; AssignCmd newAssignCmd = (AssignCmd) codeCopier.CopyCmd(assignCmd); newAssignCmd.Rhss = newRhss; newCmds.Add(newAssignCmd); } else { newCmds.Add(codeCopier.CopyCmd(assignCmd)); } } else { newCmds.Add(codeCopier.CopyCmd(cmd)); } } Block newBlock = new Block(block.tok, lblCount == 0 ? block.Label : block.Label + "$" + lblCount, newCmds, codeCopier.CopyTransferCmd(transferCmd)); newBlocks.Add(newBlock); } return newBlocks; }
double AssertionCost(PredicateCmd c) { return(1.0); }
// perform in place update of liveSet public static void Propagate(Cmd cmd, HashSet <Variable /*!*/> /*!*/ liveSet, bool allGlobalsAreLive) { Contract.Requires(cmd != null); Contract.Requires(cce.NonNullElements(liveSet)); if (cmd is AssignCmd) { AssignCmd /*!*/ assignCmd = (AssignCmd)cce.NonNull(cmd); // I must first iterate over all the targets and remove the live ones. // After the removals are done, I must add the variables referred on // the right side of the removed targets AssignCmd simpleAssignCmd = assignCmd.AsSimpleAssignCmd; HashSet <int> indexSet = new HashSet <int>(); int index = 0; foreach (AssignLhs /*!*/ lhs in simpleAssignCmd.Lhss) { Contract.Assert(lhs != null); SimpleAssignLhs salhs = lhs as SimpleAssignLhs; Contract.Assert(salhs != null); Variable var = salhs.DeepAssignedVariable; if (var != null && (liveSet.Contains(var) || (allGlobalsAreLive && var is GlobalVariable))) { indexSet.Add(index); liveSet.Remove(var); } index++; } index = 0; foreach (Expr /*!*/ expr in simpleAssignCmd.Rhss) { Contract.Assert(expr != null); if (indexSet.Contains(index)) { VariableCollector /*!*/ collector = new VariableCollector(); collector.Visit(expr); if (allGlobalsAreLive) { liveSet.UnionWith(collector.usedVars.Where(v => v is LocalVariable || v is Formal)); } else { liveSet.UnionWith(collector.usedVars); } } index++; } } else if (cmd is HavocCmd) { HavocCmd /*!*/ havocCmd = (HavocCmd)cmd; foreach (IdentifierExpr /*!*/ expr in havocCmd.Vars) { Contract.Assert(expr != null); if (expr.Decl != null) { liveSet.Remove(expr.Decl); } } } else if (cmd is PredicateCmd) { Contract.Assert((cmd is AssertCmd || cmd is AssumeCmd)); PredicateCmd /*!*/ predicateCmd = (PredicateCmd)cce.NonNull(cmd); if (predicateCmd.Expr is LiteralExpr) { LiteralExpr le = (LiteralExpr)predicateCmd.Expr; if (le.IsFalse) { liveSet.Clear(); } } else { VariableCollector /*!*/ collector = new VariableCollector(); collector.Visit(predicateCmd.Expr); if (allGlobalsAreLive) { liveSet.UnionWith(collector.usedVars.Where(v => v is LocalVariable || v is Formal)); } else { liveSet.UnionWith(collector.usedVars); } } } else if (cmd is CommentCmd) { // comments are just for debugging and don't affect verification } else if (cmd is SugaredCmd) { SugaredCmd /*!*/ sugCmd = (SugaredCmd)cce.NonNull(cmd); Propagate(sugCmd.Desugaring, liveSet, allGlobalsAreLive); } else if (cmd is StateCmd) { StateCmd /*!*/ stCmd = (StateCmd)cce.NonNull(cmd); List <Cmd> /*!*/ cmds = cce.NonNull(stCmd.Cmds); int len = cmds.Count; for (int i = len - 1; i >= 0; i--) { Propagate(cmds[i], liveSet, allGlobalsAreLive); } foreach (Variable /*!*/ v in stCmd.Locals) { Contract.Assert(v != null); liveSet.Remove(v); } } else { { Contract.Assert(false); throw new cce.UnreachableException(); } } }
public void AddInvariant(PredicateCmd pc) { header.Cmds.Insert(0, pc); }
public void AddInvariant(PredicateCmd cmd) { this.RegionHeader.Cmds.Insert(0, cmd); }
public override void OnUnreachableCode(Implementation impl) { if (HasRequiresFalse(impl)) { return; } bool hasIFUnreachable = false; this.unreachableChildren = new Microsoft.FSharp.Collections.FSharpSet <IdentifierExpr>(new List <IdentifierExpr>()); for (int i = impl.Blocks.Count - 1; i >= 0; i--) { Block b = impl.Blocks[i]; if (HasAssertFalse(b)) { foreach (var cmd in b.Cmds) { PredicateCmd pred = cmd as PredicateCmd; if (pred != null) { NAryExpr nary = pred.Expr as NAryExpr; if (nary != null) { FunctionCall f = nary.Fun as FunctionCall; if (f != null && f.Func.Name == "$expect_unreachable_master") { this.unreachableMasters = this.unreachableMasters.Add(f.Func.InParams.Last() as IdentifierExpr); hasIFUnreachable = true; } else if (f != null && f.Func.Name == "$expect_unreachable_child") { this.unreachableChildren = this.unreachableChildren.Add(f.Func.InParams.Last() as IdentifierExpr); hasIFUnreachable = true; } } } } } } bool hasRealUnreachable = false; foreach (var id in this.unreachableChildren) { if (!unreachableMasters.Contains(id)) { hasRealUnreachable = true; } } if (!hasRealUnreachable && hasIFUnreachable) { PrintSummary(VC.ConditionGeneration.Outcome.Correct); return; } var traceTokens = new List <IToken>(); for (int i = impl.Blocks.Count - 1; i >= 0; i--) { Block b = impl.Blocks[i]; foreach (var cmd in b.Cmds) { PredicateCmd pred = cmd as PredicateCmd; if (pred != null) { NAryExpr nary = pred.Expr as NAryExpr; if (nary != null) { FunctionCall f = nary.Fun as FunctionCall; if (f != null && f.Func.Name == "$expect_unreachable") { return; // Just restoring what existed. This is keeping some potentially easy to let through soundness warnings... } } } } if (!IsTokenWithoutLocation(b.TransferCmd.tok)) { traceTokens.Add(b.TransferCmd.tok); } else { for (int j = b.Cmds.Length - 1; j >= 0; j--) { if (!IsTokenWithoutLocation(b.Cmds[j].tok)) { traceTokens.Add(b.Cmds[j].tok); break; } } } } PrintSummary(VC.ConditionGeneration.Outcome.Correct); // it is correct, but this.ReportUnreachable(traceTokens); }