Beispiel #1
0
 private static Cmd ApplyOnRhss(Substitution sub, Cmd cmd)
 {
     if (cmd is AssignCmd assignCmd)
     {
         return(new AssignCmd(cmd.tok,
                              assignCmd.Lhss,
                              assignCmd.Rhss.Select(x => Substituter.Apply(sub, x)).ToList(),
                              assignCmd.Attributes));
     }
     else
     {
         return(Substituter.Apply(sub, cmd));
     }
 }
Beispiel #2
0
        public static Substitution GetSubstitution(AtomicAction from, AtomicAction to)
        {
            Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();

            for (int i = 0; i < from.impl.InParams.Count; i++)
            {
                map[from.impl.InParams[i]] = Expr.Ident(to.impl.InParams[i]);
            }
            for (int i = 0; i < Math.Min(from.impl.OutParams.Count, to.impl.OutParams.Count); i++)
            {
                map[from.impl.OutParams[i]] = Expr.Ident(to.impl.OutParams[i]);
            }
            return(Substituter.SubstitutionFromDictionary(map));
        }
Beispiel #3
0
 public Cmd CopyCmd(Cmd cmd)
 {
   if (substMap == null)
   {
     return cmd;
   }
   var newCmd = BoundVarAndReplacingOldSubstituter.Apply(substMap, oldSubstMap, prefix, cmd);
   if (cmd is ICarriesAttributes attrCmd && attrCmd.Attributes != null)
   {
     var attrCopy = (QKeyValue) attrCmd.Attributes.Clone();
     ((ICarriesAttributes) newCmd).Attributes = Substituter.ApplyReplacingOldExprs(PartialSubst, PartialOldSubst, attrCopy);
   }
   return newCmd;
 }
Beispiel #4
0
        public Tuple <Procedure, Implementation> GenerateStepChecker(AtomicAction pendingAsync, Function pendingAsyncAdd)
        {
            this.checkName = "step";
            var requires = invariantAction.gate.Select(g => new Requires(false, g.Expr)).ToList();
            var locals   = new List <Variable>();

            if (!HasChoice)
            {
                locals.Add(choice.Decl);
            }

            List <Cmd> cmds = new List <Cmd>();

            cmds.Add(GetCallCmd(invariantAction));
            cmds.Add(CmdHelper.AssumeCmd(ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.membership, choice)));
            cmds.Add(CmdHelper.AssumeCmd(Expr.Gt(Expr.Select(PAs, choice), Expr.Literal(0))));
            cmds.Add(RemoveChoice);

            AtomicAction abs = elim[pendingAsync];
            Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();
            List <Expr> inputExprs          = new List <Expr>();

            for (int i = 0; i < abs.impl.InParams.Count; i++)
            {
                var pendingAsyncParam = ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.selectors[i], choice);
                map[abs.impl.InParams[i]] = pendingAsyncParam;
                inputExprs.Add(pendingAsyncParam);
            }
            var subst = Substituter.SubstitutionFromHashtable(map);

            cmds.AddRange(GetGateAsserts(abs, subst));

            List <IdentifierExpr> outputVars = new List <IdentifierExpr>();

            if (abs.HasPendingAsyncs)
            {
                locals.Add(newPAs.Decl);
                outputVars.Add(newPAs);
            }
            cmds.Add(CmdHelper.CallCmd(abs.proc, inputExprs, outputVars));
            if (abs.HasPendingAsyncs)
            {
                cmds.Add(AddNewPAs(pendingAsyncAdd));
            }

            cmds.Add(GetCheck(GetTransitionRelation(invariantAction)));

            return(GetCheckerTuple(requires, locals, cmds, "_" + abs.proc.Name));
        }
Beispiel #5
0
            public override BinderExpr VisitBinderExpr(BinderExpr node)
            {
                var subst    = new Dictionary <Variable, Expr>();
                var newBound = new List <Variable>();

                foreach (var bv in node.Dummies)
                {
                    var bvNew = boundVars[boundVarCount++, bv.TypedIdent.Type];
                    newBound.Add(bvNew);
                    subst[bv] = new IdentifierExpr(Token.NoToken, bvNew);
                }
                node.Dummies = this.VisitVariableSeq(newBound);
                node.Body    = this.VisitExpr(Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), node.Body));
                return(node);
            }
Beispiel #6
0
            private void AddBoundVariablesForRemainingVars()
            {
                var remainingVars = NotEliminatedVars.Except(IntermediateFrameWithWitnesses);

                existsVarMap = new Dictionary <Variable, BoundVariable>();
                foreach (var v in remainingVars)
                {
                    existsVarMap[v] = new BoundVariable(Token.NoToken,
                                                        new TypedIdent(Token.NoToken, v.Name, v.TypedIdent.Type));
                }
                var varMap   = existsVarMap.ToDictionary(kvp => kvp.Key, kvp => Expr.Ident(kvp.Value) as Expr);
                var varSubst = Substituter.SubstitutionFromHashtable(varMap);

                pathExprs = pathExprs.Select(x => Substituter.Apply(varSubst, x)).ToList();
            }
