void PredicateCmd(Expr p, Expr pDom, List <Cmd> cmdSeq, Cmd cmd)
        {
            if (cmd is CallCmd)
            {
                var cCmd = (CallCmd)cmd;
                Debug.Assert(useProcedurePredicates(cCmd.Proc));
                cCmd.Ins.Insert(0, p != null ? p : Expr.True);
                cmdSeq.Add(cCmd);
            }
            else if (p == null)
            {
                new EnabledReplacementVisitor(Expr.True, pDom).Visit(cmd);
                cmdSeq.Add(cmd);
            }
            else if (cmd is AssignCmd)
            {
                var aCmd = (AssignCmd)cmd;
                cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss,
                                         new List <Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) =>
                                                                       new NAryExpr(Token.NoToken,
                                                                                    new IfThenElse(Token.NoToken),
                                                                                    new List <Expr> {
                    p, rhs, lhs.AsExpr
                })))));
            }
            else if (cmd is AssertCmd)
            {
                var  aCmd    = (AssertCmd)cmd;
                Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr);
                aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr);
                cmdSeq.Add(aCmd);
            }
            else if (cmd is AssumeCmd)
            {
                var  aCmd    = (AssumeCmd)cmd;
                Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr);
                aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr);
                cmdSeq.Add(aCmd);
            }
            else if (cmd is HavocCmd)
            {
                var hCmd = (HavocCmd)cmd;
                foreach (IdentifierExpr v in hCmd.Vars)
                {
                    Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type;
                    Contract.Assert(type != null);

                    IdentifierExpr havocTempExpr;
                    if (havocVars.ContainsKey(type))
                    {
                        havocTempExpr = havocVars[type];
                    }
                    else
                    {
                        var havocVar = new LocalVariable(Token.NoToken,
                                                         new TypedIdent(Token.NoToken,
                                                                        "_HAVOC_" + type.ToString(), type));
                        impl.LocVars.Add(havocVar);
                        havocVars[type] = havocTempExpr =
                            new IdentifierExpr(Token.NoToken, havocVar);
                    }
                    cmdSeq.Add(new HavocCmd(Token.NoToken,
                                            new List <IdentifierExpr> {
                        havocTempExpr
                    }));
                    cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v,
                                                new NAryExpr(Token.NoToken,
                                                             new IfThenElse(Token.NoToken),
                                                             new List <Expr> {
                        p, havocTempExpr, v
                    })));
                }
            }
            else if (cmd is CommentCmd)
            {
                // skip
            }
            else if (cmd is StateCmd)
            {
                var sCmd      = (StateCmd)cmd;
                var newCmdSeq = new List <Cmd>();
                foreach (Cmd c in sCmd.Cmds)
                {
                    PredicateCmd(p, pDom, newCmdSeq, c);
                }
                sCmd.Cmds = newCmdSeq;
                cmdSeq.Add(sCmd);
            }
            else
            {
                Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString());
            }
        }
