예제 #1
0
        internal void Solve(Z3BaseParams parameters, IEnumerable <IGoal> modelGoals,
                            Action <int> addRow, Func <int, ArithExpr> mkGoalRow, Action <Z3Result> setResult)
        {
            _variables.Clear();
            _goals.Clear();

            try
            {
                // Mark that we are in solving phase
                _isSolving = true;

                // Construct Z3
                ConstructSolver(parameters);

                // Add all the variables
                foreach (int vid in _model.VariableIndices)
                {
                    AddVariable(vid);
                }

                // Add all the rows
                foreach (int rid in _model.RowIndices)
                {
                    addRow(rid);
                }

                // Add enabled goals to optimization problem
                foreach (IGoal g in modelGoals)
                {
                    if (!g.Enabled)
                    {
                        continue;
                    }

                    ArithExpr gr = mkGoalRow(g.Index);
                    if (g.Minimize)
                    {
                        _goals.Add(g, _optSolver.MkMinimize(gr));
                    }
                    else
                    {
                        _goals.Add(g, _optSolver.MkMaximize(gr));
                    }
                }

                if (_goals.Any() && parameters.SMT2LogFile != null)
                {
                    Debug.WriteLine("Dumping SMT2 benchmark to log file...");
                    File.WriteAllText(parameters.SMT2LogFile, _optSolver.ToString());
                }

                bool aborted = parameters.QueryAbort();

                if (!aborted)
                {
                    // Start the abort thread
                    AbortWorker abortWorker = new AbortWorker(_context, parameters.QueryAbort);
                    Thread      abortThread = new Thread(abortWorker.Start);
                    abortThread.Start();

                    // Now solve the problem
                    Status status = _optSolver.Check();

                    // Stop the abort thread
                    abortWorker.Stop();
                    abortThread.Join();

                    switch (status)
                    {
                    case Status.SATISFIABLE:
                        Microsoft.Z3.Model model = _optSolver.Model;
                        Debug.Assert(model != null, "Should be able to get Z3 model.");
                        // Remember the solution values
                        foreach (KeyValuePair <int, Expr> pair in _variables)
                        {
                            var value = Utils.ToRational(model.Eval(pair.Value, true));
                            _model.SetValue(pair.Key, value);
                        }
                        // Remember all objective values
                        foreach (var pair in _goals)
                        {
                            var optimalValue = Utils.ToRational(pair.Value.Upper);
                            _model.SetValue(pair.Key.Index, optimalValue);
                        }
                        model.Dispose();
                        setResult(_goals.Any() ? Z3Result.Optimal : Z3Result.Feasible);
                        break;

                    case Status.UNSATISFIABLE:
                        setResult(Z3Result.Infeasible);
                        break;

                    case Status.UNKNOWN:
                        if (abortWorker.Aborted)
                        {
                            Microsoft.Z3.Model subOptimalModel = _optSolver.Model;
                            if (subOptimalModel != null && subOptimalModel.NumConsts != 0)
                            {
                                // Remember the solution values
                                foreach (KeyValuePair <int, Expr> pair in _variables)
                                {
                                    var value = Utils.ToRational(subOptimalModel.Eval(pair.Value, true));
                                    _model.SetValue(pair.Key, value);
                                }
                                // Remember all objective values
                                foreach (var pair in _goals)
                                {
                                    var optimalValue = Utils.ToRational(pair.Value.Upper);
                                    _model.SetValue(pair.Key.Index, optimalValue);
                                }
                                subOptimalModel.Dispose();

                                setResult(Z3Result.LocalOptimal);
                            }
                            else
                            {
                                setResult(Z3Result.Infeasible);
                            }
                        }
                        else
                        {
                            setResult(Z3Result.Interrupted);
                        }
                        break;

                    default:
                        Debug.Assert(false, "Unrecognized Z3 Status");
                        break;
                    }
                }
            }
            finally
            {
                _isSolving = false;
            }

            // Now kill Z3
            DestructSolver(true);
        }
