Started implementing output simplifications.

This commit is contained in:
Patrick Lühne 2017-03-16 15:45:55 +01:00
parent f85236955f
commit fc538eb7fc
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
6 changed files with 185 additions and 26 deletions

View File

@ -16,6 +16,7 @@ int main(int argc, char **argv)
("help,h", "Display this help message") ("help,h", "Display this help message")
("version,v", "Display version information") ("version,v", "Display version information")
("input,i", po::value<std::vector<std::string>>(), "Input files") ("input,i", po::value<std::vector<std::string>>(), "Input files")
("simplify,s", po::bool_switch(&context.simplify), "Simplify the output")
("color,c", po::value<std::string>()->default_value("auto"), "Colorize output (always, never, auto)") ("color,c", po::value<std::string>()->default_value("auto"), "Colorize output (always, never, auto)")
("log-priority,p", po::value<std::string>()->default_value("warning"), "Log messages starting from this priority (debug, info, warning, error)"); ("log-priority,p", po::value<std::string>()->default_value("warning"), "Log messages starting from this priority (debug, info, warning, error)");

View File

@ -397,168 +397,168 @@ const auto deepCopyVariantVector =
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
BinaryOperation deepCopy(const BinaryOperation &other) inline BinaryOperation deepCopy(const BinaryOperation &other)
{ {
return BinaryOperation(other.operator_, deepCopy(other.left), deepCopy(other.right)); return BinaryOperation(other.operator_, deepCopy(other.left), deepCopy(other.right));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Boolean deepCopy(const Boolean &other) inline Boolean deepCopy(const Boolean &other)
{ {
return Boolean(other.value); return Boolean(other.value);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Comparison deepCopy(const Comparison &other) inline Comparison deepCopy(const Comparison &other)
{ {
return Comparison(other.operator_, deepCopy(other.left), deepCopy(other.right)); return Comparison(other.operator_, deepCopy(other.left), deepCopy(other.right));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Constant deepCopy(const Constant &other) inline Constant deepCopy(const Constant &other)
{ {
return Constant(std::string(other.name)); return Constant(std::string(other.name));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Function deepCopy(const Function &other) inline Function deepCopy(const Function &other)
{ {
return Function(std::string(other.name), deepCopy(other.arguments)); return Function(std::string(other.name), deepCopy(other.arguments));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Integer deepCopy(const Integer &other) inline Integer deepCopy(const Integer &other)
{ {
return Integer(other.value); return Integer(other.value);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Interval deepCopy(const Interval &other) inline Interval deepCopy(const Interval &other)
{ {
return Interval(deepCopy(other.from), deepCopy(other.to)); return Interval(deepCopy(other.from), deepCopy(other.to));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Predicate deepCopy(const Predicate &other) inline Predicate deepCopy(const Predicate &other)
{ {
return Predicate(std::string(other.name), deepCopy(other.arguments)); return Predicate(std::string(other.name), deepCopy(other.arguments));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
SpecialInteger deepCopy(const SpecialInteger &other) inline SpecialInteger deepCopy(const SpecialInteger &other)
{ {
return SpecialInteger(other.type); return SpecialInteger(other.type);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
String deepCopy(const String &other) inline String deepCopy(const String &other)
{ {
return String(std::string(other.text)); return String(std::string(other.text));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Variable deepCopy(const Variable &other) inline Variable deepCopy(const Variable &other)
{ {
return Variable(std::string(other.name), other.type); return Variable(std::string(other.name), other.type);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<VariablePointer> deepCopy(const std::vector<VariablePointer> &other) inline std::vector<VariablePointer> deepCopy(const std::vector<VariablePointer> &other)
{ {
return deepCopyUniquePtrVector(other); return deepCopyUniquePtrVector(other);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
And deepCopy(const And &other) inline And deepCopy(const And &other)
{ {
return And(deepCopy(other.arguments)); return And(deepCopy(other.arguments));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Biconditional deepCopy(const Biconditional &other) inline Biconditional deepCopy(const Biconditional &other)
{ {
return Biconditional(deepCopy(other.left), deepCopy(other.right)); return Biconditional(deepCopy(other.left), deepCopy(other.right));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Exists deepCopy(const Exists &other) inline Exists deepCopy(const Exists &other)
{ {
return Exists(deepCopy(other.variables), deepCopy(other.argument)); return Exists(deepCopy(other.variables), deepCopy(other.argument));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ForAll deepCopy(const ForAll &other) inline ForAll deepCopy(const ForAll &other)
{ {
return ForAll(deepCopy(other.variables), deepCopy(other.argument)); return ForAll(deepCopy(other.variables), deepCopy(other.argument));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
In deepCopy(const In &other) inline In deepCopy(const In &other)
{ {
return In(deepCopy(other.element), deepCopy(other.set)); return In(deepCopy(other.element), deepCopy(other.set));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Implies deepCopy(const Implies &other) inline Implies deepCopy(const Implies &other)
{ {
return Implies(deepCopy(other.antecedent), deepCopy(other.consequent)); return Implies(deepCopy(other.antecedent), deepCopy(other.consequent));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Not deepCopy(const Not &other) inline Not deepCopy(const Not &other)
{ {
return Not(deepCopy(other.argument)); return Not(deepCopy(other.argument));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Or deepCopy(const Or &other) inline Or deepCopy(const Or &other)
{ {
return Or(deepCopy(other.arguments)); return Or(deepCopy(other.arguments));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Formula deepCopy(const Formula &formula) inline Formula deepCopy(const Formula &formula)
{ {
return deepCopyVariant(formula); return deepCopyVariant(formula);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<Formula> deepCopy(const std::vector<Formula> &formulas) inline std::vector<Formula> deepCopy(const std::vector<Formula> &formulas)
{ {
return deepCopyVariantVector(formulas); return deepCopyVariantVector(formulas);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Term deepCopy(const Term &term) inline Term deepCopy(const Term &term)
{ {
return deepCopyVariant(term); return deepCopyVariant(term);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<Term> deepCopy(const std::vector<Term> &terms) inline std::vector<Term> deepCopy(const std::vector<Term> &terms)
{ {
return deepCopyVariantVector(terms); return deepCopyVariantVector(terms);
} }

View File

@ -30,6 +30,8 @@ struct Context
bool isChoiceRule = false; bool isChoiceRule = false;
size_t numberOfHeadLiterals = 0; size_t numberOfHeadLiterals = 0;
size_t auxiliaryBodyLiteralID = 1; size_t auxiliaryBodyLiteralID = 1;
bool simplify = false;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,21 @@
#ifndef __ANTHEM__SIMPLIFICATION_H
#define __ANTHEM__SIMPLIFICATION_H
#include <anthem/AST.h>
namespace anthem
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simplification
//
////////////////////////////////////////////////////////////////////////////////////////////////////
ast::Formula simplify(ast::Formula &&formula);
////////////////////////////////////////////////////////////////////////////////////////////////////
}
#endif

View File

@ -0,0 +1,127 @@
#include <anthem/Simplification.h>
namespace anthem
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simplification
//
////////////////////////////////////////////////////////////////////////////////////////////////////
bool isPrimitiveTerm(const ast::Term &term)
{
const auto binaryOperationIsNotPrimitiveTerm =
[](const ast::BinaryOperationPointer &)
{
return false;
};
const auto intervalIsNotPrimitiveTerm =
[](const ast::IntervalPointer &)
{
return false;
};
const auto defaultIsPrimitiveTerm =
[](const auto &)
{
return true;
};
return term.match(binaryOperationIsNotPrimitiveTerm, intervalIsNotPrimitiveTerm, defaultIsPrimitiveTerm);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ast::Formula simplifyFormula(ast::Formula &&formula)
{
const auto simplifyAnd =
[&](ast::AndPointer &and_) -> ast::Formula
{
for (auto &argument : and_->arguments)
argument = simplifyFormula(std::move(argument));
return std::move(and_);
};
const auto simplifyBiconditional =
[&](ast::BiconditionalPointer &biconditional) -> ast::Formula
{
biconditional->left = simplifyFormula(std::move(biconditional->left));
biconditional->right = simplifyFormula(std::move(biconditional->right));
return std::move(biconditional);
};
const auto simplifyExists =
[&](ast::ExistsPointer &exists) -> ast::Formula
{
exists->argument = simplifyFormula(std::move(exists->argument));
return std::move(exists);
};
const auto simplifyForAll =
[&](ast::ForAllPointer &forAll) -> ast::Formula
{
forAll->argument = simplifyFormula(std::move(forAll->argument));
return std::move(forAll);
};
const auto simplifyImplies =
[&](ast::ImpliesPointer &implies) -> ast::Formula
{
implies->antecedent = simplifyFormula(std::move(implies->antecedent));
implies->consequent = simplifyFormula(std::move(implies->consequent));
return std::move(implies);
};
const auto simplifyIn =
[](ast::InPointer &in) -> ast::Formula
{
if (!isPrimitiveTerm(in->element) || !isPrimitiveTerm(in->set))
return std::move(in);
// Simplify formulas of type “A in B” to “A = B” if A and B are primitive
return std::make_unique<ast::Comparison>(ast::Comparison::Operator::Equal, std::move(in->element), std::move(in->set));
};
const auto simplifyNot =
[&](ast::NotPointer &not_) -> ast::Formula
{
not_->argument = simplifyFormula(std::move(not_->argument));
return std::move(not_);
};
const auto simplifyOr =
[&](ast::OrPointer &or_) -> ast::Formula
{
for (auto &argument : or_->arguments)
argument = simplifyFormula(std::move(argument));
return std::move(or_);
};
const auto defaultDoNothing =
[&](auto &x) -> ast::Formula
{
return std::move(x);
};
return formula.match(simplifyAnd, simplifyBiconditional, simplifyExists, simplifyForAll, simplifyImplies, simplifyIn, simplifyNot, simplifyOr, defaultDoNothing);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ast::Formula simplify(ast::Formula &&formula)
{
return simplifyFormula(std::move(formula));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}

View File

@ -7,6 +7,7 @@
#include <clingo.hh> #include <clingo.hh>
#include <anthem/Context.h> #include <anthem/Context.h>
#include <anthem/Simplification.h>
#include <anthem/StatementVisitor.h> #include <anthem/StatementVisitor.h>
#include <anthem/output/AST.h> #include <anthem/output/AST.h>
@ -41,12 +42,19 @@ void translate(const char *fileName, std::istream &stream, Context &context)
const auto translateStatement = const auto translateStatement =
[&context](const Clingo::AST::Statement &statement) [&context](const Clingo::AST::Statement &statement)
{ {
const auto formula = statement.data.accept(StatementVisitor(), statement, context); auto formula = statement.data.accept(StatementVisitor(), statement, context);
if (!formula) if (!formula)
return; return;
if (!context.simplify)
{
context.logger.outputStream() << formula.value() << std::endl; context.logger.outputStream() << formula.value() << std::endl;
return;
}
auto simplifiedFormula = simplify(std::move(formula.value()));
context.logger.outputStream() << simplifiedFormula << std::endl;
}; };
const auto logger = const auto logger =