Beispiel #7
0
 public Expr CopyExpr(Expr expr)
 {
   Contract.Requires(expr != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   if (Subst == null)
   {
     return expr;
   }
   else if (OldSubst == null)
   {
     return Substituter.Apply(Subst, expr);
   }
   else
   {
     return Substituter.ApplyReplacingOldExprs(Subst, OldSubst, expr);
   }
 }
Beispiel #8
0
 public Cmd CopyCmd(Cmd cmd)
 {
   Contract.Requires(cmd != null);
   Contract.Ensures(Contract.Result<Cmd>() != null);
   if (Subst == null)
   {
     return cmd;
   }
   else if (OldSubst == null)
   {
     return Substituter.Apply(Subst, cmd);
   }
   else
   {
     return Substituter.ApplyReplacingOldExprs(Subst, OldSubst, cmd);
   }
 }
Beispiel #9
0
 public static IEnumerable <AssertCmd> GetGateAsserts(AtomicAction action, Substitution subst, string msg)
 {
     foreach (var gate in action.gate)
     {
         AssertCmd cmd;
         if (subst != null)
         {
             cmd = (AssertCmd)Substituter.Apply(subst, gate);
         }
         else
         {
             cmd = new AssertCmd(gate.tok, gate.Expr);
         }
         cmd.ErrorData = msg;
         yield return(cmd);
     }
 }
Beispiel #10
0
            private bool TryElimination(IEnumerable <Variable> extraDefinedVariables)
            {
                bool changed       = false;
                var  remainingCmds = new List <Cmd>();

                foreach (var cmd in newCmds)
                {
                    if (cmd is AssignCmd assignCmd)
                    {
                        var lhss = new List <AssignLhs>();
                        var rhss = new List <Expr>();
                        for (int k = 0; k < assignCmd.Lhss.Count; k++)
                        {
                            var      lhs         = assignCmd.Lhss[k];
                            var      rhs         = assignCmd.Rhss[k];
                            Variable assignedVar = lhs.DeepAssignedVariable;

                            var allDefinedVars = varToExpr.Keys.Union(extraDefinedVariables);
                            if (!allDefinedVars.Contains(assignedVar) &&
                                !VariableCollector.Collect(rhs).Intersect(AllIntroducedVariables).
                                Except(allDefinedVars).Any())
                            {
                                varToExpr[assignedVar] = rhs;
                                changed = true;
                            }
                            else
                            {
                                lhss.Add(lhs);
                                rhss.Add(rhs);
                            }
                        }
                        if (lhss.Any())
                        {
                            remainingCmds.Add(new AssignCmd(cmd.tok, lhss, rhss, assignCmd.Attributes));
                        }
                    }
                    else if (cmd is AssumeCmd)
                    {
                        remainingCmds.Add(cmd);
                    }
                }
                Substitution sub = Substituter.SubstitutionFromHashtable(varToExpr);

                newCmds = remainingCmds.Select(cmd => ApplyOnRhss(sub, cmd)).ToList();
                return(changed);
            }
        private void PendingPropagate(HashSet <Variable> allExistsVars, Dictionary <Variable, Expr> existsSubstitutionMap, Variable eVar, Expr eVarSubstExpr, Dictionary <Variable, Expr> pendingMap)
        {
            var usedExistsVars = VariableCollector.Collect(eVarSubstExpr).Intersect(allExistsVars);

            if (usedExistsVars.Count() == 0)
            {
                existsSubstitutionMap[eVar] = eVarSubstExpr;
            }
            else if (usedExistsVars.Except(existsSubstitutionMap.Keys).Count() == 0)
            {
                Substitution subst = Substituter.SubstitutionFromHashtable(existsSubstitutionMap);
                existsSubstitutionMap[eVar] = Substituter.Apply(subst, eVarSubstExpr);
            }
            else
            {
                pendingMap[eVar] = eVarSubstExpr;
            }
        }
Beispiel #12
0
        private void Substitute(Dictionary <Variable, Expr> map, ref List <Expr> pathExprs, ref Dictionary <Variable, Expr> varToExpr)
        {
            Substitution subst        = Substituter.SubstitutionFromHashtable(map);
            List <Expr>  oldPathExprs = pathExprs;

            pathExprs = new List <Expr>();
            foreach (Expr pathExpr in oldPathExprs)
            {
                pathExprs.Add(Substituter.Apply(subst, pathExpr));
            }
            Dictionary <Variable, Expr> oldVarToExpr = varToExpr;

            varToExpr = new Dictionary <Variable, Expr>();
            foreach (Variable v in oldVarToExpr.Keys)
            {
                varToExpr[v] = Substituter.Apply(subst, oldVarToExpr[v]);
            }
        }
Beispiel #13
0
            private void CalculatePathExpression()
            {
                pathExprs = new List <Expr>();
                foreach (var cmd in newCmds.Where(x => x is AssumeCmd).Cast <AssumeCmd>())
                {
                    FlattenAnd(cmd.Expr, pathExprs);
                }
                foreach (AssignCmd cmd in newCmds.Where(x => x is AssignCmd).Cast <AssignCmd>())
                {
                    for (int k = 0; k < cmd.Lhss.Count; k++)
                    {
                        pathExprs.Add(Expr.Eq(Expr.Ident(cmd.Lhss[k].DeepAssignedVariable), cmd.Rhss[k]));
                    }
                }

                var varMap   = varToExpr.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                var varSubst = Substituter.SubstitutionFromHashtable(varMap);

                pathExprs = pathExprs.Select(x => Substituter.Apply(varSubst, x)).ToList();
            }
Beispiel #14
0
        private Dictionary <Implementation, List <Cmd> > CreatePreconditions(
            LinearPermissionInstrumentation linearPermissionInstrumentation)
        {
            var implToInitCmds = new Dictionary <Implementation, List <Cmd> >();

            foreach (var impl in absyMap.Keys.OfType <Implementation>())
            {
                var initCmds = new List <Cmd>();
                if (civlTypeChecker.GlobalVariables.Count() > 0)
                {
                    initCmds.Add(new HavocCmd(Token.NoToken,
                                              civlTypeChecker.GlobalVariables.Select(v => Expr.Ident(v)).ToList()));
                    linearPermissionInstrumentation.DisjointnessExprs(impl, true).ForEach(
                        expr => initCmds.Add(new AssumeCmd(Token.NoToken, expr)));

                    Substitution procToImplInParams = Substituter.SubstitutionFromHashtable(impl.Proc.InParams
                                                                                            .Zip(impl.InParams).ToDictionary(x => x.Item1, x => (Expr)Expr.Ident(x.Item2)));

                    impl.Proc.Requires.ForEach(req =>
                                               initCmds.Add(new AssumeCmd(req.tok, Substituter.Apply(procToImplInParams, req.Condition))));

                    foreach (var callCmd in GetYieldingProc(impl).yieldRequires)
                    {
                        var yieldInvariant = civlTypeChecker.procToYieldInvariant[callCmd.Proc];
                        if (layerNum == yieldInvariant.LayerNum)
                        {
                            Substitution callFormalsToActuals = Substituter.SubstitutionFromHashtable(callCmd.Proc.InParams
                                                                                                      .Zip(callCmd.Ins)
                                                                                                      .ToDictionary(x => x.Item1, x => (Expr) new OldExpr(Token.NoToken, x.Item2)));
                            callCmd.Proc.Requires.ForEach(req => initCmds.Add(new AssumeCmd(req.tok,
                                                                                            Substituter.Apply(procToImplInParams,
                                                                                                              Substituter.Apply(callFormalsToActuals, req.Condition)))));
                        }
                    }
                }

                implToInitCmds[impl] = initCmds;
            }

            return(implToInitCmds);
        }
Beispiel #15
0
        public Tuple <Procedure, Implementation> GenerateConclusionChecker()
        {
            this.checkName = "conclusion";
            var subst    = GetSubstitution(outputAction, invariantAction);
            var requires = outputAction.gate.Select(g => new Requires(false, Substituter.Apply(subst, g.Expr))).ToList();

            List <Cmd> cmds = GetGateAsserts(invariantAction, null).ToList <Cmd>();

            cmds.Add(GetCallCmd(invariantAction));
            cmds.Add(CmdHelper.AssumeCmd(PendingAsyncsEliminatedExpr));
            cmds.Add(GetCheck(Substituter.Apply(subst, GetTransitionRelation(outputAction))));
            if (!outputAction.HasPendingAsyncs)
            {
                cmds.Add(CmdHelper.AssertCmd(
                             inputAction.proc.tok,
                             NoPendingAsyncs,
                             $"IS leaves pending asyncs not summarized by ${outputAction.proc.Name}"));
            }

            return(GetCheckerTuple(requires, new List <Variable>(), cmds));
        }
Beispiel #16
0
        private void InlineYieldRequiresAndEnsures()
        {
            foreach (var impl in absyMap.Keys.OfType <Implementation>())
            {
                var yieldingProc = GetYieldingProc(impl);
                foreach (var callCmd in yieldingProc.yieldRequires)
                {
                    var yieldInvariant = civlTypeChecker.procToYieldInvariant[callCmd.Proc];
                    if (layerNum == yieldInvariant.LayerNum)
                    {
                        Dictionary <Variable, Expr> map = callCmd.Proc.InParams.Zip(callCmd.Ins)
                                                          .ToDictionary(x => x.Item1, x => x.Item2);
                        Substitution subst = Substituter.SubstitutionFromHashtable(map);
                        foreach (Requires req in callCmd.Proc.Requires)
                        {
                            impl.Proc.Requires.Add(new Requires(req.tok, req.Free, Substituter.Apply(subst, req.Condition),
                                                                null,
                                                                req.Attributes));
                        }
                    }
                }

                foreach (var callCmd in yieldingProc.yieldEnsures)
                {
                    var yieldInvariant = civlTypeChecker.procToYieldInvariant[callCmd.Proc];
                    if (layerNum == yieldInvariant.LayerNum)
                    {
                        Dictionary <Variable, Expr> map = callCmd.Proc.InParams.Zip(callCmd.Ins)
                                                          .ToDictionary(x => x.Item1, x => x.Item2);
                        Substitution subst = Substituter.SubstitutionFromHashtable(map);
                        foreach (Requires req in callCmd.Proc.Requires)
                        {
                            impl.Proc.Ensures.Add(new Ensures(req.tok, req.Free, Substituter.Apply(subst, req.Condition),
                                                              null,
                                                              req.Attributes));
                        }
                    }
                }
            }
        }
Beispiel #17
0
            public Expr TransitionRelationCompute(bool withOriginalInOutVariables = false)
            {
                Expr transitionRelation = Expr.False;

                foreach (PathInfo path in paths)
                {
                    transitionRelation = Expr.Or(transitionRelation, CalculatePathCondition(path));
                }
                ResolutionContext rc = new ResolutionContext(null);

                rc.StateMode = ResolutionContext.State.Two;
                transitionRelation.Resolve(rc);
                transitionRelation.Typecheck(new TypecheckingContext(null));

                if (withOriginalInOutVariables)
                {
                    Dictionary <Variable, Expr> invertedMap = new Dictionary <Variable, Expr>();
                    if (first != null)
                    {
                        foreach (var x in first.thatMap)
                        {
                            invertedMap[((IdentifierExpr)x.Value).Decl] = Expr.Ident(x.Key);
                        }
                    }
                    if (second != null)
                    {
                        foreach (var x in second.thisMap)
                        {
                            invertedMap[((IdentifierExpr)x.Value).Decl] = Expr.Ident(x.Key);
                        }
                    }
                    Substitution subst = Substituter.SubstitutionFromHashtable(invertedMap);
                    return(Substituter.Apply(subst, transitionRelation));
                }
                else
                {
                    return(transitionRelation);
                }
            }
            /// <summary>
            /// Performs lambda lifting (see <see cref="LambdaHelper.ExpandLambdas"/>) by replacing with bound variables
            /// maximally large subexpressions of a lambda that do not contain any of the lambda's bound variables.
            /// </summary>
            /// <param name="lambda">A lambda expression
            ///   <code>(lambda x1: T1 ... x_n: T_n :: t)</code>
            /// where <c>t</c> contains the subexpressions <c>e1</c>, ..., <c>e_m</c>. These are maximally large
            /// subexpressions that do not contain the lambda's bound variables.
            /// </param>
            /// <returns>
            /// <list type="bullet">
            ///   <item>
            ///     A function application <c>f(y1, ..., y_m)</c> where <c>f</c>'s body is defined to be the result of
            ///     replacing the expressions <c>e1</c>, ..., <c>e_m</c> in <c>t</c> with bound variables
            ///     <c>b1</c>, ..., <c>b_m</c>.
            ///   </item>
            ///   <item>
            ///     Adds a definition and axiom for <c>f</c> to <see cref="lambdaFunctions"/> and <see cref="lambdaAxioms"/>.
            ///     Memoizes <c>f</c> as the lifted lambda for <para>lambda</para>.
            ///   </item>
            /// </list>
            /// </returns>
            private Expr LiftLambdaMaxHoles(LambdaExpr lambda)
            {
                // We start by getting rid of `old` expressions. Instead, we replace the free variables `x_i` that are
                // nested inside of `old` expressions with `old(x_i)` expressions.
                var oldFinder = new OldFinder();

                oldFinder.Visit(lambda);
                var oldSubst = new Dictionary <Variable, Expr>();

                foreach (var v in oldFinder.FreeOldVars)
                {
                    if (v is GlobalVariable g)
                    {
                        oldSubst.Add(g, new OldExpr(g.tok, new IdentifierExpr(g.tok, g))
                        {
                            Type = g.TypedIdent.Type
                        });
                    }
                }
                var lambdaBody = Substituter.ApplyReplacingOldExprs(
                    Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>()),
                    Substituter.SubstitutionFromHashtable(oldSubst),
                    lambda.Body);
                var lambdaAttrs = Substituter.ApplyReplacingOldExprs(
                    Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>()),
                    Substituter.SubstitutionFromHashtable(oldSubst),
                    lambda.Attributes);
                var newLambda =
                    new LambdaExpr(lambda.tok, lambda.TypeParameters, lambda.Dummies, lambdaAttrs, lambdaBody)
                {
                    Type = lambda.Type
                };

                // We perform lambda lifting on the resulting lambda which now contains only `old` expressions of the form
                // `old(x)` where `x` is a variable that is free in the lambda.
                return(new MaxHolesLambdaLifter(
                           newLambda, liftedLambdas, FreshLambdaFunctionName(), lambdaFunctions, lambdaAxioms).VisitLambdaExpr(newLambda));
            }
