lib/y_petri/net.rb in y_petri-2.2.4 vs lib/y_petri/net.rb in y_petri-2.3.2
- old
+ new
@@ -1,128 +1,142 @@
# encoding: utf-8
-require_relative 'net/element_access'
+require_relative 'net/node_access'
require_relative 'net/visualization'
require_relative 'net/own_state'
require_relative 'net/data_set'
require_relative 'net/state'
# 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 elements (places or transitions).
+# neighbors of nodes (places or transitions).
#
class YPetri::Net
+ # ===========================================================================
+ # !!! TODO !!!
+ #
+ # Refactoring plans for Net class
+ #
+ # Make it a subclass of Module class, so places and transitions can simply
+ # be defined as its constants.
+ #
+ # ===========================================================================
+
★ NameMagic # ★ means include
- ★ ElementAccess # to be below ElementAccess
+ ★ NodeAccess
★ Visualization
★ OwnState
class << self
★ YPetri::World::Dependency
- # Constructs a net containing a particular set of elements.
+ private :new
+
+ # Constructs a net containing a particular set of nodes.
#
- def of elements
- new.tap { |inst| elements.each { |e| inst << e } }
+ def of nodes
+ new.tap { |inst| nodes.each { |node| inst << node } }
end
end
delegate :world, to: "self.class"
delegate :Place, :Transition, :Net, to: :world
# Takes 2 arguments (+:places+ and +:transitions+) and builds a net from them.
#
def initialize( places: [], transitions: [] )
- param_class( { State: State }, with: { net: self } )
+ param_class!( { State: State,
+ Simulation: YPetri::Simulation },
+ with: { net: self } )
@places, @transitions = [], []
places.each &method( :include_place )
transitions.each &method( :include_transition )
- param_class( { Simulation: YPetri::Simulation },
- with: { net: self } )
end
# Includes a place in the receiver. Returns _true_ if successful, _false_ if
# the place is already included in the receiver net.
#
- def include_place id
- pl = Place().instance( id )
- return false if includes_place? pl
- true.tap { @places << pl }
+ def include_place place
+ place = Place().instance( place )
+ return false if include_place? place
+ true.tap { @places << place }
end
# 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.
#
- def include_transition id
- tr = Transition().instance( id )
- return false if includes_transition? tr
- msg = "Transition #{tr} has arcs to places outside #{self}!"
- fail msg unless tr.arcs.all? { |p| includes_place? p }
- true.tap { @transitions << tr }
+ 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
# 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.
#
- def exclude_place id
- pl = Place().instance( id )
- msg = "Unable to exclude #{pl} from #{self}: Transition(s) depend on it!"
- fail msg if transitions.any? { |tr| tr.arcs.include? pl }
- false.tap { return true if @places.delete( pl ) }
+ 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
# Excludes a transition from the receiver. Returns _true_ if successful,
# _false_ if the transition was not found in the receiver net.
#
- def exclude_transition id
- tr = Transition().instance( id )
- false.tap { return true if @transitions.delete( tr ) }
+ def exclude_transition transition
+ transition = Transition().instance( transition )
+ false.tap { return true if @transitions.delete( transition ) }
end
# 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.
#
- def include_net id
- net = Net().instance( id )
- p_rslt = net.pp.map { |p| include_place p }.reduce :|
- t_rslt = net.tt.map { |t| include_transition t }.reduce :|
- p_rslt || t_rslt
+ 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
alias merge! include_net
# 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 element of the argument net.
+ # net contained no node of the argument net.
#
def exclude_net id
- net = Net().instance( 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
- # Includes an element (place or transition) in the net.
+ # Includes a node (place or transition) in the receiver net.
#
- def << element_id
+ def << node
begin
- type, element = :place, self.class.place( element_id )
+ type = :place
+ place = self.class.place node
rescue NameError, TypeError
begin
- type, element = :transition, self.class.transition( element_id )
+ type = :transition
+ transition = self.class.transition node
rescue NameError, TypeError => err
- raise TypeError, "Current world contains no place or transition " +
- "identified by #{element_id}! (#{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( element )
- when :transition then include_transition( element )
+ 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
# Creates a new net that contains all the places and transitions of both
@@ -133,36 +147,37 @@
net.merge! self
net.merge! other
end
end
- # Creates a new net that contains the places and transition of the receiver
- # after excluding the second operand.
+ # Returns a new net that is the result of subtraction of the net given as
+ # argument from this net.
#
def - other
self.class.send( :new ).tap do |net|
- net.merge! self
+ net.include_net self
net.exclude_net other
end
end
# Is the net _functional_?
#
def functional?
- transitions.any? { |t| t.functional? }
+ transitions.any? &:functional?
end
# Is the net _timed_?
#
def timed?
- transitions.any? { |t| t.timed? }
+ transitions.any? &:timed?
end
# Creates a new simulation from the net.
#
def simulation( **settings )
Simulation().__new__ **settings
end
+ alias new_simulation simulation
# Networks are equal when their places and transitions are equal.
#
def == other
return false unless other.class_complies?( self.class )