Esempio n. 2
0
        private bool Analyse(Implementation impl, List <Cmd> cmdSeq, bool ControlFlowIsUniform)
        {
            foreach (Cmd c in cmdSeq)
            {
                if (c is AssignCmd)
                {
                    AssignCmd assignCmd = c as AssignCmd;
                    foreach (var a in assignCmd.Lhss.Zip(assignCmd.Rhss))
                    {
                        if (a.Item1 is SimpleAssignLhs)
                        {
                            SimpleAssignLhs lhs = a.Item1 as SimpleAssignLhs;
                            Expr            rhs = a.Item2;
                            if (IsUniform(impl.Name, lhs.AssignedVariable.Name) &&
                                (!ControlFlowIsUniform || !IsUniform(impl.Name, rhs)))
                            {
                                SetNonUniform(impl.Name, lhs.AssignedVariable.Name);
                            }
                        }
                    }
                }
                else if (c is HavocCmd)
                {
                    HavocCmd havocCmd = c as HavocCmd;
                    foreach (IdentifierExpr ie in havocCmd.Vars)
                    {
                        if (IsUniform(impl.Name, ie.Decl.Name))
                        {
                            SetNonUniform(impl.Name, ie.Decl.Name);
                        }
                    }
                }
                else if (c is CallCmd)
                {
                    CallCmd         callCmd = c as CallCmd;
                    DeclWithFormals Callee  = GetProcedure(callCmd.callee);
                    Debug.Assert(Callee != null);

                    if (!ControlFlowIsUniform)
                    {
                        if (IsUniform(callCmd.callee))
                        {
                            SetNonUniform(callCmd.callee);
                        }
                    }
                    for (int i = 0; i < Callee.InParams.Count; i++)
                    {
                        if (IsUniform(callCmd.callee, Callee.InParams[i].Name) &&
                            !IsUniform(impl.Name, callCmd.Ins[i]))
                        {
                            SetNonUniform(callCmd.callee, Callee.InParams[i].Name);
                        }
                    }

                    for (int i = 0; i < Callee.OutParams.Count; i++)
                    {
                        if (IsUniform(impl.Name, callCmd.Outs[i].Name) &&
                            !IsUniform(callCmd.callee, Callee.OutParams[i].Name))
                        {
                            SetNonUniform(impl.Name, callCmd.Outs[i].Name);
                        }
                    }
                }
                else if (c is AssumeCmd)
                {
                    var ac = (AssumeCmd)c;
                    if (ControlFlowIsUniform && QKeyValue.FindBoolAttribute(ac.Attributes, "partition") &&
                        !IsUniform(impl.Name, ac.Expr))
                    {
                        ControlFlowIsUniform = false;
                    }
                }
            }

            return(ControlFlowIsUniform);
        }
        public static void Predicate(Program p,
                                     Func <Procedure, bool> useProcedurePredicates = null,
                                     UniformityAnalyser uni = null)
        {
            useProcedurePredicates = useProcedurePredicates ?? (proc => false);
            if (uni != null)
            {
                var oldUPP = useProcedurePredicates;
                useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name);
            }

            foreach (var decl in p.TopLevelDeclarations.ToList())
            {
                if (decl is Procedure || decl is Implementation)
                {
                    var            proc = decl as Procedure;
                    Implementation impl = null;
                    if (proc == null)
                    {
                        impl = (Implementation)decl;
                        proc = impl.Proc;
                    }

                    bool upp = useProcedurePredicates(proc);
                    if (upp)
                    {
                        var dwf   = (DeclWithFormals)decl;
                        var fpVar = new Formal(Token.NoToken,
                                               new TypedIdent(Token.NoToken, "_P",
                                                              Microsoft.Boogie.Type.Bool),
                                               /*incoming=*/ true);
                        dwf.InParams = new List <Variable>(
                            (new Variable[] { fpVar }.Concat(dwf.InParams.Cast <Variable>()))
                            .ToArray());

                        if (impl == null)
                        {
                            var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar);
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(fpIdentifierExpr, Expr.True).VisitExpr(r.Condition);
                                if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate"))
                                {
                                    r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition);
                                }
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar), Expr.True).VisitExpr(e.Condition);
                                if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate"))
                                {
                                    e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (impl == null)
                        {
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(r.Condition);
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(e.Condition);
                            }
                        }
                    }

                    if (impl != null)
                    {
                        try {
                            new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
                        } catch (Program.IrreducibleLoopException) { }
                    }
                }
            }
        }
Esempio n. 4
0
 public static bool HasAttribute(this ICarriesAttributes obj, string attribute)
 {
     return(QKeyValue.FindBoolAttribute(obj.Attributes, attribute));
 }
