bel 0.3.3 → 0.4.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +53 -8
  3. data/bel.gemspec +10 -15
  4. data/bin/bel +63 -4
  5. data/bin/bel2rdf.rb +1 -1
  6. data/bin/bel_compare.rb +1 -1
  7. data/bin/bel_parse.rb +1 -1
  8. data/bin/bel_rdfschema.rb +1 -1
  9. data/bin/bel_summarize.rb +1 -1
  10. data/bin/bel_upgrade.rb +1 -1
  11. data/lib/bel.rb +8 -10
  12. data/lib/bel/completion.rb +3 -2
  13. data/lib/bel/completion/value_match_rule.rb +10 -0
  14. data/lib/bel/evidence_model/citation.rb +101 -43
  15. data/lib/bel/evidence_model/evidence.rb +2 -2
  16. data/lib/bel/evidence_model/experiment_context.rb +1 -0
  17. data/lib/bel/evidence_model/metadata.rb +15 -2
  18. data/lib/bel/evidence_model/references.rb +10 -10
  19. data/lib/bel/json.rb +63 -0
  20. data/lib/bel/json/adapter/multi_json.rb +36 -0
  21. data/lib/bel/json/adapter/oj.rb +65 -0
  22. data/lib/bel/json/adapter/ruby_json.rb +28 -0
  23. data/lib/bel/json/reader.rb +9 -0
  24. data/lib/bel/json/writer.rb +9 -0
  25. data/lib/bel/libbel.rb +1 -4
  26. data/lib/bel/parser.rb +2 -2
  27. data/lib/bel/rdf_repository.rb +18 -0
  28. data/lib/bel/rdf_repository/plugins/memory.rb +28 -0
  29. data/lib/bel/rdf_repository/plugins/mongo.rb +28 -0
  30. data/lib/bel/resource.rb +24 -0
  31. data/lib/bel/resource/namespace.rb +122 -0
  32. data/lib/bel/resource/namespace_value.rb +69 -0
  33. data/lib/bel/resource/namespaces.rb +83 -0
  34. data/lib/bel/resource/search.rb +26 -0
  35. data/lib/bel/resource/search/api.rb +36 -0
  36. data/lib/bel/resource/search/search_result.rb +32 -0
  37. data/lib/bel/translate.rb +108 -0
  38. data/lib/bel/translator.rb +69 -0
  39. data/lib/bel/translator/plugins/bel_script.rb +36 -0
  40. data/lib/bel/translator/plugins/bel_script/bel_yielder.rb +144 -0
  41. data/lib/bel/translator/plugins/bel_script/evidence_yielder.rb +95 -0
  42. data/lib/bel/translator/plugins/bel_script/translator.rb +24 -0
  43. data/lib/bel/translator/plugins/jgf.rb +37 -0
  44. data/lib/bel/translator/plugins/jgf/translator.rb +160 -0
  45. data/lib/bel/translator/plugins/json_evidence.rb +38 -0
  46. data/lib/bel/translator/plugins/json_evidence/translator.rb +90 -0
  47. data/lib/bel/translator/plugins/rdf.rb +48 -0
  48. data/lib/bel/translator/plugins/rdf/bel_schema.rb +339 -0
  49. data/lib/bel/translator/plugins/rdf/monkey_patch.rb +310 -0
  50. data/lib/bel/translator/plugins/rdf/reader.rb +173 -0
  51. data/lib/bel/translator/plugins/rdf/translator.rb +40 -0
  52. data/lib/bel/translator/plugins/rdf/writer.rb +45 -0
  53. data/lib/bel/translator/plugins/xbel.rb +36 -0
  54. data/lib/bel/translator/plugins/xbel/evidence_handler.rb +468 -0
  55. data/lib/bel/translator/plugins/xbel/evidence_yielder.rb +24 -0
  56. data/lib/bel/translator/plugins/xbel/translator.rb +24 -0
  57. data/lib/bel/translator/plugins/xbel/xbel_yielder.rb +414 -0
  58. data/lib/bel/vendor/little-plugger.rb +323 -0
  59. data/lib/bel/version.rb +1 -1
  60. metadata +44 -158
  61. data/lib/bel/extension.rb +0 -37
  62. data/lib/bel/extension_format.rb +0 -207
  63. data/lib/bel/extensions/bel.rb +0 -258
  64. data/lib/bel/extensions/jgf.rb +0 -219
  65. data/lib/bel/extensions/json/jrjackson.rb +0 -31
  66. data/lib/bel/extensions/json/json.rb +0 -133
  67. data/lib/bel/extensions/json/multi_json.rb +0 -29
  68. data/lib/bel/extensions/json/oj.rb +0 -68
  69. data/lib/bel/extensions/json/ruby_json.rb +0 -29
  70. data/lib/bel/extensions/rdf/bel_rdf.rb +0 -338
  71. data/lib/bel/extensions/rdf/rdf.rb +0 -584
  72. data/lib/bel/extensions/xbel.rb +0 -923
  73. data/lib/bel/format.rb +0 -58
