petri 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 499cdfa50c7df671582543bc17bbd5db4a7cab6f
4
+ data.tar.gz: a96adde8d148ed7cee62f2013c54ae54eda2dfaa
5
+ SHA512:
6
+ metadata.gz: 21305eb0658d4b29b8696d287d69a83eff4fb150e4fd842f8cfc47622953c393f30ea93cc3f56ac6398470c60cdc367c9b6e0f54053417e7d805c891a54f5112
7
+ data.tar.gz: 07e2b532eb5edd038761de2300270073e4658c1172d92024b0288e2ede9ed66cd37ba7738ae4036b1210200bd62f06394f4ab6857e03ea22657a303fba50cf02
data/lib/petri.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'petri/element'
2
+ require 'petri/node'
3
+ require 'petri/place'
4
+ require 'petri/transition'
5
+ require 'petri/arc'
6
+ require 'petri/token'
7
+ require 'petri/net_loader'
8
+ require 'petri/net'
data/lib/petri/arc.rb ADDED
@@ -0,0 +1,12 @@
1
+ module Petri
2
+ class Arc < Element
3
+ attr_reader :from_node, :to_node, :type
4
+
5
+ def initialize(net, from: nil, to: nil, type: nil, guid: nil)
6
+ super(net, {guid: guid})
7
+ @from_node = from
8
+ @to_node = to
9
+ @type = type || :regular
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Petri
2
+ class Element
3
+ attr_reader :net, :data, :guid
4
+
5
+ # @param net [Net]
6
+ # @param data [Hash<Symbol>]
7
+ def initialize(net, data = {})
8
+ @net = net
9
+ @data = data.symbolize_keys || {}
10
+ @guid ||= data[:guid] if data[:guid]
11
+ end
12
+ end
13
+ end
data/lib/petri/net.rb ADDED
@@ -0,0 +1,50 @@
1
+ module Petri
2
+ class Net
3
+ include NetLoader
4
+
5
+ attr_reader :places, :transitions, :arcs, :tokens
6
+
7
+ def initialize
8
+ @transitions = []
9
+ @places = []
10
+ @arcs = []
11
+ @tokens = []
12
+ end
13
+
14
+ # Lets the process be started
15
+ # Populates tokens in start places
16
+ def init
17
+ places.each do |place|
18
+ put_token(place) if place.start?
19
+ end
20
+ end
21
+
22
+ # @param place [Place]
23
+ # @return [Token]
24
+ def put_token(place)
25
+ Token.new(place).tap do |token|
26
+ @tokens << token
27
+ end
28
+ end
29
+
30
+ # @param place [Place]
31
+ # @return [Token, nil]
32
+ def remove_token(place)
33
+ @tokens.each do |token|
34
+ if token.place == place
35
+ @tokens.delete(token)
36
+ return token
37
+ end
38
+ end
39
+ nil
40
+ end
41
+
42
+ protected
43
+
44
+ def node_by_guid(guid)
45
+ @places.each { |node| return node if node.guid == guid }
46
+ @transitions.each { |node| return node if node.guid == guid }
47
+ nil
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,75 @@
1
+ module Petri
2
+ module NetLoader
3
+ extend ActiveSupport::Concern
4
+
5
+ # @param guid [String]
6
+ # @param title [String]
7
+ # @param start [true, false]
8
+ def add_place(guid: , title: , start: )
9
+ @places << Place.new(self, {guid: guid, title: title, start: start})
10
+ end
11
+
12
+ # @param guid [String]
13
+ # @param title [String]
14
+ # @param action [String]
15
+ def add_transition(guid: , title: , action: )
16
+ @transitions << Transition.new(self, {guid: guid, title: title, action: action})
17
+ end
18
+
19
+ # @param guid [String]
20
+ # @param title [String]
21
+ # @param from_guid [String]
22
+ # @param to_guid [String]
23
+ # @param type [String]
24
+ def add_arc(guid: , from_guid: , to_guid: , type: )
25
+ from_node = node_by_guid(from_guid)
26
+ to_node = node_by_guid(to_guid)
27
+ @arcs << Arc.new(self, from: from_node, to: to_node, type: type.try(:to_sym), guid: guid)
28
+ end
29
+
30
+ module ClassMethods
31
+ # @param path [String]
32
+ # @return [Net]
33
+ def from_file(path)
34
+ from_stream(File.new(path))
35
+ end
36
+
37
+ # @param io [IO]
38
+ # @return [Net]
39
+ def from_stream(io)
40
+ from_string(io.read)
41
+ end
42
+
43
+ # @param str [String]
44
+ # @return [Net]
45
+ def from_string(str)
46
+ from_hash(JSON.parse(str))
47
+ end
48
+
49
+ # @param hash [Hash<String>]
50
+ # @return [Net]
51
+ def from_hash(hash)
52
+ self.new.tap do |net|
53
+ hash['places'].each do |data|
54
+ net.add_place(guid: data['guid'],
55
+ title: data['title'],
56
+ start: data['start'])
57
+ end
58
+
59
+ hash['transitions'].each do |data|
60
+ net.add_transition(guid: data['guid'],
61
+ title: data['title'],
62
+ action: data['action'])
63
+ end
64
+
65
+ hash['arcs'].each do |data|
66
+ net.add_arc(guid: data['guid'],
67
+ from_guid: data['from_guid'],
68
+ to_guid: data['to_guid'],
69
+ type: data['type'])
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
data/lib/petri/node.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Petri
2
+ class Node < Element
3
+
4
+ # @return [String, nil]
5
+ def title
6
+ @data[:title]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Petri
2
+ class Place < Node
3
+
4
+ def has_token?
5
+ net.tokens.any? { |token| token.place == self }
6
+ end
7
+
8
+ def start?
9
+ !!@data[:start]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Petri
2
+ class Token
3
+ attr_reader :place
4
+
5
+ # @param place [Place]
6
+ def initialize(place)
7
+ @place = place
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,64 @@
1
+ module Petri
2
+ class Transition < Node
3
+
4
+ # @return [String, nil]
5
+ def action
6
+ @data[:action].presence
7
+ end
8
+
9
+ def enabled?
10
+ input_places.all?(&:has_token?)
11
+ end
12
+
13
+ def fire!
14
+ raise ArgumentError, 'Transition is not enabled' unless enabled?
15
+ consume_tokens
16
+ callback.try(:call)
17
+ produce_tokens
18
+ end
19
+
20
+ # @param block [Proc]
21
+ def set_callback(&block)
22
+ @callback = block
23
+ end
24
+
25
+ # @return [Proc, nil]
26
+ def callback
27
+ @callback
28
+ end
29
+
30
+ private
31
+
32
+ def consume_tokens
33
+ input_places.each do |place|
34
+ net.remove_token(place)
35
+ end
36
+ end
37
+
38
+ def produce_tokens
39
+ output_places.each do |place|
40
+ net.put_token(place)
41
+ end
42
+ end
43
+
44
+ # @return [Array<Arc>]
45
+ def input_arcs
46
+ net.arcs.select { |arc| arc.to_node == self }
47
+ end
48
+
49
+ # @return [Array<Place>]
50
+ def input_places
51
+ input_arcs.map(&:from_node)
52
+ end
53
+
54
+ # @return [Array<Arc>]
55
+ def output_arcs
56
+ net.arcs.select { |arc| arc.from_node == self }
57
+ end
58
+
59
+ # @return [Array<Place>]
60
+ def output_places
61
+ output_arcs.map(&:to_node)
62
+ end
63
+ end
64
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: petri
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Sergei Zinin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.2.16
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '3.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.2.16
33
+ description: A simple petri nets structure
34
+ email: szinin@gmail.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - lib/petri.rb
40
+ - lib/petri/arc.rb
41
+ - lib/petri/element.rb
42
+ - lib/petri/net.rb
43
+ - lib/petri/net_loader.rb
44
+ - lib/petri/node.rb
45
+ - lib/petri/place.rb
46
+ - lib/petri/token.rb
47
+ - lib/petri/transition.rb
48
+ homepage: http://github.com/einzige/petri
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.2.2
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Petri nets
72
+ test_files: []