y_petri 2.0.15 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/lib/y_petri/{manipulator → agent}/hash_key_pointer.rb +2 -2
  3. data/lib/y_petri/agent/petri_net_related.rb +115 -0
  4. data/lib/y_petri/{manipulator → agent}/selection.rb +2 -1
  5. data/lib/y_petri/{manipulator/simulation_related_methods.rb → agent/simulation_related.rb} +93 -110
  6. data/lib/y_petri/agent.rb +22 -0
  7. data/lib/y_petri/core/timed/euler.rb +20 -0
  8. data/lib/y_petri/core/timed/pseudo_euler.rb +31 -0
  9. data/lib/y_petri/core/timed/quasi_euler.rb +23 -0
  10. data/lib/y_petri/core/timed.rb +70 -0
  11. data/lib/y_petri/core/timeless/pseudo_euler.rb +20 -0
  12. data/lib/y_petri/core/timeless.rb +12 -0
  13. data/lib/y_petri/core.rb +100 -0
  14. data/lib/y_petri/dsl.rb +66 -0
  15. data/lib/y_petri/fixed_assets.rb +7 -0
  16. data/lib/y_petri/net/element_access.rb +239 -0
  17. data/lib/y_petri/net/state/feature/delta.rb +88 -0
  18. data/lib/y_petri/net/state/feature/firing.rb +57 -0
  19. data/lib/y_petri/net/state/feature/flux.rb +58 -0
  20. data/lib/y_petri/net/state/feature/gradient.rb +75 -0
  21. data/lib/y_petri/net/state/feature/marking.rb +62 -0
  22. data/lib/y_petri/net/state/feature.rb +79 -0
  23. data/lib/y_petri/net/state/features/dataset.rb +135 -0
  24. data/lib/y_petri/net/state/features/record.rb +50 -0
  25. data/lib/y_petri/net/state/features.rb +126 -0
  26. data/lib/y_petri/net/state.rb +121 -0
  27. data/lib/y_petri/net/timed.rb +8 -0
  28. data/lib/y_petri/net/visualization.rb +3 -3
  29. data/lib/y_petri/net.rb +73 -77
  30. data/lib/y_petri/place.rb +8 -3
  31. data/lib/y_petri/simulation/dependency.rb +107 -0
  32. data/lib/y_petri/simulation/element_representation.rb +20 -0
  33. data/lib/y_petri/simulation/elements/access.rb +57 -0
  34. data/lib/y_petri/simulation/elements.rb +45 -0
  35. data/lib/y_petri/simulation/feature_set.rb +21 -0
  36. data/lib/y_petri/simulation/initial_marking/access.rb +55 -0
  37. data/lib/y_petri/simulation/initial_marking.rb +15 -0
  38. data/lib/y_petri/simulation/marking_clamps/access.rb +34 -0
  39. data/lib/y_petri/simulation/marking_clamps.rb +18 -0
  40. data/lib/y_petri/simulation/marking_vector/access.rb +106 -0
  41. data/lib/y_petri/simulation/marking_vector.rb +156 -0
  42. data/lib/y_petri/simulation/matrix.rb +64 -0
  43. data/lib/y_petri/simulation/place_mapping.rb +62 -0
  44. data/lib/y_petri/simulation/place_representation.rb +74 -0
  45. data/lib/y_petri/simulation/places/access.rb +121 -0
  46. data/lib/y_petri/simulation/places/clamped.rb +8 -0
  47. data/lib/y_petri/simulation/places/free.rb +8 -0
  48. data/lib/y_petri/simulation/places/types.rb +25 -0
  49. data/lib/y_petri/simulation/places.rb +41 -0
  50. data/lib/y_petri/simulation/recorder.rb +54 -0
  51. data/lib/y_petri/simulation/timed/recorder.rb +53 -0
  52. data/lib/y_petri/simulation/timed.rb +161 -261
  53. data/lib/y_petri/simulation/timeless/recorder.rb +25 -0
  54. data/lib/y_petri/simulation/timeless.rb +35 -0
  55. data/lib/y_petri/simulation/transition_representation/A.rb +58 -0
  56. data/lib/y_petri/simulation/transition_representation/S.rb +45 -0
  57. data/lib/y_petri/simulation/transition_representation/T.rb +80 -0
  58. data/lib/y_petri/simulation/transition_representation/TS.rb +46 -0
  59. data/lib/y_petri/simulation/transition_representation/Ts.rb +32 -0
  60. data/lib/y_petri/simulation/transition_representation/a.rb +30 -0
  61. data/lib/y_petri/simulation/transition_representation/s.rb +29 -0
  62. data/lib/y_petri/simulation/transition_representation/t.rb +37 -0
  63. data/lib/y_petri/simulation/transition_representation/tS.rb +38 -0
  64. data/lib/y_petri/simulation/transition_representation/ts.rb +32 -0
  65. data/lib/y_petri/simulation/transition_representation/types.rb +62 -0
  66. data/lib/y_petri/simulation/transition_representation.rb +79 -0
  67. data/lib/y_petri/simulation/transitions/A.rb +40 -0
  68. data/lib/y_petri/simulation/transitions/S.rb +24 -0
  69. data/lib/y_petri/simulation/transitions/T.rb +34 -0
  70. data/lib/y_petri/simulation/transitions/TS.rb +57 -0
  71. data/lib/y_petri/simulation/transitions/Ts.rb +60 -0
  72. data/lib/y_petri/simulation/transitions/a.rb +8 -0
  73. data/lib/y_petri/simulation/transitions/access.rb +186 -0
  74. data/lib/y_petri/simulation/transitions/s.rb +9 -0
  75. data/lib/y_petri/simulation/transitions/t.rb +22 -0
  76. data/lib/y_petri/simulation/transitions/tS.rb +55 -0
  77. data/lib/y_petri/simulation/transitions/ts.rb +58 -0
  78. data/lib/y_petri/simulation/transitions/types.rb +98 -0
  79. data/lib/y_petri/simulation/transitions.rb +21 -0
  80. data/lib/y_petri/simulation.rb +176 -781
  81. data/lib/y_petri/transition/assignment.rb +7 -5
  82. data/lib/y_petri/transition/construction.rb +119 -187
  83. data/lib/y_petri/transition/init.rb +311 -0
  84. data/lib/y_petri/transition/ordinary_timeless.rb +8 -6
  85. data/lib/y_petri/transition/timed.rb +11 -18
  86. data/lib/y_petri/transition.rb +104 -132
  87. data/lib/y_petri/version.rb +1 -1
  88. data/lib/y_petri/world/dependency.rb +40 -0
  89. data/lib/y_petri/world/petri_net_related.rb +61 -0
  90. data/lib/y_petri/{workspace/simulation_related_methods.rb → world/simulation_related.rb} +42 -49
  91. data/lib/y_petri/world.rb +27 -0
  92. data/lib/y_petri.rb +47 -99
  93. data/test/{manipulator_test.rb → agent_test.rb} +19 -17
  94. data/{lib/y_petri → test/examples}/demonstrator.rb +0 -0
  95. data/{lib/y_petri → test/examples}/demonstrator_2.rb +1 -0
  96. data/{lib/y_petri → test/examples}/demonstrator_3.rb +0 -0
  97. data/{lib/y_petri → test/examples}/demonstrator_4.rb +0 -0
  98. data/test/examples/example_2.rb +16 -0
  99. data/test/{manual_examples.rb → examples/manual_examples.rb} +0 -0
  100. data/test/net_test.rb +126 -121
  101. data/test/place_test.rb +1 -1
  102. data/test/sim_test +565 -0
  103. data/test/simulation_test.rb +338 -264
  104. data/test/transition_test.rb +77 -174
  105. data/test/world_mock.rb +12 -0
  106. data/test/{workspace_test.rb → world_test.rb} +19 -20
  107. data/test/y_petri_test.rb +4 -5
  108. metadata +101 -26
  109. data/lib/y_petri/dependency_injection.rb +0 -45
  110. data/lib/y_petri/manipulator/petri_net_related_methods.rb +0 -74
  111. data/lib/y_petri/manipulator.rb +0 -20
  112. data/lib/y_petri/net/selections.rb +0 -209
  113. data/lib/y_petri/simulation/collections.rb +0 -460
  114. data/lib/y_petri/workspace/parametrized_subclassing.rb +0 -22
  115. data/lib/y_petri/workspace/petri_net_related_methods.rb +0 -88
  116. data/lib/y_petri/workspace.rb +0 -16
  117. data/test/timed_simulation_test.rb +0 -153
