Class: YPetri::Net
- Inherits:
-
Object
- Object
- YPetri::Net
- Defined in:
- lib/y_petri/net.rb,
lib/y_petri/net/timed.rb
Overview
Represents a _Petri net_: A collection of places and transitions. The connector arrows – called arcs in classical Petri net terminology – can be considered a property of transitions. Therefore in YPetri::Net
, you won’t find arcs as first-class citizens, but only as a synonym denoting nearest neighbors of nodes (places or transitions).
Defined Under Namespace
Modules: NodeAccess, OwnState, Timed, Visualization Classes: DataSet, State
Class Method Summary collapse
-
.of(nodes) ⇒ Object
Constructs a net containing a particular set of nodes.
Instance Method Summary collapse
-
#+(other) ⇒ Object
Creates a new net that contains all the places and transitions of both operands.
-
#-(other) ⇒ Object
Returns a new net that is the result of subtraction of the net given as argument from this net.
-
#<<(node) ⇒ Object
Includes a node (place or transition) in the receiver net.
-
#==(other) ⇒ Object
Networks are equal when their places and transitions are equal.
-
#exclude_net(id) ⇒ Object
Excludes another net from the receiver net.
-
#exclude_place(place) ⇒ Object
Excludes a place from the receiver.
-
#exclude_transition(transition) ⇒ Object
Excludes a transition from the receiver.
-
#functional? ⇒ Boolean
Is the net functional?.
-
#include_net(net) ⇒ Object
(also: #merge!)
Includes another net in the receiver net.
-
#include_place(place) ⇒ Object
Includes a place in the receiver.
-
#include_transition(transition) ⇒ Object
Includes a transition in the receiver.
-
#initialize(places: [], transitions: []) ⇒ Net
constructor
Takes 2 arguments (
:places
and:transitions
) and builds a net from them. -
#inspect ⇒ Object
Inspect string of the instance.
-
#simulation(**settings) ⇒ Object
(also: #new_simulation)
Creates a new simulation from the net.
-
#timed? ⇒ Boolean
Is the net timed?.
-
#to_s ⇒ Object
Returns a string briefly describing the net.
Constructor Details
#initialize(places: [], transitions: []) ⇒ Net
Takes 2 arguments (:places
and :transitions
) and builds a net from them.
38 39 40 41 42 43 44 45 |
# File 'lib/y_petri/net.rb', line 38 def initialize( places: [], transitions: [] ) param_class!( { State: State, Simulation: YPetri::Simulation }, with: { net: self } ) @places, @transitions = [], [] places.each &method( :include_place ) transitions.each &method( :include_transition ) end |
Class Method Details
.of(nodes) ⇒ Object
Constructs a net containing a particular set of nodes.
28 29 30 |
# File 'lib/y_petri/net.rb', line 28 def of nodes new.tap { |inst| nodes.each { |node| inst << node } } end |
Instance Method Details
#+(other) ⇒ Object
Creates a new net that contains all the places and transitions of both operands.
135 136 137 138 139 140 |
# File 'lib/y_petri/net.rb', line 135 def + other self.class.send( :new ).tap do |net| net.merge! self net.merge! other end end |
#-(other) ⇒ Object
Returns a new net that is the result of subtraction of the net given as argument from this net.
145 146 147 148 149 150 |
# File 'lib/y_petri/net.rb', line 145 def - other self.class.send( :new ).tap do |net| net.include_net self net.exclude_net other end end |
#<<(node) ⇒ Object
Includes a node (place or transition) in the receiver net.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/y_petri/net.rb', line 112 def << node begin type = :place place = self.class.place node rescue NameError, TypeError begin type = :transition transition = self.class.transition node rescue NameError, TypeError => err raise TypeError, "Current world contains no place or " + "transition #{node}! (#{err})" end end case type # Factored out to minimize the code inside the rescue clause. when :place then include_place( place ) when :transition then include_transition( transition ) else fail "Implementation error!" end return self # important to enable chaining, eg. foo_net << p1 << p2 << t1 end |
#==(other) ⇒ Object
Networks are equal when their places and transitions are equal.
173 174 175 176 |
# File 'lib/y_petri/net.rb', line 173 def == other return false unless other.class_complies? self.class places == other.places && transitions == other.transitions end |
#exclude_net(id) ⇒ Object
Excludes another net from the receiver net. Returns true if successful (ie. if there was any change to the receiver net), false if the receiver net contained no node of the argument net.
103 104 105 106 107 108 |
# File 'lib/y_petri/net.rb', line 103 def exclude_net id net = Net().instance( id ) rescue YPetri::Net.instance( net ) t_rslt = net.tt.map { |t| exclude_transition t }.reduce :| p_rslt = net.pp.map { |p| exclude_place p }.reduce :| p_rslt || t_rslt end |
#exclude_place(place) ⇒ Object
Excludes a place from the receiver. Returns true if successful, false if the place was not found in the receiver net. A place may not be excluded from the receiver so long as any transitions therein connect to it.
72 73 74 75 76 77 |
# File 'lib/y_petri/net.rb', line 72 def exclude_place place place = Place().instance( place ) fail "Unable to exclude #{place} from #{self}: Transitions depend on it!" if transitions.any? { |transition| transition.arcs.include? place } false.tap { return true if @places.delete( place ) } end |
#exclude_transition(transition) ⇒ Object
Excludes a transition from the receiver. Returns true if successful, false if the transition was not found in the receiver net.
82 83 84 85 |
# File 'lib/y_petri/net.rb', line 82 def exclude_transition transition transition = Transition().instance( transition ) false.tap { return true if @transitions.delete( transition ) } end |
#functional? ⇒ Boolean
Is the net functional?
154 155 156 |
# File 'lib/y_petri/net.rb', line 154 def functional? transitions.any? &:functional? end |
#include_net(net) ⇒ Object Also known as: merge!
Includes another net in the receiver net. Returns true if successful (ie. if there was any change to the receiver net), false if the receiver net already includes the argument net.
91 92 93 94 95 96 |
# File 'lib/y_petri/net.rb', line 91 def include_net net net = Net().instance( net ) rescue YPetri::Net.instance( net ) p_results = net.pp.map &method( :include_place ) t_results = net.tt.map &method( :include_transition ) ( p_results + t_results ).reduce :| end |
#include_place(place) ⇒ Object
Includes a place in the receiver. Returns true if successful, false if the place is already included in the receiver net.
50 51 52 53 54 |
# File 'lib/y_petri/net.rb', line 50 def include_place place place = Place().instance( place ) return false if include_place? place true.tap { @places << place } end |
#include_transition(transition) ⇒ Object
Includes a transition in the receiver. Returns true if successful, false if the transition is already included in the net. The arcs of the transition being included may only connect to the places already in the receiver net.
60 61 62 63 64 65 66 |
# File 'lib/y_petri/net.rb', line 60 def include_transition transition transition = Transition().instance( transition ) return false if include_transition? transition fail "Transition #{transition} has arcs to places outside #{self}!" unless transition.arcs.all? { |place| include_place? place } true.tap { @transitions << transition } end |
#inspect ⇒ Object
Inspect string of the instance.
189 190 191 |
# File 'lib/y_petri/net.rb', line 189 def inspect to_s end |
#simulation(**settings) ⇒ Object Also known as: new_simulation
Creates a new simulation from the net.
166 167 168 |
# File 'lib/y_petri/net.rb', line 166 def simulation( **settings ) Simulation().__new__ **settings end |
#timed? ⇒ Boolean
Is the net timed?
160 161 162 |
# File 'lib/y_petri/net.rb', line 160 def timed? transitions.any? &:timed? end |
#to_s ⇒ Object
Returns a string briefly describing the net.
180 181 182 183 184 185 |
# File 'lib/y_petri/net.rb', line 180 def to_s form = "#<Net: %s>" content = ( name.nil? ? "%s" : "name: #{name}, %s" ) % "#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions" form % content end |