semantic_naming 2.0.6 → 2.1.0
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.
- data/lib/ontology_graph/class_node.rb +71 -0
- data/lib/ontology_graph/graph.rb +118 -0
- data/lib/semantic_naming/source_class.rb +56 -105
- data/lib/semantic_naming/uri.rb +2 -4
- data/lib/semantic_naming.rb +3 -1
- data/test/class_node_test.rb +13 -0
- data/test/graph_test.rb +133 -0
- data/test/source_class_test.rb +4 -4
- metadata +27 -23
@@ -0,0 +1,71 @@
|
|
1
|
+
module OntologyGraph
|
2
|
+
|
3
|
+
# Helper class that contains a node in the internal RDFS/OWL class graph
|
4
|
+
class ClassNode
|
5
|
+
|
6
|
+
attr_accessor :subclasses, :superclasses, :uri, :flags
|
7
|
+
|
8
|
+
# Create a new unconnected node with the given uri
|
9
|
+
def initialize(uri)
|
10
|
+
@uri = uri
|
11
|
+
@subclasses = []
|
12
|
+
@superclasses = []
|
13
|
+
end
|
14
|
+
|
15
|
+
# Add the given class as a subclass
|
16
|
+
def add_subclass(klass)
|
17
|
+
self.subclasses << klass
|
18
|
+
klass.superclasses << self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Add the given class as a superclass
|
22
|
+
def add_superclass(klass)
|
23
|
+
self.superclasses << klass
|
24
|
+
klass.subclasses << self
|
25
|
+
end
|
26
|
+
|
27
|
+
# Flag this node as "used" (meaning that there are Resources having
|
28
|
+
# this class as it's type)
|
29
|
+
def flag_used
|
30
|
+
@used = true
|
31
|
+
end
|
32
|
+
|
33
|
+
# Indicates if the node is "used", meaning if any resources have it
|
34
|
+
# as it's type
|
35
|
+
def used?
|
36
|
+
@used
|
37
|
+
end
|
38
|
+
|
39
|
+
# Used to remove all "unreal superclasses", that are created by inferencing.
|
40
|
+
# A superclass is "unreal" if it appears in the path to the root
|
41
|
+
def weed_superclasses(root_path = [])
|
42
|
+
superclasses.reject! do |sup|
|
43
|
+
reject = false
|
44
|
+
# Ignore the last element in the root path, wich points to the direct parent
|
45
|
+
if(reject = root_path[0..-2].include?(sup))
|
46
|
+
sup.subclasses.reject! { |cl| cl == self }
|
47
|
+
end
|
48
|
+
reject
|
49
|
+
end
|
50
|
+
subclasses.each { |sub| sub.weed_superclasses(root_path + [ self ]) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def uri
|
54
|
+
@uri
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
@uri
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_uri
|
62
|
+
return N::SourceClass.new(@uri)
|
63
|
+
end
|
64
|
+
|
65
|
+
def inspect
|
66
|
+
"<#{self.class.name}:#{self.object_id} @uri=\"#{uri}\" @subclasses = [#{subclasses.collect { |s| s.to_s}.join(', ')}] @superclasses = [#{superclasses.collect { |s| s.to_s}.join(', ')}] >"
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module OntologyGraph
|
2
|
+
|
3
|
+
# Class for handling the graph of ontology classes. This allows
|
4
|
+
# quick access to each RDFS class know to the system.
|
5
|
+
#
|
6
|
+
# If ActiveRDF is available, the graph can initialize itself from
|
7
|
+
# the RDF store and allows access to all the subclass and superclass
|
8
|
+
# relations in the system.
|
9
|
+
class Graph
|
10
|
+
|
11
|
+
include Enumerable
|
12
|
+
|
13
|
+
# Create a new class graph
|
14
|
+
def initialize
|
15
|
+
@class_hash = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Add a relation between a subclass or a superclass
|
19
|
+
def add_relation(superclass, subclass)
|
20
|
+
subclass = get_or_create_node(subclass)
|
21
|
+
superclass = get_or_create_node(superclass)
|
22
|
+
superclass.add_subclass(subclass)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Retrieve the graph node for the given name/URL. If the node
|
26
|
+
# does not already exist, it will be created.
|
27
|
+
def get_or_create_node(name)
|
28
|
+
node = get_node(name)
|
29
|
+
return node if(node)
|
30
|
+
node = ClassNode.new(name)
|
31
|
+
@class_hash[name] = node
|
32
|
+
node
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_node(name)
|
36
|
+
@class_hash[name.to_s]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Iterate through each node
|
40
|
+
def each(&block)
|
41
|
+
@class_hash.each_value(&block)
|
42
|
+
end
|
43
|
+
alias :each_node :each
|
44
|
+
|
45
|
+
# Build the whole graph from the RDF store. This will include all Resources that
|
46
|
+
# are either marked as an rdfs:class orare used as an rdf:type and all the subclass
|
47
|
+
# relations between them.
|
48
|
+
def build_from_ardf
|
49
|
+
return unless(N::URI.active_rdf?)
|
50
|
+
|
51
|
+
# First select all classes and add them as nodes
|
52
|
+
class_qry = Query.new(N::URI).select(:class).where(:class, N::RDF.type, N::RDFS.Class)
|
53
|
+
types = class_qry.execute
|
54
|
+
types.each { |t| @class_hash[t.to_s] = ClassNode.new(t.to_s) }
|
55
|
+
|
56
|
+
# Now, look for all subclass relationships and add them
|
57
|
+
subtype_qry = Query.new(N::URI).distinct.select(:class, :subclass)
|
58
|
+
subtype_qry.where(:subclass, RDFS.subClassOf, :class)
|
59
|
+
subtype_list = subtype_qry.execute
|
60
|
+
subtype_list.each { |cl, subcl| add_relation(cl, subcl) }
|
61
|
+
|
62
|
+
# Flag all classes that are actually used
|
63
|
+
used_types_qry = Query.new(N::URI).distinct.select(:type)
|
64
|
+
used_types_qry.where(:element, RDF.type, :type)
|
65
|
+
used_types = used_types_qry.execute
|
66
|
+
used_types.each { |t| get_or_create_node(t).flag_used }
|
67
|
+
|
68
|
+
weed_inference
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
# Reset the flags for tree walking on all nodes of the tree.
|
73
|
+
def reset_flags
|
74
|
+
@class_hash.each_value { |n| n.flags = nil }
|
75
|
+
end
|
76
|
+
|
77
|
+
# Create a tree of subclasses, starting from the given node.
|
78
|
+
# This will return a ClassNode which is the root of a tree of
|
79
|
+
# all classes that are reachable from the current node as subclasses.
|
80
|
+
def tree_from(node_name, &block)
|
81
|
+
reset_flags
|
82
|
+
make_tree_from(node_name, &block)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Weed out "inferred" subclass relationships from the graph, if
|
86
|
+
# they exist.
|
87
|
+
def weed_inference
|
88
|
+
root_elements = []
|
89
|
+
@class_hash.each_value do |node|
|
90
|
+
if(node.superclasses.empty?)
|
91
|
+
root_elements << node
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
raise(RuntimeError, "No root elements in the graph, ontology graph cannot by cyclic") if(root_elements.empty?)
|
96
|
+
|
97
|
+
root_elements.each { |root| root.weed_superclasses }
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
# See #tree_from
|
103
|
+
def make_tree_from(node_name)
|
104
|
+
node_name = node_name.to_s
|
105
|
+
start = get_or_create_node(node_name)
|
106
|
+
root = ClassNode.new(node_name)
|
107
|
+
start.flags = :visited
|
108
|
+
start.subclasses.each do |sub|
|
109
|
+
next if(sub.flags == :visited)
|
110
|
+
accepted = block_given? ? yield(sub) : true
|
111
|
+
root.add_subclass(make_tree_from(sub)) unless(!accepted && (sub.subclasses.size == 0))
|
112
|
+
end
|
113
|
+
root
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -1,43 +1,58 @@
|
|
1
1
|
module N
|
2
2
|
|
3
|
-
# This is the type of URI that represents a class of sources.
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# This is the type of URI that represents a class of sources. Each SourceClass
|
4
|
+
# object is part of the internal class graph. If an ActiveRDF connection is
|
5
|
+
# present, it is possible to quickly navigate through the type hierarchy.
|
6
|
+
#
|
7
|
+
# The class hierarchy is base on the OntologyGraph structures - it will not
|
8
|
+
# show inferred types as subtypes or supertypes of the current class.
|
9
|
+
#
|
10
|
+
# The graph of the class realtions will usually be cached, it can be reset
|
11
|
+
# by passing allow_caching = false to the respective methods.
|
6
12
|
class SourceClass < URI
|
7
13
|
|
8
14
|
# Get the supertype of this class
|
9
|
-
def supertypes
|
10
|
-
|
11
|
-
qry = Query.new(SourceClass).distinct.select(:o)
|
12
|
-
qry.where(self, RDFS.subClassOf, :o)
|
13
|
-
qry.where(:o, RDF.type, RDFS.Class)
|
14
|
-
qry.execute
|
15
|
+
def supertypes(allow_caching = true)
|
16
|
+
my_node(allow_caching).superclasses.collect { |st| SourceClass.new(st.uri) }
|
15
17
|
end
|
16
18
|
|
17
19
|
# Get the subtypes of this type
|
18
|
-
def subtypes
|
19
|
-
|
20
|
-
qry = Query.new(SourceClass).distinct.select(:s)
|
21
|
-
qry.where(:s, RDFS.subClassOf, self)
|
22
|
-
qry.where(:s, RDF.type, RDFS.Class)
|
23
|
-
qry.execute
|
20
|
+
def subtypes(allow_caching = true)
|
21
|
+
my_node(allow_caching).subclasses.collect { |st| SourceClass.new(st.uri) }
|
24
22
|
end
|
25
23
|
|
26
24
|
# Get the instances of this type. return_type will be the class used to
|
27
|
-
# create the objects that are returned.
|
25
|
+
# create the objects that are returned. This will not use the cached
|
26
|
+
# graph but cause an RDF query on each call
|
28
27
|
def instances(return_type)
|
29
28
|
return nil unless(active_rdf? && is_iri?)
|
30
|
-
qry = Query.new(
|
29
|
+
qry = Query.new(URI).distinct.select(:s)
|
31
30
|
qry.where(:s, RDF.type, self)
|
32
31
|
qry.execute
|
33
32
|
end
|
34
33
|
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
# Returns the ClassNode element related to this class. This
|
35
|
+
# will return a "dummy" element when the node is not found in
|
36
|
+
# the graph
|
37
|
+
def my_node(allow_caching = true)
|
38
|
+
graph = SourceClass.class_graph(allow_caching)
|
39
|
+
graph.get_node(@uri_s) || OntologyGraph::ClassNode.new(@uri_s)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return all the existing types as a list of SourceClass objects
|
43
|
+
def self.rdf_types(allow_caching = true)
|
44
|
+
graph = class_graph(allow_caching)
|
45
|
+
return nill unless(graph)
|
46
|
+
graph.collect { |n| SourceClass.new(n.uri) }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get all the existing types from the RDF store. Return the class
|
50
|
+
# graph directly
|
51
|
+
def self.class_graph(allow_caching = true)
|
52
|
+
return @class_graph if(allow_caching && @class_graph)
|
53
|
+
@class_graph = OntologyGraph::Graph.new
|
54
|
+
@class_graph.build_from_ardf if(URI.active_rdf?)
|
55
|
+
@class_graph
|
41
56
|
end
|
42
57
|
|
43
58
|
# Return a subclass hierarchy. This is quicker than going through
|
@@ -47,95 +62,31 @@ module N
|
|
47
62
|
# the values are hashes with the child elements, and so on
|
48
63
|
#
|
49
64
|
# E.g. : { type1 => { subtype_a => {}, subtype_b => { xtype => {}} }, type_2 => {}}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
subtype_list = qry.execute
|
57
|
-
|
58
|
-
build_hierarchy_from(subtype_list, rdf_types)
|
59
|
-
end
|
60
|
-
|
61
|
-
# This works like the subclass_hierarchy method, with the exception that
|
62
|
-
#
|
63
|
-
# * Ontology information is only used for subtype relations
|
64
|
-
# * Resources are considered a "type" if they appear as an rdf:type attribute
|
65
|
-
# * Only types that are actively used (that is they appear as an rdf:type attribute)
|
66
|
-
# are included
|
67
|
-
def self.used_subclass_hierarchy
|
68
|
-
all_types_qry = Query.new(SourceClass).distinct.select(:type)
|
69
|
-
all_types_qry.where(:element, RDF.type, :type)
|
70
|
-
all_types = all_types_qry.execute
|
71
|
-
|
72
|
-
qry = Query.new(SourceClass).distinct.select(:class, :subclass)
|
73
|
-
qry.where(:subclass, RDFS.subClassOf, :class)
|
74
|
-
subtype_list = qry.execute
|
75
|
-
|
76
|
-
all_types_hash = {}
|
77
|
-
all_types.each { |type| all_types_hash[type] = true }
|
78
|
-
|
79
|
-
# TODO: Not very efficient, but then we don't expect many types
|
80
|
-
all_type_list = (all_types + subtype_list.collect { |el| el.last }).uniq
|
81
|
-
|
82
|
-
hierarchy = build_hierarchy_from(subtype_list, all_type_list)
|
83
|
-
|
84
|
-
purge_hierarchy!(hierarchy, all_types_hash)
|
85
|
-
|
86
|
-
hierarchy
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
# Purge the elements from the hierarchy that don't have any "used"
|
92
|
-
# children. Returns true if some "used" elements were found in
|
93
|
-
# the hierarchy
|
94
|
-
def self.purge_hierarchy!(elements, used_elements)
|
95
|
-
used = false
|
96
|
-
elements.each do |element, children|
|
97
|
-
used_children = purge_hierarchy!(children, used_elements)
|
98
|
-
used_element = used_children || used_elements[element]
|
99
|
-
elements.delete(element) unless(used_element)
|
100
|
-
used ||= used_element
|
101
|
-
end
|
102
|
-
used
|
103
|
-
end
|
104
|
-
|
105
|
-
# If all_types is given, it must be a true superset of all
|
106
|
-
# types in the query result
|
107
|
-
def self.build_hierarchy_from(query_result, all_types = nil)
|
108
|
-
hierarchy = {}
|
109
|
-
# Sift through the triples and add the sub-items
|
110
|
-
query_result.each do |sub_items|
|
111
|
-
klass, subklass = sub_items
|
112
|
-
hierarchy[klass] ||= {}
|
113
|
-
hierarchy[klass][subklass] = true
|
114
|
-
end
|
65
|
+
#
|
66
|
+
# If a block is passed, it will receive the ClassNode object of each
|
67
|
+
# class in the graph. If the block returns false, this class will not
|
68
|
+
# be included in the hierarchy if possible (that is, if the class is a leaf)
|
69
|
+
def self.subclass_hierarchy(root_list = nil, allow_caching = true, &block)
|
70
|
+
graph = SourceClass.class_graph(allow_caching)
|
115
71
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
values[subkey] = hierarchy[subkey]
|
122
|
-
values[subkey][:is_child] = true
|
123
|
-
end
|
72
|
+
if(root_list)
|
73
|
+
root_list.collect! { |el| el.is_a?(OntologyGraph::ClassNode) ? el : OntologyGraph::ClassNode.new(el) }
|
74
|
+
else
|
75
|
+
root_list = []
|
76
|
+
graph.each_node { |n| root_list << n if(n.superclasses.empty?) }
|
124
77
|
end
|
125
78
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
hierarchy.
|
79
|
+
hierarchy = {}
|
80
|
+
root_list.each do |root_el|
|
81
|
+
remove = (block == nil) ? false : !block.call(root_el)
|
82
|
+
sub_hierarchy = subclass_hierarchy(root_el.subclasses, allow_caching, &block)
|
83
|
+
remove = remove && sub_hierarchy.empty?
|
84
|
+
hierarchy[N::URI.new(root_el.uri.to_s)] = sub_hierarchy unless(remove)
|
132
85
|
end
|
133
86
|
|
134
|
-
hierarchy.delete(N::RDFS.Class)
|
135
|
-
hierarchy.delete(N::OWL.Class) if(defined?(N::OWL))
|
136
|
-
|
137
87
|
hierarchy
|
138
88
|
end
|
139
89
|
|
90
|
+
|
140
91
|
end
|
141
92
|
end
|
data/lib/semantic_naming/uri.rb
CHANGED
@@ -2,9 +2,9 @@ module N
|
|
2
2
|
|
3
3
|
# This class contains basic functionality for URIs
|
4
4
|
class URI
|
5
|
-
|
5
|
+
|
6
6
|
# Should behave like an ActiveRDF resource
|
7
|
-
include RDFS::ResourceLike
|
7
|
+
include RDFS::ResourceLike if(defined?(RDFS) && defined?(RDFS::ResourceLike))
|
8
8
|
|
9
9
|
# Contains the registered uris
|
10
10
|
@@registered_uris = Hash.new
|
@@ -306,7 +306,5 @@ module N
|
|
306
306
|
result
|
307
307
|
end
|
308
308
|
|
309
|
-
|
310
|
-
|
311
309
|
end
|
312
310
|
end
|
data/lib/semantic_naming.rb
CHANGED
@@ -9,7 +9,7 @@ $: << this_dir + '/semantic_naming/'
|
|
9
9
|
require 'rubygems'
|
10
10
|
begin
|
11
11
|
require 'active_rdf'
|
12
|
-
rescue
|
12
|
+
rescue Exception
|
13
13
|
puts "ActiveRDF not found"
|
14
14
|
end
|
15
15
|
|
@@ -18,3 +18,5 @@ require 'semantic_naming/default_namespaces'
|
|
18
18
|
require 'semantic_naming/namespace'
|
19
19
|
require 'semantic_naming/source_class'
|
20
20
|
require 'semantic_naming/predicate'
|
21
|
+
require 'ontology_graph/graph'
|
22
|
+
require 'ontology_graph/class_node'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/test_helper'
|
3
|
+
# Test the uri class
|
4
|
+
class URITest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_flagging
|
7
|
+
node = OntologyGraph::ClassNode.new('test_flagging')
|
8
|
+
assert(!node.used?)
|
9
|
+
node.flag_used
|
10
|
+
assert(node.used?)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
data/test/graph_test.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/test_helper'
|
3
|
+
# Test the uri class
|
4
|
+
class URITest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_weeding
|
7
|
+
graph = build_test_for_weed
|
8
|
+
graph.weed_inference
|
9
|
+
test_node(graph, 'a', [], ['c', 'd'])
|
10
|
+
test_node(graph, 'b', [], ['d', 'e'])
|
11
|
+
test_node(graph, 'c', ['a'], [])
|
12
|
+
test_node(graph, 'd', ['a', 'b'], ['f', 'g'])
|
13
|
+
test_node(graph, 'e', ['b'], ['h'])
|
14
|
+
test_node(graph, 'f', ['d'], ['i'])
|
15
|
+
test_node(graph, 'g', ['d'], ['h'])
|
16
|
+
test_node(graph, 'h', ['g', 'e'], ['i'])
|
17
|
+
test_node(graph, 'i', ['f', 'h'], [])
|
18
|
+
end
|
19
|
+
|
20
|
+
# Test the tree. This test looks a bit tricky, as the last node
|
21
|
+
# can be reached in two ways, and only one will show up in the tree
|
22
|
+
#
|
23
|
+
# To understand this, best draw the graph from build_test_graph
|
24
|
+
def test_tree
|
25
|
+
graph = build_test_graph
|
26
|
+
# Using the standard test graph, get a tree from the 'd' node
|
27
|
+
tree = graph.tree_from('d')
|
28
|
+
# Test the parent node
|
29
|
+
test_node_direct(tree, [], ['f', 'g'])
|
30
|
+
# flag to show that we have arrived at the 'i' node on exactly
|
31
|
+
# one of the possible paths
|
32
|
+
i_reached = false
|
33
|
+
# Test the two direct children of the parent node,
|
34
|
+
# which should be f and g
|
35
|
+
tree.subclasses.each do |sub|
|
36
|
+
if(sub.to_s == 'f')
|
37
|
+
# We are on the f node.
|
38
|
+
# Check if we can reach the i node through f
|
39
|
+
# The 'i' node can either be reached through f, or
|
40
|
+
# through g-h
|
41
|
+
if(sub.subclasses.size == 1)
|
42
|
+
# We have found the i node
|
43
|
+
test_node_direct(sub, ['d'], ['i'])
|
44
|
+
i_reached = true
|
45
|
+
else
|
46
|
+
test_node_direct(sub, ['d'], [])
|
47
|
+
end
|
48
|
+
elsif(sub.to_s == 'g')
|
49
|
+
# We are in the g node, coming from d.
|
50
|
+
# The next node will be 'h', and then we can
|
51
|
+
# either find 'i' (if not found through 'f')
|
52
|
+
# or not
|
53
|
+
test_node_direct(sub, ['d'], ['h'])
|
54
|
+
assert_equal(1, sub.subclasses.size)
|
55
|
+
# Check if we find the h node
|
56
|
+
hnode = sub.subclasses.first
|
57
|
+
assert_equal('h', hnode.to_s)
|
58
|
+
# look for the i node on this path, if it wasn't found above
|
59
|
+
if(hnode.subclasses.size == 0)
|
60
|
+
test_node_direct(hnode, ['g'], [])
|
61
|
+
else
|
62
|
+
assert_not(i_reached)
|
63
|
+
test_node_direct(hnode, ['g'], ['i'])
|
64
|
+
i_reached = true
|
65
|
+
end
|
66
|
+
else
|
67
|
+
fail
|
68
|
+
end
|
69
|
+
end
|
70
|
+
assert(i_reached)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def test_node(graph, node_name, superclasses, subclasses)
|
76
|
+
test_node_direct(graph.get_node(node_name), superclasses, subclasses)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_node_direct(node, superclasses, subclasses)
|
80
|
+
assert_equal(node.superclasses.collect {|c| c.to_s }.sort, superclasses.sort)
|
81
|
+
assert_equal(node.subclasses.collect {|c| c.to_s }.sort, subclasses.sort)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Build the test graph for weeding out the inferred relations.
|
85
|
+
#
|
86
|
+
# The tree is the build_test_graph plus
|
87
|
+
# the corresponding "direct" superclass and subclass relations
|
88
|
+
def build_test_for_weed
|
89
|
+
graph = build_test_graph
|
90
|
+
|
91
|
+
graph.add_relation('a', 'f')
|
92
|
+
graph.add_relation('a', 'g')
|
93
|
+
graph.add_relation('a', 'h')
|
94
|
+
graph.add_relation('a', 'i')
|
95
|
+
graph.add_relation('d', 'h')
|
96
|
+
graph.add_relation('d', 'i')
|
97
|
+
graph.add_relation('g', 'i')
|
98
|
+
graph.add_relation('b', 'f')
|
99
|
+
graph.add_relation('b', 'g')
|
100
|
+
graph.add_relation('b', 'h')
|
101
|
+
graph.add_relation('b', 'i')
|
102
|
+
graph.add_relation('e', 'i')
|
103
|
+
graph
|
104
|
+
end
|
105
|
+
|
106
|
+
# Build a test graph
|
107
|
+
#
|
108
|
+
# The tree is
|
109
|
+
# A -> [C, D]
|
110
|
+
# B -> [D, E]
|
111
|
+
# D -> [F, G]
|
112
|
+
# E -> [H]
|
113
|
+
# F -> [I]
|
114
|
+
# G -> [H]
|
115
|
+
# H -> [I]
|
116
|
+
#
|
117
|
+
def build_test_graph
|
118
|
+
graph = OntologyGraph::Graph.new
|
119
|
+
|
120
|
+
graph.add_relation('a', 'c')
|
121
|
+
graph.add_relation('a', 'd')
|
122
|
+
graph.add_relation('d', 'f')
|
123
|
+
graph.add_relation('d', 'g')
|
124
|
+
graph.add_relation('f', 'i')
|
125
|
+
graph.add_relation('g', 'h')
|
126
|
+
graph.add_relation('h', 'i')
|
127
|
+
graph.add_relation('b', 'd')
|
128
|
+
graph.add_relation('b', 'e')
|
129
|
+
graph.add_relation('e', 'h')
|
130
|
+
graph
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
data/test/source_class_test.rb
CHANGED
@@ -41,17 +41,17 @@ class TypeTest < Test::Unit::TestCase
|
|
41
41
|
def test_rdf_types
|
42
42
|
return unless(RDF_ACTIVE)
|
43
43
|
types = N::SourceClass.rdf_types.collect { |type| type.uri.to_s }
|
44
|
-
assert_equal([N::RDFTEST.Type1.to_s, N::RDFTEST.Type2.to_s, N::RDFTEST.Type3.to_s, N::RDFTEST.Type4.to_s].sort, types.sort)
|
44
|
+
assert_equal([N::RDFTEST.Type1.to_s, N::RDFTEST.Type2.to_s, N::RDFTEST.Type3.to_s, N::RDFTEST.Type4.to_s, N::RDFS.Class.to_s].sort, types.sort)
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_subclass_hierarchy
|
48
48
|
hierarchy = N::SourceClass.subclass_hierarchy
|
49
|
-
assert_equal({N::RDFTEST.Type1 => { N::RDFTEST.Type2 => {}, N::RDFTEST.Type3 => {} }, N::RDFTEST.Type4 => { N::RDFTEST.Type3 => {}}}, hierarchy)
|
49
|
+
assert_equal({N::RDFTEST.Type1 => { N::RDFTEST.Type2 => {}, N::RDFTEST.Type3 => {} }, N::RDFTEST.Type4 => { N::RDFTEST.Type3 => {}}, N::RDFS.Class => {}}, hierarchy)
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_used_subclass_hierarchy
|
53
|
-
hierarchy = N::SourceClass.
|
54
|
-
assert_equal({N::RDFTEST.Type1 => { N::RDFTEST.Type2 => {}}}, hierarchy)
|
53
|
+
hierarchy = N::SourceClass.subclass_hierarchy { |t| t.used? }
|
54
|
+
assert_equal({N::RDFTEST.Type1 => { N::RDFTEST.Type2 => {}}, N::RDFS.Class => {}}, hierarchy)
|
55
55
|
end
|
56
56
|
|
57
57
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semantic_naming
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
|
7
|
+
- Daniel Hahn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11
|
12
|
+
date: 2009-12-11 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -20,35 +20,37 @@ executables: []
|
|
20
20
|
extensions: []
|
21
21
|
|
22
22
|
extra_rdoc_files:
|
23
|
-
|
23
|
+
- README.rdoc
|
24
24
|
files:
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
- lib/ontology_graph/class_node.rb
|
26
|
+
- lib/ontology_graph/graph.rb
|
27
|
+
- lib/semantic_naming.rb
|
28
|
+
- lib/semantic_naming/default_namespaces.rb
|
29
|
+
- lib/semantic_naming/namespace.rb
|
30
|
+
- lib/semantic_naming/predicate.rb
|
31
|
+
- lib/semantic_naming/source_class.rb
|
32
|
+
- lib/semantic_naming/uri.rb
|
33
|
+
- README.rdoc
|
32
34
|
has_rdoc: true
|
33
35
|
homepage: http://talia.discovery-project.eu/
|
34
36
|
licenses: []
|
35
37
|
|
36
38
|
post_install_message:
|
37
39
|
rdoc_options:
|
38
|
-
|
40
|
+
- --charset=UTF-8
|
39
41
|
require_paths:
|
40
|
-
|
42
|
+
- lib
|
41
43
|
required_ruby_version: !ruby/object:Gem::Requirement
|
42
44
|
requirements:
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
46
48
|
version:
|
47
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
50
|
requirements:
|
49
|
-
|
50
|
-
|
51
|
-
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
52
54
|
version:
|
53
55
|
requirements: []
|
54
56
|
|
@@ -58,7 +60,9 @@ signing_key:
|
|
58
60
|
specification_version: 3
|
59
61
|
summary: Semantic Naming Extensions for ActiveRDF, Talia and others
|
60
62
|
test_files:
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
- test/class_node_test.rb
|
64
|
+
- test/graph_test.rb
|
65
|
+
- test/namespace_test.rb
|
66
|
+
- test/predicate_test.rb
|
67
|
+
- test/source_class_test.rb
|
68
|
+
- test/uri_test.rb
|