Started implementing translation for derived predicates.

This commit is contained in:
2016-12-07 01:56:06 +01:00
parent 443c126b88
commit 3b110c0b8a
28 changed files with 471 additions and 674 deletions

View File

@@ -30,7 +30,7 @@ class Action
const Expression *precondition() const;
const Expression *effect() const;
void normalize();
void normalize(expressions::DerivedPredicates &derivedPredicates);
private:
Action() = default;

View File

@@ -2,6 +2,7 @@
#define __PLASP__PDDL__EXPRESSION_H
#include <iosfwd>
#include <set>
#include <boost/intrusive_ptr.hpp>
@@ -131,15 +132,21 @@ class Expression
virtual ExpressionPointer copy();
// Transform into a normal form as used for the translation to ASP
ExpressionPointer normalized();
// Reduce the set of used expressions (eliminates implications, for instance)
virtual ExpressionPointer reduced();
virtual ExpressionPointer negationNormalized();
virtual ExpressionPointer prenex(Expression::Type lastQuantifierType = Expression::Type::Exists);
// Transform such that only existential (and no universal) quantifiers are used
virtual ExpressionPointer existentiallyQuantified();
// Simplify the expression equivalently
virtual ExpressionPointer simplified();
virtual ExpressionPointer disjunctionNormalized();
// Decompose expression into derived predicates (eliminate recursively nested expressions)
virtual ExpressionPointer decomposed(expressions::DerivedPredicates &derivedPredicates);
// Negate the expression
ExpressionPointer negated();
virtual void collectParameters(std::set<expressions::VariablePointer> &parameters);
virtual void print(std::ostream &ostream) const = 0;
protected:

View File

@@ -27,17 +27,13 @@ class TranslatorASP
void translateDomain() const;
void translateTypes() const;
void translatePredicates() const;
void translateDerivedPredicates() const;
void translateActions() const;
void translateProblem() const;
void translateInitialState() const;
void translateGoal() const;
void translateConstants(const std::string &heading, const expressions::Constants &constants) const;
void translateVariablesHead(const expressions::Variables &variables) const;
void translateVariablesBody(const expressions::Variables &variables) const;
void translateLiteral(const Expression &literal) const;
void translatePredicate(const expressions::Predicate &predicate) const;
Description &m_description;
output::ColorStream &m_outputStream;

View File

@@ -24,7 +24,6 @@ class And: public NAry<And>
static const std::string Identifier;
public:
ExpressionPointer disjunctionNormalized() override;
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
};

View File

@@ -40,10 +40,10 @@ class At: public ExpressionCRTP<At>
ExpressionPointer argument() const;
ExpressionPointer reduced() override;
ExpressionPointer negationNormalized() override;
ExpressionPointer prenex(Expression::Type lastExpressionType) override;
ExpressionPointer existentiallyQuantified() override;
ExpressionPointer simplified() override;
ExpressionPointer disjunctionNormalized() override;
void collectParameters(std::set<VariablePointer> &parameters) override;
void print(std::ostream &ostream) const override;

View File

