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
@@ -0,0 +1,100 @@
1
+ # encoding: utf-8
2
+
3
+ class YPetri::Core
4
+ DEFAULT_METHOD = :pseudo_euler
5
+
6
+ module Guarded
7
+ # Guarded simulation.
8
+ #
9
+ def guarded?
10
+ true
11
+ end
12
+
13
+ # Guarded version of the method.
14
+ #
15
+ def increment_marking_vector( delta )
16
+ try "to update marking" do
17
+ super( note( "Δ state if tS transitions fire once",
18
+ is: Δ_if_tS_fire_once ) +
19
+ note( "Δ state if tsa transitions fire once",
20
+ is: Δ_if_tsa_fire_once ) )
21
+ end
22
+ end
23
+
24
+ # Guarded version of the method.
25
+ #
26
+ def A_all_fire!
27
+ try "to fire the assignment transitions" do
28
+ super
29
+ end
30
+ end
31
+ end
32
+
33
+ include YPetri::Simulation::Dependency
34
+
35
+ delegate :simulation, to: "self.class"
36
+ delegate :alert, to: :recorder
37
+
38
+ class << self
39
+ alias __new__ new
40
+
41
+ def new( method: nil, guarded: false, **nn )
42
+ # Alow for named arg. alias :simulation_method
43
+ sm = method || nn[:simulation_method] || DEFAULT_METHOD
44
+ using_simulation_method( sm, guarded: guarded ).__new__
45
+ end
46
+
47
+ def using_simulation_method symbol, guarded: false
48
+ simulation_method_module = const_get( symbol.to_s.camelize )
49
+ # TODO: "guarded" argument not handled yet
50
+ Class.new self do prepend( simulation_method_module ) end
51
+ end
52
+ end
53
+
54
+ # Simlation is not guarded by default.
55
+ #
56
+ def guarded?
57
+ false
58
+ end
59
+
60
+ # Delta for free places.
61
+ #
62
+ def delta_timeless
63
+ delta_ts + delta_tS
64
+ end
65
+ alias delta_t delta_timeless
66
+
67
+ # Delta contribution by tS transitions.
68
+ #
69
+ def delta_tS
70
+ simulation.tS_stoichiometry_matrix * firing_vector_tS
71
+ end
72
+
73
+ # Delta contribution by ts transitions.
74
+ #
75
+ def delta_ts
76
+ simulation.ts_delta_closure.call
77
+ end
78
+
79
+ # Firing vector of tS transitions.
80
+ #
81
+ def firing_vector_tS
82
+ simulation.tS_firing_closure.call
83
+ end
84
+
85
+ # Increments the marking vector by a given delta.
86
+ #
87
+ def increment_marking_vector( delta )
88
+ print '.'
89
+ simulation.increment_marking_vector_closure.( delta )
90
+ end
91
+
92
+ # Fires assignment transitions.
93
+ #
94
+ def assignment_transitions_all_fire!
95
+ simulation.A_assignment_closure.call
96
+ end
97
+ end # class YPetri::Core
98
+
99
+ require_relative 'core/timed'
100
+ require_relative 'core/timeless'
@@ -0,0 +1,66 @@
1
+ module YPetri
2
+ # YPetri DSL.
3
+ #
4
+ module DSL
5
+ def y_petri_agent
6
+ @y_petri_agent ||= Agent.new
7
+ .tap { puts "Defining agent for #{self}" if YPetri::DEBUG }
8
+ end
9
+ end
10
+
11
+ delegate :world, to: :y_petri_agent
12
+
13
+ # Petri net aspect.
14
+ delegate( :Place,
15
+ :Transition, :T, :A,
16
+ :Net,
17
+ :place, :transition, :pl, :tr,
18
+ :places, :transitions, :nets,
19
+ :pn, :tn, :nn,
20
+ :net_point,
21
+ :net_selection,
22
+ :net, :nnet,
23
+ :net_point_reset,
24
+ :net_point=,
25
+ to: :y_petri_agent )
26
+
27
+ # Simulation aspect.
28
+ delegate( :simulation_point, :ssc_point, :cc_point, :imc_point,
29
+ :simulation_selection, :ssc_selection,
30
+ :cc_selection, :imc_selection,
31
+ :simulations,
32
+ :clamp_collections,
33
+ :initial_marking_collections,
34
+ :simulation_settings_collections,
35
+ :clamp_collection_names, :ncc,
36
+ :initial_marking_collection_names, :nimc,
37
+ :simulation_settings_collection_names, :nssc,
38
+ :set_clamp_collection, :set_cc,
39
+ :set_initial_marking_collection, :set_imc,
40
+ :set_simulation_settings_collection, :set_ssc,
41
+ :new_simulation,
42
+ :clamp_cc, :initial_marking_cc, :simulation_settings_cc,
43
+ :simulation_point_position,
44
+ :simulation,
45
+ :clamp_collection, :cc,
46
+ :initial_marking_collection, :imc,
47
+ :simulation_settings_collection, :ssc,
48
+ :clamp,
49
+ :initial_marking,
50
+ :set_step, :set_step_size,
51
+ :set_time, :set_target_time,
52
+ :set_sampling,
53
+ :set_simulation_method,
54
+ :new_timed_simulation,
55
+ :run!,
56
+ :print_recording,
57
+ :plot,
58
+ :plot_selected,
59
+ # :plot_state,
60
+ :plot_flux,
61
+ to: :y_petri_agent )
62
+
63
+ def plot_state **nn
64
+ simulation.recording.marking.plot **nn
65
+ end
66
+ end
@@ -0,0 +1,7 @@
1
+ #encoding: utf-8
2
+
3
+ # Public command interface of YPetri.
4
+ #
5
+ module YPetri
6
+ GuardError = Class.new TypeError
7
+ end # module YPetri
@@ -0,0 +1,239 @@
1
+ # Selections of various kinds of places / transitions (place names / transition
2
+ # names) in a Petri net.
3
+ #
4
+ module YPetri::Net::ElementAccess
5
+ # Does the net include a place?
6
+ #
7
+ def includes_place? id
8
+ begin
9
+ place( id ) and true
10
+ rescue NameError, TypeError; false end
11
+ end
12
+ alias include_place? includes_place?
13
+
14
+ # Does the net include a transition?
15
+ #
16
+ def includes_transition? id
17
+ begin; transition( id ) and true; rescue NameError, TypeError; false end
18
+ end
19
+ alias include_transition? includes_transition?
20
+
21
+ # Inquirer whether the net includes an element.
22
+ #
23
+ def include? id
24
+ include_place?( id ) || include_transition?( id )
25
+ end
26
+ alias includes? include?
27
+
28
+ # Returns the net's place identified by the argument.
29
+ #
30
+ def place id
31
+ ( super rescue Place().instance( id ) ).tap do |p|
32
+ fail TypeError, "No place #{id} in the net!" unless places.include? p
33
+ end
34
+ end
35
+
36
+ # Returns the net's transition identified by the argument.
37
+ #
38
+ def transition id
39
+ ( super rescue Transition().instance( id ) ).tap do |t|
40
+ transitions.include? t or fail TypeError, "No transition #{id} in the net!"
41
+ end
42
+ end
43
+
44
+ # Returns the net's element identified by the argument
45
+ #
46
+ def element id
47
+ begin; place( id ); rescue NameError, TypeError
48
+ begin; transition( id ); rescue NameError, TypeError
49
+ raise TypeError, "The net does not include place/transition #{id}!"
50
+ end
51
+ end
52
+ end
53
+
54
+ # Returns the net's elements identified by the argument's elements.
55
+ #
56
+ def elements ids=nil
57
+ return @places + @transitions if ids.nil?
58
+ ids.map { |id| element id }
59
+ end
60
+
61
+ # Returns the names of the net's elements identified by the array.
62
+ #
63
+ def en ids=nil
64
+ elements( ids ).names
65
+ end
66
+
67
+ # Returns the net's places identified by the argument's elements.
68
+ #
69
+ def places ids=nil
70
+ return @places.dup if ids.nil?
71
+ ids.map { |id| place id }
72
+ end
73
+ alias pp places
74
+
75
+ # Returns the net's transitions identified by the argument's elements.
76
+ #
77
+ def transitions ids=nil
78
+ return @transitions.dup if ids.nil?
79
+ ids.map { |id| transition id }
80
+ end
81
+ alias tt transitions
82
+
83
+ # Names of places in the net.
84
+ #
85
+ def pn ids=nil
86
+ places( ids ).names
87
+ end
88
+
89
+ # Names of transitions in the net.
90
+ #
91
+ def tn ids=nil
92
+ transitions( ids ).names
93
+ end
94
+
95
+ # *ts* transitions.
96
+ #
97
+ def ts_transitions ids=nil
98
+ return transitions.select &:ts? if ids.nil?
99
+ transitions( ids ).aT_all "transition identifiers", "be ts", &:ts?
100
+ end
101
+ alias ts_tt ts_transitions
102
+
103
+ # Names of *ts* transitions.
104
+ #
105
+ def nts ids=nil
106
+ ts_transitions( ids ).names
107
+ end
108
+
109
+ # *tS* transitions.
110
+ #
111
+ def tS_transitions ids=nil
112
+ return transitions.select &:tS? if ids.nil?
113
+ transitions( ids ).aT_all "transition identifiers", "be tS", &:tS?
114
+ end
115
+ alias tS_tt tS_transitions
116
+
117
+ # Names of *tS* transitions.
118
+ #
119
+ def ntS ids=nil
120
+ tS_transitions( ids ).names
121
+ end
122
+
123
+ # *Ts* transitions.
124
+ #
125
+ def Ts_transitions ids=nil
126
+ return transitions.select &:Ts? if ids.nil?
127
+ transitions( ids ).aT_all "transition identifiers", "be Ts", &:Ts?
128
+ end
129
+ alias Ts_tt Ts_transitions
130
+
131
+ # Names of *Ts* transitions.
132
+ #
133
+ def nTs ids=nil
134
+ Ts_transitions( ids ).names
135
+ end
136
+
137
+ # *TS* transitions.
138
+ #
139
+ def TS_transitions ids=nil
140
+ return transitions.select &:TS? if ids.nil?
141
+ transitions( ids ).aT_all "transition identifiers", "be TS", &:TS?
142
+ end
143
+ alias TS_tt TS_transitions
144
+
145
+ # Names of *TS* transitions.
146
+ #
147
+ def nTS ids=nil
148
+ TS_transitions( ids ).names
149
+ end
150
+
151
+ # *A* transitions.
152
+ #
153
+ def A_transitions ids=nil
154
+ return transitions.select &:A? if ids.nil?
155
+ transitions( ids ).aT_all "transition identifiers", "be A", &:A?
156
+ end
157
+ alias A_tt A_transitions
158
+
159
+ # Names of *A* transitions.
160
+ #
161
+ def nA ids=nil
162
+ A_transitions( ids ).names
163
+ end
164
+
165
+ # *a* transitions.
166
+ #
167
+ def a_transitions ids=nil
168
+ return transitions.select &:a? if ids.nil?
169
+ transitions( ids ).aT_all "transition identifiers",
170
+ "be a (non-assignment)", &:a?
171
+ end
172
+ alias a_tt a_transitions
173
+
174
+ # Names of *a* transitions.
175
+ #
176
+ def na ids=nil
177
+ A_transitions( ids ).names
178
+ end
179
+
180
+ # *S* transitions.
181
+ #
182
+ def S_transitions ids=nil
183
+ return transitions.select &:S? if ids.nil?
184
+ transitions( ids ).aT_all "transition identifiers",
185
+ "be S (stoichiometric)", &:S?
186
+ end
187
+ alias S_tt S_transitions
188
+
189
+ # Names of *S* transitions.
190
+ #
191
+ def nS ids=nil
192
+ S_transitions( ids ).names
193
+ end
194
+
195
+ # *s* transitions.
196
+ #
197
+ def s_transitions ids=nil
198
+ return transitions.select &:s? if ids.nil?
199
+ transitions( ids ).aT_all "transition identifiers",
200
+ "be s (non-stoichiometric)", &:s?
201
+ end
202
+ alias s_tt s_transitions
203
+
204
+ # Names of *s* transitions.
205
+ #
206
+ def ns ids=nil
207
+ s_transitions( ids ).names
208
+ end
209
+
210
+ # *T* transitions.
211
+ #
212
+ def T_transitions ids=nil
213
+ return transitions.select &:T? if ids.nil?
214
+ transitions( ids ).aT_all "transition identifiers",
215
+ "be T (timed)", &:T?
216
+ end
217
+ alias T_tt T_transitions
218
+
219
+ # Names of *T* transitions.
220
+ #
221
+ def nT ids=nil
222
+ T_transitions( ids ).names
223
+ end
224
+
225
+ # *t* transitions.
226
+ #
227
+ def t_transitions ids=nil
228
+ return transitions.select &:t? if ids.nil?
229
+ transitions( ids ).aT_all "transition identifiers",
230
+ "be t (timeless)", &:t?
231
+ end
232
+ alias t_tt t_transitions
233
+
234
+ # Names of *t* transitions.
235
+ #
236
+ def nt ids=nil
237
+ t_transitions( ids ).names
238
+ end
239
+ end # class YPetri::Net::ElementAccess
@@ -0,0 +1,88 @@
1
+ # encoding: utf-8
2
+
3
+ class YPetri::Net::State
4
+ class Feature
5
+ # Change of a Petri net place caused by a certain set of transitions.
6
+ #
7
+ class Delta < Feature
8
+ attr_reader :place, :transitions, :step
9
+
10
+ class << self
11
+ def parametrize *args
12
+ Class.instance_method( :parametrize ).bind( self ).( *args ).tap do |ç|
13
+ # First, prepare the hash of instances.
14
+ hsh = Hash.new do |ꜧ, id|
15
+ puts "Delta received:"
16
+ p id
17
+ puts "of class #{id.class}, with ancestors:"
18
+ p id.class.ancestors
19
+ if id.is_a? Delta then
20
+ ꜧ[ [ id.place, transitions: id.transitions.sort( &:object_id ) ] ]
21
+ else
22
+ puts "here"
23
+ p id
24
+ puts "id size is #{id.size}"
25
+ p = id.fetch( 0 )
26
+ tt = id
27
+ .fetch( 1 )
28
+ .fetch( :transitions )
29
+ if p.is_a? ç.net.Place and tt.all? { |t| t.is_a? ç.net.Transition }
30
+ if tt == tt.sort then
31
+ ꜧ[ id ] = ç.__new__( *id )
32
+ else
33
+ ꜧ[ [ p, transitions: tt.sort ] ]
34
+ end
35
+ else
36
+ ꜧ[ [ ç.net.place( p ), transitions: ç.net.transitions( tt ) ] ]
37
+ end
38
+ end
39
+ end
40
+ # And then, assign it to the :@instances variable.
41
+ ç.instance_variable_set :@instances, hsh
42
+ end
43
+ end
44
+
45
+ attr_reader :instances
46
+
47
+ alias __new__ new
48
+
49
+ def new *args
50
+ return instances[ *args ] if args.size == 1
51
+ instances[ args ]
52
+ end
53
+
54
+ def of *args
55
+ new *args
56
+ end
57
+ end
58
+
59
+ def initialize place, transitions: net.tt
60
+ @place = net.place( place )
61
+ @transitions = net.transitions( transitions )
62
+ end
63
+
64
+ def extract_from arg, **nn
65
+ # **nn is here because of timed / timeless possibility, where
66
+ # **nn would contain :step named argument.
67
+ case arg
68
+ when YPetri::Simulation then
69
+ _T = arg.send( :T_transitions, transitions )
70
+ _t = arg.send( :t_transitions, transitions )
71
+ if _T.empty? then _t.delta.fetch( place ) else # time step is required
72
+ _t.delta.fetch( place ) + _T.delta( nn[:step] ).fetch( place )
73
+ end
74
+ else
75
+ fail TypeError, "Argument type not supported!"
76
+ end
77
+ end
78
+
79
+ def to_s
80
+ place.name
81
+ end
82
+
83
+ def label
84
+ "∂:#{place.name}:#{transitions.size}tt"
85
+ end
86
+ end # class Delta
87
+ end # class Feature
88
+ end # YPetri::Net::State
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ class YPetri::Net::State
3
+ class Feature
4
+ # Firing of a Petri net tS transition.
5
+ #
6
+ class Firing < Feature
7
+ attr_reader :transition
8
+
9
+ class << self
10
+ def parametrize *args
11
+ Class.instance_method( :parametrize ).bind( self ).( *args ).tap do |ç|
12
+ ç.instance_variable_set( :@instances,
13
+ Hash.new do |hsh, id|
14
+ case id
15
+ when Firing then
16
+ hsh[ id.transition ]
17
+ when ç.net.Transition then
18
+ hsh[ id ] = ç.__new__( id )
19
+ else
20
+ hsh[ ç.net.transition( id ) ]
21
+ end
22
+ end )
23
+ end
24
+ end
25
+
26
+ attr_reader :instances
27
+
28
+ alias __new__ new
29
+
30
+ def new id
31
+ instances[ id ]
32
+ end
33
+
34
+ def of id
35
+ new id
36
+ end
37
+ end
38
+
39
+ def initialize transition
40
+ @transition = net.transition( transition )
41
+ end
42
+
43
+ def extract_from arg, **nn
44
+ case arg
45
+ when YPetri::Simulation then
46
+ arg.send( :tS_transitions, [ transition ] ).firing.first
47
+ else
48
+ fail TypeError, "Argument type not supported!"
49
+ end
50
+ end
51
+
52
+ def label
53
+ "f:#{transition.name}"
54
+ end
55
+ end # class Firing
56
+ end # class Feature
57
+ end # YPetri::Net::State
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+
3
+ class YPetri::Net::State
4
+ class Feature
5
+ # Flux of a Petri net TS transition.
6
+ #
7
+ class Flux < Feature
8
+ attr_reader :transition
9
+
10
+ class << self
11
+ def parametrize *args
12
+ Class.instance_method( :parametrize ).bind( self ).( *args ).tap do |ç|
13
+ ç.instance_variable_set( :@instances,
14
+ Hash.new do |hsh, id|
15
+ case id
16
+ when Firing then
17
+ hsh[ id.transition ]
18
+ when ç.net.Transition then
19
+ hsh[ id ] = ç.__new__( id )
20
+ else
21
+ hsh[ ç.net.transition( id ) ]
22
+ end
23
+ end )
24
+ end
25
+ end
26
+
27
+ attr_reader :instances
28
+
29
+ alias __new__ new
30
+
31
+ def new id
32
+ instances[ id ]
33
+ end
34
+
35
+ def of transition_id
36
+ new transition_id
37
+ end
38
+ end
39
+
40
+ def initialize id
41
+ @transition = net.transition( id.is_a?( Flux ) ? id.transition : id )
42
+ end
43
+
44
+ def extract_from arg, **nn
45
+ case arg
46
+ when YPetri::Simulation then
47
+ arg.send( :TS_transitions, [ transition ] ).flux.first
48
+ else
49
+ fail TypeError, "Argument type not supported!"
50
+ end
51
+ end
52
+
53
+ def label
54
+ "Φ:#{transition.name}"
55
+ end
56
+ end # class Flux
57
+ end # class Feature
58
+ end # YPetri::Net::State
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ class YPetri::Net::State
4
+ class Feature
5
+ # Gradient of a Petri net place caused by a certain set of T transitions.
6
+ #
7
+ class Gradient < Feature
8
+ attr_reader :place, :transitions
9
+
10
+ class << self
11
+ def parametrize *args
12
+ Class.instance_method( :parametrize ).bind( self ).( *args ).tap do |ç|
13
+ # First, prepare the hash of instances.
14
+ hsh = Hash.new do |ꜧ, id|
15
+ if id.is_a? Gradient then
16
+ ꜧ[ [ id.place, transitions: id.transitions.sort( &:object_id ) ] ]
17
+ else
18
+ p = id.fetch( 0 )
19
+ tt = id
20
+ .fetch( 1 )
21
+ .fetch( :transitions )
22
+ if p.is_a? ç.net.Place and tt.all? { |t| t.is_a? ç.net.Transition }
23
+ if tt == tt.sort then
24
+ ꜧ[ id ] = ç.__new__( *id )
25
+ else
26
+ ꜧ[ [ p, transitions: tt.sort ] ]
27
+ end
28
+ else
29
+ ꜧ[ [ ç.net.place( p ), transitions: ç.net.transitions( tt ) ] ]
30
+ end
31
+ end
32
+ end
33
+ # And then, assign it to the :@instances variable.
34
+ ç.instance_variable_set :@instances, hsh
35
+ end
36
+ end
37
+
38
+ attr_reader :instances
39
+
40
+ alias __new__ new
41
+
42
+ def new *args
43
+ return instances[ *args ] if args.size == 1
44
+ instances[ args ]
45
+ end
46
+
47
+ def of *args
48
+ new *args
49
+ end
50
+ end
51
+
52
+ def initialize *id
53
+ @place = net.place id.fetch( 0 )
54
+ @transitions = net.transitions id.fetch( 1 ).fetch( :transitions )
55
+ end
56
+
57
+ def extract_from arg, **nn
58
+ case arg
59
+ when YPetri::Simulation then
60
+ arg.send( :T_transitions, transitions ).gradient.fetch( place )
61
+ else
62
+ fail TypeError, "Argument type not supported!"
63
+ end
64
+ end
65
+
66
+ def to_s
67
+ place.name
68
+ end
69
+
70
+ def label
71
+ "∂:#{place.name}:#{transitions.size}tt"
72
+ end
73
+ end # class Gradient
74
+ end # class Feature
75
+ end # YPetri::Net::State