class Petrinet::Net
Represents a Petri Net
in a particular state. Instances of this class are immutable. The following methods return new instances:
-
mark
-
fire
The internal representation uses a VASS - en.wikipedia.org/wiki/Vector_addition_system A good explanation of how this works with Petri Nets is here: github.com/bitwrap/bitwrap-io/blob/master/whitepaper.md
Attributes
prefire_transition_name[R]
Public Class Methods
build(&proc)
click to toggle source
# File lib/petrinet/net.rb, line 22 def self.build(&proc) builder = Builder.new proc.call(builder) builder.net end
from_pnml(xml)
click to toggle source
# File lib/petrinet/net.rb, line 17 def self.from_pnml(xml) builder = PnmlBuilder.new(xml) builder.net end
new(state_vector, place_index_by_place_name, transition_vectors_by_transition_name, prefire_transition_name = nil)
click to toggle source
# File lib/petrinet/net.rb, line 30 def initialize(state_vector, place_index_by_place_name, transition_vectors_by_transition_name, prefire_transition_name = nil) @state_vector = state_vector @place_index_by_place_name = place_index_by_place_name @transition_vectors_by_transition_name = transition_vectors_by_transition_name @prefire_transition_name = prefire_transition_name freeze end
Public Instance Methods
fire(transition_name)
click to toggle source
# File lib/petrinet/net.rb, line 48 def fire(transition_name) new_state_vector = new_state_vector(transition_name) self.class.new(new_state_vector, @place_index_by_place_name, @transition_vectors_by_transition_name) end
fireable()
click to toggle source
# File lib/petrinet/net.rb, line 66 def fireable result = Set.new @transition_vectors_by_transition_name.keys.each do |transition_name| begin fire(transition_name) result.add(transition_name) rescue => ignore # It wasn't fireable - ignore it end end result end
fireable?(transition_name)
click to toggle source
# File lib/petrinet/net.rb, line 57 def fireable?(transition_name) begin new_state_vector(transition_name) true rescue false end end
mark(marking)
click to toggle source
Marks the petri net and returns a new instance
# File lib/petrinet/net.rb, line 39 def mark(marking) new_state_vector = Array.new(@state_vector.size, 0) marking.each do |place_name, token_count| index = @place_index_by_place_name[place_name] new_state_vector[index] = token_count end self.class.new(new_state_vector, @place_index_by_place_name, @transition_vectors_by_transition_name) end
prefire(transition_name)
click to toggle source
# File lib/petrinet/net.rb, line 53 def prefire(transition_name) self.class.new(@state_vector, @place_index_by_place_name, @transition_vectors_by_transition_name, transition_name) end
to_animated_gif(transition_names, gif_path)
click to toggle source
# File lib/petrinet/net.rb, line 84 def to_animated_gif(transition_names, gif_path) builder = AnimatedGifBuilder.new(self) builder.write(transition_names, gif_path) end
to_svg()
click to toggle source
# File lib/petrinet/net.rb, line 79 def to_svg builder = GraphvizBuilder.new(self, @transition_vectors_by_transition_name, @place_index_by_place_name.invert, @state_vector) builder.svg end
Private Instance Methods
new_state_vector(transition_name)
click to toggle source
# File lib/petrinet/net.rb, line 91 def new_state_vector(transition_name) transition_vectors = @transition_vectors_by_transition_name[transition_name] raise "Unknown transition: #{transition_name}. Known transitions: #{@transition_vectors_by_transition_name.keys}" if transition_vectors.nil? transition_vectors.reduce(@state_vector) do |state_vector, transition_vector| v = state_vector.zip(transition_vector).map { |s, t| s + t } raise "Cannot fire: #{transition_name}" unless valid?(v) v end end
valid?(state_vector)
click to toggle source
# File lib/petrinet/net.rb, line 101 def valid?(state_vector) !(state_vector.any? { |s| s.negative? }) end