Beispiel #19
0
        private List <Block> SubstituteBlocks(List <Block> blocks, Substitution subst, string blockLabelPrefix)
        {
            Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>();
            List <Block> otherBlocks           = new List <Block>();

            foreach (Block block in blocks)
            {
                List <Cmd> otherCmds = new List <Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(Substituter.Apply(subst, cmd));
                }
                Block otherBlock = new Block();
                otherBlock.Cmds  = otherCmds;
                otherBlock.Label = blockLabelPrefix + block.Label;
                otherBlocks.Add(otherBlock);
                blockMap[block] = otherBlock;
            }
            foreach (Block block in blocks)
            {
                if (block.TransferCmd is ReturnCmd)
                {
                    blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    continue;
                }
                List <Block>  otherGotoCmdLabelTargets = new List <Block>();
                List <string> otherGotoCmdLabelNames   = new List <string>();
                GotoCmd       gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    otherGotoCmdLabelTargets.Add(blockMap[target]);
                    otherGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets);
            }
            return(otherBlocks);
        }
Beispiel #20
0
        public Tuple <Procedure, Implementation> GenerateConclusionChecker()
        {
            this.checkName = "conclusion";
            var subst    = GetSubstitution(outputAction, invariantAction);
            var requires = outputAction.gate.Select(g => new Requires(false, Substituter.Apply(subst, g.Expr))).ToList();
            var ensures  = new List <Ensures> {
                GetEnsures(Substituter.Apply(subst, GetTransitionRelation(outputAction)))
            };

            if (!outputAction.HasPendingAsyncs)
            {
                ensures.Add(new Ensures(false, NoPendingAsyncs));
            }

            List <Cmd> cmds = GetGateAsserts(invariantAction, null).ToList <Cmd>();

            cmds.Add(GetCallCmd(invariantAction));
            cmds.Add(new AssumeCmd(Token.NoToken, PendingAsyncsEliminatedExpr));
            var blocks = new List <Block> {
                new Block(Token.NoToken, checkName, cmds, CmdHelper.ReturnCmd)
            };

            return(GetCheckerTuple(requires, ensures, new List <Variable>(), blocks));
        }
