1 //
2 // Copyright (c) 2015-2017 Benjamin Kaufmann
3 //
4 // This file is part of Potassco.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 // IN THE SOFTWARE.
23 //
24
25 #include <potassco/aspif.h>
26 #include <potassco/aspif_text.h>
27 #include <potassco/convert.h>
28 #include <potassco/application.h>
29 #include <potassco/program_opts/typed_value.h>
30 #include <fstream>
31 #include <iostream>
32 #include <cctype>
33 #include <cstdlib>
34
35 using namespace Potassco::ProgramOptions;
36
37 class LpConvert : public Potassco::Application {
38 public:
getName() const39 virtual const char* getName() const { return "lpconvert"; }
getVersion() const40 virtual const char* getVersion() const { return "1.0.0"; }
getPositional() const41 virtual PosOption getPositional() const { return &positional; }
getUsage() const42 virtual const char* getUsage() const {
43 return
44 "[options] [<file>]\n"
45 "Convert program in <file> or standard input";
46 }
47 virtual void initOptions(OptionContext& root);
validateOptions(const OptionContext &,const ParsedOptions &,const ParsedValues &)48 virtual void validateOptions(const OptionContext&, const ParsedOptions&, const ParsedValues&) {}
setup()49 virtual void setup() {}
50 virtual void run();
printVersion()51 virtual void printVersion() {
52 Potassco::Application::printVersion();
53 printf("libpotassco version %s\n", LIB_POTASSCO_VERSION);
54 printf("Copyright (C) Benjamin Kaufmann\n");
55 printf("License: The MIT License <https://opensource.org/licenses/MIT>\n");
56 fflush(stdout);
57 }
58 private:
positional(const std::string &,std::string & optOut)59 static bool positional(const std::string&, std::string& optOut) {
60 optOut = "input";
61 return true;
62 }
error(int line,const char * what)63 static int error(int line, const char* what) {
64 fprintf(stderr, "*** ERROR: In line %d: %s\n", line, what);
65 static_cast<LpConvert*>(Application::getInstance())->exit(EXIT_FAILURE);
66 return EXIT_FAILURE;
67 }
68 std::string input_;
69 std::string output_;
70 bool potassco_;
71 bool filter_;
72 bool text_;
73 };
74
initOptions(OptionContext & root)75 void LpConvert::initOptions(OptionContext& root) {
76 OptionGroup convert("Conversion Options");
77 convert.addOptions()
78 ("input,i,@2", storeTo(input_), "Input file")
79 ("potassco,p", flag(potassco_ = false), "Enable potassco extensions")
80 ("filter,f" , flag(filter_ = false), "Hide converted potassco predicates")
81 ("output,o" , storeTo(output_)->arg("<file>"), "Write output to <file> (default: stdout)")
82 ("text,t" , flag(text_ = false), "Convert to ground text format")
83 ;
84 root.add(convert);
85 }
run()86 void LpConvert::run() {
87 std::ifstream iFile;
88 std::ofstream oFile;
89 if (!input_.empty() && input_ != "-") {
90 iFile.open(input_.c_str());
91 POTASSCO_EXPECT(iFile.is_open(), "Could not open input file!");
92 }
93 if (!output_.empty() && output_ != "-") {
94 POTASSCO_EXPECT(input_ != output_, "Input and output must be different!");
95 oFile.open(output_.c_str());
96 POTASSCO_EXPECT(oFile.is_open(), "Could not open output file!");
97 }
98 std::istream& in = iFile.is_open() ? iFile : std::cin;
99 std::ostream& os = oFile.is_open() ? oFile : std::cout;
100 Potassco::AspifTextOutput text(os);
101 POTASSCO_EXPECT(in.peek() == 'a' || std::isdigit(in.peek()), "Unrecognized input format!");
102 if (in.peek() == 'a') {
103 Potassco::SmodelsOutput writer(os, potassco_, 0);
104 Potassco::SmodelsConvert smodels(writer, potassco_);
105 Potassco::readAspif(in, !text_ ? static_cast<Potassco::AbstractProgram&>(smodels) : text, &error);
106 }
107 else {
108 Potassco::AspifOutput aspif(os);
109 Potassco::SmodelsInput::Options opts;
110 if (potassco_) {
111 opts.enableClaspExt().convertEdges().convertHeuristic();
112 if (filter_) { opts.dropConverted(); }
113 }
114 Potassco::readSmodels(in, !text_? static_cast<Potassco::AbstractProgram&>(aspif) : text, &error, opts);
115 }
116 iFile.close();
117 oFile.close();
118 }
119
main(int argc,char ** argv)120 int main(int argc, char** argv) {
121 LpConvert app;
122 return app.main(argc, argv);
123 }
124