@@ -1,9 +1,8 @@
1
- # -*- coding: utf-8 -*-
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/construction'
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 directly affects
18
- # the transition. Downstream places are those, whose marking is directly affected
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 has an _action_ -- the operation it represents. The action
24
- # of _non-stoichiometric_ transitions is directly specified by the _action_
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 result of the action closure has to be
27
- # multiplied by the transition's _stoichiometry_ _vector_ to obtain the action.
28
- # Action of the _transitions_ _with_ _rate_ is specified indirectly by the
29
- # _rate_ _closure_.
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 domain model, marking is always a discrete number of _tokens_ -- as
34
- # Carl Adam Petri handed it down to us. YPetri recognizes the usefulness of
35
- # representing a large number of tokens by a floating point number, but sees it
36
- # as a pragmatic measure only. Other Petri net implementations often make class
37
- # distincion between discrete and continuous places, and also distinguish between
38
- # _flux_ ("flow" of the continous transitions) and _propensity_ (firing
39
- # probability of discrete transitions). In YPetri, flux and propensity are
40
- # unified under the term _rate_, and the choice between discrete and stochastic
41
- # computation is seen as a concern of the simulation, not of the model.
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 6 basic types of transitions in YPetri:
44
+ # There are 4 basic transition types in YPetri:
46
45
  #
