diff --git a/include/anthem/ASTUtils.h b/include/anthem/ASTUtils.h index 66bae55..6ddadf2 100644 --- a/include/anthem/ASTUtils.h +++ b/include/anthem/ASTUtils.h @@ -31,6 +31,7 @@ class VariableStack //////////////////////////////////////////////////////////////////////////////////////////////////// +std::vector collectFreeVariables(const ast::Formula &formula); std::vector collectFreeVariables(const ast::Formula &formula, ast::VariableStack &variableStack); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/anthem/ASTUtils.cpp b/src/anthem/ASTUtils.cpp index b4e8b84..ddb34e0 100644 --- a/src/anthem/ASTUtils.cpp +++ b/src/anthem/ASTUtils.cpp @@ -175,6 +175,14 @@ struct CollectFreeVariablesVisitor //////////////////////////////////////////////////////////////////////////////////////////////////// +std::vector collectFreeVariables(const ast::Formula &formula) +{ + ast::VariableStack variableStack; + return collectFreeVariables(formula, variableStack); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + std::vector collectFreeVariables(const ast::Formula &formula, ast::VariableStack &variableStack) { std::vector freeVariables; diff --git a/src/anthem/Completion.cpp b/src/anthem/Completion.cpp index 2cb93ed..5382ddd 100644 --- a/src/anthem/Completion.cpp +++ b/src/anthem/Completion.cpp @@ -32,7 +32,10 @@ void completePredicate(const ast::Predicate &predicate, std::vector()); auto &implies = formula.get(); - assert(implies.consequent.is()); + + if (!implies.consequent.is()) + continue; + auto &otherPredicate = implies.consequent.get(); if (predicate.arity() != otherPredicate.arity() || predicate.name != otherPredicate.name) @@ -60,7 +63,13 @@ void completePredicate(const ast::Predicate &predicate, std::vector()); auto &implies = formula.get(); - assert(implies.consequent.is()); + + if (!implies.consequent.is()) + { + i++; + continue; + } + auto &otherPredicate = implies.consequent.get(); if (predicate.arity() != otherPredicate.arity() || predicate.name != otherPredicate.name) @@ -107,6 +116,30 @@ void completePredicate(const ast::Predicate &predicate, std::vector()); + auto &implies = formula.get(); + assert(implies.consequent.is()); + auto &boolean = implies.consequent.get(); + + auto variables = ast::collectFreeVariables(implies.antecedent); + + auto argument = (boolean.value == true) + ? std::move(implies.antecedent) + : ast::Formula::make(std::move(implies.antecedent)); + + if (variables.empty()) + { + formula = std::move(argument); + return; + } + + formula = ast::Formula::make(std::move(variables), std::move(argument)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void complete(std::vector &formulas) { for (const auto &formula : formulas) @@ -116,17 +149,22 @@ void complete(std::vector &formulas) auto &implies = formula.get(); - if (!implies.consequent.is()) - throw std::runtime_error("cannot perform completion, only single predicates supported as formula consequent currently"); + if (!implies.consequent.is() && !implies.consequent.is()) + throw std::runtime_error("cannot perform completion, only single predicates and Booleans supported as formula consequent currently"); } for (std::size_t i = 0; i < formulas.size(); i++) { auto &formula = formulas[i]; auto &implies = formula.get(); - auto &predicate = implies.consequent.get(); - completePredicate(predicate, formulas, i); + if (implies.consequent.is()) + { + auto &predicate = implies.consequent.get(); + completePredicate(predicate, formulas, i); + } + else if (implies.consequent.is()) + completeBoolean(formula); } }