Started implementing output simplifications.
This commit is contained in:
parent
f85236955f
commit
fc538eb7fc
@ -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)");
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
21
include/anthem/Simplification.h
Normal file
21
include/anthem/Simplification.h
Normal 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
|
127
src/anthem/Simplification.cpp
Normal file
127
src/anthem/Simplification.cpp
Normal 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 ¬_) -> 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
@ -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 =
|
||||||
|
Loading…
Reference in New Issue
Block a user