예제 #1
0
        public void ConcreteStoreDifferentValues(int depth)
        {
            var cfb = GetConstantFoldingBuilder();
            var map = GetMapVariable("m", BasicType.Int, BasicType.Int, BasicType.Int).Item1;

            Expr id     = null;
            Expr result = map;

            // Writes to the same concrete location should get folded, but here
            // the value being written each is different so we need to make a new node each time
            for (int index = 0; index < depth; ++index)
            {
                id = GetVarAndIdExpr("value" + index.ToString(), BasicType.Int).Item2;
                var oldResult = result;
                result = cfb.MapStore(result, id, cfb.ConstantInt(0), cfb.ConstantInt(1));
                Assert.AreNotSame(oldResult, result);
                CheckIsMapType(result, BasicType.Int, BasicType.Int, BasicType.Int);
            }

            // Check we have a single map store
            var asMapStore = ExprUtil.AsMapStore(result);

            Assert.AreSame(map, asMapStore.Args[0]);                 // map written to
            Assert.AreEqual(cfb.ConstantInt(0), asMapStore.Args[1]); // first index
            Assert.AreEqual(cfb.ConstantInt(1), asMapStore.Args[2]); // second index
            Assert.AreSame(id, asMapStore.Args[3]);                  // value stored
        }
예제 #2
0
        public void SymbolicStoreSameValue(int depth)
        {
            var  cfb    = GetConstantFoldingBuilder();
            var  map    = GetMapVariable("m", BasicType.Int, BasicType.Int, BasicType.Int).Item1;
            var  idx0   = GetVarAndIdExpr("idx0", BasicType.Int).Item2;
            var  idx1   = GetVarAndIdExpr("idx0", BasicType.Int).Item2;
            var  id     = GetVarAndIdExpr("value", BasicType.Int).Item2;
            Expr result = map;

            // Writes to the same concrete location should get folded
            for (int index = 0; index < depth; ++index)
            {
                var oldResult = result;
                result = cfb.MapStore(result, id, idx0, idx1);
                CheckIsMapType(result, BasicType.Int, BasicType.Int, BasicType.Int);

                if (index > 0)
                {
                    // The same location with the same value is repeatedly written to
                    // so we shouldn't create a new node for this case.
                    Assert.AreSame(oldResult, result);
                }
            }

            // Check we have a single map store
            var asMapStore = ExprUtil.AsMapStore(result);

            Assert.AreSame(map, asMapStore.Args[0]);   // map written to
            Assert.AreEqual(idx0, asMapStore.Args[1]); // first index
            Assert.AreEqual(idx1, asMapStore.Args[2]); // second index
            Assert.AreSame(id, asMapStore.Args[3]);    // value stored
        }
예제 #3
0
        public void NoFoldSymbolicStoreSameValueAtDifferentLocations(int depth)
        {
            var builders = GetSimpleAndConstantFoldingBuilder();
            var sb       = builders.Item1;
            var cfb      = builders.Item2;
            var map      = GetMapVariable("m", BasicType.Int, BasicType.Int, BasicType.Int).Item1;

            var  id       = GetVarAndIdExpr("value", BasicType.Int).Item2;
            Expr result   = map;
            Expr resultSb = map;

            // Writes to different concrete locations should not be folded
            for (int index = 0; index < depth; ++index)
            {
                var oldResult          = result;
                var unconstrainedIndex = GetVarAndIdExpr("idx" + index.ToString(), BasicType.Int).Item2;
                result   = cfb.MapStore(result, id, unconstrainedIndex, unconstrainedIndex);
                resultSb = sb.MapStore(resultSb, id, unconstrainedIndex, unconstrainedIndex);
                CheckIsMapType(result, BasicType.Int, BasicType.Int, BasicType.Int);
                CheckIsMapType(resultSb, BasicType.Int, BasicType.Int, BasicType.Int);
                Assert.AreNotSame(oldResult, result);
            }

            // Check we have a single map store
            Assert.IsNotNull(ExprUtil.AsMapStore(result));
            Assert.AreEqual(resultSb, result);
        }
