public void SelectMapStoreStoresToSymbolicIndex(int depth) { var builders = GetSimpleAndConstantFoldingBuilder(); var sb = builders.Item1; var cfb = builders.Item2; var map = GetMapVariable("m", BasicType.Int, BasicType.Int).Item1; var unconstrainedIndex = GetVarAndIdExpr("idx", BasicType.Int).Item2; var update = cfb.MapStore(map, cfb.ConstantInt(1), unconstrainedIndex); var updateSb = sb.MapStore(map, cfb.ConstantInt(1), unconstrainedIndex); // Add multiple updates to various locations, these should prevent accessing the deeply nested mapStore at unconstrainedIndex for (int index = 0; index < depth; ++index) { update = cfb.MapStore(update, cfb.ConstantInt(2 + index), cfb.ConstantInt(index)); updateSb = sb.MapStore(updateSb, sb.ConstantInt(2 + index), cfb.ConstantInt(index)); } // Now do a MapSelect from same location var result = cfb.MapSelect(update, unconstrainedIndex); var resultSb = sb.MapSelect(update, unconstrainedIndex); CheckIsInt(result); CheckIsInt(resultSb); if (depth == 0) { // Only in this case should we be able to get a concrete value back // Now check we read the concrete value we expect var asLit = ExprUtil.AsLiteral(result); Assert.IsNotNull(asLit); Assert.AreEqual(BigNum.FromInt(1), asLit.asBigNum); } else { Assert.IsNull(ExprUtil.AsLiteral(result)); Assert.IsNotNull(ExprUtil.AsMapSelect(result)); // The result should be structurally the same as what the non folding builder built (i.e no folding happened) Assert.AreEqual(resultSb, result); } }
public void ReadAtIndexMis() { // Build var m:[int][int,bool]bool var innerMapTy = GetMapVariable(BPLType.Bool, BPLType.Int, BPLType.Bool); var outerMapTy = GetMapVariable(innerMapTy, BPLType.Int); // Build map variable variable var builder = GetSimpleExprBuilder(); var mv = GetVariable("map", outerMapTy); var mapId = builder.Identifier(mv); var mp = GetMapProxy(mapId); // There are no stores so we should get a map select var indices = new List <Expr>() { builder.ConstantInt(0), builder.ConstantInt(1), builder.False }; var read = mp.ReadMapAt(indices); var asMapSelect = ExprUtil.AsMapSelect(read); Assert.IsNotNull(asMapSelect); Assert.AreEqual("map[0][1, false]", asMapSelect.ToString()); // Do concrete store mp.WriteMapAt(indices, builder.True); // Try reading back (should get constant back) var readBack = mp.ReadMapAt(indices); Assert.AreEqual(builder.True, readBack); // Force flushing by doing a read read = mp.Read(); Assert.AreEqual("map[0 := map[0][1, false := true]]", read.ToString()); // Should still be ble to read back directly readBack = mp.ReadMapAt(indices); Assert.AreEqual(builder.True, readBack); }
public void WritesAndMisRead() { // 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); // 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) })); // Read from location not stored. Should cause stores to be flushed var readAtNonStoredLocation = mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(1) }); Assert.IsNotNull(ExprUtil.AsMapSelect(readAtNonStoredLocation)); Assert.AreEqual("map[0 := false][2 := true][1]", readAtNonStoredLocation.ToString()); // Check read again Assert.AreEqual("map[0 := false][2 := true]", mp.Read().ToString()); // Try reading from another location var readAtStoredLocation = mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(2) }); Assert.AreEqual(builder.True, readAtStoredLocation); // This definitely isn't known about var read3AtNonStoredLocation = mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(18) }); Assert.IsNotNull(ExprUtil.AsMapSelect(read3AtNonStoredLocation)); Assert.AreEqual("map[0 := false][2 := true][18]", read3AtNonStoredLocation.ToString()); // Do another write and check we can read it back direcly // m[18] := false mp.WriteMapAt(new List <Expr>() { builder.ConstantInt(18) }, builder.False); // Read back Assert.AreEqual(builder.False, mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(18) })); }