case_model 0.0.1 → 0.0.4
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/README.md +0 -11
- data/case_model.gemspec +6 -1
- data/lib/models/action.rb +35 -33
- data/lib/models/answer.rb +23 -19
- data/lib/models/application.rb +54 -41
- data/lib/models/capability.rb +43 -15
- data/lib/models/deployment_plan.rb +36 -29
- data/lib/models/device.rb +24 -18
- data/lib/models/ecosystem_host.rb +5 -3
- data/lib/models/http_request.rb +20 -18
- data/lib/models/installation.rb +46 -0
- data/lib/models/installation_used_device.rb +18 -0
- data/lib/models/location.rb +13 -11
- data/lib/models/number.rb +27 -0
- data/lib/models/ontology.rb +54 -33
- data/lib/models/property.rb +46 -0
- data/lib/models/question.rb +42 -37
- data/lib/models/question_reply_type.rb +15 -11
- data/lib/models/requirement.rb +16 -10
- data/lib/models/scenario.rb +30 -0
- data/lib/models/selection.rb +25 -23
- data/lib/models/state_change.rb +15 -13
- data/lib/models/temperature.rb +13 -11
- data/lib/ontology/http_vocabulary.rb +14 -12
- data/lib/ontology/local_vocabulary.rb +24 -18
- data/lib/ontology/math_vocabulary.rb +13 -11
- data/lib/ontology/rdf_vocabulary.rb +10 -8
- data/lib/ontology/state_vocabulary.rb +8 -6
- data/lib/services/application_by_capability_finder.rb +29 -27
- data/lib/services/eye_serializer.rb +17 -15
- data/lib/services/helper.rb +12 -0
- data/lib/services/node_builder.rb +26 -24
- data/lib/services/node_query.rb +46 -40
- data/lib/services/reasoner.rb +60 -58
- data/spec/spec_helper.rb +2 -0
- metadata +64 -2
@@ -1,37 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Model
|
2
|
+
class ApplicationByCapabilityFinder
|
3
|
+
def initialize(ontology)
|
4
|
+
@ontology = ontology
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def find(options)
|
8
|
+
solutions = RDF::Query.execute(@ontology, {
|
9
|
+
application: {
|
10
|
+
LV.hasDeploymentPlan => {
|
11
|
+
LV.capability => options
|
12
|
+
}
|
11
13
|
}
|
12
|
-
}
|
13
|
-
})
|
14
|
+
})
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
solutions.map do |solution|
|
17
|
+
solution[:application]
|
18
|
+
end.uniq.map do |node|
|
19
|
+
Application.new(node, @ontology)
|
20
|
+
end
|
19
21
|
end
|
20
|
-
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
def find_by_type(type)
|
24
|
+
find({ RDF.type => type })
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
def find_by_description(description)
|
28
|
+
find({ LV.description => description })
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def find_by_actuator(actuator)
|
32
|
+
find({ LV.actuator => actuator })
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
35
|
+
def find_by_sensor(sensor)
|
36
|
+
find({ LV.sensor => sensor })
|
37
|
+
end
|
36
38
|
end
|
37
39
|
end
|
@@ -1,19 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Model
|
2
|
+
class EyeSerializer
|
3
|
+
def self.serialize_implication(facts, precondition, postcondition)
|
4
|
+
pre = serialize_graph(precondition)
|
5
|
+
post = serialize_graph(postcondition)
|
6
|
+
"#{facts.dump(:ntriples)}{#{pre}} => {#{post}}.\n"
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
def self.serialize_graph(graph)
|
10
|
+
statements = []
|
11
|
+
graph.each_statement do |statement|
|
12
|
+
statements << RDF::Statement.new({
|
13
|
+
subject: statement.subject,
|
14
|
+
predicate: statement.predicate,
|
15
|
+
object: statement.object
|
16
|
+
}).to_s + "\n"
|
17
|
+
end
|
18
|
+
statements.join
|
16
19
|
end
|
17
|
-
statements.join
|
18
20
|
end
|
19
21
|
end
|
@@ -1,34 +1,36 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Model
|
4
|
+
class NodeBuilder
|
5
|
+
def self.create(properties, repository)
|
6
|
+
node = generate_node
|
7
|
+
query = NodeQuery.new node, repository
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
properties.each do |key, v|
|
10
|
+
values = if v.is_a?(Array)
|
11
|
+
v
|
12
|
+
else
|
13
|
+
[ v ]
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
values.each do |value|
|
17
|
+
query.set_value(key,
|
18
|
+
if value.is_a?(Hash)
|
19
|
+
create(value, repository)
|
20
|
+
else
|
21
|
+
value
|
22
|
+
end, false)
|
23
|
+
end
|
22
24
|
end
|
23
|
-
end
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
node
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
+
private
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def self.generate_node
|
32
|
+
id = SecureRandom.hex
|
33
|
+
RDF::URI("http://example.org/#{id}")
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
data/lib/services/node_query.rb
CHANGED
@@ -1,55 +1,61 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Model
|
2
|
+
class NodeQuery
|
3
|
+
attr_reader :node, :repository
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(node, repository)
|
6
|
+
@node = node
|
7
|
+
@repository = repository
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def node_uri
|
11
|
+
node.to_s
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
14
|
+
def value(predicate)
|
15
|
+
values(predicate).first
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def values(predicate)
|
19
|
+
results = repository.query([ node, predicate, nil ])
|
20
|
+
results.map {|s| s.object }
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
23
|
+
def value_exists?(predicate)
|
24
|
+
values(predicate).any?
|
25
|
+
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
def set_value(predicate, object, replace = true)
|
28
|
+
delete_value(predicate) if replace
|
29
|
+
@repository << [ node, predicate, object ]
|
30
|
+
end
|
31
|
+
|
32
|
+
def predicates_and_objects
|
33
|
+
values = {}
|
34
|
+
repository.query([ node, nil, nil ]).each do |s|
|
35
|
+
if values.has_key? s.predicate
|
36
|
+
if values[s.predicate].is_a? Array
|
37
|
+
values[s.predicate] << s.object
|
38
|
+
else
|
39
|
+
values[s.predicate] = [
|
40
|
+
values[s.predicate], s.object
|
41
|
+
]
|
42
|
+
end
|
33
43
|
else
|
34
|
-
values[s.predicate] =
|
35
|
-
values[s.predicate], s.object
|
36
|
-
]
|
44
|
+
values[s.predicate] = s.object
|
37
45
|
end
|
38
|
-
else
|
39
|
-
values[s.predicate] = s.object
|
40
46
|
end
|
47
|
+
values
|
41
48
|
end
|
42
|
-
values
|
43
|
-
end
|
44
49
|
|
45
|
-
|
50
|
+
private
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
def delete_value(predicate)
|
53
|
+
# makes sure not to delete any values in subgraphs
|
54
|
+
repository.query([ node, predicate, nil ]).select do |s|
|
55
|
+
s.graph_name.nil?
|
56
|
+
end.each do |s|
|
57
|
+
repository.delete(s)
|
58
|
+
end
|
53
59
|
end
|
54
60
|
end
|
55
61
|
end
|
data/lib/services/reasoner.rb
CHANGED
@@ -1,77 +1,79 @@
|
|
1
1
|
require 'rdf/n3'
|
2
2
|
require 'tempfile'
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
module Model
|
5
|
+
class Reasoner
|
6
|
+
attr_reader :repository
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def initialize(repository)
|
9
|
+
@repository = repository
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
# implication doesn't work well when a blank node is used in the
|
13
|
+
# condition, e.g.:
|
14
|
+
# {?device1 <http://...#type> _:vehicle .} => {...}
|
15
|
+
# will always result in the postcondition, because of _:vehicle
|
16
|
+
def imply(precondition, postcondition)
|
17
|
+
eye_input = EyeSerializer.serialize_implication(
|
18
|
+
repository.facts_only,
|
19
|
+
repository.graph(precondition),
|
20
|
+
repository.graph(postcondition)
|
21
|
+
)
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
eye_output = run_eye eye_input
|
24
|
+
parse_eye_output eye_output
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
# makes sure that the graph with name condition is valid
|
28
|
+
# to do that, it creates a temporary graph (:helper_graph) and tries to imply
|
29
|
+
# condition => helper_graph
|
30
|
+
# it creates a new temp_reasoner object so as not to modify the current repository
|
31
|
+
# with the helper_graph
|
32
|
+
def check_condition(condition)
|
33
|
+
temp_repository = @repository.clone
|
34
|
+
temp_repository << [ LV.condition, LV.was, LV.true, :helper_graph ]
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
temp_reasoner = Reasoner.new temp_repository
|
37
|
+
result = temp_reasoner.imply(condition, :helper_graph)
|
37
38
|
|
38
|
-
|
39
|
-
|
39
|
+
result.query([ LV.condition, LV.was, LV.true ]).any?
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
def load_and_process_n3(n3_input)
|
43
|
+
input = [
|
44
|
+
n3_input,
|
45
|
+
EyeSerializer.serialize_graph(repository.facts_only)
|
46
|
+
].join
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
eye_output = run_eye input
|
49
|
+
parse_eye_output eye_output, @repository
|
50
|
+
@repository
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
+
private
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
def run_eye(input)
|
56
|
+
data = Tempfile.new('data')
|
57
|
+
data.write(input)
|
58
|
+
data.close
|
59
|
+
output = `eye --nope --pass #{data.path} 2> /dev/null`
|
60
|
+
data.unlink
|
60
61
|
|
61
|
-
|
62
|
-
|
62
|
+
output
|
63
|
+
end
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
65
|
+
def parse_eye_output(output, repo = nil)
|
66
|
+
output = remove_incompatible_prefix_from_eye_output output
|
67
|
+
repo = RDF::Repository.new if repo.nil?
|
68
|
+
reader = RDF::Reader.for(:n3).new(output)
|
69
|
+
reader.each_statement { |statement| repo << statement }
|
70
|
+
repo
|
71
|
+
end
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
73
|
+
def remove_incompatible_prefix_from_eye_output(output)
|
74
|
+
output.gsub(/PREFIX .+\n/) do |match|
|
75
|
+
match.sub('PREFIX ', '@prefix ') + '.'
|
76
|
+
end
|
75
77
|
end
|
76
78
|
end
|
77
79
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: case_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matus Tomlein
|
@@ -9,7 +9,63 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2016-01-28 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rdf-n3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.99.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.99.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdf-vocab
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.8.7.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.8.7.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: webmock
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.22.3
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.22.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rest-client
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.8.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.8.0
|
13
69
|
description: Built for the Context-Aware Software Ecosystem. Resolves application
|
14
70
|
model requirements using semantic reasoning.
|
15
71
|
email: matus@cs.au.dk
|
@@ -33,11 +89,16 @@ files:
|
|
33
89
|
- lib/models/device.rb
|
34
90
|
- lib/models/ecosystem_host.rb
|
35
91
|
- lib/models/http_request.rb
|
92
|
+
- lib/models/installation.rb
|
93
|
+
- lib/models/installation_used_device.rb
|
36
94
|
- lib/models/location.rb
|
95
|
+
- lib/models/number.rb
|
37
96
|
- lib/models/ontology.rb
|
97
|
+
- lib/models/property.rb
|
38
98
|
- lib/models/question.rb
|
39
99
|
- lib/models/question_reply_type.rb
|
40
100
|
- lib/models/requirement.rb
|
101
|
+
- lib/models/scenario.rb
|
41
102
|
- lib/models/selection.rb
|
42
103
|
- lib/models/state_change.rb
|
43
104
|
- lib/models/temperature.rb
|
@@ -48,6 +109,7 @@ files:
|
|
48
109
|
- lib/ontology/state_vocabulary.rb
|
49
110
|
- lib/services/application_by_capability_finder.rb
|
50
111
|
- lib/services/eye_serializer.rb
|
112
|
+
- lib/services/helper.rb
|
51
113
|
- lib/services/node_builder.rb
|
52
114
|
- lib/services/node_query.rb
|
53
115
|
- lib/services/question_references.rb
|