Added back simplification support.
This commit is contained in:
parent
1c925d661b
commit
1917f18b6a
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <experimental/optional>
|
#include <experimental/optional>
|
||||||
|
|
||||||
|
#include <anthem/ASTCopy.h>
|
||||||
#include <anthem/ASTVisitors.h>
|
#include <anthem/ASTVisitors.h>
|
||||||
|
|
||||||
namespace anthem
|
namespace anthem
|
||||||
@ -14,19 +15,19 @@ namespace anthem
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Determines whether a term is a specific variable
|
// Determines whether a term is a specific variable
|
||||||
bool matchesVariableDeclaration(const ast::Term &term, const ast::VariableDeclaration &variableDeclaration)
|
bool matchesVariableDeclaration(const ast::Term &term, const ast::VariableDeclaration *variableDeclaration)
|
||||||
{
|
{
|
||||||
if (!term.is<ast::Variable>())
|
if (!term.is<ast::Variable>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return term.get<ast::Variable>().declaration == &variableDeclaration;
|
return term.get<ast::Variable>().declaration == variableDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Extracts the term t if the given formula is of the form “X = t” and X matches the given variable
|
// Extracts the term t if the given formula is of the form “X = t” and X matches the given variable
|
||||||
// The input formula is not usable if a term is returned
|
// The input formula is not usable if a term is returned
|
||||||
std::experimental::optional<ast::Term> extractAssignedTerm(ast::Formula &formula, const ast::VariableDeclaration &variableDeclaration)
|
std::experimental::optional<ast::Term> extractAssignedTerm(ast::Formula &formula, const ast::VariableDeclaration *variableDeclaration)
|
||||||
{
|
{
|
||||||
if (!formula.is<ast::Comparison>())
|
if (!formula.is<ast::Comparison>())
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
@ -50,16 +51,16 @@ std::experimental::optional<ast::Term> extractAssignedTerm(ast::Formula &formula
|
|||||||
// Replaces all occurrences of a variable in a given term with another term
|
// Replaces all occurrences of a variable in a given term with another term
|
||||||
struct ReplaceVariableInTermVisitor : public ast::RecursiveTermVisitor<ReplaceVariableInTermVisitor>
|
struct ReplaceVariableInTermVisitor : public ast::RecursiveTermVisitor<ReplaceVariableInTermVisitor>
|
||||||
{
|
{
|
||||||
static void accept(ast::Variable &, ast::Term &, const ast::VariableDeclaration &, const ast::Term &)
|
static void accept(ast::Variable &variable, ast::Term &term, const ast::VariableDeclaration *original, const ast::Term &replacement)
|
||||||
{
|
{
|
||||||
// TODO: reimplement
|
if (variable.declaration == original)
|
||||||
//if (variable.name == variableToReplace.name)
|
// No dangling variables can result from this operation, and hence, fixing them is not necessary
|
||||||
// term = ast::deepCopy(replacementTerm);
|
term = ast::prepareCopy(replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore all other types of expressions
|
// Ignore all other types of expressions
|
||||||
template<class T>
|
template<class T>
|
||||||
static void accept(T &, ast::Term &, const ast::VariableDeclaration &, const ast::Term &)
|
static void accept(T &, ast::Term &, const ast::VariableDeclaration *, const ast::Term &)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -69,27 +70,27 @@ struct ReplaceVariableInTermVisitor : public ast::RecursiveTermVisitor<ReplaceVa
|
|||||||
// Replaces all occurrences of a variable in a given formula with a term
|
// Replaces all occurrences of a variable in a given formula with a term
|
||||||
struct ReplaceVariableInFormulaVisitor : public ast::RecursiveFormulaVisitor<ReplaceVariableInFormulaVisitor>
|
struct ReplaceVariableInFormulaVisitor : public ast::RecursiveFormulaVisitor<ReplaceVariableInFormulaVisitor>
|
||||||
{
|
{
|
||||||
static void accept(ast::Comparison &comparison, ast::Formula &, const ast::VariableDeclaration &variableDeclaration, const ast::Term &term)
|
static void accept(ast::Comparison &comparison, ast::Formula &, const ast::VariableDeclaration *original, const ast::Term &replacement)
|
||||||
{
|
{
|
||||||
comparison.left.accept(ReplaceVariableInTermVisitor(), comparison.left, variableDeclaration, term);
|
comparison.left.accept(ReplaceVariableInTermVisitor(), comparison.left, original, replacement);
|
||||||
comparison.right.accept(ReplaceVariableInTermVisitor(), comparison.right, variableDeclaration, term);
|
comparison.right.accept(ReplaceVariableInTermVisitor(), comparison.right, original, replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void accept(ast::In &in, ast::Formula &, const ast::VariableDeclaration &variableDeclaration, const ast::Term &term)
|
static void accept(ast::In &in, ast::Formula &, const ast::VariableDeclaration *original, const ast::Term &term)
|
||||||
{
|
{
|
||||||
in.element.accept(ReplaceVariableInTermVisitor(), in.element, variableDeclaration, term);
|
in.element.accept(ReplaceVariableInTermVisitor(), in.element, original, term);
|
||||||
in.set.accept(ReplaceVariableInTermVisitor(), in.set, variableDeclaration, term);
|
in.set.accept(ReplaceVariableInTermVisitor(), in.set, original, term);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void accept(ast::Predicate &predicate, ast::Formula &, const ast::VariableDeclaration &variableDeclaration, const ast::Term &term)
|
static void accept(ast::Predicate &predicate, ast::Formula &, const ast::VariableDeclaration *original, const ast::Term &replacement)
|
||||||
{
|
{
|
||||||
for (auto &argument : predicate.arguments)
|
for (auto &argument : predicate.arguments)
|
||||||
argument.accept(ReplaceVariableInTermVisitor(), argument, variableDeclaration, term);
|
argument.accept(ReplaceVariableInTermVisitor(), argument, original, replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore all other types of expressions
|
// Ignore all other types of expressions
|
||||||
template<class T>
|
template<class T>
|
||||||
static void accept(T &, ast::Formula &, const ast::VariableDeclaration &, const ast::Term &)
|
static void accept(T &, ast::Formula &, const ast::VariableDeclaration *, const ast::Term &)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -109,7 +110,7 @@ void simplify(ast::Exists &exists, ast::Formula &formula)
|
|||||||
// Simplify formulas of type “exists X (X = t and F(X))” to “F(t)”
|
// Simplify formulas of type “exists X (X = t and F(X))” to “F(t)”
|
||||||
for (auto i = exists.variables.begin(); i != exists.variables.end();)
|
for (auto i = exists.variables.begin(); i != exists.variables.end();)
|
||||||
{
|
{
|
||||||
auto &variableDeclaration = *i->get();
|
const auto *variableDeclaration = i->get();
|
||||||
|
|
||||||
bool wasVariableReplaced = false;
|
bool wasVariableReplaced = false;
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*TEST_CASE("[simplification] Rules are simplified correctly", "[simplification]")
|
TEST_CASE("[simplification] Rules are simplified correctly", "[simplification]")
|
||||||
{
|
{
|
||||||
std::stringstream input;
|
std::stringstream input;
|
||||||
std::stringstream output;
|
std::stringstream output;
|
||||||
std::stringstream errors;
|
std::stringstream errors;
|
||||||
|
|
||||||
anthem::output::Logger logger(output, errors);
|
anthem::output::Logger logger(output, errors);
|
||||||
anthem::Context context = {logger, {}};
|
anthem::Context context(std::move(logger));
|
||||||
context.simplify = true;
|
context.simplify = true;
|
||||||
context.complete = false;
|
context.complete = false;
|
||||||
|
|
||||||
@ -24,7 +24,7 @@
|
|||||||
input << ":- in(I, S), in(J, S), in(I + J, S).";
|
input << ":- in(I, S), in(J, S), in(I + J, S).";
|
||||||
anthem::translate("input", input, context);
|
anthem::translate("input", input, context);
|
||||||
|
|
||||||
CHECK(output.str() == "((in(I, S) and in(J, S) and exists X5 (X5 in (I + J) and in(X5, S))) -> #false)\n");
|
CHECK(output.str() == "((in(U1, U2) and in(U3, U2) and exists X1 (X1 in (U1 + U3) and in(X1, U2))) -> #false)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("example 2")
|
SECTION("example 2")
|
||||||
@ -32,7 +32,7 @@
|
|||||||
input << "covered(I) :- in(I, S).";
|
input << "covered(I) :- in(I, S).";
|
||||||
anthem::translate("input", input, context);
|
anthem::translate("input", input, context);
|
||||||
|
|
||||||
CHECK(output.str() == "((V1 = I and in(I, S)) -> covered(V1))\n");
|
CHECK(output.str() == "((V1 = U1 and in(U1, U2)) -> covered(V1))\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("example 3")
|
SECTION("example 3")
|
||||||
@ -40,7 +40,7 @@
|
|||||||
input << ":- not covered(I), I = 1..n.";
|
input << ":- not covered(I), I = 1..n.";
|
||||||
anthem::translate("input", input, context);
|
anthem::translate("input", input, context);
|
||||||
|
|
||||||
CHECK(output.str() == "((not covered(I) and I in 1..n) -> #false)\n");
|
CHECK(output.str() == "((not covered(U1) and U1 in 1..n) -> #false)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("comparisons")
|
SECTION("comparisons")
|
||||||
@ -48,7 +48,6 @@
|
|||||||
input << ":- M > N.";
|
input << ":- M > N.";
|
||||||
anthem::translate("input", input, context);
|
anthem::translate("input", input, context);
|
||||||
|
|
||||||
CHECK(output.str() == "(M > N -> #false)\n");
|
CHECK(output.str() == "(U1 > U2 -> #false)\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user