Started implementing output simplifications.

This commit is contained in:
2017-03-16 15:45:55 +01:00
parent f85236955f
commit fc538eb7fc
6 changed files with 185 additions and 26 deletions

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