Beispiel #1
0
        private List <Cmd> InlineYieldLoopInvariants(List <CallCmd> yieldInvariants)
        {
            var inlinedYieldInvariants = new List <Cmd>();

            foreach (var callCmd in yieldInvariants)
            {
                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)
                    {
                        var newExpr = Substituter.Apply(subst, req.Condition);
                        if (req.Free)
                        {
                            inlinedYieldInvariants.Add(new AssumeCmd(req.tok, newExpr, req.Attributes));
                        }
                        else
                        {
                            inlinedYieldInvariants.Add(new AssertCmd(req.tok, newExpr, req.Attributes));
                        }
                    }
                }
            }

            return(inlinedYieldInvariants);
        }
        public Expr TransitionRelationCompute(bool withOriginalInOutVariables = false)
        {
            Expr transitionRelation = Expr.Or(paths.Select(p => CalculatePathCondition(p)));

            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);
            }
        }
Beispiel #3
0
            public Expr Compute()
            {
                Search(second.thatAction.Blocks[0], false);
                Dictionary <Variable, Expr> map       = new Dictionary <Variable, Expr>();
                List <Variable>             boundVars = new List <Variable>();

                if (first != null)
                {
                    foreach (Variable v in first.thisAction.LocVars)
                    {
                        BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, v.Name, v.TypedIdent.Type));
                        map[v] = new IdentifierExpr(Token.NoToken, bv);
                        boundVars.Add(bv);
                    }
                }
                foreach (Variable v in second.thatAction.LocVars)
                {
                    BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, v.Name, v.TypedIdent.Type));
                    map[v] = new IdentifierExpr(Token.NoToken, bv);
                    boundVars.Add(bv);
                }
                Substitution subst = Substituter.SubstitutionFromHashtable(map);

                if (boundVars.Count > 0)
                {
                    return(new ExistsExpr(Token.NoToken, boundVars, Substituter.Apply(subst, transitionRelation)));
                }
                else
                {
                    return(transitionRelation);
                }
            }
            private void TryElimination(IEnumerable <Variable> extraDefinedVariables)
            {
                bool Defined(Variable v) => varToExpr.ContainsKey(v) || extraDefinedVariables.Contains(v);

                bool changed;

                do
                {
                    changed = false;
                    var remainingAssignments = new List <Assignment>();
                    foreach (var assignment in assignments)
                    {
                        if (!Defined(assignment.Var) &&
                            VariableCollector.Collect(assignment.Expr).
                            Intersect(AllIntroducedVariables).All(Defined))
                        {
                            varToExpr[assignment.Var] = SubstitutionHelper.Apply(varToExpr, assignment.Expr);
                            changed = true;
                        }
                        else
                        {
                            remainingAssignments.Add(assignment);
                        }
                    }
                    Substitution sub = Substituter.SubstitutionFromHashtable(varToExpr);
                    foreach (var assignment in remainingAssignments)
                    {
                        assignment.Expr = Substituter.Apply(sub, assignment.Expr);
                    }
                    assignments = remainingAssignments;
                    assumes     = SubstitutionHelper.Apply(sub, assumes).ToList();
                } while (changed);
            }
Beispiel #5
0
      /// <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 #6
0
            private void ReplacePreOrPostStateVars()
            {
                var preStateSub = GetPreStateVars().
                                  ToDictionary <Variable, Variable, Expr>(v => varCopies[0][v],
                                                                          v => new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));

                var frameCopiesSub = preStateSub;

                if (!IgnorePostState)
                {
                    var postStateSub = GetPostStateVars().
                                       ToDictionary <Variable, Variable, Expr>(v => varCopies[varLastCopyId[v]][v], v => Expr.Ident(v));

                    var notModifiedVars = new HashSet <Variable>(preStateSub.Keys.Intersect(postStateSub.Keys));
                    foreach (var v in notModifiedVars)
                    {
                        pathExprs.Add(Expr.Eq(preStateSub[v], postStateSub[v]));
                        postStateSub.Remove(v);
                    }

                    frameCopiesSub = frameCopiesSub.Union(postStateSub).ToDictionary(k => k.Key, v => v.Value);
                }

                var finalSub = Substituter.SubstitutionFromHashtable(frameCopiesSub);

                pathExprs = pathExprs.Select(x => Substituter.Apply(finalSub, x)).ToList();
            }
