y_petri 2.1.36 → 2.1.37
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/y_petri/net/data_set.rb +1 -1
- data/lib/y_petri/net/state/features/record.rb +7 -6
- data/lib/y_petri/net/state/features.rb +39 -37
- data/lib/y_petri/net.rb +2 -1
- data/lib/y_petri/simulation/marking_vector.rb +7 -1
- data/lib/y_petri/simulation.rb +17 -9
- data/lib/y_petri/version.rb +1 -1
- data/test/net_test.rb +50 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8bd3d0de26cf79301633503c11a780226ec1e1b
|
4
|
+
data.tar.gz: a8da1ce1d92d383d917116dde22356b97a42aabf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76b36988750b6ba018af3efe5f33a2017838d702a49331b8e529b05149cfbff662d78e2eeaa02dfb9f3971956be04a597483c4efb4173aa49799d946a3419eb1
|
7
|
+
data.tar.gz: 26d6113132e1154ba1a534429316a61382f62e88d7574a6f28339d8b220e9388bd278286011f92e10f5baef4670fb0e59db1bd1d749ce794670e71a874062bf7
|
data/lib/y_petri/net/data_set.rb
CHANGED
@@ -114,7 +114,7 @@ class YPetri::Net::DataSet < Hash
|
|
114
114
|
sampling = nn.must_have :sampling
|
115
115
|
t0, target_time = time_range.begin, time_range.end
|
116
116
|
t = t0
|
117
|
-
o = self.class.new
|
117
|
+
o = self.class.new type: type
|
118
118
|
loop do
|
119
119
|
o.update t => interpolate( t )
|
120
120
|
t += sampling
|
@@ -71,7 +71,8 @@ class YPetri::Net::State::Features::Record < Array
|
|
71
71
|
# (Timed nets eg. require +:time+ named argument for successful construction.)
|
72
72
|
#
|
73
73
|
def reconstruct marking_clamps: {}, **settings
|
74
|
-
|
74
|
+
m_hsh = features.marking.map { |feat| feat.place } >> marking
|
75
|
+
net.simulation marking_clamps: {}, marking: m_hsh, **settings
|
75
76
|
end
|
76
77
|
|
77
78
|
# Expects a marking feature identifier (place identifier or Marking instance),
|
@@ -80,11 +81,11 @@ class YPetri::Net::State::Features::Record < Array
|
|
80
81
|
# corresponding values. If no argument is given, values from this record for
|
81
82
|
# all the present marking features are returned.
|
82
83
|
#
|
83
|
-
def marking
|
84
|
-
return marking( features.marking ) if
|
85
|
-
case
|
86
|
-
when Array then
|
87
|
-
else fetch( features.marking
|
84
|
+
def marking arg=nil
|
85
|
+
return marking( features.marking ) if arg.nil?
|
86
|
+
case arg
|
87
|
+
when Array then arg.map { |id| marking id }
|
88
|
+
else fetch( features.marking arg ) end
|
88
89
|
end
|
89
90
|
|
90
91
|
# Expects a flux feature identifier (transition identifier or Flux instance),
|
@@ -15,7 +15,7 @@ class YPetri::Net::State::Features < Array
|
|
15
15
|
ç.define_singleton_method symbol do value end
|
16
16
|
}
|
17
17
|
ç.param_class( { Record: Record,
|
18
|
-
|
18
|
+
DataSet: YPetri::Net::DataSet },
|
19
19
|
with: { Features: ç } )
|
20
20
|
end
|
21
21
|
end
|
@@ -42,7 +42,7 @@ class YPetri::Net::State::Features < Array
|
|
42
42
|
# Parametrize them <em>one more time</em> with Features instance.
|
43
43
|
# Banged version of #param_class! ensures that #Record, #Dataset
|
44
44
|
# methods are shadowed.
|
45
|
-
inst.param_class!( { Record: Record(),
|
45
|
+
inst.param_class!( { Record: Record(), DataSet: DataSet() },
|
46
46
|
with: { features: inst } )
|
47
47
|
end
|
48
48
|
end
|
@@ -137,7 +137,7 @@ class YPetri::Net::State::Features < Array
|
|
137
137
|
# Constructs a new dataset from these features.
|
138
138
|
#
|
139
139
|
def new_dataset *args, &blk
|
140
|
-
|
140
|
+
DataSet().new *args, &blk
|
141
141
|
end
|
142
142
|
|
143
143
|
# Feature summation -- of feature class.
|
@@ -183,14 +183,14 @@ class YPetri::Net::State::Features < Array
|
|
183
183
|
# corresponding features from this feature set. If no argument is given, all
|
184
184
|
# the marking features from this set are returned.
|
185
185
|
#
|
186
|
-
def marking
|
187
|
-
return marking( select { |
|
188
|
-
case
|
189
|
-
when Array then self.class.new(
|
186
|
+
def marking arg=nil
|
187
|
+
return marking( select { |feat| feat.is_a? Marking() } ) if arg.nil?
|
188
|
+
case arg
|
189
|
+
when Array then self.class.new( arg.map { |id| marking id } )
|
190
190
|
else
|
191
|
-
Marking(
|
191
|
+
Marking( arg ).tap do |feature|
|
192
192
|
include? feature or
|
193
|
-
fail KeyError, "No marking feature '#{
|
193
|
+
fail KeyError, "No marking feature '#{arg}' in this feature set!"
|
194
194
|
end
|
195
195
|
end
|
196
196
|
end
|
@@ -201,14 +201,14 @@ class YPetri::Net::State::Features < Array
|
|
201
201
|
# array of corresponding features from this feature set. If no argument is
|
202
202
|
# given, all the firing features from this set are returned.
|
203
203
|
#
|
204
|
-
def firing
|
205
|
-
return firing( select { |
|
206
|
-
case
|
207
|
-
when Array then self.class.new(
|
204
|
+
def firing arg=nil
|
205
|
+
return firing( select { |feat| feat.is_a? Firing() } ) if arg.nil?
|
206
|
+
case arg
|
207
|
+
when Array then self.class.new( arg.map { |id| firing id } )
|
208
208
|
else
|
209
|
-
Firing(
|
209
|
+
Firing( arg ).tap do |feature|
|
210
210
|
include? feature or
|
211
|
-
fail KeyError, "No firing feature '#{
|
211
|
+
fail KeyError, "No firing feature '#{arg}' in this feature set!"
|
212
212
|
end
|
213
213
|
end
|
214
214
|
end
|
@@ -219,14 +219,14 @@ class YPetri::Net::State::Features < Array
|
|
219
219
|
# of corresponding features from this feature set. If no argument is given,
|
220
220
|
# all the flux features from this set are returned.
|
221
221
|
#
|
222
|
-
def flux
|
223
|
-
return flux( select { |
|
224
|
-
case
|
225
|
-
when Array then self.class.new(
|
222
|
+
def flux arg=nil
|
223
|
+
return flux( select { |feat| feat.is_a? Flux() } ) if arg.nil?
|
224
|
+
case arg
|
225
|
+
when Array then self.class.new( arg.map { |id| flux id } )
|
226
226
|
else
|
227
|
-
Flux(
|
227
|
+
Flux( arg ).tap do |feature|
|
228
228
|
include? feature or
|
229
|
-
fail KeyError, "No flux feature '#{
|
229
|
+
fail KeyError, "No flux feature '#{arg}' in this feature set!"
|
230
230
|
end
|
231
231
|
end
|
232
232
|
end
|
@@ -239,18 +239,19 @@ class YPetri::Net::State::Features < Array
|
|
239
239
|
# corresponding features from this feature set. If no argument is given,
|
240
240
|
# all the gradient features from this feature set are returned.
|
241
241
|
#
|
242
|
-
def gradient
|
243
|
-
if
|
244
|
-
return gradient( select { |
|
245
|
-
|
242
|
+
def gradient arg=nil, transitions: nil
|
243
|
+
if arg.nil? then
|
244
|
+
return gradient( select { |feat| feat.is_a? Gradient() } ) if
|
245
|
+
transitions.nil?
|
246
|
+
gradient.select { |feat| feat.transitions == net.tt( transitions ) }
|
246
247
|
else
|
247
|
-
case
|
248
|
+
case arg
|
248
249
|
when Array then
|
249
|
-
self.class.new(
|
250
|
+
self.class.new( arg.map { |id| gradient id, transitions: transitions } )
|
250
251
|
else
|
251
|
-
Gradient(
|
252
|
+
Gradient( arg, transitions: transitions ).tap do |feature|
|
252
253
|
include? feature or
|
253
|
-
fail KeyError, "No gradient feature '#{
|
254
|
+
fail KeyError, "No gradient feature '#{arg}' in this fature set!"
|
254
255
|
end
|
255
256
|
end
|
256
257
|
end
|
@@ -263,18 +264,19 @@ class YPetri::Net::State::Features < Array
|
|
263
264
|
# identifiers is supplied, it is mapped to the array of corresponding features
|
264
265
|
# from thie feature set.
|
265
266
|
#
|
266
|
-
def delta
|
267
|
-
if
|
268
|
-
return delta( select { |
|
269
|
-
|
267
|
+
def delta arg=nil, transitions: nil
|
268
|
+
if arg.nil? then
|
269
|
+
return delta( select { |feat| feat.is_a? Delta() } ) if
|
270
|
+
transitions.nil?
|
271
|
+
delta.select { |feat| feat.transitions == net.tt( transitions ) }
|
270
272
|
else
|
271
|
-
case
|
273
|
+
case arg
|
272
274
|
when Array then
|
273
|
-
self.class.new(
|
275
|
+
self.class.new( arg.map { |id| delta id, transitions: transitions } )
|
274
276
|
else
|
275
|
-
Delta(
|
277
|
+
Delta( arg, transitions: transitions ).tap do |feature|
|
276
278
|
include? feature or
|
277
|
-
fail KeyError, "No delta feature '#{
|
279
|
+
fail KeyError, "No delta feature '#{arg}' in this feature set!"
|
278
280
|
end
|
279
281
|
end
|
280
282
|
end
|
data/lib/y_petri/net.rb
CHANGED
@@ -135,7 +135,8 @@ class YPetri::Net
|
|
135
135
|
def to_s
|
136
136
|
"#<Net: " +
|
137
137
|
( name.nil? ? "%s" : "name: #{name}, %s" ) %
|
138
|
-
"#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions" +
|
138
|
+
"#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions" +
|
139
|
+
">"
|
139
140
|
end
|
140
141
|
|
141
142
|
# Inspect string of the instance.
|
@@ -92,7 +92,13 @@ class YPetri::Simulation
|
|
92
92
|
# given, starting vector is used.
|
93
93
|
#
|
94
94
|
def reset! arg=self.class.starting
|
95
|
-
arg
|
95
|
+
case arg
|
96
|
+
when Hash then
|
97
|
+
mapping = simulation.PlaceMapping().load( arg )
|
98
|
+
reset! places.map { |pl| mapping[ pl ] }
|
99
|
+
else # array arg assumed
|
100
|
+
arg.each.to_a.zip( annotation ).map { |value, place| set place, value }
|
101
|
+
end
|
96
102
|
end
|
97
103
|
|
98
104
|
# Access of the vector elements.
|
data/lib/y_petri/simulation.rb
CHANGED
@@ -81,21 +81,29 @@ class YPetri::Simulation
|
|
81
81
|
|
82
82
|
# The basic simulation parameter is :net – +YPetri::Net+ instance which to
|
83
83
|
# simulate. Net implies the collection of places and transitions. Other
|
84
|
-
# required attributes are
|
85
|
-
#
|
84
|
+
# required attributes are +:marking_clamps+ and +:initial_marking+
|
85
|
+
# (or +:marking -- if no +:initial_marking+ is supplied, +:marking+ will be
|
86
|
+
# used in its stead). There is a possibility to extract the initial marking
|
87
|
+
# from the net elements directly, controlled by the optional argument
|
88
|
+
# +:use_default_marking+, _true_ by default. It means that even if the caller
|
89
|
+
# does not supply required +:initial_marking+ values, the constructor will
|
90
|
+
# extract them from the places, so long as these have their initial markings
|
91
|
+
# set. Setting +:use_default_marking+ to _false_ will cause an error unless
|
92
|
+
# +:initial_marking+ and +:place_clamps+ are supplied explicitly.
|
93
|
+
#
|
86
94
|
# Simulation method is controlled by the :method argument, guarding is
|
87
|
-
# switched on and off by the :guarded argument (
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
95
|
+
# switched on and off by the :guarded argument (_true_ / _false_). Simulations
|
96
|
+
# of timed nets are timed. A timed simulation constructor may have +:time+
|
97
|
+
# (alias +:time_range+), +:step+, controlling the size of the simulation step,
|
98
|
+
# and +:sampling+, controlling the sampling period. At least one of these named
|
99
|
+
# arguments has to be set for timed simulations.
|
92
100
|
#
|
93
101
|
def initialize **settings
|
94
102
|
method = settings[:method] # the simulation method
|
95
103
|
@guarded = settings[:guarded] # guarding on / off
|
96
104
|
m_clamps = settings[:marking_clamps] || {}
|
97
105
|
m = settings[:marking]
|
98
|
-
init_m = settings[:initial_marking] || {}
|
106
|
+
init_m = settings[:initial_marking] || m || {}
|
99
107
|
use_default_marking = if settings.has? :use_default_marking then
|
100
108
|
settings[ :use_default_marking ]
|
101
109
|
else true end
|
@@ -193,7 +201,7 @@ class YPetri::Simulation
|
|
193
201
|
"#<Simulation: pp: %s, tt: %s, oid: %s>" % [ pp.size, tt.size, object_id ]
|
194
202
|
end
|
195
203
|
|
196
|
-
# Resets the simulation
|
204
|
+
# Resets the simulation.
|
197
205
|
#
|
198
206
|
def reset! **nn
|
199
207
|
m = nn[:marking]
|
data/lib/y_petri/version.rb
CHANGED
data/test/net_test.rb
CHANGED
@@ -199,3 +199,53 @@ describe YPetri::Net::State do
|
|
199
199
|
-> { @St.feature( marking: :A ) }.must_raise NameError
|
200
200
|
end
|
201
201
|
end
|
202
|
+
|
203
|
+
|
204
|
+
describe YPetri::Net::DataSet do
|
205
|
+
before do
|
206
|
+
@w = YPetri::World.new
|
207
|
+
@net = @w.Net.send :new
|
208
|
+
@net << @w.Place.send( :new, ɴ: :A )
|
209
|
+
@net << @w.Place.send( :new, ɴ: :B )
|
210
|
+
@net << @w.Transition.send( :new, ɴ: :A2B, s: { A: -1, B: 1 }, rate: 0.01 )
|
211
|
+
@net << @w.Transition.send( :new, ɴ: :A_plus, s: { A: 1 }, rate: 0.001 )
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should be constructible" do
|
215
|
+
ds = @net.State.marking( [:A, :B] ).new_dataset( type: :foobar )
|
216
|
+
ds.update foo: [ 42, 43 ]
|
217
|
+
ds.update bar: [ 43, 42 ]
|
218
|
+
ds.timed?.must_equal false
|
219
|
+
ds2 = @net.State.marking.new_dataset( type: :timed )
|
220
|
+
ds2.timed?.must_equal true
|
221
|
+
ds2.features.must_equal @net.State.marking( [:A, :B] )
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "timed dataset" do
|
225
|
+
before do
|
226
|
+
@ds = @net.State.marking.new_dataset( type: :timed )
|
227
|
+
@ds.update 0.0 => [ 0, 0 ]
|
228
|
+
@ds.update 10.0 => [ 1, 0.5 ]
|
229
|
+
@ds.update 50.0 => [ 2, 3 ]
|
230
|
+
@ds.update 200.0 => [ 2.5, 7 ]
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should give a nice plot" do
|
234
|
+
@ds.plot
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "resampling" do
|
238
|
+
before do
|
239
|
+
@resampled_ds = @ds.resample sampling: 11
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should give a nice plot" do
|
243
|
+
@resampled_ds.plot
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should be able to reconstruct the flux" do
|
247
|
+
@resampled_ds.flux.plot
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|