Compare commits
2 Commits
v0.1.7
...
v0.1.7-rc.
Author | SHA1 | Date | |
---|---|---|---|
b8bfa7db7a
|
|||
3e096e39aa
|
@@ -1,6 +1,6 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
## 0.1.7 (2018-04-08)
|
## 0.1.7 RC 2 (2018-04-06)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# The MIT License (MIT)
|
# The MIT License (MIT)
|
||||||
|
|
||||||
Copyright © 2016–2018 Patrick Lühne
|
Copyright © 2016–2017 Patrick Lühne
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@@ -70,7 +70,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (version)
|
if (version)
|
||||||
{
|
{
|
||||||
std::cout << "anthem version 0.1.7" << std::endl;
|
std::cout << "anthem version 0.1.7-rc.2" << std::endl;
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
#external color(1).
|
colored(V, red) :- vertex(V), not colored(V, green), not colored(V, blue).
|
||||||
#external edge(2).
|
colored(V, green) :- vertex(V), not colored(V, red), not colored(V, blue).
|
||||||
#external vertex(1).
|
colored(V, blue) :- vertex(V), not colored(V, red), not colored(V, green).
|
||||||
#show color/2.
|
|
||||||
|
|
||||||
{color(V,C)} :- vertex(V), color(C).
|
:- edge(V1, V2), colored(V1, C), colored(V2, C).
|
||||||
covered(V) :- color(V, _).
|
|
||||||
:- vertex(V), not covered(V).
|
vertex(a).
|
||||||
:- color(V1,C), color(V2,C), edge(V1,V2).
|
vertex(b).
|
||||||
|
vertex(c).
|
||||||
|
|
||||||
|
edge(a, b).
|
||||||
|
edge(a, c).
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <anthem/AST.h>
|
#include <anthem/AST.h>
|
||||||
#include <anthem/ASTVisitors.h>
|
#include <anthem/ASTVisitors.h>
|
||||||
#include <anthem/Context.h>
|
|
||||||
|
|
||||||
namespace anthem
|
namespace anthem
|
||||||
{
|
{
|
||||||
@@ -41,7 +40,7 @@ class VariableStack
|
|||||||
bool matches(const Predicate &lhs, const Predicate &rhs);
|
bool matches(const Predicate &lhs, const Predicate &rhs);
|
||||||
bool matches(const Predicate &predicate, const PredicateSignature &signature);
|
bool matches(const Predicate &predicate, const PredicateSignature &signature);
|
||||||
bool matches(const PredicateSignature &lhs, const PredicateSignature &rhs);
|
bool matches(const PredicateSignature &lhs, const PredicateSignature &rhs);
|
||||||
void collectPredicateSignatures(const Formula &formula, std::vector<PredicateSignature> &predicateSignatures, Context &context);
|
void collectPredicateSignatures(const Formula &formula, std::vector<PredicateSignature> &predicateSignatures);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Replacing Variables
|
// Replacing Variables
|
||||||
|
@@ -16,14 +16,6 @@ namespace anthem
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct PredicateSignatureMeta
|
|
||||||
{
|
|
||||||
ast::PredicateSignature predicateSignature;
|
|
||||||
bool used{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct Context
|
struct Context
|
||||||
{
|
{
|
||||||
Context() = default;
|
Context() = default;
|
||||||
@@ -38,8 +30,8 @@ struct Context
|
|||||||
bool performSimplification = false;
|
bool performSimplification = false;
|
||||||
bool performCompletion = false;
|
bool performCompletion = false;
|
||||||
|
|
||||||
std::optional<std::vector<PredicateSignatureMeta>> visiblePredicateSignatures;
|
std::optional<std::vector<ast::PredicateSignature>> visiblePredicateSignatures;
|
||||||
std::optional<std::vector<PredicateSignatureMeta>> externalPredicateSignatures;
|
std::optional<std::vector<ast::PredicateSignature>> externalPredicateSignatures;
|
||||||
|
|
||||||
ast::ParenthesisStyle parenthesisStyle = ast::ParenthesisStyle::Normal;
|
ast::ParenthesisStyle parenthesisStyle = ast::ParenthesisStyle::Normal;
|
||||||
};
|
};
|
||||||
|
@@ -176,8 +176,7 @@ struct StatementVisitor
|
|||||||
|
|
||||||
context.logger.log(output::Priority::Debug, statement.location) << "showing “" << signature.name() << "/" << signature.arity() << "”";
|
context.logger.log(output::Priority::Debug, statement.location) << "showing “" << signature.name() << "/" << signature.arity() << "”";
|
||||||
|
|
||||||
auto predicateSignature = ast::PredicateSignature{std::string(signature.name()), signature.arity()};
|
context.visiblePredicateSignatures.value().emplace_back(std::string(signature.name()), signature.arity());
|
||||||
context.visiblePredicateSignatures.value().emplace_back(PredicateSignatureMeta{std::move(predicateSignature)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::ShowTerm &, const Clingo::AST::Statement &statement, std::vector<ast::ScopedFormula> &, Context &)
|
void visit(const Clingo::AST::ShowTerm &, const Clingo::AST::Statement &statement, std::vector<ast::ScopedFormula> &, Context &)
|
||||||
@@ -214,13 +213,12 @@ struct StatementVisitor
|
|||||||
if (aritySymbol.type() != Clingo::SymbolType::Number)
|
if (aritySymbol.type() != Clingo::SymbolType::Number)
|
||||||
fail();
|
fail();
|
||||||
|
|
||||||
const size_t arity = arityArgument.data.get<Clingo::Symbol>().number();
|
const auto &arity = arityArgument.data.get<Clingo::Symbol>().number();
|
||||||
|
|
||||||
if (!context.externalPredicateSignatures)
|
if (!context.externalPredicateSignatures)
|
||||||
context.externalPredicateSignatures.emplace();
|
context.externalPredicateSignatures.emplace();
|
||||||
|
|
||||||
auto predicateSignature = ast::PredicateSignature{std::string(predicate.name), arity};
|
context.externalPredicateSignatures->emplace_back(std::string(predicate.name), arity);
|
||||||
context.externalPredicateSignatures->emplace_back(PredicateSignatureMeta{std::move(predicateSignature)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
Submodule lib/catch updated: d2d8455b57...0a34cc201e
@@ -59,7 +59,7 @@ bool VariableStack::contains(const VariableDeclaration &variableDeclaration) con
|
|||||||
};
|
};
|
||||||
|
|
||||||
const auto layerContainsVariableDeclaration =
|
const auto layerContainsVariableDeclaration =
|
||||||
[&variableDeclarationMatches](const auto &layer)
|
[&variableDeclaration, &variableDeclarationMatches](const auto &layer)
|
||||||
{
|
{
|
||||||
return (std::find_if(layer->cbegin(), layer->cend(), variableDeclarationMatches) != layer->cend());
|
return (std::find_if(layer->cbegin(), layer->cend(), variableDeclarationMatches) != layer->cend());
|
||||||
};
|
};
|
||||||
@@ -194,7 +194,7 @@ struct CollectFreeVariablesVisitor
|
|||||||
|
|
||||||
struct CollectPredicateSignaturesVisitor : public RecursiveFormulaVisitor<CollectPredicateSignaturesVisitor>
|
struct CollectPredicateSignaturesVisitor : public RecursiveFormulaVisitor<CollectPredicateSignaturesVisitor>
|
||||||
{
|
{
|
||||||
static void accept(const Predicate &predicate, const Formula &, std::vector<PredicateSignature> &predicateSignatures, Context &context)
|
static void accept(const Predicate &predicate, const Formula &, std::vector<PredicateSignature> &predicateSignatures)
|
||||||
{
|
{
|
||||||
const auto predicateSignatureMatches =
|
const auto predicateSignatureMatches =
|
||||||
[&predicate](const auto &predicateSignature)
|
[&predicate](const auto &predicateSignature)
|
||||||
@@ -206,35 +206,12 @@ struct CollectPredicateSignaturesVisitor : public RecursiveFormulaVisitor<Collec
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: avoid copies
|
// TODO: avoid copies
|
||||||
auto predicateSignature = PredicateSignature(std::string(predicate.name), predicate.arity());
|
predicateSignatures.emplace_back(std::string(predicate.name), predicate.arity());
|
||||||
|
|
||||||
// Ignore predicates that are declared #external
|
|
||||||
if (context.externalPredicateSignatures)
|
|
||||||
{
|
|
||||||
const auto matchesPredicateSignature =
|
|
||||||
[&](const auto &otherPredicateSignature)
|
|
||||||
{
|
|
||||||
return ast::matches(predicateSignature, otherPredicateSignature.predicateSignature);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto &externalPredicateSignatures = context.externalPredicateSignatures.value();
|
|
||||||
|
|
||||||
const auto matchingExternalPredicateSignature =
|
|
||||||
std::find_if(externalPredicateSignatures.begin(), externalPredicateSignatures.end(), matchesPredicateSignature);
|
|
||||||
|
|
||||||
if (matchingExternalPredicateSignature != externalPredicateSignatures.end())
|
|
||||||
{
|
|
||||||
matchingExternalPredicateSignature->used = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
predicateSignatures.emplace_back(std::move(predicateSignature));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore all other types of expressions
|
// Ignore all other types of expressions
|
||||||
template<class T>
|
template<class T>
|
||||||
static void accept(const T &, const Formula &, std::vector<PredicateSignature> &, const Context &)
|
static void accept(const T &, const Formula &, std::vector<PredicateSignature> &)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -263,10 +240,10 @@ bool matches(const PredicateSignature &lhs, const PredicateSignature &rhs)
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// TODO: remove const_cast
|
// TODO: remove const_cast
|
||||||
void collectPredicateSignatures(const Formula &formula, std::vector<PredicateSignature> &predicateSignatures, Context &context)
|
void collectPredicateSignatures(const Formula &formula, std::vector<PredicateSignature> &predicateSignatures)
|
||||||
{
|
{
|
||||||
auto &formulaMutable = const_cast<Formula &>(formula);
|
auto &formulaMutable = const_cast<Formula &>(formula);
|
||||||
formulaMutable.accept(CollectPredicateSignaturesVisitor(), formulaMutable, predicateSignatures, context);
|
formulaMutable.accept(CollectPredicateSignaturesVisitor(), formulaMutable, predicateSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -165,7 +165,7 @@ std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormu
|
|||||||
|
|
||||||
// Get a list of all predicates
|
// Get a list of all predicates
|
||||||
for (const auto &scopedFormula : scopedFormulas)
|
for (const auto &scopedFormula : scopedFormulas)
|
||||||
ast::collectPredicateSignatures(scopedFormula.formula, predicateSignatures, context);
|
ast::collectPredicateSignatures(scopedFormula.formula, predicateSignatures);
|
||||||
|
|
||||||
std::sort(predicateSignatures.begin(), predicateSignatures.end(),
|
std::sort(predicateSignatures.begin(), predicateSignatures.end(),
|
||||||
[](const auto &lhs, const auto &rhs)
|
[](const auto &lhs, const auto &rhs)
|
||||||
@@ -180,9 +180,47 @@ std::vector<ast::Formula> complete(std::vector<ast::ScopedFormula> &&scopedFormu
|
|||||||
|
|
||||||
std::vector<ast::Formula> completedFormulas;
|
std::vector<ast::Formula> completedFormulas;
|
||||||
|
|
||||||
|
// Warn about incorrect #external declarations
|
||||||
|
if (context.externalPredicateSignatures)
|
||||||
|
for (const auto &externalPredicateSignature : *context.externalPredicateSignatures)
|
||||||
|
{
|
||||||
|
// TODO: avoid code duplication
|
||||||
|
const auto matchesPredicateSignature =
|
||||||
|
[&](const auto &otherPredicateSignature)
|
||||||
|
{
|
||||||
|
return ast::matches(externalPredicateSignature, otherPredicateSignature);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto matchingPredicateSignature =
|
||||||
|
std::find_if(predicateSignatures.cbegin(), predicateSignatures.cend(), matchesPredicateSignature);
|
||||||
|
|
||||||
|
if (matchingPredicateSignature == predicateSignatures.cend())
|
||||||
|
context.logger.log(output::Priority::Warning) << "#external declaration of “" << externalPredicateSignature.name << "/" << externalPredicateSignature.arity <<"” does not match any known predicate";
|
||||||
|
}
|
||||||
|
|
||||||
// Complete predicates
|
// Complete predicates
|
||||||
for (const auto &predicateSignature : predicateSignatures)
|
for (const auto &predicateSignature : predicateSignatures)
|
||||||
|
{
|
||||||
|
// Don’t complete predicates that are declared #external
|
||||||
|
if (context.externalPredicateSignatures)
|
||||||
|
{
|
||||||
|
const auto matchesPredicateSignature =
|
||||||
|
[&](const auto &otherPredicateSignature)
|
||||||
|
{
|
||||||
|
return ast::matches(predicateSignature, otherPredicateSignature);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto &externalPredicateSignatures = context.externalPredicateSignatures.value();
|
||||||
|
|
||||||
|
const auto matchingExternalPredicateSignature =
|
||||||
|
std::find_if(externalPredicateSignatures.cbegin(), externalPredicateSignatures.cend(), matchesPredicateSignature);
|
||||||
|
|
||||||
|
if (matchingExternalPredicateSignature != externalPredicateSignatures.cend())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
completedFormulas.emplace_back(completePredicate(predicateSignature, scopedFormulas));
|
completedFormulas.emplace_back(completePredicate(predicateSignature, scopedFormulas));
|
||||||
|
}
|
||||||
|
|
||||||
// Complete integrity constraints
|
// Complete integrity constraints
|
||||||
for (auto &scopedFormula : scopedFormulas)
|
for (auto &scopedFormula : scopedFormulas)
|
||||||
|
@@ -194,7 +194,23 @@ void eliminateHiddenPredicates(const std::vector<ast::PredicateSignature> &predi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &visiblePredicateSignatures = context.visiblePredicateSignatures.value();
|
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
|
// Replace all occurrences of hidden predicates
|
||||||
for (size_t i = 0; i < predicateSignatures.size(); i++)
|
for (size_t i = 0; i < predicateSignatures.size(); i++)
|
||||||
@@ -204,18 +220,15 @@ void eliminateHiddenPredicates(const std::vector<ast::PredicateSignature> &predi
|
|||||||
const auto matchesPredicateSignature =
|
const auto matchesPredicateSignature =
|
||||||
[&](const auto &otherPredicateSignature)
|
[&](const auto &otherPredicateSignature)
|
||||||
{
|
{
|
||||||
return ast::matches(predicateSignature, otherPredicateSignature.predicateSignature);
|
return ast::matches(predicateSignature, otherPredicateSignature);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto matchingVisiblePredicateSignature =
|
const auto matchingVisiblePredicateSignature =
|
||||||
std::find_if(visiblePredicateSignatures.begin(), visiblePredicateSignatures.end(), matchesPredicateSignature);
|
std::find_if(visiblePredicateSignatures.cbegin(), visiblePredicateSignatures.cend(), matchesPredicateSignature);
|
||||||
|
|
||||||
// If the predicate ought to be visible, don’t eliminate it
|
// If the predicate ought to be visible, don’t eliminate it
|
||||||
if (matchingVisiblePredicateSignature != visiblePredicateSignatures.end())
|
if (matchingVisiblePredicateSignature != visiblePredicateSignatures.cend())
|
||||||
{
|
|
||||||
matchingVisiblePredicateSignature->used = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the predicate is not declared #external
|
// Check that the predicate is not declared #external
|
||||||
if (context.externalPredicateSignatures)
|
if (context.externalPredicateSignatures)
|
||||||
|
@@ -85,26 +85,6 @@ void translate(const char *fileName, std::istream &stream, Context &context)
|
|||||||
// Perform completion
|
// Perform completion
|
||||||
auto completedFormulas = complete(std::move(scopedFormulas), context);
|
auto completedFormulas = complete(std::move(scopedFormulas), context);
|
||||||
|
|
||||||
// Check for #show statements with undeclared predicates
|
|
||||||
if (context.visiblePredicateSignatures)
|
|
||||||
for (const auto &predicateSignature : context.visiblePredicateSignatures.value())
|
|
||||||
if (!predicateSignature.used)
|
|
||||||
context.logger.log(output::Priority::Warning)
|
|
||||||
<< "#show declaration of “"
|
|
||||||
<< predicateSignature.predicateSignature.name
|
|
||||||
<< "/" << predicateSignature.predicateSignature.arity
|
|
||||||
<< "” does not match any eligible predicate";
|
|
||||||
|
|
||||||
// Check for #external statements with undeclared predicates
|
|
||||||
if (context.externalPredicateSignatures)
|
|
||||||
for (const auto &predicateSignature : context.externalPredicateSignatures.value())
|
|
||||||
if (!predicateSignature.used)
|
|
||||||
context.logger.log(output::Priority::Warning)
|
|
||||||
<< "#external declaration of “"
|
|
||||||
<< predicateSignature.predicateSignature.name
|
|
||||||
<< "/" << predicateSignature.predicateSignature.arity
|
|
||||||
<< "” does not match any eligible predicate";
|
|
||||||
|
|
||||||
// Simplify output if specified
|
// Simplify output if specified
|
||||||
if (context.performSimplification)
|
if (context.performSimplification)
|
||||||
for (auto &completedFormula : completedFormulas)
|
for (auto &completedFormula : completedFormulas)
|
||||||
|
@@ -1,62 +0,0 @@
|
|||||||
#include <catch.hpp>
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <anthem/AST.h>
|
|
||||||
#include <anthem/Context.h>
|
|
||||||
#include <anthem/Translation.h>
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TEST_CASE("[placeholders] Programs with placeholders are correctly completed", "[placeholders]")
|
|
||||||
{
|
|
||||||
std::stringstream input;
|
|
||||||
std::stringstream output;
|
|
||||||
std::stringstream errors;
|
|
||||||
|
|
||||||
anthem::output::Logger logger(output, errors);
|
|
||||||
anthem::Context context(std::move(logger));
|
|
||||||
context.performSimplification = true;
|
|
||||||
context.performCompletion = true;
|
|
||||||
|
|
||||||
SECTION("no placeholders")
|
|
||||||
{
|
|
||||||
input <<
|
|
||||||
"colored(V, red) :- vertex(V), not colored(V, green), not colored(V, blue).";
|
|
||||||
anthem::translate("input", input, context);
|
|
||||||
|
|
||||||
CHECK(output.str() ==
|
|
||||||
"forall V1, V2 (colored(V1, V2) <-> (V2 = red and vertex(V1) and not colored(V1, green) and not colored(V1, blue)))\n"
|
|
||||||
"forall V3 not vertex(V3)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("single placeholder")
|
|
||||||
{
|
|
||||||
input <<
|
|
||||||
"#external vertex(1).\n"
|
|
||||||
"colored(V, red) :- vertex(V), not colored(V, green), not colored(V, blue).";
|
|
||||||
anthem::translate("input", input, context);
|
|
||||||
|
|
||||||
CHECK(output.str() ==
|
|
||||||
"forall V1, V2 (colored(V1, V2) <-> (V2 = red and vertex(V1) and not colored(V1, green) and not colored(V1, blue)))\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("complex example: graph coloring")
|
|
||||||
{
|
|
||||||
input <<
|
|
||||||
"#external color(1).\n"
|
|
||||||
"#external edge(2).\n"
|
|
||||||
"#external vertex(1).\n"
|
|
||||||
"#show color/2.\n"
|
|
||||||
"{color(V, C)} :- vertex(V), color(C).\n"
|
|
||||||
"covered(V) :- color(V, _).\n"
|
|
||||||
":- vertex(V), not covered(V).\n"
|
|
||||||
":- color(V1, C), color(V2, C), edge(V1, V2).";
|
|
||||||
anthem::translate("input", input, context);
|
|
||||||
|
|
||||||
CHECK(output.str() ==
|
|
||||||
"forall V1, V2 (color(V1, V2) <-> (vertex(V1) and color(V2) and color(V1, V2)))\n"
|
|
||||||
"forall U1 not (vertex(U1) and not exists U2 color(U1, U2))\n"
|
|
||||||
"forall U3, U4, U5 not (color(U3, U4) and color(U5, U4) and edge(U3, U5))\n");
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user