lib/y_petri/net.rb in y_petri-2.1.51 vs lib/y_petri/net.rb in y_petri-2.2.0
- old
+ new
@@ -42,71 +42,113 @@
transitions.each &method( :include_transition )
param_class( { Simulation: YPetri::Simulation },
with: { net: self } )
end
- # Includes a place in the net. Returns _true_ if successful, _false_ if the
- # place is already included in the net.
+ # 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 }
end
- # Includes a transition in the net. 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 net.
+ # 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 }
end
- # Excludes a place from the net. Returns _true_ if successful, _false_ if the
- # place was not found in the net. A place may not be excluded from the net so
- # long as any transitions in the net connect to it.
+ # 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 ) }
end
- # Excludes a transition from the net. Returns _true_ if successful, _false_ if
- # the transition was not found in the net.
+ # 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 ) }
end
- # Includes an element in the net.
+ # 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
+ 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.
+ #
+ def exclude_net id
+ net = Net().instance( id )
+ 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.
+ #
def << element_id
begin
- element = self.class.place( element_id )
- type = :place
+ type, element = :place, self.class.place( element_id )
rescue NameError, TypeError
begin
- element = self.class.transition( element_id )
- type = :transition
+ type, element = :transition, self.class.transition( element_id )
rescue NameError, TypeError => err
raise TypeError, "Current world contains no place or transition " +
"identified by #{element_id}! (#{err})"
end
end
- # Separated to minimize the code inside rescue clause:
- if type == :place then include_place element
- elsif type == :transition then include_transition element
- else fail "Implementation error in YPetri::Net#<<!" 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 )
+ 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
+ # operands.
+ #
+ def + other
+ self.class.send( :new ).tap do |net|
+ 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.
+ #
+ def - other
+ self.class.send( :new ).tap do |net|
+ net.merge! self
+ net.exclude_net other
+ end
+ end
+
# Is the net _functional_?
#
def functional?
transitions.any? { |t| t.functional? }
end
@@ -131,13 +173,13 @@
end
# Returns a string briefly describing the net.
#
def to_s
- "#<Net: " +
- ( name.nil? ? "%s" : "name: #{name}, %s" ) %
- "#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions" +
- ">"
+ form = "#<Net: %s>"
+ content = ( name.nil? ? "%s" : "name: #{name}, %s" ) %
+ "#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions"
+ form % content
end
# Inspect string of the instance.
#
def inspect