Beispiel #7
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 #8
0
 public NormalSubstituter(Substitution subst)
     : base()
 {
     Contract.Requires(subst != null);
     this.always = subst;
     this.forold = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>());
 }
Beispiel #9
0
            private void ComputeWitnessedTransitionRelationExprs()
            {
                witnessedTransitionRelations = new List <Expr>();
                Dictionary <Variable, List <WitnessFunction> > varToWitnesses = FrameWithWitnesses.
                                                                                Where(x => NotEliminatedVars.Contains(frameIntermediateCopy[x])).
                                                                                ToDictionary(
                    x => frameIntermediateCopy[x],
                    x => transitionRelationComputer.globalVarToWitnesses[(GlobalVariable)x]);

                foreach (var witnessSet in varToWitnesses.Values.CartesianProduct())
                {
                    Dictionary <Variable, Expr> witnessSubst = new Dictionary <Variable, Expr>();
                    foreach (Tuple <Variable, WitnessFunction> pair in
                             Enumerable.Zip(varToWitnesses.Keys, witnessSet, Tuple.Create))
                    {
                        WitnessFunction witnessFunction = pair.Item2;
                        List <Expr>     args            = new List <Expr>();
                        foreach (var arg in witnessFunction.InputArgs)
                        {
                            Expr expr = null;
                            switch (arg.Kind)
                            {
                            case WitnessFunction.InputArgumentKind.FIRST_ARG:
                                // TODO: Add note on the reason of using second
                                expr = Expr.Ident(second.Params.
                                                  First(x => x.Name == second.Prefix + arg.Name));
                                break;

                            case WitnessFunction.InputArgumentKind.SECOND_ARG:
                                expr = Expr.Ident(first.Params.
                                                  First(x => x.Name == first.Prefix + arg.Name));
                                break;

                            case WitnessFunction.InputArgumentKind.PRE_STATE:
                                expr = ExprHelper.Old(Expr.Ident(
                                                          frame.First(x => x.Name == arg.Name)));
                                break;

                            case WitnessFunction.InputArgumentKind.POST_STATE:
                                expr = Expr.Ident(frame.First(x => x.Name == arg.Name));
                                break;

                            default:
                                Debug.Assert(false);
                                break;
                            }
                            args.Add(expr);
                        }
                        witnessSubst[pair.Item1] = ExprHelper.FunctionCall(
                            witnessFunction.function, args.ToArray()
                            );
                    }
                    var subst = Substituter.SubstitutionFromHashtable(witnessSubst);
                    witnessedTransitionRelations.Add(
                        Substituter.Apply(subst, TransitionRelationExpr));
                }
            }
Beispiel #10
0
            private Expr CalculatePathCondition(PathInfo path)
            {
                Expr returnExpr = Expr.True;

                HashSet <Variable>          existsVars = path.existsVars;
                Dictionary <Variable, Expr> existsMap  = new Dictionary <Variable, Expr>();

                Dictionary <Variable, Expr> varToExpr = path.varToExpr;

                foreach (Variable v in varToExpr.Keys)
                {
                    if (postExistVars.Contains(v))
                    {
                        continue;
                    }
                    IdentifierExpr ie = varToExpr[v] as IdentifierExpr;
                    if (ie != null && !existsMap.ContainsKey(ie.Decl) && existsVars.Contains(ie.Decl))
                    {
                        existsMap[ie.Decl] = Expr.Ident(v);
                        existsVars.Remove(ie.Decl);
                    }
                    else
                    {
                        returnExpr      = Expr.And(returnExpr, Expr.Eq(Expr.Ident(v), (new MyDuplicator()).VisitExpr(varToExpr[v])));
                        returnExpr.Type = Type.Bool;
                    }
                }

                List <Expr> pathExprs = new List <Expr>();

                path.pathExprs.ForEach(x => pathExprs.Add((new MyDuplicator()).VisitExpr(x)));
                foreach (Expr x in pathExprs)
                {
                    Variable boundVar;
                    Expr     boundVarExpr;
                    if (InferSubstitution(x, out boundVar, out boundVarExpr) && existsVars.Contains(boundVar))
                    {
                        existsMap[boundVar] = boundVarExpr;
                        existsVars.Remove(boundVar);
                    }
                    else
                    {
                        returnExpr      = Expr.And(returnExpr, x);
                        returnExpr.Type = Type.Bool;
                    }
                }

                returnExpr = Substituter.Apply(Substituter.SubstitutionFromHashtable(existsMap), returnExpr);
                if (existsVars.Count > 0)
                {
                    returnExpr = new ExistsExpr(Token.NoToken, new List <Variable>(existsVars), returnExpr);
                }
                return(returnExpr);
            }
