Skip to content

Commit

Permalink
Merge pull request #487 from potassco/reduce-option-duplication
Browse files Browse the repository at this point in the history
Reduce duplication in gringo options.
  • Loading branch information
rkaminsk authored Feb 23, 2024
2 parents 036ea9d + 3ea8796 commit d84c400
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 322 deletions.
2 changes: 2 additions & 0 deletions libclingo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ set(header-group-clingo
"${CMAKE_CURRENT_SOURCE_DIR}/clingo/clingo_app.hh"
"${CMAKE_CURRENT_SOURCE_DIR}/clingo/clingocontrol.hh"
"${CMAKE_CURRENT_SOURCE_DIR}/clingo/control.hh"
"${CMAKE_CURRENT_SOURCE_DIR}/clingo/gringo_options.hh"
"${CMAKE_CURRENT_SOURCE_DIR}/clingo/incmode.hh"
"${CMAKE_CURRENT_SOURCE_DIR}/clingo/scripts.hh")
source_group("${ide_header_group}\\clingo" FILES ${header-group-clingo})
Expand All @@ -28,6 +29,7 @@ set(source-group
"${CMAKE_CURRENT_SOURCE_DIR}/src/clingocontrol.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/control.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gringo_app.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gringo_options.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/incmode.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/scripts.cc")
source_group("${ide_source_group}" FILES ${source-group})
Expand Down
79 changes: 2 additions & 77 deletions libclingo/clingo/clingocontrol.hh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "clingo.h"
#include <potassco/basic_types.h>
#include <clingo/control.hh>
#include <clingo/gringo_options.hh>
#include <clingo/scripts.hh>
#include <clingo/astv2.hh>
#include <gringo/output/output.hh>
Expand All @@ -42,7 +43,6 @@
#include <clasp/clingo.h>
#include <clasp/cli/clasp_options.h>
#include <potassco/application.h>
#include <potassco/string_convert.h>
#include <mutex>
#include <cstdlib>

Expand Down Expand Up @@ -82,81 +82,7 @@ private:
};

// {{{1 declaration of ClingoOptions

struct ClingoOptions {
using SigVec = std::vector<Sig>;
std::vector<std::string> defines;
Output::OutputOptions outputOptions;
Output::OutputFormat outputFormat = Output::OutputFormat::INTERMEDIATE;
bool verbose = false;
bool wNoOperationUndefined = false;
bool wNoAtomUndef = false;
bool wNoFileIncluded = false;
bool wNoGlobalVariable = false;
bool wNoOther = false;
bool rewriteMinimize = false;
bool keepFacts = false;
bool singleShot = false;
SigVec sigvec;
};

inline void enableAll(ClingoOptions& out, bool enable) {
out.wNoAtomUndef = !enable;
out.wNoFileIncluded = !enable;
out.wNoOperationUndefined = !enable;
out.wNoGlobalVariable = !enable;
out.wNoOther = !enable;
}

inline bool parseWarning(const std::string& str, ClingoOptions& out) {
if (str == "none") { enableAll(out, false); return true; }
if (str == "all") { enableAll(out, true); return true; }
if (str == "no-atom-undefined") { out.wNoAtomUndef = true; return true; }
if (str == "atom-undefined") { out.wNoAtomUndef = false; return true; }
if (str == "no-file-included") { out.wNoFileIncluded = true; return true; }
if (str == "file-included") { out.wNoFileIncluded = false; return true; }
if (str == "no-operation-undefined") { out.wNoOperationUndefined = true; return true; }
if (str == "operation-undefined") { out.wNoOperationUndefined = false; return true; }
if (str == "no-global-variable") { out.wNoGlobalVariable = true; return true; }
if (str == "global-variable") { out.wNoGlobalVariable = false; return true; }
if (str == "no-other") { out.wNoOther = true; return true; }
if (str == "other") { out.wNoOther = false; return true; }
return false;
}

inline bool parsePreserveFacts(const std::string& str, ClingoOptions& out) {
if (str == "none") { out.keepFacts = false; out.outputOptions.preserveFacts = false; return true; }
if (str == "body") { out.keepFacts = true; out.outputOptions.preserveFacts = false; return true; }
if (str == "symtab") { out.keepFacts = false; out.outputOptions.preserveFacts = true; return true; }
if (str == "all") { out.keepFacts = true; out.outputOptions.preserveFacts = true; return true; }
return false;
}

inline std::vector<std::string> split(std::string const &source, char const *delimiter = " ", bool keepEmpty = false) {
std::vector<std::string> results;
size_t prev = 0;
size_t next = 0;
while ((next = source.find_first_of(delimiter, prev)) != std::string::npos) {
if (keepEmpty || (next - prev != 0)) { results.push_back(source.substr(prev, next - prev)); }
prev = next + 1;
}
if (prev < source.size()) { results.push_back(source.substr(prev)); }
return results;
}

