2016-11-22 03:15:52 +01:00
|
|
|
#include <anthem/Translation.h>
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
#include <clingo.hh>
|
|
|
|
|
2017-04-05 18:21:38 +02:00
|
|
|
#include <anthem/Completion.h>
|
2016-11-24 00:52:28 +01:00
|
|
|
#include <anthem/Context.h>
|
2017-03-16 15:45:55 +01:00
|
|
|
#include <anthem/Simplification.h>
|
2016-11-22 03:15:52 +01:00
|
|
|
#include <anthem/StatementVisitor.h>
|
2017-03-15 16:00:00 +01:00
|
|
|
#include <anthem/output/AST.h>
|
2016-11-22 03:15:52 +01:00
|
|
|
|
|
|
|
namespace anthem
|
|
|
|
{
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Translation
|
|
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-11-24 02:42:32 +01:00
|
|
|
void translate(const std::vector<std::string> &fileNames, Context &context)
|
2016-11-22 03:15:52 +01:00
|
|
|
{
|
|
|
|
for (const auto &fileName : fileNames)
|
|
|
|
{
|
|
|
|
std::ifstream file(fileName, std::ios::in);
|
|
|
|
|
2017-06-01 03:29:09 +02:00
|
|
|
if (!file.is_open())
|
|
|
|
throw LogicException("could not read file “" + fileName + "”");
|
|
|
|
|
2016-11-24 02:42:32 +01:00
|
|
|
translate(fileName.c_str(), file, context);
|
2016-11-22 03:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-11-24 02:42:32 +01:00
|
|
|
void translate(const char *fileName, std::istream &stream, Context &context)
|
2016-11-22 03:15:52 +01:00
|
|
|
{
|
2017-05-30 17:19:26 +02:00
|
|
|
context.logger.log(output::Priority::Info) << "reading " << fileName;
|
2016-11-22 03:15:52 +01:00
|
|
|
|
|
|
|
auto fileContent = std::string(std::istreambuf_iterator<char>(stream), {});
|
|
|
|
|
2017-05-30 03:53:51 +02:00
|
|
|
std::vector<ast::ScopedFormula> scopedFormulas;
|
2017-03-23 01:23:17 +01:00
|
|
|
|
|
|
|
const auto translateStatement =
|
2017-05-30 03:53:51 +02:00
|
|
|
[&scopedFormulas, &context](const Clingo::AST::Statement &statement)
|
2017-03-23 01:23:17 +01:00
|
|
|
{
|
2017-05-30 03:53:51 +02:00
|
|
|
statement.data.accept(StatementVisitor(), statement, scopedFormulas, context);
|
2016-11-22 03:15:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const auto logger =
|
2016-11-29 02:15:28 +01:00
|
|
|
[&context](const Clingo::WarningCode, const char *text)
|
2016-11-22 03:15:52 +01:00
|
|
|
{
|
2017-05-30 17:19:26 +02:00
|
|
|
context.logger.log(output::Priority::Error) << text;
|
2016-11-22 03:15:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Clingo::parse_program(fileContent.c_str(), translateStatement, logger);
|
2017-04-05 18:15:42 +02:00
|
|
|
|
2017-06-06 02:02:26 +02:00
|
|
|
ast::PrintContext printContext(context);
|
2017-05-30 03:53:51 +02:00
|
|
|
|
2017-06-06 01:44:44 +02:00
|
|
|
if (!context.performCompletion)
|
2017-06-01 02:37:45 +02:00
|
|
|
{
|
2017-06-12 02:21:16 +02:00
|
|
|
// Simplify output if specified
|
|
|
|
if (context.performSimplification)
|
|
|
|
for (auto &scopedFormula : scopedFormulas)
|
|
|
|
simplify(scopedFormula.formula);
|
|
|
|
|
2018-04-13 20:40:40 +02:00
|
|
|
if (context.showStatementsUsed)
|
2017-06-05 04:24:00 +02:00
|
|
|
context.logger.log(output::Priority::Warning) << "#show statements are ignored because completion is not enabled";
|
|
|
|
|
2018-04-13 20:40:40 +02:00
|
|
|
if (context.externalStatementsUsed)
|
2018-04-05 23:22:25 +02:00
|
|
|
context.logger.log(output::Priority::Warning) << "#external statements are ignored because completion is not enabled";
|
|
|
|
|
2017-06-01 02:37:45 +02:00
|
|
|
for (const auto &scopedFormula : scopedFormulas)
|
|
|
|
{
|
|
|
|
ast::print(context.logger.outputStream(), scopedFormula.formula, printContext);
|
|
|
|
context.logger.outputStream() << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-12 02:21:16 +02:00
|
|
|
// Perform completion
|
2017-06-05 02:50:30 +02:00
|
|
|
auto completedFormulas = complete(std::move(scopedFormulas), context);
|
2017-06-01 02:37:45 +02:00
|
|
|
|
2018-04-13 20:40:40 +02:00
|
|
|
for (const auto &predicateDeclaration : context.predicateDeclarations)
|
|
|
|
{
|
|
|
|
if (predicateDeclaration->isUsed)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Check for #show statements with undeclared predicates
|
|
|
|
if (predicateDeclaration->visibility != ast::PredicateDeclaration::Visibility::Default)
|
|
|
|
context.logger.log(output::Priority::Warning)
|
|
|
|
<< "#show declaration of “"
|
|
|
|
<< predicateDeclaration->name
|
|
|
|
<< "/"
|
2018-04-19 16:35:37 +02:00
|
|
|
<< predicateDeclaration->arity()
|
2018-04-13 20:40:40 +02:00
|
|
|
<< "” does not match any declared predicate";
|
|
|
|
|
|
|
|
// Check for #external statements with undeclared predicates
|
|
|
|
if (predicateDeclaration->isExternal && !predicateDeclaration->isUsed)
|
|
|
|
context.logger.log(output::Priority::Warning)
|
|
|
|
<< "#external declaration of “"
|
|
|
|
<< predicateDeclaration->name
|
|
|
|
<< "/"
|
2018-04-19 16:35:37 +02:00
|
|
|
<< predicateDeclaration->arity()
|
2018-04-13 20:40:40 +02:00
|
|
|
<< "” does not match any declared predicate";
|
|
|
|
}
|
2018-04-05 23:22:25 +02:00
|
|
|
|
2017-06-12 02:21:16 +02:00
|
|
|
// Simplify output if specified
|
2017-06-06 01:44:44 +02:00
|
|
|
if (context.performSimplification)
|
2017-06-04 14:36:09 +02:00
|
|
|
for (auto &completedFormula : completedFormulas)
|
|
|
|
simplify(completedFormula);
|
|
|
|
|
|
|
|
// TODO: remove variables that are not referenced after simplification
|
|
|
|
|
2017-06-01 02:37:45 +02:00
|
|
|
for (const auto &completedFormula : completedFormulas)
|
2017-05-30 03:53:51 +02:00
|
|
|
{
|
2017-06-01 02:37:45 +02:00
|
|
|
ast::print(context.logger.outputStream(), completedFormula, printContext);
|
2017-05-30 03:53:51 +02:00
|
|
|
context.logger.outputStream() << std::endl;
|
|
|
|
}
|
2016-11-22 03:15:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
}
|