Beispiel #11
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 ensures  = new List <Ensures> {
                GetEnsures(GetTransitionRelation(invariantAction))
            };
            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));
            }
            var blocks = new List <Block> {
                new Block(Token.NoToken, pendingAsync.proc.Name, cmds, CmdHelper.ReturnCmd)
            };

            return(GetCheckerTuple(requires, ensures, locals, blocks, "_" + abs.proc.Name));
        }
Beispiel #12
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.SubstitutionFromHashtable(map));
        }
Beispiel #13
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 #14
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 #15
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 #17
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 #18
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 #19
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 #20
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 #21
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 #22
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.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);

        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.SubstitutionFromHashtable(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.SubstitutionFromHashtable(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.SubstitutionFromHashtable(subst), lambdaAttrs),
            trig, body));
        }

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

        return call;
      }
        public SomeRefinementInstrumentation(
            CivlTypeChecker civlTypeChecker,
            Implementation impl,
            Implementation originalImpl,
            Dictionary <Variable, Variable> oldGlobalMap,
            HashSet <Block> yieldingLoopHeaders)
        {
            newLocalVars = new List <Variable>();
            YieldingProc yieldingProc = civlTypeChecker.procToYieldingProc[originalImpl.Proc];
            int          layerNum     = yieldingProc.upperLayer;

            pc = Pc();
            newLocalVars.Add(pc);
            ok = Ok();
            newLocalVars.Add(ok);

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

            this.oldGlobalMap = new Dictionary <Variable, Variable>();
            foreach (Variable v in civlTypeChecker.sharedVariables)
            {
                var layerRange = civlTypeChecker.GlobalVariableLayerRange(v);
                if (layerRange.lowerLayerNum <= yieldingProc.upperLayer && yieldingProc.upperLayer < layerRange.upperLayerNum)
                {
                    this.oldGlobalMap[v] = oldGlobalMap[v];
                }
            }

            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.sharedVariables)
            {
                foroldMap[g] = Expr.Ident(oldGlobalMap[g]);
            }
            if (yieldingProc is ActionProc actionProc)
            {
                // 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; i < impl.InParams.Count; i++)
                {
                    alwaysMap[atomicActionImpl.InParams[i]] = Expr.Ident(impl.InParams[i]);
                }

                for (int i = 0; i < impl.OutParams.Count; i++)
                {
                    alwaysMap[atomicActionImpl.OutParams[i]] = Expr.Ident(impl.OutParams[i]);
                }
                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         betaExpr = GetTransitionRelation(atomicAction);
                beta = Substituter.ApplyReplacingOldExprs(always, forold, betaExpr);
                Expr alphaExpr = Expr.And(atomicAction.gate.Select(g => g.Expr));
                alphaExpr.Type = Type.Bool;
                alpha          = Substituter.Apply(always, alphaExpr);
            }
            else
            {
                beta  = Expr.And(this.oldGlobalMap.Keys.Select(v => Expr.Eq(Expr.Ident(v), foroldMap[v])));
                alpha = Expr.True;
            }

            pcsForYieldingLoopsHeaders = new Dictionary <Block, Variable>();
            oksForYieldingLoopHeaders  = new Dictionary <Block, Variable>();
            foreach (Block header in yieldingLoopHeaders)
            {
                var pcForYieldingLoopHeader = PcForYieldingLoopHeader(header);
                newLocalVars.Add(pcForYieldingLoopHeader);
                pcsForYieldingLoopsHeaders[header] = pcForYieldingLoopHeader;
                var okForYieldingLoopHeader = OkForYieldingLoopHeader(header);
                newLocalVars.Add(okForYieldingLoopHeader);
                oksForYieldingLoopHeaders[header] = okForYieldingLoopHeader;
            }
        }