inline bool parseSigVec(const std::string& str, ClingoOptions::SigVec& sigvec) {
for (auto &x : split(str, ",")) {
auto y = split(x, "/");
if (y.size() != 2) { return false; }
unsigned a;
if (!Potassco::string_cast<unsigned>(y[1], a)) { return false; }
bool sign = !y[0].empty() && y[0][0] == '-';
if (sign) { y[0] = y[0].substr(1); }
sigvec.emplace_back(y[0].c_str(), a, sign);
}
return true;
}

using ClingoOptions = GringoOptions;
// {{{1 declaration of ClingoControl

class ClingoPropagatorLock : public Clasp::ClingoPropagatorLock {
Expand Down Expand Up @@ -271,7 +197,6 @@ public:
ClingoControl(Scripts &scripts, bool clingoMode, Clasp::ClaspFacade *clasp, Clasp::Cli::ClaspCliConfig &claspConfig, PostGroundFunc pgf, PreSolveFunc psf, Logger::Printer printer, unsigned messageLimit);
~ClingoControl() noexcept override;
void prepare(Assumptions ass);
void commitExternals();
void parse();
void parse(const StringVec& files, const ClingoOptions& opts, Clasp::Asp::LogicProgram* out, bool addStdIn = true);
void main(IClingoApp &app, StringVec const &files, const ClingoOptions& opts, Clasp::Asp::LogicProgram* out);
Expand Down
56 changes: 56 additions & 0 deletions libclingo/clingo/gringo_options.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// {{{ MIT License

// Copyright 2024

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// }}}

#ifndef CLINGO_GRINGO_OPTIONS_HH
#define CLINGO_GRINGO_OPTIONS_HH

#include <gringo/output/output.hh>
#include <gringo/output/statements.hh>
#include <potassco/program_opts/program_options.h>
#include <vector>
namespace Gringo {

struct GringoOptions {
enum class AppType {Gringo, Clingo, Lib};
using SigVec = std::vector<Sig>;
std::vector<std::string> defines;
Output::OutputOptions outputOptions;
Output::OutputFormat outputFormat = Output::OutputFormat::INTERMEDIATE;
bool verbose = false;
bool wNoOperationUndefined = false;
bool wNoAtomUndef = false;
bool wNoFileIncluded = false;
bool wNoGlobalVariable = false;
bool wNoOther = false;
bool rewriteMinimize = false;
bool keepFacts = false;
bool singleShot = false;
SigVec sigvec;
};

void registerOptions(Potassco::ProgramOptions::OptionGroup& group, GringoOptions& opts, GringoOptions::AppType type);

} // namespace Gringo

#endif // CLINGO_GRINGO_OPTIONS_HH
58 changes: 1 addition & 57 deletions libclingo/src/clingo_app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,68 +33,12 @@ namespace Gringo {
ClingoApp::ClingoApp(UIClingoApp app)
: app_{std::move(app)} { }

static bool parseConst(const std::string& str, std::vector<std::string>& out) {
out.push_back(str);
return true;
}

static bool parseText(const std::string&, ClingoOptions& out) {
out.outputFormat = Gringo::Output::OutputFormat::TEXT;
return true;
}

void ClingoApp::initOptions(Potassco::ProgramOptions::OptionContext& root) {
using namespace Potassco::ProgramOptions;
BaseType::initOptions(root);
grOpts_.defines.clear();
grOpts_.verbose = false;
OptionGroup gringo("Gringo Options");
gringo.addOptions()
("text", storeTo(grOpts_, parseText)->flag(), "Print plain text format")
("const,c", storeTo(grOpts_.defines, parseConst)->composing()->arg("<id>=<term>"), "Replace term occurrences of <id> with <term>")
("output,o,@1", storeTo(grOpts_.outputFormat = Gringo::Output::OutputFormat::INTERMEDIATE, values<Gringo::Output::OutputFormat>()
("intermediate", Gringo::Output::OutputFormat::INTERMEDIATE)
("text", Gringo::Output::OutputFormat::TEXT)
("reify", Gringo::Output::OutputFormat::REIFY)
("smodels", Gringo::Output::OutputFormat::SMODELS)), "Choose output format:\n"
" intermediate: print intermediate format\n"
" text : print plain text format\n"
" reify : print program as reified facts\n"
" smodels : print smodels format\n"
" (only supports basic features)")
("output-debug,@1", storeTo(grOpts_.outputOptions.debug = Gringo::Output::OutputDebug::NONE, values<Gringo::Output::OutputDebug>()
("none", Gringo::Output::OutputDebug::NONE)
("text", Gringo::Output::OutputDebug::TEXT)
("translate", Gringo::Output::OutputDebug::TRANSLATE)
("all", Gringo::Output::OutputDebug::ALL)), "Print debug information during output:\n"
" none : no additional info\n"
" text : print rules as plain text (prefix %%)\n"
" translate: print translated rules as plain text (prefix %%%%)\n"
" all : combines text and translate")
("warn,W,@1" , storeTo(grOpts_, parseWarning)->arg("<warn>")->composing(), "Enable/disable warnings:\n"
" none : disable all warnings\n"
" all : enable all warnings\n"
" [no-]atom-undefined : a :- b.\n"
" [no-]file-included : #include \"a.lp\". #include \"a.lp\".\n"
" [no-]operation-undefined: p(1/0).\n"
" [no-]global-variable : :- #count { X } = 1, X = 1.\n"
" [no-]other : clasp related and uncategorized warnings")
("rewrite-minimize,@1" , flag(grOpts_.rewriteMinimize = false), "Rewrite minimize constraints into rules")
// for backward compatibility
("keep-facts,@3" , flag(grOpts_.keepFacts = false), "Do not remove facts from normal rules")
("preserve-facts,@1" , storeTo(grOpts_, parsePreserveFacts),
"Preserve facts in output:\n"
" none : do not preserve\n"
" body : do not preserve\n"
" symtab: do not preserve\n"
" all : preserve all facts")
("reify-sccs,@1" , flag(grOpts_.outputOptions.reifySCCs = false), "Calculate SCCs for reified output")
("reify-steps,@1" , flag(grOpts_.outputOptions.reifySteps = false), "Add step numbers to reified output")
("show-preds,@1" , storeTo(grOpts_.sigvec, parseSigVec), "Show the given signatures")
("single-shot,@2" , flag(grOpts_.singleShot = false), "Force single-shot solving mode")
;
registerOptions(gringo, grOpts_, GringoOptions::AppType::Clingo);
root.add(gringo);

OptionGroup basic("Basic Options");
basic.addOptions()
("mode", storeTo(mode_ = mode_clingo, values<Mode>()
Expand Down
43 changes: 1 addition & 42 deletions libclingo/src/clingocontrol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -899,51 +899,10 @@ ClingoLib::ClingoLib(Scripts &scripts, int argc, char const * const *argv, Logge
parse({}, grOpts_, lp, false);
}


static bool parseConst(const std::string& str, std::vector<std::string>& out) {
out.push_back(str);
return true;
}

void ClingoLib::initOptions(Potassco::ProgramOptions::OptionContext& root) {
using namespace Potassco::ProgramOptions;
grOpts_.defines.clear();
grOpts_.verbose = false;
OptionGroup gringo("Gringo Options");
gringo.addOptions()
("verbose,V" , flag(grOpts_.verbose = false), "Enable verbose output")
("const,c" , storeTo(grOpts_.defines, parseConst)->composing()->arg("<id>=<term>"), "Replace term occurrences of <id> with <term>")
("output-debug" , storeTo(grOpts_.outputOptions.debug = Output::OutputDebug::NONE, values<Output::OutputDebug>()
("none", Output::OutputDebug::NONE)
("text", Output::OutputDebug::TEXT)
("translate", Output::OutputDebug::TRANSLATE)
("all", Output::OutputDebug::ALL)),
"Print debug information during output:\n"
" none : no additional info\n"
" text : print rules as plain text (prefix %%)\n"
" translate: print translated rules as plain text (prefix %%%%)\n"
" all : combines text and translate")
("warn,W" , storeTo(grOpts_, parseWarning)->arg("<warn>")->composing(),
"Enable/disable warnings:\n"
" none : disable all warnings\n"
" all : enable all warnings\n"
" [no-]atom-undefined : a :- b.\n"
" [no-]file-included : #include \"a.lp\". #include \"a.lp\".\n"
" [no-]operation-undefined: p(1/0).\n"
" [no-]global-variable : :- #count { X } = 1, X = 1.\n"
" [no-]other : clasp related and uncategorized warnings")
("rewrite-minimize" , flag(grOpts_.rewriteMinimize = false), "Rewrite minimize constraints into rules")
// for backward compatibility
("keep-facts" , flag(grOpts_.keepFacts = false), "Preserve facts in rule bodies")
("preserve-facts" , storeTo(grOpts_, parsePreserveFacts),
"Preserve facts in output:\n"
" none : do not preserve\n"
" body : do not preserve\n"
" symtab: do not preserve\n"
" all : preserve all facts")
("single-shot" , flag(grOpts_.singleShot = false), "Force single-shot solving mode")
("show-preds" , storeTo(grOpts_.sigvec, parseSigVec), "Show the given signatures")
;
registerOptions(gringo, grOpts_, GringoOptions::AppType::Lib);
root.add(gringo);
claspConfig_.addOptions(root);
}
Expand Down
Loading

0 comments on commit d84c400

Please sign in to comment.