Parcourir la source

Add new formalism: fddevs

Eric Ramat il y a 4 ans
Parent
commit
053ab5b7ee

+ 14 - 0
src/artis-star/common/utils/Trace.hpp

@@ -70,6 +70,20 @@ namespace artis {
 
             void set_comment(const std::string& comment) { _comment = comment; }
 
+            std::string to_string() const
+            {
+                std::ostringstream ss;
+
+                ss << "TRACE: " << get_model_name() << " at " << get_time() << " <";
+                ss << FormalismType::to_string(get_formalism_type()) << ", ";
+                ss << FunctionType::to_string(get_function_type()) << ", ";
+                ss << LevelType::to_string(get_level_type()) << ">";
+                if (not get_comment().empty()) {
+                    ss << " => " << get_comment();
+                }
+                return ss.str();
+            }
+
         private:
             std::string _model_name;
             typename Time::type _time;

+ 1 - 0
src/artis-star/kernel/CMakeLists.txt

@@ -1,4 +1,5 @@
 ADD_SUBDIRECTORY(dsde)
 ADD_SUBDIRECTORY(dtss)
+ADD_SUBDIRECTORY(fddevs)
 ADD_SUBDIRECTORY(pdevs)
 ADD_SUBDIRECTORY(sss)

+ 2 - 2
src/artis-star/kernel/dsde/Coordinator.hpp

@@ -66,9 +66,9 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
-            common::GraphManager<Time>& get_graph_manager() { return _graph_manager; }
+            GraphManager& get_graph_manager() { return _graph_manager; }
 
-            const common::GraphManager<Time>& get_graph_manager() const { return _graph_manager; }
+            const GraphManager& get_graph_manager() const { return _graph_manager; }
 
             virtual std::string to_string(int level) const
             {

+ 2 - 2
src/artis-star/kernel/dtss/Coordinator.hpp

@@ -65,9 +65,9 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
-            common::GraphManager<Time>& get_graph_manager() { return _graph_manager; }
+            GraphManager& get_graph_manager() { return _graph_manager; }
 
-            const common::GraphManager<Time>& get_graph_manager() const { return _graph_manager; }
+            const GraphManager& get_graph_manager() const { return _graph_manager; }
 
             virtual void finish(const typename Time::type& t)
             {

+ 11 - 0
src/artis-star/kernel/fddevs/CMakeLists.txt

@@ -0,0 +1,11 @@
+INCLUDE_DIRECTORIES(
+        ${ARTIS_BINARY_DIR}/src
+        ${ARTIS_SOURCE_DIR}/src
+        ${Boost_INCLUDE_DIRS})
+
+LINK_DIRECTORIES(
+        ${Boost_LIBRARY_DIRS})
+
+SET(FDDEVS_HPP Coordinator.hpp Dynamics.hpp GraphManager.hpp Simulator.hpp)
+
+INSTALL(FILES ${FDDEVS_HPP} DESTINATION ${ARTIS_INCLUDE_DIRS}/kernel/fddevs)

+ 65 - 0
src/artis-star/kernel/fddevs/Coordinator.hpp

@@ -0,0 +1,65 @@
+/**
+ * @file kernel/fddevs/Coordinator.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FDDEVS_COORDINATOR
+#define FDDEVS_COORDINATOR 1
+
+#include <artis-star/kernel/pdevs/Coordinator.hpp>
+
+namespace artis {
+    namespace fddevs {
+
+        template<class Time,
+                class GraphManager,
+                class Parameters = common::NoParameters,
+                class GraphParameters = common::NoParameters>
+        class Coordinator
+                : public pdevs::Coordinator<Time, GraphManager, Parameters, GraphParameters> {
+        public:
+            Coordinator(const std::string& name, const Parameters& parameters,
+                    const GraphParameters& graph_parameters)
+                    :
+                    common::Model<Time>(name),
+                    pdevs::Coordinator<Time, GraphManager, Parameters, GraphParameters>(name,
+                            parameters, graph_parameters) { }
+
+            virtual ~Coordinator() { }
+
+            virtual std::string to_string(int level) const
+            {
+                std::ostringstream ss;
+
+                ss << common::String::make_spaces(level * 2) << "fddevs coordinator \""
+                   << this->get_name() << "\":" << std::endl;
+                ss << this->get_graph_manager().to_string(level + 1);
+                return ss.str();
+            }
+        };
+
+    }
+} // namespace artis fddevs
+
+#endif

+ 145 - 0
src/artis-star/kernel/fddevs/Dynamics.hpp

@@ -0,0 +1,145 @@
+/**
+ * @file kernel/fddevs/Dynamics.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FDDEVS_DYNAMICS
+#define FDDEVS_DYNAMICS
+
+#include <artis-star/common/Bag.hpp>
+#include <artis-star/common/ExternalEvent.hpp>
+#include <artis-star/common/Parameters.hpp>
+#include <artis-star/common/States.hpp>
+#include <artis-star/kernel/fddevs/Simulator.hpp>
+
+#include <string>
+#include <vector>
+
+namespace artis {
+    namespace fddevs {
+
+        template<class Time, class Dyn, class StateValues, class Parameters = common::NoParameters>
+        class Dynamics : public common::States<Time, Dyn> {
+            typedef fddevs::Simulator<Time, Dyn, Parameters> Simulator;
+
+        public:
+            Dynamics(const std::string& name, const Context<Time, Dyn, Parameters>& context)
+                    :
+                    _name(name), _simulator(context.simulator()) { }
+
+            virtual ~Dynamics() { }
+
+            // definition
+            void initial_state(const StateValues& state)
+            { _initial_state = state; }
+
+            // < X, Y, S, s0, tau, delta_x, sigma, delta_tau, lambda >
+            virtual void delta_tau(typename Time::type /* t */) { }
+
+            virtual void delta_x(typename Time::type /* t */, typename Time::type /* e */,
+                    const common::Bag<Time>& /* bag */) { }
+
+            virtual void initial_state(typename Time::type /* time */)
+            { state(_initial_state); }
+
+            virtual common::Bag<Time>
+            lambda(typename Time::type /* time */) const { return common::Bag<Time>(); }
+
+            virtual bool rho(typename Time::type /* time */,
+                    const common::Bag<common::DoubleTime>& /* bag */) const { return false; }
+
+            virtual typename Time::type
+            tau(typename Time::type /* time */) const { return Time::infinity; }
+
+            // observation
+            virtual common::Value observe(const typename Time::type& /* t */,
+                    unsigned int /* index */) const { return common::Value(); }
+
+            // structure
+            const std::string& get_name() const { return _name; }
+
+            void input_port(common::Port p)
+            {
+                _simulator->add_in_port(p);
+            }
+
+            size_t input_port_number() const { return _simulator->get_in_port_number(); }
+
+            void input_ports(std::initializer_list<common::Port> list)
+            {
+                for (typename std::initializer_list<common::Port>::iterator it = list.begin();
+                     it != list.end();
+                     ++it) {
+                    _simulator->add_in_port(*it);
+                }
+            }
+
+            void output_port(common::Port p)
+            {
+                _simulator->add_out_port(p);
+            }
+
+            size_t output_port_number() const { return _simulator->get_out_port_number(); }
+
+            void output_ports(std::initializer_list<common::Port> list)
+            {
+                for (typename std::initializer_list<common::Port>::iterator it =
+                        list.begin(); it != list.end(); ++it) {
+                    _simulator->add_out_port(*it);
+                }
+            }
+
+            // state
+            void restore(const common::context::State<Time>& state)
+            {
+                common::States<Time, Dyn>::restore(static_cast<Dyn*>(this), state);
+            }
+
+            void save(common::context::State<Time>& state) const
+            {
+                common::States<Time, Dyn>::save(static_cast<const Dyn*>(this), state);
+            }
+
+            void state(const StateValues& new_state)
+            {
+                _state = new_state;
+            }
+
+            const StateValues& state() const { return _state; }
+
+        private:
+            std::string _name;
+            Simulator* _simulator;
+
+            // definition
+            StateValues _initial_state;
+
+            // state
+            StateValues _state;
+        };
+
+    }
+} // namespace artis fddevs
+
+#endif