@@ -0,0 +1,310 @@
1
+ module BEL::Translator::Plugins
2
+
3
+ module Rdf
4
+
5
+ # OpenClass to contribute RDF functionality to BEL Model.
6
+ class ::BEL::Namespace::NamespaceDefinition
7
+
8
+ def to_uri
9
+ @rdf_uri
10
+ end
11
+
12
+ def to_rdf_vocabulary
13
+ ::RDF::Vocabulary.new("#{@rdf_uri}/")
14
+ end
15
+ end
16
+
17
+ class ::BEL::Model::Parameter
18
+
19
+ def to_uri
20
+ @ns.to_rdf_vocabulary[URI::encode(@value)]
21
+ end
22
+
23
+ def to_rdf
24
+ uri = to_uri
25
+ encodings = ['A'].concat(@enc.to_s.each_char.to_a).uniq
26
+ if block_given?
27
+ encodings.map { |enc| concept_statement(enc, uri) }.each do |stmt|
28
+ yield stmt
29
+ end
30
+ else
31
+ encodings.map { |enc| concept_statement(enc, uri)}
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def concept_statement(encoding_character, uri)
38
+ case encoding_character
39
+ when 'G'
40
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.GeneConcept)
41
+ when 'R'
42
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.RNAConcept)
43
+ when 'P'
44
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.ProteinConcept)
45
+ when 'M'
46
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.MicroRNAConcept)
47
+ when 'C'
48
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.ComplexConcept)
49
+ when 'B'
50
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.BiologicalProcessConcept)
51
+ when 'A'
52
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.AbundanceConcept)
53
+ when 'O'
54
+ ::RDF::Statement(uri, ::RDF.type, BEL::RDF::BELV.PathologyConcept)
55
+ end
56
+ end
57
+ end
58
+
59
+ class ::BEL::Model::Term
60
+
61
+ def to_uri
62
+ tid = to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
63
+ BEL::RDF::BELR[URI::encode(tid)]
64
+ end
65
+
66
+ def rdf_type
67
+ if respond_to? 'fx'
68
+ fx = @fx.respond_to?(:short_form) ? @fx.short_form : @fx.to_s.to_sym
69
+ if [:p, :proteinAbundance].include?(fx) &&
70
+ @arguments.find{ |x|
71
+ if x.is_a? ::BEL::Model::Term
72
+ arg_fx = x.fx
73
+ arg_fx = arg_fx.respond_to?(:short_form) ? arg_fx.short_form : arg_fx.to_s.to_sym
74
+ [:pmod, :proteinModification].include?(arg_fx)
75
+ else
76
+ false
77
+ end
78
+ }
79
+
80
+ return BEL::RDF::BELV.ModifiedProteinAbundance
81
+ end
82
+
83
+ if [:p, :proteinAbundance].include?(fx) &&
84
+ @arguments.find{ |x|
85
+ if x.is_a? ::BEL::Model::Term
86
+ arg_fx = x.fx
87
+ arg_fx = arg_fx.respond_to?(:short_form) ? arg_fx.short_form : arg_fx.to_s.to_sym
88
+ BEL::RDF::PROTEIN_VARIANT.include?(arg_fx)
89
+ else
90
+ false
91
+ end
92
+ }
93
+
94
+ return BEL::RDF::BELV.ProteinVariantAbundance
95
+ end
96
+
97
+ BEL::RDF::FUNCTION_TYPE[fx] || BEL::RDF::BELV.Abundance
98
+ end
99
+ end
100
+
101
+ def to_rdf
102
+ uri = to_uri
103
+ statements = []
104
+
105
+ # rdf:type
106
+ type = rdf_type
107
+ statements << [uri, BEL::RDF::RDF.type, BEL::RDF::BELV.Term]
108
+ statements << [uri, BEL::RDF::RDF.type, type]
109
+ fx = @fx.respond_to?(:short_form) ? @fx.short_form : @fx.to_s.to_sym
110
+ if BEL::RDF::ACTIVITY_TYPE.include? fx
111
+ statements << [uri, BEL::RDF::BELV.hasActivityType, BEL::RDF::ACTIVITY_TYPE[fx]]
112
+ end
113
+
114
+ # rdfs:label
115
+ statements << [uri, BEL::RDF::RDFS.label, to_s.force_encoding('UTF-8')]
116
+
117
+ # special proteins (does not recurse into pmod)
118
+ if [:p, :proteinAbundance].include?(fx)
119
+ pmod =
120
+ @arguments.find{ |x|
121
+ if x.is_a? ::BEL::Model::Term
122
+ arg_fx = x.fx
123
+ arg_fx = arg_fx.respond_to?(:short_form) ? arg_fx.short_form : arg_fx.to_s.to_sym
124
+ [:pmod, :proteinModification].include?(arg_fx)
125
+ else
126
+ false
127
+ end
128
+ }
129
+ if pmod
130
+ mod_string = pmod.arguments.map(&:to_s).join(',')
131
+ mod_type = BEL::RDF::MODIFICATION_TYPE.find {|k,v| mod_string.start_with? k}
132
+ mod_type = (mod_type ? mod_type[1] : BEL::RDF::BELV.Modification)
133
+ statements << [uri, BEL::RDF::BELV.hasModificationType, mod_type]
134
+ last = pmod.arguments.last.to_s
135
+ if last.match(/^\d+$/)
136
+ statements << [uri, BEL::RDF::BELV.hasModificationPosition, last.to_i]
137
+ end
138
+ # link root protein abundance as hasChild
139
+ root_param = @arguments.find{|x| x.is_a? ::BEL::Model::Parameter}
140
+ (root_id, root_statements) = ::BEL::Model::Term.new(:p, [root_param]).to_rdf
141
+ statements << [uri, BEL::RDF::BELV.hasChild, root_id]
142
+ statements += root_statements
143
+ return [uri, statements]
144
+ elsif @arguments.find{|x| x.is_a? ::BEL::Model::Term and BEL::RDF::PROTEIN_VARIANT.include? x.fx}
145
+ # link root protein abundance as hasChild
146
+ root_param = @arguments.find{|x| x.is_a? ::BEL::Model::Parameter}
147
+ (root_id, root_statements) = ::BEL::Model::Term.new(:p, [root_param]).to_rdf
148
+ statements << [uri, BEL::RDF::BELV.hasChild, root_id]
149
+ statements += root_statements
150
+ return [uri, statements]
151
+ end
152
+ end
153
+
154
+ # BEL::RDF::BELV.hasConcept]
155
+ @arguments.find_all{ |x|
156
+ x.is_a? ::BEL::Model::Parameter and x.ns != nil
157
+ }.each do |param|
158
+ concept_uri = param.ns.to_rdf_vocabulary[param.value.to_s]
159
+ statements << [uri, BEL::RDF::BELV.hasConcept, BEL::RDF::RDF::URI(Addressable::URI.encode(concept_uri))]
160
+ end
161
+
162
+ # BEL::RDF::BELV.hasChild]
163
+ @arguments.find_all{|x| x.is_a? ::BEL::Model::Term}.each do |child|
164
+ (child_id, child_statements) = child.to_rdf
165
+ statements << [uri, BEL::RDF::BELV.hasChild, child_id]
166
+ statements += child_statements
167
+ end
168
+
169
+ return [uri, statements]
170
+ end
171
+ end
172
+
173
+ class ::BEL::Model::Statement
174
+
175
+ def to_uri
176
+ case
177
+ when subject_only?
178
+ tid = @subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
179
+ BEL::RDF::BELR[URI::encode(tid)]
180
+ when simple?
181
+ sub_id = @subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
182
+ obj_id = @object.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
183
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
184
+ if rel
185
+ rel = rel.path.split('/')[-1]
186
+ else
187
+ rel = @relationship.to_s
188
+ end
189
+ BEL::RDF::BELR[URI::encode("#{sub_id}_#{rel}_#{obj_id}")]
190
+ when nested?
191
+ sub_id = @subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
192
+ nsub_id = @object.subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
193
+ nobj_id = @object.object.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
194
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
195
+ if rel
196
+ rel = rel.path.split('/')[-1]
197
+ else
198
+ rel = @relationship.to_s
199
+ end
200
+ nrel = BEL::RDF::RELATIONSHIP_TYPE[@object.relationship.to_s]
201
+ if nrel
202
+ nrel = nrel.path.split('/')[-1]
203
+ else
204
+ nrel = @object.relationship.to_s
205
+ end
206
+ BEL::RDF::BELR[URI::encode("#{sub_id}_#{rel}_#{nsub_id}_#{nrel}_#{nobj_id}")]
207
+ end
208
+ end
209
+
210
+ def to_rdf
211
+ uri = to_uri
212
+ statements = []
213
+
214
+ case
215
+ when subject_only?
216
+ (sub_uri, sub_statements) = @subject.to_rdf
217
+ statements << [uri, BEL::RDF::BELV.hasSubject, sub_uri]
218
+ statements += sub_statements
219
+ when simple?
220
+ (sub_uri, sub_statements) = @subject.to_rdf
221
+ statements += sub_statements
222
+
223
+ (obj_uri, obj_statements) = @object.to_rdf
224
+ statements += obj_statements
225
+
226
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
227
+ statements << [uri, BEL::RDF::BELV.hasSubject, sub_uri]
228
+ statements << [uri, BEL::RDF::BELV.hasObject, obj_uri]
229
+ statements << [uri, BEL::RDF::BELV.hasRelationship, rel]
230
+ when nested?
231
+ (sub_uri, sub_statements) = @subject.to_rdf
232
+ (nsub_uri, nsub_statements) = @object.subject.to_rdf
233
+ (nobj_uri, nobj_statements) = @object.object.to_rdf
234
+ statements += sub_statements
235
+ statements += nsub_statements
236
+ statements += nobj_statements
237
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
238
+ nrel = BEL::RDF::RELATIONSHIP_TYPE[@object.relationship.to_s]
239
+ nuri = BEL::RDF::BELR["#{strip_prefix(nsub_uri)}_#{nrel}_#{strip_prefix(nobj_uri)}"]
240
+
241
+ # inner
242
+ statements << [nuri, BEL::RDF::BELV.hasSubject, nsub_uri]
243
+ statements << [nuri, BEL::RDF::BELV.hasObject, nobj_uri]
244
+ statements << [nuri, BEL::RDF::BELV.hasRelationship, nrel]
245
+
246
+ # outer
247
+ statements << [uri, BEL::RDF::BELV.hasSubject, sub_uri]
248
+ statements << [uri, BEL::RDF::BELV.hasObject, nuri]
249
+ statements << [uri, BEL::RDF::BELV.hasRelationship, rel]
250
+ end
251
+
252
+ # common statement triples
253
+ statements << [uri, BEL::RDF::RDF.type, BEL::RDF::BELV.Statement]
254
+ statements << [uri, ::RDF::RDFS.label, to_s.force_encoding('UTF-8')]
255
+
256
+ # evidence
257
+ evidence_bnode = BEL::RDF::RDF::Node.uuid
258
+ statements << [evidence_bnode, BEL::RDF::RDF.type, BEL::RDF::BELV.Evidence]
259
+ statements << [uri, BEL::RDF::BELV.hasEvidence, evidence_bnode]
260
+ statements << [evidence_bnode, BEL::RDF::BELV.hasStatement, uri]
261
+
262
+ # citation
263
+ citation = @annotations.delete('Citation')
264
+ if citation
265
+ value = citation.value.map{|x| x.gsub('"', '')}
266
+ if citation and value[0] == 'PubMed'
267
+ pid = value[2]
268
+ statements << [
269
+ evidence_bnode,
270
+ BEL::RDF::BELV.hasCitation,
271
+ BEL::RDF::RDF::URI(BEL::RDF::PUBMED[pid])
272
+ ]
273
+ end
274
+ end
275
+
276
+ # evidence
277
+ evidence_text = @annotations.delete('Evidence')
278
+ if evidence_text
279
+ value = evidence_text.value.gsub('"', '').force_encoding('UTF-8')
280
+ statements << [evidence_bnode, BEL::RDF::BELV.hasEvidenceText, value]
281
+ end
282
+
283
+ # annotations
284
+ @annotations.each do |name, anno|
285
+ name = anno.name.gsub('"', '')
286
+
287
+ if BEL::RDF::const_defined? name
288
+ annotation_scheme = BEL::RDF::const_get name
289
+ [anno.value].flatten.map{|x| x.gsub('"', '')}.each do |val|
290
+ value_uri = BEL::RDF::RDF::URI(Addressable::URI.encode(annotation_scheme[val.to_s]))
291
+ statements << [evidence_bnode, BEL::RDF::BELV.hasAnnotation, value_uri]
292
+ end
293
+ end
294
+ end
295
+
296
+ return [uri, statements]
297
+ end
298
+
299
+ private
300
+
301
+ def strip_prefix(uri)
302
+ if uri.to_s.start_with? 'http://www.openbel.org/bel/'
303
+ uri.to_s[28..-1]
304
+ else
305
+ uri
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end
@@ -0,0 +1,173 @@
1
+ module BEL::Translator::Plugins
2
+
3
+ module Rdf::Reader
4
+
5
+ module EvidenceYielder
6
+
7
+ BELV = Rdf::BEL::RDF::BELV
8
+
9
+ include ::BEL::Model
10
+ include ::BEL::Quoting
11
+
12
+ # Find described resources by +type+ in +graph+.
13
+ #
14
+ # @param [::RDF::Resource] type the RDF type to find instances for
15
+ # @param [::RDF::Graph] graph the RDF graph to query
16
+ # @return [Enumerator] an enumerator of described resource instances
17
+ def resources_of_type(type, graph)
18
+ graph.query([nil, ::RDF.type, type])
19
+ .lazy
20
+ .map { |rdf_statement|
21
+ describe(rdf_statement.subject, graph)
22
+ }
23
+ end
24
+
25
+ # Describes an RDF +resource+ contained within +graph+. Describing an RDF
26
+ # resource will retrieve the neighborhood of RDF statements with
27
+ # +resource+ in the subject position.
28
+ #
29
+ # @param [::RDF::Resource] resource the RDF resource to describe
30
+ # @param [::RDF::Graph] graph the RDF graph to query
31
+ # @return [Hash] a hash of predicate to object in the
32
+ # neighborhood of +resource+
33
+ def describe(resource, graph)
34
+ graph.query([resource, nil, nil]).reduce({}) { |hash, statement|
35
+ hash[statement.predicate] = statement.object
36
+ hash
37
+ }
38
+ end
39
+
40
+ # Iterate the {BELV.Evidence} predicated statements, from the
41
+ # {::RDF::Graph graph}, and yield those correspdonding {Evidence}
42
+ # objects.
43
+ #
44
+ # @param [::RDF::Graph] graph the RDF graph to query
45
+ # @yield [evidence_model] yields an {Evidence} object
46
+ def evidence_yielder(graph)
47
+ resources_of_type(BELV.Evidence, graph).each do |evidence|
48
+
49
+ yield make_evidence(evidence, graph)
50
+ end
51
+ end
52
+
53
+ # Create an {Evidence} object from RDF statements found in
54
+ # the {::RDF::Graph graph}.
55
+ #
56
+ # @param [Hash] evidence a hash of predicate to object
57
+ # representing the described evidence
58
+ # @param [::RDF::Graph] graph the RDF graph to query
59
+ # @return [Evidence] the evidence model
60
+ def make_evidence(evidence, graph)
61
+ statement = describe(evidence[BELV.hasStatement], graph)
62
+
63
+ # values
64
+ bel_statement = statement[::RDF::RDFS.label].value
65
+ ev_text = evidence[BELV.hasEvidenceText]
66
+ citation = evidence[BELV.hasCitation]
67
+
68
+ # model
69
+ ev_model = Evidence.new
70
+ ev_model.bel_statement = ::BEL::Script.parse(bel_statement)
71
+ .find { |obj|
72
+ obj.is_a? Statement
73
+ }
74
+ ev_model.summary_text = SummaryText.new(ev_text.value) if ev_text
75
+
76
+ if citation.respond_to?(:value)
77
+ ev_model.citation =
78
+ case citation.value
79
+ when /pubmed:(\d+)$/
80
+ pubmed_id = $1.to_i
81
+ Citation.new({
82
+ :type => 'PubMed',
83
+ :id => pubmed_id,
84
+ :name => "PubMed Citation - #{pubmed_id}"
85
+ })
86
+ else
87
+ nil
88
+ end
89
+ end
90
+
91
+ ev_model
92
+ end
93
+ end
94
+
95
+ class BufferedEvidenceYielder
96
+
97
+ include EvidenceYielder
98
+
99
+ def initialize(data, format = :ntriples)
100
+ @data = data
101
+ @format = format
102
+ end
103
+
104
+ def each
105
+ if block_given?
106
+ graph = RUBYRDF::Graph.new
107
+ RUBYRDF::Reader.for(@format).new(@data) do |reader|
108
+ reader.each_statement do |statement|
109
+ graph << statement
110
+ end
111
+ end
112
+ evidence_yielder(graph) do |evidence_model|
113
+ yield evidence_model
114
+ end
115
+ else
116
+ to_enum(:each)
117
+ end
118
+ end
119
+ end
120
+
121
+ class UnbufferedEvidenceYielder
122
+
123
+ include EvidenceYielder
124
+
125
+ def initialize(data, format = :ntriples)
126
+ @data = data
127
+ @format = format
128
+ end
129
+
130
+ def each
131
+ if block_given?
132
+ graph = RUBYRDF::Graph.new
133
+ evidence_resource = nil
134
+ RUBYRDF::Reader.for(@format).new(@data) do |reader|
135
+ reader.each_statement do |statement|
136
+ case
137
+ when statement.object == BELV.Evidence &&
138
+ statement.predicate == RUBYRDF.type
139
+ evidence_resource = statement.subject
140
+ when evidence_resource &&
141
+ statement.predicate != BELV.hasEvidence &&
142
+ statement.subject != evidence_resource
143
+
144
+ # yield current graph as evidence model
145
+ yield make_evidence(
146
+ describe(evidence_resource, graph),
147
+ graph
148
+ )
149
+
150
+ # reset parse state
151
+ graph.clear
152
+ evidence_resource = nil
153
+
154
+ # insert this RDF statement
155
+ graph << statement
156
+ else
157
+ graph << statement
158
+ end
159
+ end
160
+ end
161
+
162
+ # yield last graph as evidence model
163
+ yield make_evidence(
164
+ describe(evidence_resource, graph),
165
+ graph
166
+ )
167
+ else
168
+ to_enum(:each)
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end