y_petri 2.0.7 → 2.0.14.p1
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/net/selections.rb +209 -0
- data/lib/y_petri/net/visualization.rb +67 -0
- data/lib/y_petri/net.rb +33 -311
- data/lib/y_petri/place/guard.rb +20 -13
- data/lib/y_petri/place.rb +12 -7
- data/lib/y_petri/simulation.rb +8 -9
- data/lib/y_petri/transition/assignment.rb +37 -0
- data/lib/y_petri/transition/{constructor_syntax.rb → construction.rb} +1 -0
- data/lib/y_petri/transition/ordinary_timeless.rb +46 -0
- data/lib/y_petri/transition/timed.rb +57 -0
- data/lib/y_petri/transition.rb +103 -220
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri.rb +1 -1
- data/test/acceptance/basic_usage_test.rb +30 -0
- data/test/acceptance/simulation_test.rb +132 -0
- data/test/acceptance/simulation_with_physical_units_test.rb +153 -0
- data/test/acceptance/token_game_test.rb +36 -0
- data/test/acceptance/visualization_test.rb +25 -0
- data/test/acceptance_tests.rb +14 -0
- data/test/manipulator_test.rb +100 -0
- data/test/{simple_manual_examples.rb → manual_examples.rb} +0 -0
- data/test/net_test.rb +171 -0
- data/test/place_test.rb +7 -6
- data/test/simulation_test.rb +280 -0
- data/test/timed_simulation_test.rb +149 -0
- data/test/transition_test.rb +2 -4
- data/test/workspace_test.rb +72 -0
- data/test/y_petri_test.rb +16 -1107
- metadata +34 -7
data/test/y_petri_test.rb
CHANGED
@@ -7,1114 +7,23 @@ require_relative '../lib/y_petri' # tested component itself
|
|
7
7
|
# require 'y_petri'
|
8
8
|
# require 'sy'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# Test of Net class.
|
14
|
-
# **************************************************************************
|
15
|
-
#
|
16
|
-
describe ::YPetri::Net do
|
17
|
-
before do
|
18
|
-
# skip "to speed up testing"
|
19
|
-
@tç = tç = Class.new ::YPetri::Transition
|
20
|
-
@pç = pç = Class.new ::YPetri::Place
|
21
|
-
@nç = nç = Class.new ::YPetri::Net
|
22
|
-
[ tç, pç, nç ].each { |ç|
|
23
|
-
ç.namespace!.class_exec {
|
24
|
-
define_method :Place do pç end
|
25
|
-
define_method :Transition do tç end
|
26
|
-
define_method :Net do nç end
|
27
|
-
private :Place, :Transition, :Net
|
28
|
-
}
|
29
|
-
}
|
30
|
-
@p1 = pç.new ɴ: "A", quantum: 0.1, marking: 1.1
|
31
|
-
@p2 = pç.new ɴ: "B", quantum: 0.1, marking: 2.2
|
32
|
-
@p3 = pç.new ɴ: "C", quantum: 0.1, marking: 3.3
|
33
|
-
@net = nç.new
|
34
|
-
[@p1, @p2, @p3].each { |p| @net.include_place! p }
|
35
|
-
@p_not_included = pç.new ɴ: "X", marking: 0
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "net of 3 places and no transitions" do
|
39
|
-
before do
|
40
|
-
@p1.m = 1.1
|
41
|
-
@p2.m = 2.2
|
42
|
-
@p3.m = 3.3
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should expose its elements" do
|
46
|
-
assert_equal [@p1, @p2, @p3], @net.places
|
47
|
-
assert_equal [:A, :B, :C], @net.pp
|
48
|
-
assert_equal [], @net.transitions
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should expose transition groups" do
|
52
|
-
assert_equal [], @net.transitions_with_rate
|
53
|
-
assert_equal [], @net.rateless_transitions
|
54
|
-
assert_equal [], @net.transitions_without_rate
|
55
|
-
assert_equal [], @net.stoichiometric_transitions
|
56
|
-
assert_equal [], @net.nonstoichiometric_transitions
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should tell its qualities" do
|
60
|
-
assert_equal true, @net.functional?
|
61
|
-
assert_equal true, @net.timed?
|
62
|
-
assert @net.include?( @p1 ) && !@net.include?( YPetri::Place.new )
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should have 'standard equipment' methods" do
|
66
|
-
assert @net == @net.dup
|
67
|
-
assert @net.inspect.start_with? "#<Net:"
|
68
|
-
assert @net.include?( @p1 )
|
69
|
-
assert ! @net.include?( @p_not_included )
|
70
|
-
begin
|
71
|
-
@net.exclude_place! @p_not_included
|
72
|
-
@net.include_transition! YPetri::Transition.new( s: { @p_not_included => -1 } )
|
73
|
-
flunk "Attempt to include illegal transition fails to raise"
|
74
|
-
rescue; end
|
75
|
-
end
|
76
|
-
|
77
|
-
describe "plus 1 stoichio. transition with rate" do
|
78
|
-
before do
|
79
|
-
@t1 = @tç.new!( ɴ: "T1",
|
80
|
-
s: { @p1 => 1, @p2 => -1, @p3 => -1 },
|
81
|
-
rate: 0.01 )
|
82
|
-
@net.include_transition! @t1
|
83
|
-
end
|
84
|
-
|
85
|
-
it "should expose its elements" do
|
86
|
-
assert_equal [@t1], @net.transitions
|
87
|
-
assert_equal [:T1], @net.tt
|
88
|
-
end
|
89
|
-
|
90
|
-
it "should expose transition groups" do
|
91
|
-
assert_equal true, @t1.has_rate?
|
92
|
-
assert_equal [@t1], @net.transitions_with_rate
|
93
|
-
assert_equal [], @net.rateless_transitions
|
94
|
-
assert_equal [@t1], @net.stoichiometric_transitions
|
95
|
-
assert_equal [], @net.nonstoichiometric_transitions
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should tell its qualities" do
|
99
|
-
assert_equal true, @net.functional?
|
100
|
-
assert_equal true, @net.timed?
|
101
|
-
assert @net.include?( @t1 )
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should have #place & #transition for safe access to the said elements" do
|
105
|
-
@net.send( :place, @p1 ).must_equal @p1
|
106
|
-
@net.send( :transition, @t1 ).must_equal @t1
|
107
|
-
end
|
108
|
-
|
109
|
-
it "has #new_simulation & #new_timed_simulation constructors" do
|
110
|
-
@net.must_respond_to :new_simulation
|
111
|
-
@net.must_respond_to :new_timed_simulation
|
112
|
-
end
|
113
|
-
|
114
|
-
it "should have other methods" do
|
115
|
-
assert_equal [1.1, 2.2, 3.3], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
|
116
|
-
assert_equal 2.2 * 3.3 * 0.01, @t1.rate_closure.call( @p2.marking, @p3.marking )
|
117
|
-
assert_equal [ @p2, @p3 ], @t1.domain
|
118
|
-
@t1.fire! 1
|
119
|
-
assert_equal [1.1726, 2.1274, 3.2274], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
|
120
|
-
end
|
121
|
-
|
122
|
-
describe "plus 1 more nameless timeless functionless transition" do
|
123
|
-
before do
|
124
|
-
@t2 = @tç.new s: { @p2 => -1, @p3 => 1 }
|
125
|
-
@net.include_transition! @t2
|
126
|
-
end
|
127
|
-
|
128
|
-
it "should expose its elements" do
|
129
|
-
assert_equal [@t1, @t2], @net.transitions
|
130
|
-
assert_equal [:T1, nil], @net.tt
|
131
|
-
@net.tap{ |n| n.exclude_transition! @t1 }.exclude_transition! @t2
|
132
|
-
@net.tap{ |n| n.exclude_place! @p3 }.pp.must_equal [:A, :B]
|
133
|
-
end
|
134
|
-
|
135
|
-
it "should expose transition groups" do
|
136
|
-
assert_equal [], @net.timeless_nonstoichiometric_transitions
|
137
|
-
assert_equal [], @net.timeless_nonstoichiometric_tt
|
138
|
-
assert_equal [@t2], @net.timeless_stoichiometric_transitions
|
139
|
-
assert_equal [nil], @net.timeless_stoichiometric_tt
|
140
|
-
assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
|
141
|
-
assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
|
142
|
-
assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
|
143
|
-
assert_equal [], @net.timed_rateless_nonstoichiometric_tt
|
144
|
-
assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
|
145
|
-
assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
|
146
|
-
assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
|
147
|
-
assert_equal [], @net.timed_rateless_nonstoichiometric_tt
|
148
|
-
assert_equal [], @net.nonstoichiometric_transitions_with_rate
|
149
|
-
assert_equal [], @net.nonstoichiometric_tt_with_rate
|
150
|
-
assert_equal [@t1], @net.stoichiometric_transitions_with_rate
|
151
|
-
assert_equal [:T1], @net.stoichiometric_tt_with_rate
|
152
|
-
assert_equal [], @net.assignment_transitions
|
153
|
-
assert_equal [], @net.assignment_tt
|
154
|
-
assert_equal [@t1, @t2], @net.stoichiometric_transitions
|
155
|
-
assert_equal [:T1, nil], @net.stoichiometric_tt
|
156
|
-
assert_equal [], @net.nonstoichiometric_transitions
|
157
|
-
assert_equal [], @net.nonstoichiometric_tt
|
158
|
-
assert_equal [@t1], @net.timed_transitions
|
159
|
-
assert_equal [:T1], @net.timed_tt
|
160
|
-
assert_equal [@t2], @net.timeless_transitions
|
161
|
-
assert_equal [nil], @net.timeless_tt
|
162
|
-
assert_equal [@t1], @net.transitions_with_rate
|
163
|
-
assert_equal [:T1], @net.tt_with_rate
|
164
|
-
assert_equal [@t2], @net.rateless_transitions
|
165
|
-
assert_equal [nil], @net.rateless_tt
|
166
|
-
end
|
167
|
-
|
168
|
-
it "should tell its qualities" do
|
169
|
-
assert_equal false, @net.functional?
|
170
|
-
assert_equal false, @net.timed?
|
171
|
-
@net.exclude_transition! @t2
|
172
|
-
assert_equal true, @net.functional?
|
173
|
-
assert_equal true, @net.timed?
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
|
181
|
-
# **************************************************************************
|
182
|
-
# Test of Simulation class.
|
183
|
-
# **************************************************************************
|
184
|
-
#
|
185
|
-
describe ::YPetri::Simulation do
|
186
|
-
before do
|
187
|
-
# skip "to make the testing faster"
|
188
|
-
@pç = pç = Class.new( ::YPetri::Place )
|
189
|
-
@tç = tç = Class.new( ::YPetri::Transition )
|
190
|
-
@nç = nç = Class.new( ::YPetri::Net )
|
191
|
-
[ @pç, @tç, @nç ].each { |klass|
|
192
|
-
klass.namespace!.class_exec {
|
193
|
-
private
|
194
|
-
define_method :Place do pç end
|
195
|
-
define_method :Transition do tç end
|
196
|
-
define_method :Net do nç end
|
197
|
-
}
|
198
|
-
}
|
199
|
-
@p1 = @pç.new name: "P1", default_marking: 1
|
200
|
-
@p2 = @pç.new name: "P2", default_marking: 2
|
201
|
-
@p3 = @pç.new name: "P3", default_marking: 3
|
202
|
-
@p4 = @pç.new name: "P4", default_marking: 4
|
203
|
-
@p5 = @pç.new name: "P5", default_marking: 5
|
204
|
-
@t1 = @tç.new name: "T1",
|
205
|
-
s: { @p1 => -1, @p2 => -1, @p4 => 1 },
|
206
|
-
rate: 0.1
|
207
|
-
@t2 = @tç.new name: "T2",
|
208
|
-
s: { @p1 => -1, @p3 => 1 },
|
209
|
-
rate: -> a { a * 0.5 }
|
210
|
-
@t3 = @tç.new name: "T3",
|
211
|
-
s: { @p1 => -1, @p2 => -1, @p4 => 1 },
|
212
|
-
domain: @p3,
|
213
|
-
rate: -> a { a * 0.5 }
|
214
|
-
@net = @nç.new << @p1 << @p2 << @p3 << @p4 << @p5
|
215
|
-
@net.include_transition! @t1
|
216
|
-
@net.include_transition! @t2
|
217
|
-
@net << @t3
|
218
|
-
@s = YPetri::Simulation.new net: @net,
|
219
|
-
marking_clamps: { @p1 => 2.0, @p5 => 2.0 },
|
220
|
-
initial_marking: { @p2 => @p2.default_marking,
|
221
|
-
@p3 => @p3.default_marking,
|
222
|
-
@p4 => @p4.default_marking }
|
223
|
-
end
|
224
|
-
|
225
|
-
it "exposes the net" do
|
226
|
-
@s.net.must_equal @net
|
227
|
-
@s.net.places.size.must_equal 5
|
228
|
-
@s.net.transitions.size.must_equal 3
|
229
|
-
assert @net.include? @t1
|
230
|
-
assert @s.net.include? @t1
|
231
|
-
assert @net.include? @t2
|
232
|
-
assert @s.net.include? @t2
|
233
|
-
assert @net.include? @t3
|
234
|
-
assert @s.net.include? @t3
|
235
|
-
@s.net.transitions.size.must_equal 3
|
236
|
-
end
|
237
|
-
|
238
|
-
it "exposes Petri net places" do
|
239
|
-
@s.places.must_equal [ @p1, @p2, @p3, @p4, @p5 ]
|
240
|
-
@s.pp.must_equal [ :P1, :P2, :P3, :P4, :P5 ]
|
241
|
-
@s.places( :pp ).must_equal( { @p1 => :P1, @p2 => :P2, @p3 => :P3,
|
242
|
-
@p4 => :P4, @p5 => :P5 } )
|
243
|
-
@s.pp( :pp ).must_equal( { P1: :P1, P2: :P2, P3: :P3, P4: :P4, P5: :P5 } )
|
244
|
-
end
|
245
|
-
|
246
|
-
it "exposes Petri net transitions" do
|
247
|
-
@s.transitions.must_equal [ @t1, @t2, @t3 ]
|
248
|
-
@s.tt.must_equal [ :T1, :T2, :T3 ]
|
249
|
-
@s.transitions( :tt ).must_equal( { @t1 => :T1, @t2 => :T2, @t3 => :T3 } )
|
250
|
-
@s.tt( :tt ).must_equal( { T1: :T1, T2: :T2, T3: :T3 } )
|
251
|
-
end
|
252
|
-
|
253
|
-
it "exposes place clamps" do
|
254
|
-
@s.clamped_places( :place_clamps ).must_equal( { @p1 => 2, @p5 => 2 } )
|
255
|
-
@s.clamped_pp( :place_clamps ).must_equal( { P1: 2, P5: 2 } )
|
256
|
-
end
|
257
|
-
|
258
|
-
it "presents free places" do
|
259
|
-
@s.free_places.must_equal [ @p2, @p3, @p4 ]
|
260
|
-
@s.free_pp.must_equal [ :P2, :P3, :P4 ]
|
261
|
-
@s.free_places( :free_pp )
|
262
|
-
.must_equal( { @p2 => :P2, @p3 => :P3, @p4 => :P4 } )
|
263
|
-
@s.free_pp( :free_pp )
|
264
|
-
.must_equal( { P2: :P2, P3: :P3, P4: :P4 } )
|
265
|
-
end
|
266
|
-
|
267
|
-
it "presents clamped places" do
|
268
|
-
@s.clamped_places.must_equal [ @p1, @p5 ]
|
269
|
-
@s.clamped_pp.must_equal [ :P1, :P5 ]
|
270
|
-
@s.clamped_places( :clamped_pp ).must_equal( { @p1 => :P1, @p5 => :P5 } )
|
271
|
-
@s.clamped_pp( :clamped_pp ).must_equal( { P1: :P1, P5: :P5 } )
|
272
|
-
end
|
273
|
-
|
274
|
-
it "exposes initial marking" do
|
275
|
-
@s.free_places( :im ).must_equal( { @p2 => 2, @p3 => 3, @p4 => 4 } )
|
276
|
-
@s.free_pp( :im ).must_equal( { P2: 2, P3: 3, P4: 4 } )
|
277
|
-
@s.im.must_equal [ 2, 3, 4 ]
|
278
|
-
@s.im_vector.must_equal Matrix[[2], [3], [4]]
|
279
|
-
@s.im_vector.must_equal @s.iᴍ
|
280
|
-
end
|
281
|
-
|
282
|
-
it "exposes marking (simulation state)" do
|
283
|
-
@s.m.must_equal [2, 3, 4] # (we're after reset)
|
284
|
-
@s.free_places( :m ).must_equal( { @p2 => 2, @p3 => 3, @p4 => 4 } )
|
285
|
-
@s.free_pp( :m ).must_equal( { P2: 2, P3: 3, P4: 4 } )
|
286
|
-
@s.ᴍ.must_equal Matrix[[2], [3], [4]]
|
287
|
-
end
|
288
|
-
|
289
|
-
it "separately exposes marking of clamped places" do
|
290
|
-
@s.m_clamped.must_equal [ 2, 2 ]
|
291
|
-
@s.clamped_places( :m_clamped ).must_equal( { @p1 => 2, @p5 => 2 } )
|
292
|
-
@s.clamped_pp( :m_clamped ).must_equal( { P1: 2, P5: 2 } )
|
293
|
-
@s.ᴍ_clamped.must_equal Matrix[[2], [2]]
|
294
|
-
end
|
295
|
-
|
296
|
-
it "exposes marking of all places (with capitalized M)" do
|
297
|
-
@s.marking.must_equal [ 2, 2, 3, 4, 2 ]
|
298
|
-
@s.places( :marking )
|
299
|
-
.must_equal( { @p1 => 2, @p2 => 2, @p3 => 3, @p4 => 4, @p5 => 2 } )
|
300
|
-
@s.pp( :marking ).must_equal( { P1: 2, P2: 2, P3: 3, P4: 4, P5: 2 } )
|
301
|
-
@s.marking_vector.must_equal Matrix[[2], [2], [3], [4], [2]]
|
302
|
-
end
|
303
|
-
|
304
|
-
it "has #S_for / #stoichiometry_matrix_for" do
|
305
|
-
assert_equal Matrix.empty(3, 0), @s.S_for( [] )
|
306
|
-
assert_equal Matrix[[-1], [0], [1]], @s.S_for( [@t1] )
|
307
|
-
x = Matrix[[-1, -1], [0, 0], [1, 1]]
|
308
|
-
x.must_equal @s.S_for( [@t1, @t3] )
|
309
|
-
x.must_equal( @s.S_for( [@t1, @t3] ) )
|
310
|
-
@s.stoichiometry_matrix_for( [] ).must_equal Matrix.empty( 5, 0 )
|
311
|
-
end
|
312
|
-
|
313
|
-
it "has stoichiometry matrix for 3. tS transitions" do
|
314
|
-
@s.S_for_tS.must_equal Matrix.empty( 3, 0 )
|
315
|
-
end
|
316
|
-
|
317
|
-
it "has stoichiometry matrix for 4. Sr transitions" do
|
318
|
-
@s.S_for_TSr.must_equal Matrix.empty( 3, 0 )
|
319
|
-
end
|
320
|
-
|
321
|
-
it "has stoichiometry matrix for 6. SR transitions" do
|
322
|
-
@s.S_for_SR.must_equal Matrix[[-1, 0, -1], [0, 1, 0], [1, 0, 1]]
|
323
|
-
@s.S.must_equal @s.S_for_SR
|
324
|
-
end
|
325
|
-
|
326
|
-
it "presents 1. ts" do
|
327
|
-
assert_equal [], @s.ts_transitions
|
328
|
-
assert_equal( {}, @s.ts_transitions( :ts_transitions ) )
|
329
|
-
assert_equal [], @s.ts_tt
|
330
|
-
assert_equal( {}, @s.ts_tt( :ts_tt ) )
|
331
|
-
end
|
332
|
-
|
333
|
-
it "presents 2. tS transitions" do
|
334
|
-
assert_equal [], @s.tS_transitions
|
335
|
-
assert_equal( {}, @s.tS_transitions( :tS_transitions ) )
|
336
|
-
assert_equal [], @s.tS_tt
|
337
|
-
assert_equal( {}, @s.tS_tt( :tS_tt ) )
|
338
|
-
end
|
339
|
-
|
340
|
-
it "presents 3. Tsr transitions" do
|
341
|
-
assert_equal [], @s.Tsr_transitions
|
342
|
-
assert_equal( {}, @s.Tsr_transitions( :Tsr_transitions ) )
|
343
|
-
assert_equal [], @s.Tsr_tt
|
344
|
-
assert_equal( {}, @s.Tsr_tt( :Tsr_tt ) )
|
345
|
-
end
|
346
|
-
|
347
|
-
it "presents 4. TSr transitions" do
|
348
|
-
assert_equal [], @s.TSr_transitions
|
349
|
-
assert_equal( {}, @s.TSr_transitions( :TSr_tt ) )
|
350
|
-
assert_equal [], @s.TSr_tt
|
351
|
-
assert_equal( {}, @s.TSr_tt( :TSr_tt ) )
|
352
|
-
end
|
353
|
-
|
354
|
-
it "presents 5. sR transitions" do
|
355
|
-
assert_equal [], @s.sR_transitions
|
356
|
-
assert_equal( {}, @s.sR_transitions( :sR_transitions ) )
|
357
|
-
assert_equal [], @s.sR_tt
|
358
|
-
assert_equal( {}, @s.sR_tt( :sR_tt ) )
|
359
|
-
end
|
360
|
-
|
361
|
-
it "presents SR transitions" do
|
362
|
-
assert_equal [@t1, @t2, @t3], @s.SR_transitions
|
363
|
-
assert_equal( { @t1 => :T1, @t2 => :T2, @t3 => :T3 },
|
364
|
-
@s.SR_transitions( :SR_tt ) )
|
365
|
-
assert_equal [:T1, :T2, :T3], @s.SR_tt
|
366
|
-
assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.SR_tt( :SR_tt ) )
|
367
|
-
end
|
368
|
-
|
369
|
-
it "presents A transitions" do
|
370
|
-
assert_equal [], @s.A_transitions
|
371
|
-
assert_equal( {}, @s.A_transitions( :A_tt ) )
|
372
|
-
assert_equal [], @s.A_tt
|
373
|
-
assert_equal( {}, @s.A_tt( :A_tt ) )
|
374
|
-
end
|
375
|
-
|
376
|
-
it "presents S transitions" do
|
377
|
-
assert_equal [@t1, @t2, @t3], @s.S_transitions
|
378
|
-
assert_equal [:T1, :T2, :T3], @s.S_tt
|
379
|
-
assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.S_tt( :S_tt ) )
|
380
|
-
end
|
381
|
-
|
382
|
-
it "presents s transitions" do
|
383
|
-
assert_equal [], @s.s_transitions
|
384
|
-
assert_equal [], @s.s_tt
|
385
|
-
assert_equal( {}, @s.s_tt( :s_tt ) )
|
386
|
-
end
|
387
|
-
|
388
|
-
it "presents R transitions" do
|
389
|
-
assert_equal [@t1, @t2, @t3], @s.R_transitions
|
390
|
-
assert_equal [:T1, :T2, :T3], @s.R_tt
|
391
|
-
assert_equal( { T1: :T1, T2: :T2, T3: :T3 }, @s.R_tt( :R_tt ) )
|
392
|
-
end
|
393
|
-
|
394
|
-
it "presents r transitions" do
|
395
|
-
assert_equal [], @s.r_transitions
|
396
|
-
assert_equal [], @s.r_tt
|
397
|
-
end
|
398
|
-
|
399
|
-
it "1. handles ts transitions" do
|
400
|
-
@s.Δ_closures_for_tsa.must_equal []
|
401
|
-
@s.Δ_if_tsa_fire_once.must_equal Matrix.zero( @s.free_pp.size, 1 )
|
402
|
-
end
|
403
|
-
|
404
|
-
it "2. handles Tsr transitions" do
|
405
|
-
@s.Δ_closures_for_Tsr.must_equal []
|
406
|
-
@s.Δ_for_Tsr( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
|
407
|
-
end
|
408
|
-
|
409
|
-
it "3. handles tS transitions" do
|
410
|
-
@s.action_closures_for_tS.must_equal []
|
411
|
-
@s.action_vector_for_tS.must_equal Matrix.column_vector( [] )
|
412
|
-
@s.α_for_t.must_equal Matrix.column_vector( [] )
|
413
|
-
@s.Δ_if_tS_fire_once.must_equal Matrix.zero( @s.free_pp.size, 1 )
|
414
|
-
end
|
415
|
-
|
416
|
-
it "4. handles TSr transitions" do
|
417
|
-
@s.action_closures_for_TSr.must_equal []
|
418
|
-
@s.action_closures_for_Tr.must_equal []
|
419
|
-
@s.action_vector_for_TSr( 1.0 ).must_equal Matrix.column_vector( [] )
|
420
|
-
@s.action_vector_for_Tr( 1.0 ).must_equal Matrix.column_vector( [] )
|
421
|
-
@s.Δ_for_TSr( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
|
422
|
-
end
|
423
|
-
|
424
|
-
it "5. handles sR transitions" do
|
425
|
-
assert_equal [], @s.rate_closures_for_sR
|
426
|
-
assert_equal [], @s.rate_closures_for_s
|
427
|
-
# @s.gradient_for_sR.must_equal Matrix.zero( @s.free_pp.size, 1 )
|
428
|
-
@s.Δ_Euler_for_sR( 1.0 ).must_equal Matrix.zero( @s.free_pp.size, 1 )
|
429
|
-
end
|
430
|
-
|
431
|
-
it "6. handles stoichiometric transitions with rate" do
|
432
|
-
@s.rate_closures_for_SR.size.must_equal 3
|
433
|
-
@s.rate_closures_for_S.size.must_equal 3
|
434
|
-
@s.rate_closures.size.must_equal 3
|
435
|
-
@s.flux_vector_for_SR.must_equal Matrix.column_vector( [ 0.4, 1.0, 1.5 ] )
|
436
|
-
@s.φ_for_SR.must_equal @s.flux_vector
|
437
|
-
@s.SR_tt( :φ_for_SR ).must_equal( { T1: 0.4, T2: 1.0, T3: 1.5 } )
|
438
|
-
@s.Euler_action_vector_for_SR( 1 )
|
439
|
-
.must_equal Matrix.column_vector [ 0.4, 1.0, 1.5 ]
|
440
|
-
@s.SR_tt( :Euler_action_for_SR, 1 ).must_equal( T1: 0.4, T2: 1.0, T3: 1.5 )
|
441
|
-
@s.Δ_Euler_for_SR( 1 ).must_equal Matrix[[-1.9], [1.0], [1.9]]
|
442
|
-
@s.free_pp( :Δ_Euler_for_SR, 1 ).must_equal( { P2: -1.9, P3: 1.0, P4: 1.9 } )
|
443
|
-
end
|
444
|
-
|
445
|
-
it "presents sparse stoichiometry vectors for its transitions" do
|
446
|
-
@s.sparse_σ( @t1 ).must_equal Matrix.cv( [-1, 0, 1] )
|
447
|
-
@s.sparse_stoichiometry_vector( @t1 )
|
448
|
-
.must_equal Matrix.cv( [-1, -1, 0, 1, 0] )
|
449
|
-
end
|
450
|
-
|
451
|
-
it "presents correspondence matrices free, clamped => all places" do
|
452
|
-
@s.F2A.must_equal Matrix[[0, 0, 0], [1, 0, 0], [0, 1, 0],
|
453
|
-
[0, 0, 1], [0, 0, 0]]
|
454
|
-
@s.C2A.must_equal Matrix[[1, 0], [0, 0], [0, 0], [0, 0], [0, 1]]
|
455
|
-
end
|
456
|
-
end
|
457
|
-
|
458
|
-
|
459
|
-
# **************************************************************************
|
460
|
-
# Test of TimedSimulation class.
|
461
|
-
# **************************************************************************
|
462
|
-
#
|
463
|
-
describe ::YPetri::TimedSimulation do
|
464
|
-
before do
|
465
|
-
# skip "to speed up testing"
|
466
|
-
@a = ::YPetri::Place.new default_marking: 1.0
|
467
|
-
@b = ::YPetri::Place.new default_marking: 2.0
|
468
|
-
@c = ::YPetri::Place.new default_marking: 3.0
|
469
|
-
end
|
470
|
-
|
471
|
-
describe "timed assembly a + b >> c" do
|
472
|
-
before do
|
473
|
-
@t1 = ::YPetri::Transition.new s: { @a => -1, @b => -1, @c => 1 }, rate: 0.1
|
474
|
-
@net = ::YPetri::Net.new << @a << @b << @c << @t1
|
475
|
-
@im_collection = [@a, @b, @c].τBmχHτ &:default_marking
|
476
|
-
end
|
477
|
-
|
478
|
-
describe "simulation with step size 1" do
|
479
|
-
before do
|
480
|
-
@sim = ::YPetri::TimedSimulation.new net: @net,
|
481
|
-
initial_marking: @im_collection,
|
482
|
-
step: 1,
|
483
|
-
sampling: 10,
|
484
|
-
target_time: 100
|
485
|
-
end
|
486
|
-
|
487
|
-
it "should #step! with expected results" do
|
488
|
-
m = @sim.step!.marking
|
489
|
-
assert_in_delta 0.8, m[ 0 ], 1e-9
|
490
|
-
assert_in_delta 1.8, m[ 1 ], 1e-9
|
491
|
-
assert_in_delta 3.2, m[ 2 ], 1e-9
|
492
|
-
end
|
493
|
-
|
494
|
-
it "should behave" do
|
495
|
-
assert_in_delta 0, ( Matrix.column_vector( [-0.02, -0.02, 0.02] ) -
|
496
|
-
@sim.ΔE( 0.1 ) ).column( 0 ).norm, 1e-9
|
497
|
-
@sim.step! 0.1
|
498
|
-
assert_in_delta 0, ( Matrix.column_vector( [0.98, 1.98, 3.02] ) -
|
499
|
-
@sim.marking_vector ).column( 0 ).norm, 1e-9
|
500
|
-
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
describe "simulation with step size 0.1" do
|
505
|
-
before do
|
506
|
-
@sim = ::YPetri::TimedSimulation.new net: @net,
|
507
|
-
initial_marking: @im_collection,
|
508
|
-
step: 0.1,
|
509
|
-
sampling: 10,
|
510
|
-
target_time: 100
|
511
|
-
end
|
512
|
-
|
513
|
-
it "should behave" do
|
514
|
-
m = @sim.step!.marking
|
515
|
-
assert_equal 10, @sim.sampling_period
|
516
|
-
assert_in_delta 0.98, m[ 0 ], 1e-9
|
517
|
-
assert_in_delta 1.98, m[ 1 ], 1e-9
|
518
|
-
assert_in_delta 3.02, m[ 2 ], 1e-9
|
519
|
-
end
|
520
|
-
|
521
|
-
it "should behave" do
|
522
|
-
@sim.run_until_target_time! 31
|
523
|
-
expected_recording = {
|
524
|
-
0 => [ 1, 2, 3 ],
|
525
|
-
10 => [ 0.22265, 1.22265, 3.77735 ],
|
526
|
-
20 => [ 0.07131, 1.07131, 3.92869 ],
|
527
|
-
30 => [ 0.02496, 1.02496, 3.97503 ]
|
528
|
-
}
|
529
|
-
assert_equal expected_recording.keys, @sim.recording.keys
|
530
|
-
assert_in_delta 0, expected_recording.values.zip( @sim.recording.values )
|
531
|
-
.map{ |expected, actual| ( Vector[ *expected ] -
|
532
|
-
Vector[ *actual ] ).norm }.reduce( :+ ), 1e-4
|
533
|
-
expected_recording_string =
|
534
|
-
"0.0,1.0,2.0,3.0\n" +
|
535
|
-
"10.0,0.22265,1.22265,3.77735\n" +
|
536
|
-
"20.0,0.07131,1.07131,3.92869\n" +
|
537
|
-
"30.0,0.02496,1.02496,3.97504\n"
|
538
|
-
assert_equal expected_recording_string, @sim.recording_csv_string
|
539
|
-
end
|
540
|
-
end
|
541
|
-
end
|
542
|
-
|
543
|
-
describe "timed 'isomerization' with given as λ" do
|
544
|
-
before do
|
545
|
-
@t2 = ::YPetri::Transition.new s: { @a => -1, @c => 1 },
|
546
|
-
rate_closure: -> a { a * 0.5 }
|
547
|
-
@net = ::YPetri::Net.new << @a << @b << @c << @t2
|
548
|
-
end
|
549
|
-
|
550
|
-
describe "behavior of #step" do
|
551
|
-
before do
|
552
|
-
@sim = ::YPetri::TimedSimulation.new net: @net,
|
553
|
-
initial_marking: [ @a, @b, @c ].τBᴍHτ( &:default_marking ),
|
554
|
-
step: 1,
|
555
|
-
sampling: 10
|
556
|
-
end
|
557
|
-
|
558
|
-
it "should have expected stoichiometry matrix" do
|
559
|
-
@sim.S.must_equal Matrix[ [-1, 0, 1] ].t
|
560
|
-
m = @sim.step!.marking
|
561
|
-
m[ 0 ].must_be_within_epsilon( 0.5, 1e-6 )
|
562
|
-
m[ 1 ].must_equal 2
|
563
|
-
m[ 2 ].must_be_within_delta( 3.5, 1e-9 )
|
564
|
-
end
|
565
|
-
end
|
566
|
-
end
|
567
|
-
|
568
|
-
describe "timed controlled isomerization" do
|
569
|
-
before do
|
570
|
-
@t3 = ::YPetri::Transition.new s: { @a => -1, @c => 1 },
|
571
|
-
domain: @b,
|
572
|
-
rate: -> a { a * 0.5 }
|
573
|
-
@net = ::YPetri::Net.new << @a << @b << @c << @t3
|
574
|
-
@sim = ::YPetri::TimedSimulation.new net: @net,
|
575
|
-
initial_marking: { @a => 1, @b => 0.6, @c => 3 },
|
576
|
-
step: 1,
|
577
|
-
sampling: 10,
|
578
|
-
target_time: 2
|
579
|
-
end
|
580
|
-
|
581
|
-
it "should exhibit correct behavior of #step" do
|
582
|
-
@sim.marking.must_equal [1.0, 0.6, 3.0]
|
583
|
-
@t3.stoichiometric?.must_equal true
|
584
|
-
@t3.timed?.must_equal true
|
585
|
-
@t3.has_rate?.must_equal true
|
586
|
-
@sim.gradient.must_equal Matrix.cv [-0.3, 0.0, 0.3]
|
587
|
-
@sim.Δ_Euler.must_equal Matrix.cv [-0.3, 0.0, 0.3]
|
588
|
-
@sim.step!
|
589
|
-
@sim.marking_vector.must_equal Matrix.cv [0.7, 0.6, 3.3]
|
590
|
-
@sim.euler_step!
|
591
|
-
@sim.run!
|
592
|
-
@sim.marking_vector.map( &[:round, 5] )
|
593
|
-
.must_equal Matrix.cv [0.4, 0.6, 3.6]
|
594
|
-
end
|
595
|
-
end
|
596
|
-
end
|
597
|
-
|
598
|
-
|
599
|
-
# **************************************************************************
|
600
|
-
# Test of Workspace class.
|
601
|
-
# **************************************************************************
|
602
|
-
#
|
603
|
-
describe ::YPetri::Workspace do
|
604
|
-
before do
|
605
|
-
# skip "to speed up testing"
|
606
|
-
@w = ::YPetri::Workspace.new
|
607
|
-
a = @w.Place.new!( default_marking: 1.0, name: "AA" )
|
608
|
-
b = @w.Place.new!( default_marking: 2.0, name: "BB" )
|
609
|
-
c = @w.Place.new!( ɴ: "CC", default_marking: 3.0 )
|
610
|
-
t1 = @w.Transition.new! s: { a => -1, b => -1, c => 1 },
|
611
|
-
rate: 0.1,
|
612
|
-
ɴ: "AA_BB_assembly"
|
613
|
-
t2 = @w.Transition.new! ɴ: "AA_appearing",
|
614
|
-
codomain: a,
|
615
|
-
rate: -> { 0.1 },
|
616
|
-
stoichiometry: 1
|
617
|
-
@pp, @tt = [a, b, c], [t1, t2]
|
618
|
-
@f_name = "test_output.csv"
|
619
|
-
@w.set_imc @pp.τBᴍHτ( &:default_marking )
|
620
|
-
@w.set_ssc step: 0.1, sampling: 10, target_time: 50
|
621
|
-
@w.set_cc( {} )
|
622
|
-
@sim = @w.new_timed_simulation
|
623
|
-
File.delete @f_name rescue nil
|
624
|
-
end
|
625
|
-
|
626
|
-
it "should present places, transitions, nets, simulations" do
|
627
|
-
assert_kind_of ::YPetri::Net, @w.Net::Top
|
628
|
-
assert_equal @pp[0], @w.place( "AA" )
|
629
|
-
assert_equal :AA, @w.pl( @pp[0] )
|
630
|
-
assert_equal @tt[0], @w.transition( "AA_BB_assembly" )
|
631
|
-
assert_equal :AA_appearing, @w.tr( @tt[1] )
|
632
|
-
assert_equal @pp, @w.places
|
633
|
-
assert_equal @tt, @w.transitions
|
634
|
-
assert_equal 1, @w.nets.size
|
635
|
-
assert_equal 1, @w.simulations.size
|
636
|
-
assert_equal 0, @w.cc.size
|
637
|
-
assert_equal 3, @w.imc.size
|
638
|
-
assert [0.1, 10, 50].each { |e| @w.ssc.include? e }
|
639
|
-
assert_equal @sim, @w.simulation
|
640
|
-
assert_equal [:Base], @w.clamp_collections.keys
|
641
|
-
assert_equal [:Base], @w.initial_marking_collections.keys
|
642
|
-
assert_equal [:Base], @w.simulation_settings_collections.keys
|
643
|
-
assert_equal [:AA, :BB, :CC], @w.pp
|
644
|
-
assert_equal [:AA_BB_assembly, :AA_appearing], @w.tt
|
645
|
-
assert_equal [:Top], @w.nn
|
646
|
-
end
|
647
|
-
|
648
|
-
it "should simulate" do
|
649
|
-
assert_equal 1, @w.simulations.size
|
650
|
-
assert_kind_of( ::YPetri::Simulation, @w.simulation )
|
651
|
-
assert_equal 2, @w.simulation.SR_transitions.size
|
652
|
-
@tt[0].domain.must_equal [ @pp[0], @pp[1] ]
|
653
|
-
@tt[1].domain.must_equal []
|
654
|
-
assert_equal [0.2, 0.1], @w.simulation.φ.column_to_a
|
655
|
-
@w.simulation.step!
|
656
|
-
@w.simulation.run!
|
657
|
-
rec_string = @w.simulation.recording_csv_string
|
658
|
-
expected_recording_string =
|
659
|
-
"0.0,1.0,2.0,3.0\n" +
|
660
|
-
"10.0,0.86102,0.86102,4.13898\n" +
|
661
|
-
"20.0,1.29984,0.29984,4.70016\n"
|
662
|
-
assert rec_string.start_with?( expected_recording_string )
|
663
|
-
end
|
664
|
-
end
|
665
|
-
|
666
|
-
# **************************************************************************
|
667
|
-
# Test of Manipulator class.
|
668
|
-
# **************************************************************************
|
669
|
-
#
|
670
|
-
describe ::YPetri::Manipulator do
|
671
|
-
before do
|
672
|
-
# skip "for now"
|
673
|
-
@m = ::YPetri::Manipulator.new
|
674
|
-
end
|
675
|
-
|
676
|
-
it "has net basic points" do
|
677
|
-
# --- net point related assets ---
|
678
|
-
@m.net_point_reset
|
679
|
-
@m.net_point_set @m.workspace.net( :Top )
|
680
|
-
@m.net.must_equal @m.workspace.Net::Top
|
681
|
-
# --- simulation point related assets ---
|
682
|
-
@m.simulation_point.reset
|
683
|
-
@m.simulation.must_equal nil
|
684
|
-
@m.simulation_point.key.must_equal nil
|
685
|
-
# --- cc point related assets ---
|
686
|
-
@m.cc_point.reset
|
687
|
-
@m.cc_point.set :Base
|
688
|
-
@m.cc.must_equal @m.workspace.clamp_collection
|
689
|
-
@m.cc.wont_equal :Base
|
690
|
-
@m.cc_point.key.must_equal :Base
|
691
|
-
# --- imc point related assets ---
|
692
|
-
@m.imc_point.reset
|
693
|
-
@m.imc_point.set :Base
|
694
|
-
@m.imc.must_equal @m.workspace.initial_marking_collection
|
695
|
-
@m.imc.wont_equal :Base
|
696
|
-
@m.imc_point.key.must_equal :Base
|
697
|
-
# --- ssc point related assets ---
|
698
|
-
@m.ssc_point.reset
|
699
|
-
@m.ssc_point.set :Base
|
700
|
-
@m.ssc.must_equal @m.workspace.simulation_settings_collection
|
701
|
-
@m.ssc.wont_equal :Base
|
702
|
-
@m.ssc_point.key.must_equal :Base
|
703
|
-
end
|
704
|
-
|
705
|
-
it "has basic selections" do
|
706
|
-
@m.net_selection.clear
|
707
|
-
@m.simulation_selection.clear
|
708
|
-
@m.cc_selection.clear
|
709
|
-
@m.imc_selection.clear
|
710
|
-
@m.ssc_selection.clear
|
711
|
-
@m.net_selection.get.must_equal []
|
712
|
-
@m.simulation_selection.get.must_equal []
|
713
|
-
@m.ssc_selection.get.must_equal []
|
714
|
-
@m.cc_selection.get.must_equal []
|
715
|
-
@m.imc_selection.get.must_equal []
|
716
|
-
end
|
717
|
-
|
718
|
-
it "presents some methods from workspace" do
|
719
|
-
[ @m.places, @m.transitions, @m.nets, @m.simulations ].map( &:size )
|
720
|
-
.must_equal [ 0, 0, 1, 0 ]
|
721
|
-
[ @m.clamp_collections,
|
722
|
-
@m.initial_marking_collections,
|
723
|
-
@m.simulation_settings_collections ].map( &:size ).must_equal [ 1, 1, 1 ]
|
724
|
-
[ @m.clamp_collections,
|
725
|
-
@m.initial_marking_collections,
|
726
|
-
@m.simulation_settings_collections ]
|
727
|
-
.map( &:keys ).must_equal [[:Base]] * 3
|
728
|
-
@m.pp.must_equal []
|
729
|
-
@m.tt.must_equal []
|
730
|
-
@m.nn.must_equal [ :Top ] # ie. :Top net spanning whole workspace
|
731
|
-
end
|
732
|
-
|
733
|
-
describe "slightly more complicated case" do
|
734
|
-
before do
|
735
|
-
@p = @m.Place ɴ: "P", default_marking: 1
|
736
|
-
@q = @m.Place ɴ: "Q", default_marking: 1
|
737
|
-
@decay_t = @m.Transition ɴ: "Tp", s: { P: -1 }, rate: 0.1
|
738
|
-
@constant_flux_t = @m.Transition ɴ: "Tq", s: { Q: 1 }, rate: -> { 0.02 }
|
739
|
-
@m.initial_marking @p => 1.2
|
740
|
-
@m.initial_marking @q => 2
|
741
|
-
@m.set_step 0.01
|
742
|
-
@m.set_sampling 1
|
743
|
-
@m.set_time 30
|
744
|
-
end
|
745
|
-
|
746
|
-
it "works" do
|
747
|
-
@m.run!
|
748
|
-
@m.simulation.places.must_equal [ @p, @q ]
|
749
|
-
@m.simulation.transitions.must_equal [ @decay_t, @constant_flux_t ]
|
750
|
-
@m.simulation.SR_tt.must_equal [ :Tp, :Tq ]
|
751
|
-
@m.simulation.sparse_stoichiometry_vector( :Tp )
|
752
|
-
.must_equal Matrix.column_vector( [-1, 0] )
|
753
|
-
@m.simulation.stoichiometry_matrix_for( @m.transitions ).column_size
|
754
|
-
.must_equal 2
|
755
|
-
@m.simulation.stoichiometry_matrix_for( @m.transitions ).row_size
|
756
|
-
.must_equal 2
|
757
|
-
@m.simulation.flux_vector.row_size.must_equal 2
|
758
|
-
# @m.plot_recording
|
759
|
-
end
|
760
|
-
end
|
761
|
-
end
|
762
|
-
|
763
|
-
|
764
|
-
# **************************************************************************
|
765
|
-
# Test of YPetri class itself.
|
766
|
-
# **************************************************************************
|
767
|
-
#
|
768
|
-
describe ::YPetri do
|
769
|
-
before do
|
770
|
-
# skip "to speed up testing"
|
771
|
-
end
|
772
|
-
|
10
|
+
# Unit tests for the YPetri module.
|
11
|
+
#
|
12
|
+
describe YPetri do
|
773
13
|
it "should have basic classes" do
|
774
|
-
[ :Place, :Transition, :Net,
|
775
|
-
|
776
|
-
|
777
|
-
|
14
|
+
assert [ :Place, :Transition, :Net,
|
15
|
+
:Simulation, :TimedSimulation,
|
16
|
+
:Workspace, :Manipulator
|
17
|
+
].all? { |ß| YPetri.const_get( ß ).is_a? Module }
|
778
18
|
end
|
779
19
|
end
|
780
20
|
|
781
|
-
|
782
|
-
#
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
# @m.Place name: "B"
|
791
|
-
# @m.Place name: "C", marking: 7.77
|
792
|
-
# @m.Transition name: "A2B", stoichiometry: { A: -1, B: 1 }
|
793
|
-
# @m.Transition name: "C_decay", stoichiometry: { C: -1 }, rate: 0.05
|
794
|
-
# end
|
795
|
-
|
796
|
-
# it "should work" do
|
797
|
-
# @m.place( :A ).marking = 2
|
798
|
-
# @m.place( :B ).marking = 5
|
799
|
-
# @m.places.map( &:name ).must_equal [:A, :B, :C]
|
800
|
-
# @m.places.map( &:marking ).must_equal [2, 5, 7.77]
|
801
|
-
# @m.transition( :A2B ).arcs.must_equal [ @m.place( :A ), @m.place( :B ) ]
|
802
|
-
# @m.transition( :A2B ).fire!
|
803
|
-
# @m.places.map( &:marking ).must_equal [1, 6, 7.77]
|
804
|
-
# @m.transition( :A2B ).fire!
|
805
|
-
# @m.place( :A ).marking.must_equal 0
|
806
|
-
# @m.place( :B ).marking.must_equal 7
|
807
|
-
# 2.times do @m.transition( :C_decay ).fire! 1 end
|
808
|
-
# @m.transition( :C_decay ).fire! 0.1
|
809
|
-
# 200.times do @m.transition( :C_decay ).fire! 1 end
|
810
|
-
# assert_in_delta @m.place( :C ).marking, 0.00024, 0.00001
|
811
|
-
# end
|
812
|
-
# end
|
813
|
-
|
814
|
-
# describe "Basic use of TimedSimulation" do
|
815
|
-
# before do
|
816
|
-
# @m = YPetri::Manipulator.new
|
817
|
-
# @m.Place( name: "A", default_marking: 0.5 )
|
818
|
-
# @m.Place( name: "B", default_marking: 0.5 )
|
819
|
-
# @m.Transition( name: "A_pump",
|
820
|
-
# stoichiometry: { A: -1 },
|
821
|
-
# rate: proc { 0.005 } )
|
822
|
-
# @m.Transition( name: "B_decay",
|
823
|
-
# stoichiometry: { B: -1 },
|
824
|
-
# rate: 0.05 )
|
825
|
-
# end
|
826
|
-
|
827
|
-
# it "should work" do
|
828
|
-
# @m.net.must_be_kind_of ::YPetri::Net
|
829
|
-
# @m.run!
|
830
|
-
# @m.simulation.must_be_kind_of ::YPetri::TimedSimulation
|
831
|
-
# @m.plot_state
|
832
|
-
# sleep 3
|
833
|
-
# end
|
834
|
-
# end
|
835
|
-
|
836
|
-
# describe "Graphviz visualization" do
|
837
|
-
# before do
|
838
|
-
# @m = YPetri::Manipulator.new
|
839
|
-
# @m.Place name: :A, m!: 1
|
840
|
-
# @m.Place name: :B, m!: 1.5
|
841
|
-
# @m.Place name: :C, m!: 2
|
842
|
-
# @m.Place name: :D, m!: 2.5
|
843
|
-
# @m.Transition name: :A_pump, s: { A: -1 }, rate: proc { 0.005 }
|
844
|
-
# @m.Transition name: :B_decay, s: { B: -1 }, rate: 0.05
|
845
|
-
# @m.Transition name: :C_guard, assignment: true, codomain: :C, action: λ { 2 }
|
846
|
-
# end
|
847
|
-
|
848
|
-
# it "should work" do
|
849
|
-
# @m.net.visualize
|
850
|
-
# end
|
851
|
-
# end
|
852
|
-
|
853
|
-
# describe "Simplified dTTP pathway used for demo with Dr. Chang" do
|
854
|
-
# before do
|
855
|
-
# @m = YPetri::Manipulator.new
|
856
|
-
# Cytoplasm_volume_in_litres = 5.0e-11
|
857
|
-
# NA = 6.022e23
|
858
|
-
# Pieces_per_micromolar = NA / 1_000_000 * Cytoplasm_volume_in_litres
|
859
|
-
# @m.set_step 60
|
860
|
-
# @m.set_sampling 300
|
861
|
-
# @m.set_target_time 60 * 60 * 2
|
862
|
-
# AMP = @m.Place( name: :AMP, m!: 8695.0 )
|
863
|
-
# ADP = @m.Place( name: :ADP, m!: 6521.0 )
|
864
|
-
# ATP = @m.Place( name: :ATP, m!: 3152.0 )
|
865
|
-
# Deoxycytidine = @m.Place( name: :Deoxycytidine, m!: 0.5 )
|
866
|
-
# DeoxyCTP = @m.Place( name: :DeoxyCTP, m!: 1.0 )
|
867
|
-
# DeoxyGMP = @m.Place( name: :DeoxyGMP, m!: 1.0 )
|
868
|
-
# UMP_UDP_pool = @m.Place( name: :UMP_UDP_pool, m!: 2737.0 )
|
869
|
-
# DeoxyUMP_DeoxyUDP_pool = @m.Place( name: :DeoxyUMP_DeoxyUDP_pool, m!: 0.0 )
|
870
|
-
# DeoxyTMP = @m.Place( name: :DeoxyTMP, m!: 3.3 )
|
871
|
-
# DeoxyTDP_DeoxyTTP_pool = @m.Place( name: :DeoxyTDP_DeoxyTTP_pool, m!: 5.0 )
|
872
|
-
# Thymidine = @m.Place( name: :Thymidine, m!: 0.5 )
|
873
|
-
# TK1 = @m.Place( name: :TK1, m!: 100_000 )
|
874
|
-
# TYMS = @m.Place( name: :TYMS, m!: 100_000 )
|
875
|
-
# RNR = @m.Place( name: :RNR, m!: 100_000 )
|
876
|
-
# TMPK = @m.Place( name: :TMPK, m!: 100_000 )
|
877
|
-
# TK1_kDa = 24.8
|
878
|
-
# TYMS_kDa = 66.0
|
879
|
-
# RNR_kDa = 140.0
|
880
|
-
# TMPK_kDa = 50.0
|
881
|
-
# TK1_a = 5.40
|
882
|
-
# TYMS_a = 3.80
|
883
|
-
# RNR_a = 1.00
|
884
|
-
# TMPK_a = 0.83
|
885
|
-
# @m.clamp AMP: 8695.0, ADP: 6521.0, ATP: 3152.0
|
886
|
-
# @m.clamp Deoxycytidine: 0.5, DeoxyCTP: 1.0, DeoxyGMP: 1.0
|
887
|
-
# @m.clamp Thymidine: 0.5
|
888
|
-
# @m.clamp UMP_UDP_pool: 2737.0
|
889
|
-
# # Functions
|
890
|
-
# Vmax_per_minute_per_enzyme_molecule =
|
891
|
-
# lambda { |enzyme_specific_activity_in_micromol_per_minute_per_mg,
|
892
|
-
# enzyme_molecular_mass_in_kDa|
|
893
|
-
# enzyme_specific_activity_in_micromol_per_minute_per_mg *
|
894
|
-
# enzyme_molecular_mass_in_kDa }
|
895
|
-
# Vmax_per_minute =
|
896
|
-
# lambda { |specific_activity, kDa, enzyme_molecules_per_cell|
|
897
|
-
# Vmax_per_minute_per_enzyme_molecule.( specific_activity, kDa ) *
|
898
|
-
# enzyme_molecules_per_cell }
|
899
|
-
# Vmax_per_second =
|
900
|
-
# lambda { |specific_activity, kDa, enzyme_molecules_per_cell|
|
901
|
-
# Vmax_per_minute.( specific_activity,
|
902
|
-
# kDa,
|
903
|
-
# enzyme_molecules_per_cell ) / 60 }
|
904
|
-
# Km_reduced =
|
905
|
-
# lambda { |km, ki_hash={}|
|
906
|
-
# ki_hash.map { |concentration, ci_Ki|
|
907
|
-
# concentration / ci_Ki
|
908
|
-
# }.reduce( 1, :+ ) * km }
|
909
|
-
# Occupancy =
|
910
|
-
# lambda { |concentration, reactant_Km, compet_inh_w_Ki_hash={}|
|
911
|
-
# concentration / ( concentration +
|
912
|
-
# Km_reduced.( reactant_Km,
|
913
|
-
# compet_inh_w_Ki_hash ) ) }
|
914
|
-
# MM_with_inh_micromolars_per_second =
|
915
|
-
# lambda { |reactant_concentration,
|
916
|
-
# enzyme_specific_activity,
|
917
|
-
# enzyme_mass_in_kDa,
|
918
|
-
# enzyme_molecules_per_cell,
|
919
|
-
# reactant_Km,
|
920
|
-
# competitive_inh_w_Ki_hash={}|
|
921
|
-
# Vmax_per_second.( enzyme_specific_activity,
|
922
|
-
# enzyme_mass_in_kDa,
|
923
|
-
# enzyme_molecules_per_cell ) *
|
924
|
-
# Occupancy.( reactant_concentration,
|
925
|
-
# reactant_Km,
|
926
|
-
# competitive_inh_w_Ki_hash ) }
|
927
|
-
# MMi = MM_with_inh_micromolars_per_second
|
928
|
-
# TK1_Thymidine_Km = 5.0
|
929
|
-
# TYMS_DeoxyUMP_Km = 2.0
|
930
|
-
# RNR_UDP_Km = 1.0
|
931
|
-
# DNA_creation_speed = 3_000_000_000 / ( 12 * 3600 )
|
932
|
-
# TMPK_DeoxyTMP_Km = 12.0
|
933
|
-
|
934
|
-
# # transitions
|
935
|
-
# @m.Transition name: :TK1_Thymidine_DeoxyTMP,
|
936
|
-
# domain: [ Thymidine, TK1, DeoxyTDP_DeoxyTTP_pool, DeoxyCTP, Deoxycytidine, AMP, ADP, ATP ],
|
937
|
-
# stoichiometry: { Thymidine: -1, DeoxyTMP: 1 },
|
938
|
-
# rate: proc { |rc, e, pool1, ci2, ci3, master1, master2, master3|
|
939
|
-
# ci1 = pool1 * master3 / ( master2 + master3 )
|
940
|
-
# MMi.( rc, TK1_a, TK1_kDa, e, TK1_Thymidine_Km,
|
941
|
-
# ci1 => 13.5, ci2 => 0.8, ci3 => 40.0 ) }
|
942
|
-
# @m.Transition name: :TYMS_DeoxyUMP_DeoxyTMP,
|
943
|
-
# domain: [ DeoxyUMP_DeoxyUDP_pool, TYMS, AMP, ADP, ATP ],
|
944
|
-
# stoichiometry: { DeoxyUMP_DeoxyUDP_pool: -1, DeoxyTMP: 1 },
|
945
|
-
# rate: proc { |pool, e, master1, master2, master3|
|
946
|
-
# rc = pool * master2 / ( master1 + master2 )
|
947
|
-
# MMi.( rc, TYMS_a, TYMS_kDa, e, TYMS_DeoxyUMP_Km ) }
|
948
|
-
# @m.Transition name: :RNR_UDP_DeoxyUDP,
|
949
|
-
# domain: [ UMP_UDP_pool, RNR, DeoxyUMP_DeoxyUDP_pool, AMP, ADP, ATP ],
|
950
|
-
# stoichiometry: { UMP_UDP_pool: -1, DeoxyUMP_DeoxyUDP_pool: 1 },
|
951
|
-
# rate: proc { |pool, e, master1, master2, master3|
|
952
|
-
# rc = pool * master2 / ( master1 + master2 )
|
953
|
-
# MMi.( rc, RNR_a, RNR_kDa, e, RNR_UDP_Km ) }
|
954
|
-
# @m.Transition name: :DNA_polymerase_consumption_of_DeoxyTTP,
|
955
|
-
# stoichiometry: { DeoxyTDP_DeoxyTTP_pool: -1 },
|
956
|
-
# rate: proc { DNA_creation_speed / 4 }
|
957
|
-
# @m.Transition name: :TMPK_DeoxyTMP_DeoxyTDP,
|
958
|
-
# domain: [ DeoxyTMP, TMPK, ADP,
|
959
|
-
# DeoxyTDP_DeoxyTTP_pool,
|
960
|
-
# DeoxyGMP, AMP, ATP ],
|
961
|
-
# stoichiometry: { DeoxyTMP: -1, TMPK: 0, DeoxyTDP_DeoxyTTP_pool: 1 },
|
962
|
-
# rate: proc { |rc, e, ci1, pool, ci4, master1, master3|
|
963
|
-
# master2 = ci1
|
964
|
-
# ci2 = pool * master2 / ( master2 + master3 )
|
965
|
-
# ci3 = pool * master3 / ( master2 + master3 )
|
966
|
-
# MMi.( rc, TMPK_a, TMPK_kDa, e, TMPK_DeoxyTMP_Km,
|
967
|
-
# ci1 => 250.0, ci2 => 30.0, ci3 => 750, ci4 => 117 ) }
|
968
|
-
# end
|
969
|
-
|
970
|
-
# it "should work" do
|
971
|
-
# @m.run!
|
972
|
-
# @m.plot_state
|
973
|
-
# sleep 3
|
974
|
-
# end
|
975
|
-
# end
|
976
|
-
|
977
|
-
# describe "Use of TimedSimulation with units" do
|
978
|
-
# before do
|
979
|
-
# require 'sy'
|
980
|
-
|
981
|
-
# @m = YPetri::Manipulator.new
|
982
|
-
|
983
|
-
# # === General assumptions
|
984
|
-
# Cytoplasm_volume = 5.0e-11.l
|
985
|
-
# Pieces_per_concentration = SY::Nᴀ * Cytoplasm_volume
|
986
|
-
|
987
|
-
# # === Simulation settings
|
988
|
-
# @m.set_step 60.s
|
989
|
-
# @m.set_target_time 10.min
|
990
|
-
# @m.set_sampling 120.s
|
991
|
-
|
992
|
-
# # === Places
|
993
|
-
# AMP = @m.Place m!: 8695.0.µM
|
994
|
-
# ADP = @m.Place m!: 6521.0.µM
|
995
|
-
# ATP = @m.Place m!: 3152.0.µM
|
996
|
-
# Deoxycytidine = @m.Place m!: 0.5.µM
|
997
|
-
# DeoxyCTP = @m.Place m!: 1.0.µM
|
998
|
-
# DeoxyGMP = @m.Place m!: 1.0.µM
|
999
|
-
# U12P = @m.Place m!: 2737.0.µM
|
1000
|
-
# DeoxyU12P = @m.Place m!: 0.0.µM
|
1001
|
-
# DeoxyTMP = @m.Place m!: 3.3.µM
|
1002
|
-
# DeoxyT23P = @m.Place m!: 5.0.µM
|
1003
|
-
# Thymidine = @m.Place m!: 0.5.µM
|
1004
|
-
# TK1 = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
1005
|
-
# TYMS = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
1006
|
-
# RNR = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
1007
|
-
# TMPK = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
1008
|
-
|
1009
|
-
# # === Enzyme molecular masses
|
1010
|
-
# TK1_m = 24.8.kDa
|
1011
|
-
# TYMS_m = 66.0.kDa
|
1012
|
-
# RNR_m = 140.0.kDa
|
1013
|
-
# TMPK_m = 50.0.kDa
|
1014
|
-
|
1015
|
-
# # === Specific activities of the enzymes
|
1016
|
-
# TK1_a = 5.40.µmol.min⁻¹.mg⁻¹
|
1017
|
-
# TYMS_a = 3.80.µmol.min⁻¹.mg⁻¹
|
1018
|
-
# RNR_a = 1.00.µmol.min⁻¹.mg⁻¹
|
1019
|
-
# TMPK_a = 0.83.µmol.min⁻¹.mg⁻¹
|
1020
|
-
|
1021
|
-
# # === Clamps
|
1022
|
-
# @m.clamp AMP: 8695.0.µM, ADP: 6521.0.µM, ATP: 3152.0.µM
|
1023
|
-
# @m.clamp Deoxycytidine: 0.5.µM, DeoxyCTP: 1.0.µM, DeoxyGMP: 1.0.µM
|
1024
|
-
# @m.clamp Thymidine: 0.5.µM
|
1025
|
-
# @m.clamp U12P: 2737.0.µM
|
1026
|
-
|
1027
|
-
# # === Function closures
|
1028
|
-
|
1029
|
-
# # Vmax of an enzyme.
|
1030
|
-
# #
|
1031
|
-
# Vmax_enzyme = lambda { |specific_activity, mass, enzyme_conc|
|
1032
|
-
# specific_activity * mass * enzyme_conc.( SY::Molecularity )
|
1033
|
-
# }
|
1034
|
-
|
1035
|
-
# # Michaelis constant reduced for competitive inhibitors.
|
1036
|
-
# #
|
1037
|
-
# Km_reduced = lambda { |km, ki_hash={}|
|
1038
|
-
# ki_hash.map { |concentration, ci_Ki|
|
1039
|
-
# concentration / ci_Ki }
|
1040
|
-
# .reduce( 1, :+ ) * km
|
1041
|
-
# }
|
1042
|
-
|
1043
|
-
# # Occupancy of enzyme active sites at given concentration of reactants
|
1044
|
-
# # and competitive inhibitors.
|
1045
|
-
# #
|
1046
|
-
# Occupancy = lambda { |ʀ_conc, ʀ_Km, cɪ_Kɪ={}|
|
1047
|
-
# ʀ_conc / ( ʀ_conc + Km_reduced.( ʀ_Km, cɪ_Kɪ ) )
|
1048
|
-
# }
|
1049
|
-
|
1050
|
-
# # Michaelis and Menten equation with competitive inhibitors.
|
1051
|
-
# #
|
1052
|
-
# MMi = MM_equation_with_inhibitors = lambda {
|
1053
|
-
# |ʀ_conc, ᴇ_specific_activity, ᴇ_mass, ᴇ_conc, ʀ_Km, cɪ_Kɪ={}|
|
1054
|
-
# Vmax_enzyme.( ᴇ_specific_activity, ᴇ_mass, ᴇ_conc ) *
|
1055
|
-
# Occupancy.( ʀ_conc, ʀ_Km, cɪ_Kɪ )
|
1056
|
-
# }
|
1057
|
-
|
1058
|
-
# # === Michaelis constants of the enzymes involved.
|
1059
|
-
|
1060
|
-
# TK1_Thymidine_Km = 5.0.µM
|
1061
|
-
# TYMS_DeoxyUMP_Km = 2.0.µM
|
1062
|
-
# RNR_UDP_Km = 1.0.µM
|
1063
|
-
# TMPK_DeoxyTMP_Km = 12.0.µM
|
1064
|
-
|
1065
|
-
# # === DNA synthesis speed.
|
1066
|
-
|
1067
|
-
# DNA_creation_speed = 3_000_000_000.unit.( SY::MoleAmount ) / 12.h / Cytoplasm_volume
|
1068
|
-
|
1069
|
-
# # === Transitions
|
1070
|
-
|
1071
|
-
# # Synthesis of TMP by TK1.
|
1072
|
-
# #
|
1073
|
-
# TK1_Thymidine_DeoxyTMP = @m.Transition s: { Thymidine: -1, DeoxyTMP: 1 },
|
1074
|
-
# domain: [ Thymidine, TK1, DeoxyT23P, DeoxyCTP, Deoxycytidine, AMP, ADP, ATP ],
|
1075
|
-
# rate: proc { |rc, e, pool1, ci2, ci3, master1, master2, master3|
|
1076
|
-
# ci1 = pool1 * master3 / ( master2 + master3 )
|
1077
|
-
# MMi.( rc, TK1_a, TK1_m, e, TK1_Thymidine_Km,
|
1078
|
-
# ci1 => 13.5.µM, ci2 => 0.8.µM, ci3 => 40.0.µM )
|
1079
|
-
# }
|
1080
|
-
|
1081
|
-
# # Methylation of DeoxyUMP into TMP by TYMS.
|
1082
|
-
# TYMS_DeoxyUMP_DeoxyTMP = @m.Transition s: { DeoxyU12P: -1, DeoxyTMP: 1 },
|
1083
|
-
# domain: [ DeoxyU12P, TYMS, AMP, ADP, ATP ],
|
1084
|
-
# rate: proc { |pool, e, master1, master2, master3|
|
1085
|
-
# rc = pool * master2 / ( master1 + master2 )
|
1086
|
-
# MMi.( rc, TYMS_a, TYMS_m, e, TYMS_DeoxyUMP_Km )
|
1087
|
-
# }
|
1088
|
-
|
1089
|
-
# # Reduction of UDP into DeoxyUDP by RNR.
|
1090
|
-
# RNR_UDP_DeoxyUDP = @m.Transition s: { U12P: -1, DeoxyU12P: 1 },
|
1091
|
-
# domain: [ U12P, RNR, DeoxyU12P, AMP, ADP, ATP ],
|
1092
|
-
# rate: proc { |pool, e, master1, master2, master3|
|
1093
|
-
# rc = pool * master2 / ( master1 + master2 )
|
1094
|
-
# MMi.( rc, RNR_a, RNR_m, e, RNR_UDP_Km )
|
1095
|
-
# }
|
1096
|
-
|
1097
|
-
# # Consumption of TTP by DNA synthesis.
|
1098
|
-
# DeoxyTTP_to_DNA = @m.Transition s: { DeoxyT23P: -1 },
|
1099
|
-
# rate: proc { DNA_creation_speed / 4 }
|
1100
|
-
|
1101
|
-
# # Phosphorylation of TMP into TDP-TTP pool.
|
1102
|
-
# TMPK_DeoxyTMP_DeoxyTDP = @m.Transition s: { DeoxyTMP: -1, TMPK: 0, DeoxyT23P: 1 },
|
1103
|
-
# domain: [ DeoxyTMP, TMPK, ADP, DeoxyT23P, DeoxyGMP, AMP, ATP ],
|
1104
|
-
# rate: proc { |rc, e, ci1, pool, ci4, master1, master3|
|
1105
|
-
# master2 = ci1
|
1106
|
-
# ci2 = pool * master2 / ( master2 + master3 )
|
1107
|
-
# ci3 = pool * master3 / ( master2 + master3 )
|
1108
|
-
# MMi.( rc, TMPK_a, TMPK_m, e, TMPK_DeoxyTMP_Km,
|
1109
|
-
# ci1 => 250.0.µM, ci2 => 30.0.µM, ci3 => 750.µM, ci4 => 117.µM )
|
1110
|
-
# }
|
1111
|
-
# end
|
1112
|
-
|
1113
|
-
# it "should work" do
|
1114
|
-
# # === Simulation execution
|
1115
|
-
# @m.run!
|
1116
|
-
# # === Plotting of the results
|
1117
|
-
# @m.plot_state
|
1118
|
-
# sleep 20
|
1119
|
-
# end
|
1120
|
-
# end
|
21
|
+
# Run all other unit tests.
|
22
|
+
#
|
23
|
+
require_relative 'place_test'
|
24
|
+
require_relative 'transition_test'
|
25
|
+
require_relative 'net_test'
|
26
|
+
require_relative 'simulation_test'
|
27
|
+
require_relative 'timed_simulation_test'
|
28
|
+
require_relative 'workspace_test'
|
29
|
+
require_relative 'manipulator_test'
|