lib/pione/pnml/input-reduction.rb
module Pione
module PNML
# `InputReduction` is a net rewriting rule. This rule removes unnecessary
# input nodes of transitions by following criteria. For example, the net
# likes the following(A and B are transitions)
#
# A --> place --> empty transition --> empty place --> B
#
# is rewritten as the following.
#
# A -> place -> B
#
module InputReduction
# Return subjects(source transtion, target place, and the arc) if the net
# satisfies input reduction's condtions. The conditions are followings:
#
# - There is an empty source transition.
# - There is an empty target place. It is an input of named transition.
# - There is an arc that connects the source and the target.
def self.find_subjects(net, env)
net.transitions.each do |rule|
# rule has its name
next if Perspective.empty?(env, rule)
# find source places
net.find_all_places_by_target_id(rule.id).each do |place|
# the source place has empty name
next unless Perspective.empty?(env, place)
# find transtions that generates the source place
transitions = net.find_all_transitions_by_target_id(place.id)
# only one transtion
if transitions.size == 1
transition = transitions.first
# the transition is connected to only one place at target side
if net.find_all_places_by_source_id(transition.id).size == 1
# the transition has empty name
if Perspective.empty?(env, transition)
return [transition, place, net.find_arc(transition.id, place.id)]
end
end
end
end
end
return nil
end
# Rewrite the net with subjects by the following way.
#
# - Remove the subject place.
# - Remove the subject transition.
# - Remove the subject and related arcs.
# - Connect discontinuous nodes by new arcs.
def self.rewrite(net, subjects, env)
transition, place, arc = subjects
# remove subjects from the net
net.places.delete(place)
net.transitions.delete(transition)
net.arcs.delete(arc)
# remove related arcs
input_arcs = net.find_all_arcs_by_target_id(transition.id)
input_arcs.each {|arc| net.arcs.delete(arc)}
output_arcs = net.find_all_arcs_by_source_id(place.id)
output_arcs.each {|arc| net.arcs.delete(arc)}
# append new arcs
input_arcs.each do |input_arc|
output_arcs.each do |output_arc|
net.arcs << Arc.new(net, net.generate_id, input_arc.source_id, output_arc.target_id)
end
end
end
end
end
end