petri_flow 0.2.4 → 0.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08a1f7f65f84fd9f8ffbdec71efa97d6c5d9fba3446857a5f08b69930fe734a9'
4
- data.tar.gz: f64502b080933aae92cd9b61b027f3451e4f4e7ec90fd45bcf67857c23ce7ddc
3
+ metadata.gz: e8aa58fdc47ca223aeb5758be70acdff0a0170e3a959eea8752434f0998385ab
4
+ data.tar.gz: 507036b25186d5e4b5c7a294130ebdcd5a1fee94c87cd022bc0fe830bfeb95a9
5
5
  SHA512:
6
- metadata.gz: 856886ed111aab29361a47b1e24ef17d1a5340d0d3d4838581ccfb852a24f8cfabca81fcb6548396a574e471b7086b1e87e73be907cbc8231bf8fe6546c284ac
7
- data.tar.gz: ff320c2ed77ec2021f78054a8cd23cdeae188e78494deda3bbd534a94399c7e36ef16fae550414f26d5c54ed95d78a3473e2a5c5b49023735c38ffb1c264737a
6
+ metadata.gz: 7787936e173f9afda7b22a1e76871c0c1e782681959e91be17d131330bbd38cfaabe04fad37f56e8a685f4334fcc20591c1ba7f1ccffa04cd39e8f1165a52b69
7
+ data.tar.gz: 16612786a899f27a5e5ca19fb16854481b2c7009245d773152e984fc8df484140c2395b3e307ccf9b4e22974d7b9123b858e8b1415efe7d92087b2c2f5f2fc11
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wf
4
+ class Lola
5
+ attr_reader :end_p, :start_p, :workflow
6
+ def initialize(workflow)
7
+ @workflow = workflow
8
+ @start_p = workflow.places.start.first
9
+ @end_p = workflow.places.end.first
10
+ generate_lola_file!
11
+ end
12
+
13
+ def to_text
14
+ places = workflow.places
15
+ transitions = workflow.transitions
16
+
17
+ places_text = places.map(&:lola_id).join(",")
18
+ marking_text = start_p.lola_id
19
+ # TODO: with guard
20
+ transitions_text = transitions.map do |t|
21
+ consume = t.arcs.in.map { |arc| "#{arc.place.lola_id}:1" }.join(",")
22
+ produce = t.arcs.out.map { |arc| "#{arc.place.lola_id}:1" }.join(",")
23
+ [
24
+ "TRANSITION #{t.lola_id}",
25
+ "CONSUME #{consume};",
26
+ "PRODUCE #{produce};"
27
+ ].join("\n")
28
+ end.join("\n\n")
29
+
30
+ <<~LOLA
31
+ PLACE #{places_text};
32
+
33
+ MARKING #{marking_text};
34
+
35
+ #{transitions_text}
36
+ LOLA
37
+ end
38
+
39
+ def json_path(bucket)
40
+ Rails.root.join("tmp", "#{workflow.id}-#{bucket}.json")
41
+ end
42
+
43
+ def lola_path
44
+ Rails.root.join("tmp", "#{workflow.id}-#{workflow.updated_at.to_i}.lola")
45
+ end
46
+
47
+ def generate_lola_file!
48
+ File.open(lola_path, "w") { |f| f.write(Wf::Lola.new(workflow).to_text) } unless File.exist?(lola_path)
49
+ end
50
+
51
+ def soundness?
52
+ reachability_of_final_marking? && quasiliveness? && !deadlock?
53
+ end
54
+
55
+ def reachability_of_final_marking?
56
+ formula = workflow.places.reject { |p| p == end_p }.map { |p| "#{p.lola_id} = 0" }.join(" AND ")
57
+ formula += " AND #{end_p.lola_id} >= 1"
58
+ formula = "AGEF(#{formula})"
59
+ result = run_cmd(formula, "reachability_of_final_marking")
60
+ result.dig("analysis", "result")
61
+ end
62
+
63
+ def quasiliveness?
64
+ workflow.transitions.all? { |t| !dead_transition?(t) }
65
+ end
66
+
67
+ def deadlock?
68
+ formula = "EF (DEADLOCK AND (#{end_p.lola_id} = 0))"
69
+ result = run_cmd(formula, "deadlock")
70
+ result.dig("analysis", "result")
71
+ end
72
+
73
+ private
74
+
75
+ def dead_transition?(transition)
76
+ formula = "AG NOT FIREABLE (#{transition.lola_id})"
77
+ result = run_cmd(formula, "dead_transition_#{transition.id}")
78
+ result.dig("analysis", "result")
79
+ end
80
+
81
+ def run_cmd(formula, bucket)
82
+ cmd = %(lola #{lola_path} --markinglimit=1000 --timelimit=1 --formula="#{formula}" --json=#{json_path(bucket)})
83
+ $stdout.puts cmd
84
+ system(cmd)
85
+ JSON.parse(File.read(json_path(bucket)))
86
+ end
87
+ end
88
+ end
@@ -28,5 +28,9 @@ module Wf
28
28
  def graph_id
29
29
  "#{name}/#{id}"
30
30
  end
31
+
32
+ def lola_id
33
+ "P#{id}"
34
+ end
31
35
  end
32
36
  end
@@ -67,5 +67,9 @@ module Wf
67
67
  def graph_id
68
68
  "#{name}/#{id}"
69
69
  end
70
+
71
+ def lola_id
72
+ "T#{id}"
73
+ end
70
74
  end
71
75
  end
@@ -59,6 +59,12 @@ module Wf
59
59
  end
60
60
  end
61
61
 
62
+ if Wf.use_lola
63
+ msgs << "has deadlock" if to_lola.deadlock?
64
+ msgs << "has dead transition" unless to_lola.quasiliveness?
65
+ msgs << "can not reach to the end place" unless to_lola.reachability_of_final_marking?
66
+ end
67
+
62
68
  if msgs.present?
63
69
  update_columns(is_valid: false, error_msg: msgs.join("\n"))
64
70
  else
@@ -188,6 +194,10 @@ module Wf
188
194
  File.read(path)
189
195
  end
190
196
 
197
+ def to_lola
198
+ @lola ||= Wf::Lola.new(self)
199
+ end
200
+
191
201
  def to_rgl
192
202
  graph = RGL::DirectedAdjacencyGraph.new
193
203
  places.order("place_type ASC").each do |p|
@@ -1,5 +1,15 @@
1
1
  # frozen_string_literal: true
2
- # desc "Explaining what the task does"
3
- # task :wf do
4
- # # Task goes here
5
- # end
2
+
3
+ desc "Wf tasks"
4
+
5
+ task wf: :environment do
6
+ url = "http://service-technology.org/files/lola/lola-2.0.tar.gz"
7
+ path = Rails.root.join("tmp", "lola.tar.gz").to_s
8
+ puts "Downloading, wait!"
9
+ puts `wget http://service-technology.org/files/lola/lola-2.0.tar.gz -v -t0 -O #{path}` unless File.exist?(path)
10
+ puts `cd #{Rails.root.join("tmp")} && tar -zxvf lola.tar.gz`
11
+ puts `cd #{Rails.root.join("tmp/lola-2.0")} && ./configure`
12
+ puts `cd #{Rails.root.join("tmp/lola-2.0")} && make`
13
+ puts `cd #{Rails.root.join("tmp/lola-2.0")} && sudo make install`
14
+ puts `lola --help`
15
+ end
data/lib/wf.rb CHANGED
@@ -21,6 +21,8 @@ module Wf
21
21
  attr_accessor :org_classes
22
22
 
23
23
  attr_accessor :finish_conditions
24
+
25
+ attr_accessor :use_lola
24
26
  end
25
27
 
26
28
  self.enable_callbacks = ["Wf::Callbacks::EnableDefault"]
@@ -37,4 +39,5 @@ module Wf
37
39
  self.user_class = "::Wf::User"
38
40
  self.org_classes = { group: "::Wf::Group" }
39
41
  self.finish_conditions = ["Wf::MultipleInstances::AllFinish"]
42
+ self.use_lola = false
40
43
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wf
4
- VERSION = "0.2.4"
4
+ VERSION = "0.2.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: petri_flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hooopo Wang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-29 00:00:00.000000000 Z
11
+ date: 2020-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bootstrap
@@ -297,6 +297,7 @@ files:
297
297
  - app/models/wf/form.rb
298
298
  - app/models/wf/group.rb
299
299
  - app/models/wf/guard.rb
300
+ - app/models/wf/lola.rb
300
301
  - app/models/wf/multiple_instances/all_finish.rb
301
302
  - app/models/wf/party.rb
302
303
  - app/models/wf/place.rb