47
- # * *ts* – timeless nonstoichiometric
46
+ # * *TS* – timed stoichiometric
48
47
  # * *tS* – timeless stoichiometric
49
- # * *Tsr* – timed rateless nonstoichiometric
50
- # * *TSr* – timed rateless stoichiometric
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 the 3 basic qualities:
51
+ # They arise by combining 2 qualities:
55
52
  #
56
- # 1. *Stoichiometricity*: _stoichiometric_ (*S*) / _nonstoichiometric_ (*s*)
57
- # 2. *Timedness*: _timed_ (*T*) / _timeless_ (*t*)
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
- # ==== 1. Stoichiometricity
56
+ # ==== Timedness
61
57
  #
62
- # * For *stoichiometric* transitions:
63
- # - _either_ <b>rate vector</b> is obtained as
64
- # <b>rate * stoichiometry vector</b>,
65
- # - _or_ <b>action vector</b> is obtained as
66
- # <b>action * stoichiometry vector</b>
67
- # * For *non-stoichiometric* transitions:
68
- # - _either_ <b>rate vector</b> is obtained as the <b>rate closure result</b>,
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
- # Summary: stoichiometricity distinguishes the <b>need to multiply the
72
- # rate/action closure result by stoichiometry</b>.
66
+ # ==== Stoichiometricity
73
67
  #
74
- # ==== 2. Having rate
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
- # * Transitions *with* *rate* have a _rate_ _closure_, whose result is to be
77
- # multiplied by +Δt+.
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
- # * Timed transitions are defined as those, whose action has time as a parameter.
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
- # Summary: In rateless transitions, timedness distinguishes the <b>need to
95
- # supply time step duration as the first argument to the action closure</b>.
96
- # As the transitions with rate are necessarily timed, and timeless transitions
97
- # necessarily rateless, there are only 6 instead of 2 ** 3 == 8 transition types.
98
- #
99
- # === Other transition attributes
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
- # Other Petri net implementation often make a distinction between "ordinary"
111
- # and "functional" transitions, where "ordinary" ("functionless") are the
112
- # transitions as Carl Adam Petri handed them down to us. YPetri transtions
113
- # are generally "functional", but the possibility of functionless transitions
114
- # is also provided -- stoichiometric transitions with no action or rate
115
- # specified become functionless transitions.
116
- # definition does not speak about transition "functions". The transitions are
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::DependencyInjection
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
- ts: "timeless nonstoichiometric transition",
127
- tS: "timeless stoichiometric transition",
128
- Tsr: "timed rateless nonstoichiometric transition",
129
- TSr: "timed rateless stoichiometric transition",
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 :s? :stoichiometric?
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 6 basic types :
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
- def basic_type
253
- if has_rate? then stoichiometric? ? :SR : :sR
254
- elsif timed? then stoichiometric? ? :TSr : :Tsr
255
- else stoichiometric? ? :tS : :ts end
256
- end
257
-
258
- # Reports transition's type (basic type + whether it's an assignment
259
- # transition).
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
- assignment_action? ? "A(ts)" : basic_type
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
- # Zero action
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 }(#{basic_type}%s)%s" %
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
@@ -1,4 +1,4 @@
1
1
  module YPetri
2
- VERSION = "2.0.15"
2
+ VERSION = "2.1.3"
3
3
  DEBUG = false
4
4
  end
@@ -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
- # -*- coding: utf-8 -*-
2
- # Workspace instance methods related to simulation (initial marking
3
- # collections, clamp collections, inital marking collections, management
4
- # of simulations...)
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::Workspace::SimulationRelatedMethods
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::DEFAULT_SIMULATION_SETTINGS.call }
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; @simulations end
28
+ def simulations
29
+ @simulations
30
+ end
27
31
 
28
32
  # Clamp collection names.
29
33
  #
30
- def clamp_collection_names; @clamp_collections.keys end
31
- alias cc_names clamp_collection_names
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; @initial_marking_collections.keys end
36
- alias imc_names initial_marking_collection_names
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 ssc_names simulation_settings_collection_names
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 new_timed_simulation( net: Net()::Top, **nn )
141
- net_ɪ = net( net )
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
- # simulation key
150
- key = nn.may_have( :ɴ, syn!: :name ) || # either explicit
151
- { net: net_ɪ, cc: cc_id, imc: imc_id, ssc: ssc_id }.merge( nn ) # or constructed
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
- simulation_settings = self.ssc( ssc_id )
155
- clamp_hash = self.cc( cc_id )
156
- im_hash = self.imc( imc_id )
157
-
158
- # Use places' :default_marking in absence of explicit initial marking.
159
- untreated = net_ɪ.places.select do |p|
160
- ! clamp_hash.map { |k, _| place k }.include? p and
161
- ! im_hash.map { |k, _| place k }.include? p
162
- end
163
- im_complement = Hash[ untreated.zip( untreated.map &:default_marking ) ]
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