y_petri 2.1.3 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/y_petri/agent/petri_net_related.rb +25 -5
- data/lib/y_petri/agent/selection.rb +12 -10
- data/lib/y_petri/agent/simulation_related.rb +14 -58
- data/lib/y_petri/agent.rb +15 -17
- data/lib/y_petri/core/timed/euler.rb +13 -15
- data/lib/y_petri/core/timed/pseudo_euler.rb +22 -24
- data/lib/y_petri/core/timed/quasi_euler.rb +15 -17
- data/lib/y_petri/core/timed.rb +42 -44
- data/lib/y_petri/core/timeless/pseudo_euler.rb +12 -14
- data/lib/y_petri/core/timeless.rb +10 -7
- data/lib/y_petri/core.rb +3 -3
- data/lib/y_petri/dsl.rb +46 -46
- data/lib/y_petri/fixed_assets.rb +8 -0
- data/lib/y_petri/net/data_set.rb +238 -0
- data/lib/y_petri/net/own_state.rb +63 -0
- data/lib/y_petri/net/state/feature/delta.rb +98 -71
- data/lib/y_petri/net/state/feature/firing.rb +51 -54
- data/lib/y_petri/net/state/feature/flux.rb +51 -55
- data/lib/y_petri/net/state/feature/gradient.rb +55 -59
- data/lib/y_petri/net/state/feature/marking.rb +55 -59
- data/lib/y_petri/net/state/feature.rb +65 -67
- data/lib/y_petri/net/state/features/record.rb +150 -43
- data/lib/y_petri/net/state/features.rb +252 -96
- data/lib/y_petri/net/state.rb +114 -106
- data/lib/y_petri/net/visualization.rb +3 -2
- data/lib/y_petri/net.rb +29 -24
- data/lib/y_petri/place/arcs.rb +3 -3
- data/lib/y_petri/place/guard.rb +35 -117
- data/lib/y_petri/place/guarded.rb +86 -0
- data/lib/y_petri/place.rb +6 -3
- data/lib/y_petri/simulation/element_representation.rb +2 -2
- data/lib/y_petri/simulation/elements.rb +3 -1
- data/lib/y_petri/simulation/feature_set.rb +3 -1
- data/lib/y_petri/simulation/marking_vector.rb +3 -1
- data/lib/y_petri/simulation/place_mapping.rb +3 -1
- data/lib/y_petri/simulation/places.rb +1 -1
- data/lib/y_petri/simulation/recorder.rb +60 -54
- data/lib/y_petri/simulation/timed/recorder.rb +12 -1
- data/lib/y_petri/simulation/timed.rb +173 -172
- data/lib/y_petri/simulation/transitions/access.rb +97 -29
- data/lib/y_petri/simulation.rb +11 -9
- data/lib/y_petri/transition/{assignment.rb → A.rb} +2 -2
- data/lib/y_petri/transition/{timed.rb → T.rb} +2 -2
- data/lib/y_petri/transition/arcs.rb +3 -3
- data/lib/y_petri/transition/cocking.rb +3 -3
- data/lib/y_petri/transition/{init.rb → construction_convenience.rb} +6 -53
- data/lib/y_petri/transition/{ordinary_timeless.rb → t.rb} +2 -2
- data/lib/y_petri/transition/type.rb +103 -0
- data/lib/y_petri/transition/type_information.rb +103 -0
- data/lib/y_petri/transition/types.rb +107 -0
- data/lib/y_petri/transition/usable_without_world.rb +14 -0
- data/lib/y_petri/transition.rb +87 -101
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri/world/dependency.rb +30 -28
- data/lib/y_petri/world.rb +10 -8
- data/test/acceptance/basic_usage_test.rb +3 -3
- data/test/acceptance/simulation_test.rb +3 -3
- data/test/acceptance/simulation_with_physical_units_test.rb +2 -2
- data/test/acceptance/token_game_test.rb +2 -2
- data/test/acceptance/visualization_test.rb +3 -3
- data/test/acceptance_tests.rb +2 -2
- data/test/agent_test.rb +1 -1
- data/test/net_test.rb +41 -17
- data/test/place_test.rb +1 -1
- data/test/simulation_test.rb +39 -39
- data/test/transition_test.rb +1 -1
- data/test/world_test.rb +1 -1
- data/test/y_petri_test.rb +1 -1
- metadata +13 -8
- data/lib/y_petri/net/state/features/dataset.rb +0 -135
- data/lib/y_petri/transition/construction.rb +0 -311
@@ -1,50 +1,157 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# A collection of values for a given set of state features.
|
4
|
+
#
|
5
|
+
class YPetri::Net::State::Features::Record < Array
|
6
|
+
class << self
|
7
|
+
delegate :State,
|
8
|
+
:net,
|
9
|
+
to: "Features()"
|
10
|
+
|
11
|
+
# Constructs a new Record object from a given collection of values.
|
4
12
|
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
to: "Features()"
|
10
|
-
|
11
|
-
# Construcs a new Record object from a given collection of values.
|
12
|
-
#
|
13
|
-
def load values
|
14
|
-
new( values.dup )
|
15
|
-
end
|
16
|
-
end
|
13
|
+
def load values
|
14
|
+
new( values.dup )
|
15
|
+
end
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
delegate :Features,
|
19
|
+
:State,
|
20
|
+
:net,
|
21
|
+
:features,
|
22
|
+
to: "self.class"
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
# Outputs the record as a plain array.
|
25
|
+
#
|
26
|
+
def dump precision: nil
|
27
|
+
features.map { |f| fetch( f ).round( precision ) }
|
28
|
+
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
30
|
+
# Returns an identified feature, or fails.
|
31
|
+
#
|
32
|
+
def fetch feature
|
33
|
+
super begin
|
34
|
+
Integer( feature )
|
35
|
+
rescue TypeError
|
36
|
+
features.index State().feature( feature )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the state instance implied by the receiver record, and a set of
|
41
|
+
# complementary marking clamps supplied as the argument.
|
42
|
+
#
|
43
|
+
def state marking_clamps: {}
|
44
|
+
cc = marking_clamps.with_keys { |k| net.place k }.with_values! do |v|
|
45
|
+
case v
|
46
|
+
when YPetri::Place then v.marking
|
47
|
+
when ~:call then v.call
|
48
|
+
else v end
|
49
|
+
end
|
50
|
+
msg = "Marking clamps given in the argument taken together with this " +
|
51
|
+
"record's markings must complete the full state of the net!"
|
52
|
+
fail TypeError, msg unless
|
53
|
+
features.marking.map( &:place ) + net.places( cc.keys ) == net.places
|
54
|
+
State().new net.places.map do |place|
|
55
|
+
begin; cc.fetch place; rescue IndexError; fetch marking( place ) end
|
56
|
+
end
|
57
|
+
end
|
39
58
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
59
|
+
# Given a set of marking clamps complementary to the marking features of this
|
60
|
+
# record, reconstructs a Simulation instance with the corresponding state.
|
61
|
+
# If the net is timed, or if the construction of the simulation from the net
|
62
|
+
# has need for any special settings, these must be supplied to this method.
|
63
|
+
# (Timed nets eg. require +:time+ named argument for successful construction.)
|
64
|
+
#
|
65
|
+
def reconstruct marking_clamps: {}, **settings
|
66
|
+
net.simulation marking_clamps: {}, marking: marking, **settings
|
67
|
+
end
|
68
|
+
|
69
|
+
# Expects a marking feature identifier (place identifier or Marking instance),
|
70
|
+
# and returns the value for that feature in this record. If an array of
|
71
|
+
# marking feature identifiers is supplied, it is mapped to the array of
|
72
|
+
# corresponding values. If no argument is given, values from this record for
|
73
|
+
# all the present marking features are returned.
|
74
|
+
#
|
75
|
+
def marking id=nil
|
76
|
+
return marking( features.marking ) if id.nil?
|
77
|
+
case id
|
78
|
+
when Array then id.map { |id| marking id }
|
79
|
+
else fetch( features.marking id ) end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Expects a flux feature identifier (transition identifier or Flux instance),
|
83
|
+
# and returns the value for that feature in this record. If an array of flux
|
84
|
+
# feature identifiers is supplied, it is mapped to the array of corresponding
|
85
|
+
# values. If no argument is given, values from this record for all the present
|
86
|
+
# flux features are returned.
|
87
|
+
#
|
88
|
+
def flux id=nil
|
89
|
+
return flux( features.flux ) if id.nil?
|
90
|
+
case id
|
91
|
+
when Array then id.map { |id| flux net.transition( id ) }
|
92
|
+
else fetch( features.flux id ) end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Expects a firing feature identifier (transition identifier or Firing
|
96
|
+
# instance), and returns the value for that feature in this record. If an
|
97
|
+
# array of firing feature identifiers is supplied, it is mapped to the array
|
98
|
+
# of corresponding values. If no argument is given, values from this record
|
99
|
+
# for all the present flux features are returned.
|
100
|
+
#
|
101
|
+
def firing id=nil
|
102
|
+
return firing( features.firing ) if id.nil?
|
103
|
+
case id
|
104
|
+
when Array then id.map { |id| firing net.transition( id ) }
|
105
|
+
else fetch( features.firing id ) end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Expects a gradient feature identifier (place identifier, or Gradient
|
109
|
+
# instance), qualified by an array of transitions (named argument
|
110
|
+
# +:transitions+, defaults to all timed transitions in the net), and returns
|
111
|
+
# the value for that feature in this record. If an array of gradient feature
|
112
|
+
# identifiers is supplied, it is mapped to the array of corresponding values.
|
113
|
+
# If no gradient feature identifier is given, values from this record for all
|
114
|
+
# the present gradient features are returned.
|
115
|
+
#
|
116
|
+
def gradient id=nil, transitions: nil
|
117
|
+
if id.nil? then
|
118
|
+
return gradient( features.gradient ) if transitions.nil?
|
119
|
+
gradient( features.gradient.select do |f|
|
120
|
+
f.transitions == transitions.map { |t| net.transition t }
|
121
|
+
end )
|
122
|
+
else
|
123
|
+
return gradient( id, transitions: net.T_tt ) if transitions.nil?
|
124
|
+
case id
|
125
|
+
when Array then
|
126
|
+
pl.map { |id| gradient id, transitions: transitions }
|
127
|
+
else
|
128
|
+
fetch( features.gradient id, transitions: transitions )
|
45
129
|
end
|
130
|
+
end
|
131
|
+
end
|
46
132
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
133
|
+
# Expects a gradient feature identifier (place identifier, or Delta instance),
|
134
|
+
# qualified by an array of transitions (named argument +:transitions+,
|
135
|
+
# defaults to all timed transitions in the net), and returns the value for
|
136
|
+
# that feature in this record. If an array of delta feature identifiers is
|
137
|
+
# supplied, it is mapped to the array of corresponding values. If no delta
|
138
|
+
# feature identifier is given, values from this record for all the present
|
139
|
+
# delta features are returned.
|
140
|
+
#
|
141
|
+
def delta pl=nil, transitions: nil
|
142
|
+
if id.nil? then
|
143
|
+
return delta( features.delta ) if transitions.nil?
|
144
|
+
delta( features.delta.select do |f|
|
145
|
+
f.transitions == transitions.map { |t| net.transition t }
|
146
|
+
end )
|
147
|
+
else
|
148
|
+
return delta( id, transitions: net.tt ) if transitions.nil?
|
149
|
+
case id
|
150
|
+
when Array then
|
151
|
+
id.map { |id| delta id, transitions: transitions }
|
152
|
+
else
|
153
|
+
fetch( features.delta id, transitions: net.tt( transitions ) )
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end # class YPetri::Net::State::Features::Record
|
@@ -1,126 +1,282 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require_relative 'features/record'
|
8
|
-
require_relative 'features/dataset'
|
9
|
-
|
10
|
-
class << self
|
11
|
-
# Customization of the parametrize method for the Features class: Its
|
12
|
-
# dependents Record and Dataset are also parametrized.
|
13
|
-
#
|
14
|
-
def parametrize parameters
|
15
|
-
Class.new( self ).tap do |subclass|
|
16
|
-
parameters.each_pair { |symbol, value|
|
17
|
-
subclass.define_singleton_method symbol do value end
|
18
|
-
}
|
19
|
-
subclass.param_class( { Record: Record, Dataset: Dataset },
|
20
|
-
with: { Features: subclass } )
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
delegate :net,
|
25
|
-
:Feature,
|
26
|
-
:feature,
|
27
|
-
to: "State()"
|
28
|
-
|
29
|
-
delegate :Marking,
|
30
|
-
:Firing,
|
31
|
-
:Gradient,
|
32
|
-
:Flux,
|
33
|
-
:Delta,
|
34
|
-
to: "Feature()"
|
35
|
-
|
36
|
-
delegate :load, to: :Record
|
37
|
-
|
38
|
-
alias __new__ new
|
39
|
-
|
40
|
-
def new features
|
41
|
-
ff = features.map &method( :feature )
|
42
|
-
__new__( ff ).tap do |inst|
|
43
|
-
# Parametrize them <em>one more time</em> with Features instance.
|
44
|
-
# Banged version of #param_class! ensures that #Record, #Dataset
|
45
|
-
# methods are shadowed.
|
46
|
-
inst.param_class!( { Record: Record(), Dataset: Dataset() },
|
47
|
-
with: { features: inst } )
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def marking places=net.pp
|
52
|
-
new net.pp( places ).map { |p| Marking( p ) }
|
53
|
-
end
|
54
|
-
|
55
|
-
def firing transitions=net.tS_tt
|
56
|
-
new net.tS_tt( transitions ).map { |t| Firing( t ) }
|
57
|
-
end
|
58
|
-
|
59
|
-
def gradient places=net.pp, transitions: net.T_tt
|
60
|
-
tt = net.T_tt( transitions )
|
61
|
-
new net.pp( places ).map { |p|
|
62
|
-
Gradient( p, transitions: tt )
|
63
|
-
}
|
64
|
-
end
|
65
|
-
|
66
|
-
def flux transitions=net.TS_tt
|
67
|
-
new net.TS_tt( transitions ).map { |t| Flux( t ) }
|
68
|
-
end
|
3
|
+
# A set of state features.
|
4
|
+
#
|
5
|
+
class YPetri::Net::State::Features < Array
|
6
|
+
require_relative 'features/record'
|
69
7
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
8
|
+
class << self
|
9
|
+
# Customization of the parametrize method for the Features class: Its
|
10
|
+
# dependents Record and Dataset are also parametrized.
|
11
|
+
#
|
12
|
+
def parametrize parameters
|
13
|
+
Class.new( self ).tap do |ç|
|
14
|
+
parameters.each_pair { |symbol, value|
|
15
|
+
ç.define_singleton_method symbol do value end
|
74
16
|
}
|
17
|
+
ç.param_class( { Record: Record,
|
18
|
+
Dataset: YPetri::Net::DataSet },
|
19
|
+
with: { Features: ç } )
|
75
20
|
end
|
76
21
|
end
|
77
22
|
|
78
|
-
delegate :
|
79
|
-
:net,
|
23
|
+
delegate :net,
|
80
24
|
:Feature,
|
81
25
|
:feature,
|
82
|
-
:
|
26
|
+
to: "State()"
|
27
|
+
|
28
|
+
delegate :Marking,
|
83
29
|
:Firing,
|
84
30
|
:Gradient,
|
85
31
|
:Flux,
|
86
32
|
:Delta,
|
87
|
-
:
|
88
|
-
to: "self.class"
|
33
|
+
to: "Feature()"
|
89
34
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
35
|
+
delegate :load, to: "Record()"
|
36
|
+
|
37
|
+
alias __new__ new
|
38
|
+
|
39
|
+
def new features
|
40
|
+
array = features.map &method( :feature )
|
41
|
+
__new__( array ).tap do |inst|
|
42
|
+
# Parametrize them <em>one more time</em> with Features instance.
|
43
|
+
# Banged version of #param_class! ensures that #Record, #Dataset
|
44
|
+
# methods are shadowed.
|
45
|
+
inst.param_class!( { Record: Record(), Dataset: Dataset() },
|
46
|
+
with: { features: inst } )
|
47
|
+
end
|
94
48
|
end
|
95
49
|
|
96
|
-
#
|
50
|
+
# Takes an array of marking feature identifiers (places, Marking instances),
|
51
|
+
# and returns the corresponding array of marking features valid for the
|
52
|
+
# current net. If no argument is given, an array of all the marking features
|
53
|
+
# of the current net is returned.
|
97
54
|
#
|
98
|
-
def
|
99
|
-
|
55
|
+
def marking arg=nil
|
56
|
+
return marking net.pp if arg.nil?
|
57
|
+
new arg.map { |id| Marking id }
|
100
58
|
end
|
101
59
|
|
102
|
-
#
|
60
|
+
# Takes an array of firing feature identifiers (transitions, Firing
|
61
|
+
# instances), and returns the corresponding array of firing features valid
|
62
|
+
# for the current net. If no argument is given, an array of all the firing
|
63
|
+
# features of the current net is returned.
|
103
64
|
#
|
104
|
-
def
|
105
|
-
|
65
|
+
def firing arg=nil
|
66
|
+
return firing net.tS_tt if arg.nil?
|
67
|
+
new arg.map { |id| Firing id }
|
106
68
|
end
|
107
69
|
|
108
|
-
#
|
70
|
+
# Takes an array of gradient feature identifiers (places, Marking instances),
|
71
|
+
# qualified by an array of transitions (named argument +:transitions+,
|
72
|
+
# defaults to all the timed transitions in the net), and returns the
|
73
|
+
# corresponding array of gradient features valid for the current net. If no
|
74
|
+
# argument is given, an array of all the gradient features qualified by the
|
75
|
+
# +:transitions+ argument is returned.
|
109
76
|
#
|
110
|
-
def
|
111
|
-
|
77
|
+
def gradient arg=nil, transitions: nil
|
78
|
+
if arg.nil? then
|
79
|
+
return gradient net.pp, transitions: net.T_tt if transitions.nil?
|
80
|
+
gradient net.pp, transitions: transitions
|
81
|
+
else
|
82
|
+
return new arg.map { |id| Gradient id } if transitions.nil?
|
83
|
+
new arg.map { |id| Gradient id, transitions: transitions }
|
84
|
+
end
|
112
85
|
end
|
113
86
|
|
114
|
-
#
|
87
|
+
# Takes an array of flux feature identifiers (transitions, Flux instances),
|
88
|
+
# and returns the corresponding array of flux features valid for the current
|
89
|
+
# net. If no argument is given, an array of all the flux features of the
|
90
|
+
# current net is returned.
|
115
91
|
#
|
116
|
-
def
|
117
|
-
|
92
|
+
def flux arg=nil
|
93
|
+
return flux net.TS_tt if arg.nil?
|
94
|
+
new arg.map { |t| Flux t }
|
118
95
|
end
|
119
96
|
|
120
|
-
#
|
97
|
+
# Takes an array of delta feature identifiers (places, Delta instances),
|
98
|
+
# qualified by an array of transitions (named argument +:transitions+,
|
99
|
+
# defaults to all the transitions in the net), and returns the corresponding
|
100
|
+
# array of delta features valid for the current net. If no argument is
|
101
|
+
# given, an array of all the delta features qualified by the +:transitions+
|
102
|
+
# argument is returned.
|
121
103
|
#
|
122
|
-
def
|
123
|
-
|
104
|
+
def delta arg=nil, transitions: nil
|
105
|
+
if arg.nil? then
|
106
|
+
return delta net.pp, transitions: net.tt if transitions.nil?
|
107
|
+
delta net.pp, transitions: transitions
|
108
|
+
else
|
109
|
+
return new arg.map { |id| Delta id } if transitions.nil?
|
110
|
+
new arg.map { |id| Delta id, transitions: transitions }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
delegate :State,
|
116
|
+
:net,
|
117
|
+
:Feature,
|
118
|
+
:feature,
|
119
|
+
:Marking,
|
120
|
+
:Firing,
|
121
|
+
:Gradient,
|
122
|
+
:Flux,
|
123
|
+
:Delta,
|
124
|
+
to: "self.class"
|
125
|
+
|
126
|
+
delegate :load,
|
127
|
+
to: "Record()"
|
128
|
+
|
129
|
+
alias new_record load
|
130
|
+
|
131
|
+
# Extracts the features from a given target
|
132
|
+
#
|
133
|
+
def extract_from target, **nn
|
134
|
+
new_record( map { |feature| feature.extract_from( target, **nn ) } )
|
135
|
+
end
|
136
|
+
|
137
|
+
# Constructs a new dataset from these features.
|
138
|
+
#
|
139
|
+
def new_dataset *args, &blk
|
140
|
+
Dataset().new *args, &blk
|
141
|
+
end
|
142
|
+
|
143
|
+
# Feature summation -- of feature class.
|
144
|
+
#
|
145
|
+
def + other
|
146
|
+
self.class.new( super )
|
147
|
+
end
|
148
|
+
|
149
|
+
# Feature summation -- of feature class.
|
150
|
+
#
|
151
|
+
def - other
|
152
|
+
self.class.new( super )
|
153
|
+
end
|
154
|
+
|
155
|
+
# Feature summation -- of feature class.
|
156
|
+
#
|
157
|
+
def * other
|
158
|
+
self.class.new( super )
|
159
|
+
end
|
160
|
+
|
161
|
+
# Feature labels.
|
162
|
+
#
|
163
|
+
def labels
|
164
|
+
map &:label
|
165
|
+
end
|
166
|
+
|
167
|
+
# Expects a hash identifying a set of features, that is a subset of the
|
168
|
+
# current set of features.
|
169
|
+
#
|
170
|
+
def reduce_features features
|
171
|
+
net.State.features( features ).tap do |ff|
|
172
|
+
msg = "The argument must identify a subset of the current feature set!"
|
173
|
+
fail TypeError, msg unless ( ff - self ).empty?
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Returns the subset of marking features.
|
178
|
+
|
179
|
+
|
180
|
+
# Expects a marking feature identifier (place identifier or Marking instance),
|
181
|
+
# and returns the corresponding feature from this feature set. If an array of
|
182
|
+
# marking feature identifiers is supplied, it is mapped to the array of
|
183
|
+
# corresponding features from this feature set. If no argument is given, all
|
184
|
+
# the marking features from this set are returned.
|
185
|
+
#
|
186
|
+
def marking id=nil
|
187
|
+
return marking( select { |f| f.is_a? Marking() } ) if id.nil?
|
188
|
+
case id
|
189
|
+
when Array then self.class.new( id.map { |id| marking id } )
|
190
|
+
else
|
191
|
+
Marking( id ).tap do |feature|
|
192
|
+
include? feature or
|
193
|
+
fail KeyError, "No marking feature '#{id}' in this feature set!"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Expects a firing feature idenfier (tS transition identifier, or Firing
|
199
|
+
# instance), and returns the corresponding feature from this feature set. If
|
200
|
+
# an array of firing feature identifiers is supplied, it is mapped to the
|
201
|
+
# array of corresponding features from this feature set. If no argument is
|
202
|
+
# given, all the firing features from this set are returned.
|
203
|
+
#
|
204
|
+
def firing id=nil
|
205
|
+
return firing( select { |f| f.is_a? Firing() } ) if id.nil?
|
206
|
+
case id
|
207
|
+
when Array then self.class.new( id.map { |id| firing id } )
|
208
|
+
else
|
209
|
+
Firing( id ).tap do |feature|
|
210
|
+
include? feature or
|
211
|
+
fail KeyError, "No firing feature '#{id}' in this feature set!"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Expects a flux feature identifier (TS transition identifier, or Flux
|
217
|
+
# instance), and returns the corresponding feature from this feature set. If
|
218
|
+
# an array of flux feature identifiers is supplied, it is mapped to the array
|
219
|
+
# of corresponding features from this feature set. If no argument is given,
|
220
|
+
# all the flux features from this set are returned.
|
221
|
+
#
|
222
|
+
def flux id=nil
|
223
|
+
return flux( select { |f| f.is_a? Flux() } ) if id.nil?
|
224
|
+
case id
|
225
|
+
when Array then self.class.new( id.map { |id| flux id } )
|
226
|
+
else
|
227
|
+
Flux( id ).tap do |feature|
|
228
|
+
include? feature or
|
229
|
+
fail KeyError, "No flux feature '#{id}' in this feature set!"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# Expects a gradient feature identifier (place identifier, or Gradient
|
235
|
+
# instance), qualified by an array of transitions (named argument
|
236
|
+
# +:transitions+, defaults to all timed transitions in the net), and
|
237
|
+
# returns the corresponding feature from this feature set. If an array of
|
238
|
+
# gradient feature identifiers is supplied, it is mapped to the array of
|
239
|
+
# corresponding features from this feature set. If no argument is given,
|
240
|
+
# all the gradient features from this feature set are returned.
|
241
|
+
#
|
242
|
+
def gradient id=nil, transitions: nil
|
243
|
+
if id.nil? then
|
244
|
+
return gradient( select { |f| f.is_a? Gradient() } ) if transitions.nil?
|
245
|
+
gradient.select { |f| f.transitions == net.tt( transitions ) }
|
246
|
+
else
|
247
|
+
case id
|
248
|
+
when Array then
|
249
|
+
self.class.new( id.map { |id| gradient id, transitions: transitions } )
|
250
|
+
else
|
251
|
+
Gradient( id, transitions: transitions ).tap do |feature|
|
252
|
+
include? feature or
|
253
|
+
fail KeyError, "No gradient feature '#{id}' in this fature set!"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# Expects a delta feature identifier (place identifier, or Gradient instance),
|
260
|
+
# qualified by an array of transitions (named argument +:transitions+,
|
261
|
+
# defaulting to all the transtitions in the net), and returns the
|
262
|
+
# corresponding feature from this feature set. If an array of delta feature
|
263
|
+
# identifiers is supplied, it is mapped to the array of corresponding features
|
264
|
+
# from thie feature set.
|
265
|
+
#
|
266
|
+
def delta
|
267
|
+
if id.nil? then
|
268
|
+
return delta( select { |f| f.is_a? Delta() } ) if transitions.nil?
|
269
|
+
delta.select { |f| f.transitions == net.tt( transitions ) }
|
270
|
+
else
|
271
|
+
case id
|
272
|
+
when Array then
|
273
|
+
self.class.new( id.map { |id| delta id, transitions: transitions } )
|
274
|
+
else
|
275
|
+
Delta( id, transitions: transitions ).tap do |feature|
|
276
|
+
include? feature or
|
277
|
+
fail KeyError, "No delta feature '#{id}' in this feature set!"
|
278
|
+
end
|
279
|
+
end
|
124
280
|
end
|
125
|
-
end
|
126
|
-
end # YPetri::Net::State
|
281
|
+
end
|
282
|
+
end # YPetri::Net::State::Features
|