class YPetri::Net::State::Features
A feature set. In other words, a set of state features, such as marking, flux etc. The supported features are:
- marking
-
Applicable to all places, all places have marking.
- firing
-
Applicable to all stoichiometric transitions, but delta time has to be known for timed transitions.
- flux
-
Applicable to timed stochiometric transitions only.
- delta
-
Expresses change to a chosen set of places caused by firing of a chosen set of transitions. Requires delta time to be provided if there are timed transitions in the set.
- gradient
-
Expresses gradient of change of a chosen set of places caused by firing of a chosen set of transitions. Only applicable to timed transitions.
Public Class Methods
Constructs a set of assignment features from an array of assignment feature identifiers.
# File lib/y_petri/net/state/features.rb, line 217 def Assignment array, transition: L! if transition.local_object? then new array.map &net.State.Feature.method( :Assignment ) else new array.map { |id| net.State.Feature.Assignment id, transition: transition } end end
Constructs a set of delta features from an array of delta feature identifiers, optionally qualified by an array of transitions supplied via the named argument :transitions
.
# File lib/y_petri/net/state/features.rb, line 162 def Delta array, transitions: nil return new array.map &net.State.Feature.method( :Delta ) if transitions.nil? new array.map { |id| net.State.Feature.Delta id, transitions: transitions } end
Constructs a set of firing features from an array of firing feature identifiers.
# File lib/y_petri/net/state/features.rb, line 104 def Firing array, **named_args new array.map &net.State.Feature.method( :Firing ) end
Constructs a set of flux features from an array of flux feature identifiers.
# File lib/y_petri/net/state/features.rb, line 145 def Flux array new array.map &net.State.Feature.method( :Flux ) end
Constructs a set of gradient features from an array of gradient feature identifiers, optionally qualified by an array of transitions supplied via the named argument :transitions
.
# File lib/y_petri/net/state/features.rb, line 121 def Gradient array, transitions: nil return new array.map &net.State.Feature.method( :Gradient ) if transitions.nil? ary = array.map { |id| net.State.Feature.Gradient id, transitions: transitions } new ary end
Constructs a set of marking features from an array of marking feature identifiers.
# File lib/y_petri/net/state/features.rb, line 88 def Marking array new array.map &net.State.Feature.method( :Marking ) end
Takes an arbitrary number of ordered arguments identifying features, or named arguments :marking
, :firing
, :gradient
, :flux
, :delta
, :assignment
containing arrays identifying the corresponding type of features.
# File lib/y_petri/net/state/features.rb, line 57 def [] *ordered_args, **named_args unless ordered_args.empty? fail ArgumentError, "Named arguments must not be given if ordered " + "arguments are given!" unless named_args.empty? return infer_from_nodes( ordered_args ) end a = [] a << Marking( Array named_args[ :marking ] ) if named_args[ :marking ] a << Firing( Array named_args[ :firing ] ) if named_args[ :firing ] a << Flux( Array named_args[ :flux ] ) if named_args[ :flux ] if named_args[ :gradient ] then ordered = Array( named_args[ :gradient ] ) named = ordered.extract_options! a << Gradient( ordered, **named ) end if named_args[ :delta ] then ordered = Array( named_args[ :delta ] ) named = ordered.extract_options! a << Delta( ordered, **named ) end if named_args[ :assignment ] then ordered = Array( named_args[ :assignment ] ) named = ordered.extract_options! a << Assignment( ordered, **named ) end a.size == 1 ? a.first : a.reduce( new( [] ), :+ ) end
Convenience method that returns the full set of assignment features for those places, which have exactly one A transition in their upstream arcs.
# File lib/y_petri/net/state/features.rb, line 248 def aa Assignment net.places.select { |p| upstream = p.upstream_arcs upstream.size == 1 && upstream.first.A? } end
Expects an arbitrary number of assignment feature identifiers and constructs a feature set out of them.
# File lib/y_petri/net/state/features.rb, line 230 def assignment *ids, transition: L! if transition.local_object? then fail ArgumentError, "Sorry, but Features.assignment method cannot " + "be called without arguments. There is a convenience method " + "Features.aa available, returning all the assignment features " + "for the places with exactly one A transition upstream, if that." + "is what you mean." if ids.empty? Assignment( ids ) else return Assignment( ids, transition: transition ) unless ids.empty? Assignment net.transition( transition ).codomain, transition: transition end end
Expects an arbitrary number of delta feature identifiers and constructs a feature set out of them, optionally qualified by an array of transitions supplied via the named argument :transitions
. Returns the corresponding feature set. Without ordered arguments, full delta feature set for the underlying net is returned.
# File lib/y_petri/net/state/features.rb, line 176 def delta *args, transitions: L! return Delta args, transitions: transitions unless args.empty? fail ArgumentError, "Sorry, but feature set constructor Features.delta " + "cannot be used without :transitions named argument, because it is " + "ambiguous whether the transition set should default to the timed or " + "timeless transitions (they cannot be mixed together when " + "constructing a delta feature). Please specify the transitions, or " + "disambiguate timedness by using either .delta_timed or " + ".delta_timeless method " if transitions.local_object? Delta net.pp, transitions: transitions end
Expects an arbitrary number of place idetifiers and constructs a feature set out of them, optionally qualified by an array of T transitions supplied via the named argument :transitions
. Returns the corresponding feature set. Without ordered arguments, full delta feature set for the underlying net is returned. If no transitions are supplied, full set of T transitions is assumed.
# File lib/y_petri/net/state/features.rb, line 195 def delta_timed *args, transitions: L! return delta *args, transitions: net.T_transitions if transitions.local_object? delta *args, transitions: net.T_Transitions( Array( transitions ) ) end
Expects an arbitrary number of place idetifiers and constructs a feature set out of them, optionally qualified by an array of t (timeless) transitions supplied via the named argument :transitions
. Returns the corresponding feature set. Without ordered arguments, full delta feature set for the underlying net is returned. If no transitions are supplied, full set of t (timeless) transitions is assumed.
# File lib/y_petri/net/state/features.rb, line 208 def delta_timeless *args, transitions: L! return delta *args, transitions: net.t_transitions if transitions.local_object? delta *args, transitions: net.t_Transitions( Array( transitions ) ) end
Expects an arbitrary number of firing feature identifiers and constructs a feature set out of them. Without arguments, full firing feature set (all S transitions) for the underlying net is returned.
# File lib/y_petri/net/state/features.rb, line 112 def firing *firing_feature_identifiers return Firing net.S_tt if firing_feature_identifiers.empty? Firing firing_feature_identifiers end
Expects an arbitrary number of flux feature identifiers and constructs a feature set out of them. Without arguments, full flux feature set for the underlying net is returned.
# File lib/y_petri/net/state/features.rb, line 153 def flux *flux_feature_identifiers return Flux net.TS_tt if flux_feature_identifiers.empty? Flux flux_feature_identifiers end
Expects an arbitrary number of gradient feature identifiers and constructs a feature set out of them, optionally qualified by an array of transitions supplied via the named argument :transitions
. Returns the corresponding feature set. Without ordered arguments, full gradient feature set for the underlying net is returned.
# File lib/y_petri/net/state/features.rb, line 136 def gradient *args, transitions: nil return Gradient args, transitions: transitions unless args.empty? return Gradient net.pp, transitions: net.T_tt if transitions.nil? Gradient net.pp, transitions: transitions end
Takes an array of the net's nodes, and infers a feature set from them as follows: Places or place ids are converted to marking features. Remaining array elements are treated as transition ids, and are converted to either flux features (if the transition is timed), or firing features (if the transition is timeless).
# File lib/y_petri/net/state/features.rb, line 261 def infer_from_nodes( nodes ) new nodes.map &net.State.Feature.method( :infer_from_node ) end
Expects an arbitrary number of marking feature identifiers and constructs a feature set out of them. Without arguments, full marking feature set for the underlying net is returned.
# File lib/y_petri/net/state/features.rb, line 96 def marking *marking_feature_identifiers return Marking net.pp if marking_feature_identifiers.empty? Marking marking_feature_identifiers end
# File lib/y_petri/net/state/features.rb, line 40 def new features features = features.map &State().method( :Feature ) __new__( features ).tap do |inst| # Parametrize them <em>one more time</em> with Features instance. # Banged version of #param_class! ensures that #Record, #Dataset # methods are shadowed. inst.param_class!( { Record: Record(), DataSet: DataSet() }, with: { features: inst } ) end end
Customization of the parametrize method for the Features
class: Its dependents Record
and Dataset are also parametrized.
# File lib/y_petri/net/state/features.rb, line 24 def parametrize parameters Class.new( self ).tap do |ç| parameters.each_pair { |symbol, value| ç.define_singleton_method symbol do value end } ç.param_class( { Record: Record, DataSet: YPetri::Net::DataSet }, with: { Features: ç } ) end end
Public Instance Methods
Interpolation operator +%+ acts as an alias for the #extract_from
feature extraction method.
# File lib/y_petri/net/state/features.rb, line 287 def % operand args = Array( operand ) named_args = args.extract_options! arg = args.first extract_from arg, **named_args end
Multiplication (like in arrays).
# File lib/y_petri/net/state/features.rb, line 308 def * other self.class.new( super ) end
Summation of feature sets.
# File lib/y_petri/net/state/features.rb, line 296 def + other self.class.new( super ) end
Subtraction of feature sets.
# File lib/y_petri/net/state/features.rb, line 302 def - other self.class.new( super ) end
Returns a subset of assignment features selected from this feature set. Expects a single array argument.
# File lib/y_petri/net/state/features.rb, line 442 def Assignment array self.class.new array.map { |id| net.State.Feature.Assignment( id ).tap do |f| include? f or fail KeyError, "No flux feature '#{f}' in this set!" end } end
Returns a subset of delta features selected from this feature set. Expects a single array argument, optionally qualified by :transitions
named argument, defaulting to all the transitions in the net.
# File lib/y_petri/net/state/features.rb, line 416 def Delta array, transitions: nil self.class.new array.map { |id| net.State.Feature.Delta( id, transitions: transitions ).tap do |f| include? f or fail KeyError, "No delta feature '#{f}' in this feature set!" end } end
Returns a subset of firing features selected from this feature set. Expects a single array argument.
# File lib/y_petri/net/state/features.rb, line 351 def Firing array self.class.new array.map { |id| net.State.Feature.Firing( id ).tap do |f| include? f or fail KeyError, "No firing feature '#{f}' in this set!" end } end
Returns a subset of flux features selected from this feature set. Expects a single array argument.
# File lib/y_petri/net/state/features.rb, line 370 def Flux array self.class.new array.map { |id| net.State.Feature.Flux( id ).tap do |f| include? f or fail KeyError, "No flux feature '#{f}' in this set!" end } end
Returns a subset of gradient features selected from this feature set. Expects a single array argument, optionally qualified by :transitions
named argument, defaulting to all T transitions in the net.
# File lib/y_petri/net/state/features.rb, line 390 def Gradient array, transitions: nil self.class.new array.map { |id| net.State.Feature.Gradient( id, transitions: transitions ).tap do |f| include? f or fail KeyError, "No flux feature '#{f}' in this set!" end } end
Returns a subset of marking features selected from this feature set. Expects a single array argument.
# File lib/y_petri/net/state/features.rb, line 331 def Marking array array = array.map do |id| net.State.Feature.Marking( id ).tap do |f| include? f or fail KeyError, "No marking feature '#{f}' in this set!" end end self.class.new array end
Returns a subset of assignment features selected from this feature set. Expects an arbitrary number of arguments. Without arguments, selects all of them.
# File lib/y_petri/net/state/features.rb, line 454 def assignment *ids return Assignment ids unless ids.empty? self.class.new select { |f| f.is_a? net.State.Feature.Assignment } end
Returns a subset of delta features selected from this feature set. Expects an arbitrary number of arguments, optionally qualified by :transitions
named argument, defaulting to all the transitions in the net. Without arguments, selects all the delta features.
# File lib/y_petri/net/state/features.rb, line 430 def delta *ids, transitions: L! return Delta ids, transitions: transitions unless ids.empty? if transitions.local_object? then self.class.new select { |f| f.is_a? net.State.Feature.Delta } else self.class.new select { |f| f.transitions == net.tt( Array transitions ) } end end
Extracts the features from a given target, returning a record.
# File lib/y_petri/net/state/features.rb, line 279 def extract_from target, **nn values = map { |feature| feature.extract_from( target, **nn ) } Record( values ) end
Returns a subset of firing features selected from this feature set. Expects an arbitrary number of arguments. Without arguments, selects all of them.
# File lib/y_petri/net/state/features.rb, line 362 def firing *ids return Firing ids unless ids.empty? self.class.new select { |f| f.is_a? net.State.Feature.Firing } end
Returns a subset of flux features selected from this feature set. Expects an arbitrary number of arguments. Without arguments, selects all of them.
# File lib/y_petri/net/state/features.rb, line 381 def flux *ids return Flux ids unless ids.empty? self.class.new select { |f| f.is_a? net.State.Feature.Flux } end
Returns a subset of gradient features selected from this feature set. Expects an arbitrary number of arguments, optionally qualified by :transitions
named argument, defaulting to all T transitions in the net. Without arguments, selects all of them.
# File lib/y_petri/net/state/features.rb, line 403 def gradient *ids, transitions: L! return Gradient ids, transitions: transitions unless ids.empty? if transitions.local_object? then self.class.new select { |f| f.is_a? net.State.Feature.Gradient } else self.class.new select { |f| f.transitions == net.tt( Array transitions ) } end end
Inspect string of the instance.
# File lib/y_petri/net/state/features.rb, line 469 def inspect "#<Features: #{to_s}>" end
Labels of the features of the receiver feature set.
# File lib/y_petri/net/state/features.rb, line 314 def labels map &:label end
Returns a subset of marking features selected from this feature set. Expects an arbitrary number of arguments. Without arguments, selects all of them.
# File lib/y_petri/net/state/features.rb, line 343 def marking *ids return Marking ids unless ids.empty? self.class.new select { |f| f.is_a? net.State.Feature.Marking } end
Expects a hash identifying a set of features, that is a subset of the current set of features.
# File lib/y_petri/net/state/features.rb, line 321 def reduce_features features net.State.features( features ).tap do |ff| msg = "The argument must identify a subset of the current feature set!" fail TypeError, msg unless ( ff - self ).empty? end end
Returns a string briefly describing the feature set.
# File lib/y_petri/net/state/features.rb, line 461 def to_s group_by( &:type ) .map { |feature_type, ff| "#{feature_type}: #{ff.size}" } .join ', ' end