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);
            }
 private static void SubstituteBackwardAssignments(AtomicAction action)
 {
     foreach (Block block in action.impl.Blocks)
     {
         List <Cmd> cmds = new List <Cmd>();
         foreach (Cmd cmd in block.cmds)
         {
             if (cmd is AssignCmd _assignCmd &&
                 QKeyValue.FindBoolAttribute(_assignCmd.Attributes, CivlAttributes.BACKWARD))
             {
                 AssignCmd assignCmd = _assignCmd.AsSimpleAssignCmd;
                 var       lhss      = assignCmd.Lhss;
                 var       rhss      = assignCmd.Rhss;
                 var       rhssVars  = rhss.SelectMany(x => VariableCollector.Collect(x));
                 var       lhssVars  = lhss.SelectMany(x => VariableCollector.Collect(x));
                 if (rhssVars.Intersect(lhssVars).Any())
                 {
                     // TODO
                     throw new NotImplementedException("Substitution of backward assignment where lhs appears on rhs");
                 }
                 else
                 {
                     List <Expr> assumeExprs = new List <Expr>();
                     for (int k = 0; k < lhss.Count; k++)
                     {
                         assumeExprs.Add(Expr.Eq(lhss[k].AsExpr, rhss[k]));
                     }
                     cmds.Add(new AssumeCmd(Token.NoToken, Expr.And(assumeExprs)));
                     cmds.Add(new HavocCmd(Token.NoToken, lhss.Select(x => x.DeepAssignedIdentifier).ToList()));
                 }
             }
        public AtomicAction(Procedure proc, Implementation impl, MoverType moverType, LayerRange layerRange)
        {
            this.proc       = proc;
            this.impl       = impl;
            this.moverType  = moverType;
            this.layerRange = layerRange;

            CivlUtil.AddInlineAttribute(proc);
            CivlUtil.AddInlineAttribute(impl);

            // The gate of an atomic action is represented as asserts at the beginning of the procedure body.
            this.gate = impl.Blocks[0].cmds.TakeWhile((c, i) => c is AssertCmd).Cast <AssertCmd>().ToList();
            impl.Blocks[0].cmds.RemoveRange(0, gate.Count);

            gateUsedGlobalVars   = new HashSet <Variable>(VariableCollector.Collect(gate).Where(x => x is GlobalVariable));
            actionUsedGlobalVars = new HashSet <Variable>(VariableCollector.Collect(impl).Where(x => x is GlobalVariable));
            modifiedGlobalVars   = new HashSet <Variable>(AssignedVariables().Where(x => x is GlobalVariable));

            // We usually declare the Boogie procedure and implementation of an atomic action together.
            // Since Boogie only stores the supplied attributes (in particular linearity) in the procedure parameters,
            // we copy them into the implementation parameters here.
            for (int i = 0; i < proc.InParams.Count; i++)
            {
                impl.InParams[i].Attributes = proc.InParams[i].Attributes;
            }
            for (int i = 0; i < proc.OutParams.Count; i++)
            {
                impl.OutParams[i].Attributes = proc.OutParams[i].Attributes;
            }

            AtomicActionDuplicator.SetupCopy(this, ref firstGate, ref firstImpl, "first_");
            AtomicActionDuplicator.SetupCopy(this, ref secondGate, ref secondImpl, "second_");

            DeclareTriggerFunctions();
        }
Exemple #4
0
 public override Expr VisitExpr(Expr node)
 {
     if (node is NAryExpr nary &&
         nary.Fun is BinaryOperator op &&
         op.Op == BinaryOperator.Opcode.Eq &&
         VariableCollector.Collect(node).Contains(choice))
     {
         return(Expr.True);
     }
     return(base.VisitExpr(node));
 }
Exemple #5
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;
            }
        }
        private Expr CalculatePathCondition(PathInfo path)
        {
            HashSet <Variable>          allExistsVars         = new HashSet <Variable>(firstExistsVars.Union(secondExistsVars));
            HashSet <Variable>          usedExistsVars        = new HashSet <Variable>();
            Dictionary <Variable, Expr> existsSubstitutionMap = new Dictionary <Variable, Expr>();
            List <Expr> inferredSelectEqualities = new List <Expr>();

            foreach (Variable v in path.varToExpr.Keys.Except(postExistVars))
            {
                var expr = path.varToExpr[v];
                usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars));
                IdentifierExpr ie = expr as IdentifierExpr;
                if (ie != null && IsExistsVar(ie.Decl) && !existsSubstitutionMap.ContainsKey(ie.Decl))
                {
                    existsSubstitutionMap[ie.Decl] = Expr.Ident(v);
                }
                else if (IsMapStoreExpr(expr))
                {
                    inferredSelectEqualities.Add(GenerateEqualityWithSelect(expr as NAryExpr, Expr.Ident(v)));
                }
            }

            foreach (Expr expr in path.pathExprs)
            {
                usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars));
            }
            InferSubstitution(allExistsVars, existsSubstitutionMap, path.pathExprs, inferredSelectEqualities);

            List <Expr>     triggerExprs   = new List <Expr>();
            List <Variable> quantifiedVars = new List <Variable>();

            foreach (var v in usedExistsVars.Except(existsSubstitutionMap.Keys))
            {
                var triggerFun    = TriggerFunction(v); // this call populates existsVars[v]
                var quantifiedVar = existsVars[v];
                triggerExprs.Add(
                    new NAryExpr(Token.NoToken,
                                 new FunctionCall(triggerFun),
                                 new Expr[] { Expr.Ident(quantifiedVar) }));
                quantifiedVars.Add(quantifiedVar);
                existsSubstitutionMap[v] = Expr.Ident(quantifiedVar);
            }

            Substitution subst       = Substituter.SubstitutionFromHashtable(existsSubstitutionMap);
            List <Expr>  returnExprs = new List <Expr>();

            foreach (Variable v in path.varToExpr.Keys.Except(postExistVars))
            {
                Expr withOldExpr = MyDuplicator.Duplicate(path.varToExpr[v]);
                var  substExpr   = Expr.Eq(Expr.Ident(v), Substituter.Apply(subst, withOldExpr));
                substExpr.Type = Type.Bool;
                returnExprs.Add(substExpr);
            }

            foreach (Expr x in path.pathExprs)
            {
                var withOldExpr = MyDuplicator.Duplicate(x);
                returnExprs.Add(Substituter.Apply(subst, withOldExpr));
            }

            var returnExpr = Expr.And(returnExprs);

            if (quantifiedVars.Count > 0)
            {
                if (first == null)
                {
                    returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, returnExpr);
                }
                else
                {
                    returnExpr = new ExistsExpr(Token.NoToken,
                                                quantifiedVars,
                                                new Trigger(Token.NoToken, true, triggerExprs),
                                                returnExpr);
                }
            }
            return(returnExpr);
        }