Implemented choice rules.
This commit is contained in:
parent
c819eeabfc
commit
70cb79b233
@ -19,12 +19,16 @@ struct Context
|
|||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
headTerms.clear();
|
headTerms.clear();
|
||||||
|
isChoiceRule = false;
|
||||||
|
numberOfHeadLiterals = 0;
|
||||||
auxiliaryBodyLiteralID = 1;
|
auxiliaryBodyLiteralID = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
output::Logger logger;
|
output::Logger logger;
|
||||||
|
|
||||||
std::vector<const Clingo::AST::Term *> headTerms;
|
std::vector<const Clingo::AST::Term *> headTerms;
|
||||||
|
bool isChoiceRule = false;
|
||||||
|
size_t numberOfHeadLiterals = 0;
|
||||||
size_t auxiliaryBodyLiteralID = 1;
|
size_t auxiliaryBodyLiteralID = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,15 +86,20 @@ struct LiteralCollectFunctionTermsVisitor
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// TODO: rename, because not only terms are collected anymore
|
||||||
struct HeadLiteralCollectFunctionTermsVisitor
|
struct HeadLiteralCollectFunctionTermsVisitor
|
||||||
{
|
{
|
||||||
void visit(const Clingo::AST::Literal &literal, const Clingo::AST::HeadLiteral &, Context &context)
|
void visit(const Clingo::AST::Literal &literal, const Clingo::AST::HeadLiteral &, Context &context)
|
||||||
{
|
{
|
||||||
|
context.numberOfHeadLiterals = 1;
|
||||||
|
|
||||||
literal.data.accept(LiteralCollectFunctionTermsVisitor(), literal, context);
|
literal.data.accept(LiteralCollectFunctionTermsVisitor(), literal, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::Disjunction &disjunction, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
void visit(const Clingo::AST::Disjunction &disjunction, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
||||||
{
|
{
|
||||||
|
context.numberOfHeadLiterals = disjunction.elements.size();
|
||||||
|
|
||||||
for (const auto &conditionalLiteral : disjunction.elements)
|
for (const auto &conditionalLiteral : disjunction.elements)
|
||||||
{
|
{
|
||||||
if (!conditionalLiteral.condition.empty())
|
if (!conditionalLiteral.condition.empty())
|
||||||
@ -104,9 +109,21 @@ struct HeadLiteralCollectFunctionTermsVisitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::Aggregate &, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
void visit(const Clingo::AST::Aggregate &aggregate, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(headLiteral.location, "“aggregate” head literals currently unsupported", context);
|
context.isChoiceRule = true;
|
||||||
|
context.numberOfHeadLiterals = aggregate.elements.size();
|
||||||
|
|
||||||
|
if (aggregate.left_guard || aggregate.right_guard)
|
||||||
|
throwErrorAtLocation(headLiteral.location, "aggregates with left or right guards not allowed", context);
|
||||||
|
|
||||||
|
for (const auto &conditionalLiteral : aggregate.elements)
|
||||||
|
{
|
||||||
|
if (!conditionalLiteral.condition.empty())
|
||||||
|
throwErrorAtLocation(headLiteral.location, "conditional literals in aggregates currently unsupported", context);
|
||||||
|
|
||||||
|
conditionalLiteral.literal.data.accept(LiteralCollectFunctionTermsVisitor(), conditionalLiteral.literal, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::HeadAggregate &, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
void visit(const Clingo::AST::HeadAggregate &, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
||||||
@ -244,9 +261,23 @@ struct HeadLiteralPrintSubstitutedVisitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::Aggregate &, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
void visit(const Clingo::AST::Aggregate &aggregate, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
||||||
{
|
{
|
||||||
throwErrorAtLocation(headLiteral.location, "“aggregate” head literals currently unsupported", context);
|
if (aggregate.left_guard || aggregate.right_guard)
|
||||||
|
throwErrorAtLocation(headLiteral.location, "aggregates with left or right guards not allowed", context);
|
||||||
|
|
||||||
|
for (auto i = aggregate.elements.cbegin(); i != aggregate.elements.cend(); i++)
|
||||||
|
{
|
||||||
|
const auto &conditionalLiteral = *i;
|
||||||
|
|
||||||
|
if (!conditionalLiteral.condition.empty())
|
||||||
|
throwErrorAtLocation(headLiteral.location, "conditional head literals currently unsupported", context);
|
||||||
|
|
||||||
|
if (i != aggregate.elements.cbegin())
|
||||||
|
context.logger.outputStream() << " " << Clingo::AST::BinaryOperator::Or << " ";
|
||||||
|
|
||||||
|
visit(conditionalLiteral.literal, headLiteral, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const Clingo::AST::HeadAggregate &, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
void visit(const Clingo::AST::HeadAggregate &, const Clingo::AST::HeadLiteral &headLiteral, Context &context)
|
||||||
|
@ -53,7 +53,7 @@ struct StatementVisitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule.body.empty() && context.headTerms.empty())
|
if (rule.body.empty() && context.headTerms.empty() && !context.isChoiceRule)
|
||||||
outputStream << Clingo::AST::Boolean({true});
|
outputStream << Clingo::AST::Boolean({true});
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -72,6 +72,23 @@ struct StatementVisitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle choice rules
|
||||||
|
if (context.isChoiceRule)
|
||||||
|
{
|
||||||
|
const bool isFirstOutput = rule.body.empty() && context.headTerms.empty();
|
||||||
|
|
||||||
|
if (!isFirstOutput)
|
||||||
|
outputStream << " " << Clingo::AST::BinaryOperator::And << " ";
|
||||||
|
|
||||||
|
if (context.numberOfHeadLiterals > 1 && !isFirstOutput)
|
||||||
|
outputStream << "(";
|
||||||
|
|
||||||
|
rule.head.data.accept(HeadLiteralPrintSubstitutedVisitor(), rule.head, context);
|
||||||
|
|
||||||
|
if (context.numberOfHeadLiterals > 1 && !isFirstOutput)
|
||||||
|
outputStream << ")";
|
||||||
|
}
|
||||||
|
|
||||||
outputStream << " " << output::Operator("->") << " ";
|
outputStream << " " << output::Operator("->") << " ";
|
||||||
|
|
||||||
// Print consequent of the implication
|
// Print consequent of the implication
|
||||||
|
Loading…
Reference in New Issue
Block a user