/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Jip J. Dekker */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include #include namespace MiniZinc { class GeasOptions : public SolverInstanceBase::Options { public: bool allSolutions = false; int conflicts = 0; bool freeSearch = false; int nrSolutions = 1; int objProbeLimit = 0; bool statistics = false; std::chrono::milliseconds time = std::chrono::milliseconds(0); }; class GeasVariable { public: enum Type { BOOL_TYPE, FLOAT_TYPE, INT_TYPE }; protected: Type _t; // Type of the variable union { geas::patom_t bv; geas::fp::fpvar fv; geas::intvar iv; }; public: explicit GeasVariable(const geas::patom_t& bv0) : _t(BOOL_TYPE), bv(bv0){}; explicit GeasVariable(const geas::fp::fpvar& fv0) : _t(FLOAT_TYPE), fv(fv0){}; explicit GeasVariable(const geas::intvar& iv0) : _t(INT_TYPE), iv(iv0){}; GeasVariable(const GeasVariable& gv) : _t(gv._t) { switch (_t) { case BOOL_TYPE: bv = gv.bv; break; case FLOAT_TYPE: fv = gv.fv; break; case INT_TYPE: iv = gv.iv; break; } } bool isBool() const { return _t == BOOL_TYPE; } bool isFloat() const { return _t == FLOAT_TYPE; } bool isInt() const { return _t == INT_TYPE; } geas::patom_t boolVar() const { return bv; } geas::fp::fpvar floatVar() const { return fv; } geas::intvar intVar() const { return iv; } }; class GeasTypes { public: typedef GeasVariable Variable; typedef MiniZinc::Statistics Statistics; }; class GeasSolverInstance : public SolverInstanceImpl { public: GeasSolverInstance(Env& env, std::ostream& log, SolverInstanceBase::Options* opt); ~GeasSolverInstance() override = default; void processFlatZinc() override; geas::solver_data* solverData() const { return _solver.data; } geas::solver& solver() { return _solver; } Status solve() override; Status next() override { return SolverInstance::ERROR; } // TODO: Implement void resetSolver() override; Expression* getSolutionValue(Id* id) override; void printStatistics() override; // MiniZinc to Geas conversions bool asBool(Expression* e) { return eval_bool(env().envi(), e); } vec asBool(ArrayLit* al); geas::patom_t asBoolVar(Expression* e); vec asBoolVar(ArrayLit* al); vec asInt(ArrayLit* al); int asInt(Expression* e) { return static_cast(eval_int(env().envi(), e).toInt()); } geas::intvar asIntVar(Expression* e); vec asIntVar(ArrayLit* al); // TODO: create only when necessary or use Geas internal geas::intvar zero; protected: geas::solver _solver; Model* _flat; SolveI::SolveType _objType = SolveI::ST_SAT; std::unique_ptr _objVar; GeasTypes::Variable& resolveVar(Expression* e); bool addSolutionNoGood(); void registerConstraint(const std::string& name, poster p); void registerConstraints(); }; class GeasSolverFactory : public SolverFactory { public: GeasSolverFactory(); SolverInstanceBase::Options* createOptions() override; SolverInstanceBase* doCreateSI(Env& env, std::ostream& log, SolverInstanceBase::Options* opt) override; std::string getDescription(SolverInstanceBase::Options* opt) override { return "Elsie Geas - Another Lazy Clause Generation Solver"; }; std::string getVersion(SolverInstanceBase::Options* opt) override { return "0.0.1"; } std::string getId() override { return "org.minizinc.geas"; } bool processOption(SolverInstanceBase::Options* opt, int& i, std::vector& argv, const std::string& workingDir = std::string()) override; void printHelp(std::ostream& os) override; }; } // namespace MiniZinc