Refactored error handling.
This commit is contained in:
parent
aea640a624
commit
0d8b1e94da
@ -43,10 +43,10 @@ ast::Comparison::Operator translate(Clingo::AST::ComparisonOperator comparisonOp
|
|||||||
struct BodyTermTranslateVisitor
|
struct BodyTermTranslateVisitor
|
||||||
{
|
{
|
||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Function &function, const Clingo::AST::Literal &literal, const Clingo::AST::Term &, Context &context, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Function &function, const Clingo::AST::Literal &literal, const Clingo::AST::Term &, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
if (literal.sign == Clingo::AST::Sign::DoubleNegation)
|
if (literal.sign == Clingo::AST::Sign::DoubleNegation)
|
||||||
throwErrorAtLocation(literal.location, "double-negated literals currently unsupported", context);
|
throw TranslationException(literal.location, "double-negated literals currently unsupported");
|
||||||
|
|
||||||
if (function.arguments.empty())
|
if (function.arguments.empty())
|
||||||
{
|
{
|
||||||
@ -73,7 +73,7 @@ struct BodyTermTranslateVisitor
|
|||||||
for (size_t i = 0; i < function.arguments.size(); i++)
|
for (size_t i = 0; i < function.arguments.size(); i++)
|
||||||
{
|
{
|
||||||
auto &argument = function.arguments[i];
|
auto &argument = function.arguments[i];
|
||||||
conjunction.arguments.emplace_back(ast::Formula::make<ast::In>(ast::Variable(parameters[i].get()), translate(argument, context, ruleContext, variableStack)));
|
conjunction.arguments.emplace_back(ast::Formula::make<ast::In>(ast::Variable(parameters[i].get()), translate(argument, ruleContext, variableStack)));
|
||||||
}
|
}
|
||||||
|
|
||||||
variableStack.pop();
|
variableStack.pop();
|
||||||
@ -93,11 +93,11 @@ struct BodyTermTranslateVisitor
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Literal &, const Clingo::AST::Term &term, Context &context, RuleContext &, ast::VariableStack &)
|
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Literal &, const Clingo::AST::Term &term, RuleContext &, ast::VariableStack &)
|
||||||
{
|
{
|
||||||
assert(!term.data.is<Clingo::AST::Function>());
|
assert(!term.data.is<Clingo::AST::Function>());
|
||||||
|
|
||||||
throwErrorAtLocation(term.location, "term currently unsupported in this context, expected function", context);
|
throw TranslationException(term.location, "term currently unsupported in this context, expected function");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -106,22 +106,22 @@ struct BodyTermTranslateVisitor
|
|||||||
|
|
||||||
struct BodyLiteralTranslateVisitor
|
struct BodyLiteralTranslateVisitor
|
||||||
{
|
{
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Boolean &boolean, const Clingo::AST::Literal &, Context &, RuleContext &, ast::VariableStack &)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Boolean &boolean, const Clingo::AST::Literal &, RuleContext &, ast::VariableStack &)
|
||||||
{
|
{
|
||||||
return ast::Formula::make<ast::Boolean>(boolean.value);
|
return ast::Formula::make<ast::Boolean>(boolean.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Term &term, const Clingo::AST::Literal &literal, Context &context, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Term &term, const Clingo::AST::Literal &literal, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
return term.data.accept(BodyTermTranslateVisitor(), literal, term, context, ruleContext, variableStack);
|
return term.data.accept(BodyTermTranslateVisitor(), literal, term, ruleContext, variableStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Comparison &comparison, const Clingo::AST::Literal &literal, Context &context, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Comparison &comparison, const Clingo::AST::Literal &literal, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
// Comparisons should never have a sign, because these are converted to positive comparisons by clingo
|
// Comparisons should never have a sign, because these are converted to positive comparisons by clingo
|
||||||
if (literal.sign != Clingo::AST::Sign::None)
|
if (literal.sign != Clingo::AST::Sign::None)
|
||||||
throwErrorAtLocation(literal.location, "negated comparisons currently unsupported", context);
|
throw TranslationException(literal.location, "negated comparisons currently unsupported");
|
||||||
|
|
||||||
const auto operator_ = translate(comparison.comparison);
|
const auto operator_ = translate(comparison.comparison);
|
||||||
|
|
||||||
@ -132,17 +132,17 @@ struct BodyLiteralTranslateVisitor
|
|||||||
|
|
||||||
ast::And conjunction;
|
ast::And conjunction;
|
||||||
conjunction.arguments.reserve(3);
|
conjunction.arguments.reserve(3);
|
||||||
conjunction.arguments.emplace_back(ast::Formula::make<ast::In>(ast::Variable(parameters[0].get()), translate(comparison.left, context, ruleContext, variableStack)));
|
conjunction.arguments.emplace_back(ast::Formula::make<ast::In>(ast::Variable(parameters[0].get()), translate(comparison.left, ruleContext, variableStack)));
|
||||||
conjunction.arguments.emplace_back(ast::Formula::make<ast::In>(ast::Variable(parameters[1].get()), translate(comparison.right, context, ruleContext, variableStack)));
|
conjunction.arguments.emplace_back(ast::Formula::make<ast::In>(ast::Variable(parameters[1].get()), translate(comparison.right, ruleContext, variableStack)));
|
||||||
conjunction.arguments.emplace_back(ast::Formula::make<ast::Comparison>(operator_, ast::Variable(parameters[0].get()), ast::Variable(parameters[1].get())));
|
conjunction.arguments.emplace_back(ast::Formula::make<ast::Comparison>(operator_, ast::Variable(parameters[0].get()), ast::Variable(parameters[1].get())));
|
||||||
|
|
||||||
return ast::Formula::make<ast::Exists>(std::move(parameters), std::move(conjunction));
|
return ast::Formula::make<ast::Exists>(std::move(parameters), std::move(conjunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Literal &literal, Context &context, RuleContext &, ast::VariableStack &)
|
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Literal &literal, RuleContext &, ast::VariableStack &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(literal.location, "literal currently unsupported in this context, expected function or term", context);
|
throw TranslationException(literal.location, "literal currently unsupported in this context, expected function or term");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -151,18 +151,18 @@ struct BodyLiteralTranslateVisitor
|
|||||||
|
|
||||||
struct BodyBodyLiteralTranslateVisitor
|
struct BodyBodyLiteralTranslateVisitor
|
||||||
{
|
{
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Literal &literal, const Clingo::AST::BodyLiteral &bodyLiteral, Context &context, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Literal &literal, const Clingo::AST::BodyLiteral &bodyLiteral, RuleContext &ruleContext, ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
if (bodyLiteral.sign != Clingo::AST::Sign::None)
|
if (bodyLiteral.sign != Clingo::AST::Sign::None)
|
||||||
throwErrorAtLocation(bodyLiteral.location, "only positive body literals supported currently", context);
|
throw TranslationException(bodyLiteral.location, "only positive body literals supported currently");
|
||||||
|
|
||||||
return literal.data.accept(BodyLiteralTranslateVisitor(), literal, context, ruleContext, variableStack);
|
return literal.data.accept(BodyLiteralTranslateVisitor(), literal, ruleContext, variableStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::BodyLiteral &bodyLiteral, Context &context, RuleContext &, ast::VariableStack &)
|
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::BodyLiteral &bodyLiteral, RuleContext &, ast::VariableStack &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(bodyLiteral.location, "body literal currently unsupported in this context, expected literal", context);
|
throw TranslationException(bodyLiteral.location, "body literal currently unsupported in this context, expected literal");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
102
include/anthem/Exception.h
Normal file
102
include/anthem/Exception.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#ifndef __ANTHEM__EXCEPTION_H
|
||||||
|
#define __ANTHEM__EXCEPTION_H
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <anthem/Location.h>
|
||||||
|
|
||||||
|
namespace anthem
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Exception
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// TODO: implement stream operators to modify message
|
||||||
|
class Exception: public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Exception() = delete;
|
||||||
|
Exception(const Exception &other) = delete;
|
||||||
|
Exception &operator=(const Exception &other) = delete;
|
||||||
|
Exception(Exception &&other) = default;
|
||||||
|
Exception &operator=(Exception &&other) = default;
|
||||||
|
|
||||||
|
explicit Exception(const Location &location)
|
||||||
|
: Exception(location, "unspecified error")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Exception(const Location &location, const char *message)
|
||||||
|
: Exception(location, static_cast<std::string>(message))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Exception(const Location &location, const std::string &message)
|
||||||
|
: m_location{location},
|
||||||
|
m_message{message},
|
||||||
|
// TODO: refactor
|
||||||
|
m_plainMessage{std::string(m_location.sectionStart) + ":" + std::to_string(m_location.rowStart)
|
||||||
|
+ ":" + std::to_string(m_location.columnStart) + " " + m_message}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Exception() noexcept = default;
|
||||||
|
|
||||||
|
const char *what() const noexcept
|
||||||
|
{
|
||||||
|
return m_plainMessage.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Location &location() const
|
||||||
|
{
|
||||||
|
return m_location;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &message() const
|
||||||
|
{
|
||||||
|
return m_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Location m_location;
|
||||||
|
std::string m_message;
|
||||||
|
std::string m_plainMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class LogicException : public Exception
|
||||||
|
{
|
||||||
|
using Exception::Exception;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TranslationException : public Exception
|
||||||
|
{
|
||||||
|
using Exception::Exception;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class SimplificationException : public Exception
|
||||||
|
{
|
||||||
|
using Exception::Exception;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class CompletionException : public Exception
|
||||||
|
{
|
||||||
|
using Exception::Exception;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -5,6 +5,7 @@
|
|||||||
#include <experimental/optional>
|
#include <experimental/optional>
|
||||||
|
|
||||||
#include <anthem/AST.h>
|
#include <anthem/AST.h>
|
||||||
|
#include <anthem/Exception.h>
|
||||||
#include <anthem/RuleContext.h>
|
#include <anthem/RuleContext.h>
|
||||||
#include <anthem/Utils.h>
|
#include <anthem/Utils.h>
|
||||||
#include <anthem/output/Formatting.h>
|
#include <anthem/output/Formatting.h>
|
||||||
@ -24,10 +25,10 @@ namespace anthem
|
|||||||
|
|
||||||
struct TermCollectFunctionTermsVisitor
|
struct TermCollectFunctionTermsVisitor
|
||||||
{
|
{
|
||||||
void visit(const Clingo::AST::Function &function, const Clingo::AST::Term &term, Context &context, RuleContext &ruleContext)
|
void visit(const Clingo::AST::Function &function, const Clingo::AST::Term &term, RuleContext &ruleContext)
|
||||||
{
|
{
|
||||||
if (function.external)
|
if (function.external)
|
||||||
throwErrorAtLocation(term.location, "external functions currently unsupported", context);
|
throw LogicException(term.location, "external functions currently unsupported");
|
||||||
|
|
||||||
ruleContext.headTerms.reserve(ruleContext.headTerms.size() + function.arguments.size());
|
ruleContext.headTerms.reserve(ruleContext.headTerms.size() + function.arguments.size());
|
||||||
|
|
||||||
@ -36,9 +37,9 @@ struct TermCollectFunctionTermsVisitor
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void visit(const T &, const Clingo::AST::Term &term, Context &context, RuleContext &)
|
void visit(const T &, const Clingo::AST::Term &term, RuleContext &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(term.location, "term currently unsupported in this context, function expected", context);
|
throw LogicException(term.location, "term currently unsupported in this function expected");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,19 +47,19 @@ struct TermCollectFunctionTermsVisitor
|
|||||||
|
|
||||||
struct LiteralCollectFunctionTermsVisitor
|
struct LiteralCollectFunctionTermsVisitor
|
||||||
{
|
{
|
||||||
void visit(const Clingo::AST::Boolean &, const Clingo::AST::Literal &, Context &, RuleContext &)
|
void visit(const Clingo::AST::Boolean &, const Clingo::AST::Literal &, RuleContext &)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::Term &term, const Clingo::AST::Literal &, Context &context, RuleContext &ruleContext)
|
void visit(const Clingo::AST::Term &term, const Clingo::AST::Literal &, RuleContext &ruleContext)
|
||||||
{
|
{
|
||||||
term.data.accept(TermCollectFunctionTermsVisitor(), term, context, ruleContext);
|
term.data.accept(TermCollectFunctionTermsVisitor(), term, ruleContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void visit(const T &, const Clingo::AST::Literal &literal, Context &context, RuleContext &)
|
void visit(const T &, const Clingo::AST::Literal &literal, RuleContext &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(literal.location, "only disjunctions of literals allowed as head literals", context);
|
throw LogicException(literal.location, "only disjunctions of literals allowed as head literals");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,47 +68,47 @@ struct LiteralCollectFunctionTermsVisitor
|
|||||||
// TODO: rename, because not only terms are collected anymore
|
// TODO: rename, because not only terms are collected anymore
|
||||||
struct HeadLiteralCollectFunctionTermsVisitor
|
struct HeadLiteralCollectFunctionTermsVisitor
|
||||||
{
|
{
|
||||||
void visit(const Clingo::AST::Literal &literal, const Clingo::AST::HeadLiteral &, Context &context, RuleContext &ruleContext)
|
void visit(const Clingo::AST::Literal &literal, const Clingo::AST::HeadLiteral &, RuleContext &ruleContext)
|
||||||
{
|
{
|
||||||
ruleContext.numberOfHeadLiterals = 1;
|
ruleContext.numberOfHeadLiterals = 1;
|
||||||
|
|
||||||
literal.data.accept(LiteralCollectFunctionTermsVisitor(), literal, context, ruleContext);
|
literal.data.accept(LiteralCollectFunctionTermsVisitor(), literal, ruleContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::Disjunction &disjunction, const Clingo::AST::HeadLiteral &headLiteral, Context &context, RuleContext &ruleContext)
|
void visit(const Clingo::AST::Disjunction &disjunction, const Clingo::AST::HeadLiteral &headLiteral, RuleContext &ruleContext)
|
||||||
{
|
{
|
||||||
ruleContext.numberOfHeadLiterals = disjunction.elements.size();
|
ruleContext.numberOfHeadLiterals = disjunction.elements.size();
|
||||||
|
|
||||||
for (const auto &conditionalLiteral : disjunction.elements)
|
for (const auto &conditionalLiteral : disjunction.elements)
|
||||||
{
|
{
|
||||||
if (!conditionalLiteral.condition.empty())
|
if (!conditionalLiteral.condition.empty())
|
||||||
throwErrorAtLocation(headLiteral.location, "conditional head literals currently unsupported", context);
|
throw LogicException(headLiteral.location, "conditional head literals currently unsupported");
|
||||||
|
|
||||||
conditionalLiteral.literal.data.accept(LiteralCollectFunctionTermsVisitor(), conditionalLiteral.literal, context, ruleContext);
|
conditionalLiteral.literal.data.accept(LiteralCollectFunctionTermsVisitor(), conditionalLiteral.literal, ruleContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::Aggregate &aggregate, const Clingo::AST::HeadLiteral &headLiteral, Context &context, RuleContext &ruleContext)
|
void visit(const Clingo::AST::Aggregate &aggregate, const Clingo::AST::HeadLiteral &headLiteral, RuleContext &ruleContext)
|
||||||
{
|
{
|
||||||
ruleContext.isChoiceRule = true;
|
ruleContext.isChoiceRule = true;
|
||||||
ruleContext.numberOfHeadLiterals = aggregate.elements.size();
|
ruleContext.numberOfHeadLiterals = aggregate.elements.size();
|
||||||
|
|
||||||
if (aggregate.left_guard || aggregate.right_guard)
|
if (aggregate.left_guard || aggregate.right_guard)
|
||||||
throwErrorAtLocation(headLiteral.location, "aggregates with left or right guards currently unsupported", context);
|
throw LogicException(headLiteral.location, "aggregates with left or right guards currently unsupported");
|
||||||
|
|
||||||
for (const auto &conditionalLiteral : aggregate.elements)
|
for (const auto &conditionalLiteral : aggregate.elements)
|
||||||
{
|
{
|
||||||
if (!conditionalLiteral.condition.empty())
|
if (!conditionalLiteral.condition.empty())
|
||||||
throwErrorAtLocation(headLiteral.location, "conditional literals in aggregates currently unsupported", context);
|
throw LogicException(headLiteral.location, "conditional literals in aggregates currently unsupported");
|
||||||
|
|
||||||
conditionalLiteral.literal.data.accept(LiteralCollectFunctionTermsVisitor(), conditionalLiteral.literal, context, ruleContext);
|
conditionalLiteral.literal.data.accept(LiteralCollectFunctionTermsVisitor(), conditionalLiteral.literal, ruleContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void visit(const T &, const Clingo::AST::HeadLiteral &headLiteral, Context &context, RuleContext &)
|
void visit(const T &, const Clingo::AST::HeadLiteral &headLiteral, RuleContext &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(headLiteral.location, "head literal currently unsupported in this context, expected literal, disjunction, or aggregate", context);
|
throw LogicException(headLiteral.location, "head literal currently unsupported in this expected literal, disjunction, or aggregate");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -118,10 +119,10 @@ struct HeadLiteralCollectFunctionTermsVisitor
|
|||||||
struct FunctionTermTranslateVisitor
|
struct FunctionTermTranslateVisitor
|
||||||
{
|
{
|
||||||
// TODO: check correctness
|
// TODO: check correctness
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Function &function, const Clingo::AST::Term &term, Context &context, RuleContext &ruleContext, size_t &headVariableIndex)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Function &function, const Clingo::AST::Term &term, RuleContext &ruleContext, size_t &headVariableIndex)
|
||||||
{
|
{
|
||||||
if (function.external)
|
if (function.external)
|
||||||
throwErrorAtLocation(term.location, "external functions currently unsupported", context);
|
throw TranslationException(term.location, "external functions currently unsupported");
|
||||||
|
|
||||||
std::vector<ast::Term> arguments;
|
std::vector<ast::Term> arguments;
|
||||||
arguments.reserve(function.arguments.size());
|
arguments.reserve(function.arguments.size());
|
||||||
@ -133,9 +134,9 @@ struct FunctionTermTranslateVisitor
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Term &term, Context &context, RuleContext &, size_t &)
|
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Term &term, RuleContext &, size_t &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(term.location, "term currently unsupported in this context, function expected", context);
|
throw TranslationException(term.location, "term currently unsupported in this function expected");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -144,20 +145,20 @@ struct FunctionTermTranslateVisitor
|
|||||||
|
|
||||||
struct LiteralTranslateVisitor
|
struct LiteralTranslateVisitor
|
||||||
{
|
{
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Boolean &boolean, const Clingo::AST::Literal &, Context &, RuleContext &, size_t &)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Boolean &boolean, const Clingo::AST::Literal &, RuleContext &, size_t &)
|
||||||
{
|
{
|
||||||
return ast::Formula::make<ast::Boolean>(boolean.value);
|
return ast::Formula::make<ast::Boolean>(boolean.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Term &term, const Clingo::AST::Literal &, Context &context, RuleContext &ruleContext, size_t &headVariableIndex)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Term &term, const Clingo::AST::Literal &, RuleContext &ruleContext, size_t &headVariableIndex)
|
||||||
{
|
{
|
||||||
return term.data.accept(FunctionTermTranslateVisitor(), term, context, ruleContext, headVariableIndex);
|
return term.data.accept(FunctionTermTranslateVisitor(), term, ruleContext, headVariableIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Literal &literal, Context &context, RuleContext &, size_t &)
|
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::Literal &literal, RuleContext &, size_t &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(literal.location, "only disjunctions of literals allowed as head literals", context);
|
throw TranslationException(literal.location, "only disjunctions of literals allowed as head literals");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -166,12 +167,12 @@ struct LiteralTranslateVisitor
|
|||||||
|
|
||||||
struct HeadLiteralTranslateToConsequentVisitor
|
struct HeadLiteralTranslateToConsequentVisitor
|
||||||
{
|
{
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Literal &literal, const Clingo::AST::HeadLiteral &, Context &context, RuleContext &ruleContext, size_t &headVariableIndex)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Literal &literal, const Clingo::AST::HeadLiteral &, RuleContext &ruleContext, size_t &headVariableIndex)
|
||||||
{
|
{
|
||||||
if (literal.sign == Clingo::AST::Sign::DoubleNegation)
|
if (literal.sign == Clingo::AST::Sign::DoubleNegation)
|
||||||
throwErrorAtLocation(literal.location, "double-negated head literals currently unsupported", context);
|
throw TranslationException(literal.location, "double-negated head literals currently unsupported");
|
||||||
|
|
||||||
auto translatedLiteral = literal.data.accept(LiteralTranslateVisitor(), literal, context, ruleContext, headVariableIndex);
|
auto translatedLiteral = literal.data.accept(LiteralTranslateVisitor(), literal, ruleContext, headVariableIndex);
|
||||||
|
|
||||||
if (literal.sign == Clingo::AST::Sign::None)
|
if (literal.sign == Clingo::AST::Sign::None)
|
||||||
return translatedLiteral;
|
return translatedLiteral;
|
||||||
@ -182,7 +183,7 @@ struct HeadLiteralTranslateToConsequentVisitor
|
|||||||
return ast::Formula::make<ast::Not>(std::move(translatedLiteral.value()));
|
return ast::Formula::make<ast::Not>(std::move(translatedLiteral.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Disjunction &disjunction, const Clingo::AST::HeadLiteral &headLiteral, Context &context, RuleContext &ruleContext, size_t &headVariableIndex)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Disjunction &disjunction, const Clingo::AST::HeadLiteral &headLiteral, RuleContext &ruleContext, size_t &headVariableIndex)
|
||||||
{
|
{
|
||||||
std::vector<ast::Formula> arguments;
|
std::vector<ast::Formula> arguments;
|
||||||
arguments.reserve(disjunction.elements.size());
|
arguments.reserve(disjunction.elements.size());
|
||||||
@ -190,12 +191,12 @@ struct HeadLiteralTranslateToConsequentVisitor
|
|||||||
for (const auto &conditionalLiteral : disjunction.elements)
|
for (const auto &conditionalLiteral : disjunction.elements)
|
||||||
{
|
{
|
||||||
if (!conditionalLiteral.condition.empty())
|
if (!conditionalLiteral.condition.empty())
|
||||||
throwErrorAtLocation(headLiteral.location, "conditional head literals currently unsupported", context);
|
throw TranslationException(headLiteral.location, "conditional head literals currently unsupported");
|
||||||
|
|
||||||
auto argument = visit(conditionalLiteral.literal, headLiteral, context, ruleContext, headVariableIndex);
|
auto argument = visit(conditionalLiteral.literal, headLiteral, ruleContext, headVariableIndex);
|
||||||
|
|
||||||
if (!argument)
|
if (!argument)
|
||||||
throwErrorAtLocation(headLiteral.location, "could not parse argument", context);
|
throw TranslationException(headLiteral.location, "could not parse argument");
|
||||||
|
|
||||||
arguments.emplace_back(std::move(argument.value()));
|
arguments.emplace_back(std::move(argument.value()));
|
||||||
}
|
}
|
||||||
@ -203,18 +204,18 @@ struct HeadLiteralTranslateToConsequentVisitor
|
|||||||
return ast::Formula::make<ast::Or>(std::move(arguments));
|
return ast::Formula::make<ast::Or>(std::move(arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Aggregate &aggregate, const Clingo::AST::HeadLiteral &headLiteral, Context &context, RuleContext &ruleContext, size_t &headVariableIndex)
|
std::experimental::optional<ast::Formula> visit(const Clingo::AST::Aggregate &aggregate, const Clingo::AST::HeadLiteral &headLiteral, RuleContext &ruleContext, size_t &headVariableIndex)
|
||||||
{
|
{
|
||||||
if (aggregate.left_guard || aggregate.right_guard)
|
if (aggregate.left_guard || aggregate.right_guard)
|
||||||
throwErrorAtLocation(headLiteral.location, "aggregates with left or right guards currently unsupported", context);
|
throw TranslationException(headLiteral.location, "aggregates with left or right guards currently unsupported");
|
||||||
|
|
||||||
const auto translateConditionalLiteral =
|
const auto translateConditionalLiteral =
|
||||||
[&](const auto &conditionalLiteral)
|
[&](const auto &conditionalLiteral)
|
||||||
{
|
{
|
||||||
if (!conditionalLiteral.condition.empty())
|
if (!conditionalLiteral.condition.empty())
|
||||||
throwErrorAtLocation(headLiteral.location, "conditional head literals currently unsupported", context);
|
throw TranslationException(headLiteral.location, "conditional head literals currently unsupported");
|
||||||
|
|
||||||
return this->visit(conditionalLiteral.literal, headLiteral, context, ruleContext, headVariableIndex);
|
return this->visit(conditionalLiteral.literal, headLiteral, ruleContext, headVariableIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (aggregate.elements.size() == 1)
|
if (aggregate.elements.size() == 1)
|
||||||
@ -228,7 +229,7 @@ struct HeadLiteralTranslateToConsequentVisitor
|
|||||||
auto argument = translateConditionalLiteral(conditionalLiteral);
|
auto argument = translateConditionalLiteral(conditionalLiteral);
|
||||||
|
|
||||||
if (!argument)
|
if (!argument)
|
||||||
throwErrorAtLocation(headLiteral.location, "could not parse argument", context);
|
throw TranslationException(headLiteral.location, "could not parse argument");
|
||||||
|
|
||||||
arguments.emplace_back(std::move(argument.value()));
|
arguments.emplace_back(std::move(argument.value()));
|
||||||
}
|
}
|
||||||
@ -237,9 +238,9 @@ struct HeadLiteralTranslateToConsequentVisitor
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::HeadLiteral &headLiteral, Context &context, RuleContext &, size_t &)
|
std::experimental::optional<ast::Formula> visit(const T &, const Clingo::AST::HeadLiteral &headLiteral, RuleContext &, size_t &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(headLiteral.location, "head literal currently unsupported in this context, expected literal, disjunction, or aggregate", context);
|
throw TranslationException(headLiteral.location, "head literal currently unsupported in this expected literal, disjunction, or aggregate");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <clingo.hh>
|
||||||
|
|
||||||
namespace anthem
|
namespace anthem
|
||||||
{
|
{
|
||||||
namespace input
|
|
||||||
{
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -16,6 +16,23 @@ namespace input
|
|||||||
|
|
||||||
struct Location
|
struct Location
|
||||||
{
|
{
|
||||||
|
Location() = default;
|
||||||
|
|
||||||
|
Location(const Clingo::Location &clingoLocation)
|
||||||
|
: sectionStart{clingoLocation.begin_file()},
|
||||||
|
sectionEnd{clingoLocation.end_file()},
|
||||||
|
rowStart{clingoLocation.begin_line()},
|
||||||
|
rowEnd{clingoLocation.end_line()},
|
||||||
|
columnStart{clingoLocation.begin_column()},
|
||||||
|
columnEnd{clingoLocation.end_column()}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Location(const Location &other) = default;
|
||||||
|
Location &operator=(const Location &other) = default;
|
||||||
|
Location(Location &&other) = default;
|
||||||
|
Location &operator=(Location &&other) = default;
|
||||||
|
|
||||||
const char *sectionStart = nullptr;
|
const char *sectionStart = nullptr;
|
||||||
const char *sectionEnd = nullptr;
|
const char *sectionEnd = nullptr;
|
||||||
|
|
||||||
@ -28,7 +45,6 @@ struct Location
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -42,17 +42,17 @@ struct StatementVisitor
|
|||||||
context.logger.log(output::Priority::Debug) << "[program] " << program.name;
|
context.logger.log(output::Priority::Debug) << "[program] " << program.name;
|
||||||
|
|
||||||
if (!program.parameters.empty())
|
if (!program.parameters.empty())
|
||||||
throwErrorAtLocation(statement.location, "program parameters currently unsupported", context);
|
throw LogicException(statement.location, "program parameters currently unsupported");
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::Rule &rule, const Clingo::AST::Statement &, std::vector<ast::ScopedFormula> &scopedFormulas, Context &context)
|
void visit(const Clingo::AST::Rule &rule, const Clingo::AST::Statement &, std::vector<ast::ScopedFormula> &scopedFormulas, Context &)
|
||||||
{
|
{
|
||||||
RuleContext ruleContext;
|
RuleContext ruleContext;
|
||||||
ast::VariableStack variableStack;
|
ast::VariableStack variableStack;
|
||||||
variableStack.push(&ruleContext.freeVariables);
|
variableStack.push(&ruleContext.freeVariables);
|
||||||
|
|
||||||
// Collect all head terms
|
// Collect all head terms
|
||||||
rule.head.data.accept(HeadLiteralCollectFunctionTermsVisitor(), rule.head, context, ruleContext);
|
rule.head.data.accept(HeadLiteralCollectFunctionTermsVisitor(), rule.head, ruleContext);
|
||||||
|
|
||||||
// Create new variable declarations for the head terms
|
// Create new variable declarations for the head terms
|
||||||
ruleContext.headVariablesStartIndex = ruleContext.freeVariables.size();
|
ruleContext.headVariablesStartIndex = ruleContext.freeVariables.size();
|
||||||
@ -68,16 +68,12 @@ struct StatementVisitor
|
|||||||
|
|
||||||
// Compute consequent
|
// Compute consequent
|
||||||
auto headVariableIndex = ruleContext.headVariablesStartIndex;
|
auto headVariableIndex = ruleContext.headVariablesStartIndex;
|
||||||
auto consequent = rule.head.data.accept(HeadLiteralTranslateToConsequentVisitor(), rule.head, context, ruleContext, headVariableIndex);
|
auto consequent = rule.head.data.accept(HeadLiteralTranslateToConsequentVisitor(), rule.head, ruleContext, headVariableIndex);
|
||||||
|
|
||||||
assert(ruleContext.headTerms.size() == headVariableIndex - ruleContext.headVariablesStartIndex);
|
assert(ruleContext.headTerms.size() == headVariableIndex - ruleContext.headVariablesStartIndex);
|
||||||
|
|
||||||
if (!consequent)
|
if (!consequent)
|
||||||
{
|
throw TranslationException(rule.head.location, "could not translate formula consequent");
|
||||||
// TODO: think about throwing an exception instead
|
|
||||||
context.logger.log(output::Priority::Error) << "could not translate formula consequent";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate auxiliary variables replacing the head atom’s arguments
|
// Generate auxiliary variables replacing the head atom’s arguments
|
||||||
for (auto i = ruleContext.headTerms.cbegin(); i != ruleContext.headTerms.cend(); i++)
|
for (auto i = ruleContext.headTerms.cbegin(); i != ruleContext.headTerms.cend(); i++)
|
||||||
@ -86,7 +82,7 @@ struct StatementVisitor
|
|||||||
|
|
||||||
const auto auxiliaryHeadVariableID = ruleContext.headVariablesStartIndex + i - ruleContext.headTerms.cbegin();
|
const auto auxiliaryHeadVariableID = ruleContext.headVariablesStartIndex + i - ruleContext.headTerms.cbegin();
|
||||||
auto element = ast::Variable(ruleContext.freeVariables[auxiliaryHeadVariableID].get());
|
auto element = ast::Variable(ruleContext.freeVariables[auxiliaryHeadVariableID].get());
|
||||||
auto set = translate(headTerm, context, ruleContext, variableStack);
|
auto set = translate(headTerm, ruleContext, variableStack);
|
||||||
auto in = ast::In(std::move(element), std::move(set));
|
auto in = ast::In(std::move(element), std::move(set));
|
||||||
|
|
||||||
antecedent.arguments.emplace_back(std::move(in));
|
antecedent.arguments.emplace_back(std::move(in));
|
||||||
@ -97,10 +93,10 @@ struct StatementVisitor
|
|||||||
{
|
{
|
||||||
const auto &bodyLiteral = *i;
|
const auto &bodyLiteral = *i;
|
||||||
|
|
||||||
auto argument = bodyLiteral.data.accept(BodyBodyLiteralTranslateVisitor(), bodyLiteral, context, ruleContext, variableStack);
|
auto argument = bodyLiteral.data.accept(BodyBodyLiteralTranslateVisitor(), bodyLiteral, ruleContext, variableStack);
|
||||||
|
|
||||||
if (!argument)
|
if (!argument)
|
||||||
throwErrorAtLocation(bodyLiteral.location, "could not translate body literal", context);
|
throw TranslationException(bodyLiteral.location, "could not translate body literal");
|
||||||
|
|
||||||
antecedent.arguments.emplace_back(std::move(argument.value()));
|
antecedent.arguments.emplace_back(std::move(argument.value()));
|
||||||
}
|
}
|
||||||
@ -155,9 +151,9 @@ struct StatementVisitor
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void visit(const T &, const Clingo::AST::Statement &statement, std::vector<ast::ScopedFormula> &, Context &context)
|
void visit(const T &, const Clingo::AST::Statement &statement, std::vector<ast::ScopedFormula> &, Context &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(statement.location, "statement currently unsupported, expected rule", context);
|
throw LogicException(statement.location, "statement currently unsupported, expected rule");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <anthem/AST.h>
|
#include <anthem/AST.h>
|
||||||
#include <anthem/ASTUtils.h>
|
#include <anthem/ASTUtils.h>
|
||||||
|
#include <anthem/Exception.h>
|
||||||
#include <anthem/RuleContext.h>
|
#include <anthem/RuleContext.h>
|
||||||
#include <anthem/Utils.h>
|
#include <anthem/Utils.h>
|
||||||
#include <anthem/output/Formatting.h>
|
#include <anthem/output/Formatting.h>
|
||||||
@ -18,7 +19,7 @@ namespace anthem
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ast::BinaryOperation::Operator translate(Clingo::AST::BinaryOperator binaryOperator, const Clingo::AST::Term &term, Context &context)
|
ast::BinaryOperation::Operator translate(Clingo::AST::BinaryOperator binaryOperator, const Clingo::AST::Term &term)
|
||||||
{
|
{
|
||||||
switch (binaryOperator)
|
switch (binaryOperator)
|
||||||
{
|
{
|
||||||
@ -33,7 +34,7 @@ ast::BinaryOperation::Operator translate(Clingo::AST::BinaryOperator binaryOpera
|
|||||||
case Clingo::AST::BinaryOperator::Modulo:
|
case Clingo::AST::BinaryOperator::Modulo:
|
||||||
return ast::BinaryOperation::Operator::Modulo;
|
return ast::BinaryOperation::Operator::Modulo;
|
||||||
default:
|
default:
|
||||||
throwErrorAtLocation(term.location, "“binary operation” terms currently unsupported", context);
|
throw TranslationException(term.location, "“binary operation” terms currently unsupported");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ast::BinaryOperation::Operator::Plus;
|
return ast::BinaryOperation::Operator::Plus;
|
||||||
@ -41,13 +42,13 @@ ast::BinaryOperation::Operator translate(Clingo::AST::BinaryOperator binaryOpera
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ast::Term translate(const Clingo::AST::Term &term, Context &context, RuleContext &ruleContext, const ast::VariableStack &variableStack);
|
ast::Term translate(const Clingo::AST::Term &term, RuleContext &ruleContext, const ast::VariableStack &variableStack);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct TermTranslateVisitor
|
struct TermTranslateVisitor
|
||||||
{
|
{
|
||||||
std::experimental::optional<ast::Term> visit(const Clingo::Symbol &symbol, const Clingo::AST::Term &term, Context &context, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Term> visit(const Clingo::Symbol &symbol, const Clingo::AST::Term &term, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
switch (symbol.type())
|
switch (symbol.type())
|
||||||
{
|
{
|
||||||
@ -68,10 +69,10 @@ struct TermTranslateVisitor
|
|||||||
|
|
||||||
for (const auto &argument : symbol.arguments())
|
for (const auto &argument : symbol.arguments())
|
||||||
{
|
{
|
||||||
auto translatedArgument = visit(argument, term, context, ruleContext, variableStack);
|
auto translatedArgument = visit(argument, term, ruleContext, variableStack);
|
||||||
|
|
||||||
if (!translatedArgument)
|
if (!translatedArgument)
|
||||||
throwErrorAtLocation(term.location, "could not translate argument", context);
|
throw TranslationException(term.location, "could not translate argument");
|
||||||
|
|
||||||
functionRaw.arguments.emplace_back(std::move(translatedArgument.value()));
|
functionRaw.arguments.emplace_back(std::move(translatedArgument.value()));
|
||||||
}
|
}
|
||||||
@ -83,7 +84,7 @@ struct TermTranslateVisitor
|
|||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Term> visit(const Clingo::AST::Variable &variable, const Clingo::AST::Term &, Context &, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Term> visit(const Clingo::AST::Variable &variable, const Clingo::AST::Term &, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
const auto matchingVariableDeclaration = variableStack.findUserVariableDeclaration(variable.name);
|
const auto matchingVariableDeclaration = variableStack.findUserVariableDeclaration(variable.name);
|
||||||
const auto isAnonymousVariable = (strcmp(variable.name, "_") == 0);
|
const auto isAnonymousVariable = (strcmp(variable.name, "_") == 0);
|
||||||
@ -99,58 +100,58 @@ struct TermTranslateVisitor
|
|||||||
return ast::Term::make<ast::Variable>(ruleContext.freeVariables.back().get());
|
return ast::Term::make<ast::Variable>(ruleContext.freeVariables.back().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Term> visit(const Clingo::AST::UnaryOperation &, const Clingo::AST::Term &term, Context &context, RuleContext &, const ast::VariableStack &)
|
std::experimental::optional<ast::Term> visit(const Clingo::AST::UnaryOperation &, const Clingo::AST::Term &term, RuleContext &, const ast::VariableStack &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(term.location, "“unary operation” terms currently unsupported", context);
|
throw TranslationException(term.location, "“unary operation” terms currently unsupported");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Term> visit(const Clingo::AST::BinaryOperation &binaryOperation, const Clingo::AST::Term &term, Context &context, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Term> visit(const Clingo::AST::BinaryOperation &binaryOperation, const Clingo::AST::Term &term, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
const auto operator_ = translate(binaryOperation.binary_operator, term, context);
|
const auto operator_ = translate(binaryOperation.binary_operator, term);
|
||||||
auto left = translate(binaryOperation.left, context, ruleContext, variableStack);
|
auto left = translate(binaryOperation.left, ruleContext, variableStack);
|
||||||
auto right = translate(binaryOperation.right, context, ruleContext, variableStack);
|
auto right = translate(binaryOperation.right, ruleContext, variableStack);
|
||||||
|
|
||||||
return ast::Term::make<ast::BinaryOperation>(operator_, std::move(left), std::move(right));
|
return ast::Term::make<ast::BinaryOperation>(operator_, std::move(left), std::move(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Term> visit(const Clingo::AST::Interval &interval, const Clingo::AST::Term &, Context &context, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Term> visit(const Clingo::AST::Interval &interval, const Clingo::AST::Term &, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
auto left = translate(interval.left, context, ruleContext, variableStack);
|
auto left = translate(interval.left, ruleContext, variableStack);
|
||||||
auto right = translate(interval.right, context, ruleContext, variableStack);
|
auto right = translate(interval.right, ruleContext, variableStack);
|
||||||
|
|
||||||
return ast::Term::make<ast::Interval>(std::move(left), std::move(right));
|
return ast::Term::make<ast::Interval>(std::move(left), std::move(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Term> visit(const Clingo::AST::Function &function, const Clingo::AST::Term &term, Context &context, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
std::experimental::optional<ast::Term> visit(const Clingo::AST::Function &function, const Clingo::AST::Term &term, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
if (function.external)
|
if (function.external)
|
||||||
throwErrorAtLocation(term.location, "external functions currently unsupported", context);
|
throw TranslationException(term.location, "external functions currently unsupported");
|
||||||
|
|
||||||
std::vector<ast::Term> arguments;
|
std::vector<ast::Term> arguments;
|
||||||
arguments.reserve(function.arguments.size());
|
arguments.reserve(function.arguments.size());
|
||||||
|
|
||||||
for (const auto &argument : function.arguments)
|
for (const auto &argument : function.arguments)
|
||||||
arguments.emplace_back(translate(argument, context, ruleContext, variableStack));
|
arguments.emplace_back(translate(argument, ruleContext, variableStack));
|
||||||
|
|
||||||
return ast::Term::make<ast::Function>(function.name, std::move(arguments));
|
return ast::Term::make<ast::Function>(function.name, std::move(arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::experimental::optional<ast::Term> visit(const Clingo::AST::Pool &, const Clingo::AST::Term &term, Context &context, RuleContext &, const ast::VariableStack &)
|
std::experimental::optional<ast::Term> visit(const Clingo::AST::Pool &, const Clingo::AST::Term &term, RuleContext &, const ast::VariableStack &)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(term.location, "“pool” terms currently unsupported", context);
|
throw TranslationException(term.location, "“pool” terms currently unsupported");
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ast::Term translate(const Clingo::AST::Term &term, Context &context, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
ast::Term translate(const Clingo::AST::Term &term, RuleContext &ruleContext, const ast::VariableStack &variableStack)
|
||||||
{
|
{
|
||||||
auto translatedTerm = term.data.accept(TermTranslateVisitor(), term, context, ruleContext, variableStack);
|
auto translatedTerm = term.data.accept(TermTranslateVisitor(), term, ruleContext, variableStack);
|
||||||
|
|
||||||
if (!translatedTerm)
|
if (!translatedTerm)
|
||||||
throwErrorAtLocation(term.location, "could not translate term", context);
|
throw TranslationException(term.location, "could not translate term");
|
||||||
|
|
||||||
return std::move(translatedTerm.value());
|
return std::move(translatedTerm.value());
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <clingo.hh>
|
#include <clingo.hh>
|
||||||
|
|
||||||
#include <anthem/Context.h>
|
#include <anthem/Context.h>
|
||||||
#include <anthem/input/Location.h>
|
#include <anthem/Location.h>
|
||||||
|
|
||||||
namespace anthem
|
namespace anthem
|
||||||
{
|
{
|
||||||
@ -17,34 +17,6 @@ namespace anthem
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class T1, class T2>
|
|
||||||
T1 location_cast(const T2 &location);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline input::Location location_cast(const Clingo::Location &location)
|
|
||||||
{
|
|
||||||
return {location.begin_file(), location.end_file(), location.begin_line(), location.end_line(),
|
|
||||||
location.begin_column(), location.end_column()};
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
inline void throwErrorAtLocation(const Clingo::Location &clingoLocation, const char *errorMessage,
|
|
||||||
Context &context)
|
|
||||||
{
|
|
||||||
const auto location = location_cast<input::Location>(clingoLocation);
|
|
||||||
|
|
||||||
// TODO: think about removing this to avoid double error messages
|
|
||||||
context.logger.log(output::Priority::Error, location) << errorMessage;
|
|
||||||
|
|
||||||
throw std::runtime_error(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool isPrefix(const char *prefix, const char *string)
|
inline bool isPrefix(const char *prefix, const char *string)
|
||||||
{
|
{
|
||||||
const auto prefixLength = std::strlen(prefix);
|
const auto prefixLength = std::strlen(prefix);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <anthem/input/Location.h>
|
#include <anthem/Location.h>
|
||||||
#include <anthem/output/ColorStream.h>
|
#include <anthem/output/ColorStream.h>
|
||||||
#include <anthem/output/FormatScope.h>
|
#include <anthem/output/FormatScope.h>
|
||||||
#include <anthem/output/Priority.h>
|
#include <anthem/output/Priority.h>
|
||||||
@ -34,7 +34,7 @@ class Logger
|
|||||||
void setColorPolicy(ColorStream::ColorPolicy colorPolicy);
|
void setColorPolicy(ColorStream::ColorPolicy colorPolicy);
|
||||||
|
|
||||||
FormatScope log(Priority priority);
|
FormatScope log(Priority priority);
|
||||||
FormatScope log(Priority priority, const input::Location &location);
|
FormatScope log(Priority priority, const Location &location);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ColorStream m_outputStream;
|
ColorStream m_outputStream;
|
||||||
|
@ -3,9 +3,6 @@ set(target anthem)
|
|||||||
file(GLOB core_sources "anthem/*.cpp")
|
file(GLOB core_sources "anthem/*.cpp")
|
||||||
file(GLOB core_headers "../include/anthem/*.h")
|
file(GLOB core_headers "../include/anthem/*.h")
|
||||||
|
|
||||||
file(GLOB input_sources "anthem/input/*.cpp")
|
|
||||||
file(GLOB input_headers "../include/anthem/input/*.h")
|
|
||||||
|
|
||||||
file(GLOB output_sources "anthem/output/*.cpp")
|
file(GLOB output_sources "anthem/output/*.cpp")
|
||||||
file(GLOB output_headers "../include/anthem/output/*.h")
|
file(GLOB output_headers "../include/anthem/output/*.h")
|
||||||
|
|
||||||
@ -13,9 +10,6 @@ set(sources
|
|||||||
${core_sources}
|
${core_sources}
|
||||||
${core_headers}
|
${core_headers}
|
||||||
|
|
||||||
${input_sources}
|
|
||||||
${input_headers}
|
|
||||||
|
|
||||||
${output_sources}
|
${output_sources}
|
||||||
${output_headers}
|
${output_headers}
|
||||||
)
|
)
|
||||||
|
@ -110,7 +110,7 @@ FormatScope Logger::log(Priority priority)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
FormatScope Logger::log(Priority priority, const input::Location &location)
|
FormatScope Logger::log(Priority priority, const Location &location)
|
||||||
{
|
{
|
||||||
const auto priorityID = static_cast<int>(priority);
|
const auto priorityID = static_cast<int>(priority);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
std::stringstream errors;
|
std::stringstream errors;
|
||||||
|
|
||||||
anthem::output::Logger logger(output, errors);
|
anthem::output::Logger logger(output, errors);
|
||||||
anthem::Context context = {logger, {}};
|
anthem::Context context(std::move(logger));
|
||||||
context.simplify = true;
|
context.simplify = true;
|
||||||
context.complete = true;
|
context.complete = true;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user