y_petri 2.0.15 → 2.1.3
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.
- checksums.yaml +4 -4
- data/lib/y_petri/{manipulator → agent}/hash_key_pointer.rb +2 -2
- data/lib/y_petri/agent/petri_net_related.rb +115 -0
- data/lib/y_petri/{manipulator → agent}/selection.rb +2 -1
- data/lib/y_petri/{manipulator/simulation_related_methods.rb → agent/simulation_related.rb} +93 -110
- data/lib/y_petri/agent.rb +22 -0
- data/lib/y_petri/core/timed/euler.rb +20 -0
- data/lib/y_petri/core/timed/pseudo_euler.rb +31 -0
- data/lib/y_petri/core/timed/quasi_euler.rb +23 -0
- data/lib/y_petri/core/timed.rb +70 -0
- data/lib/y_petri/core/timeless/pseudo_euler.rb +20 -0
- data/lib/y_petri/core/timeless.rb +12 -0
- data/lib/y_petri/core.rb +100 -0
- data/lib/y_petri/dsl.rb +66 -0
- data/lib/y_petri/fixed_assets.rb +7 -0
- data/lib/y_petri/net/element_access.rb +239 -0
- data/lib/y_petri/net/state/feature/delta.rb +88 -0
- data/lib/y_petri/net/state/feature/firing.rb +57 -0
- data/lib/y_petri/net/state/feature/flux.rb +58 -0
- data/lib/y_petri/net/state/feature/gradient.rb +75 -0
- data/lib/y_petri/net/state/feature/marking.rb +62 -0
- data/lib/y_petri/net/state/feature.rb +79 -0
- data/lib/y_petri/net/state/features/dataset.rb +135 -0
- data/lib/y_petri/net/state/features/record.rb +50 -0
- data/lib/y_petri/net/state/features.rb +126 -0
- data/lib/y_petri/net/state.rb +121 -0
- data/lib/y_petri/net/timed.rb +8 -0
- data/lib/y_petri/net/visualization.rb +3 -3
- data/lib/y_petri/net.rb +73 -77
- data/lib/y_petri/place.rb +8 -3
- data/lib/y_petri/simulation/dependency.rb +107 -0
- data/lib/y_petri/simulation/element_representation.rb +20 -0
- data/lib/y_petri/simulation/elements/access.rb +57 -0
- data/lib/y_petri/simulation/elements.rb +45 -0
- data/lib/y_petri/simulation/feature_set.rb +21 -0
- data/lib/y_petri/simulation/initial_marking/access.rb +55 -0
- data/lib/y_petri/simulation/initial_marking.rb +15 -0
- data/lib/y_petri/simulation/marking_clamps/access.rb +34 -0
- data/lib/y_petri/simulation/marking_clamps.rb +18 -0
- data/lib/y_petri/simulation/marking_vector/access.rb +106 -0
- data/lib/y_petri/simulation/marking_vector.rb +156 -0
- data/lib/y_petri/simulation/matrix.rb +64 -0
- data/lib/y_petri/simulation/place_mapping.rb +62 -0
- data/lib/y_petri/simulation/place_representation.rb +74 -0
- data/lib/y_petri/simulation/places/access.rb +121 -0
- data/lib/y_petri/simulation/places/clamped.rb +8 -0
- data/lib/y_petri/simulation/places/free.rb +8 -0
- data/lib/y_petri/simulation/places/types.rb +25 -0
- data/lib/y_petri/simulation/places.rb +41 -0
- data/lib/y_petri/simulation/recorder.rb +54 -0
- data/lib/y_petri/simulation/timed/recorder.rb +53 -0
- data/lib/y_petri/simulation/timed.rb +161 -261
- data/lib/y_petri/simulation/timeless/recorder.rb +25 -0
- data/lib/y_petri/simulation/timeless.rb +35 -0
- data/lib/y_petri/simulation/transition_representation/A.rb +58 -0
- data/lib/y_petri/simulation/transition_representation/S.rb +45 -0
- data/lib/y_petri/simulation/transition_representation/T.rb +80 -0
- data/lib/y_petri/simulation/transition_representation/TS.rb +46 -0
- data/lib/y_petri/simulation/transition_representation/Ts.rb +32 -0
- data/lib/y_petri/simulation/transition_representation/a.rb +30 -0
- data/lib/y_petri/simulation/transition_representation/s.rb +29 -0
- data/lib/y_petri/simulation/transition_representation/t.rb +37 -0
- data/lib/y_petri/simulation/transition_representation/tS.rb +38 -0
- data/lib/y_petri/simulation/transition_representation/ts.rb +32 -0
- data/lib/y_petri/simulation/transition_representation/types.rb +62 -0
- data/lib/y_petri/simulation/transition_representation.rb +79 -0
- data/lib/y_petri/simulation/transitions/A.rb +40 -0
- data/lib/y_petri/simulation/transitions/S.rb +24 -0
- data/lib/y_petri/simulation/transitions/T.rb +34 -0
- data/lib/y_petri/simulation/transitions/TS.rb +57 -0
- data/lib/y_petri/simulation/transitions/Ts.rb +60 -0
- data/lib/y_petri/simulation/transitions/a.rb +8 -0
- data/lib/y_petri/simulation/transitions/access.rb +186 -0
- data/lib/y_petri/simulation/transitions/s.rb +9 -0
- data/lib/y_petri/simulation/transitions/t.rb +22 -0
- data/lib/y_petri/simulation/transitions/tS.rb +55 -0
- data/lib/y_petri/simulation/transitions/ts.rb +58 -0
- data/lib/y_petri/simulation/transitions/types.rb +98 -0
- data/lib/y_petri/simulation/transitions.rb +21 -0
- data/lib/y_petri/simulation.rb +176 -781
- data/lib/y_petri/transition/assignment.rb +7 -5
- data/lib/y_petri/transition/construction.rb +119 -187
- data/lib/y_petri/transition/init.rb +311 -0
- data/lib/y_petri/transition/ordinary_timeless.rb +8 -6
- data/lib/y_petri/transition/timed.rb +11 -18
- data/lib/y_petri/transition.rb +104 -132
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri/world/dependency.rb +40 -0
- data/lib/y_petri/world/petri_net_related.rb +61 -0
- data/lib/y_petri/{workspace/simulation_related_methods.rb → world/simulation_related.rb} +42 -49
- data/lib/y_petri/world.rb +27 -0
- data/lib/y_petri.rb +47 -99
- data/test/{manipulator_test.rb → agent_test.rb} +19 -17
- data/{lib/y_petri → test/examples}/demonstrator.rb +0 -0
- data/{lib/y_petri → test/examples}/demonstrator_2.rb +1 -0
- data/{lib/y_petri → test/examples}/demonstrator_3.rb +0 -0
- data/{lib/y_petri → test/examples}/demonstrator_4.rb +0 -0
- data/test/examples/example_2.rb +16 -0
- data/test/{manual_examples.rb → examples/manual_examples.rb} +0 -0
- data/test/net_test.rb +126 -121
- data/test/place_test.rb +1 -1
- data/test/sim_test +565 -0
- data/test/simulation_test.rb +338 -264
- data/test/transition_test.rb +77 -174
- data/test/world_mock.rb +12 -0
- data/test/{workspace_test.rb → world_test.rb} +19 -20
- data/test/y_petri_test.rb +4 -5
- metadata +101 -26
- data/lib/y_petri/dependency_injection.rb +0 -45
- data/lib/y_petri/manipulator/petri_net_related_methods.rb +0 -74
- data/lib/y_petri/manipulator.rb +0 -20
- data/lib/y_petri/net/selections.rb +0 -209
- data/lib/y_petri/simulation/collections.rb +0 -460
- data/lib/y_petri/workspace/parametrized_subclassing.rb +0 -22
- data/lib/y_petri/workspace/petri_net_related_methods.rb +0 -88
- data/lib/y_petri/workspace.rb +0 -16
- data/test/timed_simulation_test.rb +0 -153
data/lib/y_petri/transition.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
require_relative 'dependency_injection'
|
4
3
|
require_relative 'transition/arcs'
|
5
4
|
require_relative 'transition/cocking'
|
6
|
-
require_relative 'transition/
|
5
|
+
require_relative 'transition/init'
|
7
6
|
require_relative 'transition/timed'
|
8
7
|
require_relative 'transition/ordinary_timeless'
|
9
8
|
require_relative 'transition/assignment'
|
@@ -14,123 +13,106 @@ require_relative 'transition/assignment'
|
|
14
13
|
# === Domain and codomin
|
15
14
|
#
|
16
15
|
# Each transition has a _domain_ (upstream places) and _codomain_ (downstream
|
17
|
-
# places). Upstream places are those, whose marking
|
18
|
-
#
|
19
|
-
# by the transition.
|
16
|
+
# places). Upstream places are those, whose marking affects the transition.
|
17
|
+
# Downstream places are those affected by the transition.
|
20
18
|
#
|
21
19
|
# === Action and action vector
|
22
20
|
#
|
23
|
-
# Every transition
|
24
|
-
#
|
21
|
+
# Every transition _action_ -- the operation it represents. The action of
|
22
|
+
# _non-stoichiometric_ transitions is directly specified by its _action_
|
25
23
|
# _closure_ (whose output arity should match the codomain size.) For
|
26
|
-
# _stoichiometric_ transitions, the
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
24
|
+
# _stoichiometric_ transitions, the action closure result must be multiplied
|
25
|
+
# by the transition's _stoichiometry_ _vector_. _Timed_ _transitions_ have
|
26
|
+
# _rate_ _closure_. Their action can be obtained by multiplying their rate
|
27
|
+
# by Δtime.
|
30
28
|
#
|
31
29
|
# === Rate
|
32
30
|
#
|
33
|
-
# In YPetri
|
34
|
-
#
|
35
|
-
# representing
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# _flux_ (
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
31
|
+
# In YPetri, marking is always considered a discrete number of _tokens_ (as
|
32
|
+
# C. A. Petri has handed it down to us). Usefulness of floating point numbers
|
33
|
+
# in representing larger amounts of tokens is acknowledged, but seen as a
|
34
|
+
# pragmatic measure, an implementation detail. There is no class distinction
|
35
|
+
# between discrete vs. continuous places / transitions. Often we see continuous
|
36
|
+
# transitions with their _flux_ (flow rate) ditinguished from discrete
|
37
|
+
# stochastic transitions with their _propensity_ (likelihood of firing in a
|
38
|
+
# time unit). In YPetri, flux and propensity are unified under a single term
|
39
|
+
# _rate_, and the choice between discrete and stochastic computation is a
|
40
|
+
# concern of the simulation, not of the object model.
|
42
41
|
#
|
43
42
|
# === Basic transition types
|
44
43
|
#
|
45
|
-
# There are
|
44
|
+
# There are 4 basic transition types in YPetri:
|
46
45
|
#
|
47
|
-
# * *
|
46
|
+
# * *TS* – timed stoichiometric
|
48
47
|
# * *tS* – timeless stoichiometric
|
49
|
-
# * *
|
50
|
-
# * *
|
51
|
-
# * *sR* – nonstoichiometric with rate
|
52
|
-
# * *SR* – stoichiometric with rate
|
48
|
+
# * *Ts* – timed nonstoichiometric
|
49
|
+
# * *ts* – timeless nonstoichiometric
|
53
50
|
#
|
54
|
-
# They arise by combining
|
51
|
+
# They arise by combining 2 qualities:
|
55
52
|
#
|
56
|
-
# 1. *
|
57
|
-
# 2. *
|
58
|
-
# 3. *Having* *rate*: having _rate_ (*R*) / not having rate (_rateless_) (*r*)
|
53
|
+
# 1. *Timedness*: _timed_ (*T*) / _timeless_ (*t*)
|
54
|
+
# 2. *Stoichiometricity*: _stoichiometric_ (*S*) / _nonstoichiometric_ (*s*)
|
59
55
|
#
|
60
|
-
# ====
|
56
|
+
# ==== Timedness
|
61
57
|
#
|
62
|
-
# *
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
# - _or_ <b>action vector</b> is obtained as the <b>action closure result</b>.
|
58
|
+
# * Timed transitions have _rate_ _closure_, whose result is to be multiplied
|
59
|
+
# by +Δtime+.
|
60
|
+
# * Timeless transitions have _action_ _closure_, whose result does not need
|
61
|
+
# to be multiplied by time.
|
62
|
+
#
|
63
|
+
# Summary: Having vs. not having rate distinguishes the <em>need to multiply the
|
64
|
+
# closure result by Δ time</em>.
|
70
65
|
#
|
71
|
-
#
|
72
|
-
# rate/action closure result by stoichiometry</b>.
|
66
|
+
# ==== Stoichiometricity
|
73
67
|
#
|
74
|
-
#
|
68
|
+
# * *TS* transitions -- <b>rate vector = rate * stoichiometry vector</b>
|
69
|
+
# * *tS* transitions -- <b>action vector = action * stoichiometry vector</b>
|
70
|
+
# * *Ts* transitions -- <b>rate vector = rate closure result</b>
|
71
|
+
# * *ts* transitions -- <b>action vector = action closure result</b>
|
75
72
|
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
# * For transitions *without* *rate* (*rateless* transitions), the action
|
79
|
-
# closure specifies the action *directly*.
|
80
|
-
#
|
81
|
-
# Summary: Having vs. not having rate distinguishes the <b>need to multiply the
|
82
|
-
# closure result by Δ time</b> -- differentiability of the action by time.
|
83
|
-
#
|
84
|
-
# ==== 3. Timedness
|
73
|
+
# Summary: stoichiometricity distinguishes the <em>need to multiply the rate/action
|
74
|
+
# closure result by stoichiometry</em>.
|
85
75
|
#
|
86
|
-
#
|
87
|
-
# - Transitions with rate are therefore always timed.
|
88
|
-
# - For rateless transitions, being timed means, that their action closure
|
89
|
-
# <b>expects Δt as its first argument</b> -- arity thus equals codomain
|
90
|
-
# size + 1.
|
91
|
-
# * Timeless transitions are those, whose action does not have time as
|
92
|
-
# a parameter. Timeless transitions are necessarily also rateless.
|
76
|
+
# === Assignment action
|
93
77
|
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
# ==== Assignment transitions (_A_ _transitions_)
|
102
|
-
# If +:assignment_action+ option is set to _true_, it makes the transition
|
103
|
-
# entirely replace the codomain marking with its action closure result -- just
|
104
|
-
# like spreadsheet functions do. This, however, is just a convenience, and does
|
105
|
-
# not constitue a novel transition type, as it can be easily emulated by an
|
106
|
-
# ordinary ts transition caring to subtract the current domain marking before
|
107
|
-
# adding the desired values.
|
78
|
+
# _Assignment_ _transitions_ (_*A*_ _transitions_) are special transitions, that
|
79
|
+
# _replace_ the codomain marking rather than modifying it -- they _assign_ new
|
80
|
+
# marking to their codomain, like we are used to from spreadsheets. Technically,
|
81
|
+
# this behavior is easily achievable with normal *ts* transitions, so the
|
82
|
+
# existence of separate *A* transitions is just a convenience, not a new type of
|
83
|
+
# a transition in the mathematical sense.
|
108
84
|
#
|
109
85
|
# ==== _Functional_ / _functionless_ transitions
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
# defined as timeless and more or less assumed to be stoichiometric. Therefore,
|
118
|
-
# in +YPetri::Transition+ constructor, stoichiometric transitions with no
|
119
|
-
# function specified become functionless vanilla Petri net transitions.
|
86
|
+
#
|
87
|
+
# Other Petri net implementation often distinguies between "ordinary" (vanilla
|
88
|
+
# as per C. A. Petri) and _functional_ transitions, whose operation is governed
|
89
|
+
# by a function. In YPetri, transitions are generally _functional_, but there
|
90
|
+
# remains a possibility of creating vanilla (_functionless_) transitions by not
|
91
|
+
# specifying any rate / action, while specifying the stoichiometry. Action
|
92
|
+
# closure as per C. A. Petri is automatically constructed for these.
|
120
93
|
#
|
121
94
|
class YPetri::Transition
|
122
95
|
include NameMagic
|
123
|
-
include YPetri::
|
96
|
+
include YPetri::World::Dependency
|
97
|
+
|
98
|
+
class << self
|
99
|
+
include YPetri::World::Dependency
|
100
|
+
end
|
101
|
+
|
102
|
+
delegate :world, to: "self.class"
|
124
103
|
|
125
104
|
BASIC_TRANSITION_TYPES = {
|
126
|
-
|
127
|
-
tS: "timeless stoichiometric
|
128
|
-
|
129
|
-
|
130
|
-
sR: "nonstoichiometric transition with rate",
|
131
|
-
SR: "stoichiometric transition with rate"
|
105
|
+
TS: "timed stoichiometric",
|
106
|
+
tS: "timeless stoichiometric",
|
107
|
+
Ts: "timed nonstoichiometric",
|
108
|
+
ts: "timeless nonstoichiometric"
|
132
109
|
}
|
133
110
|
|
111
|
+
def TS?; type == :TS end
|
112
|
+
def Ts?; type == :Ts end
|
113
|
+
def tS?; type == :tS end
|
114
|
+
def ts?; type == :ts end
|
115
|
+
|
134
116
|
# Domain, or 'upstream arcs', is a collection of places, whose marking
|
135
117
|
# directly affects the transition's action.
|
136
118
|
#
|
@@ -155,13 +137,14 @@ class YPetri::Transition
|
|
155
137
|
# Is the transition stoichiometric?
|
156
138
|
#
|
157
139
|
def stoichiometric?; @stoichiometric end
|
158
|
-
alias :
|
140
|
+
alias :S? :stoichiometric?
|
159
141
|
|
160
142
|
# Is the transition nonstoichiometric? (Opposite of #stoichiometric?)
|
161
143
|
#
|
162
144
|
def nonstoichiometric?
|
163
145
|
not stoichiometric?
|
164
146
|
end
|
147
|
+
alias :s? :nonstoichiometric?
|
165
148
|
|
166
149
|
# Stoichiometry (implies that the transition is stoichiometric).
|
167
150
|
#
|
@@ -181,18 +164,6 @@ class YPetri::Transition
|
|
181
164
|
stoichio.with_keys { |k| k.name || k.object_id }
|
182
165
|
end
|
183
166
|
|
184
|
-
# Does the transition have rate?
|
185
|
-
#
|
186
|
-
def has_rate?
|
187
|
-
@has_rate
|
188
|
-
end
|
189
|
-
|
190
|
-
# Is the transition rateless?
|
191
|
-
#
|
192
|
-
def rateless?
|
193
|
-
not has_rate?
|
194
|
-
end
|
195
|
-
|
196
167
|
# In YPetri, _rate_ is a unifying term for both _flux_ and _propensity_,
|
197
168
|
# both of which are treated as aliases of _rate_. The decision between
|
198
169
|
# discrete and continuous computation is a concern of the simulation.
|
@@ -217,12 +188,14 @@ class YPetri::Transition
|
|
217
188
|
def timed?
|
218
189
|
@timed
|
219
190
|
end
|
191
|
+
alias T? timed?
|
220
192
|
|
221
193
|
# Is the transition timeless? (Opposite of #timed?)
|
222
194
|
#
|
223
195
|
def timeless?
|
224
196
|
not timed?
|
225
197
|
end
|
198
|
+
alias t? timeless?
|
226
199
|
|
227
200
|
# Is the transition functional?
|
228
201
|
# Explanation: If rate or action closure is supplied, a transition is always
|
@@ -241,43 +214,34 @@ class YPetri::Transition
|
|
241
214
|
not functional?
|
242
215
|
end
|
243
216
|
|
244
|
-
# Reports the transition's membership in one of
|
245
|
-
# 1. ts ..... timeless nonstoichiometric
|
246
|
-
# 2. tS ..... timeless stoichiometric
|
247
|
-
# 3. Tsr .... timed rateless nonstoichiometric
|
248
|
-
# 4. TSr .... timed rateless stoichiometric
|
249
|
-
# 5. sR ..... nonstoichiometric with rate
|
250
|
-
# 6. SR ..... stoichiometric with rate
|
217
|
+
# Reports the transition's membership in one of the 4 basic types:
|
251
218
|
#
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
#
|
259
|
-
#
|
219
|
+
# 1. TS .... timed stoichiometric
|
220
|
+
# 2. tS .... timeless stoichiometric
|
221
|
+
# 3. Ts .... timed nonstoichiometric
|
222
|
+
# 4. ts .... timeless nonstoichiometric
|
223
|
+
#
|
224
|
+
# plus the fifth type
|
225
|
+
#
|
226
|
+
# 5. A .... assignment transitions
|
260
227
|
#
|
261
228
|
def type
|
262
|
-
|
229
|
+
return :A if assignment_action?
|
230
|
+
timed? ? ( stoichiometric? ? :TS : :Ts ) : ( stoichiometric? ? :tS : :ts )
|
263
231
|
end
|
264
232
|
|
265
|
-
# Is it an assignment transition?
|
266
|
-
#
|
267
|
-
# A transition can be specified to have 'assignment action', in which case
|
268
|
-
# it completely replaces codomain marking with the objects resulting from
|
269
|
-
# the transition's action. Note that for numeric marking, specifying
|
270
|
-
# assignment action is a matter of convenience, not necessity, as it can
|
271
|
-
# be emulated by fully subtracting the present codomain values and adding
|
272
|
-
# the numbers computed by the transition to them. Assignment action flag
|
273
|
-
# is a matter of necessity only when codomain marking involves objects
|
274
|
-
# not supporting subtraction/addition (which is out of the scope of Petri's
|
275
|
-
# original specification anyway.)
|
233
|
+
# Is it an assignment transition? (Transitions with 'assignment action'
|
234
|
+
# completely replace their codomain's marking.)
|
276
235
|
#
|
277
236
|
def assignment_action?; @assignment_action end
|
278
237
|
alias :assignment? :assignment_action?
|
238
|
+
alias :A? :assignment_action?
|
279
239
|
|
280
|
-
#
|
240
|
+
# Is it a non-assignment transition? (Opposite of +#A?+)
|
241
|
+
#
|
242
|
+
def a?; ! assignment_action? end
|
243
|
+
|
244
|
+
# Zero action.
|
281
245
|
#
|
282
246
|
def zero_action
|
283
247
|
codomain.map { 0 }
|
@@ -325,8 +289,16 @@ class YPetri::Transition
|
|
325
289
|
#
|
326
290
|
def to_s
|
327
291
|
"#<Transition: %s>" %
|
328
|
-
"#{name.nil? ? '' : '%s ' % name }(#{
|
292
|
+
"#{name.nil? ? '' : '%s ' % name }(#{type}%s)%s" %
|
329
293
|
[ "#{assignment_action? ? ' Assign.' : ''}",
|
330
294
|
"#{name.nil? ? ' id:%s' % object_id : ''}" ]
|
331
295
|
end
|
296
|
+
|
297
|
+
def place id
|
298
|
+
super rescue Place().instance( id )
|
299
|
+
end
|
300
|
+
|
301
|
+
def transition id
|
302
|
+
super rescue Transition().instance( id )
|
303
|
+
end
|
332
304
|
end # class YPetri::Transition
|
data/lib/y_petri/version.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# Provides basic skeleton for dependency injection for the triples of the
|
4
|
+
# parametrized subclasses of Place, Transition and Net in different workspaces.
|
5
|
+
#
|
6
|
+
module YPetri::World::Dependency
|
7
|
+
delegate :Place, :Transition, :Net, to: :world
|
8
|
+
|
9
|
+
# Place instance identification.
|
10
|
+
#
|
11
|
+
def place id
|
12
|
+
world.place( id )
|
13
|
+
end
|
14
|
+
|
15
|
+
# Transition instance identification.
|
16
|
+
#
|
17
|
+
def transition id
|
18
|
+
world.transition( id )
|
19
|
+
end
|
20
|
+
|
21
|
+
# Element instance identification.
|
22
|
+
#
|
23
|
+
def element id
|
24
|
+
begin
|
25
|
+
place( id )
|
26
|
+
rescue NameError, TypeError
|
27
|
+
begin
|
28
|
+
transition( id )
|
29
|
+
rescue NameError, TypeError => err
|
30
|
+
raise TypeError, "Unrecognized place or transition: #{element} (#{err})"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Net instance identification.
|
36
|
+
#
|
37
|
+
def net id
|
38
|
+
Net().instance( id )
|
39
|
+
end
|
40
|
+
end # module YPetri::DependencyInjection
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Workspace instance methods related to Petri net itsef (places, transitions,
|
4
|
+
# net instances).
|
5
|
+
#
|
6
|
+
module YPetri::World::PetriNetRelated
|
7
|
+
# Instance initialization.
|
8
|
+
#
|
9
|
+
def initialize
|
10
|
+
set_up_Top_net # Sets up :Top net encompassing all places and transitions.
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a place instance identified by the argument.
|
15
|
+
#
|
16
|
+
def place id
|
17
|
+
Place().instance( id )
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a transition instance identified by the argument.
|
21
|
+
#
|
22
|
+
def transition id
|
23
|
+
Transition().instance( id )
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a net instance identified by the argument.
|
27
|
+
#
|
28
|
+
def net id
|
29
|
+
Net().instance( id )
|
30
|
+
end
|
31
|
+
|
32
|
+
# Place instances.
|
33
|
+
#
|
34
|
+
def places
|
35
|
+
Place().instances
|
36
|
+
end
|
37
|
+
|
38
|
+
# Transition instances.
|
39
|
+
#
|
40
|
+
def transitions
|
41
|
+
Transition().instances
|
42
|
+
end
|
43
|
+
|
44
|
+
# Net instances.
|
45
|
+
#
|
46
|
+
def nets
|
47
|
+
Net().instances
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Creates all-encompassing Net instance named :Top.
|
53
|
+
#
|
54
|
+
def set_up_Top_net
|
55
|
+
Net().new name: :Top # all-encompassing :Top net
|
56
|
+
# Hook new places to add themselves magically to the :Top net.
|
57
|
+
Place().new_instance_closure { |new_inst| net( :Top ) << new_inst }
|
58
|
+
# Hook new transitions to add themselves magically to the :Top net.
|
59
|
+
Transition().new_instance_closure { |new_inst| net( :Top ) << new_inst }
|
60
|
+
end
|
61
|
+
end # module YPetri::World::PetriNetRelated
|
@@ -1,9 +1,10 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
# of
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Instance methods of the World class related to simulation (initial marking
|
4
|
+
# collections, clamp collections, inital marking collections, management of
|
5
|
+
# simulations...)
|
5
6
|
#
|
6
|
-
module YPetri::
|
7
|
+
module YPetri::World::SimulationRelated
|
7
8
|
# Collections of clamps, initial marking vectors, and simulation settings.
|
8
9
|
#
|
9
10
|
attr_reader :clamp_collections,
|
@@ -17,30 +18,37 @@ module YPetri::Workspace::SimulationRelatedMethods
|
|
17
18
|
@clamp_collections = { Base: {} } # { collection name => clamp hash }
|
18
19
|
@initial_marking_collections = { Base: {} } # { collection name => im hash }
|
19
20
|
@simulation_settings_collections = # { collection name => ss hash }
|
20
|
-
{ Base: YPetri::
|
21
|
+
{ Base: ( YPetri::Simulation::DEFAULT_SETTINGS.call
|
22
|
+
.update YPetri::Simulation::Timed::DEFAULT_SETTINGS.call ) }
|
21
23
|
super
|
22
24
|
end
|
23
25
|
|
24
26
|
# Hash of simulation instances and their settings.
|
25
27
|
#
|
26
|
-
def simulations
|
28
|
+
def simulations
|
29
|
+
@simulations
|
30
|
+
end
|
27
31
|
|
28
32
|
# Clamp collection names.
|
29
33
|
#
|
30
|
-
def clamp_collection_names
|
31
|
-
|
34
|
+
def clamp_collection_names
|
35
|
+
@clamp_collections.keys
|
36
|
+
end
|
37
|
+
alias ncc clamp_collection_names
|
32
38
|
|
33
39
|
# Initial marking collection names.
|
34
40
|
#
|
35
|
-
def initial_marking_collection_names
|
36
|
-
|
41
|
+
def initial_marking_collection_names
|
42
|
+
@initial_marking_collections.keys
|
43
|
+
end
|
44
|
+
alias nimc initial_marking_collection_names
|
37
45
|
|
38
46
|
# Simulation settings collection names.
|
39
47
|
#
|
40
48
|
def simulation_settings_collection_names
|
41
49
|
@simulation_settings_collections.keys
|
42
50
|
end
|
43
|
-
alias
|
51
|
+
alias nssc simulation_settings_collection_names
|
44
52
|
|
45
53
|
# Clamp collection identified by the argument.
|
46
54
|
#
|
@@ -137,47 +145,32 @@ module YPetri::Workspace::SimulationRelatedMethods
|
|
137
145
|
#
|
138
146
|
# * default_ss = { step_size: 0.1, sampling_period: 5, target_time: 60 }
|
139
147
|
#
|
140
|
-
def
|
141
|
-
|
148
|
+
def new_simulation( net: Net()::Top, **nn )
|
149
|
+
net_inst = net( net )
|
142
150
|
nn.may_have :cc, syn!: :clamp_collection
|
143
151
|
nn.may_have :imc, syn!: :initial_marking_collection
|
144
152
|
nn.may_have :ssc, syn!: :simulation_settings_collection
|
145
153
|
cc_id = nn.delete( :cc ) || :Base
|
146
154
|
imc_id = nn.delete( :imc ) || :Base
|
147
155
|
ssc_id = nn.delete( :ssc ) || :Base
|
148
|
-
|
149
|
-
#
|
150
|
-
|
151
|
-
|
152
|
-
|
156
|
+
# Construct the simulation key:
|
157
|
+
key = if nn.has? :name, syn!: :ɴ then # explicit key (name)
|
158
|
+
nn[:name]
|
159
|
+
else # constructed key
|
160
|
+
{}.merge( net: net_inst,
|
161
|
+
cc: cc_id,
|
162
|
+
imc: imc_id,
|
163
|
+
ssc: ssc_id )
|
164
|
+
.merge( nn )
|
165
|
+
end
|
153
166
|
# Let's clarify what we got so far.
|
154
|
-
|
155
|
-
|
156
|
-
im_hash =
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
# If marking can't be figured, raise nice errors.
|
166
|
-
missing = im_complement.select { |_, v| v.nil? }
|
167
|
-
err = lambda { |array, txt=''|
|
168
|
-
raise TypeError, "Missing clamp and/or initial marking for %s#{txt}!" %
|
169
|
-
Array( array ).map { |i| missing.keys[i] }.join( ', ' )
|
170
|
-
}
|
171
|
-
case missing.size
|
172
|
-
when 0 then im_hash = im_hash.merge im_complement # everything's OK
|
173
|
-
when 1 then err.( 0 )
|
174
|
-
when 2 then err.( [0, 1] )
|
175
|
-
when 3 then err.( [0, 1, 2] )
|
176
|
-
else err.( [0, 1], " and #{missing.size-2} more places" ) end
|
177
|
-
|
178
|
-
# Finally, create and return the simulation
|
179
|
-
named_args = simulation_settings.merge( initial_marking: im_hash,
|
180
|
-
marking_clamps: clamp_hash ).merge( nn )
|
181
|
-
@simulations[ key ] = net_ɪ.new_timed_simulation **named_args
|
182
|
-
end # def new_timed_simulation
|
183
|
-
end # module YPetri::Workspace::SimulationRelatedMethods
|
167
|
+
sim_settings = ssc( ssc_id )
|
168
|
+
mc_hash = cc( cc_id )
|
169
|
+
im_hash = imc( imc_id )
|
170
|
+
# Create and return the simulation
|
171
|
+
sim = net_inst.simulation **sim_settings.merge( initial_marking: im_hash,
|
172
|
+
marking_clamps: mc_hash
|
173
|
+
).merge( nn )
|
174
|
+
@simulations[ key ] = sim
|
175
|
+
end
|
176
|
+
end # module YPetri::World::SimulationRelated
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# As the name suggests, represents the world. Holds places, transitions, nets
|
2
|
+
# and other assets needed to set up and simulate Petri nets (settings, clamps,
|
3
|
+
# initial markings etc.). Provides basic methods to do what is necessary.
|
4
|
+
# More ergonomic and DSL-like methods are up to the YPetri::Agent.
|
5
|
+
#
|
6
|
+
class YPetri::World
|
7
|
+
include NameMagic
|
8
|
+
|
9
|
+
require_relative 'world/dependency'
|
10
|
+
require_relative 'world/petri_net_related'
|
11
|
+
require_relative 'world/simulation_related'
|
12
|
+
|
13
|
+
include self::PetriNetRelated
|
14
|
+
include self::SimulationRelated
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
# Parametrize the Place / Transition / Net classes.
|
18
|
+
param_class!( { Place: YPetri::Place,
|
19
|
+
Transition: YPetri::Transition,
|
20
|
+
Net: YPetri::Net },
|
21
|
+
with: { world: self } )
|
22
|
+
# Make them their own namespaces.
|
23
|
+
[ Place(), Transition(), Net() ].each &:namespace!
|
24
|
+
# And proceeed as usual.
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|