Beispiel #21
0
        public static List <Declaration> CreateNoninterferenceCheckers(
            CivlTypeChecker civlTypeChecker,
            int layerNum,
            AbsyMap absyMap,
            DeclWithFormals decl,
            List <Variable> declLocalVariables)
        {
            var linearTypeChecker = civlTypeChecker.linearTypeChecker;
            Dictionary <string, Variable>   domainNameToHoleVar = new Dictionary <string, Variable>();
            Dictionary <Variable, Variable> localVarMap         = new Dictionary <Variable, Variable>();
            Dictionary <Variable, Expr>     map = new Dictionary <Variable, Expr>();
            List <Variable> locals = new List <Variable>();
            List <Variable> inputs = new List <Variable>();

            foreach (var domainName in linearTypeChecker.linearDomains.Keys)
            {
                var inParam = linearTypeChecker.LinearDomainInFormal(domainName);
                inputs.Add(inParam);
                domainNameToHoleVar[domainName] = inParam;
            }

            foreach (Variable local in declLocalVariables.Union(decl.InParams).Union(decl.OutParams))
            {
                var copy = CopyLocal(local);
                locals.Add(copy);
                localVarMap[local] = copy;
                map[local]         = Expr.Ident(copy);
            }

            Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> assumeMap   = new Dictionary <Variable, Expr>(map);

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                var copy = OldGlobalLocal(civlTypeChecker, g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = SnapshotGlobalFormal(civlTypeChecker, g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            var linearPermissionInstrumentation = new LinearPermissionInstrumentation(civlTypeChecker,
                                                                                      layerNum, absyMap, domainNameToHoleVar, localVarMap);
            List <YieldInfo> yieldInfos = null;
            string           noninterferenceCheckerName = null;

            if (decl is Implementation impl)
            {
                noninterferenceCheckerName = $"impl_{absyMap.Original(impl).Name}_{layerNum}";
                yieldInfos = CollectYields(civlTypeChecker, absyMap, layerNum, impl).Select(kv =>
                                                                                            new YieldInfo(linearPermissionInstrumentation.DisjointnessAssumeCmds(kv.Key, false), kv.Value)).ToList();
            }
            else if (decl is Procedure proc)
            {
                yieldInfos = new List <YieldInfo>();
                if (civlTypeChecker.procToYieldInvariant.ContainsKey(proc))
                {
                    noninterferenceCheckerName = $"yield_{proc.Name}";
                    if (proc.Requires.Count > 0)
                    {
                        var disjointnessCmds = linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var yieldPredicates  = proc.Requires.Select(requires =>
                                                                    requires.Free
                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(disjointnessCmds, yieldPredicates));
                    }
                }
                else
                {
                    noninterferenceCheckerName = $"proc_{absyMap.Original(proc).Name}_{layerNum}";
                    if (proc.Requires.Count > 0)
                    {
                        var entryDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, true);
                        var entryYieldPredicates = proc.Requires.Select(requires =>
                                                                        requires.Free
                ? (PredicateCmd) new AssumeCmd(requires.tok, requires.Condition)
                : (PredicateCmd) new AssertCmd(requires.tok, requires.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(entryDisjointnessCmds, entryYieldPredicates));
                    }

                    if (proc.Ensures.Count > 0)
                    {
                        var exitDisjointnessCmds =
                            linearPermissionInstrumentation.ProcDisjointnessAssumeCmds(proc, false);
                        var exitYieldPredicates = proc.Ensures.Select(ensures =>
                                                                      ensures.Free
                ? (PredicateCmd) new AssumeCmd(ensures.tok, ensures.Condition)
                : (PredicateCmd) new AssertCmd(ensures.tok, ensures.Condition)).ToList();
                        yieldInfos.Add(new YieldInfo(exitDisjointnessCmds, exitYieldPredicates));
                    }
                }
            }
            else
            {
                Debug.Assert(false);
            }

            var filteredYieldInfos = yieldInfos.Where(info =>
                                                      info.invariantCmds.Any(predCmd => new GlobalAccessChecker().AccessesGlobal(predCmd.Expr)));

            if (filteredYieldInfos.Count() == 0)
            {
                return(new List <Declaration>());
            }

            Substitution assumeSubst = Substituter.SubstitutionFromDictionary(assumeMap);
            Substitution oldSubst    = Substituter.SubstitutionFromDictionary(oldLocalMap);
            Substitution subst       = Substituter.SubstitutionFromDictionary(map);
            List <Block> noninterferenceCheckerBlocks = new List <Block>();
            List <Block> labelTargets = new List <Block>();
            Block        noninterferenceCheckerBlock = BlockHelper.Block("exit", new List <Cmd>());

            labelTargets.Add(noninterferenceCheckerBlock);
            noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            int yieldCount = 0;

            foreach (var kv in filteredYieldInfos)
            {
                var newCmds = new List <Cmd>(kv.disjointnessCmds);
                foreach (var predCmd in kv.invariantCmds)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(predCmd.tok, newExpr));
                }

                foreach (var predCmd in kv.invariantCmds)
                {
                    if (predCmd is AssertCmd)
                    {
                        var       newExpr   = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }
                }

                newCmds.Add(CmdHelper.AssumeCmd(Expr.False));
                noninterferenceCheckerBlock = BlockHelper.Block("L" + yieldCount++, newCmds);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

            noninterferenceCheckerBlocks.Insert(0, BlockHelper.Block("enter", new List <Cmd>(), labelTargets));

            // Create the yield checker procedure
            noninterferenceCheckerName = civlTypeChecker.AddNamePrefix($"NoninterferenceChecker_{noninterferenceCheckerName}");
            var noninterferenceCheckerProc = DeclHelper.Procedure(noninterferenceCheckerName,
                                                                  inputs, new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = DeclHelper.Implementation(noninterferenceCheckerProc,
                                                                       inputs, new List <Variable>(), locals, noninterferenceCheckerBlocks);

            CivlUtil.AddInlineAttribute(noninterferenceCheckerImpl);
            return(new List <Declaration> {
                noninterferenceCheckerProc, noninterferenceCheckerImpl
            });
        }
            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();
                }
            }
