public void RemByZero() { var builders = GetSimpleAndConstantFoldingBuilder(); var sfb = builders.Item1; var cfb = builders.Item2; var dividend = cfb.ConstantBV(5, 4); var divisor = cfb.ConstantBV(0, 4); var noFoldResult = sfb.BVSMOD(dividend, divisor); var cfbNoFold = cfb.BVSMOD(dividend, divisor); CheckIsBvType(cfbNoFold, 4); CheckIsBvType(noFoldResult, 4); Assert.IsNull(ExprUtil.AsLiteral(cfbNoFold)); Assert.IsTrue(ExprUtil.StructurallyEqual(noFoldResult, cfbNoFold)); CheckIsBvType(cfbNoFold, 4); }
public void NoFold() { var builders = GetSimpleAndConstantFoldingBuilder(); SimpleExprBuilder sfb = builders.Item1; ConstantFoldingExprBuilder cfb = builders.Item2; var arg0 = GetVarAndIdExpr("x", BasicType.GetBvType(8)).Item2; var arg1 = GetVarAndIdExpr("y", BasicType.GetBvType(8)).Item2; var simpleResult = sfb.BVSGE(arg0, arg1); var result = cfb.BVSGE(arg0, arg1); CheckIsBoolType(result); CheckIsBoolType(simpleResult); Assert.IsNull(ExprUtil.AsLiteral(result)); Assert.IsNotNull(ExprUtil.AsBVSGE(result)); Assert.IsTrue(ExprUtil.StructurallyEqual(result, simpleResult)); }
public void RequiresEqualityConstraintBV() { p = LoadProgramFrom(@" var g:bv32; procedure main() modifies g; requires (g == 0bv32); { assert {:symbooglix_bp ""entry""} true; assert g == 0bv32; } ", "test.bpl"); e = GetExecutor(p, new DFSStateScheduler(), GetSolver()); int bpCounter = 0; e.BreakPointReached += delegate(object sender, Executor.BreakPointEventArgs eventArgs) { ++bpCounter; switch (eventArgs.Name) { case "entry": // Check that the global "g" is concrete var p1 = e.CurrentState.GetInScopeVariableAndExprByName("g"); var asLit = ExprUtil.AsLiteral(p1.Value); Assert.IsNotNull(asLit); Assert.IsTrue(asLit.isBvConst); Assert.AreEqual(Microsoft.Basetypes.BigNum.FromInt(0), asLit.asBvConst.Value); Assert.AreEqual(32, asLit.asBvConst.Bits); break; default: Assert.Fail("Unexpected break point"); break; } }; var tc = new TerminationCounter(); tc.Connect(e); e.Run(GetMain(p)); Assert.AreEqual(1, bpCounter); Assert.AreEqual(1, tc.Sucesses); Assert.AreEqual(0, tc.NumberOfFailures); }
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 SameExprAdded() { var cfb = GetConstantFoldingBuilder(); var x = GetVarAndIdExpr("x", BasicType.GetBvType(8)).Item2; var y = GetVarAndIdExpr("x", BasicType.GetBvType(8)).Item2; var side = cfb.BVADD(x, y); CheckIsBvType(side, 8); Assert.IsNull(ExprUtil.AsLiteral(side)); var result = cfb.BVADD(side, side); CheckIsBvType(result, 8); var mul = ExprUtil.AsBVMUL(result); Assert.IsNotNull(mul); var lhs = ExprUtil.AsLiteral(mul.Args[0]); Assert.IsNotNull(lhs); Assert.AreEqual(2, lhs.asBvConst.Value.ToInt); Assert.AreSame(side, mul.Args[1]); }
public void FollowThen() { p = LoadProgramFrom(@" procedure main() { var a:int; var b:int; var old_b:int; old_b := b; assume a > 0; b := if a > 0 then 1 else b; assert {:symbooglix_bp ""follow_then""} b == 1; } ", "test.bpl"); Run(0, 1, (object sender, Executor.BreakPointEventArgs e) => { Assert.AreEqual("follow_then", e.Name); Executor executor = sender as Executor; Assert.IsNotNull(executor); var pair = executor.CurrentState.GetInScopeVariableAndExprByName("b"); Assert.IsNotNull(ExprUtil.AsLiteral(pair.Value)); Assert.AreEqual("1", pair.Value.ToString()); }); }
public void SelectMapStoreSingleIndexRepeatedStoresToConcreteIndex(int depth) { var cfb = GetConstantFoldingBuilder(); var map = GetMapVariable("m", BasicType.Int, BasicType.Int).Item1; var update = cfb.MapStore(map, cfb.ConstantInt(1), cfb.ConstantInt(1)); // Add multiple updates to the same location for (int index = 0; index < depth; ++index) { update = cfb.MapStore(update, cfb.ConstantInt(2 + index), cfb.ConstantInt(1)); } // Now do a MapSelect from same location var result = cfb.MapSelect(update, cfb.ConstantInt(1)); CheckIsInt(result); // Now check we read the concrete value we expect var asLit = ExprUtil.AsLiteral(result); Assert.IsNotNull(asLit); Assert.AreEqual(BigNum.FromInt(1 + depth), asLit.asBigNum); }
public void SymbolicWriteForcesStoresToBeDropped() { // Build var m:[int]bool; var mapTy = GetMapVariable(BPLType.Int, 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.ConstantInt(99)); // m[2] := true mp.WriteMapAt(new List <Expr>() { builder.ConstantInt(2) }, builder.ConstantInt(101)); // m[5] := false mp.WriteMapAt(new List <Expr>() { builder.ConstantInt(5) }, builder.ConstantInt(25)); // Read back Assert.AreEqual(builder.ConstantInt(99), mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(0) })); Assert.AreEqual(builder.ConstantInt(101), mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(2) })); Assert.AreEqual(builder.ConstantInt(25), mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(5) })); // Now write to a symbolic location. This should cause all the stores to flushed // and then dropped var symIndex = GetVariable("symIndex", BPLType.Int); mp.WriteMapAt(new List <Expr>() { builder.Identifier(symIndex) }, builder.ConstantInt(11)); // Read back var m0AfterFlush = mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(0) }); Assert.IsNull(ExprUtil.AsLiteral(m0AfterFlush)); Assert.AreEqual("map[0 := 99][2 := 101][5 := 25][symIndex := 11][0]", m0AfterFlush.ToString()); var m2AfterFlush = mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(2) }); Assert.IsNull(ExprUtil.AsLiteral(m2AfterFlush)); Assert.AreEqual("map[0 := 99][2 := 101][5 := 25][symIndex := 11][2]", m2AfterFlush.ToString()); var m5AfterFlush = mp.ReadMapAt(new List <Expr>() { builder.ConstantInt(5) }); Assert.IsNull(ExprUtil.AsLiteral(m5AfterFlush)); Assert.AreEqual("map[0 := 99][2 := 101][5 := 25][symIndex := 11][5]", m5AfterFlush.ToString()); }
public IBranchSatisfiabilityResult CheckBranchSatisfiability(IConstraintManager constraints, Constraint trueExpr, IExprBuilder builder) { // Note: We implicitly assume that the constraints are satisfiable TryInterupt = false; IQueryResult falseBranchResult = null; IQueryResult trueBranchResult = null; try { Timer.Start(); // Fast path: trueExpr is constant var trueExprAsLit = ExprUtil.AsLiteral(trueExpr.Condition); if (trueExprAsLit != null) { if (!trueExprAsLit.isBool) { throw new ExprTypeCheckException("trueExpr must be of boolean type"); } if (trueExprAsLit.asBool) { return(new SimpleBranchSatsifiabilityResult(Result.SAT, Result.UNSAT)); } else { return(new SimpleBranchSatsifiabilityResult(Result.UNSAT, Result.SAT)); } } // Slow path: Invoke solver // First see if it's possible for the false branch to be feasible // ∃ X constraints(X) ∧ ¬ condition(X) var query = new Solver.Query(constraints, trueExpr); falseBranchResult = InternalComputeSatisfiability(query.WithNegatedQueryExpr(builder)); var falseBranch = falseBranchResult.Satisfiability; var trueBranch = Result.UNKNOWN; // Only invoke solver again if necessary if (falseBranch == Result.UNSAT) { // This actually implies that // // ∀X : C(X) → Q(X) // That is if the constraints are satisfiable then // the query expr is always true. Because we've been // checking constraints as we go we already know C(X) is satisfiable trueBranch = Result.SAT; } else { if (TryInterupt) { // Don't do next solver call Console.Error.WriteLine("WARNING: Tried to kill solver during CheckBranchSatisfiability()"); return(new SimpleBranchSatsifiabilityResult(Result.UNKNOWN, falseBranch)); } // Now see if it's possible for execution to continue past the assertion // ∃ X constraints(X) ∧ condition(X) trueBranchResult = InternalComputeSatisfiability(query); trueBranch = trueBranchResult.Satisfiability; } return(new SimpleBranchSatsifiabilityResult(trueBranch, falseBranch)); } finally { Timer.Stop(); if (falseBranchResult != null) { UpdateStatistics(falseBranchResult); } if (trueBranchResult != null) { UpdateStatistics(trueBranchResult); } } }