petri_net 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.rdoc +3 -3
- data/Rakefile +13 -8
- data/lib/petri_net/net.rb +29 -21
- data/lib/petri_net/{edge.rb → reachability_graph/edge.rb} +0 -0
- data/lib/petri_net/reachability_graph/graph.rb +118 -0
- data/lib/petri_net/reachability_graph/node.rb +119 -0
- data/lib/petri_net/reachability_graph.rb +5 -1
- data/lib/petri_net/version.rb +3 -1
- data/lib/petri_net.rb +0 -2
- data/test/{tc_edge.rb → reachability_graph/tc_edge.rb} +0 -0
- data/test/reachability_graph/tc_graph.rb +61 -0
- data/test/reachability_graph/tc_node.rb +67 -0
- data/test/tc_petri_net.rb +6 -1
- data/test/ts_all.rb +2 -0
- data/test/ts_petri_net.rb +4 -0
- data/test/ts_reachability_graph.rb +3 -0
- metadata +17 -12
- data/lib/petri_net/node.rb +0 -44
- data/test/tc_graph.rb +0 -0
- data/test/tc_node.rb +0 -0
- data/test/ts_test_all.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ac9fa5977f53b289d5fc97d42c14a2847b80c9c
|
4
|
+
data.tar.gz: d66436746d5f190ef3bf3c8361242ecb71dd5d6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1e585661a11b0ab1789454a4f401d85de55fecbafdf913663083f06c23d2686cbb9ba6e98e7db810358f78514aa998af8ad6be448ffae2480cb81c2aab6ba8a
|
7
|
+
data.tar.gz: 3fbcf881036c7f18f87f14b0b21d226bfcc81b14e33ea772c9d716cda5b5dcdd805949e2c54f825d57f3ca04f8e03b487208e21f4a6fbbd4ea420f5f2fc9aa79
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
{<img src="https://travis-ci.org/cclausen/
|
1
|
+
{<img src="https://travis-ci.org/cclausen/petri_net.png" />}[https://travis-ci.org/cclausen/petri_net]
|
2
2
|
|
3
|
-
{<img src="https://codeclimate.com/github/cclausen/
|
3
|
+
{<img src="https://codeclimate.com/github/cclausen/petri_net.png" />}[https://codeclimate.com/github/cclausen/petri_net]
|
4
4
|
|
5
5
|
= PTNet: Petri-net Simulation in Ruby
|
6
6
|
===== based on the code by Brian D Nelson <bdnelson@wildcoder.com>
|
7
|
-
===== Christian Clausen cclausen@tzi.de
|
7
|
+
===== Christian Clausen <cclausen@tzi.de>
|
8
8
|
|
9
9
|
== Version 0.6
|
10
10
|
I implemented most of the basics you need for playing with PetriNets but there are a lot things to add.
|
data/Rakefile
CHANGED
@@ -1,24 +1,29 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'rake'
|
2
3
|
require 'rake/testtask'
|
3
|
-
|
4
|
+
require 'rake/tasklib'
|
5
|
+
require 'rdoc/rdoc'
|
6
|
+
require 'rdoc/task'
|
7
|
+
|
4
8
|
require 'net/sftp'
|
5
9
|
require 'fileutils'
|
6
10
|
|
7
11
|
desc 'Default task'
|
8
|
-
task :default => [:test, :rdoc, :
|
12
|
+
task :default => [:test, :rdoc, :clean]
|
9
13
|
|
10
14
|
task(:test) { puts "==> Running main test suite" }
|
11
15
|
Rake::TestTask.new(:test) do |t|
|
12
|
-
t.test_files = FileList['test/
|
16
|
+
t.test_files = FileList['test/ts_all']
|
13
17
|
t.ruby_opts = ['-rubygems'] if defined? Gem
|
14
18
|
end
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
21
|
+
rdoc.main = "README"
|
22
|
+
rdoc.rdoc_files.include('LICENSE', 'CHANGELOG','lib/')
|
23
|
+
rdoc.title = "PetriNet Documentation"
|
19
24
|
# rdoc.options << '--webcvs=http://svn.wildcoder.com/svn/petri/trunk/'
|
20
|
-
|
21
|
-
|
25
|
+
rdoc.rdoc_dir = 'doc' # rdoc output folder
|
26
|
+
end
|
22
27
|
|
23
28
|
desc 'Clean up unused files.'
|
24
29
|
task :clean => :clobber_rdoc do
|
data/lib/petri_net/net.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
class PetriNet::Net < PetriNet::Base
|
2
4
|
# Human readable name
|
3
5
|
attr_accessor :name
|
@@ -152,27 +154,22 @@ class PetriNet::Net < PetriNet::Base
|
|
152
154
|
|
153
155
|
# Stringify this Petri Net.
|
154
156
|
def to_s
|
155
|
-
str =
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
str += "Arcs\n"
|
172
|
-
str += "----------------------------\n"
|
173
|
-
@arcs.each_value {|a| str += @objects[a].to_s + "\n"}
|
174
|
-
str += "\n"
|
175
|
-
|
157
|
+
str =
|
158
|
+
%{Petri Net [#{@name}]
|
159
|
+
----------------------------
|
160
|
+
Description: #{@description}
|
161
|
+
Filename: #{@filename}
|
162
|
+
|
163
|
+
Places
|
164
|
+
----------------------------
|
165
|
+
#{str = ''; @places.each_value {|p| str += @objects[p].to_s + "\n"}; str }
|
166
|
+
Transitions
|
167
|
+
----------------------------
|
168
|
+
#{str = ''; @transitions.each_value {|t| str += @objects[t].to_s + "\n" }; str }
|
169
|
+
Arcs
|
170
|
+
----------------------------
|
171
|
+
#{str = ''; @arcs.each_value {|a| str += @objects[a].to_s + "\n" }; str}
|
172
|
+
}
|
176
173
|
return str
|
177
174
|
end
|
178
175
|
|
@@ -289,6 +286,14 @@ class PetriNet::Net < PetriNet::Base
|
|
289
286
|
@objects.find_index object
|
290
287
|
end
|
291
288
|
|
289
|
+
def save filename
|
290
|
+
File.open(filename, 'w') {|f| @net.to_yaml}
|
291
|
+
end
|
292
|
+
|
293
|
+
def load filename
|
294
|
+
@net = YAML.load(File.read(filename))
|
295
|
+
end
|
296
|
+
|
292
297
|
private
|
293
298
|
|
294
299
|
def changed_structure
|
@@ -306,6 +311,9 @@ class PetriNet::Net < PetriNet::Base
|
|
306
311
|
current_node = PetriNet::ReachabilityGraph::Node.new(markings: get_markings)
|
307
312
|
current_node_id = @graph.add_node current_node
|
308
313
|
@graph.add_edge PetriNet::ReachabilityGraph::Edge.new(source: source, destination: current_node, probability: @objects[tid].probability) unless current_node_id < 0
|
314
|
+
if current_node_id < 0 && @graph.get_node(current_node_id * -1) < current_node
|
315
|
+
@graph.getNode(current_node_id * -1).add_omega current_node
|
316
|
+
end
|
309
317
|
reachability_helper get_markings, current_node unless (current_node_id < 0)
|
310
318
|
end
|
311
319
|
set_markings markings
|
File without changes
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class PetriNet::InfiniteReachabilityGraphError < RuntimeError
|
2
|
+
end
|
3
|
+
|
4
|
+
class PetriNet::ReachabilityGraph < PetriNet::Base
|
5
|
+
def initialize(net, options = Hash.new)
|
6
|
+
@objects = Array.new
|
7
|
+
@nodes = Hash.new
|
8
|
+
@edges = Hash.new
|
9
|
+
@name = net.name
|
10
|
+
if options['unlimited'].nil?
|
11
|
+
@unlimited = true
|
12
|
+
else
|
13
|
+
@unlimited = options['unlimited']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_node(node)
|
18
|
+
@nodes.each_value do |n|
|
19
|
+
begin
|
20
|
+
if node > @objects[n]
|
21
|
+
if @unlimited
|
22
|
+
return @objects[n].id *-1
|
23
|
+
else
|
24
|
+
raise PetriNet::ReachabilityGraph::InfiniteReachabilityGraphError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
rescue ArgumentError
|
28
|
+
#just two different markings, completly ok
|
29
|
+
end
|
30
|
+
end
|
31
|
+
node_index = @objects.index node
|
32
|
+
if (!node_index.nil?)
|
33
|
+
return @objects[node_index].id * -1
|
34
|
+
end
|
35
|
+
|
36
|
+
if (node.validate && (!@nodes.include? node.name))
|
37
|
+
@objects[node.id] = node
|
38
|
+
@nodes[node.name] = node.id
|
39
|
+
node.graph = self
|
40
|
+
return node.id
|
41
|
+
end
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_edge(edge)
|
46
|
+
if (edge.validate && (!@edges.include? edge.name))
|
47
|
+
@objects[edge.id] = edge
|
48
|
+
@edges[edge.name] = edge.id
|
49
|
+
edge.graph = self
|
50
|
+
return edge.id
|
51
|
+
end
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add an object to the Petri Net.
|
56
|
+
def <<(object)
|
57
|
+
case object.class.to_s
|
58
|
+
when "Array"
|
59
|
+
object.each {|o| self << o}
|
60
|
+
when "PetriNet::ReachabilityGraph::Edge"
|
61
|
+
add_edge(object)
|
62
|
+
when "PetriNet::ReachabilityGraph::Node"
|
63
|
+
add_node(object)
|
64
|
+
else
|
65
|
+
raise "(PetriNet::ReachabilityGraph) Unknown object #{object.class}."
|
66
|
+
end
|
67
|
+
self
|
68
|
+
end
|
69
|
+
alias_method :add_object, :<<
|
70
|
+
|
71
|
+
def get_node(id)
|
72
|
+
return @objects[id]
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_gv
|
76
|
+
# General graph options
|
77
|
+
str = "digraph #{@name} {\n"
|
78
|
+
str += "\t// General graph options\n"
|
79
|
+
str += "\trankdir = LR;\n"
|
80
|
+
str += "\tsize = \"10.5,7.5\";\n"
|
81
|
+
str += "\tnode [ style = filled, fillcolor = white, fontsize = 8.0 ]\n"
|
82
|
+
str += "\tedge [ arrowhead = vee, arrowsize = 0.5, fontsize = 8.0 ]\n"
|
83
|
+
str += "\n"
|
84
|
+
|
85
|
+
str += "\t// Nodes\n"
|
86
|
+
str += "\tnode [ shape = circle ];\n"
|
87
|
+
@nodes.each_value {|id| str += @objects[id].to_gv }
|
88
|
+
str += "\n"
|
89
|
+
|
90
|
+
str += "\t// Edges\n"
|
91
|
+
@edges.each_value {|id| str += @objects[id].to_gv }
|
92
|
+
str += "}\n" # Graph closure
|
93
|
+
|
94
|
+
return str
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_s
|
99
|
+
str = "Reachability Graph [#{@name}]\n"
|
100
|
+
str += "----------------------------\n"
|
101
|
+
str += "Description: #{@description}\n"
|
102
|
+
str += "Filename: #{@filename}\n"
|
103
|
+
str += "\n"
|
104
|
+
|
105
|
+
str += "Nodes\n"
|
106
|
+
str += "----------------------------\n"
|
107
|
+
@nodes.each_value {|p| str += @objects[p].to_s + "\n" }
|
108
|
+
str += "\n"
|
109
|
+
|
110
|
+
str += "Edges\n"
|
111
|
+
str += "----------------------------\n"
|
112
|
+
@edges.each_value {|t| str += @objects[t].to_s + "\n" }
|
113
|
+
str += "\n"
|
114
|
+
|
115
|
+
return str
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
class PetriNet::ReachabilityGraph::Node < PetriNet::Base
|
2
|
+
include Comparable
|
3
|
+
|
4
|
+
# human readable name
|
5
|
+
attr_reader :name
|
6
|
+
# unique ID
|
7
|
+
attr_reader :id
|
8
|
+
# Makking this node represents
|
9
|
+
attr_reader :markings
|
10
|
+
# The graph this node belongs to
|
11
|
+
attr_accessor :graph
|
12
|
+
# Omega-marked node (unlimited Petrinet -> coverabilitygraph)
|
13
|
+
attr_reader :omega_marked
|
14
|
+
# Incoming edges
|
15
|
+
attr_reader :inputs
|
16
|
+
# Outgoing edges
|
17
|
+
attr_reader :outputs
|
18
|
+
# Label of the node
|
19
|
+
attr_reader :label
|
20
|
+
|
21
|
+
def initialize(options = {}, &block)
|
22
|
+
@id = next_object_id
|
23
|
+
@name = (options[:name] or "Node#{@id}")
|
24
|
+
@description = (options[:description] or "Node #{@id}")
|
25
|
+
@inputs = Array.new
|
26
|
+
@outputs = Array.new
|
27
|
+
@label = (options[:label] or @name)
|
28
|
+
@markings = options[:markings]
|
29
|
+
if @markings.nil?
|
30
|
+
raise ArgumentError.new "Every Node needs markings"
|
31
|
+
end
|
32
|
+
if @markings.include? Float::INFINITY
|
33
|
+
@omega_marked = true
|
34
|
+
else
|
35
|
+
@omega_marked = false
|
36
|
+
end
|
37
|
+
|
38
|
+
yield self unless block.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add an omega-marking to a specified place
|
42
|
+
def add_omega object
|
43
|
+
if object.class.to_s == "PetriNet::ReachabilityGraph::Node"
|
44
|
+
if self > object
|
45
|
+
counter = 0
|
46
|
+
object.markings.each do |marking|
|
47
|
+
if @markings[counter] < marking
|
48
|
+
@markings[counter] = Fload::INFINITY
|
49
|
+
end
|
50
|
+
counter += 1
|
51
|
+
end
|
52
|
+
else
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
elsif object.class.to_s == "Array"
|
56
|
+
object.each do |place|
|
57
|
+
markings[place] = Float::INFINITY
|
58
|
+
end
|
59
|
+
elsif object.class.to_s == "Fixnum"
|
60
|
+
markings[object] = Float::INFINITY
|
61
|
+
end
|
62
|
+
@omega_marked = true
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
def gv_id
|
70
|
+
"N#{@id}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_gv
|
74
|
+
"\t#{self.gv_id} [ label = \"#{@markings}\" ];\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Compare-operator, other Operators are available through comparable-mixin
|
78
|
+
def <=>(object)
|
79
|
+
return nil unless object.class.to_s == "PetriNet::ReachabilityGraph::Node"
|
80
|
+
if @markings == object.markings
|
81
|
+
return 0
|
82
|
+
end
|
83
|
+
|
84
|
+
counter = 0
|
85
|
+
less = true
|
86
|
+
self.markings.each do |marking|
|
87
|
+
if marking <= object.markings[counter] && less
|
88
|
+
less = true
|
89
|
+
else
|
90
|
+
less = false
|
91
|
+
break
|
92
|
+
end
|
93
|
+
counter += 1
|
94
|
+
end
|
95
|
+
if less
|
96
|
+
return -1
|
97
|
+
end
|
98
|
+
counter = 0
|
99
|
+
more = true
|
100
|
+
self.markings.each do |marking|
|
101
|
+
if marking >= object.markings[counter] && more
|
102
|
+
more = true
|
103
|
+
else
|
104
|
+
more = false
|
105
|
+
break
|
106
|
+
end
|
107
|
+
counter += 1
|
108
|
+
end
|
109
|
+
if more
|
110
|
+
return 1
|
111
|
+
end
|
112
|
+
return nil
|
113
|
+
end
|
114
|
+
|
115
|
+
def to_s
|
116
|
+
"#{@id}: #{@name} (#{@markings})"
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -1,4 +1,8 @@
|
|
1
|
+
require_relative 'reachability_graph/graph'
|
2
|
+
require_relative 'reachability_graph/node'
|
3
|
+
require_relative 'reachability_graph/edge'
|
1
4
|
class PetriNet::ReachabilityGraph < PetriNet::Base
|
5
|
+
=begin
|
2
6
|
def initialize(net)
|
3
7
|
@objects = Array.new
|
4
8
|
@nodes = Hash.new
|
@@ -89,5 +93,5 @@ class PetriNet::ReachabilityGraph < PetriNet::Base
|
|
89
93
|
|
90
94
|
return str
|
91
95
|
end
|
92
|
-
|
96
|
+
=end
|
93
97
|
end
|
data/lib/petri_net/version.rb
CHANGED
data/lib/petri_net.rb
CHANGED
@@ -31,5 +31,3 @@ require "#{PETRI_LIB_FILE_PATH}/petri_net/transition"
|
|
31
31
|
require "#{PETRI_LIB_FILE_PATH}/petri_net/arc"
|
32
32
|
require "#{PETRI_LIB_FILE_PATH}/petri_net/marking"
|
33
33
|
require "#{PETRI_LIB_FILE_PATH}/petri_net/reachability_graph"
|
34
|
-
require "#{PETRI_LIB_FILE_PATH}/petri_net/node"
|
35
|
-
require "#{PETRI_LIB_FILE_PATH}/petri_net/edge"
|
File without changes
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'logger'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class TestPetriNetReachabilityGraph < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@net = PetriNet::Net.new(:name => 'Water', :description => 'Creation of water from base elements.')
|
8
|
+
@net.logger = Logger.new(STDOUT)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fill_net
|
12
|
+
@net << PetriNet::Place.new(:name => "testplace")
|
13
|
+
@net << PetriNet::Transition.new(:name => "testtrans")
|
14
|
+
arc = PetriNet::Arc.new do |a|
|
15
|
+
a.name = 'testarc'
|
16
|
+
a.weight = 2
|
17
|
+
a.add_source(@net.get_place 'testplace')
|
18
|
+
a.add_destination(@net.get_transition 'testtrans')
|
19
|
+
end
|
20
|
+
@net << arc
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
@net.reset
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_trivial_generate_reachability_graph
|
28
|
+
assert_equal "Reachability Graph [Water]
|
29
|
+
----------------------------
|
30
|
+
Description:
|
31
|
+
Filename:
|
32
|
+
|
33
|
+
Nodes
|
34
|
+
----------------------------
|
35
|
+
1: Node1 ([])
|
36
|
+
|
37
|
+
Edges
|
38
|
+
----------------------------
|
39
|
+
|
40
|
+
", @net.generate_reachability_graph().to_s, "Simple Reachability Graph with only one reachable state"
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_generate_reachability_graph
|
44
|
+
fill_net
|
45
|
+
assert_equal "Reachability Graph [Water]
|
46
|
+
----------------------------
|
47
|
+
Description:
|
48
|
+
Filename:
|
49
|
+
|
50
|
+
Nodes
|
51
|
+
----------------------------
|
52
|
+
4: Node4 ([0])
|
53
|
+
|
54
|
+
Edges
|
55
|
+
----------------------------
|
56
|
+
|
57
|
+
", @net.generate_reachability_graph().to_s, "Reachability Graph of sample net"
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'logger'
|
5
|
+
require 'test/unit'
|
6
|
+
require "#{File.dirname(__FILE__)}/../../lib/petri_net"
|
7
|
+
|
8
|
+
#require 'pry'
|
9
|
+
|
10
|
+
class TestReachabilityGraphNode < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@net = PetriNet::Net.new(:name => 'Water', :description => 'Creation of water from base elements.')
|
13
|
+
@node = PetriNet::ReachabilityGraph::Node.new(markings: [1,3,5,4,0])
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
@net.reset
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_create_node
|
21
|
+
node = PetriNet::ReachabilityGraph::Node.new(markings: [1,3,5,4,0])
|
22
|
+
assert_not_nil node
|
23
|
+
assert_equal "Node2", node.name
|
24
|
+
assert_equal [], node.inputs
|
25
|
+
assert_equal [], node.outputs
|
26
|
+
assert_equal node.name, node.label
|
27
|
+
assert_equal [1,3,5,4,0], node.markings
|
28
|
+
assert !node.omega_marked, "should not be omega_marked as there is no omega-marking"
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_omega_marking
|
32
|
+
node = PetriNet::ReachabilityGraph::Node.new(markings: [1,3,5,Float::INFINITY,0])
|
33
|
+
assert node.omega_marked, "should be omega_marked as there is an omega marking"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_adding_omega_marking
|
37
|
+
assert !@node.omega_marked
|
38
|
+
@node.add_omega 3
|
39
|
+
assert_equal [1,3,5,Float::INFINITY,0], @node.markings
|
40
|
+
assert @node.omega_marked
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_compare
|
44
|
+
node1 = PetriNet::ReachabilityGraph::Node.new(markings: [0,1,0,0,1])
|
45
|
+
node2 = PetriNet::ReachabilityGraph::Node.new(markings: [0,1,0,0,1])
|
46
|
+
node3 = PetriNet::ReachabilityGraph::Node.new(markings: [0,0,1,0,1])
|
47
|
+
node4 = PetriNet::ReachabilityGraph::Node.new(markings: [0,2,0,0,1])
|
48
|
+
node5 = PetriNet::ReachabilityGraph::Node.new(markings: [1,1,0,0,1])
|
49
|
+
node6 = PetriNet::ReachabilityGraph::Node.new(markings: [1,1,0,0,0])
|
50
|
+
|
51
|
+
assert node1 == node1
|
52
|
+
assert node2 == node2
|
53
|
+
assert node1 == node2
|
54
|
+
assert !(node1 < node2)
|
55
|
+
assert !(node1 > node2)
|
56
|
+
assert !(node3 == node1)
|
57
|
+
assert_raise ArgumentError do node3 > node1 end
|
58
|
+
assert_raise ArgumentError do node3 < node1 end
|
59
|
+
assert node4 > node1
|
60
|
+
assert node1 < node4
|
61
|
+
assert node5 > node1
|
62
|
+
assert !(node4 == node5)
|
63
|
+
assert_raise ArgumentError do node4 > node5 end
|
64
|
+
assert_raise ArgumentError do node6 > node1 end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/test/tc_petri_net.rb
CHANGED
@@ -5,7 +5,6 @@ require 'logger'
|
|
5
5
|
require 'test/unit'
|
6
6
|
require "#{File.dirname(__FILE__)}/../lib/petri_net"
|
7
7
|
|
8
|
-
#require 'pry'
|
9
8
|
|
10
9
|
class TestPetriNet < Test::Unit::TestCase
|
11
10
|
def setup
|
@@ -255,6 +254,12 @@ Edges
|
|
255
254
|
assert_equal 3, @net.objects_size
|
256
255
|
end
|
257
256
|
|
257
|
+
def test_save_and_load
|
258
|
+
fill_net
|
259
|
+
@net.save("/tmp/petrinet")
|
260
|
+
net = YAML.load(File.read("/tmp/petrinet"))
|
261
|
+
assert_not_nil net
|
262
|
+
end
|
258
263
|
|
259
264
|
# def test_create_marking
|
260
265
|
# place = PetriNet::Place.new(:name => 'Hydrogen')
|
data/test/ts_all.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: petri_net
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cclausen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-sftp
|
@@ -42,24 +42,27 @@ files:
|
|
42
42
|
- lib/petri_net.rb
|
43
43
|
- lib/petri_net/arc.rb
|
44
44
|
- lib/petri_net/base.rb
|
45
|
-
- lib/petri_net/edge.rb
|
46
45
|
- lib/petri_net/marking.rb
|
47
46
|
- lib/petri_net/net.rb
|
48
|
-
- lib/petri_net/node.rb
|
49
47
|
- lib/petri_net/place.rb
|
50
48
|
- lib/petri_net/reachability_graph.rb
|
49
|
+
- lib/petri_net/reachability_graph/edge.rb
|
50
|
+
- lib/petri_net/reachability_graph/graph.rb
|
51
|
+
- lib/petri_net/reachability_graph/node.rb
|
51
52
|
- lib/petri_net/transition.rb
|
52
53
|
- lib/petri_net/version.rb
|
53
54
|
- petri_net.gemspec
|
54
55
|
- test/create.rb
|
56
|
+
- test/reachability_graph/tc_edge.rb
|
57
|
+
- test/reachability_graph/tc_graph.rb
|
58
|
+
- test/reachability_graph/tc_node.rb
|
55
59
|
- test/tc_arc.rb
|
56
|
-
- test/tc_edge.rb
|
57
|
-
- test/tc_graph.rb
|
58
|
-
- test/tc_node.rb
|
59
60
|
- test/tc_petri_net.rb
|
60
61
|
- test/tc_place.rb
|
61
62
|
- test/tc_transition.rb
|
62
|
-
- test/
|
63
|
+
- test/ts_all.rb
|
64
|
+
- test/ts_petri_net.rb
|
65
|
+
- test/ts_reachability_graph.rb
|
63
66
|
homepage: https://github.com/cclausen/petri
|
64
67
|
licenses:
|
65
68
|
- MIT
|
@@ -87,11 +90,13 @@ summary: You can create Petri Nets and do some calculations with them like gener
|
|
87
90
|
the Reachability Graph
|
88
91
|
test_files:
|
89
92
|
- test/create.rb
|
93
|
+
- test/reachability_graph/tc_edge.rb
|
94
|
+
- test/reachability_graph/tc_graph.rb
|
95
|
+
- test/reachability_graph/tc_node.rb
|
90
96
|
- test/tc_arc.rb
|
91
|
-
- test/tc_edge.rb
|
92
|
-
- test/tc_graph.rb
|
93
|
-
- test/tc_node.rb
|
94
97
|
- test/tc_petri_net.rb
|
95
98
|
- test/tc_place.rb
|
96
99
|
- test/tc_transition.rb
|
97
|
-
- test/
|
100
|
+
- test/ts_all.rb
|
101
|
+
- test/ts_petri_net.rb
|
102
|
+
- test/ts_reachability_graph.rb
|
data/lib/petri_net/node.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
class PetriNet::ReachabilityGraph::Node < PetriNet::Base
|
2
|
-
# human readable name
|
3
|
-
attr_reader :name
|
4
|
-
# unique ID
|
5
|
-
attr_reader :id
|
6
|
-
# Makking this node represents
|
7
|
-
attr_reader :markings
|
8
|
-
# The graph this node belongs to
|
9
|
-
attr_accessor :graph
|
10
|
-
|
11
|
-
def initialize(options = {}, &block)
|
12
|
-
@id = next_object_id
|
13
|
-
@name = (options[:name] or "Node#{@id}")
|
14
|
-
@description = (options[:description] or "Node #{@id}")
|
15
|
-
@inputs = Array.new
|
16
|
-
@outputs = Array.new
|
17
|
-
@label = (options[:label] or @name)
|
18
|
-
@markings = options[:markings]
|
19
|
-
|
20
|
-
yield self unless block.nil?
|
21
|
-
end
|
22
|
-
|
23
|
-
def validate
|
24
|
-
true
|
25
|
-
end
|
26
|
-
|
27
|
-
def gv_id
|
28
|
-
"N#{@id}"
|
29
|
-
end
|
30
|
-
|
31
|
-
def to_gv
|
32
|
-
"\t#{self.gv_id} [ label = \"#{@markings}\" ];\n"
|
33
|
-
end
|
34
|
-
|
35
|
-
def ==(object)
|
36
|
-
return false unless object.class.to_s == "PetriNet::ReachabilityGraph::Node"
|
37
|
-
@markings == object.markings
|
38
|
-
end
|
39
|
-
|
40
|
-
def to_s
|
41
|
-
"#{@id}: #{@name} (#{@markings})"
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
data/test/tc_graph.rb
DELETED
File without changes
|
data/test/tc_node.rb
DELETED
File without changes
|
data/test/ts_test_all.rb
DELETED