예제 #4
0
        public void WriteAtConstantIndicesDoIndexedReadThenFlush()
        {
            // Build var m:[int][int][int]bool
            var innerMapTy  = GetMapVariable(BPLType.Bool, BPLType.Int);
            var middleMapTy = GetMapVariable(innerMapTy, BPLType.Int);
            var outerMapTy  = GetMapVariable(middleMapTy, BPLType.Int);

            // Build map variable variable
            var builder = GetSimpleExprBuilder();
            var mv      = GetVariable("map", outerMapTy);
            var mapId   = builder.Identifier(mv);
            var mp      = GetMapProxy(mapId);

            // do m[1][2][3] := False
            var indices = new List <Expr>()
            {
                builder.ConstantInt(1), builder.ConstantInt(2), builder.ConstantInt(3)
            };

            mp.WriteMapAt(indices, builder.False);

            // Read back by index
            var indexedRead = mp.ReadMapAt(indices);

            Assert.AreEqual(builder.False, indexedRead);

            // Force the expressions to be flushed
            var fullRead   = mp.Read();
            var asMapStore = ExprUtil.AsMapStore(fullRead);

            Assert.IsNotNull(asMapStore);
            Assert.AreEqual("map[1 := map[1][2 := map[1][2][3 := false]]]", asMapStore.ToString());

            // We only did a read so should still be able to get the stored expression
            Assert.AreEqual(builder.False, mp.ReadMapAt(indices));
        }
예제 #5
0
        public void FlushMultipleWrites()
        {
            // Build var m:[int]bool;
            var mapTy = GetMapVariable(BPLType.Bool, BPLType.Int);

            // Build map variable variable
            var builder = GetSimpleExprBuilder();
            var mv      = GetVariable("map", mapTy);
            var mapId   = builder.Identifier(mv);
            var mp      = GetMapProxy(mapId);

            // m[0] := false
            mp.WriteMapAt(new List <Expr>()
            {
                builder.ConstantInt(0)
            }, builder.False);

            // m[2] := true
            mp.WriteMapAt(new List <Expr>()
            {
                builder.ConstantInt(2)
            }, builder.True);

            // m[5] := false
            mp.WriteMapAt(new List <Expr>()
            {
                builder.ConstantInt(5)
            }, builder.False);

            // Overwrite
            // m[5] := true
            mp.WriteMapAt(new List <Expr>()
            {
                builder.ConstantInt(5)
            }, builder.True);

            // Read back
            Assert.AreEqual(builder.False, mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(0)
            }));
            Assert.AreEqual(builder.True, mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(2)
            }));
            Assert.AreEqual(builder.True, mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(5)
            }));

            // Force flush
            var fullResult = mp.Read();
            var asMapStore = ExprUtil.AsMapStore(fullResult);

            Assert.IsNotNull(asMapStore);
            Assert.AreEqual("map[0 := false][2 := true][5 := true]", asMapStore.ToString());

            // Do again check we get the same
            fullResult = mp.Read();
            asMapStore = ExprUtil.AsMapStore(fullResult);
            Assert.IsNotNull(asMapStore);
            Assert.AreEqual("map[0 := false][2 := true][5 := true]", asMapStore.ToString());

            // The read should not clear the stores so we will read back the stored expression
            Assert.AreEqual(builder.False, mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(0)
            }));
            Assert.AreEqual(builder.True, mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(2)
            }));
            Assert.AreEqual(builder.True, mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(5)
            }));

            // Reading at a index not stored should give full expression
            Assert.AreEqual("map[0 := false][2 := true][5 := true][1]", mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(1)
            }).ToString());
            Assert.AreEqual("map[0 := false][2 := true][5 := true][3]", mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(3)
            }).ToString());
            Assert.AreEqual("map[0 := false][2 := true][5 := true][4]", mp.ReadMapAt(new List <Expr>()
            {
                builder.ConstantInt(4)
            }).ToString());
        }