Example #1
0
        private List <Cmd> AbstractAssign(AssignCmd acmd)
        {
            var newcmd = new List <Cmd>();

            // !KeepSimple: then map indices are given special treatment
            var KeepSimple = UseSimpleSlicing || (currImplementation == null) || (acmd.Lhss.Count != 1);

            if (acmd.Lhss.Count != 1)
            {
                EncounteredParallelAssignment = true;
            }

            var newLhss     = new List <AssignLhs>();
            var newRhss     = new List <Expr>();
            var varsToHavoc = new HashSet <Variable>();

            for (int i = 0; i < acmd.Lhss.Count; i++)
            {
                AssignLhs lhs = acmd.Lhss[i];
                Expr      rhs = acmd.Rhss[i];

                //IdentifierExpr assignedVar = getAssignedVariable(lhs);
                IdentifierExpr assignedVar = lhs.DeepAssignedIdentifier;

                if (isTrackedVariable(assignedVar.Decl))
                {
                    if (lhs is MapAssignLhs && !indicesAreTracked((MapAssignLhs)lhs))
                    {
                        // convert to assignedVar := *
                        varsToHavoc.Add(assignedVar.Decl);
                    }
                    else if (!isTracked(rhs))
                    {
                        // Convert to lhs := *
                        if (KeepSimple || lhs is SimpleAssignLhs)
                        {
                            varsToHavoc.Add(assignedVar.Decl);
                        }
                        else
                        {
                            // convert to "havoc lhs" as follows:
                            // havoc dummy; lhs := dummy;
                            // This is done when lhs is Mem[x]. We're not
                            // allowed to say "havoc Mem[x]".

                            // We should be doing this only when we can add new
                            // local variables
                            Debug.Assert(currImplementation != null);

                            // Get new local variable dummy
                            LocalVariable dummy = getNewLocal(lhs.Type, currImplementation);

                            // havoc dummy
                            newcmd.Add(BoogieAstFactory.MkHavocVar(dummy));

                            // lhs := dummy
                            newLhss.Add(lhs);
                            newRhss.Add(Expr.Ident(dummy));
                        }
                    }
                    else
                    {
                        // It is possible to come here because a variable may be untracked in this scope,
                        // yet tracked globally because it is on the lhs
                        newLhss.Add(lhs);
                        newRhss.Add(rhs);
                    }
                }
            }

            if (newLhss.Count != 0)
            {
                newcmd.Add(new AssignCmd(Token.NoToken, newLhss, newRhss));
            }

            if (varsToHavoc.Count != 0)
            {
                var ieseq = new List <IdentifierExpr>();
                varsToHavoc.Iter(v => ieseq.Add(Expr.Ident(v)));
                newcmd.Add(new HavocCmd(Token.NoToken, ieseq));
            }

            return(newcmd);
        }