Beispiel #23
0
        public Implementation Inject(Implementation implementation, Program programInCachedSnapshot)
        {
            Contract.Requires(implementation != null && programInCachedSnapshot != null);

            this.programInCachedSnapshot = programInCachedSnapshot;
            assumptionVariableCount      = 0;
            temporaryVariableCount       = 0;
            currentImplementation        = implementation;

            #region Introduce explict assumption about the precondition.

            var oldProc = programInCachedSnapshot.FindProcedure(currentImplementation.Proc.Name);
            if (oldProc != null &&
                oldProc.DependencyChecksum != currentImplementation.Proc.DependencyChecksum &&
                currentImplementation.ExplicitAssumptionAboutCachedPrecondition == null)
            {
                var  axioms      = new List <Axiom>();
                var  after       = new List <Cmd>();
                Expr assumedExpr = new LiteralExpr(Token.NoToken, false);
                var  canUseSpecs = DependencyCollector.CanExpressOldSpecs(oldProc, Program, true);
                if (canUseSpecs && oldProc.SignatureEquals(currentImplementation.Proc))
                {
                    var always = Substituter.SubstitutionFromHashtable(currentImplementation.GetImplFormalMap(), true,
                                                                       currentImplementation.Proc);
                    var forOld  = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>());
                    var clauses = oldProc.Requires.Select(r =>
                                                          Substituter.FunctionCallReresolvingApply(always, forOld, r.Condition, Program));
                    var conj = Expr.And(clauses, true);
                    assumedExpr = conj != null
            ? FunctionExtractor.Extract(conj, Program, axioms)
            : new LiteralExpr(Token.NoToken, true);
                }

                if (assumedExpr != null)
                {
                    var lv = new LocalVariable(Token.NoToken,
                                               new TypedIdent(Token.NoToken, string.Format("a##cached##{0}", FreshAssumptionVariableName), Type.Bool),
                                               new QKeyValue(Token.NoToken, "assumption", new List <object>(), null));
                    currentImplementation.InjectAssumptionVariable(lv, !canUseSpecs);
                    var lhs     = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, lv));
                    var rhs     = LiteralExpr.And(new IdentifierExpr(Token.NoToken, lv), assumedExpr);
                    var assumed = new AssignCmd(currentImplementation.tok, new List <AssignLhs> {
                        lhs
                    }, new List <Expr> {
                        rhs
                    });
                    assumed.IrrelevantForChecksumComputation = true;
                    currentImplementation.ExplicitAssumptionAboutCachedPrecondition = assumed;
                    after.Add(assumed);
                }

                if (CommandLineOptions.Clo.TraceCachingForTesting || CommandLineOptions.Clo.TraceCachingForBenchmarking)
                {
                    using (var tokTxtWr = new TokenTextWriter("<console>", Console.Out, false, false))
                    {
                        var loc = currentImplementation.tok != null && currentImplementation.tok != Token.NoToken
              ? string.Format("{0}({1},{2})", currentImplementation.tok.filename, currentImplementation.tok.line,
                              currentImplementation.tok.col)
              : "<unknown location>";
                        Console.Out.WriteLine("Processing implementation {0} (at {1}):", currentImplementation.Name, loc);
                        foreach (var a in axioms)
                        {
                            Console.Out.Write("  >>> added axiom: ");
                            a.Expr.Emit(tokTxtWr);
                            Console.Out.WriteLine();
                        }

                        foreach (var b in after)
                        {
                            Console.Out.Write("  >>> added after assuming the current precondition: ");
                            b.Emit(tokTxtWr, 0);
                        }
                    }
                }
            }

            #endregion

            var result = VisitImplementation(currentImplementation);
            currentImplementation        = null;
            this.programInCachedSnapshot = null;
            return(result);
        }
Beispiel #24
0
        public ActionRefinementInstrumentation(
            CivlTypeChecker civlTypeChecker,
            Implementation impl,
            Implementation originalImpl,
            Dictionary <Variable, Variable> oldGlobalMap)
        {
            this.civlTypeChecker = civlTypeChecker;
            this.tok             = impl.tok;
            this.oldGlobalMap    = new Dictionary <Variable, Variable>();
            ActionProc actionProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc] as ActionProc;

            this.layerNum = actionProc.upperLayer;
            foreach (Variable v in civlTypeChecker.GlobalVariables)
            {
                var layerRange = civlTypeChecker.GlobalVariableLayerRange(v);
                if (layerRange.lowerLayerNum <= layerNum && layerNum < layerRange.upperLayerNum)
                {
                    this.oldGlobalMap[v] = oldGlobalMap[v];
                }
            }

            this.newLocalVars = new List <Variable>();
            pc = civlTypeChecker.LocalVariable("pc", Type.Bool);
            newLocalVars.Add(pc);
            ok = civlTypeChecker.LocalVariable("ok", Type.Bool);
            newLocalVars.Add(ok);

            this.transitionRelationCache = new Dictionary <AtomicAction, Expr>();

            oldOutputMap = new Dictionary <Variable, Variable>();
            foreach (Variable f in impl.OutParams)
            {
                LocalVariable copy = Old(f);
                newLocalVars.Add(copy);
                oldOutputMap[f] = copy;
            }

            Dictionary <Variable, Expr> foroldMap = new Dictionary <Variable, Expr>();

            foreach (Variable g in civlTypeChecker.GlobalVariables)
            {
                foroldMap[g] = Expr.Ident(oldGlobalMap[g]);
            }

            // The parameters of an atomic action come from the implementation that denotes the atomic action specification.
            // To use the transition relation computed below in the context of the yielding procedure of the refinement check,
            // we need to substitute the parameters.
            AtomicAction   atomicAction           = actionProc.refinedAction;
            Implementation atomicActionImpl       = atomicAction.impl;
            Dictionary <Variable, Expr> alwaysMap = new Dictionary <Variable, Expr>();

            for (int i = 0, j = 0; i < impl.InParams.Count; i++)
            {
                if (civlTypeChecker.FormalRemainsInAction(actionProc, actionProc.proc.InParams[i]))
                {
                    alwaysMap[atomicActionImpl.InParams[j]] = Expr.Ident(impl.InParams[i]);
                    j++;
                }
            }

            for (int i = 0, j = 0; i < impl.OutParams.Count; i++)
            {
                if (civlTypeChecker.FormalRemainsInAction(actionProc, actionProc.proc.OutParams[i]))
                {
                    alwaysMap[atomicActionImpl.OutParams[j]] = Expr.Ident(impl.OutParams[i]);
                    j++;
                }
            }

            if (atomicAction.HasPendingAsyncs)
            {
                Variable collectedPAs = civlTypeChecker.implToPendingAsyncCollector[originalImpl];
                alwaysMap[atomicActionImpl.OutParams.Last()] = Expr.Ident(collectedPAs);
                LocalVariable copy = Old(collectedPAs);
                newLocalVars.Add(copy);
                oldOutputMap[collectedPAs] = copy;
            }

            Substitution always = Substituter.SubstitutionFromHashtable(alwaysMap);
            Substitution forold = Substituter.SubstitutionFromHashtable(foroldMap);
            Expr         transitionRelationExpr = GetTransitionRelation(atomicAction);

            transitionRelation = Substituter.ApplyReplacingOldExprs(always, forold, transitionRelationExpr);
            Expr gateExpr = Expr.And(atomicAction.gate.Select(g => g.Expr));

            gateExpr.Type = Type.Bool;
            gate          = Substituter.Apply(always, gateExpr);
        }
