petri_flow 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/wf/lola.rb +88 -0
- data/app/models/wf/place.rb +4 -0
- data/app/models/wf/transition.rb +4 -0
- data/app/models/wf/workflow.rb +10 -0
- data/lib/tasks/wf_tasks.rake +14 -4
- data/lib/wf.rb +3 -0
- data/lib/wf/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8aa58fdc47ca223aeb5758be70acdff0a0170e3a959eea8752434f0998385ab
|
4
|
+
data.tar.gz: 507036b25186d5e4b5c7a294130ebdcd5a1fee94c87cd022bc0fe830bfeb95a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/app/models/wf/place.rb
CHANGED
data/app/models/wf/transition.rb
CHANGED
data/app/models/wf/workflow.rb
CHANGED
@@ -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|
|
data/lib/tasks/wf_tasks.rake
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
data/lib/wf/version.rb
CHANGED
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
|
+
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
|
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
|