Пример #1
0
        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);
        }
Пример #2
0
            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);
            }
Пример #3
0
        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);
        }
Пример #6
0
 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);
 }
Пример #7
0
        /////////////////////////////////////////////////////////////////////////////////////
        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);
        }
Пример #8
0
    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;
    }
Пример #9
0
 double AssertionCost(PredicateCmd c)
 {
     return(1.0);
 }
Пример #10
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();
            }
        }
    }
Пример #11
0
 public void AddInvariant(PredicateCmd pc)
 {
     header.Cmds.Insert(0, pc);
 }
Пример #12
0
 public void AddInvariant(PredicateCmd cmd)
 {
     this.RegionHeader.Cmds.Insert(0, cmd);
 }
Пример #13
0
        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);
        }