Beispiel #25
0
        public ActionInfo(Procedure proc, CodeExpr codeExpr, MoverType moverType, int phaseNum)
        {
            this.proc            = proc;
            this.moverType       = moverType;
            this.phaseNum        = phaseNum;
            this.callerPhaseNums = new HashSet <int>();
            this.thisGate        = new List <AssertCmd>();
            this.thisAction      = codeExpr;
            this.thisInParams    = new List <Variable>();
            this.thisOutParams   = new List <Variable>();
            this.thatGate        = new List <AssertCmd>();
            this.thatInParams    = new List <Variable>();
            this.thatOutParams   = new List <Variable>();

            var cmds = thisAction.Blocks[0].Cmds;

            for (int i = 0; i < cmds.Count; i++)
            {
                AssertCmd assertCmd = cmds[i] as AssertCmd;
                if (assertCmd == null)
                {
                    break;
                }
                thisGate.Add(assertCmd);
                cmds[i] = new AssumeCmd(assertCmd.tok, assertCmd.Expr);
            }

            Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();

            foreach (Variable x in proc.InParams)
            {
                this.thisInParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true);
                this.thatInParams.Add(y);
                map[x] = new IdentifierExpr(Token.NoToken, y);
            }
            foreach (Variable x in proc.OutParams)
            {
                this.thisOutParams.Add(x);
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                this.thatOutParams.Add(y);
                map[x] = new IdentifierExpr(Token.NoToken, y);
            }
            List <Variable> otherLocVars = new List <Variable>();

            foreach (Variable x in thisAction.LocVars)
            {
                Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false);
                map[x] = new IdentifierExpr(Token.NoToken, y);
                otherLocVars.Add(y);
            }
            Contract.Assume(proc.TypeParameters.Count == 0);
            Substitution subst = Substituter.SubstitutionFromHashtable(map);

            foreach (AssertCmd assertCmd in thisGate)
            {
                thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd));
            }
            Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>();
            List <Block> otherBlocks           = new List <Block>();

            foreach (Block block in thisAction.Blocks)
            {
                List <Cmd> otherCmds = new List <Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    otherCmds.Add(Substituter.Apply(subst, cmd));
                }
                Block otherBlock = new Block();
                otherBlock.Cmds  = otherCmds;
                otherBlock.Label = "that_" + block.Label;
                block.Label      = "this_" + block.Label;
                otherBlocks.Add(otherBlock);
                blockMap[block] = otherBlock;
                if (block.TransferCmd is GotoCmd)
                {
                    GotoCmd gotoCmd = block.TransferCmd as GotoCmd;
                    for (int i = 0; i < gotoCmd.labelNames.Count; i++)
                    {
                        gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i];
                    }
                }
            }
            foreach (Block block in thisAction.Blocks)
            {
                if (block.TransferCmd is ReturnExprCmd)
                {
                    block.TransferCmd           = new ReturnCmd(block.TransferCmd.tok);
                    blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok);
                    continue;
                }
                List <Block>  otherGotoCmdLabelTargets = new List <Block>();
                List <string> otherGotoCmdLabelNames   = new List <string>();
                GotoCmd       gotoCmd = block.TransferCmd as GotoCmd;
                foreach (Block target in gotoCmd.labelTargets)
                {
                    otherGotoCmdLabelTargets.Add(blockMap[target]);
                    otherGotoCmdLabelNames.Add(blockMap[target].Label);
                }
                blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets);
            }
            this.thatAction = new CodeExpr(otherLocVars, otherBlocks);
        }
Beispiel #26
0
 public CodeCopier(Dictionary<Variable, Expr> substMap, Dictionary<Variable, Expr> oldSubstMap) {
   Contract.Requires(oldSubstMap != null);
   Contract.Requires(substMap != null);
   Subst = Substituter.SubstitutionFromHashtable(substMap);
   OldSubst = Substituter.SubstitutionFromHashtable(oldSubstMap);
 }
Beispiel #27
0
    // result[0] is the entry block
    protected List<Block/*!*/>/*!*/ CreateInlinedBlocks(CallCmd callCmd, Implementation impl, string nextBlockLabel) {
      Contract.Requires(nextBlockLabel != null);
      Contract.Requires(impl != null);
      Contract.Requires(impl.Proc != null);
      Contract.Requires(callCmd != null);
      Contract.Requires(codeCopier.Subst != null);

      Contract.Requires(codeCopier.OldSubst != null);
      Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>()));
      List<Block/*!*/>/*!*/ implBlocks = cce.NonNull(impl.OriginalBlocks);
      Contract.Assert(implBlocks.Count > 0);

      Procedure proc = impl.Proc;
      string startLabel = implBlocks[0].Label;

      List<Block/*!*/>/*!*/ inlinedBlocks = new List<Block/*!*/>();

      // create in block
      List<Cmd> inCmds = new List<Cmd>();

      // assign in parameters
      for (int i = 0; i < impl.InParams.Count; ++i) {
        Cmd cmd = Cmd.SimpleAssign(impl.tok,
                                   (IdentifierExpr)cce.NonNull(codeCopier.Subst)(cce.NonNull(impl.InParams[i])),
                                   cce.NonNull(callCmd.Ins[i]));
        inCmds.Add(cmd);
      }

      // inject requires
      for (int i = 0; i < proc.Requires.Count; i++) {
        Requires/*!*/ req = cce.NonNull(proc.Requires[i]);
        inCmds.Add(InlinedRequires(callCmd, req));
      }

      List<Variable> locVars = cce.NonNull(impl.OriginalLocVars);

      // havoc locals and out parameters in case procedure is invoked in a loop
      List<IdentifierExpr> havocVars = new List<IdentifierExpr>();
      foreach (Variable v in locVars)
      {
          havocVars.Add((IdentifierExpr)codeCopier.Subst(v));
      }
      foreach (Variable v in impl.OutParams)
      {
          havocVars.Add((IdentifierExpr)codeCopier.Subst(v));
      }
      if (havocVars.Count > 0)
      {
          inCmds.Add(new HavocCmd(Token.NoToken, havocVars));
      }

      // add where clauses of local vars as assume
      for (int i = 0; i < locVars.Count; ++i) {
        Expr whereExpr = (cce.NonNull(locVars[i])).TypedIdent.WhereExpr;
        if (whereExpr != null) {
          whereExpr = Substituter.Apply(codeCopier.Subst, whereExpr);
          // FIXME we cannot overwrite it, can we?!
          (cce.NonNull(locVars[i])).TypedIdent.WhereExpr = whereExpr;
          AssumeCmd/*!*/ a = new AssumeCmd(Token.NoToken, whereExpr);
          Contract.Assert(a != null);
          inCmds.Add(a);
        }
      }

      // add where clauses of output params as assume
      for (int i = 0; i < impl.OutParams.Count; ++i) {
        Expr whereExpr = (cce.NonNull(impl.OutParams[i])).TypedIdent.WhereExpr;
        if (whereExpr != null) {
          whereExpr = Substituter.Apply(codeCopier.Subst, whereExpr);
          // FIXME likewise
          (cce.NonNull(impl.OutParams[i])).TypedIdent.WhereExpr = whereExpr;
          AssumeCmd/*!*/ a = new AssumeCmd(Token.NoToken, whereExpr);
          Contract.Assert(a != null);
          inCmds.Add(a);
        }
      }

      // assign modifies old values
      foreach (IdentifierExpr/*!*/ mie in proc.Modifies) {
        Contract.Assert(mie != null);
        Variable/*!*/ mvar = cce.NonNull(mie.Decl);
        AssignCmd assign = Cmd.SimpleAssign(impl.tok, (IdentifierExpr)cce.NonNull(codeCopier.OldSubst(mvar)), mie);
        inCmds.Add(assign);
      }

      GotoCmd inGotoCmd = new GotoCmd(callCmd.tok, new List<String> { GetInlinedProcLabel(proc.Name) + "$" + startLabel });
      Block inBlock = new Block(impl.tok, GetInlinedProcLabel(proc.Name) + "$Entry", inCmds, inGotoCmd);
      inlinedBlocks.Add(inBlock);

      // inject the blocks of the implementation
      Block intBlock;
      foreach (Block block in implBlocks) {
        List<Cmd> copyCmds = codeCopier.CopyCmdSeq(block.Cmds);
        if (0 <= inlineDepth) {
          copyCmds = RemoveAsserts(copyCmds);
        }
        TransferCmd transferCmd = CreateInlinedTransferCmd(cce.NonNull(block.TransferCmd), GetInlinedProcLabel(proc.Name));
        intBlock = new Block(block.tok, GetInlinedProcLabel(proc.Name) + "$" + block.Label, copyCmds, transferCmd);
        inlinedBlocks.Add(intBlock);
      }

      // create out block
      List<Cmd> outCmds = new List<Cmd>();

      // inject ensures
      for (int i = 0; i < proc.Ensures.Count; i++) {
        Ensures/*!*/ ens = cce.NonNull(proc.Ensures[i]);
        outCmds.Add(InlinedEnsures(callCmd, ens));
      }

      // assign out params
      for (int i = 0; i < impl.OutParams.Count; ++i) {
        Expr/*!*/ cout_exp = (IdentifierExpr)cce.NonNull(codeCopier.Subst(cce.NonNull(impl.OutParams[i])));
        Cmd cmd = Cmd.SimpleAssign(impl.tok, cce.NonNull(callCmd.Outs[i]), cout_exp);
        outCmds.Add(cmd);
      }

      // create out block
      GotoCmd outGotoCmd = new GotoCmd(Token.NoToken, new List<String> { nextBlockLabel });
      Block outBlock = new Block(impl.tok, GetInlinedProcLabel(proc.Name) + "$Return", outCmds, outGotoCmd);
      inlinedBlocks.Add(outBlock);

      return inlinedBlocks;
    }
