Class: YPetri::Net::State::Features

Inherits:
Array
  • Object
show all
Defined in:
lib/y_petri/net/state/features.rb

Overview

A set of state features.

Defined Under Namespace

Classes: Record

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.__new__Object



37
# File 'lib/y_petri/net/state/features.rb', line 37

alias __new__ new

.delta(arg = nil, transitions: nil) ⇒ Object

Takes an array of delta feature identifiers (places, Delta instances), qualified by an array of transitions (named argument :transitions, defaults to all the transitions in the net), and returns the corresponding array of delta features valid for the current net. If no argument is given, an array of all the delta features qualified by the :transitions argument is returned.



104
105
106
107
108
109
110
111
112
# File 'lib/y_petri/net/state/features.rb', line 104

def delta arg=nil, transitions: nil
  if arg.nil? then
    return delta net.pp, transitions: net.tt if transitions.nil?
    delta net.pp, transitions: transitions
  else
    return new arg.map { |id| Delta id } if transitions.nil?
    new arg.map { |id| Delta id, transitions: transitions }
  end
end

.firing(arg = nil) ⇒ Object

Takes an array of firing feature identifiers (transitions, Firing instances), and returns the corresponding array of firing features valid for the current net. If no argument is given, an array of all the firing features of the current net is returned.



65
66
67
68
# File 'lib/y_petri/net/state/features.rb', line 65

def firing arg=nil
  return firing net.tS_tt if arg.nil?
  new arg.map { |id| Firing id }
end

.flux(arg = nil) ⇒ Object

Takes an array of flux feature identifiers (transitions, Flux instances), and returns the corresponding array of flux features valid for the current net. If no argument is given, an array of all the flux features of the current net is returned.



92
93
94
95
# File 'lib/y_petri/net/state/features.rb', line 92

def flux arg=nil
  return flux net.TS_tt if arg.nil?
  new arg.map { |t| Flux t }
end

.gradient(arg = nil, transitions: nil) ⇒ Object

Takes an array of gradient feature identifiers (places, Marking instances), qualified by an array of transitions (named argument :transitions, defaults to all the timed transitions in the net), and returns the corresponding array of gradient features valid for the current net. If no argument is given, an array of all the gradient features qualified by the :transitions argument is returned.



77
78
79
80
81
82
83
84
85
# File 'lib/y_petri/net/state/features.rb', line 77

def gradient arg=nil, transitions: nil
  if arg.nil? then
    return gradient net.pp, transitions: net.T_tt if transitions.nil?
    gradient net.pp, transitions: transitions
  else
    return new arg.map { |id| Gradient id } if transitions.nil?
    new arg.map { |id| Gradient id, transitions: transitions }
  end
end

.infer_from_elements(net_elements) ⇒ Object

Takes an array of the net elements (places and/or transitions), and infers a feature set from them in the following way: Places or place ids are converted to marking features. The 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).



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/y_petri/net/state/features.rb', line 120

def infer_from_elements( net_elements )
  new net_elements.map { |e| net.element( e ) }.map { |e|
    element, element_type = case e
                            when Feature() then [ e, :feature ]
                            else
                              begin
                                [ net.place( e ), :place ]
                              rescue TypeError, NameError
                                [ net.transition( e ), :transition ]
                              end
                            end
    case element_type
    when :feature then element
    when :place then Marking( element )
    when :transition then
      fail TypeError, "Flux / firing features can only be auto-inferred " +
        "from S transitions! (#{element} was given)" unless element.S?
      element.timed? ? Flux( element ) : Firing( element )
    end
  }
end

.marking(arg = nil) ⇒ Object

Takes an array of marking feature identifiers (places, Marking instances), and returns the corresponding array of marking features valid for the current net. If no argument is given, an array of all the marking features of the current net is returned.



55
56
57
58
# File 'lib/y_petri/net/state/features.rb', line 55

def marking arg=nil
  return marking net.pp if arg.nil?
  new arg.map { |id| Marking id }
end

.new(features) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/y_petri/net/state/features.rb', line 39

def new features
  array = features.map &method( :feature )
  __new__( array ).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

.parametrize(parameters) ⇒ Object

Customization of the parametrize method for the Features class: Its dependents Record and Dataset are also parametrized.



12
13
14
15
16
17
18
19
20
21
# File 'lib/y_petri/net/state/features.rb', line 12

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

Instance Method Details

#*(other) ⇒ Object

Feature summation – of feature class.



192
193
194
# File 'lib/y_petri/net/state/features.rb', line 192

def * other
  self.class.new( super )
end

#+(other) ⇒ Object

Feature summation – of feature class.



180
181
182
# File 'lib/y_petri/net/state/features.rb', line 180

def + other
  self.class.new( super )
end

#-(other) ⇒ Object

Feature summation – of feature class.



186
187
188
# File 'lib/y_petri/net/state/features.rb', line 186

def - other
  self.class.new( super )
end

#delta(arg = nil, transitions: nil) ⇒ Object

Expects a delta feature identifier (place identifier, or Gradient instance), qualified by an array of transitions (named argument :transitions, defaulting to all the transtitions in the net), and returns the corresponding feature from this feature set. If an array of delta feature identifiers is supplied, it is mapped to the array of corresponding features from thie feature set.



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/y_petri/net/state/features.rb', line 301

