예제 #1
0
            public IQueryResult ComputeSatisfiability(Query query)
            {
                // FIXME: Optimise the case where only the query expression has changed
                Printer.ClearDeclarations();
                foreach (var constraint in query.Constraints.Constraints)
                {
                    Printer.AddDeclarations(constraint);
                }
                Printer.AddDeclarations(query.QueryExpr);


                Printer.PrintCommentLine("Query " + UseCounter + " Begin");
                PrintDeclarationsAndConstraints(query.Constraints);
                Printer.PrintCommentLine("Query Expr:" + query.QueryExpr.Origin.ToString());
                Printer.PrintAssert(query.QueryExpr.Condition);
                Printer.PrintCheckSat();

                var result = UnderlyingImpl.ComputeSatisfiability(query);

                Printer.PrintCommentLine("Result : " + result.Satisfiability);

                Printer.PrintExit();
                Printer.PrintCommentLine("End of Query " + (UseCounter));
                ++UseCounter;
                return(result);
            }
예제 #2
0
            public IQueryResult ComputeSatisfiability(Query query)
            {
                IQueryResult cachedResult = null;

                Cache.TryGetValue(query, out cachedResult);

                if (cachedResult != null)
                {
                    ++InternalStatistics.cacheHits;
                    return(cachedResult);
                }
                else
                {
                    ++InternalStatistics.cacheMisses;
                    var result = UnderlyingSolver.ComputeSatisfiability(query);

                    if (MaxCacheSize != 0 && Cache.Count >= MaxCacheSize)
                    {
                        // We need to drop something from the cache
                        // Drop this first thing we find
                        var e        = Cache.GetEnumerator();
                        var ok       = e.MoveNext();
                        var toRemove = e.Current.Key;
                        Debug.Assert(ok);
                        if (!Cache.Remove(toRemove))
                        {
                            throw new InvalidOperationException("Failed to remove key from cache");
                        }
                    }

                    // Make sure we store a copy. We can't store what we were given because the executor
                    // will change it during execution
                    Cache[query.Clone()] = result;
                    return(result);
                }
            }
예제 #3
0
            protected IQueryResult InternalComputeSatisfiability(Query query)
            {
                // Check for a few things that we can quick give an answer for
                // otherwise call the real solver

                if (ExprUtil.IsTrue(query.QueryExpr.Condition))
                {
                    return(new SimpleQueryResult(Result.SAT));
                }

                if (ExprUtil.IsFalse(query.QueryExpr.Condition))
                {
                    return(new SimpleQueryResult(Result.UNSAT));
                }

                // If queryExpr is already in the constraint set then the result
                // is satisfiable
                if (query.Constraints.Contains(query.QueryExpr))
                {
                    return(new SimpleQueryResult(Result.SAT));
                }

                return(SolverImpl.ComputeSatisfiability(query));
            }
            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));
            }