Beispiel #24
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 #25
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 #26
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
            });
        }
Beispiel #27
0
        private void DesugarParCallCmdInBlock(Block block, bool isBlockInYieldingLoop)
        {
            var        parCallCmd = (ParCallCmd)block.Cmds[0];
            List <Cmd> newCmds    = new List <Cmd>();

            if (!isBlockInYieldingLoop)
            {
                newCmds.AddRange(refinementInstrumentation.CreateUpdatesToRefinementVars(IsParCallMarked(parCallCmd)));
            }

            List <Expr>           ins  = new List <Expr>();
            List <IdentifierExpr> outs = new List <IdentifierExpr>();
            string procName            = "ParallelCall";

            foreach (CallCmd callCmd in parCallCmd.CallCmds)
            {
                // Use original procedure names to make aggregated name more readable
                procName = procName + "_" + absyMap.OriginalOrInput(callCmd.Proc).Name;
                ins.AddRange(callCmd.Ins);
                outs.AddRange(callCmd.Outs);
            }
            procName = civlTypeChecker.AddNamePrefix(procName) + "_" + layerNum;

            if (!parallelCallAggregators.ContainsKey(procName))
            {
                List <Variable> inParams    = new List <Variable>();
                List <Variable> outParams   = new List <Variable>();
                List <Requires> requiresSeq = new List <Requires>();
                List <Ensures>  ensuresSeq  = new List <Ensures>();
                int             count       = 0;
                foreach (CallCmd callCmd in parCallCmd.CallCmds)
                {
                    Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>();
                    foreach (Variable x in callCmd.Proc.InParams)
                    {
                        Variable y = ParCallDesugarFormal(x, count, true);
                        inParams.Add(y);
                        map[x] = Expr.Ident(y);
                    }

                    foreach (Variable x in callCmd.Proc.OutParams)
                    {
                        Variable y = ParCallDesugarFormal(x, count, false);
                        outParams.Add(y);
                        map[x] = Expr.Ident(y);
                    }

                    Contract.Assume(callCmd.Proc.TypeParameters.Count == 0);
                    Substitution subst = Substituter.SubstitutionFromHashtable(map);
                    foreach (Requires req in callCmd.Proc.Requires)
                    {
                        requiresSeq.Add(new Requires(req.tok, req.Free, Substituter.Apply(subst, req.Condition), null,
                                                     req.Attributes));
                    }

                    foreach (Ensures ens in callCmd.Proc.Ensures)
                    {
                        ensuresSeq.Add(new Ensures(ens.tok, ens.Free, Substituter.Apply(subst, ens.Condition), null,
                                                   ens.Attributes));
                    }

                    count++;
                }

                parallelCallAggregators[procName] = new Procedure(Token.NoToken, procName,
                                                                  new List <TypeVariable>(), inParams, outParams, requiresSeq,
                                                                  civlTypeChecker.GlobalVariables.Select(v => Expr.Ident(v)).ToList(), ensuresSeq);
            }

            Procedure proc           = parallelCallAggregators[procName];
            CallCmd   checkerCallCmd = new CallCmd(parCallCmd.tok, proc.Name, ins, outs, parCallCmd.Attributes);

            checkerCallCmd.Proc = proc;
            newCmds.Add(checkerCallCmd);
            newCmds.AddRange(refinementInstrumentation.CreateAssumeCmds());
            newCmds.AddRange(globalSnapshotInstrumentation.CreateUpdatesToOldGlobalVars());
            newCmds.AddRange(refinementInstrumentation.CreateUpdatesToOldOutputVars());
            newCmds.AddRange(noninterferenceInstrumentation.CreateUpdatesToPermissionCollector(parCallCmd));
            newCmds.AddRange(block.cmds.GetRange(1, block.cmds.Count - 1));
            block.cmds = newCmds;
        }
