Class: YPetri::Simulation

Inherits:
Object
  • Object
show all
Defined in:
lib/y_petri/simulation.rb,
lib/y_petri/simulation/nodes.rb,
lib/y_petri/simulation/dependency.rb,
lib/y_petri/simulation/feature_set.rb,
lib/y_petri/simulation/transitions.rb,
lib/y_petri/simulation/place_mapping.rb,
lib/y_petri/simulation/marking_clamps.rb,
lib/y_petri/simulation/marking_vector.rb,
lib/y_petri/simulation/initial_marking.rb,
lib/y_petri/simulation/place_representation.rb,
lib/y_petri/simulation/transition_representation.rb

Overview

Representation of a YPetri::Transition inside a YPetri::Simulation instance.

Defined Under Namespace

Modules: Dependency, Timed, Timeless Classes: FeatureSet, InitialMarking, MarkingClamps, MarkingVector, NodeRepresentation, Nodes, PlaceMapping, PlaceRepresentation, Places, Recorder, TransitionRepresentation, Transitions

Constant Summary collapse

DEFAULT_SETTINGS =
-> do { method: :basic, guarded: false } end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(use_default_marking: true, guarded: false, marking_clamps: {}, initial_marking: {}, marking: nil, **settings) ⇒ Simulation

The basic simulation parameter is :net – a collection of places and transitions (a YPetri::Net instance) that is simulated. Other required arguments are :marking_clamps and :initial_marking (or +:marking – if no :initial_marking is supplied, :marking will be used in its stead). Even when the caller did not provide all the :initial_marking, there is an option of extracting them from the place instances themselves. This option, controlled by the named argument use_default_marking, is normally set to true, to turn it off, change it to false.

Simulation method is set by :method named argument, guarding is controlled by :guarded named argument (true/false). Simulations of timed nets are also timed. For a timed simulation, the constructor permits named arguments :time (alias :time_range), :step (simulation step size), and :sampling (sampling period), and requires that at least one of these named arguments be supplied.


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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
190
191
192
193
# File 'lib/y_petri/simulation.rb', line 132

def initialize use_default_marking: true,
               guarded: false,
               marking_clamps: {},
               initial_marking: {},
               marking: nil,
               **settings
  param_class!( { PlacePS: PlaceRepresentation, # PS = parametrized subclass
                  PlacesPS: Places,
                  TransitionPS: TransitionRepresentation,
                  TransitionsPS: Transitions,
                  NodesPS: Nodes,
                  PlaceMapping: PlaceMapping,
                  InitialMarking: InitialMarking,
                  MarkingClamps: MarkingClamps,
                  MarkingVector: MarkingVector },
                with: { simulation: self } )
  [ PlacePS(), TransitionPS() ].each &:namespace! # each serves as its namespace
  @guarded = guarded # TODO: Not operable as of now.
  @places = PlacesPS().load( net.places )
  @marking_clamps = MarkingClamps().load( marking_clamps )
  @initial_marking = if marking then
                       m = PlaceMapping().load( marking )
                       im = PlaceMapping().load( initial_marking )
                       InitialMarking().load( m.merge im )
                     else
                       InitialMarking().load( initial_marking )
                     end
  # Fill in the missing initial marking from the places' default marking.
  @places.send( :complete_initial_marking,
                use_default_marking: use_default_marking )
  # Correspondence matrix free places --> all places
  @f2a = free_places.correspondence_matrix( places )
  # Correspondence matrix clamped places --> all places
  @c2a = clamped_places.correspondence_matrix( places )
  # Conditionally extend self depending on net's timedness.
  time_mentioned = settings[:time] || settings[:step] || settings[:sampling]
  if time_mentioned then extend Timed else extend Timeless end
  # Initialize the marking vector.
  @m_vector = MarkingVector().zero
  # Set up the collection of transitions.
  @transitions = TransitionsPS().load( net.transitions )
  # Set up stoichiometry matrices relative to free places.
  @tS_stoichiometry_matrix = transitions.tS.stoichiometry_matrix
  @TS_stoichiometry_matrix = transitions.TS.stoichiometry_matrix
  # Set up stoichiometry matrices relative to all places.
  @tS_SM = transitions.tS.SM
  @TS_SM = transitions.TS.SM
  # Call timedness-dependent #init subroutine.
  init **settings
  # Make time-independent closures.
  @ts_delta_closure = transitions.ts.delta_closure
  @tS_firing_closure = transitions.tS.firing_closure
  @A_direct_assignment_closure = transitions.A.direct_assignment_closure
  @increment_marking_vector_closure = m_vector.increment_closure
  # Make timed-only closures.
  if timed? then
    @Ts_gradient_closure = transitions.Ts.gradient_closure
    @TS_rate_closure = transitions.TS.rate_closure
  end
  # Reset.
  if marking then reset! marking: marking else reset! end
end

Instance Attribute Details

#A_direct_assignment_closureObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def A_direct_assignment_closure
  @A_direct_assignment_closure
end

#guardedObject (readonly) Also known as: guarded?

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def guarded
  @guarded
end

#increment_marking_vector_closureObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def increment_marking_vector_closure
  @increment_marking_vector_closure
end

#recorderObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def recorder
  @recorder
end

#ts_delta_closureObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def ts_delta_closure
  @ts_delta_closure
end

#tS_firing_closureObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def tS_firing_closure
  @tS_firing_closure
end

#Ts_gradient_closureObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def Ts_gradient_closure
  @Ts_gradient_closure
end

#TS_rate_closureObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def TS_rate_closure
  @TS_rate_closure
end

#TS_SMObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def TS_SM
  @TS_SM
end

#tS_SMObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def tS_SM
  @tS_SM
end

#tS_stoichiometry_matrixObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def tS_stoichiometry_matrix
  @tS_stoichiometry_matrix
end

#TS_stoichiometry_matrixObject (readonly)

Parametrized subclasses.


56
57
58
# File 'lib/y_petri/simulation.rb', line 56

def TS_stoichiometry_matrix
  @TS_stoichiometry_matrix
end

Class Method Details

.__new__Object


48
# File 'lib/y_petri/simulation.rb', line 48

alias __new__ new

.new(net: (fail ArgumentError, "No net supplied!"), **settings) ⇒ Object


50
51
52
# File 'lib/y_petri/simulation.rb', line 50

def new net: (fail ArgumentError, "No net supplied!"), **settings
  net.simulation **settings
end

Instance Method Details

#dup(marking: marking(), recording: recording(), **named_args) ⇒ Object

Returns a new simulation instance. Unless modified by arguments, the state of the new instance is the same as the creator's. Arguments can partially or wholly modify the attributes of the duplicate.


209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/y_petri/simulation.rb', line 209

def dup( marking: marking(), recording: recording(), **named_args )
  named_args.reverse_merge! settings( true )
  self.class.new( named_args ).tap do |duplicate|
    duplicate.recorder.reset! recording: recording
    duplicate.m_vector.reset! case marking
                              when Hash then
                                m_vector.to_hash_with_source_places
                                  .update( PlaceMapping().load( marking )
                                             .to_marking_vector
                                             .to_hash_with_source_places )
                              when Matrix, Array then marking
                              else marking.each.to_a end
  end
end

#firing(ids_of_tS_transitions = nil) ⇒ Object

Returns the firing of the indicated tS transitions (all tS transitions, if no argument is given).


91
92
93
94
95
96
97
# File 'lib/y_petri/simulation.rb', line 91

def firing ids_of_tS_transitions=nil
  tt = tS_transitions()
  return firing tt if ids_of_tS_transitions.nil?
  tS_transitions( ids_of_tS_transitions ).map { |t|
    firing_vector_tS.column_to_a.fetch tt.index( t )
  }
end

#get_features(*args) ⇒ Object

Extract a prescribed set of features.


258
259
260
# File 'lib/y_petri/simulation.rb', line 258

def get_features *args
  net.State.Features( *args ).extract_from( self )
end

#guard_Δ!(Δ_free_places) ⇒ Object

Guards proposed marking delta.


247
248
249
250
# File 'lib/y_petri/simulation.rb', line 247

def guard_Δ! Δ_free_places
  ary = ( marking_vector + F2A() * Δ_free_places ).column_to_a
  places.zip( ary ).each { |pl, proposed_m| pl.guard.( proposed_m ) }
end

#inspectObject

Inspect string for this simulation.


226
227
228
# File 'lib/y_petri/simulation.rb', line 226

def inspect
  to_s
end

#pfiring(ids = nil, gap: 0, precision: 4) ⇒ Object

Pretty prints firing of the indicated tS transitions as hash with transition names as keys. Takes optional list of tS transition ids (first ordered arg.), and optional 2 named arguments (:gap and :precision), as in #pretty_print_numeric_values.


111
112
113
# File 'lib/y_petri/simulation.rb', line 111

def pfiring ids=nil, gap: 0, precision: 4
  t_firing( ids ).pretty_print_numeric_values( gap: gap, precision: precision )
end

#reset!(marking: nil, **named_args) ⇒ Object

Resets the simulation.


238
239
240
241
242
243
# File 'lib/y_petri/simulation.rb', line 238

def reset! marking: nil, **named_args
  tap do
    marking ? m_vector.reset!( marking ) : m_vector.reset!
    recorder.reset!.alert!
  end
end

#settings(all = false) ⇒ Object

Simulation settings.


197
198
199
200
201
202
203
# File 'lib/y_petri/simulation.rb', line 197

def settings all=false
  return { method: simulation_method, guarded: guarded? } unless all == true
  { net: net,
    marking_clamps: marking_clamps.keys_to_source_places,
    initial_marking: initial_markings.keys_to_source_places
  }.update( settings )
end

#t_firing(ids = nil) ⇒ Object

Firing of the indicated tS transitions (as hash with transition names as keys).


102
103
104
# File 'lib/y_petri/simulation.rb', line 102

def t_firing ids=nil
  tS_transitions( ids ).names( true ) >> firing( ids )
end

#to_sObject

String representation of this simulation.


232
233
234
# File 'lib/y_petri/simulation.rb', line 232

def to_s
  "#<Simulation: pp: %s, tt: %s, oid: %s>" % [ pp.size, tt.size, object_id ]
end