y_petri 2.0.15 → 2.1.3
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/{manipulator → agent}/hash_key_pointer.rb +2 -2
- data/lib/y_petri/agent/petri_net_related.rb +115 -0
- data/lib/y_petri/{manipulator → agent}/selection.rb +2 -1
- data/lib/y_petri/{manipulator/simulation_related_methods.rb → agent/simulation_related.rb} +93 -110
- data/lib/y_petri/agent.rb +22 -0
- data/lib/y_petri/core/timed/euler.rb +20 -0
- data/lib/y_petri/core/timed/pseudo_euler.rb +31 -0
- data/lib/y_petri/core/timed/quasi_euler.rb +23 -0
- data/lib/y_petri/core/timed.rb +70 -0
- data/lib/y_petri/core/timeless/pseudo_euler.rb +20 -0
- data/lib/y_petri/core/timeless.rb +12 -0
- data/lib/y_petri/core.rb +100 -0
- data/lib/y_petri/dsl.rb +66 -0
- data/lib/y_petri/fixed_assets.rb +7 -0
- data/lib/y_petri/net/element_access.rb +239 -0
- data/lib/y_petri/net/state/feature/delta.rb +88 -0
- data/lib/y_petri/net/state/feature/firing.rb +57 -0
- data/lib/y_petri/net/state/feature/flux.rb +58 -0
- data/lib/y_petri/net/state/feature/gradient.rb +75 -0
- data/lib/y_petri/net/state/feature/marking.rb +62 -0
- data/lib/y_petri/net/state/feature.rb +79 -0
- data/lib/y_petri/net/state/features/dataset.rb +135 -0
- data/lib/y_petri/net/state/features/record.rb +50 -0
- data/lib/y_petri/net/state/features.rb +126 -0
- data/lib/y_petri/net/state.rb +121 -0
- data/lib/y_petri/net/timed.rb +8 -0
- data/lib/y_petri/net/visualization.rb +3 -3
- data/lib/y_petri/net.rb +73 -77
- data/lib/y_petri/place.rb +8 -3
- data/lib/y_petri/simulation/dependency.rb +107 -0
- data/lib/y_petri/simulation/element_representation.rb +20 -0
- data/lib/y_petri/simulation/elements/access.rb +57 -0
- data/lib/y_petri/simulation/elements.rb +45 -0
- data/lib/y_petri/simulation/feature_set.rb +21 -0
- data/lib/y_petri/simulation/initial_marking/access.rb +55 -0
- data/lib/y_petri/simulation/initial_marking.rb +15 -0
- data/lib/y_petri/simulation/marking_clamps/access.rb +34 -0
- data/lib/y_petri/simulation/marking_clamps.rb +18 -0
- data/lib/y_petri/simulation/marking_vector/access.rb +106 -0
- data/lib/y_petri/simulation/marking_vector.rb +156 -0
- data/lib/y_petri/simulation/matrix.rb +64 -0
- data/lib/y_petri/simulation/place_mapping.rb +62 -0
- data/lib/y_petri/simulation/place_representation.rb +74 -0
- data/lib/y_petri/simulation/places/access.rb +121 -0
- data/lib/y_petri/simulation/places/clamped.rb +8 -0
- data/lib/y_petri/simulation/places/free.rb +8 -0
- data/lib/y_petri/simulation/places/types.rb +25 -0
- data/lib/y_petri/simulation/places.rb +41 -0
- data/lib/y_petri/simulation/recorder.rb +54 -0
- data/lib/y_petri/simulation/timed/recorder.rb +53 -0
- data/lib/y_petri/simulation/timed.rb +161 -261
- data/lib/y_petri/simulation/timeless/recorder.rb +25 -0
- data/lib/y_petri/simulation/timeless.rb +35 -0
- data/lib/y_petri/simulation/transition_representation/A.rb +58 -0
- data/lib/y_petri/simulation/transition_representation/S.rb +45 -0
- data/lib/y_petri/simulation/transition_representation/T.rb +80 -0
- data/lib/y_petri/simulation/transition_representation/TS.rb +46 -0
- data/lib/y_petri/simulation/transition_representation/Ts.rb +32 -0
- data/lib/y_petri/simulation/transition_representation/a.rb +30 -0
- data/lib/y_petri/simulation/transition_representation/s.rb +29 -0
- data/lib/y_petri/simulation/transition_representation/t.rb +37 -0
- data/lib/y_petri/simulation/transition_representation/tS.rb +38 -0
- data/lib/y_petri/simulation/transition_representation/ts.rb +32 -0
- data/lib/y_petri/simulation/transition_representation/types.rb +62 -0
- data/lib/y_petri/simulation/transition_representation.rb +79 -0
- data/lib/y_petri/simulation/transitions/A.rb +40 -0
- data/lib/y_petri/simulation/transitions/S.rb +24 -0
- data/lib/y_petri/simulation/transitions/T.rb +34 -0
- data/lib/y_petri/simulation/transitions/TS.rb +57 -0
- data/lib/y_petri/simulation/transitions/Ts.rb +60 -0
- data/lib/y_petri/simulation/transitions/a.rb +8 -0
- data/lib/y_petri/simulation/transitions/access.rb +186 -0
- data/lib/y_petri/simulation/transitions/s.rb +9 -0
- data/lib/y_petri/simulation/transitions/t.rb +22 -0
- data/lib/y_petri/simulation/transitions/tS.rb +55 -0
- data/lib/y_petri/simulation/transitions/ts.rb +58 -0
- data/lib/y_petri/simulation/transitions/types.rb +98 -0
- data/lib/y_petri/simulation/transitions.rb +21 -0
- data/lib/y_petri/simulation.rb +176 -781
- data/lib/y_petri/transition/assignment.rb +7 -5
- data/lib/y_petri/transition/construction.rb +119 -187
- data/lib/y_petri/transition/init.rb +311 -0
- data/lib/y_petri/transition/ordinary_timeless.rb +8 -6
- data/lib/y_petri/transition/timed.rb +11 -18
- data/lib/y_petri/transition.rb +104 -132
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri/world/dependency.rb +40 -0
- data/lib/y_petri/world/petri_net_related.rb +61 -0
- data/lib/y_petri/{workspace/simulation_related_methods.rb → world/simulation_related.rb} +42 -49
- data/lib/y_petri/world.rb +27 -0
- data/lib/y_petri.rb +47 -99
- data/test/{manipulator_test.rb → agent_test.rb} +19 -17
- data/{lib/y_petri → test/examples}/demonstrator.rb +0 -0
- data/{lib/y_petri → test/examples}/demonstrator_2.rb +1 -0
- data/{lib/y_petri → test/examples}/demonstrator_3.rb +0 -0
- data/{lib/y_petri → test/examples}/demonstrator_4.rb +0 -0
- data/test/examples/example_2.rb +16 -0
- data/test/{manual_examples.rb → examples/manual_examples.rb} +0 -0
- data/test/net_test.rb +126 -121
- data/test/place_test.rb +1 -1
- data/test/sim_test +565 -0
- data/test/simulation_test.rb +338 -264
- data/test/transition_test.rb +77 -174
- data/test/world_mock.rb +12 -0
- data/test/{workspace_test.rb → world_test.rb} +19 -20
- data/test/y_petri_test.rb +4 -5
- metadata +101 -26
- data/lib/y_petri/dependency_injection.rb +0 -45
- data/lib/y_petri/manipulator/petri_net_related_methods.rb +0 -74
- data/lib/y_petri/manipulator.rb +0 -20
- data/lib/y_petri/net/selections.rb +0 -209
- data/lib/y_petri/simulation/collections.rb +0 -460
- data/lib/y_petri/workspace/parametrized_subclassing.rb +0 -22
- data/lib/y_petri/workspace/petri_net_related_methods.rb +0 -88
- data/lib/y_petri/workspace.rb +0 -16
- data/test/timed_simulation_test.rb +0 -153
@@ -19,12 +19,14 @@ module YPetri::Transition::Assignment
|
|
19
19
|
# Assigns the action closure result to the codomain, regardless of cocking.
|
20
20
|
#
|
21
21
|
def fire!
|
22
|
-
|
22
|
+
consciously "to #fire!" do
|
23
23
|
act = note "action", is: Array( action )
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
msg = "Wrong output arity of the action closure of #{self}"
|
25
|
+
fail TypeError, msg if act.size != codomain.size
|
26
|
+
codomain.each_with_index { |p, i|
|
27
|
+
note "assigning action element no. #{i} to #{p}"
|
28
|
+
p.marking = note "marking to assign", is: act.fetch( i )
|
29
|
+
}
|
28
30
|
end
|
29
31
|
return nil
|
30
32
|
end
|
@@ -14,7 +14,29 @@ class YPetri::Transition
|
|
14
14
|
# best explained by examples -- let us have 3 places A, B, C, for whe we will
|
15
15
|
# create different kinds of transitions:
|
16
16
|
#
|
17
|
+
#
|
18
|
+
# ==== TS (timed stoichiometric)
|
19
|
+
#
|
20
|
+
# Rate closure and stoichiometry has to be supplied. Rate closure arity should
|
21
|
+
# correspond to the domain size. Return arity should be 1 (to be multiplied by
|
22
|
+
# the stoichiometry vector, as in all other stoichiometric transitions).
|
23
|
+
#
|
24
|
+
# Transition.new stoichiometry: { A: -1, B: 1 },
|
25
|
+
# rate: -> a { a * 0.5 }
|
26
|
+
#
|
27
|
+
#
|
28
|
+
# ==== Ts (timed nonstoichiometric)
|
29
|
+
#
|
30
|
+
# Rate closure has to be supplied, whose arity should match the domain, and
|
31
|
+
# output arity codomain.
|
32
|
+
#
|
33
|
+
# ==== tS (timeless stoichiometric)
|
34
|
+
#
|
35
|
+
# Stoichiometry has to be supplied, action closure is optional. If supplied,
|
36
|
+
# its return arity should be 1 (to be multiplied by the stoichiometry vector).
|
37
|
+
#
|
17
38
|
# ==== ts transitions (timeless nonstoichiometric)
|
39
|
+
#
|
18
40
|
# Action closure is expected with return arity equal to the codomain size:
|
19
41
|
#
|
20
42
|
# Transition.new upstream_arcs: [A, C], downstream_arcs: [A, B],
|
@@ -23,43 +45,8 @@ class YPetri::Transition
|
|
23
45
|
# else [1, 0] end
|
24
46
|
# }
|
25
47
|
#
|
26
|
-
|
27
|
-
|
28
|
-
#
|
29
|
-
# ==== tS transitions (timeless stoichiometric)
|
30
|
-
# Stochiometry has to be supplied, action closure is optional. If supplied,
|
31
|
-
# its return arity should be 1 (to be multiplied by the stochiometry vector).
|
32
|
-
#
|
33
|
-
# If no action closure is given, a _functionless_ transition will be
|
34
|
-
# constructed, with action closure == 1 * stoichiometry vector.
|
35
|
-
#
|
36
|
-
# ==== Tsr transitions (timed rateless nonstoichiometric)
|
37
|
-
# Action closure has to be supplied, whose first argument is Δt, and the
|
38
|
-
# remaining ones correspond to the domain size. Return arity of this closure
|
39
|
-
# should, in turn, correspond to the codomain size.
|
40
|
-
#
|
41
|
-
# ==== TSr transitions (timed rateless stoichiometric)
|
42
|
-
# Action closure has to be supplied, whose first argument is Δt, and the
|
43
|
-
# remaining ones correspond to the domain size. Return arity of this closure
|
44
|
-
# should be 1 (to be multiplied by the stoichiometry vector).
|
45
|
-
#
|
46
|
-
# ==== sR transitions (nonstoichiometric transitions with rate)
|
47
|
-
# Rate closure has to be supplied, whose arity should correspond to the domain
|
48
|
-
# size (Δt argument is not needed). Return arity of this should, in turn,
|
49
|
-
# correspond to the codomain size -- it represents this transition's
|
50
|
-
# contribution to the rate of change of marking of the codomain places.
|
51
|
-
#
|
52
|
-
# ==== SR transitions (stoichiometric transitions with rate)
|
53
|
-
#
|
54
|
-
# Rate closure and stoichiometry has to be supplied. Rate closure arity should
|
55
|
-
# correspond to the domain size. Return arity should be 1 (to be multiplied by
|
56
|
-
# the stoichiometry vector, as in all other stoichiometric transitions).
|
57
|
-
#
|
58
|
-
# Transition.new stoichiometry: { A: -1, B: 1 },
|
59
|
-
# rate: -> a { a * 0.5 }
|
60
|
-
#
|
61
|
-
def initialize *args
|
62
|
-
check_in_arguments *args # the big work of checking in args
|
48
|
+
def initialize *args, &block
|
49
|
+
check_in_arguments *args, &block # the big job
|
63
50
|
extend timed? ? Timed : assignment? ? Assignment : OrdinaryTimeless
|
64
51
|
inform_upstream_places # that they have been connected
|
65
52
|
inform_downstream_places # that they have been connected
|
@@ -73,52 +60,55 @@ class YPetri::Transition
|
|
73
60
|
# else then defining the duck type of the input argument collection.
|
74
61
|
# TypeError is therefore raised if invalid collection has been supplied.
|
75
62
|
#
|
76
|
-
def check_in_arguments
|
77
|
-
|
78
|
-
|
63
|
+
def check_in_arguments **nn, &block
|
64
|
+
nn.update( action: block ) if block_given?
|
65
|
+
nn.may_have :domain, syn!: [ :domain_arcs, :domain_places,
|
66
|
+
:upstream, :upstream_arcs, :upstream_places ]
|
67
|
+
nn.may_have :codomain, syn!: [ :codomain_arcs, :codomain_places,
|
79
68
|
:downstream,
|
80
69
|
:downstream_arcs, :downstream_places,
|
81
70
|
:action_arcs ]
|
82
|
-
|
83
|
-
:upstream, :upstream_arcs, :upstream_places ]
|
84
|
-
oo.may_have :rate, syn!: [ :rate_closure, :propensity,
|
71
|
+
nn.may_have :rate, syn!: [ :rate_closure, :propensity,
|
85
72
|
:propensity_closure ]
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
73
|
+
nn.may_have :action, syn!: :action_closure
|
74
|
+
nn.may_have :stoichiometry, syn!: [ :stoichio, :s ]
|
75
|
+
nn.may_have :domain_guard
|
76
|
+
nn.may_have :codomain_guard
|
90
77
|
|
91
|
-
|
78
|
+
# If the rate was given, the transition is timed:
|
79
|
+
@timed = nn.has? :rate
|
92
80
|
|
93
|
-
#
|
94
|
-
@stoichiometric =
|
81
|
+
# If stoichiometry was given, the transition is stoichiometric:
|
82
|
+
@stoichiometric = nn.has? :stoichiometry
|
95
83
|
|
96
|
-
#
|
84
|
+
# Downstream description involves the codomain, and the stochiometry
|
85
|
+
# (for stoichiometric transitions only):
|
97
86
|
if stoichiometric? then
|
98
|
-
@codomain, @stoichiometry =
|
99
|
-
else
|
100
|
-
@codomain =
|
87
|
+
@codomain, @stoichiometry = __downstream_for_S__( **nn )
|
88
|
+
else
|
89
|
+
@codomain = __downstream_for_s__( **nn )
|
101
90
|
end
|
102
91
|
|
103
|
-
#
|
104
|
-
|
92
|
+
# Check in the domain first, :missing symbol may be returned if the user
|
93
|
+
# has not supplied the domaing (the constructor will attempt to guessf it
|
94
|
+
# automatically).
|
95
|
+
@domain = __domain__( **nn )
|
105
96
|
|
106
|
-
#
|
107
|
-
|
108
|
-
|
109
|
-
|
97
|
+
# Upstream description involves the domain and the rate/action closure.
|
98
|
+
# Also, :missing domain is taken care of here.
|
99
|
+
if timed? then
|
100
|
+
@domain, @rate_closure, @functional = __upstream_for_T__( **nn )
|
110
101
|
else
|
111
|
-
@domain, @action_closure, @
|
112
|
-
check_in_upstream_description_for_r( oo, &block )
|
102
|
+
@domain, @action_closure, @functional = __upstream_for_t__( **nn )
|
113
103
|
end
|
114
104
|
|
115
|
-
#
|
116
|
-
@assignment_action =
|
105
|
+
# Optional assignment action:
|
106
|
+
@assignment_action = __assignment_action__( **nn )
|
107
|
+
|
108
|
+
# Optional type guards for domain / codomain:
|
109
|
+
@domain_guard, @codomain_guard = __guards__( **nn )
|
110
|
+
end
|
117
111
|
|
118
|
-
# optional type guards for domain / codomain:
|
119
|
-
@domain_guard, @codomain_guard = check_in_guards( oo )
|
120
|
-
end # def check_in_arguments
|
121
|
-
|
122
112
|
# Validates that the supplied collection consists only of places of
|
123
113
|
# correct type. Second optional argument customizes the error message.
|
124
114
|
#
|
@@ -134,10 +124,10 @@ class YPetri::Transition
|
|
134
124
|
coll == coll.uniq
|
135
125
|
end
|
136
126
|
end
|
137
|
-
|
127
|
+
|
138
128
|
# Private method, part of #initialize argument checking-in.
|
139
129
|
#
|
140
|
-
def
|
130
|
+
def __domain__( **oo )
|
141
131
|
if oo.has? :domain then
|
142
132
|
sanitize_place_collection( oo[:domain], "supplied domain" )
|
143
133
|
else
|
@@ -150,131 +140,73 @@ class YPetri::Transition
|
|
150
140
|
# Barring the caller's error, missing domain can mean:
|
151
141
|
# 1. empty domain
|
152
142
|
# 2. domain == codomain
|
153
|
-
# This will be figured later by rate/action closure arity
|
143
|
+
# This will be figured later by the rate/action closure arity.
|
154
144
|
end
|
155
145
|
end
|
156
146
|
end
|
157
147
|
|
158
|
-
# Private method, part of the init process
|
159
|
-
# care for missing domain
|
148
|
+
# Private method, part of the init process for timed transitions. Also takes
|
149
|
+
# care for :missing domain, if :missing.
|
160
150
|
#
|
161
|
-
def
|
151
|
+
def __upstream_for_T__( **oo )
|
162
152
|
_domain = domain # this method may modify domain
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
# but if it was supplied explicitly, it must be empty.
|
190
|
-
fail TypeError, "Rate is a number, but non-empty domain " +
|
191
|
-
"was supplied!" unless domain.empty? if oo.has?( :domain )
|
192
|
-
-> { ra }
|
193
|
-
end
|
194
|
-
end
|
195
|
-
# R transitions are implicitly timed
|
196
|
-
_timed = true
|
197
|
-
# check against colliding :timed argument
|
198
|
-
oo[:timed].tE :timed, "not be false if rate given" if oo.has? :timed
|
199
|
-
# R transitions are implicitly functional
|
200
|
-
_functional = true
|
201
|
-
return _domain, rate_λ, _timed, _functional
|
153
|
+
_functional = true # T transitions are implicitly functional
|
154
|
+
fail ArgumentError, "Rate and action collision!" if oo.has? :action
|
155
|
+
# Let's figure the rate closure now.
|
156
|
+
λ = oo[:rate]
|
157
|
+
if λ.is_a? Proc then
|
158
|
+
# Solve :missing domain:
|
159
|
+
_domain = λ.arity == 0 ? [] : codomain if domain == :missing
|
160
|
+
# Validate arity:
|
161
|
+
msg = "Rate closure arity (#{λ.arity}) > domain (#{domain.size})!"
|
162
|
+
fail TypeError, msg if λ.arity.abs > domain.size
|
163
|
+
else # not a Proc, must guess user's intent
|
164
|
+
λ = if stoichiometric? then # standard mass action
|
165
|
+
msg = "With numeric rate, domain must not be given!"
|
166
|
+
fail TypeError, msg if oo.has? :domain
|
167
|
+
__standard_mass_action__( λ )
|
168
|
+
else # constant closure
|
169
|
+
msg = "With numeric rate and no stoichio., codomain size must be 1!"
|
170
|
+
fail TypeError, msg unless codomain.size == 1
|
171
|
+
_domain = [] if domain == :missing # Missing domain is OK here,
|
172
|
+
# But in case it was supplied explicitly, it must be empty.
|
173
|
+
msg = "Rate is a number, but domain is non-empty!"
|
174
|
+
fail TypeError, msg unless domain.empty? if oo.has? :domain
|
175
|
+
-> { λ } # the closure itself
|
176
|
+
end
|
177
|
+
end
|
178
|
+
return _domain, λ, _functional
|
202
179
|
end
|
203
180
|
|
204
181
|
# Private method, part of the init process when :rate is not given. Also
|
205
182
|
# takes care for missing domain (@domain == :missing).
|
206
183
|
#
|
207
|
-
def
|
208
|
-
_domain = domain
|
184
|
+
def __upstream_for_t__( **oo )
|
185
|
+
_domain = domain # this method may modify domain
|
209
186
|
_functional = true
|
210
|
-
# Was action
|
187
|
+
# Was action given explicitly?
|
211
188
|
if oo.has? :action then
|
212
|
-
|
213
|
-
|
214
|
-
if
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
[] # user meant empty domain
|
220
|
-
else
|
221
|
-
codomain # user meant domain same as codomain
|
222
|
-
end
|
223
|
-
else # domain not missing
|
224
|
-
fail TypeError, "Rate closure arity (#{rate_arg.arity}) > domain " +
|
225
|
-
"size (#{domain.size})!" if action_λ.arity.abs > domain.size
|
226
|
-
end
|
227
|
-
else # :timed argument not supplied
|
228
|
-
if domain == :missing then
|
229
|
-
# If no domain was supplied, there is no way to reasonably figure
|
230
|
-
# out the user's intent, except when arity is 0:
|
231
|
-
_domain = case action_λ.arity
|
232
|
-
when 0 then
|
233
|
-
_timed = false
|
234
|
-
[] # empty domain is implied
|
235
|
-
else # no deduction of user intent possible
|
236
|
-
fail ArgumentError, "Too much ambiguity: Rateless " +
|
237
|
-
"transition with neither domain nor timedness given."
|
238
|
-
end
|
239
|
-
else # domain not missing
|
240
|
-
# Even if the user did not bother to inform us explicitly about
|
241
|
-
# timedness, we can use closure arity as a clue. If it equals the
|
242
|
-
# domain size, leaving no room for Δtime argument, the user intent
|
243
|
-
# was to create timeless transition. If it equals domain size + 1,
|
244
|
-
# theu user intended to create a timed transition.
|
245
|
-
_timed = case action_λ.arity
|
246
|
-
when domain.size then false
|
247
|
-
when domain.size + 1 then true
|
248
|
-
else # no deduction of user intent possible
|
249
|
-
fail ArgumentError, "Timedness was not specified, and " +
|
250
|
-
"action closure arity (#{action_λ.arity}) does not " +
|
251
|
-
"give a clear hint on it!"
|
252
|
-
end
|
253
|
-
end
|
189
|
+
λ = oo[:action].aT_is_a Proc, "supplied action named argument"
|
190
|
+
# Time to worry about the domain_missing, guess the user's intention:
|
191
|
+
if domain == :missing then
|
192
|
+
_domain = ( λ.arity == 0 ? [] : codomain )
|
193
|
+
else
|
194
|
+
msg = "Action closure arity (#{λ.arity}) > domain size (#{domain.size})!"
|
195
|
+
fail TypeError, msg if λ.arity.abs > domain.size
|
254
196
|
end
|
255
|
-
else #
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
# The transition is then required to be stoichiometric and timeless.
|
262
|
-
# Domain will be required empty.
|
263
|
-
fail ArgumentError, "Stoichiometry is compulsory, if no rate/action " +
|
264
|
-
"was supplied." unless stoichiometric?
|
265
|
-
# With this, we can drop worries about missing domain.
|
266
|
-
fail ArgumentError, "When no rate/propensity or action is supplied, " +
|
267
|
-
"the transition cannot be timed." if oo[:timed] if oo.has? :timed
|
268
|
-
_timed = false
|
269
|
-
_domain = []
|
270
|
-
_functional = false # the transition is considered functionless
|
197
|
+
else # functionless transition
|
198
|
+
_functional = false
|
199
|
+
λ = -> { 1 }
|
200
|
+
msg = "Stoichiometry is compulsory, if no rate/action was supplied."
|
201
|
+
fail ArgumentError, msg unless S?
|
202
|
+
_domain = [] # in any case, the domain is empty
|
271
203
|
end
|
272
|
-
return _domain,
|
204
|
+
return _domain, λ, _functional
|
273
205
|
end
|
274
206
|
|
275
207
|
# Default rate closure for SR transitions whose rate is hinted as a number.
|
276
208
|
#
|
277
|
-
def
|
209
|
+
def __standard_mass_action__( num )
|
278
210
|
# assume standard mass-action law
|
279
211
|
nonpositive_coeffs = stoichiometry.select { |coeff| coeff <= 0 }
|
280
212
|
# the closure takes markings of the domain as its arguments
|
@@ -294,21 +226,21 @@ class YPetri::Transition
|
|
294
226
|
# Private method, checking in downstream specification from the argument
|
295
227
|
# field for stoichiometric transition.
|
296
228
|
#
|
297
|
-
def
|
229
|
+
def __downstream_for_S__( **oo )
|
298
230
|
codomain, stoichio =
|
299
231
|
case oo[:stoichiometry]
|
300
232
|
when Hash then
|
301
233
|
# contains pairs { codomain place => stoichiometry coefficient }
|
302
|
-
|
303
|
-
|
234
|
+
msg = "With hash-type stoichiometry, :codomain must not be given!"
|
235
|
+
fail ArgumentError, msg if oo.has? :codomain
|
304
236
|
oo[:stoichiometry].each_with_object [[], []] do |(cd_pl, coeff), memo|
|
305
|
-
|
306
|
-
|
307
|
-
|
237
|
+
memo[0] << cd_pl
|
238
|
+
memo[1] << coeff
|
239
|
+
end
|
308
240
|
else
|
309
241
|
# array of stoichiometry coefficients
|
310
|
-
|
311
|
-
|
242
|
+
msg = "With array-type stoichiometry, :codomain must be given!"
|
243
|
+
fail ArgumentError unless oo.has? :codomain
|
312
244
|
[ oo[:codomain], Array( oo[:stoichiometry] ) ]
|
313
245
|
end
|
314
246
|
# enforce that stoichiometry is a collection of numbers
|
@@ -319,7 +251,7 @@ class YPetri::Transition
|
|
319
251
|
# Private method, checking in downstream specification from the argument
|
320
252
|
# field for nonstoichiometric transition.
|
321
253
|
#
|
322
|
-
def
|
254
|
+
def __downstream_for_s__( **oo )
|
323
255
|
# codomain must be explicitly given - no way around it:
|
324
256
|
fail ArgumentError, "For non-stoichiometric transitions, :codomain " +
|
325
257
|
"argument is compulsory." unless oo.has? :codomain
|
@@ -328,7 +260,7 @@ class YPetri::Transition
|
|
328
260
|
|
329
261
|
# Private method, part of #initialize argument checking-in.
|
330
262
|
#
|
331
|
-
def
|
263
|
+
def __assignment_action__( **oo )
|
332
264
|
if oo.has? :assignment_action, syn!: [ :assignment, :assign, :A ] then
|
333
265
|
if timed? then
|
334
266
|
false.tap do
|
@@ -341,7 +273,7 @@ class YPetri::Transition
|
|
341
273
|
|
342
274
|
# Private method, part of #initialize argument checking-in
|
343
275
|
#
|
344
|
-
def
|
276
|
+
def __guards__( **oo )
|
345
277
|
if oo.has? :domain_guard then
|
346
278
|
oo[:domain_guard].aT_is_a Proc, "supplied domain guard"
|
347
279
|
else
|