예제 #2
0
파일: Z3BaseSolver.cs 프로젝트: jawline/z3
        internal void Solve(Z3BaseParams parameters, IEnumerable<IGoal> modelGoals, 
                            Action<int> addRow, Func<int, ArithExpr> mkGoalRow, Action<Z3Result> setResult)
        {
            _variables.Clear();
            _goals.Clear();

            try
            {
                // Mark that we are in solving phase
                _isSolving = true;

                // Construct Z3
                ConstructSolver(parameters);

                // Add all the variables
                foreach (int vid in _model.VariableIndices)
                {
                    AddVariable(vid);
                }

                // Add all the rows
                foreach (int rid in _model.RowIndices)
                {
                    addRow(rid);
                }

                // Add enabled goals to optimization problem
                foreach (IGoal g in modelGoals)
                {
                    if (!g.Enabled) continue;

                    ArithExpr gr = mkGoalRow(g.Index);
                    if (g.Minimize)
                        _goals.Add(g, _optSolver.MkMinimize(gr));
                    else
                        _goals.Add(g, _optSolver.MkMaximize(gr));
                }

                if (_goals.Any() && parameters.SMT2LogFile != null)
                {
                    Debug.WriteLine("Dumping SMT2 benchmark to log file...");
                    File.WriteAllText(parameters.SMT2LogFile, _optSolver.ToString());
                }

                bool aborted = parameters.QueryAbort();

                if (!aborted)
                {
                    // Start the abort thread
                    AbortWorker abortWorker = new AbortWorker(_context, parameters.QueryAbort);
                    Thread abortThread = new Thread(abortWorker.Start);
                    abortThread.Start();

                    // Now solve the problem
                    Status status = _optSolver.Check();

                    // Stop the abort thread
                    abortWorker.Stop();
                    abortThread.Join();

                    switch (status)
                    {
                        case Status.SATISFIABLE:
                            Microsoft.Z3.Model model = _optSolver.Model;
                            Debug.Assert(model != null, "Should be able to get Z3 model.");
                            // Remember the solution values
                            foreach (KeyValuePair<int, Expr> pair in _variables)
                            {
                                var value = Utils.ToRational(model.Eval(pair.Value, true));
                                _model.SetValue(pair.Key, value);
                            }
                            // Remember all objective values
                            foreach (var pair in _goals)
                            {
                                var optimalValue = Utils.ToRational(pair.Value.Upper);
                                _model.SetValue(pair.Key.Index, optimalValue);
                            }
                            model.Dispose();
                            setResult(_goals.Any() ? Z3Result.Optimal : Z3Result.Feasible);
                            break;
                        case Status.UNSATISFIABLE:
                            setResult(Z3Result.Infeasible);
                            break;
                        case Status.UNKNOWN:
                            if (abortWorker.Aborted)
                            {
                                Microsoft.Z3.Model subOptimalModel = _optSolver.Model;
                                if (subOptimalModel != null && subOptimalModel.NumConsts != 0)
                                {
                                    // Remember the solution values
                                    foreach (KeyValuePair<int, Expr> pair in _variables)
                                    {
                                        var value = Utils.ToRational(subOptimalModel.Eval(pair.Value, true));
                                        _model.SetValue(pair.Key, value);
                                    }
                                    // Remember all objective values
                                    foreach (var pair in _goals)
                                    {
                                        var optimalValue = Utils.ToRational(pair.Value.Upper);
                                        _model.SetValue(pair.Key.Index, optimalValue);
                                    }
                                    subOptimalModel.Dispose();

                                    setResult(Z3Result.LocalOptimal);
                                }
                                else
                                    setResult(Z3Result.Infeasible);
                            }
                            else
                                setResult(Z3Result.Interrupted);
                            break;
                        default:
                            Debug.Assert(false, "Unrecognized Z3 Status");
                            break;
                    }
                }
            }
            finally
            {
                _isSolving = false;
            }

            // Now kill Z3
            DestructSolver(true);
        }