Beispiel #28
0
    protected void BeginInline(Implementation impl) {
      Contract.Requires(impl != null);
      Contract.Requires(impl.Proc != null);
      Contract.Requires(newModifies != null);
      Contract.Requires(newLocalVars != null);
      
      Dictionary<Variable, Expr> substMap = new Dictionary<Variable, Expr>();
      Procedure proc = impl.Proc;

      foreach (Variable/*!*/ locVar in cce.NonNull(impl.OriginalLocVars)) {
        Contract.Assert(locVar != null);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, locVar.Name), locVar.TypedIdent.Type, locVar.TypedIdent.WhereExpr));
        localVar.Attributes = locVar.Attributes; // copy attributes
        newLocalVars.Add(localVar);
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMap.Add(locVar, ie);
      }

      for (int i = 0; i < impl.InParams.Count; i++) {
        Variable inVar = cce.NonNull(impl.InParams[i]);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, inVar.Name), inVar.TypedIdent.Type, inVar.TypedIdent.WhereExpr));
        newLocalVars.Add(localVar);
        if (impl.Proc != null) localVar.Attributes = impl.Proc.InParams[i].Attributes; // copy attributes
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMap.Add(inVar, ie);
        // also add a substitution from the corresponding formal occurring in the PROCEDURE declaration
        Variable procInVar = cce.NonNull(proc.InParams[i]);
        if (procInVar != inVar) {
          substMap.Add(procInVar, ie);
        }
      }

      for (int i = 0; i < impl.OutParams.Count; i++) {
        Variable outVar = cce.NonNull(impl.OutParams[i]);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, outVar.Name), outVar.TypedIdent.Type, outVar.TypedIdent.WhereExpr));
        if (impl.Proc != null) localVar.Attributes = impl.Proc.OutParams[i].Attributes; // copy attributes
        newLocalVars.Add(localVar);
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMap.Add(outVar, ie);
        // also add a substitution from the corresponding formal occurring in the PROCEDURE declaration
        Variable procOutVar = cce.NonNull(proc.OutParams[i]);
        if (procOutVar != outVar) {
          substMap.Add(procOutVar, ie);
        }
      }

      Dictionary<Variable, Expr> substMapOld = new Dictionary<Variable, Expr>();

      foreach (IdentifierExpr/*!*/ mie in proc.Modifies) {
        Contract.Assert(mie != null);
        Variable/*!*/ mVar = cce.NonNull(mie.Decl);
        LocalVariable localVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, GetProcVarName(proc.Name, mVar.Name), mVar.TypedIdent.Type));
        newLocalVars.Add(localVar);
        IdentifierExpr ie = new IdentifierExpr(Token.NoToken, localVar);
        substMapOld.Add(mVar, ie);
        // FIXME why are we doing this? the modifies list should already include them.
        // add the modified variable to the modifies list of the procedure
        if (!newModifies.Contains(mie)) {
          newModifies.Add(mie);
        }
      }

      codeCopier.Subst = Substituter.SubstitutionFromHashtable(substMap);
      codeCopier.OldSubst = Substituter.SubstitutionFromHashtable(substMapOld);
    }
