y_petri 2.0.7 → 2.0.14.p1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,153 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require_relative '../../lib/y_petri' # tested component itself
|
7
|
+
# require 'y_petri'
|
8
|
+
# require 'sy'
|
9
|
+
|
10
|
+
describe "Use of TimedSimulation with units" do
|
11
|
+
before do
|
12
|
+
require 'sy'
|
13
|
+
|
14
|
+
@m = YPetri::Manipulator.new
|
15
|
+
|
16
|
+
# === General assumptions
|
17
|
+
Cytoplasm_volume = 5.0e-11.l
|
18
|
+
Pieces_per_concentration = SY::Nᴀ * Cytoplasm_volume
|
19
|
+
|
20
|
+
# === Simulation settings
|
21
|
+
@m.set_step 60.s
|
22
|
+
@m.set_target_time 10.min
|
23
|
+
@m.set_sampling 120.s
|
24
|
+
|
25
|
+
# === Places
|
26
|
+
AMP = @m.Place m!: 8695.0.µM
|
27
|
+
ADP = @m.Place m!: 6521.0.µM
|
28
|
+
ATP = @m.Place m!: 3152.0.µM
|
29
|
+
Deoxycytidine = @m.Place m!: 0.5.µM
|
30
|
+
DeoxyCTP = @m.Place m!: 1.0.µM
|
31
|
+
DeoxyGMP = @m.Place m!: 1.0.µM
|
32
|
+
U12P = @m.Place m!: 2737.0.µM
|
33
|
+
DeoxyU12P = @m.Place m!: 0.0.µM
|
34
|
+
DeoxyTMP = @m.Place m!: 3.3.µM
|
35
|
+
DeoxyT23P = @m.Place m!: 5.0.µM
|
36
|
+
Thymidine = @m.Place m!: 0.5.µM
|
37
|
+
TK1 = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
38
|
+
TYMS = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
39
|
+
RNR = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
40
|
+
TMPK = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
|
41
|
+
|
42
|
+
# === Enzyme molecular masses
|
43
|
+
TK1_m = 24.8.kDa
|
44
|
+
TYMS_m = 66.0.kDa
|
45
|
+
RNR_m = 140.0.kDa
|
46
|
+
TMPK_m = 50.0.kDa
|
47
|
+
|
48
|
+
# === Specific activities of the enzymes
|
49
|
+
TK1_a = 5.40.µmol.min⁻¹.mg⁻¹
|
50
|
+
TYMS_a = 3.80.µmol.min⁻¹.mg⁻¹
|
51
|
+
RNR_a = 1.00.µmol.min⁻¹.mg⁻¹
|
52
|
+
TMPK_a = 0.83.µmol.min⁻¹.mg⁻¹
|
53
|
+
|
54
|
+
# === Clamps
|
55
|
+
@m.clamp AMP: 8695.0.µM, ADP: 6521.0.µM, ATP: 3152.0.µM
|
56
|
+
@m.clamp Deoxycytidine: 0.5.µM, DeoxyCTP: 1.0.µM, DeoxyGMP: 1.0.µM
|
57
|
+
@m.clamp Thymidine: 0.5.µM
|
58
|
+
@m.clamp U12P: 2737.0.µM
|
59
|
+
|
60
|
+
# === Function closures
|
61
|
+
|
62
|
+
# Vmax of an enzyme.
|
63
|
+
#
|
64
|
+
Vmax_enzyme = lambda { |specific_activity, mass, enzyme_conc|
|
65
|
+
specific_activity * mass * enzyme_conc.( SY::Molecularity )
|
66
|
+
}
|
67
|
+
|
68
|
+
# Michaelis constant reduced for competitive inhibitors.
|
69
|
+
#
|
70
|
+
Km_reduced = lambda { |km, ki_hash={}|
|
71
|
+
ki_hash.map { |concentration, ci_Ki|
|
72
|
+
concentration / ci_Ki }
|
73
|
+
.reduce( 1, :+ ) * km
|
74
|
+
}
|
75
|
+
|
76
|
+
# Occupancy of enzyme active sites at given concentration of reactants
|
77
|
+
# and competitive inhibitors.
|
78
|
+
#
|
79
|
+
Occupancy = lambda { |ʀ_conc, ʀ_Km, cɪ_Kɪ={}|
|
80
|
+
ʀ_conc / ( ʀ_conc + Km_reduced.( ʀ_Km, cɪ_Kɪ ) )
|
81
|
+
}
|
82
|
+
|
83
|
+
# Michaelis and Menten equation with competitive inhibitors.
|
84
|
+
#
|
85
|
+
MMi = MM_equation_with_inhibitors = lambda {
|
86
|
+
|ʀ_conc, ᴇ_specific_activity, ᴇ_mass, ᴇ_conc, ʀ_Km, cɪ_Kɪ={}|
|
87
|
+
Vmax_enzyme.( ᴇ_specific_activity, ᴇ_mass, ᴇ_conc ) *
|
88
|
+
Occupancy.( ʀ_conc, ʀ_Km, cɪ_Kɪ )
|
89
|
+
}
|
90
|
+
|
91
|
+
# === Michaelis constants of the enzymes involved.
|
92
|
+
|
93
|
+
TK1_Thymidine_Km = 5.0.µM
|
94
|
+
TYMS_DeoxyUMP_Km = 2.0.µM
|
95
|
+
RNR_UDP_Km = 1.0.µM
|
96
|
+
TMPK_DeoxyTMP_Km = 12.0.µM
|
97
|
+
|
98
|
+
# === DNA synthesis speed.
|
99
|
+
|
100
|
+
DNA_creation_speed = 3_000_000_000.unit.( SY::MoleAmount ) / 12.h / Cytoplasm_volume
|
101
|
+
|
102
|
+
# === Transitions
|
103
|
+
|
104
|
+
# Synthesis of TMP by TK1.
|
105
|
+
#
|
106
|
+
TK1_Thymidine_DeoxyTMP = @m.Transition s: { Thymidine: -1, DeoxyTMP: 1 },
|
107
|
+
domain: [ Thymidine, TK1, DeoxyT23P, DeoxyCTP, Deoxycytidine, AMP, ADP, ATP ],
|
108
|
+
rate: proc { |rc, e, pool1, ci2, ci3, master1, master2, master3|
|
109
|
+
ci1 = pool1 * master3 / ( master2 + master3 )
|
110
|
+
MMi.( rc, TK1_a, TK1_m, e, TK1_Thymidine_Km,
|
111
|
+
ci1 => 13.5.µM, ci2 => 0.8.µM, ci3 => 40.0.µM )
|
112
|
+
}
|
113
|
+
|
114
|
+
# Methylation of DeoxyUMP into TMP by TYMS.
|
115
|
+
TYMS_DeoxyUMP_DeoxyTMP = @m.Transition s: { DeoxyU12P: -1, DeoxyTMP: 1 },
|
116
|
+
domain: [ DeoxyU12P, TYMS, AMP, ADP, ATP ],
|
117
|
+
rate: proc { |pool, e, master1, master2, master3|
|
118
|
+
rc = pool * master2 / ( master1 + master2 )
|
119
|
+
MMi.( rc, TYMS_a, TYMS_m, e, TYMS_DeoxyUMP_Km )
|
120
|
+
}
|
121
|
+
|
122
|
+
# Reduction of UDP into DeoxyUDP by RNR.
|
123
|
+
RNR_UDP_DeoxyUDP = @m.Transition s: { U12P: -1, DeoxyU12P: 1 },
|
124
|
+
domain: [ U12P, RNR, DeoxyU12P, AMP, ADP, ATP ],
|
125
|
+
rate: proc { |pool, e, master1, master2, master3|
|
126
|
+
rc = pool * master2 / ( master1 + master2 )
|
127
|
+
MMi.( rc, RNR_a, RNR_m, e, RNR_UDP_Km )
|
128
|
+
}
|
129
|
+
|
130
|
+
# Consumption of TTP by DNA synthesis.
|
131
|
+
DeoxyTTP_to_DNA = @m.Transition s: { DeoxyT23P: -1 },
|
132
|
+
rate: proc { DNA_creation_speed / 4 }
|
133
|
+
|
134
|
+
# Phosphorylation of TMP into TDP-TTP pool.
|
135
|
+
TMPK_DeoxyTMP_DeoxyTDP = @m.Transition s: { DeoxyTMP: -1, TMPK: 0, DeoxyT23P: 1 },
|
136
|
+
domain: [ DeoxyTMP, TMPK, ADP, DeoxyT23P, DeoxyGMP, AMP, ATP ],
|
137
|
+
rate: proc { |rc, e, ci1, pool, ci4, master1, master3|
|
138
|
+
master2 = ci1
|
139
|
+
ci2 = pool * master2 / ( master2 + master3 )
|
140
|
+
ci3 = pool * master3 / ( master2 + master3 )
|
141
|
+
MMi.( rc, TMPK_a, TMPK_m, e, TMPK_DeoxyTMP_Km,
|
142
|
+
ci1 => 250.0.µM, ci2 => 30.0.µM, ci3 => 750.µM, ci4 => 117.µM )
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should work" do
|
147
|
+
# === Simulation execution
|
148
|
+
@m.run!
|
149
|
+
# === Plotting of the results
|
150
|
+
@m.plot_state
|
151
|
+
sleep 20
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require_relative '../../lib/y_petri' # tested component itself
|
7
|
+
# require 'y_petri'
|
8
|
+
# require 'sy'
|
9
|
+
|
10
|
+
describe "Token game" do
|
11
|
+
before do
|
12
|
+
@m = YPetri::Manipulator.new
|
13
|
+
@m.Place name: "A"
|
14
|
+
@m.Place name: "B"
|
15
|
+
@m.Place name: "C", marking: 7.77
|
16
|
+
@m.Transition name: "A2B", stoichiometry: { A: -1, B: 1 }
|
17
|
+
@m.Transition name: "C_decay", stoichiometry: { C: -1 }, rate: 0.05
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should work" do
|
21
|
+
@m.place( :A ).marking = 2
|
22
|
+
@m.place( :B ).marking = 5
|
23
|
+
@m.places.map( &:name ).must_equal [:A, :B, :C]
|
24
|
+
@m.places.map( &:marking ).must_equal [2, 5, 7.77]
|
25
|
+
@m.transition( :A2B ).arcs.must_equal [ @m.place( :A ), @m.place( :B ) ]
|
26
|
+
@m.transition( :A2B ).fire!
|
27
|
+
@m.places.map( &:marking ).must_equal [1, 6, 7.77]
|
28
|
+
@m.transition( :A2B ).fire!
|
29
|
+
@m.place( :A ).marking.must_equal 0
|
30
|
+
@m.place( :B ).marking.must_equal 7
|
31
|
+
2.times do @m.transition( :C_decay ).fire! 1 end
|
32
|
+
@m.transition( :C_decay ).fire! 0.1
|
33
|
+
200.times do @m.transition( :C_decay ).fire! 1 end
|
34
|
+
assert_in_delta @m.place( :C ).marking, 0.00024, 0.00001
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require_relative '../../lib/y_petri' # tested component itself
|
7
|
+
# require 'y_petri'
|
8
|
+
# require 'sy'
|
9
|
+
|
10
|
+
describe "Graphviz visualization" do
|
11
|
+
before do
|
12
|
+
@m = YPetri::Manipulator.new
|
13
|
+
@m.Place name: :A, m!: 1
|
14
|
+
@m.Place name: :B, m!: 1.5
|
15
|
+
@m.Place name: :C, m!: 2
|
16
|
+
@m.Place name: :D, m!: 2.5
|
17
|
+
@m.Transition name: :A_pump, s: { A: -1 }, rate: proc { 0.005 }
|
18
|
+
@m.Transition name: :B_decay, s: { B: -1 }, rate: 0.05
|
19
|
+
@m.Transition name: :C_guard, assignment: true, codomain: :C, action: -> { 2 }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should work" do
|
23
|
+
@m.net.visualize
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require_relative '../lib/y_petri' # tested component itself
|
7
|
+
# require 'y_petri'
|
8
|
+
# require 'sy'
|
9
|
+
|
10
|
+
require_relative 'acceptance/token_game_test'
|
11
|
+
require_relative 'acceptance/basic_usage_test'
|
12
|
+
require_relative 'acceptance/simulation_test'
|
13
|
+
require_relative 'acceptance/visualization_test'
|
14
|
+
require_relative 'acceptance/simulation_with_physical_units_test'
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require_relative '../lib/y_petri' # tested component itself
|
7
|
+
# require 'y_petri'
|
8
|
+
# require 'sy'
|
9
|
+
|
10
|
+
describe ::YPetri::Manipulator do
|
11
|
+
before do
|
12
|
+
@m = ::YPetri::Manipulator.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has net basic points" do
|
16
|
+
# --- net point related assets ---
|
17
|
+
@m.net_point_reset
|
18
|
+
@m.net_point_set @m.workspace.net( :Top )
|
19
|
+
@m.net.must_equal @m.workspace.Net::Top
|
20
|
+
# --- simulation point related assets ---
|
21
|
+
@m.simulation_point.reset
|
22
|
+
@m.simulation.must_equal nil
|
23
|
+
@m.simulation_point.key.must_equal nil
|
24
|
+
# --- cc point related assets ---
|
25
|
+
@m.cc_point.reset
|
26
|
+
@m.cc_point.set :Base
|
27
|
+
@m.cc.must_equal @m.workspace.clamp_collection
|
28
|
+
@m.cc.wont_equal :Base
|
29
|
+
@m.cc_point.key.must_equal :Base
|
30
|
+
# --- imc point related assets ---
|
31
|
+
@m.imc_point.reset
|
32
|
+
@m.imc_point.set :Base
|
33
|
+
@m.imc.must_equal @m.workspace.initial_marking_collection
|
34
|
+
@m.imc.wont_equal :Base
|
35
|
+
@m.imc_point.key.must_equal :Base
|
36
|
+
# --- ssc point related assets ---
|
37
|
+
@m.ssc_point.reset
|
38
|
+
@m.ssc_point.set :Base
|
39
|
+
@m.ssc.must_equal @m.workspace.simulation_settings_collection
|
40
|
+
@m.ssc.wont_equal :Base
|
41
|
+
@m.ssc_point.key.must_equal :Base
|
42
|
+
end
|
43
|
+
|
44
|
+
it "has basic selections" do
|
45
|
+
@m.net_selection.clear
|
46
|
+
@m.simulation_selection.clear
|
47
|
+
@m.cc_selection.clear
|
48
|
+
@m.imc_selection.clear
|
49
|
+
@m.ssc_selection.clear
|
50
|
+
@m.net_selection.get.must_equal []
|
51
|
+
@m.simulation_selection.get.must_equal []
|
52
|
+
@m.ssc_selection.get.must_equal []
|
53
|
+
@m.cc_selection.get.must_equal []
|
54
|
+
@m.imc_selection.get.must_equal []
|
55
|
+
end
|
56
|
+
|
57
|
+
it "presents some methods from workspace" do
|
58
|
+
[ @m.places, @m.transitions, @m.nets, @m.simulations ].map( &:size )
|
59
|
+
.must_equal [ 0, 0, 1, 0 ]
|
60
|
+
[ @m.clamp_collections,
|
61
|
+
@m.initial_marking_collections,
|
62
|
+
@m.simulation_settings_collections ].map( &:size ).must_equal [ 1, 1, 1 ]
|
63
|
+
[ @m.clamp_collections,
|
64
|
+
@m.initial_marking_collections,
|
65
|
+
@m.simulation_settings_collections ]
|
66
|
+
.map( &:keys ).must_equal [[:Base]] * 3
|
67
|
+
@m.pp.must_equal []
|
68
|
+
@m.tt.must_equal []
|
69
|
+
@m.nn.must_equal [ :Top ] # ie. :Top net spanning whole workspace
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "slightly more complicated case" do
|
73
|
+
before do
|
74
|
+
@p = @m.Place ɴ: "P", default_marking: 1
|
75
|
+
@q = @m.Place ɴ: "Q", default_marking: 1
|
76
|
+
@decay_t = @m.Transition ɴ: "Tp", s: { P: -1 }, rate: 0.1
|
77
|
+
@constant_flux_t = @m.Transition ɴ: "Tq", s: { Q: 1 }, rate: -> { 0.02 }
|
78
|
+
@m.initial_marking @p => 1.2
|
79
|
+
@m.initial_marking @q => 2
|
80
|
+
@m.set_step 0.01
|
81
|
+
@m.set_sampling 1
|
82
|
+
@m.set_time 30
|
83
|
+
end
|
84
|
+
|
85
|
+
it "works" do
|
86
|
+
@m.run!
|
87
|
+
@m.simulation.places.must_equal [ @p, @q ]
|
88
|
+
@m.simulation.transitions.must_equal [ @decay_t, @constant_flux_t ]
|
89
|
+
@m.simulation.SR_tt.must_equal [ :Tp, :Tq ]
|
90
|
+
@m.simulation.sparse_stoichiometry_vector( :Tp )
|
91
|
+
.must_equal Matrix.column_vector( [-1, 0] )
|
92
|
+
@m.simulation.stoichiometry_matrix_for( @m.transitions ).column_size
|
93
|
+
.must_equal 2
|
94
|
+
@m.simulation.stoichiometry_matrix_for( @m.transitions ).row_size
|
95
|
+
.must_equal 2
|
96
|
+
@m.simulation.flux_vector.row_size.must_equal 2
|
97
|
+
# @m.plot_recording
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
File without changes
|
data/test/net_test.rb
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require_relative '../lib/y_petri' # tested component itself
|
7
|
+
# require 'y_petri'
|
8
|
+
# require 'sy'
|
9
|
+
|
10
|
+
describe YPetri::Net do
|
11
|
+
before do
|
12
|
+
@tç = tç = Class.new YPetri::Transition
|
13
|
+
@pç = pç = Class.new YPetri::Place
|
14
|
+
@nç = nç = Class.new YPetri::Net
|
15
|
+
[ tç, pç, nç ].each { |ç|
|
16
|
+
ç.namespace!.class_exec {
|
17
|
+
define_method :Place do pç end
|
18
|
+
define_method :Transition do tç end
|
19
|
+
define_method :Net do nç end
|
20
|
+
private :Place, :Transition, :Net
|
21
|
+
}
|
22
|
+
}
|
23
|
+
@p1 = pç.new ɴ: "A", quantum: 0.1, marking: 1.1
|
24
|
+
@p2 = pç.new ɴ: "B", quantum: 0.1, marking: 2.2
|
25
|
+
@p3 = pç.new ɴ: "C", quantum: 0.1, marking: 3.3
|
26
|
+
@net = nç.new
|
27
|
+
[@p1, @p2, @p3].each { |p| @net.include_place! p }
|
28
|
+
@p_not_included = pç.new ɴ: "X", marking: 0
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "net of 3 places and no transitions" do
|
32
|
+
before do
|
33
|
+
@p1.m = 1.1
|
34
|
+
@p2.m = 2.2
|
35
|
+
@p3.m = 3.3
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should expose its elements" do
|
39
|
+
assert_equal [@p1, @p2, @p3], @net.places
|
40
|
+
assert_equal [:A, :B, :C], @net.pp
|
41
|
+
assert_equal [], @net.transitions
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should expose transition groups" do
|
45
|
+
assert_equal [], @net.transitions_with_rate
|
46
|
+
assert_equal [], @net.rateless_transitions
|
47
|
+
assert_equal [], @net.transitions_without_rate
|
48
|
+
assert_equal [], @net.stoichiometric_transitions
|
49
|
+
assert_equal [], @net.nonstoichiometric_transitions
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should tell its qualities" do
|
53
|
+
assert_equal true, @net.functional?
|
54
|
+
assert_equal true, @net.timed?
|
55
|
+
assert @net.include?( @p1 ) && !@net.include?( YPetri::Place.new )
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have 'standard equipment' methods" do
|
59
|
+
assert @net == @net.dup
|
60
|
+
assert @net.inspect.start_with? "#<Net:"
|
61
|
+
assert @net.include?( @p1 )
|
62
|
+
assert ! @net.include?( @p_not_included )
|
63
|
+
begin
|
64
|
+
@net.exclude_place! @p_not_included
|
65
|
+
@net.include_transition! YPetri::Transition.new( s: { @p_not_included => -1 } )
|
66
|
+
flunk "Attempt to include illegal transition fails to raise"
|
67
|
+
rescue; end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "plus 1 stoichio. transition with rate" do
|
71
|
+
before do
|
72
|
+
@t1 = @tç.new!( ɴ: "T1",
|
73
|
+
s: { @p1 => 1, @p2 => -1, @p3 => -1 },
|
74
|
+
rate: 0.01 )
|
75
|
+
@net.include_transition! @t1
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should expose its elements" do
|
79
|
+
assert_equal [@t1], @net.transitions
|
80
|
+
assert_equal [:T1], @net.tt
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should expose transition groups" do
|
84
|
+
assert_equal true, @t1.has_rate?
|
85
|
+
assert_equal [@t1], @net.transitions_with_rate
|
86
|
+
assert_equal [], @net.rateless_transitions
|
87
|
+
assert_equal [@t1], @net.stoichiometric_transitions
|
88
|
+
assert_equal [], @net.nonstoichiometric_transitions
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should tell its qualities" do
|
92
|
+
assert_equal true, @net.functional?
|
93
|
+
assert_equal true, @net.timed?
|
94
|
+
assert @net.include?( @t1 )
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should have #place & #transition for safe access to the said elements" do
|
98
|
+
@net.send( :place, @p1 ).must_equal @p1
|
99
|
+
@net.send( :transition, @t1 ).must_equal @t1
|
100
|
+
end
|
101
|
+
|
102
|
+
it "has #new_simulation & #new_timed_simulation constructors" do
|
103
|
+
@net.must_respond_to :new_simulation
|
104
|
+
@net.must_respond_to :new_timed_simulation
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should have other methods" do
|
108
|
+
assert_equal [1.1, 2.2, 3.3], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
|
109
|
+
assert_equal 2.2 * 3.3 * 0.01, @t1.rate_closure.call( @p2.marking, @p3.marking )
|
110
|
+
assert_equal [ @p2, @p3 ], @t1.domain
|
111
|
+
@t1.fire! 1
|
112
|
+
assert_equal [1.1726, 2.1274, 3.2274], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "plus 1 more nameless timeless functionless transition" do
|
116
|
+
before do
|
117
|
+
@t2 = @tç.new s: { @p2 => -1, @p3 => 1 }
|
118
|
+
@net.include_transition! @t2
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should expose its elements" do
|
122
|
+
assert_equal [@t1, @t2], @net.transitions
|
123
|
+
assert_equal [:T1, nil], @net.tt
|
124
|
+
@net.tap{ |n| n.exclude_transition! @t1 }.exclude_transition! @t2
|
125
|
+
@net.tap{ |n| n.exclude_place! @p3 }.pp.must_equal [:A, :B]
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should expose transition groups" do
|
129
|
+
assert_equal [], @net.timeless_nonstoichiometric_transitions
|
130
|
+
assert_equal [], @net.timeless_nonstoichiometric_tt
|
131
|
+
assert_equal [@t2], @net.timeless_stoichiometric_transitions
|
132
|
+
assert_equal [nil], @net.timeless_stoichiometric_tt
|
133
|
+
assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
|
134
|
+
assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
|
135
|
+
assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
|
136
|
+
assert_equal [], @net.timed_rateless_nonstoichiometric_tt
|
137
|
+
assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
|
138
|
+
assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
|
139
|
+
assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
|
140
|
+
assert_equal [], @net.timed_rateless_nonstoichiometric_tt
|
141
|
+
assert_equal [], @net.nonstoichiometric_transitions_with_rate
|
142
|
+
assert_equal [], @net.nonstoichiometric_tt_with_rate
|
143
|
+
assert_equal [@t1], @net.stoichiometric_transitions_with_rate
|
144
|
+
assert_equal [:T1], @net.stoichiometric_tt_with_rate
|
145
|
+
assert_equal [], @net.assignment_transitions
|
146
|
+
assert_equal [], @net.assignment_tt
|
147
|
+
assert_equal [@t1, @t2], @net.stoichiometric_transitions
|
148
|
+
assert_equal [:T1, nil], @net.stoichiometric_tt
|
149
|
+
assert_equal [], @net.nonstoichiometric_transitions
|
150
|
+
assert_equal [], @net.nonstoichiometric_tt
|
151
|
+
assert_equal [@t1], @net.timed_transitions
|
152
|
+
assert_equal [:T1], @net.timed_tt
|
153
|
+
assert_equal [@t2], @net.timeless_transitions
|
154
|
+
assert_equal [nil], @net.timeless_tt
|
155
|
+
assert_equal [@t1], @net.transitions_with_rate
|
156
|
+
assert_equal [:T1], @net.tt_with_rate
|
157
|
+
assert_equal [@t2], @net.rateless_transitions
|
158
|
+
assert_equal [nil], @net.rateless_tt
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should tell its qualities" do
|
162
|
+
assert_equal false, @net.functional?
|
163
|
+
assert_equal false, @net.timed?
|
164
|
+
@net.exclude_transition! @t2
|
165
|
+
assert_equal true, @net.functional?
|
166
|
+
assert_equal true, @net.timed?
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
data/test/place_test.rb
CHANGED
@@ -66,18 +66,19 @@ describe YPetri::Place do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should have guard mechanics" do
|
69
|
-
@p.guards.size.must_equal
|
69
|
+
@p.guards.size.must_equal 3 # working automatic guard construction
|
70
70
|
g1, g2 = @p.guards
|
71
|
-
g1.assertion.
|
72
|
-
|
71
|
+
[g1.assertion, g2.assertion].tap { |u, v|
|
72
|
+
assert u.include?( "number" ) || u.include?( "Numeric" )
|
73
|
+
assert v.include?( "complex" ) || v.include?( "Complex" )
|
74
|
+
}
|
73
75
|
begin; g1.validate 11.1; g2.validate 11.1; @p.guard.( 11.1 ); :nothing_raised
|
74
76
|
rescue; :error end.must_equal :nothing_raised
|
75
77
|
-> { g2.validate Complex( 1, 1 ) }.must_raise YPetri::GuardError
|
76
78
|
@p.marking "must be in 0..10" do |m| fail unless ( 0..10 ) === m end
|
77
|
-
@p.guards.size.must_equal
|
79
|
+
@p.guards.size.must_equal 4
|
78
80
|
g = @p.federated_guard_closure
|
79
81
|
-> { g.( 11.1 ) }.must_raise YPetri::GuardError
|
80
|
-
@p.marking = -1.11
|
81
|
-
-> { @p.guard! }.must_raise YPetri::GuardError
|
82
|
+
-> { @p.marking = -1.11 }.must_raise YPetri::GuardError
|
82
83
|
end
|
83
84
|
end
|