+ 53 - 0
src/artis-star/kernel/fddevs/GraphManager.hpp

@@ -0,0 +1,53 @@
+/**
+ * @file kernel/fddevs/GraphManager.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FDDEVS_GRAPH_MANAGER
+#define FDDEVS_GRAPH_MANAGER
+
+#include <artis-star/kernel/pdevs/GraphManager.hpp>
+
+namespace artis {
+    namespace fddevs {
+
+        template<class Time,
+                class Parameters = common::NoParameters,
+                class GraphParameters = common::NoParameters>
+        class GraphManager : public pdevs::GraphManager<Time, Parameters, GraphParameters> {
+        public:
+            GraphManager(common::Coordinator<Time>* coordinator,
+                    const Parameters& parameters,
+                    const GraphParameters& graph_parameters)
+                    :
+                    pdevs::GraphManager<Time, Parameters, GraphParameters>(coordinator, parameters,
+                            graph_parameters) { }
+
+            ~GraphManager() override = default;
+        };
+
+    }
+} // namespace artis fddevs
+
+#endif

+ 295 - 0
src/artis-star/kernel/fddevs/Simulator.hpp

@@ -0,0 +1,295 @@
+/**
+ * @file kernel/fddevs/Simulator.hpp
+ * @author The ARTIS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * ARTIS - the multimodeling and simulation environment
+ * This file is a part of the ARTIS environment
+ *
+ * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FDDEVS_SIMULATOR
+#define FDDEVS_SIMULATOR
+
+#include <artis-star/common/Coordinator.hpp>
+#include <artis-star/common/Parameters.hpp>
+#include <artis-star/common/Simulator.hpp>
+#include <artis-star/common/utils/String.hpp>
+#include <artis-star/common/utils/Trace.hpp>
+
+#include <cassert>
+
+namespace artis {
+    namespace fddevs {
+
+        template<class Time, class Dynamics, class Parameters>
+        class Simulator;
+
+        template<class Time, class Dynamics,
+                class Parameters = common::NoParameters>
+        class Context {
+            typedef fddevs::Simulator<Time, Dynamics, Parameters> Simulator;
+
+        public:
+            Context(const Parameters& parameters, Simulator* simulator)
+                    :
+                    _parameters(parameters), _simulator(simulator) { }
+
+            virtual ~Context() { }
+
+            const Parameters& parameters() const { return _parameters; }
+
+            Simulator* simulator() const { return _simulator; }
+
+        private:
+            const Parameters& _parameters;
+            Simulator* _simulator;
+        };
+
+        template<class Time, class Dynamics,
+                class Parameters = common::NoParameters>
+        class Simulator : public common::Simulator<Time> {
+            typedef Simulator<Time, Dynamics, Parameters> type;
+
+        public :
+            Simulator(const std::string& name, const Parameters& parameters)
+                    :
+                    common::Model<Time>(name),
+                    common::Simulator<Time>(name),
+                    _dynamics(name, Context<Time, Dynamics, Parameters>(parameters, this)) { }
+
+            ~Simulator() { }
+
+            const Dynamics& dynamics() const { return _dynamics; }
+
+            virtual void restore(const common::context::State<Time>& state)
+            {
+                common::Simulator<Time>::restore(state);
+                _dynamics.restore(state);
+            }
+
+            virtual void save(common::context::State<Time>& state) const
+            {
+                common::Simulator<Time>::save(state);
+                _dynamics.save(state);
+            }
+
+            virtual std::string to_string(int level) const
+            {
+                std::ostringstream ss;
+
+                ss << common::String::make_spaces(level * 2) << "p-devs simulator \""
+                   << type::get_name() << "\"" << std::endl;
+                return ss.str();
+            }
+
+            virtual void finish(const typename Time::type& t)
+            {
+#ifndef WITH_TRACE
+                (void) t;
+#endif
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::FINISH,
+                                common::LevelType::FORMALISM);
+                common::Trace<Time>::trace().flush();
+#endif
+            }
+
+            typename Time::type start(const typename Time::type& t)
+            {
+//                When i-message(t)
+//                  tl = t - e
+//                  tn = tl + ta(s)
+//                End
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::I_MESSAGE,
+                                common::LevelType::FORMALISM)
+                        << ": BEFORE => " << "tl = " << type::_tl << " ; tn = "
+                        << type::_tn;
+                common::Trace<Time>::trace().flush();
+#endif
+
+                _dynamics.initial_state(t);
+                type::_tl = t;
+                type::_tn = type::_tl + _dynamics.tau(t);
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::I_MESSAGE,
+                                common::LevelType::FORMALISM)
+                        << ": AFTER => " << "tl = " << type::_tl << " ; tn = "
+                        << type::_tn;
+                common::Trace<Time>::trace().flush();
+#endif
+
+                return type::_tn;
+            }
+
+            common::Value observe(const typename Time::type& t,
+                    unsigned int index) const { return _dynamics.observe(t, index); }
+
+            void output(const typename Time::type& t)
+            {
+//                When *-message(t)
+//                  if (t = tn) then
+//                    y = lambda(s)
+//                    send y-message(y,t) to parent
+//                End
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::OUTPUT,
+                                common::LevelType::FORMALISM)
+                                << ": BEFORE";
+                common::Trace<Time>::trace().flush();
+#endif
+
+                if (t == type::_tn) {
+                    common::Bag<Time> bag = _dynamics.lambda(t);
+
+                    if (not bag.empty()) {
+                        for (auto& event : bag) {
+                            event.set_model(this);
+                        }
+
+#ifdef WITH_TRACE
+                        common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::OUTPUT,
+                                common::LevelType::FORMALISM)
+                                << ": AFTER" << " => "
+                                << bag.to_string();
+                common::Trace<Time>::trace().flush();
+#endif
+
+                        dynamic_cast < common::Coordinator<Time>* >(
+                                type::get_parent())->dispatch_events(bag, t);
+                    }
+                }
+            }
+
+            void post_event(const typename Time::type& t,
+                    const common::ExternalEvent<Time>& event)
+            {
+
+#ifndef WITH_TRACE
+                (void) t;
+#endif
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::POST_EVENT,
+                                common::LevelType::FORMALISM)
+                        << ": BEFORE => " << event.to_string();
+                common::Trace<Time>::trace().flush();
+#endif
+
+                type::add_event(event);
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::POST_EVENT,
+                                common::LevelType::FORMALISM)
+                        << ": AFTER => " << event.to_string();
+                common::Trace<Time>::trace().flush();
+#endif
+
+            }
+
+            typename Time::type transition(const typename Time::type& t)
+            {
+//                When x-message(t)
+//                  if (x is empty and t = tn) then
+//                    s = delta_int(s)
+//                  else if (x isn't empty and t = tn)
+//                    s = delta_conf(s,x)
+//                  else if (x isn't empty and t < tn)
+//                    e = t - tl
+//                    s = delta_ext(s,e,x)
+//                  tn = t + ta(s)
+//                  tl = t
+//                End
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::S_MESSAGE,
+                                common::LevelType::FORMALISM)
+                        << ": BEFORE => " << "tl = " << type::_tl << " ; tn = " << type::_tn
+                        << " ; S = " << _dynamics.state();
+                common::Trace<Time>::trace().flush();
+#endif
+
+                assert(type::_tl <= t and t <= type::_tn);
+
+                if (t == type::_tn) {
+                    if (type::event_number() == 0) {
+                        _dynamics.delta_tau(t);
+                        type::_tn = t + _dynamics.tau(t);
+                        type::_tl = t;
+                    }
+                } else {
+                    _dynamics.delta_x(t, t - type::_tl, type::get_bag());
+                    if (not _dynamics.rho(t, type::get_bag())) {
+                        type::_tn = t + _dynamics.tau(t);
+                        type::_tl = t;
+                    }
+                }
+                type::clear_bag();
+
+#ifdef WITH_TRACE
+                common::Trace<Time>::trace()
+                        << common::TraceElement<Time>(type::get_name(), t,
+                                common::FormalismType::FDDEVS,
+                                common::FunctionType::S_MESSAGE,
+                                common::LevelType::FORMALISM)
+                        << ": AFTER => " << "tl = " << type::_tl << " ; tn = " << type::_tn
+                        << " ; S = " << _dynamics.state();
+                common::Trace<Time>::trace().flush();
+#endif
+
+                return type::_tn;
+            }
+
+        private :
+            Dynamics _dynamics;
+        };
+
+    }
+} // namespace artis fddevs
+
+#endif

+ 2 - 2
src/artis-star/kernel/pdevs/Coordinator.hpp

@@ -58,9 +58,9 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
-            common::GraphManager<Time>& get_graph_manager() { return _graph_manager; }
+            GraphManager& get_graph_manager() { return _graph_manager; }
 
-            const common::GraphManager<Time>& get_graph_manager() const { return _graph_manager; }
+            const GraphManager& get_graph_manager() const { return _graph_manager; }
 
             virtual std::string to_string(int level) const
             {

+ 2 - 2
src/artis-star/kernel/sss/Coordinator.hpp

@@ -71,9 +71,9 @@ namespace artis {
 
             virtual ~Coordinator() { }
 
-            common::GraphManager<Time>& get_graph_manager() { return _graph_manager; }
+            GraphManager& get_graph_manager() { return _graph_manager; }
 
-            const common::GraphManager<Time>& get_graph_manager() const { return _graph_manager; }
+            const GraphManager& get_graph_manager() const { return _graph_manager; }
 
             virtual bool is_atomic() const { return common::Coordinator<Time>::is_atomic(); }
 

+ 1 - 2
src/artis-star/kernel/sss/Model.hpp

@@ -48,8 +48,7 @@ namespace artis {
 
             virtual void update_buffer(typename Time::type /* time */) = 0;
 
-            void add_event(const common::ExternalEvent<Time>&
-            message)
+            void add_event(const common::ExternalEvent<Time>& message)
             {
                 common::Model<Time>::add_event(message);
                 std::map<std::string, bool>::iterator it =