pyjevsim 2.0.0__tar.gz → 2.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {pyjevsim-2.0.0/pyjevsim.egg-info → pyjevsim-2.0.1}/PKG-INFO +112 -31
  2. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/README.md +111 -30
  3. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/behavior_model.py +1 -1
  4. pyjevsim-2.0.1/pyjevsim/structural_model.py +133 -0
  5. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/system_executor.py +27 -2
  6. {pyjevsim-2.0.0 → pyjevsim-2.0.1/pyjevsim.egg-info}/PKG-INFO +112 -31
  7. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyproject.toml +1 -1
  8. pyjevsim-2.0.0/pyjevsim/structural_model.py +0 -48
  9. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/LICENSE +0 -0
  10. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/MANIFEST.in +0 -0
  11. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/__init__.py +0 -0
  12. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/atomic_model.py +0 -0
  13. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/behavior_executor.py +0 -0
  14. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/core_model.py +0 -0
  15. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/default_message_catcher.py +0 -0
  16. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/definition.py +0 -0
  17. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/executor.py +0 -0
  18. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/executor_factory.py +0 -0
  19. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/exgen.py +0 -0
  20. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/message_deliverer.py +0 -0
  21. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/restore_handler.py +0 -0
  22. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/schedule_queue.py +0 -0
  23. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/snapshot_condition.py +0 -0
  24. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/snapshot_executor.py +0 -0
  25. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/snapshot_factory.py +0 -0
  26. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/snapshot_manager.py +0 -0
  27. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/structural_executor.py +0 -0
  28. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/system_message.py +0 -0
  29. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/system_object.py +0 -0
  30. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim/termination_manager.py +0 -0
  31. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim.egg-info/SOURCES.txt +0 -0
  32. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim.egg-info/dependency_links.txt +0 -0
  33. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim.egg-info/requires.txt +0 -0
  34. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/pyjevsim.egg-info/top_level.txt +0 -0
  35. {pyjevsim-2.0.0 → pyjevsim-2.0.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyjevsim
3
- Version: 2.0.0
3
+ Version: 2.0.1
4
4
  Summary: A DEVS(Discrete Event System Specification) Modeling & Simulation environment with journaling functionality
5
5
  Author-email: Changbeom Choi <me@cbchoi.info>
6
6
  License-Expression: MIT
@@ -26,48 +26,129 @@ Requires-Dist: pytest>=7.0; extra == "dev"
26
26
  Dynamic: license-file
27
27
 
28
28
  # pyjevsim
29
+
30
+ [![PyPI](https://img.shields.io/pypi/v/pyjevsim.svg)](https://pypi.org/project/pyjevsim/)
31
+ [![Python](https://img.shields.io/pypi/pyversions/pyjevsim.svg)](https://pypi.org/project/pyjevsim/)
32
+ [![Docs](https://readthedocs.org/projects/pyjevsim/badge/?version=latest)](https://pyjevsim.readthedocs.io/en/latest/)
33
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
34
+
29
35
  ## Introduction
30
- pyjevsim is a DEVS(discrete event system specification) environment that provides journaling functionality.
31
- It provides the ability to snapshot and restore models or simulation engines.
32
- It's compatible with Python versions 3.10+.
33
-
34
- For more information, see the documentation. : [pyjevsim](https://pyjevsim.readthedocs.io/en/latest/index.html)
35
-
36
+
37
+ pyjevsim is a DEVS (discrete event system specification) modeling and
38
+ simulation environment with built-in journaling. It supports snapshot
39
+ and restore of individual models or the full simulation engine,
40
+ virtual-time and real-time execution, and HLA federate integration via
41
+ a stepped execution mode. Compatible with Python 3.10+.
42
+
43
+ Full documentation: <https://pyjevsim.readthedocs.io/en/latest/>
44
+
45
+ ### What's new in 2.0
46
+
47
+ - **Two-phase tick.** `SysExecutor` evaluates every imminent model's
48
+ `output()` first, then routes outputs and applies transitions —
49
+ fixing confluent-event ordering under Parallel-DEVS semantics.
50
+ - **HLA stepped execution.** `step(granted_time)` and
51
+ `get_next_event_time()` let an IEEE 1516-2010 RTI federate drive
52
+ pyjevsim without owning the main loop.
53
+ - **V_TIME jump-to-next-event.** The virtual-time scheduler hops
54
+ directly to the next scheduled event instead of advancing by a fixed
55
+ `time_resolution`, eliminating idle ticks on sparse models.
56
+ - **Opt-in uncaught-message tracking** for debugging dangling outputs.
57
+ - **DEVStone benchmark suite** with cross-engine comparison adapters.
58
+
36
59
  ## Installing
37
- You can install pyjevsim via
60
+
61
+ From PyPI (recommended):
62
+
38
63
  ```
39
- git clone https://github.com/eventsim/pyjevsim
64
+ pip install pyjevsim
40
65
  ```
41
-
42
- ## Dependencies
43
- The only dependency required by pyjevsim is dill ~= 0.3.6 for model serialization and restoration.
44
- dill is an essential library for serializing models and simulation states and can be installed via.
66
+
67
+ From source:
68
+
45
69
  ```
46
- pip install dill
70
+ git clone https://github.com/eventsim/pyjevsim
71
+ cd pyjevsim
72
+ pip install -e .
47
73
  ```
48
-
49
- ### Optional Dependencies
50
- pytest is an optional dependency required for running test cases and example executions.
51
- You can install pyjevsim via
74
+
75
+ ## Dependencies
76
+
77
+ - Python >= 3.10
78
+ - `dill >= 0.3.6` (installed automatically) — used for model
79
+ serialization and restoration.
80
+
81
+ `pytest` is required only to run the test suite and is declared under
82
+ the `dev` extra:
83
+
52
84
  ```
53
- pip install pytest
85
+ pip install pyjevsim[dev]
54
86
  ```
55
-
56
- Additionally, you can install all necessary libraries, including optional dependencies, by running the following command:
87
+
88
+ ## Quick Start
89
+
90
+ A minimal generator → sink simulation:
91
+
92
+ ```python
93
+ from pyjevsim.behavior_model import BehaviorModel
94
+ from pyjevsim.definition import ExecutionType, Infinite
95
+ from pyjevsim.system_executor import SysExecutor
96
+ from pyjevsim.system_message import SysMessage
97
+
98
+
99
+ class Gen(BehaviorModel):
100
+ def __init__(self, name):
101
+ super().__init__(name)
102
+ self.init_state("Generate")
103
+ self.insert_state("Generate", 1)
104
+ self.insert_output_port("out")
105
+
106
+ def ext_trans(self, port, msg): pass
107
+ def int_trans(self): pass
108
+ def output(self, md):
109
+ msg = SysMessage(self.get_name(), "out")
110
+ msg.insert("tick")
111
+ md.insert_message(msg)
112
+ def time_advance(self):
113
+ return 1
114
+
115
+
116
+ class Sink(BehaviorModel):
117
+ def __init__(self, name):
118
+ super().__init__(name)
119
+ self.init_state("Idle")
120
+ self.insert_state("Idle", Infinite)
121
+ self.insert_input_port("in")
122
+
123
+ def ext_trans(self, port, msg):
124
+ print(f"received: {msg.retrieve()}")
125
+ def int_trans(self): pass
126
+ def output(self, md): pass
127
+ def time_advance(self):
128
+ return Infinite
129
+
130
+
131
+ se = SysExecutor(1, ex_mode=ExecutionType.V_TIME)
132
+ gen = Gen("g")
133
+ sink = Sink("s")
134
+ se.register_entity(gen)
135
+ se.register_entity(sink)
136
+ se.coupling_relation(gen, "out", sink, "in")
137
+ se.simulate(5)
57
138
  ```
58
- pip install -r requirements.txt
59
- ```
60
139
 
61
- ## Working with pyjevsim
62
- Once you have installed the library, you can begin working with it.
140
+ See the [quick-start guide](https://pyjevsim.readthedocs.io/en/latest/pyjevsim_quick_start.html)
141
+ for structural models, snapshots, and HLA stepped execution.
142
+
143
+ ### Examples
63
144
 
64
- ### Quick Start
65
- The docs describe how to configure a simulation via pyjevsim's BehaviorModel and SysExecutor.
66
- Check out the [documentation](link) to configure your simulation.
145
+ The [`examples/`](examples/) directory contains:
67
146
 
68
- ### Example
69
- There is a banksim example that uses pyjevsim's DEVS functionality and journaling features.
70
- [documentation](link)
147
+ - **`banksim/`** — bank queue simulation demonstrating BehaviorModel,
148
+ StructuralModel, and snapshot/restore.
149
+ - **`atsim/`** — anti-torpedo simulator with self-propelled and
150
+ stationary decoy models.
151
+ - **`mwmsim/`** — municipal waste management agent-based model.
71
152
 
72
153
  ### Output messages are shared by reference
73
154
 
@@ -1,46 +1,127 @@
1
1
  # pyjevsim
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/pyjevsim.svg)](https://pypi.org/project/pyjevsim/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/pyjevsim.svg)](https://pypi.org/project/pyjevsim/)
5
+ [![Docs](https://readthedocs.org/projects/pyjevsim/badge/?version=latest)](https://pyjevsim.readthedocs.io/en/latest/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+
2
8
  ## Introduction
3
- pyjevsim is a DEVS(discrete event system specification) environment that provides journaling functionality.
4
- It provides the ability to snapshot and restore models or simulation engines.
5
- It's compatible with Python versions 3.10+.
6
-
7
- For more information, see the documentation. : [pyjevsim](https://pyjevsim.readthedocs.io/en/latest/index.html)
8
-
9
+
10
+ pyjevsim is a DEVS (discrete event system specification) modeling and
11
+ simulation environment with built-in journaling. It supports snapshot
12
+ and restore of individual models or the full simulation engine,
13
+ virtual-time and real-time execution, and HLA federate integration via
14
+ a stepped execution mode. Compatible with Python 3.10+.
15
+
16
+ Full documentation: <https://pyjevsim.readthedocs.io/en/latest/>
17
+
18
+ ### What's new in 2.0
19
+
20
+ - **Two-phase tick.** `SysExecutor` evaluates every imminent model's
21
+ `output()` first, then routes outputs and applies transitions —
22
+ fixing confluent-event ordering under Parallel-DEVS semantics.
23
+ - **HLA stepped execution.** `step(granted_time)` and
24
+ `get_next_event_time()` let an IEEE 1516-2010 RTI federate drive
25
+ pyjevsim without owning the main loop.
26
+ - **V_TIME jump-to-next-event.** The virtual-time scheduler hops
27
+ directly to the next scheduled event instead of advancing by a fixed
28
+ `time_resolution`, eliminating idle ticks on sparse models.
29
+ - **Opt-in uncaught-message tracking** for debugging dangling outputs.
30
+ - **DEVStone benchmark suite** with cross-engine comparison adapters.
31
+
9
32
  ## Installing
10
- You can install pyjevsim via
33
+
34
+ From PyPI (recommended):
35
+
11
36
  ```
12
- git clone https://github.com/eventsim/pyjevsim
37
+ pip install pyjevsim
13
38
  ```
14
-
15
- ## Dependencies
16
- The only dependency required by pyjevsim is dill ~= 0.3.6 for model serialization and restoration.
17
- dill is an essential library for serializing models and simulation states and can be installed via.
39
+
40
+ From source:
41
+
18
42
  ```
19
- pip install dill
43
+ git clone https://github.com/eventsim/pyjevsim
44
+ cd pyjevsim
45
+ pip install -e .
20
46
  ```
21
-
22
- ### Optional Dependencies
23
- pytest is an optional dependency required for running test cases and example executions.
24
- You can install pyjevsim via
47
+
48
+ ## Dependencies
49
+
50
+ - Python >= 3.10
51
+ - `dill >= 0.3.6` (installed automatically) — used for model
52
+ serialization and restoration.
53
+
54
+ `pytest` is required only to run the test suite and is declared under
55
+ the `dev` extra:
56
+
25
57
  ```
26
- pip install pytest
58
+ pip install pyjevsim[dev]
27
59
  ```
28
-
29
- Additionally, you can install all necessary libraries, including optional dependencies, by running the following command:
60
+
61
+ ## Quick Start
62
+
63
+ A minimal generator → sink simulation:
64
+
65
+ ```python
66
+ from pyjevsim.behavior_model import BehaviorModel
67
+ from pyjevsim.definition import ExecutionType, Infinite
68
+ from pyjevsim.system_executor import SysExecutor
69
+ from pyjevsim.system_message import SysMessage
70
+
71
+
72
+ class Gen(BehaviorModel):
73
+ def __init__(self, name):
74
+ super().__init__(name)
75
+ self.init_state("Generate")
76
+ self.insert_state("Generate", 1)
77
+ self.insert_output_port("out")
78
+
79
+ def ext_trans(self, port, msg): pass
80
+ def int_trans(self): pass
81
+ def output(self, md):
82
+ msg = SysMessage(self.get_name(), "out")
83
+ msg.insert("tick")
84
+ md.insert_message(msg)
85
+ def time_advance(self):
86
+ return 1
87
+
88
+
89
+ class Sink(BehaviorModel):
90
+ def __init__(self, name):
91
+ super().__init__(name)
92
+ self.init_state("Idle")
93
+ self.insert_state("Idle", Infinite)
94
+ self.insert_input_port("in")
95
+
96
+ def ext_trans(self, port, msg):
97
+ print(f"received: {msg.retrieve()}")
98
+ def int_trans(self): pass
99
+ def output(self, md): pass
100
+ def time_advance(self):
101
+ return Infinite
102
+
103
+
104
+ se = SysExecutor(1, ex_mode=ExecutionType.V_TIME)
105
+ gen = Gen("g")
106
+ sink = Sink("s")
107
+ se.register_entity(gen)
108
+ se.register_entity(sink)
109
+ se.coupling_relation(gen, "out", sink, "in")
110
+ se.simulate(5)
30
111
  ```
31
- pip install -r requirements.txt
32
- ```
33
112
 
34
- ## Working with pyjevsim
35
- Once you have installed the library, you can begin working with it.
113
+ See the [quick-start guide](https://pyjevsim.readthedocs.io/en/latest/pyjevsim_quick_start.html)
114
+ for structural models, snapshots, and HLA stepped execution.
115
+
116
+ ### Examples
36
117
 
37
- ### Quick Start
38
- The docs describe how to configure a simulation via pyjevsim's BehaviorModel and SysExecutor.
39
- Check out the [documentation](link) to configure your simulation.
118
+ The [`examples/`](examples/) directory contains:
40
119
 
41
- ### Example
42
- There is a banksim example that uses pyjevsim's DEVS functionality and journaling features.
43
- [documentation](link)
120
+ - **`banksim/`** — bank queue simulation demonstrating BehaviorModel,
121
+ StructuralModel, and snapshot/restore.
122
+ - **`atsim/`** — anti-torpedo simulator with self-propelled and
123
+ stationary decoy models.
124
+ - **`mwmsim/`** — municipal waste management agent-based model.
44
125
 
45
126
  ### Output messages are shared by reference
46
127
 
@@ -5,7 +5,7 @@ Copyright (c) 2021-2024 Hanbat National University
5
5
  License: MIT. The full license text is available at:
6
6
  https://github.com/eventsim/pyjevsim/blob/main/LICENSE
7
7
 
8
- This module contains a BehaivorModel object that allows you to implement the Discrete Event System Specification AtomicModel.
8
+ This module contains a BehaviorModel object that allows you to implement the Discrete Event System Specification AtomicModel.
9
9
  """
10
10
 
11
11
  from abc import abstractmethod
@@ -0,0 +1,133 @@
1
+ """
2
+ Author: Changbeom Choi (@cbchoi)
3
+ Copyright (c) 2014-2020 Handong Global University
4
+ Copyright (c) 2021-2024 Hanbat National University
5
+ License: MIT. The full license text is available at:
6
+ https://github.com/eventsim/pyjevsim/blob/main/LICENSE
7
+
8
+ This module contains a StructuralModel object that allows you to implement the Discrete Event System Specification CoupledModel.
9
+ """
10
+
11
+ from .core_model import CoreModel
12
+ from .definition import ModelType
13
+ from .system_message import SysMessage
14
+
15
+
16
+ class StructuralModel(CoreModel):
17
+ """A DEVS coupled model: a container that aggregates child models and
18
+ declares the message flow between them.
19
+
20
+ A StructuralModel does **not** define its own state, transition, or
21
+ output behavior. Its job is to expose external input / output ports,
22
+ register child models (atomic or structural), and declare port-level
23
+ coupling relations. ``SysExecutor`` flattens these couplings when
24
+ routing messages so a hierarchical graph behaves identically to a
25
+ flattened one.
26
+
27
+ Three coupling patterns are supported through the same
28
+ :py:meth:`coupling_relation` call:
29
+
30
+ - **External Input Coupling (EIC):** ``self -> child.in_port``
31
+ - **Internal Coupling (IC):** ``child_a.out -> child_b.in``
32
+ - **External Output Coupling (EOC):** ``child.out -> self``
33
+
34
+ See :doc:`pyjevsim_quick_start` for a complete example.
35
+ """
36
+
37
+ def __init__(self, _name=""):
38
+ """Initializes a StructuralModel.
39
+
40
+ Args:
41
+ _name (str): Identifier used by ``SysExecutor`` for routing
42
+ and by hierarchical lookup. Must be unique within its
43
+ parent scope.
44
+ """
45
+ super().__init__(_name, ModelType.STRUCTURAL)
46
+
47
+ self.model_map = {} # name -> child model
48
+ self.port_map = {} # (src_obj, src_port) -> [(dst_obj, dst_port), ...]
49
+
50
+ def register_entity(self, obj):
51
+ """Registers a child model under this structural model.
52
+
53
+ The child is keyed by ``obj.get_name()``; registering a second
54
+ model with the same name overwrites the first.
55
+
56
+ Args:
57
+ obj: An ``AtomicModel``, ``BehaviorModel``, or
58
+ ``StructuralModel`` instance to add as a child.
59
+ """
60
+ self.model_map[obj.get_name()] = obj
61
+
62
+ def remove_model(self, obj):
63
+ """Removes a child model previously added with
64
+ :py:meth:`register_entity`.
65
+
66
+ Existing coupling entries that reference ``obj`` are **not**
67
+ cleaned up automatically; callers should drop them via
68
+ ``port_map`` if needed.
69
+
70
+ Args:
71
+ obj: The child model to remove. Must already be registered.
72
+ """
73
+ del self.model_map[obj.get_name()]
74
+
75
+ def find_model(self, name):
76
+ """Looks up a registered child model by name.
77
+
78
+ Args:
79
+ name (str): The child model's name as returned by
80
+ ``get_name()``.
81
+
82
+ Returns:
83
+ The child model instance.
84
+
85
+ Raises:
86
+ KeyError: If no child with that name is registered.
87
+ """
88
+ return self.model_map[name]
89
+
90
+ def get_models(self):
91
+ """Returns the full ``name -> child model`` mapping.
92
+
93
+ Returns:
94
+ dict: The internal ``model_map``. Mutating the returned
95
+ dict mutates the structural model.
96
+ """
97
+ return self.model_map
98
+
99
+ def coupling_relation(self, src_obj, src_port, dst_obj, dst_port):
100
+ """Declares a coupling from one (model, port) to another.
101
+
102
+ The same ``(src_obj, src_port)`` may be coupled to multiple
103
+ destinations; each call appends a new destination. ``src_obj``
104
+ or ``dst_obj`` may be ``self`` to express EIC or EOC.
105
+
106
+ Note: messages are propagated **by reference**; downstream
107
+ receivers should treat them as immutable. See
108
+ :doc:`pyjevsim_quick_start` (Output Messages Are Shared by
109
+ Reference) for the rationale.
110
+
111
+ Args:
112
+ src_obj: Source model (or ``self`` for EIC).
113
+ src_port (str): Source port name.
114
+ dst_obj: Destination model (or ``self`` for EOC).
115
+ dst_port (str): Destination port name.
116
+ """
117
+ src = (src_obj, src_port)
118
+ dst = (dst_obj, dst_port)
119
+
120
+ if src not in self.port_map:
121
+ self.port_map[src] = []
122
+
123
+ self.port_map[src].append(dst)
124
+
125
+ def get_couplings(self):
126
+ """Returns the coupling map.
127
+
128
+ Returns:
129
+ dict: ``{(src_obj, src_port): [(dst_obj, dst_port), ...]}``
130
+ describing every declared coupling under this structural
131
+ model.
132
+ """
133
+ return self.port_map
@@ -27,7 +27,28 @@ from .termination_manager import TerminationManager
27
27
  from .message_deliverer import MessageDeliverer
28
28
 
29
29
  class SysExecutor(CoreModel):
30
- """SysExecutor managing the execution of models in a simulation.(Simulation Engine)"""
30
+ """The pyjevsim simulation engine.
31
+
32
+ ``SysExecutor`` owns the global simulated clock, the future-event
33
+ list (FEL), the coupling graph, and the lifecycle of registered
34
+ executors. It runs each simulated instant as a two-phase tick —
35
+ Phase A drains every imminent model's ``output()`` against its
36
+ pre-transition state; Phase B routes outputs through coupling and
37
+ applies ``int_trans`` / ``ext_trans`` / ``con_trans`` per
38
+ Parallel-DEVS semantics.
39
+
40
+ Three execution modes are supported via :class:`ExecutionType`:
41
+
42
+ - ``V_TIME`` — virtual-time, jump-to-next-event. ``simulate()``
43
+ drives the loop and ``global_time`` hops directly to the next
44
+ scheduled event.
45
+ - ``R_TIME`` — real-time, ``time_resolution``-stepped with a
46
+ ``time.sleep`` to match wall-clock pace.
47
+ - ``HLA_TIME`` — federate-driven. The executor does not advance
48
+ time on its own; an HLA ambassador calls
49
+ :py:meth:`get_next_event_time` then :py:meth:`step` to grant
50
+ cascade rounds inside an RTI-issued time grant.
51
+ """
31
52
 
32
53
  EXTERNAL_SRC = "SRC"
33
54
  EXTERNAL_DST = "DST"
@@ -41,7 +62,11 @@ class SysExecutor(CoreModel):
41
62
  Args:
42
63
  _time_resolution (float): The time resolution for the simulation
43
64
  _sim_name (str, optional): The name of the simulation
44
- ex_mode (R_TIME or VTIME): The execution mode
65
+ ex_mode (ExecutionType): The execution mode — one of
66
+ ``V_TIME`` (virtual time, jump-to-next-event),
67
+ ``R_TIME`` (real time, ``time_resolution``-stepped),
68
+ or ``HLA_TIME`` (federate-driven via
69
+ :py:meth:`step`).
45
70
  snapshot_manager (ModelSnapshotManager, optional): Manages SnapshotExecutor
46
71
  track_uncaught (bool, optional): When True, output messages
47
72
  emitted to ports with no downstream coupling are routed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyjevsim
3
- Version: 2.0.0
3
+ Version: 2.0.1
4
4
  Summary: A DEVS(Discrete Event System Specification) Modeling & Simulation environment with journaling functionality
5
5
  Author-email: Changbeom Choi <me@cbchoi.info>
6
6
  License-Expression: MIT
@@ -26,48 +26,129 @@ Requires-Dist: pytest>=7.0; extra == "dev"
26
26
  Dynamic: license-file
27
27
 
28
28
  # pyjevsim
29
+
30
+ [![PyPI](https://img.shields.io/pypi/v/pyjevsim.svg)](https://pypi.org/project/pyjevsim/)
31
+ [![Python](https://img.shields.io/pypi/pyversions/pyjevsim.svg)](https://pypi.org/project/pyjevsim/)
32
+ [![Docs](https://readthedocs.org/projects/pyjevsim/badge/?version=latest)](https://pyjevsim.readthedocs.io/en/latest/)
33
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
34
+
29
35
  ## Introduction
30
- pyjevsim is a DEVS(discrete event system specification) environment that provides journaling functionality.
31
- It provides the ability to snapshot and restore models or simulation engines.
32
- It's compatible with Python versions 3.10+.
33
-
34
- For more information, see the documentation. : [pyjevsim](https://pyjevsim.readthedocs.io/en/latest/index.html)
35
-
36
+
37
+ pyjevsim is a DEVS (discrete event system specification) modeling and
38
+ simulation environment with built-in journaling. It supports snapshot
39
+ and restore of individual models or the full simulation engine,
40
+ virtual-time and real-time execution, and HLA federate integration via
41
+ a stepped execution mode. Compatible with Python 3.10+.
42
+
43
+ Full documentation: <https://pyjevsim.readthedocs.io/en/latest/>
44
+
45
+ ### What's new in 2.0
46
+
47
+ - **Two-phase tick.** `SysExecutor` evaluates every imminent model's
48
+ `output()` first, then routes outputs and applies transitions —
49
+ fixing confluent-event ordering under Parallel-DEVS semantics.
50
+ - **HLA stepped execution.** `step(granted_time)` and
51
+ `get_next_event_time()` let an IEEE 1516-2010 RTI federate drive
52
+ pyjevsim without owning the main loop.
53
+ - **V_TIME jump-to-next-event.** The virtual-time scheduler hops
54
+ directly to the next scheduled event instead of advancing by a fixed
55
+ `time_resolution`, eliminating idle ticks on sparse models.
56
+ - **Opt-in uncaught-message tracking** for debugging dangling outputs.
57
+ - **DEVStone benchmark suite** with cross-engine comparison adapters.
58
+
36
59
  ## Installing
37
- You can install pyjevsim via
60
+
61
+ From PyPI (recommended):
62
+
38
63
  ```
39
- git clone https://github.com/eventsim/pyjevsim
64
+ pip install pyjevsim
40
65
  ```
41
-
42
- ## Dependencies
43
- The only dependency required by pyjevsim is dill ~= 0.3.6 for model serialization and restoration.
44
- dill is an essential library for serializing models and simulation states and can be installed via.
66
+
67
+ From source:
68
+
45
69
  ```
46
- pip install dill
70
+ git clone https://github.com/eventsim/pyjevsim
71
+ cd pyjevsim
72
+ pip install -e .
47
73
  ```
48
-
49
- ### Optional Dependencies
50
- pytest is an optional dependency required for running test cases and example executions.
51
- You can install pyjevsim via
74
+
75
+ ## Dependencies
76
+
77
+ - Python >= 3.10
78
+ - `dill >= 0.3.6` (installed automatically) — used for model
79
+ serialization and restoration.
80
+
81
+ `pytest` is required only to run the test suite and is declared under
82
+ the `dev` extra:
83
+
52
84
  ```
53
- pip install pytest
85
+ pip install pyjevsim[dev]
54
86
  ```
55
-
56
- Additionally, you can install all necessary libraries, including optional dependencies, by running the following command:
87
+
88
+ ## Quick Start
89
+
90
+ A minimal generator → sink simulation:
91
+
92
+ ```python
93
+ from pyjevsim.behavior_model import BehaviorModel
94
+ from pyjevsim.definition import ExecutionType, Infinite
95
+ from pyjevsim.system_executor import SysExecutor
96
+ from pyjevsim.system_message import SysMessage
97
+
98
+
99
+ class Gen(BehaviorModel):
100
+ def __init__(self, name):
101
+ super().__init__(name)
102
+ self.init_state("Generate")
103
+ self.insert_state("Generate", 1)
104
+ self.insert_output_port("out")
105
+
106
+ def ext_trans(self, port, msg): pass
107
+ def int_trans(self): pass
108
+ def output(self, md):
109
+ msg = SysMessage(self.get_name(), "out")
110
+ msg.insert("tick")
111
+ md.insert_message(msg)
112
+ def time_advance(self):
113
+ return 1
114
+
115
+
116
+ class Sink(BehaviorModel):
117
+ def __init__(self, name):
118
+ super().__init__(name)
119
+ self.init_state("Idle")
120
+ self.insert_state("Idle", Infinite)
121
+ self.insert_input_port("in")
122
+
123
+ def ext_trans(self, port, msg):
124
+ print(f"received: {msg.retrieve()}")
125
+ def int_trans(self): pass
126
+ def output(self, md): pass
127
+ def time_advance(self):
128
+ return Infinite
129
+
130
+
131
+ se = SysExecutor(1, ex_mode=ExecutionType.V_TIME)
132
+ gen = Gen("g")
133
+ sink = Sink("s")
134
+ se.register_entity(gen)
135
+ se.register_entity(sink)
136
+ se.coupling_relation(gen, "out", sink, "in")
137
+ se.simulate(5)
57
138
  ```
58
- pip install -r requirements.txt
59
- ```
60
139
 
61
- ## Working with pyjevsim
62
- Once you have installed the library, you can begin working with it.
140
+ See the [quick-start guide](https://pyjevsim.readthedocs.io/en/latest/pyjevsim_quick_start.html)
141
+ for structural models, snapshots, and HLA stepped execution.
142
+
143
+ ### Examples
63
144
 
64
- ### Quick Start
65
- The docs describe how to configure a simulation via pyjevsim's BehaviorModel and SysExecutor.
66
- Check out the [documentation](link) to configure your simulation.
145
+ The [`examples/`](examples/) directory contains:
67
146
 
68
- ### Example
69
- There is a banksim example that uses pyjevsim's DEVS functionality and journaling features.
70
- [documentation](link)
147
+ - **`banksim/`** — bank queue simulation demonstrating BehaviorModel,
148
+ StructuralModel, and snapshot/restore.
149
+ - **`atsim/`** — anti-torpedo simulator with self-propelled and
150
+ stationary decoy models.
151
+ - **`mwmsim/`** — municipal waste management agent-based model.
71
152
 
72
153
  ### Output messages are shared by reference
73
154
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyjevsim"
7
- version = "2.0.0"
7
+ version = "2.0.1"
8
8
  description = "A DEVS(Discrete Event System Specification) Modeling & Simulation environment with journaling functionality"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,48 +0,0 @@
1
- """
2
- Author: Changbeom Choi (@cbchoi)
3
- Copyright (c) 2014-2020 Handong Global University
4
- Copyright (c) 2021-2024 Hanbat National University
5
- License: MIT. The full license text is available at:
6
- https://github.com/eventsim/pyjevsim/blob/main/LICENSE
7
-
8
- This module contains a StructuralModel object that allows you to implement the Discrete Event System Specification CoupledModel.
9
- """
10
-
11
- from .core_model import CoreModel
12
- from .definition import ModelType
13
- from .system_message import SysMessage
14
-
15
- class StructuralModel(CoreModel):
16
- def __init__(self, _name=""):
17
- super().__init__(_name, ModelType.STRUCTURAL)
18
-
19
- self.model_map = {}#(name, model)
20
-
21
- self.port_map = {}
22
-
23
- def register_entity(self, obj):
24
- self.model_map[obj.get_name()] = obj
25
-
26
- def remove_model(self, obj) :
27
- del self.model_map[obj.get_name()]
28
-
29
- def find_model(self, name) :
30
- return self.model_map[name]
31
-
32
- def get_models(self):
33
- return self.model_map
34
-
35
- def coupling_relation(self, src_obj, src_port, dst_obj, dst_port):
36
- src = (src_obj, src_port)
37
- dst = (dst_obj, dst_port)
38
-
39
- # If the source is not in the map, initialize it with an empty list
40
- if src not in self.port_map:
41
- self.port_map[src] = []
42
-
43
- # Add the destination to the source's list of destinations
44
- self.port_map[src].append(dst)
45
- pass
46
-
47
- def get_couplings(self) :
48
- return self.port_map
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes