Implemented #show statements for completed output.
This commit is contained in:
parent
4fd143ef64
commit
14abc37116
@ -241,8 +241,10 @@ struct PredicateSignature
|
||||
|
||||
PredicateSignature(const PredicateSignature &other) = delete;
|
||||
PredicateSignature &operator=(const PredicateSignature &other) = delete;
|
||||
PredicateSignature(PredicateSignature &&other) noexcept = default;
|
||||
PredicateSignature &operator=(PredicateSignature &&other) noexcept = default;
|
||||
// TODO: make noexcept again
|
||||
// GCC versions before 7 don’t declare moving std::string noexcept and would complain here
|
||||
PredicateSignature(PredicateSignature &&other) = default;
|
||||
PredicateSignature &operator=(PredicateSignature &&other) = default;
|
||||
|
||||
std::string name;
|
||||
size_t arity;
|
||||
|
@ -38,7 +38,9 @@ class VariableStack
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const Predicate &lhs, const Predicate &rhs);
|
||||
void collectPredicates(const Formula &formula, std::vector<const Predicate *> &predicates);
|
||||
bool matches(const Predicate &predicate, const PredicateSignature &signature);
|
||||
bool matches(const PredicateSignature &lhs, const PredicateSignature &rhs);
|
||||
void collectPredicateSignatures(const Formula &formula, std::vector<PredicateSignature> &predicateSignatures);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Replacing Variables
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __ANTHEM__COMPLETION_H
|
||||
|
||||
#include <anthem/AST.h>
|
||||
#include <anthem/Context.h>
|
||||
|
||||
namespace anthem
|
||||
{
|
||||
@ -12,7 +13,7 @@ namespace anthem
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormulas);
|
||||
std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormulas, Context &context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
22
include/anthem/HiddenPredicateElimination.h
Normal file
22
include/anthem/HiddenPredicateElimination.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __ANTHEM__HIDDEN_PREDICATE_ELIMINATION_H
|
||||
#define __ANTHEM__HIDDEN_PREDICATE_ELIMINATION_H
|
||||
|
||||
#include <anthem/AST.h>
|
||||
#include <anthem/Context.h>
|
||||
|
||||
namespace anthem
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HiddenPredicateElimination
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eliminateHiddenPredicates(const std::vector<ast::PredicateSignature> &predicateSignatures, std::vector<ast::Formula> &completedFormulas, Context &context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -192,23 +192,26 @@ struct CollectFreeVariablesVisitor
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct CollectPredicatesVisitor : public RecursiveFormulaVisitor<CollectPredicatesVisitor>
|
||||
struct CollectPredicateSignaturesVisitor : public RecursiveFormulaVisitor<CollectPredicateSignaturesVisitor>
|
||||
{
|
||||
static void accept(const Predicate &predicate, const Formula &, std::vector<const Predicate *> &predicates)
|
||||
static void accept(const Predicate &predicate, const Formula &, std::vector<PredicateSignature> &predicateSignatures)
|
||||
{
|
||||
const auto predicateMatches =
|
||||
[&predicate](const auto *otherPredicate)
|
||||
const auto predicateSignatureMatches =
|
||||
[&predicate](const auto &predicateSignature)
|
||||
{
|
||||
return matches(predicate, *otherPredicate);
|
||||
return matches(predicate, predicateSignature);
|
||||
};
|
||||
|
||||
if (std::find_if(predicates.cbegin(), predicates.cend(), predicateMatches) == predicates.cend())
|
||||
predicates.emplace_back(&predicate);
|
||||
if (std::find_if(predicateSignatures.cbegin(), predicateSignatures.cend(), predicateSignatureMatches) != predicateSignatures.cend())
|
||||
return;
|
||||
|
||||
// TODO: avoid copies
|
||||
predicateSignatures.emplace_back(std::string(predicate.name), predicate.arity());
|
||||
}
|
||||
|
||||
// Ignore all other types of expressions
|
||||
template<class T>
|
||||
static void accept(const T &, const Formula &, std::vector<const Predicate *> &)
|
||||
static void accept(const T &, const Formula &, std::vector<PredicateSignature> &)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -222,11 +225,25 @@ bool matches(const Predicate &lhs, const Predicate &rhs)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const Predicate &predicate, const PredicateSignature &signature)
|
||||
{
|
||||
return (predicate.name == signature.name && predicate.arity() == signature.arity);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const PredicateSignature &lhs, const PredicateSignature &rhs)
|
||||
{
|
||||
return (lhs.name == rhs.name && lhs.arity == rhs.arity);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: remove const_cast
|
||||
void collectPredicates(const Formula &formula, std::vector<const Predicate *> &predicates)
|
||||
void collectPredicateSignatures(const Formula &formula, std::vector<PredicateSignature> &predicateSignatures)
|
||||
{
|
||||
auto &formulaMutable = const_cast<Formula &>(formula);
|
||||
formulaMutable.accept(CollectPredicatesVisitor(), formulaMutable, predicates);
|
||||
formulaMutable.accept(CollectPredicateSignaturesVisitor(), formulaMutable, predicateSignatures);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <anthem/ASTUtils.h>
|
||||
#include <anthem/ASTVisitors.h>
|
||||
#include <anthem/Exception.h>
|
||||
#include <anthem/HiddenPredicateElimination.h>
|
||||
#include <anthem/Utils.h>
|
||||
|
||||
namespace anthem
|
||||
@ -99,22 +100,22 @@ ast::Formula buildCompletedFormulaQuantified(ast::Predicate &&predicate, ast::Fo
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::Formula completePredicate(const ast::Predicate &predicate, std::vector<ast::ScopedFormula> &scopedFormulas)
|
||||
ast::Formula completePredicate(const ast::PredicateSignature &predicateSignature, std::vector<ast::ScopedFormula> &scopedFormulas)
|
||||
{
|
||||
// Create new set of parameters for the completed definition for the predicate
|
||||
ast::VariableDeclarationPointers parameters;
|
||||
parameters.reserve(predicate.arguments.size());
|
||||
parameters.reserve(predicateSignature.arity);
|
||||
|
||||
std::vector<ast::Term> arguments;
|
||||
arguments.reserve(predicate.arguments.size());
|
||||
arguments.reserve(predicateSignature.arity);
|
||||
|
||||
for (size_t i = 0; i < predicate.arguments.size(); i++)
|
||||
for (size_t i = 0; i < predicateSignature.arity; i++)
|
||||
{
|
||||
parameters.emplace_back(std::make_unique<ast::VariableDeclaration>(ast::VariableDeclaration::Type::Head));
|
||||
arguments.emplace_back(ast::Term::make<ast::Variable>(parameters.back().get()));
|
||||
}
|
||||
|
||||
ast::Predicate predicateCopy(std::string(predicate.name), std::move(arguments));
|
||||
ast::Predicate predicateCopy(std::string(predicateSignature.name), std::move(arguments));
|
||||
|
||||
auto completedFormulaDisjunction = buildCompletedFormulaDisjunction(predicateCopy, parameters, scopedFormulas);
|
||||
auto completedFormulaQuantified = buildCompletedFormulaQuantified(std::move(predicateCopy), std::move(completedFormulaDisjunction));
|
||||
@ -146,7 +147,7 @@ ast::Formula completeIntegrityConstraint(ast::ScopedFormula &scopedFormula)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormulas)
|
||||
std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormulas, Context &context)
|
||||
{
|
||||
// Check whether formulas are in normal form
|
||||
for (const auto &scopedFormula : scopedFormulas)
|
||||
@ -160,28 +161,28 @@ std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormu
|
||||
throw CompletionException("cannot perform completion, only single predicates and Booleans supported as formula consequent currently");
|
||||
}
|
||||
|
||||
std::vector<const ast::Predicate *> predicates;
|
||||
std::vector<ast::PredicateSignature> predicateSignatures;
|
||||
|
||||
// Get a list of all predicates
|
||||
for (const auto &scopedFormula : scopedFormulas)
|
||||
ast::collectPredicates(scopedFormula.formula, predicates);
|
||||
ast::collectPredicateSignatures(scopedFormula.formula, predicateSignatures);
|
||||
|
||||
std::sort(predicates.begin(), predicates.end(),
|
||||
[](const auto *lhs, const auto *rhs)
|
||||
std::sort(predicateSignatures.begin(), predicateSignatures.end(),
|
||||
[](const auto &lhs, const auto &rhs)
|
||||
{
|
||||
const auto order = std::strcmp(lhs->name.c_str(), rhs->name.c_str());
|
||||
const auto order = std::strcmp(lhs.name.c_str(), rhs.name.c_str());
|
||||
|
||||
if (order != 0)
|
||||
return order < 0;
|
||||
return (order < 0);
|
||||
|
||||
return lhs->arity() < rhs->arity();
|
||||
return lhs.arity < rhs.arity;
|
||||
});
|
||||
|
||||
std::vector<ast::Formula> completedFormulas;
|
||||
|
||||
// Complete predicates
|
||||
for (const auto *predicate : predicates)
|
||||
completedFormulas.emplace_back(completePredicate(*predicate, scopedFormulas));
|
||||
for (const auto &predicateSignature : predicateSignatures)
|
||||
completedFormulas.emplace_back(completePredicate(predicateSignature, scopedFormulas));
|
||||
|
||||
// Complete integrity constraints
|
||||
for (auto &scopedFormula : scopedFormulas)
|
||||
@ -200,6 +201,9 @@ std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormu
|
||||
completedFormulas.emplace_back(completeIntegrityConstraint(scopedFormula));
|
||||
}
|
||||
|
||||
// Eliminate all predicates that should not be visible in the output
|
||||
eliminateHiddenPredicates(predicateSignatures, completedFormulas, context);
|
||||
|
||||
return completedFormulas;
|
||||
}
|
||||
|
||||
|
268
src/anthem/HiddenPredicateElimination.cpp
Normal file
268
src/anthem/HiddenPredicateElimination.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
#include <anthem/HiddenPredicateElimination.h>
|
||||
|
||||
#include <anthem/ASTCopy.h>
|
||||
#include <anthem/ASTUtils.h>
|
||||
#include <anthem/ASTVisitors.h>
|
||||
#include <anthem/Exception.h>
|
||||
#include <anthem/Simplification.h>
|
||||
#include <anthem/output/AST.h>
|
||||
|
||||
namespace anthem
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HiddenPredicateElimination
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PredicateReplacement
|
||||
{
|
||||
const ast::Predicate &predicate;
|
||||
ast::Formula replacement;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Replaces all occurrences of a variable in a given term with another variable
|
||||
struct ReplaceVariableInTermVisitor : public ast::RecursiveTermVisitor<ReplaceVariableInTermVisitor>
|
||||
{
|
||||
static void accept(ast::Variable &variable, ast::Term &, const ast::VariableDeclaration &original, ast::VariableDeclaration &replacement)
|
||||
{
|
||||
if (variable.declaration == &original)
|
||||
// No dangling variables can result from this operation, and hence, fixing them is not necessary
|
||||
variable.declaration = &replacement;
|
||||
}
|
||||
|
||||
// Ignore all other types of expressions
|
||||
template<class T>
|
||||
static void accept(T &, ast::Term &, const ast::VariableDeclaration &, ast::VariableDeclaration &)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Replaces all occurrences of a variable in a given formula with another variable
|
||||
struct ReplaceVariableInFormulaVisitor : public ast::RecursiveFormulaVisitor<ReplaceVariableInFormulaVisitor>
|
||||
{
|
||||
static void accept(ast::Comparison &comparison, ast::Formula &, const ast::VariableDeclaration &original, ast::VariableDeclaration &replacement)
|
||||
{
|
||||
comparison.left.accept(ReplaceVariableInTermVisitor(), comparison.left, original, replacement);
|
||||
comparison.right.accept(ReplaceVariableInTermVisitor(), comparison.right, original, replacement);
|
||||
}
|
||||
|
||||
static void accept(ast::In &in, ast::Formula &, const ast::VariableDeclaration &original, ast::VariableDeclaration &replacement)
|
||||
{
|
||||
in.element.accept(ReplaceVariableInTermVisitor(), in.element, original, replacement);
|
||||
in.set.accept(ReplaceVariableInTermVisitor(), in.set, original, replacement);
|
||||
}
|
||||
|
||||
static void accept(ast::Predicate &predicate, ast::Formula &, const ast::VariableDeclaration &original, ast::VariableDeclaration &replacement)
|
||||
{
|
||||
for (auto &argument : predicate.arguments)
|
||||
argument.accept(ReplaceVariableInTermVisitor(), argument, original, replacement);
|
||||
}
|
||||
|
||||
// Ignore all other types of expressions
|
||||
template<class T>
|
||||
static void accept(T &, ast::Formula &, const ast::VariableDeclaration &, ast::VariableDeclaration &)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Replace a predicate in a term with a formula
|
||||
struct ReplacePredicateInFormulaVisitor : public ast::RecursiveFormulaVisitor<ReplacePredicateInFormulaVisitor>
|
||||
{
|
||||
static void accept(ast::Predicate &predicate, ast::Formula &formula, const PredicateReplacement &predicateReplacement)
|
||||
{
|
||||
if (!ast::matches(predicate, predicateReplacement.predicate))
|
||||
return;
|
||||
|
||||
auto formulaReplacement = ast::prepareCopy(predicateReplacement.replacement);
|
||||
|
||||
for (size_t i = 0; i < predicate.arguments.size(); i++)
|
||||
{
|
||||
assert(predicateReplacement.predicate.arguments[i].is<ast::Variable>());
|
||||
const auto &original = *predicateReplacement.predicate.arguments[i].get<ast::Variable>().declaration;
|
||||
|
||||
assert(predicate.arguments[i].is<ast::Variable>());
|
||||
auto &replacement = *predicate.arguments[i].get<ast::Variable>().declaration;
|
||||
|
||||
formulaReplacement.accept(ReplaceVariableInFormulaVisitor(), formulaReplacement, original, replacement);
|
||||
}
|
||||
|
||||
formula = std::move(formulaReplacement);
|
||||
}
|
||||
|
||||
// Ignore all other types of expressions
|
||||
template<class T>
|
||||
static void accept(T &, ast::Formula &, const PredicateReplacement &)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Detect whether a formula contains a circular dependency on a given predicate
|
||||
struct DetectCircularDependcyVisitor : public ast::RecursiveFormulaVisitor<DetectCircularDependcyVisitor>
|
||||
{
|
||||
static void accept(ast::Predicate &predicate, ast::Formula &, const ast::PredicateSignature &predicateSignature, bool &hasCircularDependency)
|
||||
{
|
||||
if (ast::matches(predicate, predicateSignature))
|
||||
hasCircularDependency = true;
|
||||
}
|
||||
|
||||
// Ignore all other types of expressions
|
||||
template<class T>
|
||||
static void accept(T &, ast::Formula &, const ast::PredicateSignature &, bool &)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Finds the replacement for predicates of the form “forall X1, ..., Xn (p(X1, ..., Xn) <-> ...)”
|
||||
PredicateReplacement findReplacement(const ast::PredicateSignature &predicateSignature, const ast::ForAll &forAll)
|
||||
{
|
||||
// Declare variable used, only used in debug mode
|
||||
(void)(predicateSignature);
|
||||
|
||||
// Form: “forall X1, ..., Xn p(X1, ..., Xn)”
|
||||
// Replace with “#true”
|
||||
if (forAll.argument.is<ast::Predicate>())
|
||||
{
|
||||
assert(ast::matches(forAll.argument.get<ast::Predicate>(), predicateSignature));
|
||||
|
||||
return {forAll.argument.get<ast::Predicate>(), ast::Formula::make<ast::Boolean>(true)};
|
||||
}
|
||||
|
||||
// Form: “forall X1, ..., Xn (p(X1, ..., Xn) <-> ...)”
|
||||
// Replace with “#false”
|
||||
if (forAll.argument.is<ast::Not>())
|
||||
{
|
||||
auto ¬Argument = forAll.argument.get<ast::Not>().argument;
|
||||
|
||||
assert(notArgument.is<ast::Predicate>());
|
||||
assert(ast::matches(notArgument.get<ast::Predicate>(), predicateSignature));
|
||||
|
||||
return {notArgument.get<ast::Predicate>(), ast::Formula::make<ast::Boolean>(false)};
|
||||
}
|
||||
|
||||
assert(forAll.argument.is<ast::Biconditional>());
|
||||
|
||||
const auto &biconditional = forAll.argument.get<ast::Biconditional>();
|
||||
|
||||
assert(biconditional.left.is<ast::Predicate>());
|
||||
assert(ast::matches(biconditional.left.get<ast::Predicate>(), predicateSignature));
|
||||
|
||||
// TODO: avoid copy
|
||||
return {biconditional.left.get<ast::Predicate>(), ast::prepareCopy(biconditional.right)};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Finds a replacement for a predicate that should be hidden
|
||||
PredicateReplacement findReplacement(const ast::PredicateSignature &predicateSignature, const ast::Formula &completedPredicateDefinition)
|
||||
{
|
||||
if (completedPredicateDefinition.is<ast::ForAll>())
|
||||
return findReplacement(predicateSignature, completedPredicateDefinition.get<ast::ForAll>());
|
||||
else if (completedPredicateDefinition.is<ast::Predicate>())
|
||||
return {completedPredicateDefinition.get<ast::Predicate>(), ast::Formula::make<ast::Boolean>(true)};
|
||||
else if (completedPredicateDefinition.is<ast::Not>())
|
||||
{
|
||||
const auto ¬Argument = completedPredicateDefinition.get<ast::Not>().argument;
|
||||
assert(notArgument.is<ast::Predicate>());
|
||||
|
||||
return {notArgument.get<ast::Predicate>(), ast::Formula::make<ast::Boolean>(false)};
|
||||
}
|
||||
|
||||
throw CompletionException("invalid completed predicate definition for predicate “" + predicateSignature.name + "/" + std::to_string(predicateSignature.arity) + "”");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eliminateHiddenPredicates(const std::vector<ast::PredicateSignature> &predicateSignatures, std::vector<ast::Formula> &completedFormulas, Context &context)
|
||||
{
|
||||
if (!context.visiblePredicateSignatures)
|
||||
{
|
||||
context.logger.log(output::Priority::Debug) << "no predicates to be eliminated";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &visiblePredicateSignatures = context.visiblePredicateSignatures.value();
|
||||
|
||||
// Check for undeclared predicates that are requested to be shown
|
||||
for (const auto &visiblePredicateSignature : visiblePredicateSignatures)
|
||||
{
|
||||
const auto matchesPredicateSignature =
|
||||
[&](const auto &predicateSignature)
|
||||
{
|
||||
return ast::matches(predicateSignature, visiblePredicateSignature);
|
||||
};
|
||||
|
||||
const auto matchingPredicateSignature =
|
||||
std::find_if(predicateSignatures.cbegin(), predicateSignatures.cend(), matchesPredicateSignature);
|
||||
|
||||
if (matchingPredicateSignature == predicateSignatures.cend())
|
||||
context.logger.log(output::Priority::Warning) << "cannot show undeclared predicate “" << visiblePredicateSignature.name << "/" << visiblePredicateSignature.arity <<"”";
|
||||
}
|
||||
|
||||
// Replace all occurrences of hidden predicates
|
||||
for (size_t i = 0; i < predicateSignatures.size(); i++)
|
||||
{
|
||||
auto &predicateSignature = predicateSignatures[i];
|
||||
|
||||
const auto matchesVisiblePredicateSignature =
|
||||
[&](const auto &visiblePredicateSignature)
|
||||
{
|
||||
return ast::matches(predicateSignature, visiblePredicateSignature);
|
||||
};
|
||||
|
||||
const auto matchingPredicateSignature =
|
||||
std::find_if(visiblePredicateSignatures.cbegin(), visiblePredicateSignatures.cend(), matchesVisiblePredicateSignature);
|
||||
|
||||
// If the predicate ought to be visible, don’t eliminate it
|
||||
if (matchingPredicateSignature != visiblePredicateSignatures.cend())
|
||||
continue;
|
||||
|
||||
context.logger.log(output::Priority::Debug) << "eliminating “" << predicateSignature.name << "/" << predicateSignature.arity << "”";
|
||||
|
||||
const auto &completedPredicateDefinition = completedFormulas[i];
|
||||
auto replacement = findReplacement(predicateSignature, completedPredicateDefinition);
|
||||
|
||||
bool hasCircularDependency = false;
|
||||
replacement.replacement.accept(DetectCircularDependcyVisitor(), replacement.replacement, predicateSignature, hasCircularDependency);
|
||||
|
||||
if (hasCircularDependency)
|
||||
{
|
||||
context.logger.log(output::Priority::Warning) << "cannot hide predicate “" << predicateSignature.name << "/" << predicateSignature.arity << "” due to circular dependency";
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < completedFormulas.size(); j++)
|
||||
if (j != i)
|
||||
completedFormulas[j].accept(ReplacePredicateInFormulaVisitor(), completedFormulas[j], replacement);
|
||||
|
||||
// TODO: refactor
|
||||
completedFormulas[i] = ast::Formula::make<ast::Boolean>(true);
|
||||
}
|
||||
|
||||
const auto canBeRemoved =
|
||||
[&](const ast::Formula &completedFormula)
|
||||
{
|
||||
if (!completedFormula.is<ast::Boolean>())
|
||||
return false;
|
||||
|
||||
return completedFormula.get<ast::Boolean>().value == true;
|
||||
};
|
||||
|
||||
auto removedFormulas = std::remove_if(completedFormulas.begin(), completedFormulas.end(), canBeRemoved);
|
||||
completedFormulas.erase(removedFormulas, completedFormulas.end());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
@ -77,7 +77,7 @@ void translate(const char *fileName, std::istream &stream, Context &context)
|
||||
return;
|
||||
}
|
||||
|
||||
auto completedFormulas = complete(std::move(scopedFormulas));
|
||||
auto completedFormulas = complete(std::move(scopedFormulas), context);
|
||||
|
||||
// TODO: rethink simplification steps
|
||||
if (context.simplify)
|
||||
|
Loading…
Reference in New Issue
Block a user