def delta arg=nil, transitions: nil
  if arg.nil? then
    return delta( select { |feat| feat.is_a? Delta() } ) if
      transitions.nil?
    delta.select { |feat| feat.transitions == net.tt( transitions ) }
  else
    case arg
    when Array then
      self.class.new( arg.map { |id| delta id, transitions: transitions } )
    else
      Delta( arg, transitions: transitions ).tap do |feature|
        include? feature or
          fail KeyError, "No delta feature '#{arg}' in this feature set!"
      end
    end
  end
end

#extract_from(target, **nn) ⇒ Object

Extracts the features from a given target



161
162
163
164
# File 'lib/y_petri/net/state/features.rb', line 161

def extract_from target, **nn
  values = map { |feat| feat.extract_from( target, **nn ) }
  new_record( values )
end

#firing(arg = nil) ⇒ Object

Expects a firing feature idenfier (tS transition identifier, or Firing instance), and returns the corresponding feature from this feature set. If an array of firing feature identifiers is supplied, it is mapped to the array of corresponding features from this feature set. If no argument is given, all the firing features from this set are returned.



238
239
240
241
242
243
244
245
246
247
248
# File 'lib/y_petri/net/state/features.rb', line 238

def firing arg=nil
  return firing( select { |feat| feat.is_a? Firing() } ) if arg.nil?
  case arg
  when Array then self.class.new( arg.map { |id| firing id } )
  else
    Firing( arg ).tap do |feature|
      include? feature or
        fail KeyError, "No firing feature '#{arg}' in this feature set!"
    end
  end
end

#flux(arg = nil) ⇒ Object

Expects a flux feature identifier (TS transition identifier, or Flux instance), and returns the corresponding feature from this feature set. If an array of flux feature identifiers is supplied, it is mapped to the array of corresponding features from this feature set. If no argument is given, all the flux features from this set are returned.



256
257
258
259
260
261
262
263
264
265
266
# File 'lib/y_petri/net/state/features.rb', line 256

def flux arg=nil
  return flux( select { |feat| feat.is_a? Flux() } ) if arg.nil?
  case arg
  when Array then self.class.new( arg.map { |id| flux id } )
  else
    Flux( arg ).tap do |feature|
      include? feature or
        fail KeyError, "No flux feature '#{arg}' in this feature set!"
    end
  end
end

#gradient(arg = nil, transitions: nil) ⇒ Object

Expects a gradient feature identifier (place identifier, or Gradient instance), qualified by an array of transitions (named argument :transitions, defaults to all timed transitions in the net), and returns the corresponding feature from this feature set. If an array of gradient feature identifiers is supplied, it is mapped to the array of corresponding features from this feature set. If no argument is given, all the gradient features from this feature set are returned.



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/y_petri/net/state/features.rb', line 276

def gradient arg=nil, transitions: nil
   if arg.nil? then
     return gradient( select { |feat| feat.is_a? Gradient() } ) if
       transitions.nil?
     gradient.select { |feat| feat.transitions == net.tt( transitions ) }
   else
     case arg
     when Array then
       self.class.new( arg.map { |id| gradient id, transitions: transitions } )
     else
       Gradient( arg, transitions: transitions ).tap do |feature|
         include? feature or
           fail KeyError, "No gradient feature '#{arg}' in this fature set!"
       end
     end
   end
end

#inspectObject

Inspect string of the instance.



329
330
331
# File 'lib/y_petri/net/state/features.rb', line 329

def inspect
  "#<Features: #{to_s}>"
end

#labelsObject

Feature labels.



198
199
200
# File 'lib/y_petri/net/state/features.rb', line 198

def labels
  map &:label
end

#marking(arg = nil) ⇒ Object

Expects a marking feature identifier (place identifier or Marking instance), and returns the corresponding feature from this feature set. If an array of marking feature identifiers is supplied, it is mapped to the array of corresponding features from this feature set. If no argument is given, all the marking features from this set are returned.



220
221
222
223
224
225
226
227
228
229
230
# File 'lib/y_petri/net/state/features.rb', line 220

def marking arg=nil
  return marking( select { |feat| feat.is_a? Marking() } ) if arg.nil?
  case arg
  when Array then self.class.new( arg.map { |id| marking id } )
  else
    Marking( arg ).tap do |feature|
      include? feature or
        fail KeyError, "No marking feature '#{arg}' in this feature set!"
    end
  end
end

#new_dataset(*args, &blk) ⇒ Object

Constructs a new dataset from these features.



174
175
176
# File 'lib/y_petri/net/state/features.rb', line 174

def new_dataset *args, &blk
  DataSet().new *args, &blk
end

#reduce_features(features) ⇒ Object

Expects a hash identifying a set of features, that is a subset of the current set of features.



205
206
207
208
209
210
# File 'lib/y_petri/net/state/features.rb', line 205

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_sObject

Returns a string briefly describing the feature set.



321
322
323
324
325
# File 'lib/y_petri/net/state/features.rb', line 321

def to_s
  group_by( &:type )
    .map { |feature_type, ff| "#{feature_type}: #{ff.size}" }
    .join ', '
end