From decbcea53bafcc56a34047830f4c616fc83a1648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Matar=C3=A9?= Date: Mon, 2 Dec 2019 15:11:55 +0100 Subject: [PATCH 1/2] refactor sensing action handling AbstractSemantics::append_sensing_result(...) now takes a fluent and a value. --- src/model/execution.cpp | 10 ++++++++-- src/model/fluent.h | 2 -- src/model/history.h | 2 +- src/semantics/readylog/action.cpp | 9 --------- src/semantics/readylog/action.h | 3 --- src/semantics/readylog/history.cpp | 15 +++++++++++++-- src/semantics/readylog/history.h | 2 +- 7 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/model/execution.cpp b/src/model/execution.cpp index 9fe37b75..7ee725c7 100644 --- a/src/model/execution.cpp +++ b/src/model/execution.cpp @@ -137,8 +137,14 @@ void ExecutionContext::run(Block &&program) backend().cancel_activity(trans); else if (trans->hook() == Transition::Hook::START) backend().start_activity(trans); - else if (trans->hook() == Transition::Hook::FINISH && trans->target()->senses()) - history().abstract_semantics().append_sensing_result(backend().end_activity(trans)); + else if (trans->hook() == Transition::Hook::FINISH) { + shared_ptr activity = backend().end_activity(trans); + if (trans->target()->senses()) + history().abstract_semantics().append_sensing_result( + *activity->target()->senses(), + activity->sensing_result().get() + ); + } else backend().end_activity(trans); } diff --git a/src/model/fluent.h b/src/model/fluent.h index f6db652f..f236c9d2 100644 --- a/src/model/fluent.h +++ b/src/model/fluent.h @@ -84,9 +84,7 @@ class Fluent virtual Expression *ref(const vector ¶ms) override; virtual void attach_semantics(SemanticsFactory &implementor) override; - virtual string to_string(const string &pfx) const override; - virtual void compile(AExecutionContext &ctx) override; private: diff --git a/src/model/history.h b/src/model/history.h index f9923339..039de785 100644 --- a/src/model/history.h +++ b/src/model/history.h @@ -34,7 +34,7 @@ class AbstractSemantics : public AbstractSemantics get_last_transition() = 0; virtual void append_exog(shared_ptr>) = 0; - virtual void append_sensing_result(shared_ptr) = 0; + virtual void append_sensing_result(const Reference &f, const Value &v) = 0; virtual bool should_progress() const = 0; virtual void progress() = 0; diff --git a/src/semantics/readylog/action.cpp b/src/semantics/readylog/action.cpp index a9bc6312..cf9747f1 100644 --- a/src/semantics/readylog/action.cpp +++ b/src/semantics/readylog/action.cpp @@ -154,15 +154,6 @@ EC_word Semantics::plterm() } -EC_word Semantics::sensing_result() -{ - return ::term(EC_functor("e", 2), - activity().target()->senses()->semantics().plterm(), - activity().sensing_result()->semantics().plterm() - ); -} - - const Transition &Semantics::trans() { return dynamic_cast(element()); } diff --git a/src/semantics/readylog/action.h b/src/semantics/readylog/action.h index 9d5e17ab..9110786f 100644 --- a/src/semantics/readylog/action.h +++ b/src/semantics/readylog/action.h @@ -89,9 +89,7 @@ class Semantics virtual ~Semantics() override = default; const Activity &activity(); - virtual EC_word plterm() override; - EC_word sensing_result(); }; @@ -105,7 +103,6 @@ class Semantics virtual ~Semantics() override = default; const Transition &trans(); - virtual EC_word plterm() override; }; diff --git a/src/semantics/readylog/history.cpp b/src/semantics/readylog/history.cpp index 8828aadb..65fe7a7f 100644 --- a/src/semantics/readylog/history.cpp +++ b/src/semantics/readylog/history.cpp @@ -22,6 +22,7 @@ #include "execution.h" #include "utilities.h" #include "value.h" +#include "fluent.h" #include #include @@ -114,8 +115,18 @@ shared_ptr Semantics::get_last_transition() void Semantics::append_exog(shared_ptr> trans) { extend_history(::list(trans->semantics().plterm(), current_history())); } -void Semantics::append_sensing_result(shared_ptr a) -{ extend_history(::list(a->semantics().sensing_result(), current_history())); } +void Semantics::append_sensing_result(const Reference &f, const Value &v) +{ + extend_history( + ::list( + ::term(EC_functor("e", 2), + f.semantics().plterm(), + v.semantics().plterm() + ), + current_history() + ) + ); +} EC_word Semantics::current_history() const { return readylog_history_; } diff --git a/src/semantics/readylog/history.h b/src/semantics/readylog/history.h index 874f7a7d..c5240b0e 100644 --- a/src/semantics/readylog/history.h +++ b/src/semantics/readylog/history.h @@ -34,7 +34,7 @@ class Semantics : public AbstractSemantics { virtual shared_ptr get_last_transition() override; virtual void append_exog(shared_ptr> exog) override; - virtual void append_sensing_result(shared_ptr) override; + virtual void append_sensing_result(const Reference &f, const Value &v) override; virtual bool should_progress() const override; virtual void progress() override; From fee583edeaa2f3a27800e0af1c04e39250fe7834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Matar=C3=A9?= Date: Mon, 2 Dec 2019 19:33:45 +0100 Subject: [PATCH 2/2] model: First shot at fluent synchronization Although what's really being synced is an ExogEvent for an ExogAction that is being generated if a fluent is marked synced. --- src/model/action.cpp | 3 ++ src/model/effect_axiom.cpp | 17 +++++++ src/model/effect_axiom.h | 3 ++ src/model/execution.cpp | 45 +++++++++++++++++- src/model/execution.h | 10 +++- src/model/expressions.cpp | 3 ++ src/model/expressions.h | 2 +- src/model/fluent.cpp | 68 ++++++++++++++++++++++++++-- src/model/fluent.h | 10 ++-- src/model/gologpp.h | 2 + src/model/platform_backend.cpp | 3 ++ src/model/platform_backend.h | 3 ++ src/model/reference.h | 11 ++++- src/model/semantics.h | 1 - src/semantics/readylog/execution.cpp | 2 +- src/semantics/readylog/execution.h | 5 +- 16 files changed, 171 insertions(+), 17 deletions(-) diff --git a/src/model/action.cpp b/src/model/action.cpp index 18ea55c9..cfb84236 100644 --- a/src/model/action.cpp +++ b/src/model/action.cpp @@ -51,6 +51,9 @@ AbstractAction::AbstractAction( const vector> &AbstractAction::effects() const { return effects_; } +vector> &AbstractAction::effects() +{ return effects_; } + void AbstractAction::add_effect(AbstractEffectAxiom *effect) { diff --git a/src/model/effect_axiom.cpp b/src/model/effect_axiom.cpp index 51bbe259..5ee14c22 100644 --- a/src/model/effect_axiom.cpp +++ b/src/model/effect_axiom.cpp @@ -49,4 +49,21 @@ void AbstractEffectAxiom::set_condition(Expression *condition) condition_->set_parent(this); } + + + +template<> +const Reference &EffectAxiom>::fluent() const +{ return lhs(); } + +template<> +const Reference &EffectAxiom::fluent() const +{ return dynamic_cast &>(lhs().subject()); } + +template<> +const Reference &EffectAxiom::fluent() const +{ return dynamic_cast &>(lhs().subject()); } + + + } // namespace gologpp diff --git a/src/model/effect_axiom.h b/src/model/effect_axiom.h index 87293c5b..83009810 100644 --- a/src/model/effect_axiom.h +++ b/src/model/effect_axiom.h @@ -47,6 +47,7 @@ class AbstractEffectAxiom : public virtual AbstractLanguageElement { const Expression &condition() const; Expression &condition(); void set_condition(Expression *condition); + virtual const Reference &fluent() const = 0; protected: AbstractAction *action_; @@ -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() const override; + DEFINE_ATTACH_SEMANTICS_WITH_MEMBERS(*condition_, *assignment_) diff --git a/src/model/execution.cpp b/src/model/execution.cpp index 7ee725c7..b3964cc7 100644 --- a/src/model/execution.cpp +++ b/src/model/execution.cpp @@ -22,6 +22,7 @@ #include "history.h" #include "platform_backend.h" #include "activity.h" +#include "effect_axiom.h" #include @@ -100,6 +101,37 @@ History &AExecutionContext::history() { return history_; } +void AExecutionContext::precompile() +{ + precompile_(); +} + +void AExecutionContext::postcompile() +{ postcompile_(); } + + +void AExecutionContext::sync_fluent(const Reference &f, const Activity &context) +{ + vector> sync_exog_args; + for (const unique_ptr &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 &&semantics, unique_ptr &&exec_backend) : AExecutionContext(std::move(semantics), std::move(exec_backend)) @@ -139,11 +171,22 @@ void ExecutionContext::run(Block &&program) backend().start_activity(trans); else if (trans->hook() == Transition::Hook::FINISH) { shared_ptr 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); diff --git a/src/model/execution.h b/src/model/execution.h index eb53cf51..d9224c32 100644 --- a/src/model/execution.h +++ b/src/model/execution.h @@ -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; @@ -71,7 +71,13 @@ class AExecutionContext { PlatformBackend &backend(); History &history(); +protected: + void sync_fluent(const Reference &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_; diff --git a/src/model/expressions.cpp b/src/model/expressions.cpp index 99694be9..cd9e9aa7 100644 --- a/src/model/expressions.cpp +++ b/src/model/expressions.cpp @@ -40,6 +40,9 @@ const AbstractLanguageElement *Expression::parent() const void Expression::set_parent(AbstractLanguageElement *parent) { parent_ = parent; } +AbstractSemantics &Expression::abstract_expr_semantics() const +{ return dynamic_cast &>(abstract_semantics()); } + const string &Expression::type_name() const { return type().name(); } diff --git a/src/model/expressions.h b/src/model/expressions.h index 40a65b3a..352991ef 100644 --- a/src/model/expressions.h +++ b/src/model/expressions.h @@ -45,7 +45,7 @@ class Expression : public virtual AbstractLanguageElement { AbstractLanguageElement *parent(); const AbstractLanguageElement *parent() const; void set_parent(AbstractLanguageElement *parent); - + AbstractSemantics &abstract_expr_semantics() const; const string &type_name() const; protected: diff --git a/src/model/fluent.cpp b/src/model/fluent.cpp index b594aff1..c2e81bbd 100644 --- a/src/model/fluent.cpp +++ b/src/model/fluent.cpp @@ -17,6 +17,7 @@ #include "fluent.h" #include "execution.h" +#include "effect_axiom.h" namespace gologpp { @@ -106,20 +107,29 @@ Fluent::Fluent(Scope *own_scope, const string &type_name, const string &name, co const vector> &Fluent::initially() const { return initial_values_; } -void Fluent::define(const vector &initial_values) -{ define(boost::optional>(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 &initial_values, bool synced) +{ define(boost::optional>(initial_values), synced); } Reference *Fluent::make_ref(const vector &args) { return make_ref_(args); } -Expression *Fluent::ref(const vector &args) +Reference *Fluent::ref(const vector &args) { return make_ref(args); } void Fluent::compile(AExecutionContext &ctx) { ctx.compile(*this); } -void Fluent::define(const boost::optional> &initial_values) +void Fluent::define(const boost::optional> &initial_values, bool synced) { for (shared_ptr ¶m : params()) if (param->domain().is_implicit()) @@ -154,6 +164,56 @@ void Fluent::define(const boost::optional> &initial_value } else throw UserError("Fluent " + signature_str() + ": No `initially:' block"); + + if (synced) { + Scope *exog_scope = new Scope(global_scope()); + + vector> exog_params; + vector effect_fluent_args; + for (const auto &fluent_param : this->params()) { + shared_ptr exog_param = exog_scope->get_var( + VarDefinitionMode::FORCE, + static_cast(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(this->type()), + this->name() + "_value" + ) + ); + + Reference *effect_fluent_value = exog_params.back()->ref(); + + ExogAction *sync_exog = global_scope().declare_global( + exog_scope, + UndefinedType::name(), + "gpp~sync_" + this->name(), + { exog_params } + ); + + EffectAxiom> *set_fluent_effect = new EffectAxiom>(); + set_fluent_effect->define( + {}, // no condition + this->ref(effect_fluent_args), + effect_fluent_value + ); + + sync_exog->define( + {}, // no precondition + vector{ set_fluent_effect }, + {} // no mapping + ); + + global_scope().register_global(sync_exog); + + this->sync_action_.reset(sync_exog); + } } diff --git a/src/model/fluent.h b/src/model/fluent.h index f236c9d2..e73d799b 100644 --- a/src/model/fluent.h +++ b/src/model/fluent.h @@ -76,12 +76,15 @@ class Fluent virtual ~Fluent() override = default; const vector> &initially() const; + bool synced() const; + const ExogAction &sync_action() const; + ExogAction &sync_action(); - void define(const vector &initial_values); - void define(const boost::optional> &initial_values); + void define(const vector &initial_values, bool synced = false); + void define(const boost::optional> &initial_values, bool synced = false); Reference *make_ref(const vector ¶ms); - virtual Expression *ref(const vector ¶ms) override; + virtual Reference *ref(const vector ¶ms) override; virtual void attach_semantics(SemanticsFactory &implementor) override; virtual string to_string(const string &pfx) const override; @@ -89,6 +92,7 @@ class Fluent private: vector> initial_values_; + shared_ptr sync_action_; }; diff --git a/src/model/gologpp.h b/src/model/gologpp.h index 46f00776..3b131315 100644 --- a/src/model/gologpp.h +++ b/src/model/gologpp.h @@ -124,6 +124,8 @@ class History; template class Semantics; template class AbstractSemantics; +template<> class AbstractSemantics; +template<> class AbstractSemantics; class SemanticsFactory; diff --git a/src/model/platform_backend.cpp b/src/model/platform_backend.cpp index 5fba6ed4..2da25155 100644 --- a/src/model/platform_backend.cpp +++ b/src/model/platform_backend.cpp @@ -161,5 +161,8 @@ Clock::time_point DummyBackend::time() const noexcept } +void DummyBackend::sync_event(const ExogEvent &) +{ throw Bug("Not implemented"); } + } diff --git a/src/model/platform_backend.h b/src/model/platform_backend.h index 9e15fca3..d25f037a 100644 --- a/src/model/platform_backend.h +++ b/src/model/platform_backend.h @@ -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 a) = 0; @@ -82,6 +83,8 @@ class DummyBackend : public PlatformBackend { virtual void preempt_activity(shared_ptr) override; virtual Clock::time_point time() const noexcept override; + virtual void sync_event(const ExogEvent &) override; + private: virtual void execute_activity(shared_ptr a) override; diff --git a/src/model/reference.h b/src/model/reference.h index 98d892eb..455eced0 100644 --- a/src/model/reference.h +++ b/src/model/reference.h @@ -107,6 +107,10 @@ class ReferenceBase ) {} + ReferenceBase(TargetT &target, vector> &&args) + : ReferenceBase(std::dynamic_pointer_cast(target.shared_from_this()), std::move(args)) + {} + ReferenceBase(const string &target_name, const boost::optional> &args) : ReferenceBase(target_name, args.get_value_or({})) {} @@ -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 &other) const { diff --git a/src/model/semantics.h b/src/model/semantics.h index c583a883..a0fa7cdc 100644 --- a/src/model/semantics.h +++ b/src/model/semantics.h @@ -19,7 +19,6 @@ #define GOLOGPP_IMPLEMENTATION_H_ #include "gologpp.h" -#include "expressions.h" #include #include diff --git a/src/semantics/readylog/execution.cpp b/src/semantics/readylog/execution.cpp index 7ae6dc4f..d26c4adb 100644 --- a/src/semantics/readylog/execution.cpp +++ b/src/semantics/readylog/execution.cpp @@ -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"); diff --git a/src/semantics/readylog/execution.h b/src/semantics/readylog/execution.h index a4e4f17e..22f82f03 100644 --- a/src/semantics/readylog/execution.h +++ b/src/semantics/readylog/execution.h @@ -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; @@ -61,6 +59,9 @@ class ReadylogContext : public ExecutionContext { private: ReadylogContext(const eclipse_opts &options, unique_ptr &&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();