semantic_naming 2.0.6 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|