Esempio n. 5
0
            private void IntroduceIntermediateVars()
            {
                var oldSub = SubstitutionHelper.FromVariableMap(LatestCopies(trc.PreStateVars));

                assignments = new List <Assignment>();
                assumes     = new List <Expr>();
                for (int k = 0; k < trc.path.Count; k++)
                {
                    if (trc.IsJoint && k == trc.transferIndex)
                    {
                        PopulateIntermediateFrameCopy();
                        oldSub = SubstitutionHelper.FromVariableMap(LatestCopies(trc.PreStateVars));
                    }

                    Cmd cmd = trc.path[k];
                    if (cmd is AssignCmd assignCmd)
                    {
                        assignCmd = assignCmd.AsSimpleAssignCmd;
                        var preState = LatestCopies();
                        foreach (var v in assignCmd.Lhss)
                        {
                            MakeNewCopy(v.DeepAssignedVariable);
                        }

                        var postState = LatestCopies();

                        if (QKeyValue.FindBoolAttribute(assignCmd.Attributes, CivlAttributes.BACKWARD))
                        {
                            var tmp = preState;
                            preState  = postState;
                            postState = tmp;
                        }

                        var rhsSub = SubstitutionHelper.FromVariableMap(preState);

                        for (int i = 0; i < assignCmd.Lhss.Count; i++)
                        {
                            var var  = postState[assignCmd.Lhss[i].DeepAssignedVariable];
                            var expr = Substituter.ApplyReplacingOldExprs(rhsSub, oldSub, assignCmd.Rhss[i]);
                            assignments.Add(new Assignment(var, expr));
                        }
                    }
                    else if (cmd is AssumeCmd assumeCmd)
                    {
                        var sub = SubstitutionHelper.FromVariableMap(LatestCopies());
                        assumes.Add(Substituter.ApplyReplacingOldExprs(sub, oldSub, assumeCmd.Expr));
                    }
                    else if (cmd is HavocCmd havocCmd)
                    {
                        foreach (var v in havocCmd.Vars)
                        {
                            MakeNewCopy(v.Decl);
                        }
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }

                // In case there were no commands from the second action
                if (trc.IsJoint && trc.path.Count == trc.transferIndex)
                {
                    PopulateIntermediateFrameCopy();
                }
            }
Esempio n. 6
0
        public void TypeCheck()
        {
            foreach (var proc in program.Procedures)
            {
                if (!QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    continue;
                }

                int        createdAtLayerNum; // must be initialized by the following code, otherwise it is an error
                int        availableUptoLayerNum = int.MaxValue;
                List <int> attrs = FindLayers(proc.Attributes);
                if (attrs.Count == 1)
                {
                    createdAtLayerNum = attrs[0];
                }
                else if (attrs.Count == 2)
                {
                    createdAtLayerNum     = attrs[0];
                    availableUptoLayerNum = attrs[1];
                }
                else
                {
                    Error(proc, "Incorrect number of layers");
                    continue;
                }
                foreach (Ensures e in proc.Ensures)
                {
                    MoverType moverType = GetMoverType(e);
                    if (moverType == MoverType.Top)
                    {
                        continue;
                    }
                    CodeExpr codeExpr = e.Condition as CodeExpr;
                    if (codeExpr == null)
                    {
                        Error(e, "An atomic action must be a CodeExpr");
                        continue;
                    }
                    if (procToActionInfo.ContainsKey(proc))
                    {
                        Error(proc, "A procedure can have at most one atomic action");
                        continue;
                    }
                    if (availableUptoLayerNum <= createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be less than the available upto layer number");
                        continue;
                    }

                    minLayerNum         = int.MaxValue;
                    maxLayerNum         = -1;
                    canAccessSharedVars = true;
                    enclosingProc       = proc;
                    enclosingImpl       = null;
                    base.VisitEnsures(e);
                    canAccessSharedVars = false;
                    if (maxLayerNum > createdAtLayerNum)
                    {
                        Error(e, "A variable being accessed is introduced after this action is created");
                    }
                    else if (availableUptoLayerNum > minLayerNum)
                    {
                        Error(e, "A variable being accessed is hidden before this action becomes unavailable");
                    }
                    else
                    {
                        procToActionInfo[proc] = new AtomicActionInfo(proc, e, moverType, createdAtLayerNum, availableUptoLayerNum);
                    }
                }
                if (errorCount > 0)
                {
                    continue;
                }
                if (!procToActionInfo.ContainsKey(proc))
                {
                    if (availableUptoLayerNum < createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be no more than the available upto layer number");
                        continue;
                    }
                    else
                    {
                        procToActionInfo[proc] = new ActionInfo(proc, createdAtLayerNum, availableUptoLayerNum);
                    }
                }
            }
            if (errorCount > 0)
            {
                return;
            }
            foreach (var impl in program.Implementations)
            {
                if (!procToActionInfo.ContainsKey(impl.Proc))
                {
                    continue;
                }
                procToActionInfo[impl.Proc].hasImplementation = true;
            }
            foreach (var proc in procToActionInfo.Keys)
            {
                ActionInfo actionInfo = procToActionInfo[proc];
                if (actionInfo.isExtern && actionInfo.hasImplementation)
                {
                    Error(proc, "Extern procedure cannot have an implementation");
                    continue;
                }
                if (actionInfo.isExtern || actionInfo.hasImplementation)
                {
                    continue;
                }
                if (leastUnimplementedLayerNum == int.MaxValue)
                {
                    leastUnimplementedLayerNum = actionInfo.createdAtLayerNum;
                }
                else if (leastUnimplementedLayerNum != actionInfo.createdAtLayerNum)
                {
                    Error(proc, "All unimplemented atomic actions must be created at the same layer");
                }
            }
            foreach (var g in this.globalVarToSharedVarInfo.Keys)
            {
                var info = globalVarToSharedVarInfo[g];
                if (!this.AllCreatedLayerNums.Contains(info.introLayerNum))
                {
                    Error(g, "Variable must be introduced with creation of some atomic action");
                }
                if (info.hideLayerNum != int.MaxValue && !this.AllCreatedLayerNums.Contains(info.hideLayerNum))
                {
                    Error(g, "Variable must be hidden with creation of some atomic action");
                }
            }
            if (errorCount > 0)
            {
                return;
            }
            this.VisitProgram(program);
            foreach (Procedure proc in program.Procedures)
            {
                if (procToActionInfo.ContainsKey(proc))
                {
                    continue;
                }
                foreach (var ie in proc.Modifies)
                {
                    if (!SharedVariables.Contains(ie.Decl))
                    {
                        continue;
                    }
                    Error(proc, "A ghost procedure must not modify a global variable with layer annotation");
                }
            }
            if (errorCount > 0)
            {
                return;
            }
            YieldTypeChecker.PerformYieldSafeCheck(this);
            new LayerEraser().VisitProgram(program);
        }
Esempio n. 7
0
            private void IntroduceIntermediateVars()
            {
                var oldSub = Substituter.SubstitutionFromHashtable(GetPreStateVars().
                                                                   ToDictionary <Variable, Variable, Expr>(v => v, v => Expr.Ident(varCopies[0][v])));

                newCmds = new List <Cmd>();
                for (int k = 0; k < cmds.Count; k++)
                {
                    if (IsJoint() && k == transitionRelationComputer.transferIndex)
                    {
                        PopulateIntermediateFrameCopy();
                        oldSub = Substituter.SubstitutionFromHashtable(GetPreStateVars().
                                                                       ToDictionary <Variable, Variable, Expr>(v => v, v => Expr.Ident(varCopies[varLastCopyId[v]][v])));
                    }
                    Cmd cmd = cmds[k];
                    if (cmd is AssignCmd)
                    {
                        AssignCmd assignCmd = ((AssignCmd)cmd).AsSimpleAssignCmd;
                        var       preState  = GetVarCopiesFromIds(varLastCopyId);
                        foreach (var v in assignCmd.Lhss)
                        {
                            MakeNewCopy(v.DeepAssignedVariable);
                        }
                        var postState = GetVarCopiesFromIds(varLastCopyId);

                        Dictionary <Variable, Variable> lhsMap = postState, rhsMap = preState;
                        if (QKeyValue.FindBoolAttribute(assignCmd.Attributes, CivlAttributes.BACKWARD))
                        {
                            lhsMap = preState;
                            rhsMap = postState;
                        }

                        var rhsSub = Substituter.SubstitutionFromHashtable(
                            rhsMap.ToDictionary(
                                kvp => kvp.Key, kvp => Expr.Ident(kvp.Value) as Expr
                                ));

                        List <AssignLhs> lhss = assignCmd.Lhss.Select(x => (AssignLhs) new SimpleAssignLhs(Token.NoToken,
                                                                                                           new IdentifierExpr(Token.NoToken, lhsMap[x.DeepAssignedVariable]))).ToList();
                        List <Expr> rhss = assignCmd.Rhss.Select(x =>
                                                                 Substituter.ApplyReplacingOldExprs(rhsSub, oldSub, x)).ToList();

                        newCmds.Add(new AssignCmd(Token.NoToken, lhss, rhss, assignCmd.Attributes));
                    }
                    else if (cmd is AssumeCmd)
                    {
                        var sub = Substituter.SubstitutionFromHashtable(
                            GetVarCopiesFromIds(varLastCopyId).ToDictionary(
                                kvp => kvp.Key, kvp => Expr.Ident(kvp.Value) as Expr
                                ));
                        newCmds.Add(new AssumeCmd(cmd.tok,
                                                  Substituter.ApplyReplacingOldExprs(sub, oldSub, ((AssumeCmd)cmd).Expr)));
                    }
                    else if (cmd is HavocCmd havocCmd)
                    {
                        foreach (var v in havocCmd.Vars)
                        {
                            MakeNewCopy(v.Decl);
                        }
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
                // TODO: Add note on this
                if (!IsJoint() || cmds.Count == transitionRelationComputer.transferIndex)
                {
                    PopulateIntermediateFrameCopy();
                }
            }
Esempio n. 8
0
        public void TypeCheck()
        {
            foreach (var proc in program.Procedures)
            {
                if (!QKeyValue.FindBoolAttribute(proc.Attributes, "pure"))
                {
                    continue;
                }
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    Error(proc, "Pure procedure must not yield");
                    continue;
                }
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "layer"))
                {
                    Error(proc, "Pure procedure must not have layers");
                    continue;
                }
                if (proc.Modifies.Count > 0)
                {
                    Error(proc, "Pure procedure must not modify a global variable");
                    continue;
                }
                procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo();
            }
            foreach (var proc in program.Procedures)
            {
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    continue;
                }
                var procLayerNums = FindLayers(proc.Attributes);
                if (procLayerNums.Count == 0)
                {
                    continue;
                }
                foreach (IdentifierExpr ie in proc.Modifies)
                {
                    if (!globalVarToSharedVarInfo.ContainsKey(ie.Decl))
                    {
                        Error(proc, "Atomic procedure cannot modify a global variable without layer numbers");
                        continue;
                    }
                }
                int lower, upper;
                if (procLayerNums.Count == 1)
                {
                    lower = procLayerNums[0];
                    upper = procLayerNums[0];
                }
                else if (procLayerNums.Count == 2)
                {
                    lower = procLayerNums[0];
                    upper = procLayerNums[1];
                    if (lower >= upper)
                    {
                        Error(proc, "Lower layer must be less than upper layer");
                        continue;
                    }
                }
                else
                {
                    Error(proc, "Atomic procedure must specify a layer range");
                    continue;
                }
                LayerRange layerRange = new LayerRange(lower, upper);
                procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo(layerRange);
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (Implementation impl in program.Implementations)
            {
                if (!procToAtomicProcedureInfo.ContainsKey(impl.Proc))
                {
                    continue;
                }
                var atomicProcedureInfo = procToAtomicProcedureInfo[impl.Proc];
                if (atomicProcedureInfo.isPure)
                {
                    this.enclosingImpl = impl;
                    (new PurityChecker(this)).VisitImplementation(impl);
                }
                else
                {
                    this.enclosingImpl      = impl;
                    this.sharedVarsAccessed = new HashSet <Variable>();
                    (new PurityChecker(this)).VisitImplementation(impl);
                    LayerRange upperBound = FindLayerRange();
                    LayerRange lowerBound = atomicProcedureInfo.layerRange;
                    if (!lowerBound.Subset(upperBound))
                    {
                        Error(impl, "Atomic procedure cannot access global variable");
                    }
                    this.sharedVarsAccessed = null;
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (var proc in program.Procedures)
            {
                if (!QKeyValue.FindBoolAttribute(proc.Attributes, "yields"))
                {
                    continue;
                }

                int        createdAtLayerNum; // must be initialized by the following code, otherwise it is an error
                int        availableUptoLayerNum = int.MaxValue;
                List <int> attrs = FindLayers(proc.Attributes);
                if (attrs.Count == 1)
                {
                    createdAtLayerNum = attrs[0];
                }
                else if (attrs.Count == 2)
                {
                    createdAtLayerNum     = attrs[0];
                    availableUptoLayerNum = attrs[1];
                }
                else
                {
                    Error(proc, "Incorrect number of layers");
                    continue;
                }
                foreach (Ensures e in proc.Ensures)
                {
                    MoverType moverType = GetMoverType(e);
                    if (moverType == MoverType.Top)
                    {
                        continue;
                    }
                    CodeExpr codeExpr = e.Condition as CodeExpr;
                    if (codeExpr == null)
                    {
                        Error(e, "An atomic action must be a CodeExpr");
                        continue;
                    }
                    if (procToActionInfo.ContainsKey(proc))
                    {
                        Error(proc, "A procedure can have at most one atomic action");
                        continue;
                    }
                    if (availableUptoLayerNum <= createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be less than the available upto layer number");
                        continue;
                    }

                    sharedVarsAccessed = new HashSet <Variable>();
                    enclosingProc      = proc;
                    enclosingImpl      = null;
                    base.VisitEnsures(e);
                    LayerRange upperBound = FindLayerRange();
                    LayerRange lowerBound = new LayerRange(createdAtLayerNum, availableUptoLayerNum);
                    if (lowerBound.Subset(upperBound))
                    {
                        procToActionInfo[proc] = new AtomicActionInfo(proc, e, moverType, createdAtLayerNum, availableUptoLayerNum);
                    }
                    else
                    {
                        Error(e, "A variable being accessed in this action is unavailable");
                    }
                    sharedVarsAccessed = null;
                }
                if (errorCount > 0)
                {
                    continue;
                }
                if (!procToActionInfo.ContainsKey(proc))
                {
                    if (availableUptoLayerNum < createdAtLayerNum)
                    {
                        Error(proc, "Creation layer number must be no more than the available upto layer number");
                        continue;
                    }
                    else
                    {
                        procToActionInfo[proc] = new ActionInfo(proc, createdAtLayerNum, availableUptoLayerNum);
                    }
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (var impl in program.Implementations)
            {
                if (!procToActionInfo.ContainsKey(impl.Proc))
                {
                    continue;
                }
                ActionInfo actionInfo = procToActionInfo[impl.Proc];
                procToActionInfo[impl.Proc].hasImplementation = true;
                if (actionInfo.isExtern)
                {
                    Error(impl.Proc, "Extern procedure cannot have an implementation");
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            foreach (Procedure proc in procToActionInfo.Keys)
            {
                for (int i = 0; i < proc.InParams.Count; i++)
                {
                    Variable v     = proc.InParams[i];
                    var      layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum);
                    if (layer == int.MinValue)
                    {
                        continue;
                    }
                    localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer);
                }
                for (int i = 0; i < proc.OutParams.Count; i++)
                {
                    Variable v     = proc.OutParams[i];
                    var      layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum);
                    if (layer == int.MinValue)
                    {
                        continue;
                    }
                    localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer);
                }
            }
            foreach (Implementation node in program.Implementations)
            {
                if (!procToActionInfo.ContainsKey(node.Proc))
                {
                    continue;
                }
                foreach (Variable v in node.LocVars)
                {
                    var layer = FindLocalVariableLayer(node, v, procToActionInfo[node.Proc].createdAtLayerNum);
                    if (layer == int.MinValue)
                    {
                        continue;
                    }
                    localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer);
                }
                for (int i = 0; i < node.Proc.InParams.Count; i++)
                {
                    Variable v = node.Proc.InParams[i];
                    if (!localVarToLocalVariableInfo.ContainsKey(v))
                    {
                        continue;
                    }
                    var layer = localVarToLocalVariableInfo[v].layer;
                    localVarToLocalVariableInfo[node.InParams[i]] = new LocalVariableInfo(layer);
                }
                for (int i = 0; i < node.Proc.OutParams.Count; i++)
                {
                    Variable v = node.Proc.OutParams[i];
                    if (!localVarToLocalVariableInfo.ContainsKey(v))
                    {
                        continue;
                    }
                    var layer = localVarToLocalVariableInfo[v].layer;
                    localVarToLocalVariableInfo[node.OutParams[i]] = new LocalVariableInfo(layer);
                }
            }
            if (errorCount > 0)
            {
                return;
            }

            this.VisitProgram(program);
            if (errorCount > 0)
            {
                return;
            }
            YieldTypeChecker.PerformYieldSafeCheck(this);
            new LayerEraser().VisitProgram(program);
        }
Esempio n. 9
0
        public static void Predicate(Program p,
                                     Func <Procedure, bool> useProcedurePredicates = null,
                                     UniformityAnalyser uni = null)
        {
            useProcedurePredicates = useProcedurePredicates ?? (proc => false);
            if (uni != null)
            {
                var oldUPP = useProcedurePredicates;
                useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name);
            }

            foreach (var decl in p.TopLevelDeclarations.ToList())
            {
                if (decl is Procedure || decl is Implementation)
                {
                    var            proc = decl as Procedure;
                    Implementation impl = null;
                    if (proc == null)
                    {
                        impl = (Implementation)decl;
                        proc = impl.Proc;
                    }

                    bool upp = useProcedurePredicates(proc);
                    if (upp)
                    {
                        var dwf = (DeclWithFormals)decl;
                        // Copy InParams, as the list is shared between impl and proc
                        var inParams = new List <Variable>(dwf.InParams);

                        var fpVar = new Formal(Token.NoToken,
                                               new TypedIdent(Token.NoToken, "_P",
                                                              Microsoft.Boogie.Type.Bool),
                                               /*incoming=*/ true);
                        inParams.Insert(0, fpVar);
                        var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar);

                        // Add in-parameters for all out-parameters. These new in-parameters
                        // are used to ensure we preserve the value of the variable assigned
                        // to when the passed predicate value is false.
                        var newEqParamExprs = new List <Expr>();
                        var newAssignCmds   = new List <Cmd>();
                        foreach (Variable outV in dwf.OutParams)
                        {
                            var inV = new Formal(Token.NoToken,
                                                 new TypedIdent(Token.NoToken, "_V" + outV.TypedIdent.Name,
                                                                outV.TypedIdent.Type),
                                                 /*incoming=*/ true);
                            inParams.Add(inV);

                            var inVExpr  = new IdentifierExpr(Token.NoToken, inV);
                            var outVExpr = new IdentifierExpr(Token.NoToken, outV);
                            newEqParamExprs.Add(Expr.Imp(Expr.Not(fpIdentifierExpr), Expr.Eq(inVExpr, outVExpr)));
                            newAssignCmds.Add(new AssignCmd(Token.NoToken,
                                                            new List <AssignLhs> {
                                new SimpleAssignLhs(Token.NoToken, outVExpr)
                            },
                                                            new List <Expr> {
                                new NAryExpr(Token.NoToken,
                                             new IfThenElse(Token.NoToken),
                                             new List <Expr> {
                                    fpIdentifierExpr, outVExpr, inVExpr
                                })
                            }));
                        }
                        dwf.InParams = inParams;

                        if (impl == null)
                        {
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(fpIdentifierExpr, Expr.True).VisitExpr(r.Condition);
                                if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate"))
                                {
                                    r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition);
                                }
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar), Expr.True).VisitExpr(e.Condition);
                                if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate"))
                                {
                                    e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition);
                                }
                            }
                            foreach (Expr e in newEqParamExprs)
                            {
                                proc.Ensures.Add(new Ensures(false, e));
                            }
                        }
                        else
                        {
                            try {
                                new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
                                foreach (AssignCmd c in newAssignCmds)
                                {
                                    impl.Blocks.First().Cmds.Insert(0, c);
                                }
                            } catch (Program.IrreducibleLoopException) { }
                        }
                    }
                    else
                    {
                        if (impl == null)
                        {
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(r.Condition);
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(e.Condition);
                            }
                        }
                        else
                        {
                            try {
                                new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
                            } catch (Program.IrreducibleLoopException) { }
                        }
                    }
                }
            }
        }