Beispiel #28
0
        private void CreateFailurePreservationChecker(Program program, ActionInfo first, ActionInfo second)
        {
            Tuple <ActionInfo, ActionInfo> actionPair = new Tuple <ActionInfo, ActionInfo>(first, second);

            if (failurePreservationCheckerCache.Contains(actionPair))
            {
                return;
            }
            failurePreservationCheckerCache.Add(actionPair);

            List <Variable> inputs = new List <Variable>();

            inputs.AddRange(first.thisInParams);
            inputs.AddRange(second.thatInParams);

            Expr transitionRelation = (new TransitionRelationComputation(program, second)).Compute();
            Expr expr = Expr.True;

            foreach (AssertCmd assertCmd in first.thisGate)
            {
                expr = Expr.And(assertCmd.Expr, expr);
            }
            List <Requires> requires = DisjointnessRequires(program, first, second);

            requires.Add(new Requires(false, Expr.Not(expr)));
            foreach (AssertCmd assertCmd in second.thatGate)
            {
                requires.Add(new Requires(false, assertCmd.Expr));
            }

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

            foreach (Variable v in program.GlobalVariables())
            {
                BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type));
                boundVars.Add(bv);
                map[v] = new IdentifierExpr(Token.NoToken, bv);
            }
            foreach (Variable v in second.thatOutParams)
            {
                {
                    BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type));
                    boundVars.Add(bv);
                    map[v] = new IdentifierExpr(Token.NoToken, bv);
                }
                {
                    BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type));
                    boundVars.Add(bv);
                    oldMap[v] = new IdentifierExpr(Token.NoToken, bv);
                }
            }
            foreach (Variable v in second.thatAction.LocVars)
            {
                BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type));
                boundVars.Add(bv);
                oldMap[v] = new IdentifierExpr(Token.NoToken, bv);
            }

            Expr ensuresExpr = Expr.And(transitionRelation, Expr.Not(expr));

            if (boundVars.Count > 0)
            {
                Substitution subst    = Substituter.SubstitutionFromHashtable(map);
                Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldMap);
                ensuresExpr = new ExistsExpr(Token.NoToken, boundVars, (Expr) new MySubstituter(subst, oldSubst).Visit(ensuresExpr));
            }
            List <Ensures> ensures = new List <Ensures>();

            ensures.Add(new Ensures(false, ensuresExpr));
            List <Block> blocks = new List <Block>();

            blocks.Add(new Block(Token.NoToken, "L", new List <Cmd>(), new ReturnCmd(Token.NoToken)));
            string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name);
            List <IdentifierExpr> globalVars = new List <IdentifierExpr>();

            program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x)));
            Procedure      proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), requires, globalVars, ensures);
            Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), new List <Variable>(), blocks);

            impl.Proc = proc;
            this.decls.Add(impl);
            this.decls.Add(proc);
        }
Beispiel #29
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 #30
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.SubstitutionFromHashtable(assumeMap);
            Substitution  oldSubst    = Substituter.SubstitutionFromHashtable(oldLocalMap);
            Substitution  subst       = Substituter.SubstitutionFromHashtable(map);
            List <Block>  noninterferenceCheckerBlocks = new List <Block>();
            List <String> labels       = new List <String>();
            List <Block>  labelTargets = new List <Block>();
            Block         noninterferenceCheckerBlock =
                new Block(Token.NoToken, "exit", new List <Cmd>(), new ReturnCmd(Token.NoToken));

            labels.Add(noninterferenceCheckerBlock.Label);
            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(Token.NoToken, 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(new AssumeCmd(Token.NoToken, Expr.False));
                noninterferenceCheckerBlock =
                    new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken));
                labels.Add(noninterferenceCheckerBlock.Label);
                labelTargets.Add(noninterferenceCheckerBlock);
                noninterferenceCheckerBlocks.Add(noninterferenceCheckerBlock);
            }

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

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

            CivlUtil.AddInlineAttribute(noninterferenceCheckerProc);

            // Create the yield checker implementation
            var noninterferenceCheckerImpl = new Implementation(Token.NoToken, noninterferenceCheckerName,
                                                                decl.TypeParameters, inputs,
                                                                new List <Variable>(), locals, noninterferenceCheckerBlocks);

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