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

Assignment(array, transition: L!) click to toggle source

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
Delta(array, transitions: nil) click to toggle source

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
Firing(array, **named_args) click to toggle source

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
Flux(array) click to toggle source

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
Gradient(array, transitions: nil) click to toggle source

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
Marking(array) click to toggle source

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
[](*ordered_args, **named_args) click to toggle source

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
__new__(features)
Alias for: new
aa() click to toggle source

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
assignment(*ids, transition: L!) click to toggle source

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
delta(*args, transitions: L!) click to toggle source

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
delta_timed(*args, transitions: L!) click to toggle source

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
delta_timeless(*args, transitions: L!) click to toggle source

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
firing(*firing_feature_identifiers) click to toggle source

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
flux(*flux_feature_identifiers) click to toggle source

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
gradient(*args, transitions: nil) click to toggle source

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
infer_from_nodes( nodes ) click to toggle source

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
marking(*marking_feature_identifiers) click to toggle source

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
new(features) click to toggle source
# 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
Also aliased as: __new__
parametrize(parameters) click to toggle source

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

%(operand) click to toggle source

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
*(other) click to toggle source

Multiplication (like in arrays).

Calls superclass method
# File lib/y_petri/net/state/features.rb, line 308
def * other
  self.class.new( super )
end
+(other) click to toggle source

Summation of feature sets.

Calls superclass method
# File lib/y_petri/net/state/features.rb, line 296
def + other
  self.class.new( super )
end
-(other) click to toggle source

Subtraction of feature sets.

Calls superclass method
# File lib/y_petri/net/state/features.rb, line 302
def - other
  self.class.new( super )
end
Assignment(array) click to toggle source

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
Delta(array, transitions: nil) click to toggle source

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
Firing(array) click to toggle source

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
Flux(array) click to toggle source

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
Gradient(array, transitions: nil) click to toggle source

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
Marking(array) click to toggle source

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
assignment(*ids) click to toggle source

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
delta(*ids, transitions: L!) click to toggle source

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
extract_from(target, **nn) click to toggle source

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
firing(*ids) click to toggle source

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
flux(*ids) click to toggle source

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
gradient(*ids, transitions: L!) click to toggle source

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() click to toggle source

Inspect string of the instance.

# File lib/y_petri/net/state/features.rb, line 469
def inspect
  "#<Features: #{to_s}>"
end
labels() click to toggle source

Labels of the features of the receiver feature set.

# File lib/y_petri/net/state/features.rb, line 314
def labels
  map &:label
end
marking(*ids) click to toggle source

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
reduce_features(features) click to toggle source

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
to_s() click to toggle source

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