Skip to content

Commit

Permalink
model: First shot at fluent synchronization
Browse files Browse the repository at this point in the history
Although what's really being synced is an ExogEvent for an ExogAction
that is being generated if a fluent is marked synced.
  • Loading branch information
vmatare committed Dec 3, 2019
1 parent decbcea commit fee583e
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 17 deletions.
3 changes: 3 additions & 0 deletions src/model/action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ AbstractAction::AbstractAction(
const vector<unique_ptr<AbstractEffectAxiom>> &AbstractAction::effects() const
{ return effects_; }

vector<unique_ptr<AbstractEffectAxiom>> &AbstractAction::effects()
{ return effects_; }


void AbstractAction::add_effect(AbstractEffectAxiom *effect)
{
Expand Down
17 changes: 17 additions & 0 deletions src/model/effect_axiom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,21 @@ void AbstractEffectAxiom::set_condition(Expression *condition)
condition_->set_parent(this);
}




template<>
const Reference<Fluent> &EffectAxiom<Reference<Fluent>>::fluent() const
{ return lhs(); }

template<>
const Reference<Fluent> &EffectAxiom<FieldAccess>::fluent() const
{ return dynamic_cast<const Reference<Fluent> &>(lhs().subject()); }

template<>
const Reference<Fluent> &EffectAxiom<ListAccess>::fluent() const
{ return dynamic_cast<const Reference<Fluent> &>(lhs().subject()); }



} // namespace gologpp
3 changes: 3 additions & 0 deletions src/model/effect_axiom.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class AbstractEffectAxiom : public virtual AbstractLanguageElement {
const Expression &condition() const;
Expression &condition();
void set_condition(Expression *condition);
virtual const Reference<Fluent> &fluent() const = 0;

protected:
AbstractAction *action_;
Expand Down Expand Up @@ -95,6 +96,8 @@ class EffectAxiom : public AbstractEffectAxiom, public NoScopeOwner, public Lang
virtual const Scope &parent_scope() const override
{ return action().scope(); }

virtual const Reference<Fluent> &fluent() const override;


DEFINE_ATTACH_SEMANTICS_WITH_MEMBERS(*condition_, *assignment_)

Expand Down
45 changes: 44 additions & 1 deletion src/model/execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "history.h"
#include "platform_backend.h"
#include "activity.h"
#include "effect_axiom.h"

#include <iostream>

Expand Down Expand Up @@ -100,6 +101,37 @@ History &AExecutionContext::history()
{ return history_; }


void AExecutionContext::precompile()
{
precompile_();
}

void AExecutionContext::postcompile()
{ postcompile_(); }


void AExecutionContext::sync_fluent(const Reference<Fluent> &f, const Activity &context)
{
vector<unique_ptr<Value>> sync_exog_args;
for (const unique_ptr<Expression> &arg : f.args())
sync_exog_args.emplace_back(
new Value(arg->abstract_expr_semantics().evaluate(context, history()))
);

sync_exog_args.emplace_back(
new Value(context.target()->senses()->abstract_expr_semantics().evaluate(context, history()))
);

backend().sync_event(
ExogEvent(
context.target()->senses()->target()->sync_action(),
std::move(sync_exog_args)
)
);
}




ExecutionContext::ExecutionContext(unique_ptr<SemanticsFactory> &&semantics, unique_ptr<PlatformBackend> &&exec_backend)
: AExecutionContext(std::move(semantics), std::move(exec_backend))
Expand Down Expand Up @@ -139,11 +171,22 @@ void ExecutionContext::run(Block &&program)
backend().start_activity(trans);
else if (trans->hook() == Transition::Hook::FINISH) {
shared_ptr<Activity> activity = backend().end_activity(trans);
if (trans->target()->senses())

// Sync effects if necessary
for (const auto &effect : trans->target()->effects())
if (effect->fluent()->synced())
sync_fluent(effect->fluent(), *activity);

if (trans->target()->senses()) {
history().abstract_semantics().append_sensing_result(
*activity->target()->senses(),
activity->sensing_result().get()
);

// Sync sensed fluent if necessary
if (trans->target()->senses()->target()->synced())
sync_fluent(*trans->target()->senses(), *activity);
}
}
else
backend().end_activity(trans);
Expand Down
10 changes: 8 additions & 2 deletions src/model/execution.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ class AExecutionContext {
/**
* @brief compile called once for the toplevel @param program.
*/
virtual void precompile() = 0;
void precompile();
virtual void compile(const Block &program) = 0;
virtual void compile(const Fluent &fluent) = 0;
virtual void compile(const AbstractAction &action) = 0;
virtual void compile(const Function &function) = 0;
virtual void compile(const Procedure &function) = 0;
virtual void postcompile() = 0;
void postcompile();

virtual void run(Block &&program) = 0;

Expand All @@ -71,7 +71,13 @@ class AExecutionContext {
PlatformBackend &backend();
History &history();

protected:
void sync_fluent(const Reference<Fluent> &f, const Activity &context);

private:
virtual void precompile_() = 0;
virtual void postcompile_() = 0;

std::mutex exog_mutex_;
std::condition_variable queue_empty_condition_;
std::mutex queue_empty_mutex_;
Expand Down
3 changes: 3 additions & 0 deletions src/model/expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ const AbstractLanguageElement *Expression::parent() const
void Expression::set_parent(AbstractLanguageElement *parent)
{ parent_ = parent; }

AbstractSemantics<Expression> &Expression::abstract_expr_semantics() const
{ return dynamic_cast<AbstractSemantics<Expression> &>(abstract_semantics()); }

const string &Expression::type_name() const
{ return type().name(); }

Expand Down
2 changes: 1 addition & 1 deletion src/model/expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Expression : public virtual AbstractLanguageElement {
AbstractLanguageElement *parent();
const AbstractLanguageElement *parent() const;
void set_parent(AbstractLanguageElement *parent);

AbstractSemantics<Expression> &abstract_expr_semantics() const;
const string &type_name() const;

protected:
Expand Down
68 changes: 64 additions & 4 deletions src/model/fluent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "fluent.h"
#include "execution.h"
#include "effect_axiom.h"

namespace gologpp {

Expand Down Expand Up @@ -106,20 +107,29 @@ Fluent::Fluent(Scope *own_scope, const string &type_name, const string &name, co
const vector<unique_ptr<InitialValue>> &Fluent::initially() const
{ return initial_values_; }

void Fluent::define(const vector<InitialValue *> &initial_values)
{ define(boost::optional<vector<InitialValue *>>(initial_values)); }
bool Fluent::synced() const
{ return sync_action_.get(); }

const ExogAction &Fluent::sync_action() const
{ return *sync_action_; }

ExogAction &Fluent::sync_action()
{ return *sync_action_; }

void Fluent::define(const vector<InitialValue *> &initial_values, bool synced)
{ define(boost::optional<vector<InitialValue *>>(initial_values), synced); }

Reference<Fluent> *Fluent::make_ref(const vector<Expression *> &args)
{ return make_ref_<Fluent>(args); }

Expression *Fluent::ref(const vector<Expression *> &args)
Reference<Fluent> *Fluent::ref(const vector<Expression *> &args)
{ return make_ref(args); }

void Fluent::compile(AExecutionContext &ctx)
{ ctx.compile(*this); }


void Fluent::define(const boost::optional<vector<InitialValue *>> &initial_values)
void Fluent::define(const boost::optional<vector<InitialValue *>> &initial_values, bool synced)
{
for (shared_ptr<Variable> &param : params())
if (param->domain().is_implicit())
Expand Down Expand Up @@ -154,6 +164,56 @@ void Fluent::define(const boost::optional<vector<InitialValue *>> &initial_value
}
else
throw UserError("Fluent " + signature_str() + ": No `initially:' block");

if (synced) {
Scope *exog_scope = new Scope(global_scope());

vector<shared_ptr<Variable>> exog_params;
vector<Expression *> effect_fluent_args;
for (const auto &fluent_param : this->params()) {
shared_ptr<Variable> exog_param = exog_scope->get_var(
VarDefinitionMode::FORCE,
static_cast<string>(fluent_param->type()),
this->name() + "_" + fluent_param->name()
);
exog_params.push_back(exog_param);
effect_fluent_args.push_back(exog_param->ref());
}

exog_params.push_back(
exog_scope->get_var(
VarDefinitionMode::FORCE,
static_cast<string>(this->type()),
this->name() + "_value"
)
);

Reference<Variable> *effect_fluent_value = exog_params.back()->ref();

ExogAction *sync_exog = global_scope().declare_global<ExogAction>(
exog_scope,
UndefinedType::name(),
"gpp~sync_" + this->name(),
{ exog_params }
);

EffectAxiom<Reference<Fluent>> *set_fluent_effect = new EffectAxiom<Reference<Fluent>>();
set_fluent_effect->define(
{}, // no condition
this->ref(effect_fluent_args),
effect_fluent_value
);

sync_exog->define(
{}, // no precondition
vector<AbstractEffectAxiom *>{ set_fluent_effect },
{} // no mapping
);

global_scope().register_global(sync_exog);

this->sync_action_.reset(sync_exog);
}
}


Expand Down
10 changes: 7 additions & 3 deletions src/model/fluent.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,23 @@ class Fluent
virtual ~Fluent() override = default;

const vector<unique_ptr<InitialValue>> &initially() const;
bool synced() const;
const ExogAction &sync_action() const;
ExogAction &sync_action();

void define(const vector<InitialValue *> &initial_values);
void define(const boost::optional<vector<InitialValue *>> &initial_values);
void define(const vector<InitialValue *> &initial_values, bool synced = false);
void define(const boost::optional<vector<InitialValue *>> &initial_values, bool synced = false);

Reference<Fluent> *make_ref(const vector<Expression *> &params);
virtual Expression *ref(const vector<Expression *> &params) override;
virtual Reference<Fluent> *ref(const vector<Expression *> &params) override;

virtual void attach_semantics(SemanticsFactory &implementor) override;
virtual string to_string(const string &pfx) const override;
virtual void compile(AExecutionContext &ctx) override;

private:
vector<unique_ptr<InitialValue>> initial_values_;
shared_ptr<ExogAction> sync_action_;
};


Expand Down
2 changes: 2 additions & 0 deletions src/model/gologpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ class History;

template<class> class Semantics;
template<class> class AbstractSemantics;
template<> class AbstractSemantics<Expression>;
template<> class AbstractSemantics<Instruction>;

class SemanticsFactory;

Expand Down
3 changes: 3 additions & 0 deletions src/model/platform_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,8 @@ Clock::time_point DummyBackend::time() const noexcept
}


void DummyBackend::sync_event(const ExogEvent &)
{ throw Bug("Not implemented"); }


}
3 changes: 3 additions & 0 deletions src/model/platform_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class PlatformBackend {
virtual Clock::time_point time() const noexcept = 0;
void set_context(AExecutionContext *ctx);

virtual void sync_event(const ExogEvent &) = 0;

private:
virtual void execute_activity(shared_ptr<Activity> a) = 0;
Expand All @@ -82,6 +83,8 @@ class DummyBackend : public PlatformBackend {
virtual void preempt_activity(shared_ptr<Activity>) override;
virtual Clock::time_point time() const noexcept override;

virtual void sync_event(const ExogEvent &) override;

private:
virtual void execute_activity(shared_ptr<Activity> a) override;

Expand Down
11 changes: 9 additions & 2 deletions src/model/reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ class ReferenceBase
)
{}

ReferenceBase(TargetT &target, vector<unique_ptr<ArgsT>> &&args)
: ReferenceBase(std::dynamic_pointer_cast<TargetT>(target.shared_from_this()), std::move(args))
{}

ReferenceBase(const string &target_name, const boost::optional<vector<ArgsT *>> &args)
: ReferenceBase(target_name, args.get_value_or({}))
{}
Expand All @@ -122,8 +126,11 @@ class ReferenceBase
TargetT &operator * () const
{ return target(); }

TargetT *operator -> () const
{ return &target(); }
const TargetT *operator -> () const
{ return target().get(); }

TargetT *operator -> ()
{ return target().get(); }

bool operator == (const ReferenceBase<TargetT, ArgsT> &other) const
{
Expand Down
1 change: 0 additions & 1 deletion src/model/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#define GOLOGPP_IMPLEMENTATION_H_

#include "gologpp.h"
#include "expressions.h"
#include <memory>

#include <boost/preprocessor/seq/for_each.hpp>
Expand Down
2 changes: 1 addition & 1 deletion src/semantics/readylog/execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ std::string ReadylogContext::find_boilerplate() {
}


void ReadylogContext::postcompile()
void ReadylogContext::postcompile_()
{
if (!ec_query(EC_atom("compile_SSAs")))
throw Bug("Failed to compile SSAs");
Expand Down
5 changes: 3 additions & 2 deletions src/semantics/readylog/execution.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,11 @@ class ReadylogContext : public ExecutionContext {
static void shutdown();
static ReadylogContext &instance();

virtual void precompile() override {}
virtual void compile(const Block &block) override;
virtual void compile(const AbstractAction &action) override;
virtual void compile(const Fluent &fluent) override;
virtual void compile(const Function &function) override;
virtual void compile(const Procedure &proc) override;
virtual void postcompile() override;

virtual bool final(Block &program, History &history) override;
virtual bool trans(Block &program, History &history) override;
Expand All @@ -61,6 +59,9 @@ class ReadylogContext : public ExecutionContext {
private:
ReadylogContext(const eclipse_opts &options, unique_ptr<PlatformBackend> &&exec_backend);

virtual void precompile_() override {}
virtual void postcompile_() override;

virtual void compile_term(const EC_word &term);
std::string find_readylog();
std::string find_boilerplate();
Expand Down

0 comments on commit fee583e

Please sign in to comment.