y_petri 2.0.15 → 2.1.3
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/{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
|