Started implementing translation for derived predicates.
This commit is contained in:
@@ -30,7 +30,7 @@ class Action
|
||||
const Expression *precondition() const;
|
||||
const Expression *effect() const;
|
||||
|
||||
void normalize();
|
||||
void normalize(expressions::DerivedPredicates &derivedPredicates);
|
||||
|
||||
private:
|
||||
Action() = default;
|
||||
|
@@ -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> ¶meters);
|
||||
|
||||
virtual void print(std::ostream &ostream) const = 0;
|
||||
|
||||
protected:
|
||||
|
@@ -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;
|
||||
|
@@ -24,7 +24,6 @@ class And: public NAry<And>
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
ExpressionPointer disjunctionNormalized() override;
|
||||
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
|
||||
};
|
||||
|
||||
|
@@ -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> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
|
@@ -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> ¶meters) 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> ¶meters)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -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> ¶meters() const;
|
||||
|
||||
void setArgument(ExpressionPointer argument);
|
||||
ExpressionPointer argument() const;
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) 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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -24,7 +24,7 @@ class ForAll: public QuantifiedCRTP<ForAll>
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
|
||||
ExpressionPointer existentiallyQuantified() override;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -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> ¶meters) 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 children’s 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 quantifier’s 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> ¶meters)
|
||||
{
|
||||
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 << ")";
|
||||
}
|
||||
|
@@ -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> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
protected:
|
||||
|
@@ -30,6 +30,10 @@ class Predicate: public ExpressionCRTP<Predicate>
|
||||
|
||||
bool isDeclared() const;
|
||||
|
||||
ExpressionPointer decomposed(expressions::DerivedPredicates &derivedPredicates) override;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
|
@@ -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> ¶meters);
|
||||
|
||||
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> ¶meters)
|
||||
{
|
||||
m_argument->collectParameters(parameters);
|
||||
|
||||
// Remove bound variables
|
||||
for (const auto &variable : m_variables)
|
||||
parameters.erase(variable);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -39,6 +39,8 @@ class Variable: public ExpressionCRTP<Variable>
|
||||
void setDirty(bool isDirty = true);
|
||||
bool isDirty() const;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
|
Reference in New Issue
Block a user