rdf-isomorphic 0.2.0 → 0.3.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/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
|