y_petri 2.4.0 → 2.4.2
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/core.rb +13 -1
- data/lib/y_petri/core/timeless.rb +1 -6
- data/lib/y_petri/core/timeless/basic.rb +1 -1
- data/lib/y_petri/simulation/timed.rb +6 -2
- data/lib/y_petri/simulation/timeless.rb +34 -21
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri/world/simulation_aspect.rb +5 -5
- data/test/core_test.rb +38 -1
- data/test/examples/issues.rb +71 -0
- data/test/examples/manual_examples.rb +2 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb7a7b5033fa23e8fbdaee627d1864722a31f850
|
4
|
+
data.tar.gz: b17971ab72080978c0877a281e6a22fd7dcef2df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df9453ff5bd03c744158b2d8f848c7700ea3cdc80f0c3eb6fb64c409a0436eb7bae5e7538ed86f96c3e759acd4b68c79d9b07cc0045bad0718d0ae7ea5d761ea
|
7
|
+
data.tar.gz: dd0569b0b5a0b402a78b1130b7805d3d8202ccd8219ddcdb35a18c7a10f4c479d12b4e4216f1a6c8cce84ff314ce18d228ab803e2f89d785682719d517901c2e
|
data/lib/y_petri/core.rb
CHANGED
@@ -75,7 +75,7 @@ module YPetri::Core
|
|
75
75
|
|
76
76
|
delegate :alert!, to: :recorder
|
77
77
|
|
78
|
-
# Delta
|
78
|
+
# Delta contribution to free places by timeless transitions.
|
79
79
|
#
|
80
80
|
def delta_timeless
|
81
81
|
delta_ts + delta_tS
|
@@ -112,6 +112,18 @@ module YPetri::Core
|
|
112
112
|
simulation.increment_marking_vector_closure.( delta )
|
113
113
|
end
|
114
114
|
|
115
|
+
# For now, alias method for #increment_marking_vector.
|
116
|
+
# TODO: I already said to myself that I want the core not to rely
|
117
|
+
# on the simulation's increment_marking_vector_closure.
|
118
|
+
#
|
119
|
+
def increment_free_vector( by: fail( "No delta given!" ) )
|
120
|
+
print '.'
|
121
|
+
simulation.increment_marking_vector_closure.( by )
|
122
|
+
# Also, here it is not clear that #increment_marking_vector_closure
|
123
|
+
# returns a closure that expects only Δ for free places. Should have
|
124
|
+
# better mnemonic name.
|
125
|
+
end
|
126
|
+
|
115
127
|
# Fires all the assignment transitions.
|
116
128
|
#
|
117
129
|
def fire_all_assignment_transitions!
|
@@ -31,10 +31,5 @@ class YPetri::Core::Timeless
|
|
31
31
|
delta_timeless # this method was taken from core.rb
|
32
32
|
# delta_ts + delta_tS # this is the contents of delta_timeless method
|
33
33
|
end
|
34
|
-
|
35
|
-
# Computes the system state delta.
|
36
|
-
#
|
37
|
-
def Δ
|
38
|
-
delta
|
39
|
-
end
|
34
|
+
alias Δ delta
|
40
35
|
end # module YPetri::Core::Timeless
|
@@ -10,7 +10,7 @@ module YPetri::Core::Timeless::Basic
|
|
10
10
|
def step!
|
11
11
|
# Compute the sum of the contribution of ts and tS transitions, and
|
12
12
|
# increment the free marking vector by it.
|
13
|
-
increment_free_vector by:
|
13
|
+
increment_free_vector by: Δ
|
14
14
|
# Fire all the assignment transitions in their order.
|
15
15
|
fire_all_assignment_transitions!
|
16
16
|
# before: assignment_transitions_all_fire!
|
@@ -349,9 +349,13 @@ module YPetri::Simulation::Timed
|
|
349
349
|
else
|
350
350
|
YPetri::Core::Timed.new( simulation: self, method: method, guarded: false )
|
351
351
|
end
|
352
|
+
# TODO: But why am I doing it like this? Did I want to emphasize the standalone
|
353
|
+
# nature of Core class? Maybe... And maybe I did it so that the runge-kutta method
|
354
|
+
# with its @rk_core instance variable instead of @core does not have @core and #core.
|
355
|
+
# In this manner, I'm forcing myself to rethink Simulation class.
|
352
356
|
singleton_class.class_exec do
|
353
357
|
attr_reader :core
|
354
|
-
delegate :simulation_method,
|
358
|
+
delegate :simulation_method, # this looks quite redundant with simulation.rb
|
355
359
|
:step!,
|
356
360
|
:firing_vector_tS,
|
357
361
|
to: :core
|
@@ -370,5 +374,5 @@ module YPetri::Simulation::Timed
|
|
370
374
|
else
|
371
375
|
Recorder().new( sampling: settings[:sampling] )
|
372
376
|
end
|
373
|
-
end
|
377
|
+
end # def init
|
374
378
|
end # module YPetri::Simulation::Timed
|
@@ -27,26 +27,39 @@ module YPetri::Simulation::Timeless
|
|
27
27
|
method = settings[:method] # the simulation method
|
28
28
|
features_to_record = settings[:record]
|
29
29
|
# Sets up a parametrized subclass of the sampler for timeless simulation.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
Recorder().new # init the recorder
|
50
|
-
end
|
30
|
+
param_class( { Recorder: Recorder }, with: { simulation: self } )
|
31
|
+
@core = if @guarded then
|
32
|
+
YPetri::Core::Timeless
|
33
|
+
.new( simulation: self, method: method, guarded: true )
|
34
|
+
else
|
35
|
+
YPetri::Core::Timeless
|
36
|
+
.new( simulation: self, method: method, guarded: false )
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: But why am I doing it like this? Did I want to emphasize the standalone
|
40
|
+
# nature of Core class? Maybe... And maybe I did it so that the runge-kutta method
|
41
|
+
# with its @rk_core instance variable instead of @core does not have @core and #core.
|
42
|
+
# In this manner, I'm forcing myself to rethink Simulation class.
|
43
|
+
singleton_class.class_exec do
|
44
|
+
attr_reader :core
|
45
|
+
delegate :simulation_method, # this looks quite redundant with simulation.rb
|
46
|
+
:step!,
|
47
|
+
:firing_vector_tS,
|
48
|
+
to: :core
|
51
49
|
end
|
50
|
+
|
51
|
+
@recorder = if features_to_record then
|
52
|
+
# we'll have to figure out features
|
53
|
+
ff = case features_to_record
|
54
|
+
when Array then
|
55
|
+
net.State.Features
|
56
|
+
.infer_from_nodes( features_to_record )
|
57
|
+
when Hash then
|
58
|
+
net.State.features( features_to_record )
|
59
|
+
end
|
60
|
+
Recorder().new( features: ff )
|
61
|
+
else
|
62
|
+
Recorder().new # init the recorder
|
63
|
+
end
|
64
|
+
end # def init
|
52
65
|
end # module YPetri::Simulation::Timeless
|
data/lib/y_petri/version.rb
CHANGED
@@ -321,7 +321,7 @@ module YPetri::World::SimulationAspect
|
|
321
321
|
#
|
322
322
|
# * default_ss = { step_size: 0.1, sampling_period: 5, target_time: 60 }
|
323
323
|
#
|
324
|
-
def new_simulation( net: Net()
|
324
|
+
def new_simulation( net: Net().instance( :Top ), **nn )
|
325
325
|
net_inst = net( net )
|
326
326
|
nn.may_have :cc, syn!: :clamp_collection
|
327
327
|
nn.may_have :imc, syn!: :initial_marking_collection
|
@@ -330,13 +330,13 @@ module YPetri::World::SimulationAspect
|
|
330
330
|
imc_id = nn.delete( :imc ) || :Base
|
331
331
|
ssc_id = nn.delete( :ssc ) || :Base
|
332
332
|
# Construct the simulation key:
|
333
|
-
key = if nn.has? :name, syn!: :ɴ then
|
333
|
+
key = if nn.has? :name, syn!: :ɴ then # explicit key (name)
|
334
334
|
nn[:name]
|
335
|
-
else
|
335
|
+
else # constructed key
|
336
336
|
{}.merge( net: net_inst,
|
337
337
|
cc: cc_id,
|
338
|
-
|
339
|
-
|
338
|
+
imc: imc_id,
|
339
|
+
ssc: ssc_id )
|
340
340
|
.merge( nn )
|
341
341
|
end
|
342
342
|
# Let's clarify what we got so far.
|
data/test/core_test.rb
CHANGED
@@ -7,8 +7,10 @@ require_relative '../lib/y_petri' # tested component itself
|
|
7
7
|
# require 'y_petri'
|
8
8
|
# require 'sy'
|
9
9
|
|
10
|
-
describe "
|
10
|
+
describe "core" do
|
11
11
|
before do
|
12
|
+
@timed_core_class = YPetri::Core::Timed
|
13
|
+
@timeless_core_class = YPetri::Core::Timeless
|
12
14
|
# set up a user of core, which will imitate some of the needs
|
13
15
|
# of the Simulation class, or be an actual instance of that class
|
14
16
|
end
|
@@ -22,5 +24,40 @@ describe "use of timed and timeless core" do
|
|
22
24
|
# number of steps or until some other condition is fulfilled, or
|
23
25
|
# step backward, or even run backward, if the system allows such thing
|
24
26
|
# at all.
|
27
|
+
@timed_core_class::METHODS.keys.must_include :basic
|
28
|
+
@timeless_core_class::METHODS.keys.must_include :basic
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "timed core" do
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "timeless core" do
|
35
|
+
describe "basic method" do
|
36
|
+
before do
|
37
|
+
# @timeless_core_class.new( method: :basic )
|
38
|
+
# TODO: The above logically fails, because core now
|
39
|
+
# requires simulation. But newly, a core should no
|
40
|
+
# longer require a simulation. It should simply receive
|
41
|
+
# initial marking vector, information about places
|
42
|
+
# (including clamped places and their clamps), information
|
43
|
+
# above processes (ie. transitions). Surely, this looks
|
44
|
+
# like a third redundant layer of place and transition
|
45
|
+
# representations (the first two are in Net and Simulation
|
46
|
+
# class). But it serves me right since I want to do things
|
47
|
+
# properly :-) Core represents a simulation machine,
|
48
|
+
# hardware. Of course, I have no hardware other than
|
49
|
+
# Ruby itself. I am not even able to compile the simulation
|
50
|
+
# into C. It is quite imaginable that Simulation would
|
51
|
+
# be flexible about using cores and simulation methods
|
52
|
+
# to do what the user requires it to do, while cores would
|
53
|
+
# be more inflexible, method specific and machine specific.
|
54
|
+
# So Core is a machine abstraction, while Simulation is the
|
55
|
+
# abstraction of what the user might require from a Simulation.
|
56
|
+
# Anyway a good way to kill time.
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should behave" do
|
60
|
+
end
|
61
|
+
end
|
25
62
|
end
|
26
63
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# Found things that do not work with YPetri.
|
4
|
+
|
5
|
+
require 'y_petri'
|
6
|
+
include YPetri
|
7
|
+
|
8
|
+
A = Place default_marking: 5
|
9
|
+
B = Place default_marking: 5
|
10
|
+
C = Place default_marking: 0
|
11
|
+
D = Place default_marking: 0
|
12
|
+
|
13
|
+
T1 = Transition stoichiometry: { A: -1, B: -1, C: 1 }
|
14
|
+
T2 = Transition stoichiometry: { C: -1, D: 1 }
|
15
|
+
|
16
|
+
net.timed? # The net is timeless
|
17
|
+
|
18
|
+
new_simulation # This produces timed simulation (same as run!)
|
19
|
+
|
20
|
+
net.simulation # While this produces timeless simulation.
|
21
|
+
|
22
|
+
# This is happening because I have deleted :core selector from
|
23
|
+
# Simulation class code. I did this because when adding Runge-Kutta
|
24
|
+
# method, I construct instance-specific instance variable @rk_core
|
25
|
+
# instead of @core.
|
26
|
+
|
27
|
+
# This, again, will produce timed simulation.
|
28
|
+
net.simulation **ssc
|
29
|
+
|
30
|
+
# Simulation#initialize has hard times deciding whether it is
|
31
|
+
# constructing timed or timeless simulation. When it sees time
|
32
|
+
# mentioned (:step, :sampling, :time parameters are all set)
|
33
|
+
# in ssc, it decides to construct a timed simulation.
|
34
|
+
#
|
35
|
+
# When it does not see the time mentioned, it decides to construct
|
36
|
+
# a timeless simulation. The decision is quite right when I merely
|
37
|
+
# call net.simulation, because the net is actually quite timeless.
|
38
|
+
#
|
39
|
+
# But once I call for :basic simulation method ...
|
40
|
+
#
|
41
|
+
# Now I used to call :basic method :pseudo_euler, which would suggest
|
42
|
+
# timed simulation. But timeless simulations also have :basic method
|
43
|
+
# among them...
|
44
|
+
#
|
45
|
+
# The question is whether I should have timed and timeless methods
|
46
|
+
# with same names...
|
47
|
+
|
48
|
+
# I should keep at this and rethink the Simulation class
|
49
|
+
|
50
|
+
# also, another problem
|
51
|
+
#
|
52
|
+
# set_ssc :Hello
|
53
|
+
#
|
54
|
+
# instead of trying to set the simulation settings collection
|
55
|
+
# to the one named :Hello will cause the simulation settings
|
56
|
+
# collection named :Base be set to :Hello
|
57
|
+
|
58
|
+
simulation_settings_collection # alias ssc
|
59
|
+
|
60
|
+
simulation_settings_collections
|
61
|
+
|
62
|
+
set_simulation_settings_collection :Hello
|
63
|
+
|
64
|
+
simulation_settings_collection # alias ssc
|
65
|
+
|
66
|
+
simulation_settings_collections
|
67
|
+
|
68
|
+
# This is obviously wrong. Whole idea of collections of clamps
|
69
|
+
# and initial values and simulation settings is quite dated, it
|
70
|
+
# dates back to the times when I was not at the top of my Ruby
|
71
|
+
# proficiency yet. Maybe time to rethink World / Agent classes.
|
@@ -9,7 +9,7 @@ set_step 10
|
|
9
9
|
set_target_time 600
|
10
10
|
set_sampling 10
|
11
11
|
# Euler with timeless transitions firing after each step:
|
12
|
-
set_simulation_method :
|
12
|
+
set_simulation_method :basic
|
13
13
|
|
14
14
|
A = Place m!: 1
|
15
15
|
B = Place m!: 10
|
@@ -25,4 +25,4 @@ Transition name: :C_held_at_half_B,
|
|
25
25
|
assignment: -> x { x / 2 }
|
26
26
|
|
27
27
|
run!
|
28
|
-
|
28
|
+
recording.plot
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: y_petri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -253,6 +253,7 @@ files:
|
|
253
253
|
- test/examples/example_2.rb
|
254
254
|
- test/examples/example_IV.rb
|
255
255
|
- test/examples/example_VI_gillespie.rb
|
256
|
+
- test/examples/issues.rb
|
256
257
|
- test/examples/manual_examples.rb
|
257
258
|
- test/net_test.rb
|
258
259
|
- test/place_test.rb
|
@@ -305,6 +306,7 @@ test_files:
|
|
305
306
|
- test/examples/example_2.rb
|
306
307
|
- test/examples/example_IV.rb
|
307
308
|
- test/examples/example_VI_gillespie.rb
|
309
|
+
- test/examples/issues.rb
|
308
310
|
- test/examples/manual_examples.rb
|
309
311
|
- test/net_test.rb
|
310
312
|
- test/place_test.rb
|