@@ -32,13 +32,14 @@ class Binary: public ExpressionCRTP<Derived>
ExpressionPointer copy() override;
void setArgument(size_t i, ExpressionPointer argument);
std::array<ExpressionPointer, 2> &arguments();
const std::array<ExpressionPointer, 2> &arguments() const;
ExpressionPointer reduced() override;
ExpressionPointer negationNormalized() override;
ExpressionPointer prenex(Expression::Type lastExpressionType) override;
ExpressionPointer existentiallyQuantified() override;
ExpressionPointer simplified() override;
ExpressionPointer disjunctionNormalized() override;
void collectParameters(std::set<VariablePointer> &parameters) override;
void print(std::ostream &ostream) const override;
@@ -100,6 +101,14 @@ void Binary<Derived>::setArgument(size_t i, ExpressionPointer expression)
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
std::array<ExpressionPointer, 2> &Binary<Derived>::arguments()
{
return m_arguments;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
const std::array<ExpressionPointer, 2> &Binary<Derived>::arguments() const
{
@@ -111,11 +120,11 @@ const std::array<ExpressionPointer, 2> &Binary<Derived>::arguments() const
template<class Derived>
inline ExpressionPointer Binary<Derived>::reduced()
{
for (size_t i = 0; i < m_arguments.size(); i++)
for (auto &argument : m_arguments)
{
BOOST_ASSERT(m_arguments[i]);
BOOST_ASSERT(argument);
m_arguments[i] = m_arguments[i]->reduced();
argument = argument->reduced();
}
return this;
@@ -124,13 +133,13 @@ inline ExpressionPointer Binary<Derived>::reduced()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer Binary<Derived>::negationNormalized()
inline ExpressionPointer Binary<Derived>::existentiallyQuantified()
{
for (size_t i = 0; i < m_arguments.size(); i++)
for (auto &argument : m_arguments)
{
BOOST_ASSERT(m_arguments[i]);
BOOST_ASSERT(argument);
m_arguments[i] = m_arguments[i]->negationNormalized();
argument = argument->existentiallyQuantified();
}
return this;
@@ -138,23 +147,14 @@ inline ExpressionPointer Binary<Derived>::negationNormalized()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer Binary<Derived>::prenex(Expression::Type)
{
// TODO: implement by refactoring binary expressions
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer Binary<Derived>::simplified()
{
for (size_t i = 0; i < m_arguments.size(); i++)
for (auto &argument : m_arguments)
{
BOOST_ASSERT(m_arguments[i]);
BOOST_ASSERT(argument);
m_arguments[i] = m_arguments[i]->simplified();
argument = argument->simplified();
}
return this;
@@ -163,16 +163,10 @@ inline ExpressionPointer Binary<Derived>::simplified()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer Binary<Derived>::disjunctionNormalized()
inline void Binary<Derived>::collectParameters(std::set<VariablePointer> &parameters)
{
for (size_t i = 0; i < m_arguments.size(); i++)
{
BOOST_ASSERT(m_arguments[i]);
m_arguments[i] = m_arguments[i]->disjunctionNormalized();
}
return this;
for (const auto &argument : m_arguments)
argument->collectParameters(parameters);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,6 +1,8 @@
#ifndef __PLASP__PDDL__EXPRESSIONS__DERIVED_PREDICATE_H
#define __PLASP__PDDL__EXPRESSIONS__DERIVED_PREDICATE_H
#include <set>
#include <plasp/pddl/Expression.h>
namespace plasp
@@ -24,19 +26,22 @@ class DerivedPredicate: public ExpressionCRTP<DerivedPredicate>
// TODO: consider implementing parsing functions for compatibility with older PDDL versions
public:
explicit DerivedPredicate(size_t id);
void setPreconditions(std::vector<Expressions> &&preconditions);
const std::vector<Expressions> &preconditions() const;
size_t id() const;
const std::set<VariablePointer> &parameters() const;
void setArgument(ExpressionPointer argument);
ExpressionPointer argument() const;
void collectParameters(std::set<VariablePointer> &parameters) override;
void print(std::ostream &ostream) const override;
private:
size_t m_id;
void collectParameters();
ExpressionPointer m_argument;
// The arguments are interpreted as a disjunction of conjunctions
std::vector<Expressions> m_preconditions;
std::set<VariablePointer> m_parameters;
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -22,9 +22,6 @@ class Exists: public QuantifiedCRTP<Exists>
static const Expression::Type ExpressionType = Expression::Type::Exists;
static const std::string Identifier;
public:
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -24,7 +24,7 @@ class ForAll: public QuantifiedCRTP<ForAll>
static const std::string Identifier;
public:
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
ExpressionPointer existentiallyQuantified() override;
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -37,10 +37,10 @@ class NAry: public ExpressionCRTP<Derived>
const Expressions &arguments() const;
ExpressionPointer reduced() override;
ExpressionPointer negationNormalized() override;
ExpressionPointer prenex(Expression::Type lastExpressionType) override;
ExpressionPointer existentiallyQuantified() override;
ExpressionPointer simplified() override;
ExpressionPointer disjunctionNormalized() override;
void collectParameters(std::set<VariablePointer> &parameters) override;
void print(std::ostream &ostream) const override;
@@ -143,11 +143,11 @@ Expressions &NAry<Derived>::arguments()
template<class Derived>
inline ExpressionPointer NAry<Derived>::reduced()
{
for (size_t i = 0; i < m_arguments.size(); i++)
for (auto &argument : m_arguments)
{
BOOST_ASSERT(m_arguments[i]);
BOOST_ASSERT(argument);
m_arguments[i] = m_arguments[i]->reduced();
argument = argument->reduced();
}
return this;
@@ -156,13 +156,13 @@ inline ExpressionPointer NAry<Derived>::reduced()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer NAry<Derived>::negationNormalized()
inline ExpressionPointer NAry<Derived>::existentiallyQuantified()
{
for (size_t i = 0; i < m_arguments.size(); i++)
for (auto &argument : m_arguments)
{
BOOST_ASSERT(m_arguments[i]);
BOOST_ASSERT(argument);
m_arguments[i] = m_arguments[i]->negationNormalized();
argument = argument->existentiallyQuantified();
}
return this;
@@ -170,106 +170,22 @@ inline ExpressionPointer NAry<Derived>::negationNormalized()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer NAry<Derived>::prenex(Expression::Type lastExpressionType)
{
// First, move all childrens quantifiers to the front
for (size_t i = 0; i < m_arguments.size(); i++)
{
BOOST_ASSERT(m_arguments[i]);
m_arguments[i] = m_arguments[i]->prenex(lastExpressionType);
}
// Next, move all childrens quantifiers up
const auto isQuantifier =
[](const auto &expression)
{
return expression->expressionType() == Expression::Type::Exists
|| expression->expressionType() == Expression::Type::ForAll;
};
QuantifiedPointer front = nullptr;
QuantifiedPointer back = nullptr;
const auto moveUpQuantifiers =
[&](auto &child, const auto expressionType)
{
BOOST_ASSERT(child);
bool changed = false;
while (isQuantifier(child)
&& child->expressionType() == expressionType)
{
// Decouple quantifier from tree and replace it with its child
auto expression = Expression::moveUpQuantifiers(nullptr, child);
auto quantifier = QuantifiedPointer(dynamic_cast<Quantified *>(expression.get()));
if (!front)
front = quantifier;
else
back->setArgument(quantifier);
back = quantifier;
changed = true;
}
return changed;
};
bool changed = true;
const auto otherExpressionType = (lastExpressionType == Expression::Type::Exists)
? Expression::Type::ForAll : Expression::Type::Exists;
// Group quantifiers of the same type when moving them up, starting with the parent quantifiers type
while (changed)
{
changed = false;
// Group all quantifiers of the same type as the parent quantifier
for (size_t i = 0; i < m_arguments.size(); i++)
changed = moveUpQuantifiers(m_arguments[i], lastExpressionType) || changed;
// Group all other quantifiers
for (size_t i = 0; i < m_arguments.size(); i++)
changed = moveUpQuantifiers(m_arguments[i], otherExpressionType) || changed;
}
// If quantifiers were moved up, put this node back into the node hierarchy
if (front)
{
BOOST_ASSERT(back);
back->setArgument(this);
return front;
}
// If no quantifiers were moved up, simply return this node
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer NAry<Derived>::simplified()
{
// Associate same-type children, such as (a && (b && c)) == (a && b && c)
for (size_t i = 0; i < m_arguments.size();)
{
m_arguments[i] = m_arguments[i]->simplified();
auto &argument = m_arguments[i];
argument = argument->simplified();
if (m_arguments[i]->expressionType() != Derived::ExpressionType)
if (argument->expressionType() != Derived::ExpressionType)
{
i++;
continue;
}
auto child = m_arguments[i];
auto &nAryExpression = dynamic_cast<Derived &>(*child);
auto &nAryExpression = dynamic_cast<Derived &>(*argument);
BOOST_ASSERT(!nAryExpression.arguments().empty());
@@ -292,16 +208,10 @@ inline ExpressionPointer NAry<Derived>::simplified()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer NAry<Derived>::disjunctionNormalized()
inline void NAry<Derived>::collectParameters(std::set<VariablePointer> &parameters)
{
for (size_t i = 0; i < m_arguments.size(); i++)
{
BOOST_ASSERT(m_arguments[i]);
m_arguments[i] = m_arguments[i]->disjunctionNormalized();
}
return this;
for (const auto &argument : m_arguments)
argument->collectParameters(parameters);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -311,12 +221,11 @@ inline void NAry<Derived>::print(std::ostream &ostream) const
{
ostream << "(" << Derived::Identifier;
std::for_each(m_arguments.begin(), m_arguments.end(),
[&](auto &argument)
{
ostream << " ";
argument->print(ostream);
});
for (const auto &argument : m_arguments)
{
ostream << " ";
argument->print(ostream);
}
ostream << ")";
}

View File

@@ -35,12 +35,12 @@ class Not: public ExpressionCRTP<Not>
ExpressionPointer argument() const;
ExpressionPointer reduced() override;
ExpressionPointer negationNormalized() override;
ExpressionPointer prenex(Expression::Type lastExpressionType) override;
ExpressionPointer existentiallyQuantified() override;
ExpressionPointer simplified() override;
ExpressionPointer disjunctionNormalized() override;
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
void collectParameters(std::set<VariablePointer> &parameters) override;
void print(std::ostream &ostream) const override;
protected:

View File

@@ -30,6 +30,10 @@ class Predicate: public ExpressionCRTP<Predicate>
bool isDeclared() const;
ExpressionPointer decomposed(expressions::DerivedPredicates &derivedPredicates) override;
void collectParameters(std::set<VariablePointer> &parameters) override;
void print(std::ostream &ostream) const override;
private:

View File

@@ -4,6 +4,7 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/expressions/DerivedPredicate.h>
#include <plasp/pddl/expressions/Variable.h>
namespace plasp
@@ -52,10 +53,11 @@ class QuantifiedCRTP: public Quantified
ExpressionPointer copy() override;
ExpressionPointer reduced() override;
ExpressionPointer negationNormalized() override;
ExpressionPointer prenex(Expression::Type lastExpressionType) override;
ExpressionPointer existentiallyQuantified() override;
ExpressionPointer simplified() override;
ExpressionPointer disjunctionNormalized() override;
ExpressionPointer decomposed(expressions::DerivedPredicates &derivedPredicates) override;
void collectParameters(std::set<VariablePointer> &parameters);
void print(std::ostream &ostream) const override;
};
@@ -155,30 +157,17 @@ inline ExpressionPointer QuantifiedCRTP<Derived>::reduced()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer QuantifiedCRTP<Derived>::negationNormalized()
inline ExpressionPointer QuantifiedCRTP<Derived>::existentiallyQuantified()
{
BOOST_ASSERT(m_argument);
m_argument = m_argument->negationNormalized();
m_argument = m_argument->existentiallyQuantified();
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer QuantifiedCRTP<Derived>::prenex(Expression::Type)
{
BOOST_ASSERT(m_argument);
m_argument = m_argument->prenex(Derived::ExpressionType);
// Quantifiers may not move before other quantifiers, their order matters
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer QuantifiedCRTP<Derived>::simplified()
{
@@ -206,13 +195,28 @@ inline ExpressionPointer QuantifiedCRTP<Derived>::simplified()
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline ExpressionPointer QuantifiedCRTP<Derived>::disjunctionNormalized()
inline ExpressionPointer QuantifiedCRTP<Derived>::decomposed(expressions::DerivedPredicates &derivedPredicates)
{
BOOST_ASSERT(m_argument);
derivedPredicates.emplace_back(new DerivedPredicate());
auto &derivedPredicate = derivedPredicates.back();
m_argument = m_argument->disjunctionNormalized();
m_argument = m_argument->decomposed(derivedPredicates);
return this;
derivedPredicate->setPreconditions({{this}});
return derivedPredicate;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived>
inline void QuantifiedCRTP<Derived>::collectParameters(std::set<VariablePointer> &parameters)
{
m_argument->collectParameters(parameters);
// Remove bound variables
for (const auto &variable : m_variables)
parameters.erase(variable);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -39,6 +39,8 @@ class Variable: public ExpressionCRTP<Variable>
void setDirty(bool isDirty = true);
bool isDirty() const;
void collectParameters(std::set<VariablePointer> &parameters) override;
void print(std::ostream &ostream) const override;
private: