Class: YPetri::Transition
- Inherits:
-
Object
- Object
- YPetri::Transition
- Defined in:
- lib/y_petri/transition.rb
Overview
Transitions – little boxes in Petri net drawings – represent atomic operations on the Petri net’s marking.
Domain and codomin
Each transition has a domain (upstream places) and codomain (downstream places). Upstream places are those, whose marking affects the transition. Downstream places are those affected by the transition.
Action and action vector
Every transition action – the operation it represents. The action of non-stoichiometric transitions is directly specified by its action closure (whose output arity should match the codomain size.) For stoichiometric transitions, the action closure result must be multiplied by the transition’s stoichiometry vector. Timed transitions have rate closure. Their action can be obtained by multiplying their rate by Δtime.
Rate
In YPetri, marking is always considered a discrete number of tokens (as
-
Petri has handed it down to us). Usefulness of floating point numbers
-
in representing larger amounts of tokens is acknowledged, but seen as a pragmatic measure, an implementation detail. There is no class distinction between discrete vs. continuous places / transitions. Often we see continuous transitions with their flux (flow rate) ditinguished from discrete stochastic transitions with their propensity (likelihood of firing in a time unit). In YPetri, flux and propensity are unified under a single term rate, and the choice between discrete and stochastic computation is a concern of the simulation, not of the object model.
Basic transition types
There are 4 basic transition types in YPetri:
-
TS – timed stoichiometric
-
tS – timeless stoichiometric
-
Ts – timed nonstoichiometric
-
ts – timeless nonstoichiometric
They arise by combining 2 qualities:
-
Timedness: timed (T) / timeless (t)
-
Stoichiometricity: stoichiometric (S) / nonstoichiometric (s)
Timedness
-
Timed transitions have rate closure, whose result is to be multiplied by Δtime.
-
Timeless transitions have action closure, whose result does not need to be multiplied by time.
Summary: Having vs. not having rate distinguishes the need to multiply the closure result by Δ time.
Stoichiometricity
-
TS transitions – rate vector = rate * stoichiometry vector
-
tS transitions – action vector = action * stoichiometry vector
-
Ts transitions – rate vector = rate closure result
-
ts transitions – action vector = action closure result
Summary: stoichiometricity distinguishes the need to multiply the rate/action closure result by stoichiometry.
Assignment action
Assignment transitions (_A_ transitions) are special transitions, that replace the codomain marking rather than modifying it – they assign new marking to their codomain, like we are used to from spreadsheets. Technically, this behavior is easily achievable with normal ts transitions, so the existence of separate A transitions is just a convenience, not a new type of a transition in the mathematical sense.
Functional / functionless transitions
Other Petri net implementation often distinguies between “ordinary” (vanilla as per C. A. Petri) and functional transitions, whose operation is governed by a function. In YPetri, transitions are generally functional, but there remains a possibility of creating vanilla (functionless) transitions by not specifying any rate / action, while specifying the stoichiometry. Action closure as per C. A. Petri is automatically constructed for these.
Defined Under Namespace
Modules: Arcs, Cocking, ConstructionConvenience, TypeInformation, Type_A, Type_T, Type_t, Types, UsableWithoutWorld
Constant Summary collapse
- TYPES =
{ T: "timed", t: "timeless", S: "stoichiometric", s: "non-stoichiometric", A: "assignment", a: "non-assignment", TS: "timed stoichiometric", tS: "timeless stoichiometric", Ts: "timed nonstoichiometric", ts: "timeless nonstoichiometric" }
Instance Attribute Summary collapse
-
#action_closure ⇒ Object
(also: #action)
readonly
For rateless transition, action closure must be present.
-
#codomain ⇒ Object
(also: #codomain_arcs, #codomain_places, #downstream, #downstream_arcs, #downstream_places, #action_arcs)
readonly
Codomain, ‘downstream arcs’, or ‘action arcs’, is a collection of places, whose marking is directly changed by this transition’s firing.
-
#domain ⇒ Object
(also: #domain_arcs, #domain_places, #upstream, #upstream_arcs, #upstream_places)
readonly
Domain, or ‘upstream arcs’, is a collection of places, whose marking directly affects the transition’s action.
-
#rate_closure ⇒ Object
(also: #rate, #flux_closure, #flux, #propensity_closure, #propensity)
readonly
In YPetri, rate is a unifying term for both flux and propensity, both of which are treated as aliases of rate.
-
#stoichiometry ⇒ Object
readonly
Stoichiometry (implies that the transition is stoichiometric).
Instance Method Summary collapse
-
#initialize(*args, &block) ⇒ Transition
constructor
Transition class represents many different kinds of Petri net transitions.
-
#inspect ⇒ Object
Inspect string for a transition.
- #place(id) ⇒ Object
-
#s ⇒ Object
Stoichiometry as a hash of pairs: { codomain_place_name_symbol => stoichiometric_coefficient }.
-
#stoichio ⇒ Object
Stoichiometry as a hash of pairs: { codomain_place_instance => stoichiometric_coefficient }.
-
#to_s ⇒ Object
Conversion to a string.
- #transition(id) ⇒ Object
-
#zero_action ⇒ Object
Zero action.
Constructor Details
#initialize(*args, &block) ⇒ Transition
Transition class represents many different kinds of Petri net transitions. It makes the constructor syntax a bit more polymorphic. The type of the transition to construct is mostly inferred from the constructor arguments.
Mandatorily, the constructor will always need a way to determine the domain (upstream arcs) and codomain (downstream arcs) of the transition. Also, the constructor must have a way to determine the transition’s action. This is best explained by examples – let us have 3 places A, B, C, for whe we will create different kinds of transitions:
TS (timed stoichiometric)
Rate closure and stoichiometry has to be supplied. Rate closure arity should correspond to the domain size. Return arity should be 1 (to be multiplied by the stoichiometry vector, as in all other stoichiometric transitions).
Transition.new stoichiometry: { A: -1, B: 1 },
rate: -> a { a * 0.5 }
Ts (timed nonstoichiometric)
Rate closure has to be supplied, whose arity should match the domain, and output arity codomain.
tS (timeless stoichiometric)
Stoichiometry has to be supplied, action closure is optional. If supplied, its return arity should be 1 (to be multiplied by the stoichiometry vector).
ts transitions (timeless nonstoichiometric)
Action closure is expected with return arity equal to the codomain size:
Transition.new upstream_arcs: [A, C], downstream_arcs: [A, B],
action_closure: proc { |m, x|
if x > 0 then [-(m / 2), (m / 2)]
else [1, 0] end
}
164 165 166 167 168 169 170 171 172 |
# File 'lib/y_petri/transition.rb', line 164 def initialize *args, &block check_in_arguments *args, &block # the big job extend( if timed? then Type_T elsif assignment_action? then Type_A else Type_t end ) inform_upstream_places # that they have been connected inform_downstream_places # that they have been connected uncock # initialize in the uncocked state end |
Instance Attribute Details
#action_closure ⇒ Object (readonly) Also known as: action
For rateless transition, action closure must be present. Action closure input arguments must correspond to the domain places, and for timed transitions, the first argument of the action closure must be Δtime.
229 230 231 |
# File 'lib/y_petri/transition.rb', line 229 def action_closure @action_closure end |
#codomain ⇒ Object (readonly) Also known as: codomain_arcs, codomain_places, downstream, downstream_arcs, downstream_places, action_arcs
Codomain, ‘downstream arcs’, or ‘action arcs’, is a collection of places, whose marking is directly changed by this transition’s firing.
187 188 189 |
# File 'lib/y_petri/transition.rb', line 187 def codomain @codomain end |
#domain ⇒ Object (readonly) Also known as: domain_arcs, domain_places, upstream, upstream_arcs, upstream_places
Domain, or ‘upstream arcs’, is a collection of places, whose marking directly affects the transition’s action.
177 178 179 |
# File 'lib/y_petri/transition.rb', line 177 def domain @domain end |
#rate_closure ⇒ Object (readonly) Also known as: rate, flux_closure, flux, propensity_closure, propensity
In YPetri, rate is a unifying term for both flux and propensity, both of which are treated as aliases of rate. The decision between discrete and continuous computation is a concern of the simulation. Rate closure arity should correspond to the transition’s domain.
218 219 220 |
# File 'lib/y_petri/transition.rb', line 218 def rate_closure @rate_closure end |
#stoichiometry ⇒ Object (readonly)
Stoichiometry (implies that the transition is stoichiometric).
197 198 199 |
# File 'lib/y_petri/transition.rb', line 197 def stoichiometry @stoichiometry end |
Instance Method Details
#inspect ⇒ Object
Inspect string for a transition.
272 273 274 |
# File 'lib/y_petri/transition.rb', line 272 def inspect to_s end |
#place(id) ⇒ Object
283 284 285 |
# File 'lib/y_petri/transition.rb', line 283 def place id super rescue Place().instance( id ) end |
#s ⇒ Object
Stoichiometry as a hash of pairs: { codomain_place_name_symbol => stoichiometric_coefficient }
209 210 211 |
# File 'lib/y_petri/transition.rb', line 209 def s stoichio.with_keys { |k| k.name || k.object_id } end |
#stoichio ⇒ Object
Stoichiometry as a hash of pairs: { codomain_place_instance => stoichiometric_coefficient }
202 203 204 |
# File 'lib/y_petri/transition.rb', line 202 def stoichio Hash[ codomain.zip( @stoichiometry ) ] end |
#to_s ⇒ Object
Conversion to a string.
278 279 280 281 |
# File 'lib/y_petri/transition.rb', line 278 def to_s "#<Transition: %s>" % "#{'%s ' % name if name}(#{type})#{' id:%s' % object_id unless name}" end |
#transition(id) ⇒ Object
287 288 289 |
# File 'lib/y_petri/transition.rb', line 287 def transition id super rescue Transition().instance( id ) end |
#zero_action ⇒ Object
Zero action.
234 235 236 |
# File 'lib/y_petri/transition.rb', line 234 def zero_action codomain.map { 0 } end |