y_petri 2.2.4 → 2.3.2

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/LICENSE.txt +675 -0
  3. data/README.md +6 -3
  4. data/Rakefile +1 -1
  5. data/lib/y_petri/agent/{petri_net_related.rb → petri_net_aspect.rb} +34 -10
  6. data/lib/y_petri/agent/{simulation_related.rb → simulation_aspect.rb} +49 -34
  7. data/lib/y_petri/agent.rb +5 -5
  8. data/lib/y_petri/core/guarded.rb +24 -0
  9. data/lib/y_petri/core/timed/euler.rb +4 -8
  10. data/lib/y_petri/core/timed/gillespie.rb +11 -17
  11. data/lib/y_petri/core/timed/methods.rb +23 -0
  12. data/lib/y_petri/core/timed/pseudo_euler.rb +10 -13
  13. data/lib/y_petri/core/timed/quasi_euler.rb +9 -8
  14. data/lib/y_petri/core/timed/runge_kutta.rb +10 -18
  15. data/lib/y_petri/core/timed.rb +6 -14
  16. data/lib/y_petri/core/timeless/methods.rb +15 -0
  17. data/lib/y_petri/core/timeless/pseudo_euler.rb +4 -8
  18. data/lib/y_petri/core/timeless.rb +9 -4
  19. data/lib/y_petri/core.rb +44 -42
  20. data/lib/y_petri/net/data_set.rb +246 -142
  21. data/lib/y_petri/net/node_access.rb +282 -0
  22. data/lib/y_petri/net/own_state.rb +14 -4
  23. data/lib/y_petri/net/state/feature/assignment.rb +123 -0
  24. data/lib/y_petri/net/state/feature/delta.rb +55 -35
  25. data/lib/y_petri/net/state/feature/firing.rb +68 -25
  26. data/lib/y_petri/net/state/feature/flux.rb +9 -2
  27. data/lib/y_petri/net/state/feature/gradient.rb +36 -19
  28. data/lib/y_petri/net/state/feature/marking.rb +10 -5
  29. data/lib/y_petri/net/state/feature.rb +105 -11
  30. data/lib/y_petri/net/state/features/record.rb +144 -99
  31. data/lib/y_petri/net/state/features.rb +327 -200
  32. data/lib/y_petri/net/state.rb +48 -82
  33. data/lib/y_petri/net/visualization.rb +1 -1
  34. data/lib/y_petri/net.rb +62 -47
  35. data/lib/y_petri/place/arcs.rb +44 -0
  36. data/lib/y_petri/place/features.rb +115 -0
  37. data/lib/y_petri/place.rb +62 -29
  38. data/lib/y_petri/simulation/dependency.rb +31 -67
  39. data/lib/y_petri/simulation/feature_set.rb +1 -1
  40. data/lib/y_petri/simulation/initial_marking/access.rb +42 -26
  41. data/lib/y_petri/simulation/marking_clamps/access.rb +22 -17
  42. data/lib/y_petri/simulation/marking_clamps.rb +0 -2
  43. data/lib/y_petri/simulation/marking_vector/access.rb +102 -40
  44. data/lib/y_petri/simulation/marking_vector.rb +35 -37
  45. data/lib/y_petri/simulation/matrix.rb +1 -1
  46. data/lib/y_petri/simulation/node_representation.rb +25 -0
  47. data/lib/y_petri/simulation/nodes/access.rb +78 -0
  48. data/lib/y_petri/simulation/{elements.rb → nodes.rb} +14 -13
  49. data/lib/y_petri/simulation/place_mapping.rb +2 -2
  50. data/lib/y_petri/simulation/place_representation.rb +8 -7
  51. data/lib/y_petri/simulation/places/access.rb +89 -70
  52. data/lib/y_petri/simulation/places/free.rb +1 -1
  53. data/lib/y_petri/simulation/places/types.rb +20 -22
  54. data/lib/y_petri/simulation/places.rb +23 -18
  55. data/lib/y_petri/simulation/recorder.rb +23 -18
  56. data/lib/y_petri/simulation/timed/recorder.rb +19 -11
  57. data/lib/y_petri/simulation/timed.rb +93 -29
  58. data/lib/y_petri/simulation/timeless/recorder.rb +11 -6
  59. data/lib/y_petri/simulation/timeless.rb +13 -3
  60. data/lib/y_petri/simulation/transition_representation/A.rb +24 -4
  61. data/lib/y_petri/simulation/transition_representation/S.rb +11 -1
  62. data/lib/y_petri/simulation/transition_representation/T.rb +1 -1
  63. data/lib/y_petri/simulation/transition_representation/Ts.rb +1 -1
  64. data/lib/y_petri/simulation/transition_representation/a.rb +1 -1
  65. data/lib/y_petri/simulation/transition_representation/s.rb +12 -1
  66. data/lib/y_petri/simulation/transition_representation/t.rb +1 -1
  67. data/lib/y_petri/simulation/transition_representation/tS.rb +1 -1
  68. data/lib/y_petri/simulation/transition_representation/ts.rb +1 -1
  69. data/lib/y_petri/simulation/transition_representation/types.rb +1 -1
  70. data/lib/y_petri/simulation/transition_representation.rb +4 -11
  71. data/lib/y_petri/simulation/transitions/A.rb +17 -2
  72. data/lib/y_petri/simulation/transitions/S.rb +1 -1
  73. data/lib/y_petri/simulation/transitions/T.rb +1 -1
  74. data/lib/y_petri/simulation/transitions/Ts.rb +6 -5
  75. data/lib/y_petri/simulation/transitions/a.rb +1 -1
  76. data/lib/y_petri/simulation/transitions/access.rb +195 -168
  77. data/lib/y_petri/simulation/transitions/s.rb +1 -1
  78. data/lib/y_petri/simulation/transitions/t.rb +1 -1
  79. data/lib/y_petri/simulation/transitions/tS.rb +1 -1
  80. data/lib/y_petri/simulation/transitions/ts.rb +1 -1
  81. data/lib/y_petri/simulation/transitions/types.rb +1 -1
  82. data/lib/y_petri/simulation/transitions.rb +5 -7
  83. data/lib/y_petri/simulation.rb +84 -90
  84. data/lib/y_petri/transition/A.rb +8 -2
  85. data/lib/y_petri/transition/T.rb +25 -2
  86. data/lib/y_petri/transition/arcs.rb +19 -3
  87. data/lib/y_petri/transition/construction_convenience.rb +11 -10
  88. data/lib/y_petri/transition/t.rb +14 -1
  89. data/lib/y_petri/transition/types.rb +6 -1
  90. data/lib/y_petri/transition.rb +9 -12
  91. data/lib/y_petri/version.rb +1 -1
  92. data/lib/y_petri/world/dependency.rb +3 -3
  93. data/lib/y_petri/world/{petri_net_related.rb → petri_net_aspect.rb} +4 -4
  94. data/lib/y_petri/world/simulation_aspect.rb +352 -0
  95. data/lib/y_petri/world.rb +4 -4
  96. data/lib/y_petri.rb +1 -1
  97. data/test/agent_test.rb +2 -1
  98. data/test/examples/demonstrator.rb +4 -1
  99. data/test/examples/demonstrator_2.rb +5 -0
  100. data/test/examples/demonstrator_4.rb +6 -5
  101. data/test/examples/example_2.rb +2 -0
  102. data/test/examples/manual_examples.rb +4 -4
  103. data/test/net_test.rb +457 -54
  104. data/test/place_test.rb +11 -7
  105. data/test/simulation_test.rb +358 -331
  106. data/test/transition_test.rb +11 -10
  107. data/test/world_test.rb +2 -0
  108. data/test/y_petri_test.rb +2 -1
  109. data/y_petri.gemspec +24 -18
  110. metadata +71 -17
  111. data/LICENSE +0 -22
  112. data/lib/y_petri/net/element_access.rb +0 -239
  113. data/lib/y_petri/simulation/element_representation.rb +0 -20
  114. data/lib/y_petri/simulation/elements/access.rb +0 -57
  115. data/lib/y_petri/transition/type.rb +0 -103
  116. data/lib/y_petri/transition/type_information.rb +0 -103
  117. data/lib/y_petri/world/simulation_related.rb +0 -176