Esempio n. 10
0
        void PredicateCmd(List <Cmd> cmdSeq, Cmd cmd)
        {
            if (cmd is AssignCmd)
            {
                var aCmd = (AssignCmd)cmd;
                cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss,
                                         new List <Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) =>
                                                                       new NAryExpr(Token.NoToken,
                                                                                    new IfThenElse(Token.NoToken),
                                                                                    new List <Expr> {
                    p, rhs, lhs.AsExpr
                })))));
            }
            else if (cmd is AssertCmd)
            {
                var aCmd = (AssertCmd)cmd;
                if (cmdSeq.Last() is AssignCmd &&
                    cmdSeq.Cast <Cmd>().SkipEnd(1).All(c => c is AssertCmd))
                {
                    // This may be a loop invariant.  Make sure it continues to appear as
                    // the first statement in the block.
                    var assign = cmdSeq.Last();
                    cmdSeq.RemoveAt(cmdSeq.Count - 1);
                    Expr newExpr = new EnabledReplacementVisitor(pExpr).VisitExpr(aCmd.Expr);
                    aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(pExpr, newExpr);
                    cmdSeq.Add(aCmd);
                    // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(pExpr, aCmd.Expr)));
                    cmdSeq.Add(assign);
                }
                else
                {
                    aCmd.Expr = Expr.Imp(p, aCmd.Expr);
                    cmdSeq.Add(aCmd);
                    // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(p, aCmd.Expr)));
                }
            }
            else if (cmd is AssumeCmd)
            {
                var aCmd = (AssumeCmd)cmd;
                cmdSeq.Add(new AssumeCmd(Token.NoToken, Expr.Imp(p, aCmd.Expr)));
            }
            else if (cmd is HavocCmd)
            {
                var hCmd = (HavocCmd)cmd;
                foreach (IdentifierExpr v in hCmd.Vars)
                {
                    Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type;
                    Contract.Assert(type != null);

                    IdentifierExpr havocTempExpr;
                    if (havocVars.ContainsKey(type))
                    {
                        havocTempExpr = havocVars[type];
                    }
                    else
                    {
                        var havocVar = new LocalVariable(Token.NoToken,
                                                         new TypedIdent(Token.NoToken,
                                                                        "_HAVOC_" + type.ToString(), type));
                        impl.LocVars.Add(havocVar);
                        havocVars[type] = havocTempExpr =
                            new IdentifierExpr(Token.NoToken, havocVar);
                    }
                    cmdSeq.Add(new HavocCmd(Token.NoToken,
                                            new List <IdentifierExpr> {
                        havocTempExpr
                    }));
                    cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v,
                                                new NAryExpr(Token.NoToken,
                                                             new IfThenElse(Token.NoToken),
                                                             new List <Expr> {
                        p, havocTempExpr, v
                    })));
                }
            }
            else if (cmd is CallCmd)
            {
                Debug.Assert(useProcedurePredicates);
                var cCmd = (CallCmd)cmd;
                cCmd.Ins.Insert(0, p);
                cmdSeq.Add(cCmd);
            }
            else if (cmd is CommentCmd)
            {
                // skip
            }
            else if (cmd is StateCmd)
            {
                var sCmd      = (StateCmd)cmd;
                var newCmdSeq = new List <Cmd>();
                foreach (Cmd c in sCmd.Cmds)
                {
                    PredicateCmd(newCmdSeq, c);
                }
                sCmd.Cmds = newCmdSeq;
                cmdSeq.Add(sCmd);
            }
            else
            {
                Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString());
            }
        }