private void PrintDeclarationsAndConstraints(IConstraintManager cm) { Printer.PrintSortDeclarations(); Printer.PrintVariableDeclarations(); Printer.PrintFunctionDeclarations(); Printer.PrintCommentLine(cm.Count.ToString() + " Constraints"); foreach (var constraint in cm.ConstraintExprs) { Printer.PrintAssert(constraint); } }
public ExecutionState() { Mem = new Memory(); Constraints = new ConstraintManager(); Id = NewId++; TerminationType = null; Speculative = false; ExplicitBranchDepth = 0; TreeNode = null; //new ExecutionTreeNode(this, null, null); // FIXME: Disabled due to design issues. CreatedAt = null; }
public Query(IConstraintManager constraints, Constraint queryExpr) { this.Constraints = constraints; this.QueryExpr = queryExpr; }
public IQueryResult ComputeSatisfiability(Query query) { Interrupted = false; ConstraintSetReductionTimer.Start(); HashSet <SymbolicVariable> usedVariables = new HashSet <SymbolicVariable>(query.QueryExpr.UsedVariables); HashSet <Function> usedUinterpretedFunctions = new HashSet <Function>(query.QueryExpr.UsedUninterpretedFunctions); // Compute a new constraint set that only contains relevant contraints HashSet <Constraint> relevantConstraints = new HashSet <Constraint>(); bool changed = false; IConstraintManager reducedConstraints = null; do { changed = false; foreach (var constraint in query.Constraints.Constraints) { if (Interrupted) { Console.WriteLine("WARNING: ConstraintIndependenceSolver interrupted!"); ConstraintSetReductionTimer.Stop(); return(new SimpleQueryResult(Result.UNKNOWN)); } if (relevantConstraints.Contains(constraint)) { // We've already added this constraint continue; } if (constraint.UsedVariables.Overlaps(usedVariables) || constraint.UsedUninterpretedFunctions.Overlaps(usedUinterpretedFunctions)) { // This constraint is relevant so we should pass it to // the underlying solver. We also need to add the variables // it uses to the usedVariables set we are maintaining so that // transitively propagate the usedVariables relevantConstraints.Add(constraint); usedVariables.UnionWith(constraint.UsedVariables); usedUinterpretedFunctions.UnionWith(constraint.UsedUninterpretedFunctions); changed = true; } } } while (changed); // Make the new IConstraintManager reducedConstraints = query.Constraints.GetSubSet(relevantConstraints); Debug.Assert(reducedConstraints.Count <= query.Constraints.Count); // Update statistics if (reducedConstraints.Count == query.Constraints.Count) { ++InternalStatistics.ConstraintSetsLeftUnchanged; } else { ++InternalStatistics.ConstraintSetsReduced; } ConstraintSetReductionTimer.Stop(); // FIXME: We should wrap the returned IQueryResult object because the client may ask // for the assignment to variables which we removed. var reducedQuery = new Query(reducedConstraints, query.QueryExpr); return(UnderlyingSolver.ComputeSatisfiability(reducedQuery)); }
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); } } }