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.
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