cclausen/petri_net

View on GitHub
lib/petri_net/place.rb

Summary

Maintainability
A
55 mins
Test Coverage
class PetriNet::Place < PetriNet::Base
    # Unique ID
    attr_reader :id
    # Needed to sanitize a Petrinet after merging
    attr_writer :id
    # Human readable name
    attr_accessor :name
    # description
    attr_accessor :description
    #Token capacity
    attr_accessor :capacity
    # List of input-arcs
    attr_reader   :inputs
    # List of output-arcs
    attr_reader   :outputs
    # Current token
    attr_reader :markings
    # The net this place belongs to
    attr_writer   :net

    # Initialize a new place.  Supports block configuration.
    def initialize(options = {}, &block)
        @id = next_object_id
        @name = (options[:name] or "Place#{@id}")
        @description = (options[:description] or "Place #{@id}")
        @capacity = options[:capacity].nil? ? Float::INFINITY : options[:capacity]
        @inputs = Array.new
        @outputs = Array.new
        @markings = Array.new

        yield self unless block == nil
    end    

    # Add an input arc
    def add_input(arc)
        @inputs << arc.id unless (arc.nil? or !validate_input arc)
    end

    # Add an output arc
    def add_output(arc)
        @outputs << arc.id unless (arc.nil? or !validate_input arc)
    end

    def add_marking(count = 1)
        if count <= @capacity
            count.times do
                @markings << PetriNet::Marking.new
            end
            return true
        else
            raise "Tried to add more markings than possible"
        end
    end

    def set_marking(count)
        @markings = []
        add_marking count
    end

    alias_method :+, :add_marking

    def remove_marking(count = 1)
        if @markings.size >= count
            ret = @markings.pop(count)
            return ret unless ret.nil?
        else
            raise "Tried to remove more markings that possible" 
        end
    end
    alias_method :-, :remove_marking

    # GraphViz ID
    def gv_id
        "P#{@id}"
    end

    # Validate the setup of this place.
    def validate
        return false if @id.nil? or @id < 0
        return false if @name.nil? or @name.strip.length <= 0
        return false if @description.nil? or @description.strip.length <= 0
        return false if @capacity.nil? or @capacity < -1
        return true
    end

    def pretransitions
        raise "Not part of a net" if @net.nil?
        transitions = Array.new
        places << inputs.map{|i| @net.objects[i].source}
    end

    def posttransitions
        raise "Not part of a net" if @net.nil?
        outputs.map{|o| @net.objects[o].source}
    end

    # Stringify this place.
    def to_s
        "#{@id}: #{@name} (#{@capacity == nil ? -1 : 0}) #{'*' * @markings.length}"
    end

    # GraphViz definition
    def to_gv
        "\t#{self.gv_id} [ label = \"#{@name} #{@markings.size}  \" ];\n"
    end
    def ==(object)
        return true if name == object.name && description = object.description
    end

private
        def validate_input(arc)
            self.inputs.each do |a|
                return false if ((@net.get_objects[a] <=> arc) == 0)
            end
            true
        end 
        def validate_output(arc)
            self.outputs.each do |a|
                return false if ((@net.get_objects[a] <=> arc) == 0)
            end
            true
        end
end