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