y_petri 2.0.15 → 2.1.3
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/{manipulator → agent}/hash_key_pointer.rb +2 -2
- data/lib/y_petri/agent/petri_net_related.rb +115 -0
- data/lib/y_petri/{manipulator → agent}/selection.rb +2 -1
- data/lib/y_petri/{manipulator/simulation_related_methods.rb → agent/simulation_related.rb} +93 -110
- data/lib/y_petri/agent.rb +22 -0
- data/lib/y_petri/core/timed/euler.rb +20 -0
- data/lib/y_petri/core/timed/pseudo_euler.rb +31 -0
- data/lib/y_petri/core/timed/quasi_euler.rb +23 -0
- data/lib/y_petri/core/timed.rb +70 -0
- data/lib/y_petri/core/timeless/pseudo_euler.rb +20 -0
- data/lib/y_petri/core/timeless.rb +12 -0
- data/lib/y_petri/core.rb +100 -0
- data/lib/y_petri/dsl.rb +66 -0
- data/lib/y_petri/fixed_assets.rb +7 -0
- data/lib/y_petri/net/element_access.rb +239 -0
- data/lib/y_petri/net/state/feature/delta.rb +88 -0
- data/lib/y_petri/net/state/feature/firing.rb +57 -0
- data/lib/y_petri/net/state/feature/flux.rb +58 -0
- data/lib/y_petri/net/state/feature/gradient.rb +75 -0
- data/lib/y_petri/net/state/feature/marking.rb +62 -0
- data/lib/y_petri/net/state/feature.rb +79 -0
- data/lib/y_petri/net/state/features/dataset.rb +135 -0
- data/lib/y_petri/net/state/features/record.rb +50 -0
- data/lib/y_petri/net/state/features.rb +126 -0
- data/lib/y_petri/net/state.rb +121 -0
- data/lib/y_petri/net/timed.rb +8 -0
- data/lib/y_petri/net/visualization.rb +3 -3
- data/lib/y_petri/net.rb +73 -77
- data/lib/y_petri/place.rb +8 -3
- data/lib/y_petri/simulation/dependency.rb +107 -0
- data/lib/y_petri/simulation/element_representation.rb +20 -0
- data/lib/y_petri/simulation/elements/access.rb +57 -0
- data/lib/y_petri/simulation/elements.rb +45 -0
- data/lib/y_petri/simulation/feature_set.rb +21 -0
- data/lib/y_petri/simulation/initial_marking/access.rb +55 -0
- data/lib/y_petri/simulation/initial_marking.rb +15 -0
- data/lib/y_petri/simulation/marking_clamps/access.rb +34 -0
- data/lib/y_petri/simulation/marking_clamps.rb +18 -0
- data/lib/y_petri/simulation/marking_vector/access.rb +106 -0
- data/lib/y_petri/simulation/marking_vector.rb +156 -0
- data/lib/y_petri/simulation/matrix.rb +64 -0
- data/lib/y_petri/simulation/place_mapping.rb +62 -0
- data/lib/y_petri/simulation/place_representation.rb +74 -0
- data/lib/y_petri/simulation/places/access.rb +121 -0
- data/lib/y_petri/simulation/places/clamped.rb +8 -0
- data/lib/y_petri/simulation/places/free.rb +8 -0
- data/lib/y_petri/simulation/places/types.rb +25 -0
- data/lib/y_petri/simulation/places.rb +41 -0
- data/lib/y_petri/simulation/recorder.rb +54 -0
- data/lib/y_petri/simulation/timed/recorder.rb +53 -0
- data/lib/y_petri/simulation/timed.rb +161 -261
- data/lib/y_petri/simulation/timeless/recorder.rb +25 -0
- data/lib/y_petri/simulation/timeless.rb +35 -0
- data/lib/y_petri/simulation/transition_representation/A.rb +58 -0
- data/lib/y_petri/simulation/transition_representation/S.rb +45 -0
- data/lib/y_petri/simulation/transition_representation/T.rb +80 -0
- data/lib/y_petri/simulation/transition_representation/TS.rb +46 -0
- data/lib/y_petri/simulation/transition_representation/Ts.rb +32 -0
- data/lib/y_petri/simulation/transition_representation/a.rb +30 -0
- data/lib/y_petri/simulation/transition_representation/s.rb +29 -0
- data/lib/y_petri/simulation/transition_representation/t.rb +37 -0
- data/lib/y_petri/simulation/transition_representation/tS.rb +38 -0
- data/lib/y_petri/simulation/transition_representation/ts.rb +32 -0
- data/lib/y_petri/simulation/transition_representation/types.rb +62 -0
- data/lib/y_petri/simulation/transition_representation.rb +79 -0
- data/lib/y_petri/simulation/transitions/A.rb +40 -0
- data/lib/y_petri/simulation/transitions/S.rb +24 -0
- data/lib/y_petri/simulation/transitions/T.rb +34 -0
- data/lib/y_petri/simulation/transitions/TS.rb +57 -0
- data/lib/y_petri/simulation/transitions/Ts.rb +60 -0
- data/lib/y_petri/simulation/transitions/a.rb +8 -0
- data/lib/y_petri/simulation/transitions/access.rb +186 -0
- data/lib/y_petri/simulation/transitions/s.rb +9 -0
- data/lib/y_petri/simulation/transitions/t.rb +22 -0
- data/lib/y_petri/simulation/transitions/tS.rb +55 -0
- data/lib/y_petri/simulation/transitions/ts.rb +58 -0
- data/lib/y_petri/simulation/transitions/types.rb +98 -0
- data/lib/y_petri/simulation/transitions.rb +21 -0
- data/lib/y_petri/simulation.rb +176 -781
- data/lib/y_petri/transition/assignment.rb +7 -5
- data/lib/y_petri/transition/construction.rb +119 -187
- data/lib/y_petri/transition/init.rb +311 -0
- data/lib/y_petri/transition/ordinary_timeless.rb +8 -6
- data/lib/y_petri/transition/timed.rb +11 -18
- data/lib/y_petri/transition.rb +104 -132
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri/world/dependency.rb +40 -0
- data/lib/y_petri/world/petri_net_related.rb +61 -0
- data/lib/y_petri/{workspace/simulation_related_methods.rb → world/simulation_related.rb} +42 -49
- data/lib/y_petri/world.rb +27 -0
- data/lib/y_petri.rb +47 -99
- data/test/{manipulator_test.rb → agent_test.rb} +19 -17
- data/{lib/y_petri → test/examples}/demonstrator.rb +0 -0
- data/{lib/y_petri → test/examples}/demonstrator_2.rb +1 -0
- data/{lib/y_petri → test/examples}/demonstrator_3.rb +0 -0
- data/{lib/y_petri → test/examples}/demonstrator_4.rb +0 -0
- data/test/examples/example_2.rb +16 -0
- data/test/{manual_examples.rb → examples/manual_examples.rb} +0 -0
- data/test/net_test.rb +126 -121
- data/test/place_test.rb +1 -1
- data/test/sim_test +565 -0
- data/test/simulation_test.rb +338 -264
- data/test/transition_test.rb +77 -174
- data/test/world_mock.rb +12 -0
- data/test/{workspace_test.rb → world_test.rb} +19 -20
- data/test/y_petri_test.rb +4 -5
- metadata +101 -26
- data/lib/y_petri/dependency_injection.rb +0 -45
- data/lib/y_petri/manipulator/petri_net_related_methods.rb +0 -74
- data/lib/y_petri/manipulator.rb +0 -20
- data/lib/y_petri/net/selections.rb +0 -209
- data/lib/y_petri/simulation/collections.rb +0 -460
- data/lib/y_petri/workspace/parametrized_subclassing.rb +0 -22
- data/lib/y_petri/workspace/petri_net_related_methods.rb +0 -88
- data/lib/y_petri/workspace.rb +0 -16
- data/test/timed_simulation_test.rb +0 -153
data/lib/y_petri/net.rb
CHANGED
@@ -1,102 +1,101 @@
|
|
1
1
|
#encoding: utf-8
|
2
2
|
|
3
|
-
require_relative 'dependency_injection'
|
4
3
|
require_relative 'net/visualization'
|
5
|
-
require_relative 'net/
|
4
|
+
require_relative 'net/element_access'
|
5
|
+
require_relative 'net/state'
|
6
6
|
|
7
7
|
# Represents a _Petri net_: A collection of places and transitions. The
|
8
8
|
# connector arrows – called _arcs_ in classical Petri net terminology – can be
|
9
|
-
# considered a property of transitions. Therefore in +YPetri+,
|
10
|
-
#
|
9
|
+
# considered a property of transitions. Therefore in +YPetri::Net+, you won't
|
10
|
+
# find arcs as first-class citizens, but only as a synonym denoting nearest
|
11
|
+
# neighbors of elements (places or transitions).
|
11
12
|
#
|
12
13
|
class YPetri::Net
|
13
14
|
include NameMagic
|
14
|
-
include YPetri::
|
15
|
-
|
16
|
-
attr_reader :places, :transitions
|
15
|
+
include YPetri::World::Dependency # it is important for the Dependency
|
16
|
+
include ElementAccess # to be below ElementAccess
|
17
17
|
|
18
|
+
class << self
|
19
|
+
include YPetri::World::Dependency
|
20
|
+
|
21
|
+
# Constructs a net containing a particular set of elements.
|
22
|
+
#
|
23
|
+
def of *elements
|
24
|
+
new.tap { |inst| elements.each { |e| inst << e } }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
delegate :world, to: "self.class"
|
29
|
+
|
30
|
+
# Takes 2 arguments (+:places+ and +:transitions+) and builds a net from them.
|
31
|
+
#
|
18
32
|
def initialize( places: [], transitions: [] )
|
19
|
-
|
33
|
+
param_class( { State: State }, with: { net: self } )
|
34
|
+
@places, @transitions = [], []
|
35
|
+
places.each &method( :include_place )
|
36
|
+
transitions.each &method( :include_transition )
|
37
|
+
param_class( { Simulation: YPetri::Simulation },
|
38
|
+
with: { net: self } )
|
20
39
|
end
|
21
40
|
|
22
41
|
# Includes a place in the net. Returns _true_ if successful, _false_ if the
|
23
42
|
# place is already included in the net.
|
24
43
|
#
|
25
|
-
def include_place
|
26
|
-
pl =
|
27
|
-
return false if
|
28
|
-
@places << pl
|
29
|
-
return true
|
44
|
+
def include_place id
|
45
|
+
pl = Place().instance( id )
|
46
|
+
return false if includes_place? pl
|
47
|
+
true.tap { @places << pl }
|
30
48
|
end
|
31
49
|
|
32
50
|
# Includes a transition in the net. Returns _true_ if successful, _false_ if
|
33
51
|
# the transition is already included in the net. The arcs of the transition
|
34
52
|
# being included may only connect to the places already in the net.
|
35
53
|
#
|
36
|
-
def include_transition
|
37
|
-
tr =
|
38
|
-
return false if
|
39
|
-
|
40
|
-
"It connects to one or more places outside the net." unless
|
41
|
-
tr.arcs.all? { |pl| include? pl }
|
42
|
-
@transitions << tr
|
43
|
-
return true
|
54
|
+
def include_transition id
|
55
|
+
tr = Transition().instance( id )
|
56
|
+
return false if includes_transition? tr
|
57
|
+
true.tap { @transitions << tr }
|
44
58
|
end
|
45
59
|
|
46
60
|
# Excludes a place from the net. Returns _true_ if successful, _false_ if the
|
47
61
|
# place was not found in the net. A place may not be excluded from the net so
|
48
62
|
# long as any transitions in the net connect to it.
|
49
63
|
#
|
50
|
-
def exclude_place
|
51
|
-
pl =
|
52
|
-
|
53
|
-
|
54
|
-
return true if @places.delete pl
|
55
|
-
return false
|
64
|
+
def exclude_place id
|
65
|
+
pl = Place().instance( id )
|
66
|
+
msg = "Unable to exclude #{pl} from #{self}: Transition(s) depend on it!"
|
67
|
+
fail msg if transitions.any? { |tr| tr.arcs.include? pl }
|
68
|
+
false.tap { return true if @places.delete( pl ) }
|
56
69
|
end
|
57
70
|
|
58
71
|
# Excludes a transition from the net. Returns _true_ if successful, _false_ if
|
59
72
|
# the transition was not found in the net.
|
60
73
|
#
|
61
|
-
def exclude_transition
|
62
|
-
tr =
|
63
|
-
return true if @transitions.delete tr
|
64
|
-
return false
|
74
|
+
def exclude_transition id
|
75
|
+
tr = Transition().instance( id )
|
76
|
+
false.tap { return true if @transitions.delete( tr ) }
|
65
77
|
end
|
66
78
|
|
67
|
-
# Includes an
|
68
|
-
# +#include_place!+ or +#include_transition!+, as needed, swallowing errors.
|
79
|
+
# Includes an element in the net.
|
69
80
|
#
|
70
|
-
def <<
|
71
|
-
begin
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
place( place_or_transition )
|
89
|
-
rescue NameError
|
90
|
-
nil
|
91
|
-
end
|
92
|
-
return places.include? pl if pl
|
93
|
-
tr = begin
|
94
|
-
transition( place_or_transition )
|
95
|
-
rescue NameError
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
return transitions.include? tr if tr
|
99
|
-
return false
|
81
|
+
def << element_id
|
82
|
+
element_type, element = begin
|
83
|
+
[ :place,
|
84
|
+
self.class.place( element_id ) ]
|
85
|
+
rescue NameError, TypeError
|
86
|
+
begin
|
87
|
+
[ :transition,
|
88
|
+
self.class.transition( element_id ) ]
|
89
|
+
rescue NameError, TypeError => err
|
90
|
+
msg = "Current world contains no place or" +
|
91
|
+
"transition identified by #{element_id}!"
|
92
|
+
raise TypeError, "#{msg} (#{err})"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
case element_type
|
96
|
+
when :place then include_place( element )
|
97
|
+
when :transition then include_transition( element )
|
98
|
+
else fail "Mangled method YPetri::Net#<<!" end
|
100
99
|
end
|
101
100
|
|
102
101
|
# Is the net _functional_?
|
@@ -104,40 +103,37 @@ class YPetri::Net
|
|
104
103
|
def functional?
|
105
104
|
transitions.all? { |t| t.functional? }
|
106
105
|
end
|
107
|
-
|
106
|
+
|
108
107
|
# Is the net <em>timed</em>?
|
109
108
|
#
|
110
109
|
def timed?
|
111
|
-
transitions.
|
110
|
+
transitions.any? { |t| t.timed? }
|
112
111
|
end
|
113
112
|
|
114
113
|
# Creates a new simulation from the net.
|
115
114
|
#
|
116
|
-
def
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
# Creates a new timed simulation from the net.
|
121
|
-
#
|
122
|
-
def new_timed_simulation( **nn )
|
123
|
-
new_simulation( **nn ).aT &:timed?
|
115
|
+
def simulation( **settings )
|
116
|
+
Simulation().__new__ **settings
|
124
117
|
end
|
125
118
|
|
126
119
|
# Networks are equal when their places and transitions are equal.
|
127
120
|
#
|
128
121
|
def == other
|
129
|
-
return false unless other.class_complies?(
|
122
|
+
return false unless other.class_complies?( self.class )
|
130
123
|
places == other.places && transitions == other.transitions
|
131
124
|
end
|
132
125
|
|
133
126
|
# Returns a string briefly describing the net.
|
134
127
|
#
|
135
128
|
def to_s
|
136
|
-
"#<Net: " +
|
137
|
-
|
129
|
+
"#<Net: " +
|
130
|
+
( name.nil? ? "%s" : "name: #{name}, %s" ) %
|
131
|
+
"#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions" + ">"
|
138
132
|
end
|
139
133
|
|
140
134
|
# Inspect string of the instance.
|
141
135
|
#
|
142
|
-
def inspect
|
136
|
+
def inspect
|
137
|
+
to_s
|
138
|
+
end
|
143
139
|
end # class YPetri::Net
|
data/lib/y_petri/place.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
require_relative 'dependency_injection'
|
4
3
|
require_relative 'place/guard'
|
5
4
|
require_relative 'place/arcs'
|
6
5
|
|
@@ -8,7 +7,13 @@ require_relative 'place/arcs'
|
|
8
7
|
#
|
9
8
|
class YPetri::Place
|
10
9
|
include NameMagic
|
11
|
-
include YPetri::
|
10
|
+
include YPetri::World::Dependency
|
11
|
+
|
12
|
+
class << self
|
13
|
+
include YPetri::World::Dependency
|
14
|
+
end
|
15
|
+
|
16
|
+
delegate :world, to: "self.class"
|
12
17
|
|
13
18
|
attr_reader :quantum
|
14
19
|
attr_reader :guards
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# Place / transition collection mixin for parametrized classes of
|
4
|
+
# YPetri::Simulation. Expects the module where it is included to define
|
5
|
+
# +#simulation+ method returning the current simulation instance.
|
6
|
+
#
|
7
|
+
class YPetri::Simulation
|
8
|
+
module Dependency
|
9
|
+
delegate :Place,
|
10
|
+
:Transition,
|
11
|
+
:MarkingClamp,
|
12
|
+
:InitialMarkingObject,
|
13
|
+
:Places,
|
14
|
+
:Transitions,
|
15
|
+
:MarkingClamps,
|
16
|
+
:InitialMarking,
|
17
|
+
:net,
|
18
|
+
:p, :t, :e,
|
19
|
+
:pp, :tt, :ee,
|
20
|
+
:free_pp, :clamped_pp,
|
21
|
+
:ts_tt, :tS_tt, :Ts_tt, :TS_tt,
|
22
|
+
:t_tt, :T_tt, :s_tt, :S_tt,
|
23
|
+
:A_tt,
|
24
|
+
:f2a, :c2a,
|
25
|
+
:m_vector,
|
26
|
+
:recorder,
|
27
|
+
to: :simulation
|
28
|
+
|
29
|
+
# Delegates to the protected (and private) methods of simulation.
|
30
|
+
#
|
31
|
+
def self.delegate_to_simulation! *symbols
|
32
|
+
symbols.each do |sym|
|
33
|
+
module_exec do
|
34
|
+
define_method sym do |*aa, &b| simulation.send sym, *aa, &b end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def element *args, &block
|
40
|
+
simulation.send :element, *args, &block
|
41
|
+
end
|
42
|
+
|
43
|
+
def place *args, &block
|
44
|
+
simulation.send :place, *args, &block
|
45
|
+
end
|
46
|
+
|
47
|
+
def transition *args, &block
|
48
|
+
simulation.send :transition, *args, &block
|
49
|
+
end
|
50
|
+
|
51
|
+
def elements *args, &block
|
52
|
+
simulation.send :elements, *args, &block
|
53
|
+
end
|
54
|
+
|
55
|
+
def places *args, &block
|
56
|
+
simulation.send :places, *args, &block
|
57
|
+
end
|
58
|
+
|
59
|
+
def transitions *args, &block
|
60
|
+
simulation.send :transitions, *args, &block
|
61
|
+
end
|
62
|
+
|
63
|
+
def free_places *args, &block
|
64
|
+
simulation.send :free_places, *args, &block
|
65
|
+
end
|
66
|
+
|
67
|
+
def clamped_places *args, &block
|
68
|
+
simulation.send :clamped_places, *args, &block
|
69
|
+
end
|
70
|
+
|
71
|
+
def ts_transitions *args, &block
|
72
|
+
simulation.send :ts_transitions, *args, &block
|
73
|
+
end
|
74
|
+
|
75
|
+
def tS_transitions *args, &block
|
76
|
+
simulation.send :tS_transitions, *args, &block
|
77
|
+
end
|
78
|
+
|
79
|
+
def Ts_transitions *args, &block
|
80
|
+
simulation.send :Ts_transitions, *args, &block
|
81
|
+
end
|
82
|
+
|
83
|
+
def TS_transitions *args, &block
|
84
|
+
simulation.send :TS_transitions, *args, &block
|
85
|
+
end
|
86
|
+
|
87
|
+
def t_transitions *args, &block
|
88
|
+
simulation.send :t_transitions, *args, &block
|
89
|
+
end
|
90
|
+
|
91
|
+
def T_transitions *args, &block
|
92
|
+
simulation.send :T_transitions, *args, &block
|
93
|
+
end
|
94
|
+
|
95
|
+
def s_transitions *args, &block
|
96
|
+
simulation.send :s_transitions, *args, &block
|
97
|
+
end
|
98
|
+
|
99
|
+
def S_transitions *args, &block
|
100
|
+
simulation.send :S_transitions, *args, &block
|
101
|
+
end
|
102
|
+
|
103
|
+
def A_transitions *args, &block
|
104
|
+
simulation.send :A_transitions, *args, &block
|
105
|
+
end
|
106
|
+
end # class Dependency
|
107
|
+
end # class YPetri::Simulation
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# Representation of a YPetri::Place inside a YPetri::Simulation instance.
|
4
|
+
#
|
5
|
+
class YPetri::Simulation
|
6
|
+
class ElementRepresentation
|
7
|
+
include NameMagic
|
8
|
+
include Dependency
|
9
|
+
|
10
|
+
attr_reader :source # source place
|
11
|
+
|
12
|
+
delegate :simulation, to: "self.class"
|
13
|
+
|
14
|
+
# Expect a single YPetri place as an argument.
|
15
|
+
#
|
16
|
+
def initialize net_element_id
|
17
|
+
@source = net.element( net_element_id )
|
18
|
+
end
|
19
|
+
end # class ElementRepresentation
|
20
|
+
end # class YPetri::Simulation
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# Simulation mixin providing access to elements (an element is either a
|
4
|
+
# place, or a transition -- see also mixins +Places::Access+ and
|
5
|
+
# +Transitions::Access+.
|
6
|
+
#
|
7
|
+
class YPetri::Simulation::Elements
|
8
|
+
module Access
|
9
|
+
# Does an element belong to the simulation?
|
10
|
+
#
|
11
|
+
def includes?( id )
|
12
|
+
includes_place?( id ) || includes_transition?( id )
|
13
|
+
end
|
14
|
+
alias include? includes?
|
15
|
+
|
16
|
+
# Element of the simulation (belonging to the net).
|
17
|
+
#
|
18
|
+
def e( id )
|
19
|
+
element( id ).source
|
20
|
+
end
|
21
|
+
|
22
|
+
# Elements of the simulation (belonging to the net).
|
23
|
+
#
|
24
|
+
def ee( ids=nil )
|
25
|
+
elements( ids ).sources
|
26
|
+
end
|
27
|
+
|
28
|
+
# Names of the simulation's elements. Arguments, if any, are treated
|
29
|
+
# analogically to the +#elements+ method.
|
30
|
+
#
|
31
|
+
def en ids=nil
|
32
|
+
elements( ids ).names
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
# Element instance identification.
|
38
|
+
#
|
39
|
+
def element( id )
|
40
|
+
if include_place? id
|
41
|
+
return place( id )
|
42
|
+
end
|
43
|
+
if include_transition? id
|
44
|
+
return transition( id )
|
45
|
+
end
|
46
|
+
fail TypeError, "No element #{id} in the simulation!"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Without arguments, returns all the elements (places + transitions). If
|
50
|
+
# arguments are given, they are converted into elements.
|
51
|
+
#
|
52
|
+
def elements ids=nil
|
53
|
+
return places + transitions if ids.nil?
|
54
|
+
ids.map { |id| element id }
|
55
|
+
end
|
56
|
+
end # module Access
|
57
|
+
end # class YPetri::Simulation::Elements
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Basic elements of a simulation, a mixin intended for YPetri::Simulation.
|
2
|
+
#
|
3
|
+
class YPetri::Simulation
|
4
|
+
class Elements < Array
|
5
|
+
include Dependency
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# New collection constructor
|
9
|
+
#
|
10
|
+
def load collection
|
11
|
+
new.tap { |inst| inst.load collection }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
delegate :simulation, to: "self.class"
|
16
|
+
|
17
|
+
# Loads elements to this collection.
|
18
|
+
#
|
19
|
+
def load elements
|
20
|
+
elements.each{ |e| push e }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Creates a subset of this collection (of the same class).
|
24
|
+
#
|
25
|
+
def subset element_ids=nil, &block
|
26
|
+
if block_given? then
|
27
|
+
msg = "If block is given, arguments are not allowed!"
|
28
|
+
fail ArgumentError, msg unless element_ids.nil?
|
29
|
+
self.class.load select( &block )
|
30
|
+
else
|
31
|
+
ee = elements( element_ids )
|
32
|
+
ee.all? { |e| include? e } or
|
33
|
+
fail TypeError, "All subset elements must be in the collection."
|
34
|
+
self.class.load( ee )
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns an array of the element sources (elemens in the original net).
|
39
|
+
#
|
40
|
+
def sources
|
41
|
+
map &:source
|
42
|
+
end
|
43
|
+
alias to_sources sources
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Basic elements of a simulation, a mixin intended for YPetri::Simulation.
|
2
|
+
#
|
3
|
+
class YPetri::Simulation
|
4
|
+
# Represents a set of features of a simulation state.
|
5
|
+
#
|
6
|
+
class FeatureSet
|
7
|
+
include DependencyInjection
|
8
|
+
|
9
|
+
attr_reader :marking, :firing, :delta
|
10
|
+
|
11
|
+
# Initializes the feature set.
|
12
|
+
#
|
13
|
+
def initialize marking: [], firing: [],
|
14
|
+
delta: { places: [], transitions: [] }
|
15
|
+
@marking = x
|
16
|
+
|
17
|
+
@firing =
|
18
|
+
@marking, @firing, @delta = marking, firing, delta
|
19
|
+
end
|
20
|
+
end # class FeatureSet
|
21
|
+
end # YPetri::Simulation
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# Simulation mixin providing access to the initial marking.
|
4
|
+
#
|
5
|
+
class YPetri::Simulation::InitialMarking
|
6
|
+
module Access
|
7
|
+
# Without arguments, acts as a getter of @initial_marking. If arguments are
|
8
|
+
# supplied, they must identify free places, and are mapped to their initial
|
9
|
+
# marking.
|
10
|
+
#
|
11
|
+
def initial_marking ids=nil
|
12
|
+
if ids.nil? then
|
13
|
+
@initial_marking or
|
14
|
+
fail TypeError, "InitialMarking object not instantiated yet!"
|
15
|
+
else
|
16
|
+
free_places( ids ).map { |pl| initial_marking[ place( pl ) ] }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Without arguments, returns the marking of all the simulation's places
|
21
|
+
# (both free and clamped) as it appears after reset. If arguments are
|
22
|
+
# supplied, they must identify places, and are converted to either their
|
23
|
+
# initial marking (free places), or their clamp value (clamped places).
|
24
|
+
#
|
25
|
+
def im ids=nil
|
26
|
+
return im( places ) if ids.nil?
|
27
|
+
places( ids ).map { |pl|
|
28
|
+
pl.free? ? initial_marking( of: pl ) : marking_clamp( of: pl )
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns initial marking vector for free places. Like +#initial_marking+,
|
33
|
+
# but returns a column vector.
|
34
|
+
#
|
35
|
+
def initial_marking_vector ids=nil
|
36
|
+
initial_marking( ids ).to_column_vector
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns initial marking vector for all places. Like +#initial_marking+,
|
40
|
+
# but returns a column vector.
|
41
|
+
#
|
42
|
+
def im_vector ids=nil
|
43
|
+
im( ids ).to_column_vector
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Sets the initial marking of a place (frontend of +InitialMarking#set+).
|
49
|
+
#
|
50
|
+
def set_initial_marking( of: (fail ArgumentError), to: (fail ArgumentError) )
|
51
|
+
initial_marking.set( of, to: to )
|
52
|
+
end
|
53
|
+
end # module Access
|
54
|
+
end # class YPetri::Simulation::InitialMarking
|
55
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Manages the initial marking of a simulation.
|
2
|
+
#
|
3
|
+
class YPetri::Simulation
|
4
|
+
class InitialMarking < PlaceMapping
|
5
|
+
# Sets the initial marking for a given place to a given value.
|
6
|
+
#
|
7
|
+
def set( place_id, to: (fail ArgumentError) )
|
8
|
+
fail TypeError, "The place #{place_id} is already clamped!" if
|
9
|
+
begin # fails if marking clamps are not set yet
|
10
|
+
place( place_id ).clamped?
|
11
|
+
rescue TypeError, NoMethodError; end
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end # class InitialMarking
|
15
|
+
end # class YPetri::Simulation
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# Simulation mixin providing access to the marking clamps.
|
4
|
+
#
|
5
|
+
class YPetri::Simulation::MarkingClamps
|
6
|
+
module Access
|
7
|
+
# Without arguments, acts as a getter of the @marking_clamp hash. If
|
8
|
+
# arguments are supplied, they must identify clamped places, and are mapped
|
9
|
+
# to their clamp values.
|
10
|
+
#
|
11
|
+
def marking_clamps ids=nil
|
12
|
+
if ids.nil? then
|
13
|
+
@marking_clamps or
|
14
|
+
fail TypeError, "MarkingClamps object not instantiated yet!"
|
15
|
+
else
|
16
|
+
clamped_places( ids ).map { |p| marking_clamp of: p }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
alias clamps marking_clamps
|
20
|
+
|
21
|
+
# Marking clamp identification.
|
22
|
+
#
|
23
|
+
def marking_clamp( of: (fail ArgumentError) )
|
24
|
+
marking_clamps.clamp_of( of )
|
25
|
+
end
|
26
|
+
|
27
|
+
# Sets the marking clamp of a place (frontend of +InitialMarking#set+).
|
28
|
+
#
|
29
|
+
def set_marking_clamp( of: (fail ArgumentError), to: (fail ArgumentError) )
|
30
|
+
marking_clamps.set( of, to: to )
|
31
|
+
end
|
32
|
+
end # module Access
|
33
|
+
end # class YPetri::Simulation::MarkingClamps
|
34
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Collection of marking clamps for YPetri::Simulation.
|
2
|
+
#
|
3
|
+
class YPetri::Simulation
|
4
|
+
class MarkingClamps < PlaceMapping
|
5
|
+
alias clamp_of of
|
6
|
+
|
7
|
+
# Sets the clamp for a given place to a given value.
|
8
|
+
#
|
9
|
+
def set place_id, to: (fail ArgumentError, "No :to value!")
|
10
|
+
pl = place( place_id )
|
11
|
+
# free places change into clamped ones.
|
12
|
+
initial_marking.delete pl if begin # fails if initial marking not set yet
|
13
|
+
pl.free?
|
14
|
+
rescue TypeError, NoMethodError; end
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end # class MarkingClamps
|
18
|
+
end # class YPetri::Simulation
|