rdf-isomorphic 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/rdf/isomorphic.rb +33 -9
- data/lib/rdf/isomorphic/version.rb +1 -1
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/rdf/isomorphic.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'digest/sha1'
|
2
2
|
require 'rdf'
|
3
|
+
require 'rdf/ntriples'
|
3
4
|
|
4
5
|
|
5
6
|
module RDF
|
@@ -75,7 +76,6 @@ module RDF
|
|
75
76
|
# @private
|
76
77
|
def build_bijection_to(anon_stmts, nodes, other_anon_stmts, other_nodes, these_grounded_hashes = {}, other_grounded_hashes = {})
|
77
78
|
|
78
|
-
|
79
79
|
# Create a hash signature of every node, based on the signature of
|
80
80
|
# statements it exists in.
|
81
81
|
# We also save hashes of nodes that cannot be reliably known; we will use
|
@@ -85,20 +85,31 @@ module RDF
|
|
85
85
|
these_hashes, these_ungrounded_hashes = RDF::Isomorphic.hash_nodes(anon_stmts, nodes, these_grounded_hashes)
|
86
86
|
other_hashes, other_ungrounded_hashes = RDF::Isomorphic.hash_nodes(other_anon_stmts, other_nodes, other_grounded_hashes)
|
87
87
|
|
88
|
+
# Grounded hashes are built at the same rate between the two graphs (if
|
89
|
+
# they are isomorphic). If there exists a grounded node in one that is
|
90
|
+
# not in the other, we can just return. Ungrounded nodes might still
|
91
|
+
# conflict, so we don't check them. This is a little bit messy in the
|
92
|
+
# middle of the method, and probably slows down isomorphic checks, but
|
93
|
+
# prevents almost-isomorphic cases from getting nutty.
|
94
|
+
return nil if these_hashes.values.any? { |hash|
|
95
|
+
!(other_hashes.values.member?(hash)) }
|
96
|
+
return nil if other_hashes.values.any? { |hash| !(these_hashes.values.member?(hash)) }
|
88
97
|
|
89
98
|
# Using the created hashes, map nodes to other_nodes
|
99
|
+
# Ungrounded hashes will also be equal, but we keep the distinction
|
100
|
+
# around for when we recurse later (we only recurse on ungrounded nodes)
|
90
101
|
bijection = {}
|
91
102
|
nodes.each do | node |
|
92
|
-
other_node, other_hash =
|
103
|
+
other_node, other_hash = other_ungrounded_hashes.find do | other_node, other_hash |
|
93
104
|
# we need to use eql?, as coincedentally-named bnode identifiers are == in rdf.rb
|
94
|
-
|
105
|
+
these_ungrounded_hashes[node].eql? other_hash
|
95
106
|
end
|
96
107
|
next unless other_node
|
97
108
|
bijection[node] = other_node
|
98
|
-
|
99
|
-
#
|
100
|
-
#
|
101
|
-
|
109
|
+
|
110
|
+
# Deletion is required to keep counts even; two nodes with identical
|
111
|
+
# signatures can biject to each other at random.
|
112
|
+
other_ungrounded_hashes.delete other_node
|
102
113
|
end
|
103
114
|
|
104
115
|
# bijection is now a mapping of nodes to other_nodes. If all are
|
@@ -166,17 +177,26 @@ module RDF
|
|
166
177
|
# grounded, other nodes can then use it to decide their own state of
|
167
178
|
# grounded.
|
168
179
|
while hash_needed
|
169
|
-
|
180
|
+
starting_grounded_nodes = hashes.size
|
170
181
|
nodes.each do | node |
|
171
182
|
unless hashes.member? node
|
172
183
|
grounded, hash = node_hash_for(node, statements, hashes)
|
173
184
|
if grounded
|
174
|
-
hash_needed = true
|
175
185
|
hashes[node] = hash
|
176
186
|
end
|
177
187
|
ungrounded_hashes[node] = hash
|
178
188
|
end
|
179
189
|
end
|
190
|
+
# after going over the list, any nodes with a unique hash can be marked
|
191
|
+
# as grounded, even if we have not tied them back to a root yet.
|
192
|
+
uniques = {}
|
193
|
+
ungrounded_hashes.each do |node, hash|
|
194
|
+
uniques[hash] = uniques[hash].is_a?(RDF::Node) ? false : node
|
195
|
+
end
|
196
|
+
uniques.each do |hash, node|
|
197
|
+
hashes[node] = hash unless node == false
|
198
|
+
end
|
199
|
+
hash_needed = starting_grounded_nodes != hashes.size
|
180
200
|
end
|
181
201
|
[hashes,ungrounded_hashes]
|
182
202
|
end
|
@@ -245,6 +265,10 @@ module RDF
|
|
245
265
|
hashes[node]
|
246
266
|
when node.node?
|
247
267
|
"a blank node"
|
268
|
+
# RDF.rb auto-boxing magic makes some literals the same when they
|
269
|
+
# should not be; the ntriples serializer will take care of us
|
270
|
+
when node.literal?
|
271
|
+
node.class.name + RDF::NTriples.serialize(node)
|
248
272
|
else
|
249
273
|
node.to_s
|
250
274
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ben Lavender
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-10-26 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|