public void WriteMap(Variable mapVariable, IList <Expr> indicies, Expr value)
        {
            if (!IsMapVariable(mapVariable))
            {
                throw new ArgumentException("expected map variable");
            }

            MapProxy mapProxyObj = null;

            MapTypeVariableStore.TryGetValue(mapVariable, out mapProxyObj);

            if (mapProxyObj == null)
            {
                throw new KeyNotFoundException("map variable not in store");
            }

            if (mapProxyObj.CopyOnWriteOwnerKey != this.CopyOnWriteKey)
            {
                // Perform copy
                var newMp = mapProxyObj.Clone(this.CopyOnWriteKey);
                MapTypeVariableStore[mapVariable] = newMp;
                mapProxyObj = newMp;
            }
            Debug.Assert(mapProxyObj.CopyOnWriteOwnerKey == this.CopyOnWriteKey);
            mapProxyObj.WriteMapAt(indicies, value);
        }
        public void Add(Variable v, Expr initialValue)
        {
            TypeCheckDirectAssign(v, initialValue);

            if (IsMapVariable(v))
            {
                var mp = new MapProxy(initialValue, this.CopyOnWriteKey);
                MapTypeVariableStore.Add(v, mp);
            }
            else
            {
                BasicTypeVariableStore.Add(v, initialValue);
            }
        }
        public Expr ReadMap(Variable mapVariable, IList <Expr> indicies)
        {
            if (!IsMapVariable(mapVariable))
            {
                throw new ArgumentException("expected map variable");
            }

            MapProxy mapProxyObj = null;

            MapTypeVariableStore.TryGetValue(mapVariable, out mapProxyObj);

            if (mapProxyObj == null)
            {
                throw new KeyNotFoundException("map variable not in store");
            }

            return(mapProxyObj.ReadMapAt(indicies));
        }
 // Avoid using this for maps. It will force map store flushes
 public Expr this[Variable v]
 {
     get
     {
         if (IsMapVariable(v))
         {
             return(MapTypeVariableStore[v].Read());
         }
         else
         {
             return(BasicTypeVariableStore[v]);
         }
     }
     set
     {
         TypeCheckDirectAssign(v, value);
         if (IsMapVariable(v))
         {
             if (MapTypeVariableStore.ContainsKey(v))
             {
                 var mp = MapTypeVariableStore[v];
                 if (mp.CopyOnWriteOwnerKey != this.CopyOnWriteKey)
                 {
                     // Make copy
                     var newMp = mp.Clone(this.CopyOnWriteKey);
                     MapTypeVariableStore[v] = newMp;
                 }
                 MapTypeVariableStore[v].Write(value);
             }
             else
             {
                 MapTypeVariableStore[v] = new MapProxy(value, this.CopyOnWriteKey);
             }
             Debug.Assert(MapTypeVariableStore[v].CopyOnWriteOwnerKey == this.CopyOnWriteKey);
         }
         else
         {
             BasicTypeVariableStore[v] = value;
         }
     }
 }
Beispiel #5
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            // Try to do direct map indexing
            // FIXME: If there are nested mapselects but they don't end on a variable
            // then we'll do a lot of unnecessary work every time we traverse into a map select down.
            var asMapSelect = ExprUtil.AsMapSelect(node);

            if (asMapSelect != null)
            {
                // Gather the indices. They will be backwards as we traversing top down so have to
                // reverse at the end.
                //
                // Here's an example showing this:
                //
                // var m:[int][int]bool;
                // y:= m[0][1]
                //
                // The indicies we want are [0][1], but when traverse we will visit them backwards as
                // we start at the root of the expression tree.
                //
                // The structure of this is
                //
                //            mapselect
                //            /        \
                //    mapselect        1
                //    /      \
                //  m        0
                var  indices  = new List <Expr>();
                Expr firstArg = null;
                do
                {
                    // Traverse multi-arity arguments in reverse because later on we reverse them.
                    for (int index = asMapSelect.Args.Count - 1; index >= 1; --index)
                    {
                        // Don't do index variable mapping here because we might
                        // need to throw away what we've done
                        indices.Add(asMapSelect.Args[index]);
                    }
                    firstArg    = asMapSelect.Args[0];
                    asMapSelect = ExprUtil.AsMapSelect(firstArg);
                } while (asMapSelect != null);

                // Hopefully a map variable we can write to
                var asId = ExprUtil.AsIdentifer(firstArg);

                if (asId != null && asId.Decl.TypedIdent.Type.IsMap)
                {
                    // Do a remapping if necessary
                    // FIXME: This sucks. Fix boogie instead!
                    Variable V = null;
                    if (preReplacementReMap.ContainsKey(asId.Decl))
                    {
                        V = preReplacementReMap[asId.Decl];
                    }
                    else
                    {
                        V = asId.Decl;
                    }

                    // We need to make sure that the map variable isn't bound and that
                    // Note: that map is being fully indexed into and not partially
                    if ((!BoundVariables.Contains(V)) &&
                        indices.Count == MapProxy.ComputeIndicesRequireToDirectlyIndex(asId.Decl.TypedIdent.Type))
                    {
                        // Put indices in correct order
                        indices.Reverse();

                        // Expand the indices so variables are mapped
                        var expandedIndices = new List <Expr>();
                        foreach (var index in indices)
                        {
                            expandedIndices.Add((Expr)this.Visit(index));
                        }

                        var valueFromMap = State.ReadMapVariableInScopeAt(V, expandedIndices);
                        return(valueFromMap);
                    }
                }
            }

            // Handle all other NAryExpr and fall back when we encounter a mapselect we can't support
            // (e.g. the map variable being used is not known).
            return(base.VisitNAryExpr(node));
        }