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,5 +1,5 @@
1
1
  #! /usr/bin/ruby
2
- # -*- coding: utf-8 -*-
2
+ # encoding: utf-8
3
3
 
4
4
  require 'minitest/spec'
5
5
  require 'minitest/autorun'
@@ -7,275 +7,349 @@ require_relative '../lib/y_petri' # tested component itself
7
7
  # require 'y_petri'
8
8
  # require 'sy'
9
9
 
10
- describe ::YPetri::Simulation do
10
+ describe YPetri::Simulation do
11
11
  before do
12
- @ = pç = Class.new( ::YPetri::Place )
13
- @tç = tç = Class.new( ::YPetri::Transition )
14
- @nç = nç = Class.new( ::YPetri::Net )
15
- [ @pç, @tç, @nç ].each { |klass|
16
- klass.namespace!
17
- klass.class_exec {
18
- private
19
- define_method :Place do pç end
20
- define_method :Transition do tç end
21
- define_method :Net do nç end
22
- }
23
- }
24
- @p1 = @pç.new name: "P1", default_marking: 1
25
- @p2 = @pç.new name: "P2", default_marking: 2
26
- @p3 = @pç.new name: "P3", default_marking: 3
27
- @p4 = @pç.new name: "P4", default_marking: 4
28
- @p5 = @pç.new name: "P5", default_marking: 5
29
- @t1 = @tç.new name: "T1",
30
- s: { @p1 => -1, @p2 => -1, @p4 => 1 },
31
- rate: 0.1
32
- @t2 = @tç.new name: "T2",
33
- s: { @p1 => -1, @p3 => 1 },
34
- rate: -> a { a * 0.5 }
35
- @t3 = @tç.new name: "T3",
36
- s: { @p1 => -1, @p2 => -1, @p4 => 1 },
37
- domain: @p3,
38
- rate: -> a { a * 0.5 }
39
- @net = @nç.new << @p1 << @p2 << @p3 << @p4 << @p5
40
- @net.include_transition! @t1
41
- @net.include_transition! @t2
42
- @net << @t3
43
- @s = YPetri::Simulation.new net: @net,
44
- marking_clamps: { @p1 => 2.0, @p5 => 2.0 },
45
- initial_marking: { @p2 => @p2.default_marking,
46
- @p3 => @p3.default_marking,
47
- @p4 => @p4.default_marking }
48
- end
49
-
50
- it "exposes the net" do
51
- @s.net.must_equal @net
52
- @s.net.places.size.must_equal 5
53
- @s.net.transitions.size.must_equal 3
54
- assert @net.include? @t1
55
- assert @s.net.include? @t1
56
- assert @net.include? @t2
57
- assert @s.net.include? @t2
58
- assert @net.include? @t3
59
- assert @s.net.include? @t3
60
- @s.net.transitions.size.must_equal 3
61
- end
62
-
63
- it "exposes Petri net places" do
64
- @s.places.must_equal [ @p1, @p2, @p3, @p4, @p5 ]
65
- @s.pp.must_equal [ :P1, :P2, :P3, :P4, :P5 ]
66
- @s.places( :pp ).must_equal( { @p1 => :P1, @p2 => :P2, @p3 => :P3,
67
- @p4 => :P4, @p5 => :P5 } )
68
- @s.pp( :pp ).must_equal( { P1: :P1, P2: :P2, P3: :P3, P4: :P4, P5: :P5 } )
69
- end
70
-
71
- it "exposes Petri net transitions" do
72
- @s.transitions.must_equal [ @t1, @t2, @t3 ]
73
- @s.tt.must_equal [ :T1, :T2, :T3 ]
74
- @s.transitions( :tt ).must_equal( { @t1 => :T1, @t2 => :T2, @t3 => :T3 } )
75
- @s.tt( :tt ).must_equal( { T1: :T1, T2: :T2, T3: :T3 } )
76
- end
77
-
78
- it "exposes place clamps" do
79
- @s.clamped_places( :place_clamps ).must_equal( { @p1 => 2, @p5 => 2 } )
80
- @s.clamped_pp( :place_clamps ).must_equal( { P1: 2, P5: 2 } )
81
- end
82
-
83
- it "presents free places" do
84
- @s.free_places.must_equal [ @p2, @p3, @p4 ]
85
- @s.free_pp.must_equal [ :P2, :P3, :P4 ]
86
- @s.free_places( :free_pp )
87
- .must_equal( { @p2 => :P2, @p3 => :P3, @p4 => :P4 } )
88
- @s.free_pp( :free_pp )
89
- .must_equal( { P2: :P2, P3: :P3, P4: :P4 } )
90
- end
91
-
92
- it "presents clamped places" do
93
- @s.clamped_places.must_equal [ @p1, @p5 ]
94
- @s.clamped_pp.must_equal [ :P1, :P5 ]
95
- @s.clamped_places( :clamped_pp ).must_equal( { @p1 => :P1, @p5 => :P5 } )
96
- @s.clamped_pp( :clamped_pp ).must_equal( { P1: :P1, P5: :P5 } )
97
- end
98
-
99
- it "exposes initial marking" do
100
- @s.free_places( :im ).must_equal( { @p2 => 2, @p3 => 3, @p4 => 4 } )
101
- @s.free_pp( :im ).must_equal( { P2: 2, P3: 3, P4: 4 } )
102
- @s.im.must_equal [ 2, 3, 4 ]
103
- @s.im_vector.must_equal Matrix[[2], [3], [4]]
104
- @s.im_vector.must_equal @s.iᴍ
105
- end
106
-
107
- it "exposes marking (simulation state)" do
108
- @s.m.must_equal [2, 3, 4] # (we're after reset)
109
- @s.free_places( :m ).must_equal( { @p2 => 2, @p3 => 3, @p4 => 4 } )
110
- @s.free_pp( :m ).must_equal( { P2: 2, P3: 3, P4: 4 } )
111
- @s.ᴍ.must_equal Matrix[[2], [3], [4]]
112
- end
113
-
114
- it "separately exposes marking of clamped places" do
115
- @s.m_clamped.must_equal [ 2, 2 ]
116
- @s.clamped_places( :m_clamped ).must_equal( { @p1 => 2, @p5 => 2 } )
117
- @s.clamped_pp( :m_clamped ).must_equal( { P1: 2, P5: 2 } )
118
- @s.ᴍ_clamped.must_equal Matrix[[2], [2]]
119
- end
120
-
121
- it "exposes marking of all places (with capitalized M)" do
122
- @s.marking.must_equal [ 2, 2, 3, 4, 2 ]
123
- @s.places( :marking )
124
- .must_equal( { @p1 => 2, @p2 => 2, @p3 => 3, @p4 => 4, @p5 => 2 } )
125
- @s.pp( :marking ).must_equal( { P1: 2, P2: 2, P3: 3, P4: 4, P5: 2 } )
126
- @s.marking_vector.must_equal Matrix[[2], [2], [3], [4], [2]]
127
- end
128
-
129
- it "has #S_for / #stoichiometry_matrix_for" do
130
- assert_equal Matrix.empty(3, 0), @s.S_for( [] )
131
- assert_equal Matrix[[-1], [0], [1]], @s.S_for( [@t1] )
132
- x = Matrix[[-1, -1], [0, 0], [1, 1]]
133
- x.must_equal @s.S_for( [@t1, @t3] )
134
- x.must_equal( @s.S_for( [@t1, @t3] ) )
135
- @s.stoichiometry_matrix_for( [] ).must_equal Matrix.empty( 5, 0 )
136
- end
137
-
138
- it "has stoichiometry matrix for 3. tS transitions" do
139
- @s.S_tS.must_equal Matrix.empty( 3, 0 )
140
- end
141
-
142
- it "has stoichiometry matrix for 4. Sr transitions" do
143
- @s.S_TSr.must_equal Matrix.empty( 3, 0 )
144
- end
145
-
146
- it "has stoichiometry matrix for 6. SR transitions" do
147
- @s.S_SR.must_equal Matrix[[-1, 0, -1], [0, 1, 0], [1, 0, 1]]
148
- @s.S.must_equal @s.S_SR
149
- end
150
-
151
- it "presents 1. ts" do
152
- assert_equal [], @s.ts_transitions
153
- assert_equal( {}, @s.ts_transitions( :ts_transitions ) )
154
- assert_equal [], @s.ts_tt
155
- assert_equal( {}, @s.ts_tt( :ts_tt ) )
156
- end
157
-
158
- it "presents 2. tS transitions" do
159
- assert_equal [], @s.tS_transitions
160
- assert_equal( {}, @s.tS_transitions( :tS_transitions ) )
161
- assert_equal [], @s.tS_tt
162
- assert_equal( {}, @s.tS_tt( :tS_tt ) )
163
- end
164
-
165
- it "presents 3. Tsr transitions" do
166
- assert_equal [], @s.Tsr_transitions
167
- assert_equal( {}, @s.Tsr_transitions( :Tsr_transitions ) )
168
- assert_equal [], @s.Tsr_tt
169
- assert_equal( {}, @s.Tsr_tt( :Tsr_tt ) )
170
- end
171
-
172
- it "presents 4. TSr transitions" do
173
- assert_equal [], @s.TSr_transitions
174
- assert_equal( {}, @s.TSr_transitions( :TSr_tt ) )
175
- assert_equal [], @s.TSr_tt
176
- assert_equal( {}, @s.TSr_tt( :TSr_tt ) )
177
- end
178
-
179
- it "presents 5. sR transitions" do
180
- assert_equal [], @s.sR_transitions
181
- assert_equal( {}, @s.sR_transitions( :sR_transitions ) )
182
- assert_equal [], @s.sR_tt
183
- assert_equal( {}, @s.sR_tt( :sR_tt ) )
184
- end
185
-
186
- it "presents SR transitions" do
187
- assert_equal [@t1, @t2, @t3], @s.SR_transitions
188
- assert_equal( { @t1 => :T1, @t2 => :T2, @t3 => :T3 },
189
- @s.SR_transitions( :SR_tt ) )
190
- assert_equal [:T1, :T2, :T3], @s.SR_tt
191
- assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.SR_tt( :SR_tt ) )
192
- end
193
-
194
- it "presents A transitions" do
195
- assert_equal [], @s.A_transitions
196
- assert_equal( {}, @s.A_transitions( :A_tt ) )
197
- assert_equal [], @s.A_tt
198
- assert_equal( {}, @s.A_tt( :A_tt ) )
199
- end
200
-
201
- it "presents S transitions" do
202
- assert_equal [@t1, @t2, @t3], @s.S_transitions
203
- assert_equal [:T1, :T2, :T3], @s.S_tt
204
- assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.S_tt( :S_tt ) )
205
- end
206
-
207
- it "presents s transitions" do
208
- assert_equal [], @s.s_transitions
209
- assert_equal [], @s.s_tt
210
- assert_equal( {}, @s.s_tt( :s_tt ) )
211
- end
212
-
213
- it "presents R transitions" do
214
- assert_equal [@t1, @t2, @t3], @s.R_transitions
215
- assert_equal [:T1, :T2, :T3], @s.R_tt
216
- assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.R_tt( :R_tt ) )
217
- end
218
-
219
- it "presents r transitions" do
220
- assert_equal [], @s.r_transitions
221
- assert_equal [], @s.r_tt
222
- end
223
-
224
- it "1. handles ts transitions" do
225
- @s.Δ_closures_for_tsa.must_equal []
226
- @s.Δ_if_tsa_fire_once.must_equal Matrix.zero( @s.free_pp.size, 1 )
227
- end
228
-
229
- it "2. handles Tsr transitions" do
230
- @s.Δ_closures_for_Tsr.must_equal []
231
- @s.Δ_Tsr( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
232
- end
233
-
234
- it "3. handles tS transitions" do
235
- @s.action_closures_for_tS.must_equal []
236
- @s.action_vector_for_tS.must_equal Matrix.column_vector( [] )
237
- @s.ᴀ_t.must_equal Matrix.column_vector( [] )
238
- @s.Δ_if_tS_fire_once.must_equal Matrix.zero( @s.free_pp.size, 1 )
239
- end
240
-
241
- it "4. handles TSr transitions" do
242
- @s.action_closures_for_TSr.must_equal []
243
- @s.action_closures_for_Tr.must_equal []
244
- @s.action_vector_for_TSr( 1.0 ).must_equal Matrix.column_vector( [] )
245
- @s.action_vector_for_Tr( 1.0 ).must_equal Matrix.column_vector( [] )
246
- @s.Δ_TSr( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
12
+ @w = YPetri::World.new
13
+ end
14
+
15
+ it "should allow for creation of an empty simulation" do
16
+ net = @w.Net.new
17
+ sim = net.simulation
18
+ sim.pp.must_equal []
19
+ sim.pp( *[] ).must_equal []
20
+ sim.tt.must_equal( [] )
21
+ sim.tt( *[] ).must_equal []
22
+ end
23
+
24
+ describe "simulation setup" do
25
+ before do
26
+ @p = @w.Place.new name: :A, default_marking: 1
27
+ @q = @w.Place.new name: :B, default_marking: 2
28
+ @net = @w.Net.of @p, @q
29
+ end
30
+
31
+ it "should allow to set up a simplistic simulation instance" do
32
+ @net.simulation
33
+ @net.simulation marking_clamps: { @q => 42 } # one clamp
34
+ @net.simulation initial_marking: { @p => 42, @q => 43 }
35
+ @net.simulation marking_clamps: { @p => 42 }, initial_marking: { @q => 43 }
36
+ @net.simulation initial_marking: { A: 42 }
37
+ end
38
+
39
+ it "should fail with malformed arguments" do
40
+ -> { @net.simulation use_default_marking: false }.must_raise TypeError
41
+ -> { @net.simulation initial_marking: { Foo: 1 } }.must_raise NameError
42
+ end
43
+
44
+ describe "place representation aspects" do
45
+ before do
46
+ @s = YPetri::Simulation.new( net: @net,
47
+ initial_marking: { A: 42 },
48
+ marking_clamps: { B: 43 } )
49
+ end
50
+
51
+ it "should have elements/access" do
52
+ @s.send( :place, :A )
53
+ .must_be_kind_of YPetri::Simulation::PlaceRepresentation
54
+ @s.send( :place, :B )
55
+ .must_be_kind_of YPetri::Simulation::PlaceRepresentation
56
+ @s.net.places.names.must_equal [:A, :B]
57
+ @s.pn.must_equal [:A, :B]
58
+ @s.send( :places ).free.size.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.new name: "T_ts", codomain: :A, action: -> { 1 }
84
+ @tS = @w.Transition.new name: "T_tS", s: { B: -1, A: 1 }, action: proc { 1 }
85
+ @Ts = @w.Transition.new name: "T_Ts", codomain: :A, rate: -> { 1 }
86
+ @TS = @w.Transition.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.pm.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.pm.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::State::Features::Dataset
231
+ @sim.recording.must_equal @net.State.marking.new_dataset.update( 0.0 => [1, 2] )
232
+ @sim.recording.must_equal( { 0.0 => [1, 2] } )
233
+ @sim.step! 1
234
+ @sim.recording.must_equal( { 0.0 => [1, 2], 1.0 => [2, 1] } )
235
+ end
236
+ end
237
+
238
+ describe "with clamps" do
239
+ before do
240
+ @sim = @net.simulation sampling: 1, marking_clamps: { B: 43 }
241
+ end
242
+
243
+ it "should behave" do
244
+ @sim.recording.must_equal( { 0.0 => [1] } )
245
+ 3.times do @sim.step! end
246
+ @sim.recording.must_equal( { 0.0 => [1], 1.0 => [2], 2.0 => [3], 3.0 => [4] } )
247
+ end
248
+ end
249
+ end # TS transition
250
+ end # transition representation aspects
247
251
  end
252
+ end
248
253
 
249
- it "5. handles sR transitions" do
250
- assert_equal [], @s.rate_closures_for_sR
251
- assert_equal [], @s.rate_closures_for_s
252
- # @s.gradient_for_sR.must_equal Matrix.zero( @s.free_pp.size, 1 )
253
- @s.Δ_sR( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
254
- end
255
254
 
256
- it "6. handles stoichiometric transitions with rate" do
257
- @s.rate_closures_for_SR.size.must_equal 3
258
- @s.rate_closures_for_S.size.must_equal 3
259
- @s.rate_closures.size.must_equal 3
260
- @s.flux_vector_for_SR.must_equal Matrix.column_vector( [ 0.4, 1.0, 1.5 ] )
261
- @s.φ_for_SR.must_equal @s.flux_vector
262
- @s.SR_tt( :φ_for_SR ).must_equal( { T1: 0.4, T2: 1.0, T3: 1.5 } )
263
- @s.first_order_action_vector_for_SR( 1 )
264
- .must_equal Matrix.column_vector [ 0.4, 1.0, 1.5 ]
265
- @s.SR_tt( :first_order_action_for_SR, 1 ).must_equal( T1: 0.4, T2: 1.0, T3: 1.5 )
266
- @s.Δ_SR( 1 ).must_equal Matrix[[-1.9], [1.0], [1.9]]
267
- @s.free_pp( :Δ_SR, 1 ).must_equal( { P2: -1.9, P3: 1.0, P4: 1.9 } )
255
+ describe YPetri::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
+ simulation.tap do |s|
269
+ assert ! s.timed?
270
+ s.core.must_be_kind_of YPetri::Core::Timeless::PseudoEuler
271
+ s.recording.size.must_equal 6
272
+ s.recording.events.must_equal [0, 1, 2, 3, 4, 5]
273
+ s.recording.reconstruct( event: 2 ).pm.must_equal( { U: 2.5, V: 4.5 } )
274
+ s.recording.marking.slice( 2..4 ).series
275
+ .must_equal [[2.5, 2.5, 2.5], [4.5, 5.5, 6.5]]
276
+ s.recording.marking( slice: 2..4 )
277
+ .must_equal( { 2 => [2.5, 4.5],
278
+ 3 => [2.5, 5.5],
279
+ 4 => [2.5, 6.5] } )
280
+ s.recording.firing_series( slice: 1..2 )
281
+ .must_equal [[1, 1]]
282
+ s.recording.firing_series( transitions: [:U2V] )
283
+ .must_equal [[1, 1, 1, 1, 1, 1]]
284
+ s.recording.delta_series( places: [:U], transitions: [:Uplus] )
285
+ .must_equal [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0]]
286
+ tmp = s.recording.features( marking: [:U], firing: [:U2V] )
287
+ tmp.delete( :features )
288
+ .must_equal( { marking: [:U], firing: [:U2V],
289
+ delta: { places: [], transitions: [] } } )
290
+ tmp.must_equal( { 0 => [2.5, 1], 1 => [2.5, 1], 2 => [2.5, 1],
291
+ 3 => [2.5, 1], 4 => [2.5, 1], 5 => [2.5, 1] } )
292
+ end
268
293
  end
294
+ end
269
295
 
270
- it "presents sparse stoichiometry vectors for its transitions" do
271
- @s.sparse_σ( @t1 ).must_equal Matrix.cv( [-1, 0, 1] )
272
- @s.sparse_stoichiometry_vector( @t1 )
273
- .must_equal Matrix.cv( [-1, -1, 0, 1, 0] )
274
- end
275
296
 
276
- it "presents correspondence matrices free, clamped => all places" do
277
- @s.F2A.must_equal Matrix[[0, 0, 0], [1, 0, 0], [0, 1, 0],
278
- [0, 0, 1], [0, 0, 0]]
279
- @s.C2A.must_equal Matrix[[1, 0], [0, 0], [0, 0], [0, 0], [0, 1]]
297
+ describe YPetri::Simulation::Timed do
298
+ before do
299
+ skip
300
+ self.class.class_exec { include YPetri }
301
+ A = Place m!: 0.5
302
+ B = Place m!: 0.5
303
+ A_pump = T s: { A: -1 } do 0.005 end
304
+ B_decay = Transition s: { B: -1 }, rate: 0.05
305
+ run!
306
+ end
307
+
308
+ it "should behave" do
309
+ places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
310
+ simulation.tap do |s|
311
+ s.settings.must_equal( { method: :pseudo_euler, guarded: false,
312
+ step: 0.1, sampling: 5, time: 0..60 } )
313
+ assert s.recording.to_csv.start_with?( "0.0,0.5,0.5\n" +
314
+ "5.0,0.475,0.38916\n" +
315
+ "10.0,0.45,0.30289\n" +
316
+ "15.0,0.425,0.23574\n" +
317
+ "20.0,0.4,0.18348\n" +
318
+ "25.0,0.375,0.1428\n" )
319
+ assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
320
+ s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
321
+ 25.0, 30.0, 35.0, 40.0, 45.0,
322
+ 50.0, 55.0, 60.0 ]
323
+ s.recording.values_at( 5, 10 )
324
+ .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
325
+ s.recording.slice( 2..12 )
326
+ .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
327
+ s.recording.net
328
+ .must_equal net
329
+ s.recording.features
330
+ .must_equal net.State.marking( [:A, :B] )
331
+ net.State.Features.State
332
+ .must_equal net.State
333
+ s.recording.State
334
+ .must_equal net.State
335
+ s.recording.series( marking: [:A] )
336
+ .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
337
+ 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
338
+ s.recording.firing.series
339
+ .must_equal []
340
+ s.recording.firing
341
+ .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
342
+ # It is obvious why this fails: Given delta feature is not in the
343
+ # recording. It has to be generated, and since the net is timed,
344
+ # it also requires Δt to be generated.
345
+
346
+ # I'll comment it out for a while to see what the plot is doing.
347
+ =begin
348
+ s.recording.delta( [:A], transitions: [:A_pump] )
349
+ .must_equal [ [ -0.0005 ] * 13 ]
350
+ =end
351
+ plot_state
352
+ sleep 5
353
+ end
280
354
  end
281
355
  end