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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/lib/y_petri/{manipulator → agent}/hash_key_pointer.rb +2 -2
  3. data/lib/y_petri/agent/petri_net_related.rb +115 -0
  4. data/lib/y_petri/{manipulator → agent}/selection.rb +2 -1
  5. data/lib/y_petri/{manipulator/simulation_related_methods.rb → agent/simulation_related.rb} +93 -110
  6. data/lib/y_petri/agent.rb +22 -0
  7. data/lib/y_petri/core/timed/euler.rb +20 -0
  8. data/lib/y_petri/core/timed/pseudo_euler.rb +31 -0
  9. data/lib/y_petri/core/timed/quasi_euler.rb +23 -0
  10. data/lib/y_petri/core/timed.rb +70 -0
  11. data/lib/y_petri/core/timeless/pseudo_euler.rb +20 -0
  12. data/lib/y_petri/core/timeless.rb +12 -0
  13. data/lib/y_petri/core.rb +100 -0
  14. data/lib/y_petri/dsl.rb +66 -0
  15. data/lib/y_petri/fixed_assets.rb +7 -0
  16. data/lib/y_petri/net/element_access.rb +239 -0
  17. data/lib/y_petri/net/state/feature/delta.rb +88 -0
  18. data/lib/y_petri/net/state/feature/firing.rb +57 -0
  19. data/lib/y_petri/net/state/feature/flux.rb +58 -0
  20. data/lib/y_petri/net/state/feature/gradient.rb +75 -0
  21. data/lib/y_petri/net/state/feature/marking.rb +62 -0
  22. data/lib/y_petri/net/state/feature.rb +79 -0
  23. data/lib/y_petri/net/state/features/dataset.rb +135 -0
  24. data/lib/y_petri/net/state/features/record.rb +50 -0
  25. data/lib/y_petri/net/state/features.rb +126 -0
  26. data/lib/y_petri/net/state.rb +121 -0
  27. data/lib/y_petri/net/timed.rb +8 -0
  28. data/lib/y_petri/net/visualization.rb +3 -3
  29. data/lib/y_petri/net.rb +73 -77
  30. data/lib/y_petri/place.rb +8 -3
  31. data/lib/y_petri/simulation/dependency.rb +107 -0
  32. data/lib/y_petri/simulation/element_representation.rb +20 -0
  33. data/lib/y_petri/simulation/elements/access.rb +57 -0
  34. data/lib/y_petri/simulation/elements.rb +45 -0
  35. data/lib/y_petri/simulation/feature_set.rb +21 -0
  36. data/lib/y_petri/simulation/initial_marking/access.rb +55 -0
  37. data/lib/y_petri/simulation/initial_marking.rb +15 -0
  38. data/lib/y_petri/simulation/marking_clamps/access.rb +34 -0
  39. data/lib/y_petri/simulation/marking_clamps.rb +18 -0
  40. data/lib/y_petri/simulation/marking_vector/access.rb +106 -0
  41. data/lib/y_petri/simulation/marking_vector.rb +156 -0
  42. data/lib/y_petri/simulation/matrix.rb +64 -0
  43. data/lib/y_petri/simulation/place_mapping.rb +62 -0
  44. data/lib/y_petri/simulation/place_representation.rb +74 -0
  45. data/lib/y_petri/simulation/places/access.rb +121 -0
  46. data/lib/y_petri/simulation/places/clamped.rb +8 -0
  47. data/lib/y_petri/simulation/places/free.rb +8 -0
  48. data/lib/y_petri/simulation/places/types.rb +25 -0
  49. data/lib/y_petri/simulation/places.rb +41 -0
  50. data/lib/y_petri/simulation/recorder.rb +54 -0
  51. data/lib/y_petri/simulation/timed/recorder.rb +53 -0
  52. data/lib/y_petri/simulation/timed.rb +161 -261
  53. data/lib/y_petri/simulation/timeless/recorder.rb +25 -0
  54. data/lib/y_petri/simulation/timeless.rb +35 -0
  55. data/lib/y_petri/simulation/transition_representation/A.rb +58 -0
  56. data/lib/y_petri/simulation/transition_representation/S.rb +45 -0
  57. data/lib/y_petri/simulation/transition_representation/T.rb +80 -0
  58. data/lib/y_petri/simulation/transition_representation/TS.rb +46 -0
  59. data/lib/y_petri/simulation/transition_representation/Ts.rb +32 -0
  60. data/lib/y_petri/simulation/transition_representation/a.rb +30 -0
  61. data/lib/y_petri/simulation/transition_representation/s.rb +29 -0
  62. data/lib/y_petri/simulation/transition_representation/t.rb +37 -0
  63. data/lib/y_petri/simulation/transition_representation/tS.rb +38 -0
  64. data/lib/y_petri/simulation/transition_representation/ts.rb +32 -0
  65. data/lib/y_petri/simulation/transition_representation/types.rb +62 -0
  66. data/lib/y_petri/simulation/transition_representation.rb +79 -0
  67. data/lib/y_petri/simulation/transitions/A.rb +40 -0
  68. data/lib/y_petri/simulation/transitions/S.rb +24 -0
  69. data/lib/y_petri/simulation/transitions/T.rb +34 -0
  70. data/lib/y_petri/simulation/transitions/TS.rb +57 -0
  71. data/lib/y_petri/simulation/transitions/Ts.rb +60 -0
  72. data/lib/y_petri/simulation/transitions/a.rb +8 -0
  73. data/lib/y_petri/simulation/transitions/access.rb +186 -0
  74. data/lib/y_petri/simulation/transitions/s.rb +9 -0
  75. data/lib/y_petri/simulation/transitions/t.rb +22 -0
  76. data/lib/y_petri/simulation/transitions/tS.rb +55 -0
  77. data/lib/y_petri/simulation/transitions/ts.rb +58 -0
  78. data/lib/y_petri/simulation/transitions/types.rb +98 -0
  79. data/lib/y_petri/simulation/transitions.rb +21 -0
  80. data/lib/y_petri/simulation.rb +176 -781
  81. data/lib/y_petri/transition/assignment.rb +7 -5
  82. data/lib/y_petri/transition/construction.rb +119 -187
  83. data/lib/y_petri/transition/init.rb +311 -0
  84. data/lib/y_petri/transition/ordinary_timeless.rb +8 -6
  85. data/lib/y_petri/transition/timed.rb +11 -18
  86. data/lib/y_petri/transition.rb +104 -132
  87. data/lib/y_petri/version.rb +1 -1
  88. data/lib/y_petri/world/dependency.rb +40 -0
  89. data/lib/y_petri/world/petri_net_related.rb +61 -0
  90. data/lib/y_petri/{workspace/simulation_related_methods.rb → world/simulation_related.rb} +42 -49
  91. data/lib/y_petri/world.rb +27 -0
  92. data/lib/y_petri.rb +47 -99
  93. data/test/{manipulator_test.rb → agent_test.rb} +19 -17
  94. data/{lib/y_petri → test/examples}/demonstrator.rb +0 -0
  95. data/{lib/y_petri → test/examples}/demonstrator_2.rb +1 -0
  96. data/{lib/y_petri → test/examples}/demonstrator_3.rb +0 -0
  97. data/{lib/y_petri → test/examples}/demonstrator_4.rb +0 -0
  98. data/test/examples/example_2.rb +16 -0
  99. data/test/{manual_examples.rb → examples/manual_examples.rb} +0 -0
  100. data/test/net_test.rb +126 -121
  101. data/test/place_test.rb +1 -1
  102. data/test/sim_test +565 -0
  103. data/test/simulation_test.rb +338 -264
  104. data/test/transition_test.rb +77 -174
  105. data/test/world_mock.rb +12 -0
  106. data/test/{workspace_test.rb → world_test.rb} +19 -20
  107. data/test/y_petri_test.rb +4 -5
  108. metadata +101 -26
  109. data/lib/y_petri/dependency_injection.rb +0 -45
  110. data/lib/y_petri/manipulator/petri_net_related_methods.rb +0 -74
  111. data/lib/y_petri/manipulator.rb +0 -20
  112. data/lib/y_petri/net/selections.rb +0 -209
  113. data/lib/y_petri/simulation/collections.rb +0 -460
  114. data/lib/y_petri/workspace/parametrized_subclassing.rb +0 -22
  115. data/lib/y_petri/workspace/petri_net_related_methods.rb +0 -88
  116. data/lib/y_petri/workspace.rb +0 -16
  117. 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/selections'
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+, term 'arcs' is
10
- # mostly used as a synonym denoting neighboring places / transitions.
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::DependencyInjection
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
- @places, @transitions = places, transitions
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! place
26
- pl = place( place )
27
- return false if @places.include? pl
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! transition;
37
- tr = transition( transition )
38
- return false if @transitions.include? tr
39
- raise TypeError, "Unable to include the transition #{tr} in #{self}: " +
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! place
51
- pl = place( place )
52
- raise "Unable to exclude #{pl} from #{self}: One or more transitions" +
53
- "depend on it" if transitions.any? { |tr| tr.arcs.include? pl }
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! transition
62
- tr = transition( transition )
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 object (either place or transition) in the net. Acts by calling
68
- # +#include_place!+ or +#include_transition!+, as needed, swallowing errors.
79
+ # Includes an element in the net.
69
80
  #
70
- def << place_or_transition
71
- begin
72
- include_place! place_or_transition
73
- rescue NameError
74
- begin
75
- include_transition! place_or_transition
76
- rescue NameError
77
- raise NameError, "Unrecognized place/transition: #{place_or_transition}"
78
- # TODO: Exceptional Ruby
79
- end
80
- end
81
- return self
82
- end
83
-
84
- # Inquirer whether the net includes a place / transition.
85
- #
86
- def include? place_or_transition
87
- pl = begin
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.all? { |t| t.timed? }
110
+ transitions.any? { |t| t.timed? }
112
111
  end
113
112
 
114
113
  # Creates a new simulation from the net.
115
114
  #
116
- def new_simulation( **nn )
117
- YPetri::Simulation.new **nn.merge( net: self )
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: " + ( name.nil? ? "%s" : "name: #{name}, %s" ) %
137
- "#{places.size} places, #{transitions.size} transitions" + ">"
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; to_s end
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
- # -*- coding: utf-8 -*-
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::DependencyInjection
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