Beispiel #29
0
      /// <summary>
      /// Performs lambda lifting (see <see cref="LambdaHelper.ExpandLambdas"/>) by replacing the lambda's
      /// free variables with bound ones.
      /// </summary>
      /// <param name="lambda">A lambda expression
      ///   <code>(lambda x1: T1 ... x_n: T_n :: t)</code>
      /// where <c>t</c> contains the free variables <c>y1</c>, ..., <c>y_m</c>.
      /// </param>
      /// <returns>
      /// <list type="bullet">
      ///   <item>
      ///     A function application <c>f(y1, ..., y_m)</c> where <c>f</c>'s body is defined to be the result of
      ///     replacing the free variables <c>y1</c>, ..., <c>y_m</c> in <c>t</c> with bound variables
      ///     <c>b1</c>, ..., <c>b_m</c>.
      ///   </item>
      ///   <item>
      ///     Adds a definition and axiom for <c>f</c> to <see cref="lambdaFunctions"/> and <see cref="lambdaAxioms"/>.
      ///     Memoizes <c>f</c> as the lifted lambda for <para>lambda</para>.
      ///   </item>
      /// </list>
      /// </returns>
      private Expr LiftLambdaFreeVars(LambdaExpr lambda)
      {
        // We start by getting rid of any use of "old" inside the lambda.  This is done as follows.
        // For each variable "g" occurring inside lambda as "old(... g ...)", create a new name "og".
        // Replace each old occurrence of "g" with "og", removing the enclosing "old" wrappers.
        var oldFinder = new OldFinder();
        oldFinder.Visit(lambda);
        var oldSubst = new Dictionary<Variable, Expr>(); // g -> g0
        var callOldMapping = new Dictionary<Variable, Expr>(); // g0 -> old(g)
        foreach (var v in oldFinder.FreeOldVars)
        {
          var g = v as GlobalVariable;
          if (g != null)
          {
            var g0 = new GlobalVariable(g.tok, new TypedIdent(g.tok, g.TypedIdent.Name + "@old", g.TypedIdent.Type));
            oldSubst.Add(g, new IdentifierExpr(g0.tok, g0));
            callOldMapping.Add(g0, new OldExpr(g0.tok, new IdentifierExpr(g.tok, g)));
          }
        }

        var lambdaBody = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()),
          Substituter.SubstitutionFromDictionary(oldSubst),
          lambda.Body);
        var lambdaAttrs = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()),
          Substituter.SubstitutionFromDictionary(oldSubst),
          lambda.Attributes);

        if (0 < CommandLineOptions.Clo.VerifySnapshots &&
            QKeyValue.FindStringAttribute(lambdaAttrs, "checksum") == null)
        {
          // Attach a dummy checksum to avoid issues in the dependency analysis.
          var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> {"lambda expression"}, null);
          if (lambdaAttrs == null)
          {
            lambdaAttrs = checksumAttr;
          }
          else
          {
            lambdaAttrs.AddLast(checksumAttr);
          }
        }

        // this is ugly, the output will depend on hashing order
        var subst = new Dictionary<Variable, Expr>();
        var substFnAttrs = new Dictionary<Variable, Expr>();
        var formals = new List<Variable>();
        var callArgs = new List<Expr>();
        var axCallArgs = new List<Expr>();
        var dummies = new List<Variable>(lambda.Dummies);
        var freeTypeVars = new List<TypeVariable>();
        var fnTypeVarActuals = new List<Type /*!*/>();
        var freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition

        // compute the free variables of the lambda expression, but with lambdaBody instead of lambda.Body
        Set freeVars = new Set();
        BinderExpr.ComputeBinderFreeVariables(lambda.TypeParameters, lambda.Dummies, lambdaBody, null, lambdaAttrs,
          freeVars);

        foreach (object o in freeVars)
        {
          // 'o' is either a Variable or a TypeVariable.
          if (o is Variable)
          {
            var v = o as Variable;
            var ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type);
            var f = new Formal(v.tok, ti, true);
            formals.Add(f);
            substFnAttrs.Add(v, new IdentifierExpr(f.tok, f));
            var b = new BoundVariable(v.tok, ti);
            dummies.Add(b);
            if (callOldMapping.ContainsKey(v))
            {
              callArgs.Add(callOldMapping[v]);
            }
            else
            {
              callArgs.Add(new IdentifierExpr(v.tok, v));
            }

            Expr id = new IdentifierExpr(b.tok, b);
            subst.Add(v, id);
            axCallArgs.Add(id);
          }
          else
          {
            var tv = (TypeVariable) o;
            freeTypeVars.Add(tv);
            fnTypeVarActuals.Add(tv);
            freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name));
          }
        }

        var sw = new System.IO.StringWriter();
        var wr = new TokenTextWriter(sw, true);
        lambda.Emit(wr);
        string lam_str = sw.ToString();

        FunctionCall fcall;
        IToken tok = lambda.tok;
        Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false);

        if (liftedLambdas.TryGetValue(lambda, out fcall))
        {
          if (CommandLineOptions.Clo.TraceVerify)
          {
            Console.WriteLine("Old lambda: {0}", lam_str);
          }
        }
        else
        {
          if (CommandLineOptions.Clo.TraceVerify)
          {
            Console.WriteLine("New lambda: {0}", lam_str);
          }

          Function fn = new Function(tok, FreshLambdaFunctionName(), freshTypeVars, formals, res,
            "auto-generated lambda function",
            Substituter.Apply(Substituter.SubstitutionFromDictionary(substFnAttrs), lambdaAttrs));
          fn.OriginalLambdaExprAsString = lam_str;

          fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name));
          fcall.Func = fn; // resolve here
          liftedLambdas[lambda] = fcall;

          List<Expr /*!*/> selectArgs = new List<Expr /*!*/>();
          foreach (Variable /*!*/ v in lambda.Dummies)
          {
            Contract.Assert(v != null);
            selectArgs.Add(new IdentifierExpr(v.tok, v));
          }

          NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs);
          axcall.Type = res.TypedIdent.Type;
          axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);
          NAryExpr select = Expr.Select(axcall, selectArgs);
          select.Type = lambdaBody.Type;
          List<Type /*!*/> selectTypeParamActuals = new List<Type /*!*/>();
          List<TypeVariable> forallTypeVariables = new List<TypeVariable>();
          foreach (TypeVariable /*!*/ tp in lambda.TypeParameters)
          {
            Contract.Assert(tp != null);
            selectTypeParamActuals.Add(tp);
            forallTypeVariables.Add(tp);
          }

          forallTypeVariables.AddRange(freeTypeVars);
          select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals);

          Expr bb = Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaBody);
          NAryExpr body = Expr.Eq(select, bb);
          body.Type = Type.Bool;
          body.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
          Trigger trig = new Trigger(select.tok, true, new List<Expr> {select});

          lambdaFunctions.Add(fn);
          lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies,
            Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaAttrs),
            trig, body));
        }

        NAryExpr call = new NAryExpr(tok, fcall, callArgs);
        call.Type = res.TypedIdent.Type;
        call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);

        return call;
      }
Beispiel #30
0
        public List <Declaration> CreateYieldCheckerProcImpl(
            Implementation impl,
            IEnumerable <List <PredicateCmd> > yields)
        {
            Dictionary <Variable, Expr> map    = new Dictionary <Variable, Expr>();
            List <Variable>             locals = new List <Variable>();
            List <Variable>             inputs = new List <Variable>();

            foreach (Variable local in impl.LocVars.Union(impl.InParams).Union(impl.OutParams))
            {
                var copy = CopyLocal(local);
                locals.Add(copy);
                map[local] = Expr.Ident(copy);
            }

            foreach (var domainName in linearTypeChecker.linearDomains.Keys)
            {
                var inParam = linearTypeChecker.LinearDomainInFormal(domainName);
                inputs.Add(inParam);
                map[linearTypeChecker.domainNameToHoleVar[domainName]] = Expr.Ident(inParam);
            }

            Dictionary <Variable, Expr> oldLocalMap = new Dictionary <Variable, Expr>();
            Dictionary <Variable, Expr> assumeMap   = new Dictionary <Variable, Expr>(map);

            foreach (Variable g in civlTypeChecker.sharedVariables)
            {
                var copy = OldLocalLocal(g);
                locals.Add(copy);
                oldLocalMap[g] = Expr.Ident(copy);
                Formal f = OldGlobalFormal(g);
                inputs.Add(f);
                assumeMap[g] = Expr.Ident(f);
            }

            Substitution  assumeSubst        = Substituter.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst           = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst              = Substituter.SubstitutionFromHashtable(map);
            List <Block>  yieldCheckerBlocks = new List <Block>();
            List <String> labels             = new List <String>();
            List <Block>  labelTargets       = new List <Block>();
            Block         yieldCheckerBlock  = new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            labels.Add(yieldCheckerBlock.Label);
            labelTargets.Add(yieldCheckerBlock);
            yieldCheckerBlocks.Add(yieldCheckerBlock);
            int yieldCount = 0;

            foreach (var cs in yields)
            {
                List <Cmd> newCmds = new List <Cmd>();
                foreach (var predCmd in cs)
                {
                    var newExpr = Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr);
                    newCmds.Add(new AssumeCmd(Token.NoToken, newExpr));
                }

                foreach (var predCmd in cs)
                {
                    if (predCmd is AssertCmd)
                    {
                        var       newExpr   = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr);
                        AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes);
                        assertCmd.ErrorData = "Non-interference check failed";
                        newCmds.Add(assertCmd);
                    }

                    /*
                     * Disjointness assumes injected by LinearTypeChecker are dropped now because the
                     * previous loop has already substituted the old global state in these assumes.
                     * It would be unsound to have these assumes on the current global state.
                     */
                }

                newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(yieldCheckerBlock.Label);
                labelTargets.Add(yieldCheckerBlock);
                yieldCheckerBlocks.Add(yieldCheckerBlock);
            }

            yieldCheckerBlocks.Insert(0,
                                      new Block(Token.NoToken, "enter", new List <Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets)));

            // Create the yield checker procedure
            var yieldCheckerName = $"Impl_YieldChecker_{impl.Name}";
            var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs,
                                                 new List <Variable>(), new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());

            CivlUtil.AddInlineAttribute(yieldCheckerProc);

            // Create the yield checker implementation
            var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs,
                                                      new List <Variable>(), locals, yieldCheckerBlocks);

            yieldCheckerImpl.Proc = yieldCheckerProc;
            CivlUtil.AddInlineAttribute(yieldCheckerImpl);
            return(new List <Declaration> {
                yieldCheckerProc, yieldCheckerImpl
            });
        }