2018-03-25 23:49:39 +02:00
|
|
|
#ifndef __ANTHEM__SIMPLIFICATION_VISITORS_H
|
|
|
|
#define __ANTHEM__SIMPLIFICATION_VISITORS_H
|
|
|
|
|
|
|
|
#include <anthem/AST.h>
|
|
|
|
#include <anthem/Simplification.h>
|
2018-04-27 23:37:13 +02:00
|
|
|
#include <anthem/Utils.h>
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
namespace anthem
|
|
|
|
{
|
|
|
|
namespace ast
|
|
|
|
{
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Simplification Visitor
|
|
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
struct FormulaSimplificationVisitor
|
|
|
|
{
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(And &and_, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
for (auto &argument : and_.arguments)
|
2018-04-27 23:37:13 +02:00
|
|
|
if (argument.accept(*this, argument, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Biconditional &biconditional, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
2018-04-27 23:37:13 +02:00
|
|
|
if (biconditional.left.accept(*this, biconditional.left, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
2018-04-27 23:37:13 +02:00
|
|
|
if (biconditional.right.accept(*this, biconditional.right, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Boolean &, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Comparison &, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Exists &exists, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
2018-04-27 23:37:13 +02:00
|
|
|
if (exists.argument.accept(*this, exists.argument, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(ForAll &forAll, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
2018-04-27 23:37:13 +02:00
|
|
|
if (forAll.argument.accept(*this, forAll.argument, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Implies &implies, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
2018-04-27 23:37:13 +02:00
|
|
|
if (implies.antecedent.accept(*this, implies.antecedent, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
2018-04-27 23:37:13 +02:00
|
|
|
if (implies.consequent.accept(*this, implies.consequent, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(In &, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Not ¬_, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
2018-04-27 23:37:13 +02:00
|
|
|
if (not_.argument.accept(*this, not_.argument, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Or &or_, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
for (auto &argument : or_.arguments)
|
2018-04-27 23:37:13 +02:00
|
|
|
if (argument.accept(*this, argument, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Predicate &, Formula &formula, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(formula, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-04-27 23:37:13 +02:00
|
|
|
template<class T, class OperationResult = void>
|
2018-03-25 23:49:39 +02:00
|
|
|
struct TermSimplificationVisitor
|
|
|
|
{
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(BinaryOperation &binaryOperation, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
2018-04-27 23:37:13 +02:00
|
|
|
if (binaryOperation.left.accept(*this, binaryOperation.left, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
2018-04-27 23:37:13 +02:00
|
|
|
if (binaryOperation.right.accept(*this, binaryOperation.right, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Boolean &, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Function &function, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
for (auto &argument : function.arguments)
|
2018-04-27 23:37:13 +02:00
|
|
|
if (argument.accept(*this, argument, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Integer &, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Interval &interval, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
2018-04-27 23:37:13 +02:00
|
|
|
if (interval.from.accept(*this, interval.from, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
2018-04-27 23:37:13 +02:00
|
|
|
if (interval.to.accept(*this, interval.to, std::forward<Arguments>(arguments)...) == OperationResult::Changed)
|
|
|
|
return OperationResult::Changed;
|
2018-03-25 23:49:39 +02:00
|
|
|
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(SpecialInteger &, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(String &, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... Arguments>
|
2018-04-27 23:37:13 +02:00
|
|
|
OperationResult visit(Variable &, Term &term, Arguments &&... arguments)
|
2018-03-25 23:49:39 +02:00
|
|
|
{
|
|
|
|
return T::accept(term, std::forward<Arguments>(arguments)...);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|