@@ -1,303 +1,325 @@
1
1
  #! /usr/bin/ruby
2
2
  # encoding: utf-8
3
3
 
4
+ gem 'minitest'
4
5
  require 'minitest/autorun'
5
6
  require_relative '../lib/y_petri' # tested component itself
6
7
  # require 'y_petri'
7
8
  # require 'sy'
8
9
 
9
- describe YPetri::Simulation do
10
- before do
11
- @w = YPetri::World.new
12
- end
13
-
14
- it "should allow for creation of an empty simulation" do
15
- net = @w.Net.send :new
16
- sim = net.simulation
17
- sim.pp.must_equal []
18
- sim.pp( *[] ).must_equal []
19
- sim.tt.must_equal( [] )
20
- sim.tt( *[] ).must_equal []
21
- end
22
-
23
- describe "simulation setup" do
24
- before do
25
- @p = @w.Place.send :new, name: :A, default_marking: 1
26
- @q = @w.Place.send :new, name: :B, default_marking: 2
27
- @net = @w.Net.of [ @p, @q ]
28
- end
29
-
30
- it "should allow to set up a simplistic simulation instance" do
31
- @net.simulation
32
- @net.simulation marking_clamps: { @q => 42 } # one clamp
33
- @net.simulation initial_marking: { @p => 42, @q => 43 }
34
- @net.simulation marking_clamps: { @p => 42 }, initial_marking: { @q => 43 }
35
- @net.simulation initial_marking: { A: 42 }
36
- end
37
-
38
- it "should fail with malformed arguments" do
39
- -> { @net.simulation use_default_marking: false }.must_raise TypeError
40
- -> { @net.simulation initial_marking: { Foo: 1 } }.must_raise NameError
41
- end
42
-
43
- describe "place representation aspects" do
44
- before do
45
- @s = YPetri::Simulation.new( net: @net,
46
- initial_marking: { A: 42 },
47
- marking_clamps: { B: 43 } )
48
- end
49
-
50
- it "should have elements/access" do
51
- @s.send( :place, :A )
52
- .must_be_kind_of YPetri::Simulation::PlaceRepresentation
53
- @s.send( :place, :B )
54
- .must_be_kind_of YPetri::Simulation::PlaceRepresentation
55
- @s.net.places.names.must_equal [:A, :B]
56
- @s.pn.must_equal [:A, :B]
57
- @s.send( :places ).free.size.must_equal 1
58
- @s.send( :places ).first.quantum.must_equal 1
59
- @s.send( :free_places ).names.must_equal [:A]
60
- @s.send( :places ).clamped.size.must_equal 1
61
- @s.send( :clamped_places ).names.must_equal [:B]
62
- @s.send( :places, [:A] ).map( &:source ).must_equal [@p]
63
- @s.send( :transitions, [] ).must_equal []
64
- @s.send( :places, [:A] ).map( &:source ).must_equal [@p]
65
- @s.send( :places, [] ).must_equal []
66
- end
67
-
68
- describe "marking vector representation" do
69
- it "should work" do
70
- @s.instance_variable_get( :@m_vector ).must_equal @s.m_vector
71
- @s.m_vector.must_be_kind_of YPetri::Simulation::MarkingVector
72
- @s.m_vector.size.must_equal 2
73
- @s.m_vector.to_a.must_equal [42, 43]
74
- @s.m.must_equal [42, 43]
75
- @s.marking.must_equal [42]
76
- @s.marking_clamps.keys_to_names.must_equal( { B: 43 } )
77
- end
78
- end
79
- end # describe simulation step
80
-
81
- describe "transition representation aspects" do
82
- before do
83
- @ts = @w.Transition.send :new, name: "T_ts", codomain: :A, action: -> { 1 }
84
- @tS = @w.Transition.send :new, name: "T_tS", s: { B: -1, A: 1 }, action: proc { 1 }
85
- @Ts = @w.Transition.send :new, name: "T_Ts", codomain: :A, rate: -> { 1 }
86
- @TS = @w.Transition.send :new, name: "T_TS", s: { B: -1, A: 1 }, rate: proc { 1 }
87
- end
88
-
89
- it "should be what intended" do
90
- @ts.type.must_equal :ts
91
- @ts.domain.must_equal []
92
- @ts.codomain.must_equal [@p]
93
- @tS.type.must_equal :tS
94
- @tS.domain.must_equal [@q] # inferred
95
- @tS.codomain.must_equal [@q, @p]
96
- @Ts.type.must_equal :Ts
97
- @Ts.domain.must_equal []
98
- @Ts.codomain.must_equal [@p]
99
- @TS.type.must_equal :TS
100
- @TS.domain.must_equal [@q] # inferred
101
- @TS.codomain.must_equal [@q, @p]
102
- end
103
-
104
- describe "ts transition" do
105
- before do
106
- @net = @w.Net.of [ @p, @q, @ts ]
107
- end
108
-
109
- describe "no clamps" do
110
- before do
111
- @sim = @net.simulation net: @net
112
- end
113
-
114
- it "should behave" do
115
- @sim.tt.size.must_equal 1
116
- @ts.codomain.names.must_equal [:A]
117
- @sim.ts_tt.first.codomain.names.must_equal [:A]
118
- @ts.domain.names.must_equal []
119
- @sim.ts_tt.first.domain.names.must_equal []
120
- @sim.timed?.must_equal false
121
- @sim.m.must_equal [1, 2]
122
- @sim.p_m.must_equal( { A: 1, B: 2 } )
123
- @sim.recording.must_equal( { 0 => [1, 2]} )
124
- @sim.simulation_method.must_equal :pseudo_euler
125
- @sim.core.must_be_kind_of YPetri::Core
126
- @sim.ts_tt.first.domain.must_equal []
127
- @sim.send( :ts_transitions ).first.domain_access_code.must_equal ''
128
- λ = @sim.send( :transitions ).ts.first.delta_closure
129
- λ.arity.must_equal 0
130
- λ.call.must_equal 1
131
- cc = @sim.send( :transitions ).ts.delta_closures
132
- cc.map( &:call ).must_equal [1]
133
- cl = @sim.send( :transitions ).ts.delta_closure
134
- cl.call.must_equal Matrix[ [1], [0] ]
135
- @sim.step!
136
- @sim.p_m.must_equal( { A: 2, B: 2 } ) # marking of A goes up by 1
137
- @sim.recording.must_equal( { 0 => [1, 2], 1 => [2, 2] } )
138
- end
139
- end
140
-
141
- describe "with clamps" do
142
- before do
143
- @sim = @net.simulation marking_clamps: { B: 42 }
144
- end
145
-
146
- it "should behave" do
147
- @sim.recording.must_equal( { 0 => [1] } )
148
- @sim.step!
149
- @sim.recording.must_equal( { 0 => [1], 1 => [2] } )
150
- end
151
- end
152
- end # ts transition
153
-
154
- describe "tS transition" do
155
- before do
156
- @net = @w.Net.of [ @p, @q, @tS ]
157
- end
158
-
159
- describe "no clamps" do
160
- before do
161
- @sim = @net.simulation net: @net
162
- end
163
-
164
- it "should behave" do
165
- @sim.recording.must_equal( { 0 => [1, 2] } )
166
- @sim.step!
167
- @sim.recording.must_equal( { 0 => [1, 2], 1 => [2, 1] } )
168
- end
169
- end
170
-
171
- describe "with clamps" do
172
- before do
173
- @sim = @net.simulation marking_clamps: { B: 43 }
174
- end
175
-
176
- it "should behave" do
177
- @sim.recording.must_equal( { 0 => [1] } )
178
- 3.times do @sim.step! end
179
- @sim.recording.must_equal( { 0 => [1], 1 => [2], 2 => [3], 3 => [4] } )
180
- end
181
- end
182
- end # tS transition
183
-
184
- describe "Ts transition" do
185
- before do
186
- @net = @w.Net.of [ @p, @q, @Ts ]
187
- end
188
-
189
- describe "no clamps" do
190
- before do
191
- @sim = @net.simulation sampling: 1
192
- end
193
-
194
- it "should behave" do
195
- @sim.timed?.must_equal true
196
- @sim.simulation_method.must_equal :pseudo_euler
197
- @sim.Ts_tt.size.must_equal 1
198
- @sim.send( :transitions ).Ts.first.gradient_closure.call.must_equal 1
199
- @sim.Ts_tt.first.codomain.names.must_equal [:A]
200
- @sim.recording.must_equal( { 0.0 => [1, 2] } )
201
- @sim.step! 1
202
- @sim.recording.must_equal( { 0.0 => [1, 2], 1.0 => [2, 2] } )
203
- end
204
- end
205
-
206
- describe "with clamps" do
207
- before do
208
- @sim = @net.simulation sampling: 1, marking_clamps: { B: 43 }
209
- end
210
-
211
- it "should behave" do
212
- @sim.recording.must_equal( { 0.0 => [1] } )
213
- 3.times do @sim.step! 1 end
214
- @sim.recording.must_equal( { 0.0 => [1], 1.0 => [2], 2.0 => [3], 3.0 => [4] } )
215
- end
216
- end
217
- end # Ts transition
218
-
219
- describe "TS transition" do
220
- before do
221
- @net = @w.Net.of [ @p, @q, @TS ]
222
- end
223
-
224
- describe "no clamps" do
225
- before do
226
- @sim = @net.simulation sampling: 1
227
- end
228
-
229
- it "should behave" do
230
- @sim.recording.must_be_kind_of YPetri::Net::DataSet
231
- @sim.recording
232
- .must_equal @net.State.marking.new_dataset.update( 0.0 => [1, 2] )
233
- @sim.recording.must_equal( { 0.0 => [1, 2] } )
234
- @sim.step! 1
235
- @sim.recording.must_equal( { 0.0 => [1, 2], 1.0 => [2, 1] } )
236
- end
237
- end
238
-
239
- describe "with clamps" do
240
- before do
241
- @sim = @net.simulation sampling: 1, marking_clamps: { B: 43 }
242
- end
243
-
244
- it "should behave" do
245
- @sim.recording.must_equal( { 0.0 => [1] } )
246
- 3.times do @sim.step! end
247
- @sim.recording.must_equal( { 0.0 => [1], 1.0 => [2], 2.0 => [3], 3.0 => [4] } )
248
- end
249
- end
250
- end # TS transition
251
- end # transition representation aspects
252
- end
253
- end
254
-
255
- describe "timeless simulation" do
256
- before do
257
- self.class.class_exec { include YPetri }
258
- U = Place m!: 2.5
259
- V = Place m!: 2.5
260
- Uplus = Transition codomain: :U do 1 end # s transition
261
- U2V = Transition s: { U: -1, V: 1 } # S transition
262
- set_ssc :Timeless, YPetri::Simulation::DEFAULT_SETTINGS.call
263
- new_simulation ssc: :Timeless
264
- 5.times do simulation.step! end
265
- end
266
-
267
- it "should behave" do
268
- s = simulation
269
- assert ! s.timed?
270
- s.core.must_be_kind_of YPetri::Core::Timeless::PseudoEuler
271
- ds = s.recording
272
- ds.size.must_equal 6
273
- ds.events.must_equal [0, 1, 2, 3, 4, 5]
274
- ds.interpolate( 1 )
275
- .must_equal [2.5, 3.5]
276
- ds.interpolate( 2 )
277
- .must_equal [2.5, 4.5]
278
- -> { ds.interpolate( 1.5 ) }.must_raise TypeError
279
- ds.reconstruct( event: 2 )
280
- .p_m.must_equal( { U: 2.5, V: 4.5 } )
281
- ds.reconstruct( event: 2 ).must_respond_to( :pm )
282
- ds.marking.slice( 2..4 ).series
283
- .must_equal [[2.5, 2.5, 2.5], [4.5, 5.5, 6.5]]
284
- ds.marking.slice( 2..4 )
285
- .must_equal( { 2 => [2.5, 4.5],
286
- 3 => [2.5, 5.5],
287
- 4 => [2.5, 6.5] } )
288
- ds.firing.slice( 1..2 ).series
289
- .must_equal [[1, 1]]
290
- ds.series( firing: [:U2V] )
291
- .must_equal [ [ 1, 1, 1, 1, 1, 1 ] ]
292
- ds.delta( [:U], transitions: [:Uplus] ).series
293
- .must_equal [ [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ]
294
- tmp = ds.reduce_features( marking: [:U], firing: [:U2V] )
295
- tmp.features
296
- .must_equal( ds.net.State.features marking: [:U], firing: [:U2V] )
297
- tmp.must_equal( { 0 => [2.5, 1], 1 => [2.5, 1], 2 => [2.5, 1],
298
- 3 => [2.5, 1], 4 => [2.5, 1], 5 => [2.5, 1] } )
299
- end
300
- end
10
+ # describe YPetri::Simulation do
11
+ # before do
12
+ # @w = YPetri::World.new
13
+ # end
14
+
15
+ # it "should allow for creation of an empty simulation" do
16
+ # net = @w.Net.send :new
17
+ # sim = net.simulation
18
+ # skip
19
+ # sim.pp.must_equal []
20
+ # sim.pp( *[] ).must_equal []
21
+ # sim.tt.must_equal( [] )
22
+ # sim.tt( *[] ).must_equal []
23
+ # end
24
+
25
+ # describe "simulation setup" do
26
+ # before do
27
+ # @p = @w.Place.send :new, name: :A, default_marking: 1
28
+ # @q = @w.Place.send :new, name: :B, default_marking: 2
29
+ # @net = @w.Net.of [ @p, @q ]
30
+ # end
31
+
32
+ # it "should allow to set up a simplistic simulation instance" do
33
+ # @net.simulation
34
+ # @net.simulation marking_clamps: { @q => 42 } # one clamp
35
+ # @net.simulation initial_marking: { @p => 42, @q => 43 }
36
+ # @net.simulation marking_clamps: { @p => 42 }, initial_marking: { @q => 43 }
37
+ # @net.simulation initial_marking: { A: 42 }
38
+ # end
39
+
40
+ # it "should fail with malformed arguments" do
41
+ # -> { @net.simulation use_default_marking: false }.must_raise TypeError
42
+ # -> { @net.simulation initial_marking: { Foo: 1 } }.must_raise NameError
43
+ # end
44
+
45
+ # describe "place representation aspects" do
46
+ # before do
47
+ # @s = YPetri::Simulation.new( net: @net,
48
+ # initial_marking: { A: 42 },
49
+ # marking_clamps: { B: 43 } )
50
+ # end
51
+
52
+ # it "should have elements/access" do
53
+ # @s.send( :place, :A )
54
+ # .must_be_kind_of YPetri::Simulation::PlaceRepresentation
55
+ # @s.send( :place, :B )
56
+ # .must_be_kind_of YPetri::Simulation::PlaceRepresentation
57
+ # @s.net.places.names.must_equal [:A, :B]
58
+ # @s.pn.must_equal [:A, :B]
59
+ # @s.send( :places ).free.size.must_equal 1
60
+ # @s.send( :places ).first.quantum.must_equal 1
61
+ # @s.send( :free_places ).names.must_equal [:A]
62
+ # @s.send( :places ).clamped.size.must_equal 1
63
+ # @s.send( :clamped_places ).names.must_equal [:B]
64
+ # @s.send( :Places, [:A] ).map( &:source ).must_equal [@p]
65
+ # @s.send( :places, :A ).map( &:source ).must_equal [@p]
66
+ # @s.send( :Transitions, [] ).must_equal []
67
+ # @s.send( :Places, [] ).must_equal []
68
+ # end
69
+
70
+ # describe "marking vector representation" do
71
+ # it "should work" do
72
+ # @s.instance_variable_get( :@m_vector ).must_equal @s.m_vector
73
+ # @s.m_vector.must_be_kind_of YPetri::Simulation::MarkingVector
74
+ # @s.m_vector.size.must_equal 2
75
+ # @s.m_vector.to_a.must_equal [42, 43]
76
+ # @s.m.must_equal [42, 43]
77
+ # @s.marking.must_equal [42]
78
+ # @s.marking_clamps.keys_to_names.must_equal( { B: 43 } )
79
+ # end
80
+ # end
81
+ # end # describe simulation step
82
+
83
+ # describe "transition representation aspects" do
84
+ # before do
85
+ # @ts = @w.Transition.send :new, name: "T_ts", codomain: :A, action: -> { 1 }
86
+ # @tS = @w.Transition.send :new, name: "T_tS", s: { B: -1, A: 1 }, action: proc { 1 }
87
+ # @Ts = @w.Transition.send :new, name: "T_Ts", codomain: :A, rate: -> { 1 }
88
+ # @TS = @w.Transition.send :new, name: "T_TS", s: { B: -1, A: 1 }, rate: proc { 1 }
89
+ # end
90
+
91
+ # it "should be what intended" do
92
+ # @ts.type.must_equal :ts
93
+ # @ts.domain.must_equal []
94
+ # @ts.codomain.must_equal [@p]
95
+ # @tS.type.must_equal :tS
96
+ # @tS.domain.must_equal [@q] # inferred
97
+ # @tS.codomain.must_equal [@q, @p]
98
+ # @Ts.type.must_equal :Ts
99
+ # @Ts.domain.must_equal []
100
+ # @Ts.codomain.must_equal [@p]
101
+ # @TS.type.must_equal :TS
102
+ # @TS.domain.must_equal [@q] # inferred
103
+ # @TS.codomain.must_equal [@q, @p]
104
+ # end
105
+
106
+ # describe "ts transition" do
107
+ # before do
108
+ # @net = @w.Net.of [ @p, @q, @ts ]
109
+ # end
110
+
111
+ # describe "no clamps" do
112
+ # before do
113
+ # @sim = @net.simulation net: @net
114
+ # end
115
+
116
+ # it "should behave" do
117
+ # @sim.tt.size.must_equal 1
118
+ # @ts.codomain.names.must_equal [:A]
119
+ # @sim.ts_tt.first.codomain.names.must_equal [:A]
120
+ # @ts.domain.names.must_equal []
121
+ # @sim.ts_tt.first.domain.names.must_equal []
122
+ # @sim.timed?.must_equal false
123
+ # @sim.m.must_equal [1, 2]
124
+ # @sim.p_m.must_equal( { A: 1, B: 2 } )
125
+ # @sim.recording.must_equal( { 0 => [1, 2]} )
126
+ # @sim.simulation_method.must_equal :pseudo_euler
127
+ # @sim.core.must_be_kind_of YPetri::Core
128
+ # @sim.ts_tt.first.domain.must_equal []
129
+ # @sim.send( :ts_transitions ).first.domain_access_code.must_equal ''
130
+ # λ = @sim.send( :transitions ).ts.first.delta_closure
131
+ # λ.arity.must_equal 0
132
+ # λ.call.must_equal [1]
133
+ # cc = @sim.send( :transitions ).ts.delta_closures
134
+ # cc.map( &:call ).map( &:first ).must_equal [1]
135
+ # cl = @sim.send( :transitions ).ts.delta_closure
136
+ # cl.call.must_equal Matrix[ [1], [0] ]
137
+ # @sim.step!
138
+ # @sim.p_m.must_equal( { A: 2, B: 2 } ) # marking of A goes up by 1
139
+ # @sim.recording.must_equal( { 0 => [1, 2], 1 => [2, 2] } )
140
+ # end
141
+ # end
142
+
143
+ # describe "with clamps" do
144
+ # before do
145
+ # @sim = @net.simulation marking_clamps: { B: 42 }
146
+ # end
147
+
148
+ # it "should behave" do
149
+ # @sim.recording.must_equal( { 0 => [1] } )
150
+ # @sim.step!
151
+ # @sim.recording.must_equal( { 0 => [1], 1 => [2] } )
152
+ # end
153
+ # end
154
+ # end # ts transition
155
+
156
+ # describe "tS transition" do
157
+ # before do
158
+ # @net = @w.Net.of [ @p, @q, @tS ]
159
+ # end
160
+
161
+ # describe "no clamps" do
162
+ # before do
163
+ # @sim = @net.simulation net: @net
164
+ # end
165
+
166
+ # it "should behave" do
167
+ # @sim.recording.must_equal( { 0 => [1, 2] } )
168
+ # @sim.step!
169
+ # @sim.recording.must_equal( { 0 => [1, 2], 1 => [2, 1] } )
170
+ # end
171
+ # end
172
+
173
+ # describe "with clamps" do
174
+ # before do
175
+ # @sim = @net.simulation marking_clamps: { B: 43 }
176
+ # end
177
+
178
+ # it "should behave" do
179
+ # @sim.recording.must_equal( { 0 => [1] } )
180
+ # 3.times do @sim.step! end
181
+ # @sim.recording.must_equal( { 0 => [1], 1 => [2], 2 => [3], 3 => [4] } )
182
+ # end
183
+ # end
184
+ # end # tS transition
185
+
186
+ # describe "Ts transition" do
187
+ # before do
188
+ # @net = @w.Net.of [ @p, @q, @Ts ]
189
+ # end
190
+
191
+ # describe "no clamps" do
192
+ # before do
193
+ # @sim = @net.simulation sampling: 1
194
+ # end
195
+
196
+ # it "should behave" do
197
+ # @sim.timed?.must_equal true
198
+ # @sim.simulation_method.must_equal :pseudo_euler
199
+ # @sim.Ts_tt.size.must_equal 1
200
+ # @sim.send( :transitions ).Ts.first.gradient_closure.call.must_equal [1]
201
+ # @sim.Ts_tt.first.codomain.names.must_equal [:A]
202
+ # @sim.recording.must_equal( { 0.0 => [1, 2] } )
203
+ # @sim.step! 1
204
+ # @sim.recording.must_equal( { 0.0 => [1, 2], 1.0 => [2, 2] } )
205
+ # end
206
+ # end
207
+
208
+ # describe "with clamps" do
209
+ # before do
210
+ # @sim = @net.simulation sampling: 1, marking_clamps: { B: 43 }
211
+ # end
212
+
213
+ # it "should behave" do
214
+ # @sim.send( :transitions ).Ts.first.codomain.names.must_equal [:A]
215
+ # @sim.simulation_method.must_equal :pseudo_euler
216
+ # @sim.timed?.must_equal true
217
+ # @sim.core.timed?.must_equal true
218
+ # @sim.reset!
219
+ # @sim.time.must_equal 0
220
+ # @sim.p_m.must_equal( { A: 1, B: 43 } )
221
+ # @sim.recording.must_equal( { 0.0 => [1] } )
222
+ # @sim.send( :transitions ).Ts.first.gradient_closure.call.must_equal [1]
223
+ # @sim.step! 1
224
+ # @sim.time.must_equal 1
225
+ # @sim.p_m.must_equal( { A: 2, B: 43 } )
226
+ # @sim.recording.to_h.must_equal( { 0.0 => [1], 1.0 => [2] } )
227
+ # @sim.send( :transitions ).Ts.first.gradient_closure.call.must_equal [1]
228
+ # @sim.step! 1
229
+ # @sim.time.must_equal 2
230
+ # @sim.p_m.must_equal( { A: 3, B: 43 } )
231
+ # @sim.recording.to_h.must_equal( { 0.0 => [1], 1.0 => [2], 2.0 => [3] } )
232
+ # @sim.send( :transitions ).Ts.first.gradient_closure.call.must_equal [1]
233
+
234
+ # 3.times do @sim.step! 1 end
235
+ # @sim.recording.to_h
236
+ # .must_equal( { 0.0 => [1], 1.0 => [2], 2.0 => [3], 3.0 => [4] } )
237
+ # end
238
+ # end
239
+ # end # Ts transition
240
+
241
+ # describe "TS transition" do
242
+ # before do
243
+ # @net = @w.Net.of [ @p, @q, @TS ]
244
+ # end
245
+
246
+ # describe "no clamps" do
247
+ # before do
248
+ # @sim = @net.simulation sampling: 1
249
+ # end
250
+
251
+ # it "should behave" do
252
+ # @sim.recording.must_be_kind_of YPetri::Net::DataSet
253
+ # @sim.recording
254
+ # .must_equal @net.State.Features.marking.DataSet.new.update( 0.0 => [1, 2] )
255
+ # @sim.recording.must_equal( { 0.0 => [1, 2] } )
256
+ # @sim.step! 1
257
+ # @sim.recording.must_equal( { 0.0 => [1, 2], 1.0 => [2, 1] } )
258
+ # end
259
+ # end
260
+
261
+ # describe "with clamps" do
262
+ # before do
263
+ # @sim = @net.simulation sampling: 1, marking_clamps: { B: 43 }
264
+ # end
265
+
266
+ # it "should behave" do
267
+ # @sim.recording.must_equal( { 0.0 => [1] } )
268
+ # 3.times do @sim.step! end
269
+ # @sim.recording.must_equal( { 0.0 => [1], 1.0 => [2], 2.0 => [3], 3.0 => [4] } )
270
+ # end
271
+ # end
272
+ # end # TS transition
273
+ # end # transition representation aspects
274
+ # end
275
+ # end
276
+
277
+ # describe "timeless simulation" do
278
+ # before do
279
+ # self.class.class_exec { include YPetri }
280
+ # U = Place m!: 2.5
281
+ # V = Place m!: 2.5
282
+ # Uplus = Transition codomain: :U do 1 end # s transition
283
+ # U2V = Transition s: { U: -1, V: 1 } # S transition
284
+ # set_ssc :Timeless, YPetri::Simulation::DEFAULT_SETTINGS.call
285
+ # new_simulation ssc: :Timeless
286
+ # 5.times do simulation.step! end
287
+ # end
288
+
289
+ # it "should behave" do
290
+ # s = simulation
291
+ # assert ! s.timed?
292
+ # s.core.must_be_kind_of YPetri::Core::Timeless::PseudoEuler
293
+ # ds = s.recording
294
+ # ds.size.must_equal 6
295
+ # ds.events.must_equal [0, 1, 2, 3, 4, 5]
296
+ # ds.interpolate( 1 )
297
+ # .must_equal [2.5, 3.5]
298
+ # ds.interpolate( 2 )
299
+ # .must_equal [2.5, 4.5]
300
+ # -> { ds.interpolate( 1.5 ) }.must_raise TypeError
301
+ # ds.reconstruct( at: 2 )
302
+ # .p_m.must_equal( { U: 2.5, V: 4.5 } )
303
+ # ds.reconstruct( at: 2 ).must_respond_to( :pm )
304
+ # ds.marking.slice( 2..4 ).series
305
+ # .must_equal [[2.5, 2.5, 2.5], [4.5, 5.5, 6.5]]
306
+ # ds.marking.slice( 2..4 )
307
+ # .must_equal( { 2 => [2.5, 4.5],
308
+ # 3 => [2.5, 5.5],
309
+ # 4 => [2.5, 6.5] } )
310
+ # ds.firing.slice( 1..2 ).series
311
+ # .must_equal [[1, 1]]
312
+ # ds.series( firing: [:U2V] )
313
+ # .must_equal [ [ 1, 1, 1, 1, 1, 1 ] ]
314
+ # ds.Delta( [:U], transitions: [:Uplus] ).series
315
+ # .must_equal [ [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] ]
316
+ # tmp = ds.reduce_features( marking: [:U], firing: [:U2V] )
317
+ # tmp.features
318
+ # .must_equal( ds.net.State.Features marking: [:U], firing: [:U2V] )
319
+ # tmp.must_equal( { 0 => [2.5, 1], 1 => [2.5, 1], 2 => [2.5, 1],
320
+ # 3 => [2.5, 1], 4 => [2.5, 1], 5 => [2.5, 1] } )
321
+ # end
322
+ # end
301
323
 
302
324
  describe "timed simulation" do
303
325
  before do
@@ -311,44 +333,49 @@ describe "timed simulation" do
311
333
 
312
334
  it "should behave" do
313
335
  places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
314
- simulation.tap do |s|
315
- s.settings.must_equal( { method: :pseudo_euler, guarded: false,
316
- step: 0.1, sampling: 5, time: 0..60 } )
317
- assert s.recording.to_csv.start_with?( "0.0,0.5,0.5\n" +
318
- "5.0,0.475,0.38916\n" +
319
- "10.0,0.45,0.30289\n" +
320
- "15.0,0.425,0.23574\n" +
321
- "20.0,0.4,0.18348\n" +
322
- "25.0,0.375,0.1428\n" )
323
- assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
324
- s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
325
- 25.0, 30.0, 35.0, 40.0, 45.0,
326
- 50.0, 55.0, 60.0 ]
327
- s.recording.values_at( 5, 10 )
328
- .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
329
- s.recording.slice( 2..12 )
330
- .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
331
- s.recording.net
332
- .must_equal net
333
- s.recording.features
334
- .must_equal net.State.marking( [:A, :B] )
335
- net.State.Features.State
336
- .must_equal net.State
337
- s.recording.State
338
- .must_equal net.State
339
- s.recording.series( marking: [:A] )
340
- .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
341
- 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
342
- s.recording.firing.series
343
- .must_equal []
344
- s.recording.firing
345
- .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
346
- s.recording
347
- .delta( [:A], transitions: [:A_pump], delta_time: 0.1 )
348
- .series
349
- .must_equal [ [ -0.0005 ] * 13 ]
350
- plot_state
351
- sleep 5
352
- end
336
+ s = simulation
337
+ s.settings.must_equal( { method: :pseudo_euler, guarded: false,
338
+ step: 0.1, sampling: 5, time: 0..60 } )
339
+ assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
340
+ "0.0,0.5,0.5\n" +
341
+ "5.0,0.475,0.38916\n" +
342
+ "10.0,0.45,0.30289\n" +
343
+ "15.0,0.425,0.23574\n" +
344
+ "20.0,0.4,0.18348\n" +
345
+ "25.0,0.375,0.1428\n" )
346
+ assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
347
+ s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
348
+ 25.0, 30.0, 35.0, 40.0, 45.0,
349
+ 50.0, 55.0, 60.0 ]
350
+ s.recording.values_at( 5, 10 )
351
+ .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
352
+ s.recording.slice( 2..12 )
353
+ .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
354
+ s.recording.net
355
+ .must_equal net
356
+ s.recording.features
357
+ .must_equal net.State.Features.marking( :A, :B )
358
+ net.State.Features.State
359
+ .must_equal net.State
360
+ s.recording.net.State
361
+ .must_equal net.State
362
+ s.recording.series( marking: [:A] )
363
+ .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
364
+ 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
365
+ s.net.State.Features.firing.map( &:transition ).names
366
+ .must_equal [ :A_pump, :B_decay ]
367
+ s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
368
+ .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
369
+ .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
370
+ s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
371
+ .must_equal [ 0.0005, 0.0025 ]
372
+ s.recording.Firing( [] )
373
+ .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
374
+ s.recording
375
+ .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
376
+ .series
377
+ .must_equal [ [ -0.0005 ] * 13 ]
378
+ plot_state
379
+ sleep 5
353
380
  end
354
381
  end