class Pione::PNML::ConstituentRuleBuilder
ConstituentRuleBuilder
builds constituent rule definitions.
Public Class Methods
@param net [PNML::Net]
net
@param net_name [String]
name of the net
@param env [Lang::Environment]
language environment
# File lib/pione/pnml/compiler.rb, line 98 def initialize(net, net_name, env) @net = net @net_name = net_name @env = env end
Public Instance Methods
Build a consituent rule definitions by transitions in the net.
@return [Array(Array
<RuleDefinition>,Array)]
# File lib/pione/pnml/compiler.rb, line 107 def build definition = build_rule_definition_table() # save all inner rules rules = definition.values.compact flow_elements = definition.values.compact # conditional branch @net.transitions.each do |transition| inputs = @net.find_all_places_by_target_id(transition.id).select do |place| Perspective.data_place?(@env, place) end.map {|input| InputData.new(input)} if Perspective.if_transition?(@env, transition) flow_elements << create_if_branch(transition, definition, inputs, flow_elements) elsif Perspective.case_transition?(@env, transition) flow_elements << create_case_branch(transition, definition, inputs, flow_elements) end end return [rules, flow_elements] end
Private Instance Methods
Build rule definition table.
@return [Hash{String=>RuleDefinition}]
relatioin table between transition ID and rule definition
# File lib/pione/pnml/compiler.rb, line 136 def build_rule_definition_table return @net.transitions.each_with_object({}) do |transition, table| if Perspective.rule_transition?(@env, transition) type = :action rule_name = LabelExtractor.extract_rule_expr(transition.name) is_external = Perspective.external_rule_transition?(@env, transition) rule = RuleDefinition.new(rule_name, type, is_external, @net_name, table.size) # setup rule conditions rule.inputs = find_inputs(transition) rule.outputs = find_outputs(transition) rule.params = find_params(transition) rule.constraints = find_constraints(transition) rule.source_tickets = find_source_tickets(transition) rule.target_tickets = find_target_tickets(transition) rule.features = find_features(transition) table[transition.id] = rule end end end
Create a case-branch from the transiton.
@param transition [PNML::Transition]
base transition
@return [ConditionalBranch]
conditional branch
# File lib/pione/pnml/compiler.rb, line 333 def create_case_branch(transition, definition, inputs, flow_elements) expr = @net.find_place_by_source_id(transition.id) nodes = @net.find_all_transitions_by_source_id(expr.id) keys_when = nodes.select{|node| Perspective.when_transition?(@env, node)} key_else = nodes.find{|node| Perspective.else_transition?(@env, node)} branch = ConditionalBranch.new(:case, expr.name) keys_when.each do |key| find_next_rules(key).each do |transition| rule = definition[transition.id] rule.inputs += inputs flow_elements.delete(rule) conditional_value_place = @net.find_place_by_source_id(key.id) branch.table[conditional_value_place.name] << rule end end if key_else find_next_rules(key_else).each do |transition| rule = definition[transition.id] rule.inputs += inputs flow_elements.delete(rule) branch.table[:else] << rule end end return branch end
Create a if-branch from the transiton.
@param transition [PNML::Transition]
base transition
@return [ConditionalBranch]
conditional branch
# File lib/pione/pnml/compiler.rb, line 299 def create_if_branch(transition, definition, inputs, flow_elements) condition = @net.find_place_by_source_id(transition.id) nodes = @net.find_all_transitions_by_source_id(condition.id) key_then = nodes.find{|node| Perspective.then_transition?(@env, node)} key_else = nodes.find{|node| Perspective.else_transition?(@env, node)} branch = ConditionalBranch.new(:if, condition.name) find_next_rules(key_then).each do |transition| rule = definition[transition.id] rule.inputs += inputs flow_elements.delete(rule) branch.table[:then] << rule end if key_else find_next_rules(key_else).each do |transition| rule = definition[transition.id] rule.inputs += inputs flow_elements.delete(rule) branch.table[:else] << rule end end return branch end
Find constraints from net.
@param transition [Transition]
base transition
@return [Array<Constraint>]
rule constraints
# File lib/pione/pnml/compiler.rb, line 224 def find_constraints(transition) @net.find_all_places_by_target_id(transition.id).each_with_object([]) do |place, constraints| prev_transitions = @net.find_all_transitions_by_target_id(place.id) constraint_transitions = prev_transitions.select{|t| Perspective.constraint_transition?(@env, t)} case constraint_transitions.size when 0 # ignore when 1 if Perspective.expr_place?(@env, place) constraints << Constraint.new(place.name) else # the place should be constraint expression raise CompilerError.should_be_constraint_expr(place) end else # multiple constraint keywords found raise CompilerError.multiple_constraint_keywords(transition.name) end end end
Find features from net.
@param transition [Transition]
base transition
@return [Array<Feature>]
features
# File lib/pione/pnml/compiler.rb, line 280 def find_features(transition) @net.find_all_places_by_target_id(transition.id).each_with_object([]) do |place, features| if Perspective.feature_place?(@env, place) keyword_transitions = @net.find_all_transitions_by_target_id(place.id).select do |t| Perspective.keyword_transition?(@env, t) end if keyword_transitions.empty? features << Feature.new(place.name) end end end end
Find inputs from net.
@param transition [Transition]
base transition
@return [Array<InputData>]
rule inputs
# File lib/pione/pnml/compiler.rb, line 164 def find_inputs(transition) @net.find_all_places_by_target_id(transition.id).each_with_object([]) do |place, inputs| begin # consideration for constraint nodes prev_transition = @net.find_transition_by_target_id(place.id) if Perspective.constraint_transition?(@env, prev_transition) @net.find_all_places_by_target_id(prev_transition.id).each do |_place| if Perspective.data_place?(@env, _place) inputs << InputData.new(_place) end end else if Perspective.data_place?(@env, place) inputs << InputData.new(place) end end rescue AmbiguousNetQueryResult # ignore end end end
Find next rules.
@param base_rule [PNML::Transition]
base transition
# File lib/pione/pnml/compiler.rb, line 368 def find_next_rules(base_rule) @net.find_all_places_by_source_id(base_rule.id).each_with_object([]) do |place, res| @net.find_all_transitions_by_source_id(place.id).each do |transition| if Perspective.rule_transition?(@env, transition) res << transition else find_next_rules(transition) end end end end
Find outputs from net.
@param transition [Transition]
base transition
@return [Array]
rule outputs
# File lib/pione/pnml/compiler.rb, line 192 def find_outputs(transition) @net.find_all_places_by_source_id(transition.id).each_with_object([]) do |place, outputs| if Perspective.data_place?(@env, place) outputs << OutputData.new(place) end end end
Find parameters from net.
@param transition [Transition]
base transition
@return [Array<Param>]
rule parameters
# File lib/pione/pnml/compiler.rb, line 206 def find_params(transition) @net.find_all_places_by_target_id(transition.id).each_with_object([]) do |place, params| if Perspective.param_place?(@env, place) prev_transitions = @net.find_all_transitions_by_target_id(place.id) keyword_transitions = prev_transitions.select{|t| Perspective.keyword_transition?(@env, t)} if keyword_transitions.empty? params << Param.set_of(place) end end end end
Find source tickets from net.
@param transition [Transition]
base transition
@return [Array<Ticket>]
tickets
# File lib/pione/pnml/compiler.rb, line 252 def find_source_tickets(transition) @net.find_all_places_by_target_id(transition.id).each_with_object([]) do |place, tickets| if Perspective.ticket_place?(@env, place) tickets << Ticket.new(place.name) end end end
Find target tickets from net.
@param transition [Transition]
base transition
@return [Array<Ticket>]
tickets
# File lib/pione/pnml/compiler.rb, line 266 def find_target_tickets(transition) @net.find_all_places_by_source_id(transition.id).each_with_object([]) do |place, tickets| if Perspective.ticket_place?(@env, place) tickets << Ticket.new(place.name) end end end