y_petri 2.2.4 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +675 -0
- data/README.md +6 -3
- data/Rakefile +1 -1
- data/lib/y_petri/agent/{petri_net_related.rb → petri_net_aspect.rb} +34 -10
- data/lib/y_petri/agent/{simulation_related.rb → simulation_aspect.rb} +49 -34
- data/lib/y_petri/agent.rb +5 -5
- data/lib/y_petri/core/guarded.rb +24 -0
- data/lib/y_petri/core/timed/euler.rb +4 -8
- data/lib/y_petri/core/timed/gillespie.rb +11 -17
- data/lib/y_petri/core/timed/methods.rb +23 -0
- data/lib/y_petri/core/timed/pseudo_euler.rb +10 -13
- data/lib/y_petri/core/timed/quasi_euler.rb +9 -8
- data/lib/y_petri/core/timed/runge_kutta.rb +10 -18
- data/lib/y_petri/core/timed.rb +6 -14
- data/lib/y_petri/core/timeless/methods.rb +15 -0
- data/lib/y_petri/core/timeless/pseudo_euler.rb +4 -8
- data/lib/y_petri/core/timeless.rb +9 -4
- data/lib/y_petri/core.rb +44 -42
- data/lib/y_petri/net/data_set.rb +246 -142
- data/lib/y_petri/net/node_access.rb +282 -0
- data/lib/y_petri/net/own_state.rb +14 -4
- data/lib/y_petri/net/state/feature/assignment.rb +123 -0
- data/lib/y_petri/net/state/feature/delta.rb +55 -35
- data/lib/y_petri/net/state/feature/firing.rb +68 -25
- data/lib/y_petri/net/state/feature/flux.rb +9 -2
- data/lib/y_petri/net/state/feature/gradient.rb +36 -19
- data/lib/y_petri/net/state/feature/marking.rb +10 -5
- data/lib/y_petri/net/state/feature.rb +105 -11
- data/lib/y_petri/net/state/features/record.rb +144 -99
- data/lib/y_petri/net/state/features.rb +327 -200
- data/lib/y_petri/net/state.rb +48 -82
- data/lib/y_petri/net/visualization.rb +1 -1
- data/lib/y_petri/net.rb +62 -47
- data/lib/y_petri/place/arcs.rb +44 -0
- data/lib/y_petri/place/features.rb +115 -0
- data/lib/y_petri/place.rb +62 -29
- data/lib/y_petri/simulation/dependency.rb +31 -67
- data/lib/y_petri/simulation/feature_set.rb +1 -1
- data/lib/y_petri/simulation/initial_marking/access.rb +42 -26
- data/lib/y_petri/simulation/marking_clamps/access.rb +22 -17
- data/lib/y_petri/simulation/marking_clamps.rb +0 -2
- data/lib/y_petri/simulation/marking_vector/access.rb +102 -40
- data/lib/y_petri/simulation/marking_vector.rb +35 -37
- data/lib/y_petri/simulation/matrix.rb +1 -1
- data/lib/y_petri/simulation/node_representation.rb +25 -0
- data/lib/y_petri/simulation/nodes/access.rb +78 -0
- data/lib/y_petri/simulation/{elements.rb → nodes.rb} +14 -13
- data/lib/y_petri/simulation/place_mapping.rb +2 -2
- data/lib/y_petri/simulation/place_representation.rb +8 -7
- data/lib/y_petri/simulation/places/access.rb +89 -70
- data/lib/y_petri/simulation/places/free.rb +1 -1
- data/lib/y_petri/simulation/places/types.rb +20 -22
- data/lib/y_petri/simulation/places.rb +23 -18
- data/lib/y_petri/simulation/recorder.rb +23 -18
- data/lib/y_petri/simulation/timed/recorder.rb +19 -11
- data/lib/y_petri/simulation/timed.rb +93 -29
- data/lib/y_petri/simulation/timeless/recorder.rb +11 -6
- data/lib/y_petri/simulation/timeless.rb +13 -3
- data/lib/y_petri/simulation/transition_representation/A.rb +24 -4
- data/lib/y_petri/simulation/transition_representation/S.rb +11 -1
- data/lib/y_petri/simulation/transition_representation/T.rb +1 -1
- data/lib/y_petri/simulation/transition_representation/Ts.rb +1 -1
- data/lib/y_petri/simulation/transition_representation/a.rb +1 -1
- data/lib/y_petri/simulation/transition_representation/s.rb +12 -1
- data/lib/y_petri/simulation/transition_representation/t.rb +1 -1
- data/lib/y_petri/simulation/transition_representation/tS.rb +1 -1
- data/lib/y_petri/simulation/transition_representation/ts.rb +1 -1
- data/lib/y_petri/simulation/transition_representation/types.rb +1 -1
- data/lib/y_petri/simulation/transition_representation.rb +4 -11
- data/lib/y_petri/simulation/transitions/A.rb +17 -2
- data/lib/y_petri/simulation/transitions/S.rb +1 -1
- data/lib/y_petri/simulation/transitions/T.rb +1 -1
- data/lib/y_petri/simulation/transitions/Ts.rb +6 -5
- data/lib/y_petri/simulation/transitions/a.rb +1 -1
- data/lib/y_petri/simulation/transitions/access.rb +195 -168
- data/lib/y_petri/simulation/transitions/s.rb +1 -1
- data/lib/y_petri/simulation/transitions/t.rb +1 -1
- data/lib/y_petri/simulation/transitions/tS.rb +1 -1
- data/lib/y_petri/simulation/transitions/ts.rb +1 -1
- data/lib/y_petri/simulation/transitions/types.rb +1 -1
- data/lib/y_petri/simulation/transitions.rb +5 -7
- data/lib/y_petri/simulation.rb +84 -90
- data/lib/y_petri/transition/A.rb +8 -2
- data/lib/y_petri/transition/T.rb +25 -2
- data/lib/y_petri/transition/arcs.rb +19 -3
- data/lib/y_petri/transition/construction_convenience.rb +11 -10
- data/lib/y_petri/transition/t.rb +14 -1
- data/lib/y_petri/transition/types.rb +6 -1
- data/lib/y_petri/transition.rb +9 -12
- data/lib/y_petri/version.rb +1 -1
- data/lib/y_petri/world/dependency.rb +3 -3
- data/lib/y_petri/world/{petri_net_related.rb → petri_net_aspect.rb} +4 -4
- data/lib/y_petri/world/simulation_aspect.rb +352 -0
- data/lib/y_petri/world.rb +4 -4
- data/lib/y_petri.rb +1 -1
- data/test/agent_test.rb +2 -1
- data/test/examples/demonstrator.rb +4 -1
- data/test/examples/demonstrator_2.rb +5 -0
- data/test/examples/demonstrator_4.rb +6 -5
- data/test/examples/example_2.rb +2 -0
- data/test/examples/manual_examples.rb +4 -4
- data/test/net_test.rb +457 -54
- data/test/place_test.rb +11 -7
- data/test/simulation_test.rb +358 -331
- data/test/transition_test.rb +11 -10
- data/test/world_test.rb +2 -0
- data/test/y_petri_test.rb +2 -1
- data/y_petri.gemspec +24 -18
- metadata +71 -17
- data/LICENSE +0 -22
- data/lib/y_petri/net/element_access.rb +0 -239
- data/lib/y_petri/simulation/element_representation.rb +0 -20
- data/lib/y_petri/simulation/elements/access.rb +0 -57
- data/lib/y_petri/transition/type.rb +0 -103
- data/lib/y_petri/transition/type_information.rb +0 -103
- data/lib/y_petri/world/simulation_related.rb +0 -176
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# Basic elements of a simulation, a mixin intended for YPetri::Simulation.
|
4
|
-
#
|
5
3
|
class YPetri::Simulation
|
4
|
+
# The class in which places' marking is stored insid a simulation.
|
5
|
+
#
|
6
6
|
class MarkingVector < Matrix
|
7
7
|
★ Dependency
|
8
8
|
|
@@ -20,10 +20,10 @@ class YPetri::Simulation
|
|
20
20
|
when Hash then annotated_with( arg.keys )[ arg.values ]
|
21
21
|
when Array then
|
22
22
|
if annotation then
|
23
|
-
|
24
|
-
"
|
25
|
-
|
26
|
-
column_vector arg
|
23
|
+
fail ArgumentError, "The size of the argument (#{arg.size}) does " +
|
24
|
+
"not match the annotation size (#{annotation.size})!" unless
|
25
|
+
msg unless arg.size == annotation.size
|
26
|
+
column_vector( arg )
|
27
27
|
else
|
28
28
|
annotated_with( places )[ args ]
|
29
29
|
end
|
@@ -32,57 +32,55 @@ class YPetri::Simulation
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
# Returns a subclass of self annotated with the supplied places.
|
35
|
+
# Returns a subclass of self annotated with the supplied array of places.
|
36
36
|
#
|
37
|
-
def annotated_with
|
38
|
-
annot =
|
39
|
-
annotation.subset place_ids
|
40
|
-
else
|
41
|
-
places( place_ids )
|
42
|
-
end
|
37
|
+
def annotated_with places
|
38
|
+
annot = annotation ? annotation.subset( places ) : Places( places )
|
43
39
|
Class.new self do @annotation = annot end
|
44
40
|
end
|
45
41
|
|
46
|
-
# Without arguments, constructs the starting marking vector for all
|
47
|
-
# using either initial values, or clamp values. Optionally,
|
48
|
-
#
|
42
|
+
# Without arguments, constructs the starting marking vector for all the
|
43
|
+
# places, using either initial values, or clamp values. Optionally, an
|
44
|
+
# array of places or place ids can be supplied, for which the starting
|
45
|
+
# vector is returned.
|
49
46
|
#
|
50
|
-
def starting
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
self[ annotation.map &st ]
|
47
|
+
def starting places=nil
|
48
|
+
if places.nil? then
|
49
|
+
return starting places() if annotation.nil?
|
50
|
+
self[ annotation.map { |p| p.free? ? p.initial_marking : p.clamp } ]
|
55
51
|
else
|
56
|
-
annotated_with(
|
52
|
+
annotated_with( places ).starting
|
57
53
|
end
|
58
54
|
end
|
59
55
|
|
60
|
-
# Without arguments, constructs a zero marking vector for all places.
|
61
|
-
# Optionally, places can be
|
62
|
-
# returned.
|
56
|
+
# Without arguments, constructs a zero marking vector for all the places.
|
57
|
+
# Optionally, an array of places or places ids can be supplied, for which
|
58
|
+
# the zero vector is returned.
|
63
59
|
#
|
64
|
-
def zero
|
65
|
-
starting(
|
60
|
+
def zero places=nil
|
61
|
+
starting( places ) * 0
|
66
62
|
end
|
67
63
|
end
|
68
64
|
|
69
65
|
delegate :simulation, to: "self.class"
|
70
66
|
|
71
|
-
#
|
67
|
+
# Expects an array of places or place ids, and creates a subset of this
|
68
|
+
# marking vector. Alternatively, a block can be supplied that performs
|
69
|
+
# the places selection similarly to +Enumerable#select+.
|
72
70
|
#
|
73
|
-
def select
|
71
|
+
def select places, &block
|
74
72
|
if block_given? then
|
75
|
-
|
76
|
-
|
77
|
-
select annotation.select
|
73
|
+
fail ArgumentError, "Arguments not allowed if block given!" unless
|
74
|
+
place_ids.empty?
|
75
|
+
select annotation.select &block
|
78
76
|
else
|
79
|
-
pp = places(
|
77
|
+
pp = places( *places )
|
80
78
|
annotated_subcl = self.class.annotated_with( pp )
|
81
79
|
annotated_subcl[ pp.map { |p| fetch p } ]
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
85
|
-
# Modifying the vector
|
83
|
+
# Modifying the vector nodes.
|
86
84
|
#
|
87
85
|
def set id, value
|
88
86
|
self[ index( id ), 0 ] = value
|
@@ -104,7 +102,7 @@ class YPetri::Simulation
|
|
104
102
|
end
|
105
103
|
end
|
106
104
|
|
107
|
-
# Access of the vector
|
105
|
+
# Access of the vector nodes.
|
108
106
|
#
|
109
107
|
def fetch id
|
110
108
|
self[ index( id ), 0 ]
|
@@ -166,8 +164,8 @@ class YPetri::Simulation
|
|
166
164
|
|
167
165
|
# Pretty-prints the marking vector.
|
168
166
|
#
|
169
|
-
def pretty_print
|
170
|
-
to_h.pretty_print_numeric_values
|
167
|
+
def pretty_print *args
|
168
|
+
to_h.pretty_print_numeric_values *args
|
171
169
|
end
|
172
170
|
alias pp pretty_print
|
173
171
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Representation of a YPetri::Place inside a YPetri::Simulation instance.
|
4
|
+
#
|
5
|
+
class YPetri::Simulation::NodeRepresentation
|
6
|
+
★ NameMagic
|
7
|
+
★ YPetri::Simulation::Dependency
|
8
|
+
|
9
|
+
attr_reader :source # source place
|
10
|
+
|
11
|
+
delegate :simulation, to: "self.class"
|
12
|
+
|
13
|
+
# Expect a single YPetri place as an argument.
|
14
|
+
#
|
15
|
+
def initialize net_node_id
|
16
|
+
@source = net.node( net_node_id )
|
17
|
+
end
|
18
|
+
|
19
|
+
# Tweak the #to_s method to give the node representations the inspect string
|
20
|
+
# of type #<Name>.
|
21
|
+
#
|
22
|
+
def to_s
|
23
|
+
"#<#{super}>"
|
24
|
+
end
|
25
|
+
end # class YPetri::Simulation::NodeRepresentation
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Simulation mixin providing access to nodes (places / transitions). Also see
|
4
|
+
# mixins +Places::Access+ and +Transitions::Access+.
|
5
|
+
#
|
6
|
+
class YPetri::Simulation::Nodes
|
7
|
+
module Access
|
8
|
+
# Does a node belong to the simulation?
|
9
|
+
#
|
10
|
+
def includes?( id )
|
11
|
+
includes_place?( id ) || includes_transition?( id )
|
12
|
+
end
|
13
|
+
alias include? includes?
|
14
|
+
|
15
|
+
# Node of the simulation belonging to the net. Each simulation has its
|
16
|
+
# representations of places and transitions, which are based on the places
|
17
|
+
# and transitions of the underlying net. This method takes one argument,
|
18
|
+
# which (place, place name, transition, or transition name) and returns the
|
19
|
+
# corresponding node of the underlying net.
|
20
|
+
#
|
21
|
+
def n( node )
|
22
|
+
node( node ).source
|
23
|
+
end
|
24
|
+
|
25
|
+
# Nodes of the simulation (belonging to the net). Expects a single array of
|
26
|
+
# nodes (places / transitions) or node ids and returns an array of the
|
27
|
+
# corresponding nodes in the underlying net.
|
28
|
+
#
|
29
|
+
def Nn( array )
|
30
|
+
Nodes( array ).sources
|
31
|
+
end
|
32
|
+
|
33
|
+
# Without arguments, returns all the nodes of the underlying net. Otherwise,
|
34
|
+
# it accepts an arbitrary number of nodes or node ids as arguments, and
|
35
|
+
# returns an array of the corresponding nodes of the underlying net.
|
36
|
+
#
|
37
|
+
def nn( *nodes )
|
38
|
+
nodes( *nodes ).sources
|
39
|
+
end
|
40
|
+
|
41
|
+
# Names of the simulation's nodes. Arguments, if any, are treated
|
42
|
+
# analogically to the +#nodes+ method.
|
43
|
+
#
|
44
|
+
def nnn *nodes
|
45
|
+
nnn( *nodes ).names
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
# Node instance identification.
|
51
|
+
#
|
52
|
+
def node( node )
|
53
|
+
return place node if include_place? node
|
54
|
+
return transition node if include_transition? node
|
55
|
+
fail TypeError, "No node #{node} in the simulation!"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Expects a single array of nodes (places / transitions) or node ids and
|
59
|
+
# returns an array of the corresponding node instances.
|
60
|
+
#
|
61
|
+
def Nodes( array )
|
62
|
+
# NOTE: At the moment, the Simulation instance does not have a
|
63
|
+
# parametrized subclass of Simulation::Nodes class, the following
|
64
|
+
# statement is thus made to return a plain array of elements.
|
65
|
+
Nodes().load array.map &method( :node )
|
66
|
+
end
|
67
|
+
|
68
|
+
# Without arguments, returns all the nodes (places / transitions) of the
|
69
|
+
# simulation. Otherwise, it accepts an arbitrary number of nodes or node ids
|
70
|
+
# as arguments, and returns an array of the corresponding nodes of the
|
71
|
+
# simulation.
|
72
|
+
#
|
73
|
+
def nodes( *nodes )
|
74
|
+
return places + transitions if nodes.empty?
|
75
|
+
Nodes( nodes )
|
76
|
+
end
|
77
|
+
end # module Access
|
78
|
+
end # class YPetri::Simulation::Nodes
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# Basic elements of a simulation, a mixin intended for YPetri::Simulation.
|
4
|
-
#
|
5
3
|
class YPetri::Simulation
|
6
|
-
|
4
|
+
# An array of simulation owned places and/or transitions.
|
5
|
+
#
|
6
|
+
class Nodes < Array
|
7
7
|
★ Dependency
|
8
8
|
|
9
9
|
class << self
|
@@ -16,28 +16,29 @@ class YPetri::Simulation
|
|
16
16
|
|
17
17
|
delegate :simulation, to: "self.class"
|
18
18
|
|
19
|
-
# Loads
|
19
|
+
# Loads nodes to this collection.
|
20
20
|
#
|
21
|
-
def load
|
22
|
-
|
21
|
+
def load nodes
|
22
|
+
nodes.each{ |node| push node }
|
23
23
|
end
|
24
24
|
|
25
25
|
# Creates a subset of this collection (of the same class).
|
26
26
|
#
|
27
|
-
def subset
|
27
|
+
def subset nodes=nil, &block
|
28
28
|
if block_given? then
|
29
|
-
|
30
|
-
|
29
|
+
fail ArgumentError, "If block given, arguments not allowed!" unless
|
30
|
+
nodes.nil?
|
31
31
|
self.class.load select( &block )
|
32
32
|
else
|
33
|
-
|
34
|
-
|
33
|
+
fail ArgumentError, "A collection or a block expected!" if nodes.nil?
|
34
|
+
nn = Nodes( nodes )
|
35
|
+
nn.all? { |node| include? node } or
|
35
36
|
fail TypeError, "All subset elements must be in the collection."
|
36
|
-
self.class.load(
|
37
|
+
self.class.load( nn )
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
|
-
# Returns an array of the
|
41
|
+
# Returns an array of the node sources (nodes in the underlying net).
|
41
42
|
#
|
42
43
|
def sources
|
43
44
|
map &:source
|
@@ -3,10 +3,11 @@
|
|
3
3
|
# Representation of a YPetri::Place inside a YPetri::Simulation instance.
|
4
4
|
#
|
5
5
|
class YPetri::Simulation
|
6
|
-
class PlaceRepresentation <
|
6
|
+
class PlaceRepresentation < NodeRepresentation
|
7
7
|
attr_reader :quantum
|
8
8
|
|
9
|
-
# Index
|
9
|
+
# Index.
|
10
|
+
#
|
10
11
|
def m_vector_index
|
11
12
|
places.index( self )
|
12
13
|
end
|
@@ -21,32 +22,32 @@ class YPetri::Simulation
|
|
21
22
|
# Setter of clamp.
|
22
23
|
#
|
23
24
|
def clamp=( value )
|
24
|
-
simulation.set_marking_clamp(
|
25
|
+
simulation.set_marking_clamp( self, to: value )
|
25
26
|
end
|
26
27
|
|
27
28
|
# Setter of initial marking.
|
28
29
|
#
|
29
30
|
def initial_marking=( value )
|
30
|
-
simulation.set_initial_marking(
|
31
|
+
simulation.set_initial_marking( self, to: value )
|
31
32
|
end
|
32
33
|
|
33
34
|
# Marking clamp value (or nil, if the place is clamped).
|
34
35
|
#
|
35
36
|
def marking_clamp
|
36
|
-
simulation.marking_clamp
|
37
|
+
simulation.marking_clamp( self ) if clamped?
|
37
38
|
end
|
38
39
|
alias clamp marking_clamp
|
39
40
|
|
40
41
|
# Initial marking value (or nil, if the place is free).
|
41
42
|
#
|
42
43
|
def initial_marking
|
43
|
-
simulation.initial_marking
|
44
|
+
simulation.initial_marking( self ) if free?
|
44
45
|
end
|
45
46
|
|
46
47
|
# Is the place free in the current simulation?
|
47
48
|
#
|
48
49
|
def free?
|
49
|
-
simulation.
|
50
|
+
simulation.initial_markings.places.include? self
|
50
51
|
end
|
51
52
|
|
52
53
|
# Is the place clamped in the current simulation?
|
@@ -1,121 +1,140 @@
|
|
1
|
-
#encoding: utf-8
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
3
|
# Simulation mixin providing access to places.
|
4
4
|
#
|
5
5
|
class YPetri::Simulation::Places
|
6
6
|
module Access
|
7
|
-
# With no arguments, a reader of
|
8
|
-
# free places and all places. If argument is given, it is assumed
|
9
|
-
# a column vector, and multiplication is performed.
|
7
|
+
# With no arguments, acts as a reader of f2a -- the correspondence matrix
|
8
|
+
# between free places and all places. If argument is given, it is assumed
|
9
|
+
# to be a column vector, and multiplication with f2a is performed.
|
10
10
|
#
|
11
11
|
def f2a arg=nil
|
12
|
-
|
12
|
+
arg.nil? ? @f2a : @f2a * arg
|
13
13
|
end
|
14
14
|
|
15
|
-
# With no arguments, a reader of
|
16
|
-
# clamped places and all places. If argument is given, it is assumed
|
17
|
-
# a column vector, and multiplication is performed.
|
15
|
+
# With no arguments, acts as a reader of c2a -- the correspondence matrix
|
16
|
+
# between clamped places and all places. If argument is given, it is assumed
|
17
|
+
# to be a column vector, and multiplication with c2a is performed.
|
18
18
|
#
|
19
19
|
def c2a arg=nil
|
20
|
-
|
20
|
+
arg.nil? ? @c2a : @c2a * arg
|
21
21
|
end
|
22
22
|
|
23
23
|
# Does a place belong to the simulation?
|
24
24
|
#
|
25
|
-
def includes_place?
|
26
|
-
true.tap { begin; place
|
27
|
-
rescue NameError, TypeError
|
25
|
+
def includes_place? place
|
26
|
+
true.tap { begin; place place; rescue NameError, TypeError
|
28
27
|
return false
|
29
28
|
end }
|
30
29
|
end
|
31
30
|
alias include_place? includes_place?
|
32
31
|
|
33
|
-
#
|
32
|
+
# Net's place.
|
34
33
|
#
|
35
|
-
def p(
|
36
|
-
place(
|
34
|
+
def p( place )
|
35
|
+
place( place ).source
|
37
36
|
end
|
38
37
|
|
39
|
-
#
|
38
|
+
# Makes it so that when "places" is abbreviated to "pp", places of the
|
39
|
+
# underlying net are returned rather than simulation's place representations.
|
40
40
|
#
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
chain Pp: :Places,
|
42
|
+
pp: :places,
|
43
|
+
Free_pp: :Free_places,
|
44
|
+
free_pp: :free_places,
|
45
|
+
Clamped_pp: :Clamped_places,
|
46
|
+
clamped_pp: :clamped_places,
|
47
|
+
&:sources
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
def free_pp( ids=nil )
|
48
|
-
free_places( ids ).sources
|
49
|
-
end
|
49
|
+
alias free_Pp Free_pp
|
50
|
+
alias clamped_Pp Clamped_pp
|
50
51
|
|
51
|
-
#
|
52
|
+
# Makes it so that +Pn+/+pn+ means "names of places", and that when message
|
53
|
+
# "n" + place_type is sent to the simulation, it returns names of the places
|
54
|
+
# of the specified type.
|
52
55
|
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
+
chain Pn: :Pt,
|
57
|
+
pn: :pp,
|
58
|
+
nfree: :free_places,
|
59
|
+
nclamped: :clamped_places do |r| r.names( true ) end
|
56
60
|
|
57
|
-
# Places' names. Arguments, if any, are treated as in +#places+ method.
|
58
|
-
#
|
59
|
-
def pn( ids=nil )
|
60
|
-
places( ids ).names
|
61
|
-
end
|
62
|
-
|
63
|
-
# Names of free places. Arguments are handled as with +#free_places+.
|
64
|
-
#
|
65
|
-
def nfree ids=nil
|
66
|
-
free_places( ids ).names
|
67
|
-
end
|
68
61
|
alias free_pn nfree
|
69
|
-
|
70
|
-
# Names of free places. Arguments are handled as with +#clamped_places+.
|
71
|
-
#
|
72
|
-
def nclamped ids=nil
|
73
|
-
clamped_places( ids ).names
|
74
|
-
end
|
75
62
|
alias clamped_pn nclamped
|
76
63
|
|
77
64
|
protected
|
78
65
|
|
79
66
|
# Place instance identification.
|
80
67
|
#
|
81
|
-
def place(
|
82
|
-
begin
|
83
|
-
Place().instance( id )
|
84
|
-
rescue NameError, TypeError
|
68
|
+
def place( place )
|
69
|
+
begin; Place().instance( place ); rescue NameError, TypeError
|
85
70
|
begin
|
86
|
-
|
87
|
-
places.find { |
|
88
|
-
Place().instance(
|
71
|
+
place = net.place( place )
|
72
|
+
places.find { |place_rep| place_rep.source == place } ||
|
73
|
+
Place().instance( place.name )
|
89
74
|
rescue NameError, TypeError => msg
|
90
|
-
raise
|
91
|
-
|
92
|
-
|
75
|
+
raise # FIXME: This raise needs to be here in order for the current
|
76
|
+
# tests to pass (they expect NameError, while the raise below would
|
77
|
+
# raise TypeError). But it is not clear to me anymore why the tests
|
78
|
+
# require NameError in the first place. Gotta look into it.
|
79
|
+
raise TypeError, "The argument #{place} (class #{place.class}) does " +
|
80
|
+
"not identify a place instance! (#{msg})"
|
93
81
|
end
|
94
82
|
end
|
95
83
|
end
|
96
84
|
|
97
|
-
#
|
98
|
-
#
|
85
|
+
# Constructs an instance of @Places parametrized subclass. Expects a single
|
86
|
+
# array of places or place ids and returns an array of corresponding place
|
87
|
+
# representations in the simulation. Note that the includer of the
|
88
|
+
# +Places::Access+ module normally overloads :Places message in such way,
|
89
|
+
# that even without an argument, it does not fail, but returns the @Places
|
90
|
+
# parametrized subclass itself.
|
91
|
+
#
|
92
|
+
def Places( array )
|
93
|
+
# Kernel.p array
|
94
|
+
Places().load array.map &method( :place )
|
95
|
+
end
|
96
|
+
|
97
|
+
# Without arguments, returns all the place representations in the simulation.
|
98
|
+
# Otherwise, it accepts an arbitrary number of places or place ids as
|
99
|
+
# arguments, and a corresponding array of place representations.
|
100
|
+
#
|
101
|
+
def places( *places )
|
102
|
+
return @places if places.empty?
|
103
|
+
Places( places )
|
104
|
+
end
|
105
|
+
|
106
|
+
# Expects a single array of free places or place ids and returns an array of
|
107
|
+
# the corresponding free place representations in the simulation.
|
108
|
+
#
|
109
|
+
def Free_places( array )
|
110
|
+
places.free.subset( array )
|
111
|
+
end
|
112
|
+
alias free_Places Free_places
|
113
|
+
|
114
|
+
# Without arguments, returns all free places of the simulation. Otherwise, it
|
115
|
+
# accepts an arbitrary number of free places or place ids as arguments, and
|
116
|
+
# returns an array of the corresponding free places of the simulation.
|
99
117
|
#
|
100
|
-
def
|
101
|
-
return
|
102
|
-
|
118
|
+
def free_places( *free_places )
|
119
|
+
return places.free if free_places.empty?
|
120
|
+
Free_places( free_places )
|
103
121
|
end
|
104
122
|
|
105
|
-
#
|
106
|
-
#
|
123
|
+
# Expects a single array of clamped places or place ids and returns an array
|
124
|
+
# of the corresponding clamped place representations in the simulation.
|
107
125
|
#
|
108
|
-
def
|
109
|
-
|
110
|
-
places.free.subset( ids )
|
126
|
+
def Clamped_places( array )
|
127
|
+
places.clamped.subset( array )
|
111
128
|
end
|
129
|
+
alias clamped_Places Clamped_places
|
112
130
|
|
113
|
-
#
|
114
|
-
# places
|
131
|
+
# Withoud arguments, returns all clamped places of the simulation. Otherwise,
|
132
|
+
# it accepts an arbitrary number of clamped places or place ids as arguments,
|
133
|
+
# and returns and array of the correspondingg clamped places.
|
115
134
|
#
|
116
|
-
def clamped_places
|
117
|
-
return places.clamped if
|
118
|
-
|
135
|
+
def clamped_places( *clamped_places )
|
136
|
+
return places.clamped if clamped_places.empty?
|
137
|
+
Clamped_places( clamped_places )
|
119
138
|
end
|
120
139
|
end # module Access
|
121
140
|
end # class YPetri::Simulation::Places
|
@@ -1,25 +1,23 @@
|
|
1
|
-
#encoding: utf-8
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
3
|
# A mixin with place type selectors.
|
4
4
|
#
|
5
|
-
class YPetri::Simulation
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end # class Places
|
25
|
-
end # class YPetri::Simulation
|
5
|
+
class YPetri::Simulation::Places
|
6
|
+
module Types
|
7
|
+
# Subset of free places, if any.
|
8
|
+
#
|
9
|
+
def free
|
10
|
+
( @Type_free ||= Class.new( self.class ).tap do |klass|
|
11
|
+
klass.class_exec { include Type_free }
|
12
|
+
end ).load subset( &:free? )
|
13
|
+
end
|
14
|
+
|
15
|
+
# Subset of clamped places, if any.
|
16
|
+
#
|
17
|
+
def clamped
|
18
|
+
( @Type_clamped ||= Class.new( self.class ).tap do |klass|
|
19
|
+
klass.class_exec { include Type_clamped }
|
20
|
+
end ).load subset( &:clamped? )
|
21
|
+
end
|
22
|
+
end # Types
|
23
|
+
end # class YPetri::Simulation::Places
|