bel 0.3.0.beta1-x64-mingw32

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.
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ # if set in environment, set compiler for make
4
+ # example:
5
+ # CC=gcc-4.8 gem install bel.rb
6
+ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
7
+
8
+ create_makefile('libbel')
@@ -0,0 +1,5 @@
1
+ void Init_libbel() {
2
+ // initialization for bel_ext extension
3
+ // empty; loaded using ffi
4
+ }
5
+
@@ -0,0 +1,26 @@
1
+ EXPORTS
2
+ Init_libbel
3
+ bel_ast_as_string
4
+ bel_copy_ast_node
5
+ bel_free_ast
6
+ bel_free_ast_node
7
+ bel_new_ast
8
+ bel_new_ast_node_token
9
+ bel_new_ast_node_value
10
+ bel_new_token
11
+ bel_new_token_iterator
12
+ bel_new_token_list
13
+ bel_parse_statement
14
+ bel_parse_term
15
+ bel_print_ast
16
+ bel_print_ast_node
17
+ bel_print_token
18
+ bel_print_token_list
19
+ bel_set_value
20
+ bel_token_iterator_end
21
+ bel_token_iterator_get
22
+ bel_token_iterator_next
23
+ bel_tokenize_term
24
+ free_bel_token
25
+ free_bel_token_iterator
26
+ free_bel_token_list
@@ -0,0 +1,17 @@
1
+ # Load core objects
2
+ require_relative 'libbel'
3
+ require_relative 'bel/completion'
4
+ require_relative 'bel/language'
5
+ require_relative 'bel/namespace'
6
+ include BEL::Language
7
+ include BEL::Namespace
8
+
9
+ module BEL
10
+ autoload :Script, "#{File.dirname(__FILE__)}/bel/script"
11
+ autoload :RDF, "#{File.dirname(__FILE__)}/bel/rdf"
12
+
13
+ require_relative './features.rb'
14
+ require_relative './util.rb'
15
+ end
16
+ # vim: ts=2 sw=2:
17
+ # encoding: utf-8
@@ -0,0 +1,53 @@
1
+ require_relative '../libbel'
2
+ require_relative 'completion_rule'
3
+ require_relative 'language'
4
+ require_relative 'namespace'
5
+
6
+ module BEL
7
+ module Completion
8
+
9
+ # Provides completions on BEL expressions.
10
+ #
11
+ # If +bel_expression+ is +nil+ then its assumed to be the empty string
12
+ # otherwise the +to_s+ method is called. An empty +bel_expression+ will
13
+ # return all BEL functions as possible completions.
14
+ #
15
+ # If +search+ is +nil+ then namespace values will not be provided as
16
+ # completion. +search+ is expected to implement {IdentifierSearch}.
17
+ #
18
+ # If +position+ is +nil+ then its assumed to be the last index of
19
+ # +bel_expression+ otherwise the +to_i+ method is called.
20
+ #
21
+ # If +position+ is negative or greater than the length of +bel_expression+
22
+ # an +IndexError+ is raised.
23
+ #
24
+ # @param bel_expression [responds to #to_s] the bel expression to
25
+ # complete on
26
+ # @param search [IdentifierSearch] the search object used to
27
+ # provide namespace value completions
28
+ # @param position [responds to #to_i] the position to complete from
29
+ # @return [Array<Completion>]
30
+ def self.complete(bel_expression, search = nil, position = nil)
31
+ bel_expression = (bel_expression || '').to_s
32
+ position = (position || bel_expression.length).to_i
33
+ if position < 0 or position > bel_expression.length
34
+ msg = %Q{position #{position}, bel_expression "#{bel_expression}"}
35
+ fail IndexError, msg
36
+ end
37
+
38
+ token_list = LibBEL::tokenize_term(bel_expression)
39
+ active_token, active_index = token_list.token_at(position)
40
+
41
+ # no active token indicates the position is out of
42
+ # range of all tokens in the list.
43
+ return [] unless active_token
44
+
45
+ tokens = token_list.to_a
46
+ options = {
47
+ :search => search
48
+ }
49
+ BEL::Completion::run_rules(tokens, active_index, active_token, options)
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,236 @@
1
+ require_relative 'language'
2
+ require_relative 'namespace'
3
+ require_relative 'quoting'
4
+ require 'uri'
5
+
6
+ module BEL
7
+ module Completion
8
+
9
+ SORTED_FUNCTIONS = BEL::Language::FUNCTIONS.keys.sort.map(&:to_s)
10
+ SORTED_NAMESPACES = BEL::Namespace::NAMESPACE_LATEST.keys.sort.map(&:to_s)
11
+ EMPTY_MATCH = []
12
+
13
+ def self.run_rules(tokens, active_index, active_token, options = {})
14
+ self.rules.reduce([]) { |completion_results, rule|
15
+ completion_results.concat(
16
+ rule.apply(tokens, active_token, active_index, options)
17
+ )
18
+ }
19
+ end
20
+
21
+ def self.rules
22
+ [
23
+ MatchFunctionRule.new,
24
+ MatchNamespacePrefixRule.new,
25
+ MatchNamespaceValueRule.new
26
+ ]
27
+ end
28
+
29
+ module Rule
30
+
31
+ def apply(token_list, active_token, active_token_index, options = {})
32
+ matches = _apply(token_list, active_token, active_token_index, options)
33
+
34
+ matches.map { |match|
35
+ match = map_highlight(match, active_token)
36
+ match = map_actions(match, active_token)
37
+ match.delete(:offset)
38
+ match
39
+ }
40
+ end
41
+
42
+ protected
43
+
44
+ def _apply(token_list, active_token, active_token_index, options = {})
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def map_highlight(match, active_token)
49
+ if active_token and not [:O_PAREN, :COMMA].include?(active_token.type)
50
+ value_start = match[:value].downcase.index(active_token.value.downcase)
51
+ if value_start
52
+ value_end = value_start + active_token.value.length
53
+ highlight = {
54
+ :start_position => value_start,
55
+ :end_position => value_end,
56
+ :range_type => :inclusive
57
+ }
58
+ else
59
+ highlight = nil
60
+ end
61
+ else
62
+ highlight = nil
63
+ end
64
+ match.merge!({:highlight => highlight})
65
+ end
66
+
67
+ def map_actions(match, active_token)
68
+ position_start = active_token ? active_token.pos_start : 0
69
+ actions = []
70
+
71
+ if active_token and not [:O_PAREN, :COLON].include?(active_token.type)
72
+ # delete from start of active token to end of a
73
+ actions.push({
74
+ :delete => {
75
+ :start_position => position_start,
76
+ :end_position => active_token.pos_end - 1,
77
+ :range_type => :inclusive
78
+ }
79
+ })
80
+ end
81
+
82
+ # add the active_token length if we do not need to delete it
83
+ if active_token and actions.empty?
84
+ position_start += active_token.value.length
85
+ end
86
+
87
+ actions.concat([
88
+ {
89
+ :insert => {
90
+ :position => position_start,
91
+ :value => match[:value]
92
+ }
93
+ },
94
+ {
95
+ :move_cursor => {
96
+ :position => position_start + match[:value].length + match[:offset]
97
+ }
98
+ }
99
+ ])
100
+ match.merge!({:actions => actions})
101
+ end
102
+ end
103
+
104
+ class MatchFunctionRule
105
+ include Rule
106
+
107
+ def _apply(token_list, active_token, active_token_index, options = {})
108
+ if token_list.empty? or active_token.type == :O_PAREN
109
+ return SORTED_FUNCTIONS.map { |fx| map_function(fx) }.uniq.sort_by { |fx|
110
+ fx[:label]
111
+ }
112
+ end
113
+
114
+ if active_token.type == :IDENT
115
+ value = active_token.value.downcase
116
+ return SORTED_FUNCTIONS.find_all { |x|
117
+ x.downcase.include? value
118
+ }.map { |fx| map_function(fx) }.uniq.sort_by { |fx| fx[:label] }
119
+ end
120
+
121
+ return EMPTY_MATCH
122
+ end
123
+
124
+ protected
125
+
126
+ def map_function(fx_name)
127
+ fx = Function.new(FUNCTIONS[fx_name.to_sym])
128
+ if fx
129
+ {
130
+ :id => fx.short_form,
131
+ :type => :function,
132
+ :label => fx.long_form,
133
+ :value => "#{fx.short_form}()",
134
+ :offset => -1
135
+ }
136
+ else
137
+ nil
138
+ end
139
+ end
140
+ end
141
+
142
+ class MatchNamespacePrefixRule
143
+ include Rule
144
+
145
+ def _apply(token_list, active_token, active_token_index, options = {})
146
+ if token_list.empty? or active_token.type == :O_PAREN
147
+ return SORTED_NAMESPACES.map { |ns_prefix|
148
+ map_namespace_prefix(ns_prefix)
149
+ }
150
+ end
151
+
152
+ # first token is always function
153
+ return [] if active_token == token_list[0]
154
+
155
+ if active_token.type == :IDENT
156
+ value = active_token.value.downcase
157
+ return SORTED_NAMESPACES.find_all { |x|
158
+ x.downcase.include? value
159
+ }.map { |ns_prefix|
160
+ map_namespace_prefix(ns_prefix)
161
+ }
162
+ end
163
+
164
+ return EMPTY_MATCH
165
+ end
166
+
167
+ private
168
+
169
+ def map_namespace_prefix(ns_prefix)
170
+ {
171
+ :id => ns_prefix,
172
+ :type => :namespace_prefix,
173
+ :label => ns_prefix,
174
+ :value => "#{ns_prefix}:",
175
+ :offset => 0
176
+ }
177
+ end
178
+ end
179
+
180
+ class MatchNamespaceValueRule
181
+ include Rule
182
+ include BEL::Quoting
183
+
184
+ def _apply(token_list, active_token, active_token_index, options = {})
185
+ search = options.delete(:search)
186
+ return EMPTY_MATCH if not search or token_list.empty?
187
+
188
+ if active_token.type == :IDENT && active_token.value.length > 1
189
+ previous_token = token_list[active_token_index - 1]
190
+ if previous_token and previous_token.type == :COLON
191
+ # search within a namespace
192
+ prefix_token = token_list[active_token_index - 2]
193
+ if prefix_token and prefix_token.type == :IDENT
194
+ namespace = BEL::Namespace::NAMESPACE_LATEST[prefix_token.value.to_sym]
195
+ if namespace
196
+ scheme_uri = namespace[1]
197
+ return search.search_namespace(
198
+ URI(scheme_uri),
199
+ "#{active_token.value}*",
200
+ :start => 0,
201
+ :size => 10
202
+ ).
203
+ map { |search_result|
204
+ map_namespace_value(search_result.pref_label)
205
+ }.to_a
206
+ end
207
+ end
208
+ else
209
+ return search.search(
210
+ active_token.value,
211
+ :start => 0,
212
+ :size => 10
213
+ ).
214
+ map { |search_result|
215
+ map_namespace_value(search_result.pref_label)
216
+ }.to_a
217
+ end
218
+ end
219
+
220
+ return EMPTY_MATCH
221
+ end
222
+
223
+ protected
224
+
225
+ def map_namespace_value(ns_value)
226
+ {
227
+ :id => ns_value,
228
+ :type => :namespace_value,
229
+ :label => ns_value,
230
+ :value => ensure_quotes(ns_value),
231
+ :offset => 0
232
+ }
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,1052 @@
1
+ require_relative '../features'
2
+ require_relative 'quoting'
3
+ module BEL
4
+ module Language
5
+
6
+ class Newline
7
+ def to_bel
8
+ ""
9
+ end
10
+ alias_method :to_s, :to_bel
11
+ end
12
+ NEW_LINE = Newline.new
13
+
14
+ Comment = Struct.new(:text) do
15
+ def to_bel
16
+ %Q{##{self.text}}
17
+ end
18
+ alias_method :to_s, :to_bel
19
+ end
20
+
21
+ DocumentProperty = Struct.new(:name, :value) do
22
+ include BEL::Quoting
23
+
24
+ def to_bel
25
+ %Q{SET DOCUMENT #{self.name} = #{ensure_quotes(self.value)}}
26
+ end
27
+ alias_method :to_s, :to_bel
28
+ end
29
+
30
+ AnnotationDefinition = Struct.new(:type, :prefix, :value) do
31
+ def to_bel
32
+ case self.type
33
+ when :list
34
+ %Q{DEFINE ANNOTATION #{self.prefix} AS LIST {#{self.value.join(',')}}}
35
+ when :pattern
36
+ %Q{DEFINE ANNOTATION #{self.prefix} AS PATTERN "#{self.value}"}
37
+ when :url
38
+ %Q{DEFINE ANNOTATION #{self.prefix} AS URL "#{self.value}"}
39
+ end
40
+ end
41
+ alias_method :to_s, :to_bel
42
+ end
43
+
44
+ class Parameter
45
+ include BEL::Quoting
46
+ include Comparable
47
+ attr_accessor :ns, :value, :enc, :signature
48
+
49
+ def initialize(ns, value, enc=nil)
50
+ @ns = ns
51
+ @value = value
52
+ @enc = enc || ''
53
+ @signature = E.new(@enc)
54
+ end
55
+
56
+ def <=>(other)
57
+ ns_compare = @ns <=> other.ns
58
+ if ns_compare == 0
59
+ @value <=> other.value
60
+ else
61
+ ns_compare
62
+ end
63
+ end
64
+
65
+ def valid?
66
+ return false unless value
67
+ return true unless @ns
68
+ @ns.respond_to?(:values) && ns.values.include?(value)
69
+ end
70
+
71
+ def hash
72
+ [@ns, @value].hash
73
+ end
74
+
75
+ def ==(other)
76
+ return false if other == nil
77
+ @ns == other.ns && @value == other.value
78
+ end
79
+
80
+ alias_method :eql?, :'=='
81
+
82
+ def to_bel
83
+ %Q{#{@ns ? @ns.prefix.to_s + ':' : ''}#{ensure_quotes(@value)}}
84
+ end
85
+
86
+ alias_method :to_s, :to_bel
87
+ end
88
+
89
+ class Function
90
+ attr_reader :short_form, :long_form, :return_type,
91
+ :description, :signatures
92
+
93
+ def initialize args
94
+ args.each do |k,v|
95
+ instance_variable_set("@#{k}", v) unless v.nil?
96
+ end
97
+ end
98
+
99
+ def [](key)
100
+ instance_variable_get("@#{key}")
101
+ end
102
+
103
+ def hash
104
+ [@short_form, @long_form, @return_type, @description, @signatures].hash
105
+ end
106
+
107
+ def ==(other)
108
+ return false if other == nil
109
+ @short_form == other.short_form &&
110
+ @long_form == other.long_form &&
111
+ @return_type == other.return_type &&
112
+ @description == other.description &&
113
+ @signatures == other.signatures
114
+ end
115
+
116
+ alias_method :eql?, :'=='
117
+
118
+ def to_sym
119
+ @short_form
120
+ end
121
+
122
+ def to_s
123
+ @long_form.to_s
124
+ end
125
+ end
126
+
127
+ class Term
128
+ include Comparable
129
+ attr_accessor :fx, :arguments, :signature
130
+
131
+ def initialize(fx, *arguments)
132
+ @fx = case fx
133
+ when String
134
+ when Symbol
135
+ Function.new(FUNCTIONS[fx.to_sym])
136
+ when Function
137
+ fx
138
+ when nil
139
+ raise ArgumentError, 'fx must not be nil'
140
+ end
141
+ @arguments = (arguments ||= []).flatten
142
+ @signature = Signature.new(
143
+ @fx[:short_form],
144
+ *@arguments.map { |arg|
145
+ case arg
146
+ when Term
147
+ F.new(arg.fx.return_type)
148
+ when Parameter
149
+ E.new(arg.enc)
150
+ when nil
151
+ NullE.new
152
+ end
153
+ })
154
+ end
155
+
156
+ def <<(item)
157
+ @arguments << item
158
+ end
159
+
160
+ def valid?
161
+ invalid_signatures = @arguments.find_all { |arg|
162
+ arg.is_a? Term
163
+ }.find_all { |term|
164
+ not term.valid?
165
+ }
166
+ return false if not invalid_signatures.empty?
167
+
168
+ sigs = @fx.signatures
169
+ sigs.any? do |sig| (@signature <=> sig) >= 0 end
170
+ end
171
+
172
+ def valid_signatures
173
+ @fx.signatures.find_all { |sig| (@signature <=> sig) >= 0 }
174
+ end
175
+
176
+ def invalid_signatures
177
+ @fx.signatures.find_all { |sig| (@signature <=> sig) < 0 }
178
+ end
179
+
180
+ def hash
181
+ [@fx, @arguments].hash
182
+ end
183
+
184
+ def ==(other)
185
+ return false if other == nil
186
+ @fx == other.fx && @arguments == other.arguments
187
+ end
188
+
189
+ alias_method :eql?, :'=='
190
+
191
+ def to_bel
192
+ "#{@fx[:short_form]}(#{[@arguments].flatten.map(&:to_bel).join(',')})"
193
+ end
194
+
195
+ alias_method :to_s, :to_bel
196
+ end
197
+
198
+ Annotation = Struct.new(:name, :value) do
199
+ include BEL::Quoting
200
+
201
+ def to_bel
202
+ if self.value.respond_to? :each
203
+ value = self.value.map {|v| always_quote(v)}
204
+ value = "{#{value.join(',')}}"
205
+ else
206
+ value = ensure_quotes(self.value)
207
+ end
208
+ "SET #{self.name} = #{value}"
209
+ end
210
+
211
+ alias_method :to_s, :to_bel
212
+ end
213
+
214
+ UnsetAnnotation = Struct.new(:name) do
215
+ def to_bel
216
+ %Q{UNSET #{self.name}}
217
+ end
218
+
219
+ alias_method :to_s, :to_bel
220
+ end
221
+
222
+ class Statement
223
+ attr_accessor :subject, :relationship, :object, :annotations, :comment
224
+
225
+ def initialize(subject=nil, relationship=nil, object=nil, annotations=[], comment=nil)
226
+ @subject = subject
227
+ @relationship = relationship
228
+ @object = object
229
+ @annotations = annotations
230
+ @comment = comment
231
+ end
232
+
233
+ def subject_only?
234
+ !@relationship
235
+ end
236
+
237
+ def simple?
238
+ @object and @object.is_a? Term
239
+ end
240
+
241
+ def nested?
242
+ @object and @object.is_a? Statement
243
+ end
244
+
245
+ def hash
246
+ [@subject, @relationship, @object, @annotations, @comment].hash
247
+ end
248
+
249
+ def ==(other)
250
+ return false if other == nil
251
+ @subject == other.subject &&
252
+ @relationship == other.relationship &&
253
+ @object == other.object &&
254
+ @annotations == other.annotations &&
255
+ @comment == comment
256
+ end
257
+
258
+ alias_method :eql?, :'=='
259
+
260
+ def to_bel
261
+ lbl = case
262
+ when subject_only?
263
+ @subject.to_s
264
+ when simple?
265
+ "#{@subject.to_s} #{@relationship} #{@object.to_s}"
266
+ when nested?
267
+ "#{@subject.to_s} #{@relationship} (#{@object.to_s})"
268
+ else
269
+ ''
270
+ end
271
+ comment ? lbl + ' //' + comment : lbl
272
+ end
273
+
274
+ alias_method :to_s, :to_bel
275
+ end
276
+
277
+ StatementGroup = Struct.new(:name, :statements, :annotations) do
278
+ include BEL::Quoting
279
+
280
+ def <=>(other_group)
281
+ if not other_group || other_group.is_a?
282
+ 1
283
+ else
284
+ (statements || []) <=> (other_group.statements || [])
285
+ end
286
+ end
287
+
288
+ def to_bel
289
+ %Q{SET STATEMENT_GROUP = #{ensure_quotes(self.name)}}
290
+ end
291
+
292
+ alias_method :to_s, :to_bel
293
+ end
294
+
295
+ UnsetStatementGroup = Struct.new(:name) do
296
+ def to_bel
297
+ %Q{UNSET STATEMENT_GROUP}
298
+ end
299
+
300
+ alias_method :to_s, :to_bel
301
+ end
302
+
303
+ class Signature
304
+ attr_reader :fx, :arguments
305
+ def initialize(fx, *arguments)
306
+ @fx = fx
307
+ @arguments = arguments
308
+
309
+ dup_hash = {}
310
+ @arguments.each_with_index { |arg, i| (dup_hash[arg] ||= []) << i }
311
+ dup_hash.keep_if { |k, v| v.length > 1 }.values.each do |v|
312
+ first_arg = @arguments[v[0]]
313
+ if F === first_arg
314
+ replace_range = (v.first..v.last)
315
+ @arguments[replace_range] = F.new(first_arg.func_return, true)
316
+ end
317
+ end
318
+ end
319
+
320
+ def ==(other)
321
+ return false if other == nil
322
+ @fx == other.fx && @arguments == other.arguments
323
+ end
324
+
325
+ def <=>(other)
326
+ return 1 if other.nil?
327
+ return -1 if @fx != other.fx
328
+ return -1 if @arguments.nil? and not other.nil?
329
+ return 1 if not @arguments.nil? and other.nil?
330
+ @arguments <=> other.arguments
331
+ end
332
+
333
+ def to_s
334
+ return_type = FUNCTIONS[@fx][:return_type]
335
+ "#{@fx}(#{@arguments.map(&:to_s) * ','})#{return_type}"
336
+ end
337
+ end
338
+
339
+ class F
340
+ attr_reader :func_return, :var
341
+ def initialize(func_return, var=false)
342
+ @func_return = func_return
343
+ @var = var
344
+ end
345
+
346
+ def ==(other)
347
+ return false if other == nil
348
+ return false if not other.respond_to? :func_return
349
+ @func_return == other.func_return and @var == other.var
350
+ end
351
+
352
+ alias_method :eql?, :==
353
+
354
+ def hash
355
+ [@func_return, @var].hash
356
+ end
357
+
358
+ def <=>(other)
359
+ return 1 if @var ^ other.var
360
+
361
+ tree = FUNCTION_TYPES[@func_return]
362
+ return -1 if not tree.include?(other.func_return)
363
+ -(tree.index(@func_return) <=> tree.index(other.func_return))
364
+ end
365
+
366
+ def to_s
367
+ "F:#{@func_return}#{'...' if @var}"
368
+ end
369
+ end
370
+
371
+ class E
372
+ attr_reader :encoding, :var
373
+ def initialize(encoding, var=false)
374
+ @encoding = encoding
375
+ @var = var
376
+ end
377
+
378
+ def <=>(other)
379
+ return 1 if @var ^ other.var
380
+
381
+ # compare for equals and wildcard case
382
+ cmp = @encoding <=> other.encoding
383
+ return cmp if cmp.zero? or (@encoding == :* or other.encoding == :*)
384
+
385
+ # compare encoding for assignability; based on array index
386
+ @encoding.to_s.each_char do |enc_char|
387
+ enc_sym = enc_char.to_sym
388
+ tree = PARAMETER_ENCODING[enc_sym]
389
+ next if not tree.include?(other.encoding)
390
+
391
+ match = -(tree.index(enc_sym) <=> tree.index(other.encoding))
392
+ return match if match >= 0
393
+ end
394
+ -1
395
+ end
396
+
397
+ def to_s
398
+ "E:#{@encoding}"
399
+ end
400
+ end
401
+
402
+ class NullE
403
+ def <=>(other)
404
+ return 0 if NullE === other
405
+ -1
406
+ end
407
+
408
+ def to_s
409
+ "E:nil"
410
+ end
411
+ end
412
+
413
+ FUNCTIONS = {
414
+ a: {
415
+ short_form: :a,
416
+ long_form: :abundance,
417
+ description: 'Denotes the abundance of an entity',
418
+ return_type: :a,
419
+ signatures: [
420
+ Signature.new(:a, E.new(:A))
421
+ ]
422
+ },
423
+ bp: {
424
+ short_form: :bp,
425
+ long_form: :biologicalProcess,
426
+ description: 'Denotes a process or population of events',
427
+ return_type: :bp,
428
+ signatures: [
429
+ Signature.new(:bp, E.new(:B))
430
+ ]
431
+ },
432
+ cat: {
433
+ short_form: :cat,
434
+ long_form: :catalyticActivity,
435
+ description: 'Denotes the frequency or abundance of events where a member acts as an enzymatic catalyst of biochecmial reactions',
436
+ return_type: :a,
437
+ signatures: [
438
+ Signature.new(:cat, F.new(:complex)),
439
+ Signature.new(:cat, F.new(:p))
440
+ ]
441
+ },
442
+ sec: {
443
+ short_form: :sec,
444
+ long_form: :cellSecretion,
445
+ description: 'Denotes the frequency or abundance of events in which members of an abundance move from cells to regions outside of the cells',
446
+ return_type: :a,
447
+ signatures: [
448
+ Signature.new(:sec, F.new(:a))
449
+ ]
450
+ },
451
+ surf: {
452
+ short_form: :surf,
453
+ long_form: :cellSurfaceExpression,
454
+ description: 'Denotes the frequency or abundance of events in which members of an abundance move to the surface of cells',
455
+ return_type: :a,
456
+ signatures: [
457
+ Signature.new(:surf, F.new(:a))
458
+ ]
459
+ },
460
+ chap: {
461
+ short_form: :chap,
462
+ long_form: :chaperoneActivity,
463
+ description: 'Denotes the frequency or abundance of events in which a member binds to some substrate and acts as a chaperone for the substrate',
464
+ return_type: :a,
465
+ signatures: [
466
+ Signature.new(:chap, F.new(:complex)),
467
+ Signature.new(:chap, F.new(:p))
468
+ ]
469
+ },
470
+ complex: {
471
+ short_form: :complex,
472
+ long_form: :complexAbundance,
473
+ description: 'Denotes the abundance of a molecular complex',
474
+ return_type: :complex,
475
+ signatures: [
476
+ Signature.new(:complex, E.new(:A)),
477
+ Signature.new(:complex, F.new(:a, true))
478
+ ]
479
+ },
480
+ composite: {
481
+ short_form: :composite,
482
+ long_form: :compositeAbundance,
483
+ description: 'Denotes the frequency or abundance of events in which members are present',
484
+ return_type: :a,
485
+ signatures: [
486
+ Signature.new(:composite, F.new(:a, true))
487
+ ]
488
+ },
489
+ deg: {
490
+ short_form: :deg,
491
+ long_form: :degradation,
492
+ description: 'Denotes the frequency or abundance of events in which a member is degraded in some way such that it is no longer a member',
493
+ return_type: :a,
494
+ signatures: [
495
+ Signature.new(:deg, F.new(:a))
496
+ ]
497
+ },
498
+ fus: {
499
+ short_form: :fus,
500
+ long_form: :fusion,
501
+ description: 'Specifies the abundance of a protein translated from the fusion of a gene',
502
+ return_type: :fus,
503
+ signatures: [
504
+ Signature.new(:fus, E.new(:G)),
505
+ Signature.new(:fus, E.new(:G), E.new(:*), E.new(:*)),
506
+ Signature.new(:fus, E.new(:P)),
507
+ Signature.new(:fus, E.new(:P), E.new(:*), E.new(:*)),
508
+ Signature.new(:fus, E.new(:R)),
509
+ Signature.new(:fus, E.new(:R), E.new(:*), E.new(:*))
510
+ ]
511
+ },
512
+ g: {
513
+ short_form: :g,
514
+ long_form: :geneAbundance,
515
+ description: 'Denotes the abundance of a gene',
516
+ return_type: :g,
517
+ signatures: [
518
+ Signature.new(:g, E.new(:G)),
519
+ Signature.new(:g, E.new(:G), F.new(:fus))
520
+ ]
521
+ },
522
+ gtp: {
523
+ short_form: :gtp,
524
+ long_form: :gtpBoundActivity,
525
+ description: 'Denotes the frequency or abundance of events in which a member of a G-protein abundance is GTP-bound',
526
+ return_type: :a,
527
+ signatures: [
528
+ Signature.new(:gtp, F.new(:complex)),
529
+ Signature.new(:gtp, F.new(:p))
530
+ ]
531
+ },
532
+ kin: {
533
+ short_form: :kin,
534
+ long_form: :kinaseActivity,
535
+ description: 'Denotes the frequency or abundance of events in which a member acts as a kinase, performing enzymatic phosphorylation of a substrate',
536
+ return_type: :a,
537
+ signatures: [
538
+ Signature.new(:kin, F.new(:complex)),
539
+ Signature.new(:kin, F.new(:p))
540
+ ]
541
+ },
542
+ list: {
543
+ short_form: :list,
544
+ long_form: :list,
545
+ description: 'Groups a list of terms together',
546
+ return_type: :list,
547
+ signatures: [
548
+ Signature.new(:list, E.new(:A, true)),
549
+ Signature.new(:list, F.new(:a, true))
550
+ ]
551
+ },
552
+ m: {
553
+ short_form: :m,
554
+ long_form: :microRNAAbundance,
555
+ description: 'Denotes the abundance of a processed, functional microRNA',
556
+ return_type: :m,
557
+ signatures: [
558
+ Signature.new(:m, E.new(:M))
559
+ ]
560
+ },
561
+ act: {
562
+ short_form: :act,
563
+ long_form: :molecularActivity,
564
+ description: 'Denotes the frequency or abundance of events in which a member acts as a causal agent at the molecular scale',
565
+ return_type: :a,
566
+ signatures: [
567
+ Signature.new(:act, F.new(:a))
568
+ ]
569
+ },
570
+ path: {
571
+ short_form: :path,
572
+ long_form: :pathology,
573
+ description: 'Denotes a disease or pathology process',
574
+ return_type: :path,
575
+ signatures: [
576
+ Signature.new(:path, E.new(:O))
577
+ ]
578
+ },
579
+ pep: {
580
+ short_form: :pep,
581
+ long_form: :peptidaseActivity,
582
+ description: 'Denotes the frequency or abundance of events in which a member acts to cleave a protein',
583
+ return_type: :a,
584
+ signatures: [
585
+ Signature.new(:pep, F.new(:complex)),
586
+ Signature.new(:pep, F.new(:p))
587
+ ]
588
+ },
589
+ phos: {
590
+ short_form: :phos,
591
+ long_form: :phosphataseActivity,
592
+ description: 'Denotes the frequency or abundance of events in which a member acts as a phosphatase',
593
+ return_type: :a,
594
+ signatures: [
595
+ Signature.new(:phos, F.new(:complex)),
596
+ Signature.new(:phos, F.new(:p))
597
+ ]
598
+ },
599
+ products: {
600
+ short_form: :products,
601
+ long_form: :products,
602
+ description: 'Denotes the products of a reaction',
603
+ return_type: :products,
604
+ signatures: [
605
+ Signature.new(:products, F.new(:a))
606
+ ]
607
+ },
608
+ p: {
609
+ short_form: :p,
610
+ long_form: :proteinAbundance,
611
+ description: 'Denotes the abundance of a protein',
612
+ return_type: :p,
613
+ signatures: [
614
+ Signature.new(:p, E.new(:P)),
615
+ Signature.new(:p, E.new(:P), F.new(:pmod)),
616
+ Signature.new(:p, E.new(:P), F.new(:sub)),
617
+ Signature.new(:p, E.new(:P), F.new(:fus)),
618
+ Signature.new(:p, E.new(:P), F.new(:trunc))
619
+ ]
620
+ },
621
+ pmod: {
622
+ short_form: :pmod,
623
+ long_form: :proteinModification,
624
+ description: 'Denotes a covalently modified protein abundance',
625
+ return_type: :pmod,
626
+ signatures: [
627
+ Signature.new(:pmod, E.new(:*)),
628
+ Signature.new(:pmod, E.new(:*), E.new(:*)),
629
+ Signature.new(:pmod, E.new(:*), E.new(:*), E.new(:*))
630
+ ]
631
+ },
632
+ reactants: {
633
+ short_form: :reactants,
634
+ long_form: :reactants,
635
+ description: 'Denotes the reactants of a reaction',
636
+ return_type: :reactants,
637
+ signatures: [
638
+ Signature.new(:reactants, F.new(:a))
639
+ ]
640
+ },
641
+ rxn: {
642
+ short_form: :rxn,
643
+ long_form: :reaction,
644
+ description: 'Denotes the frequency or abundance of events in a reaction',
645
+ return_type: :a,
646
+ signatures: [
647
+ Signature.new(:rxn, F.new(:reactants), F.new(:products))
648
+ ]
649
+ },
650
+ ribo: {
651
+ short_form: :ribo,
652
+ long_form: :ribosylationActivity,
653
+ description: 'Denotes the frequency or abundance of events in which a member acts to perform post-translational modification of proteins',
654
+ return_type: :a,
655
+ signatures: [
656
+ Signature.new(:ribo, F.new(:complex)),
657
+ Signature.new(:ribo, F.new(:p))
658
+ ]
659
+ },
660
+ r: {
661
+ short_form: :r,
662
+ long_form: :rnaAbundance,
663
+ description: 'Denotes the abundance of a gene',
664
+ return_type: :g,
665
+ signatures: [
666
+ Signature.new(:r, E.new(:R)),
667
+ Signature.new(:r, E.new(:R), F.new(:fus))
668
+ ]
669
+ },
670
+ sub: {
671
+ short_form: :sub,
672
+ long_form: :substitution,
673
+ description: 'Indicates the abundance of proteins with amino acid substitution sequence',
674
+ return_type: :sub,
675
+ signatures: [
676
+ Signature.new(:sub, E.new(:*), E.new(:*), E.new(:*))
677
+ ]
678
+ },
679
+ tscript: {
680
+ short_form: :tscript,
681
+ long_form: :transcriptionalActivity,
682
+ description: 'Denotes the frequency or abundance of events in which a member directly acts to control transcription of genes',
683
+ return_type: :a,
684
+ signatures: [
685
+ Signature.new(:tscript, F.new(:complex)),
686
+ Signature.new(:tscript, F.new(:p))
687
+ ]
688
+ },
689
+ tloc: {
690
+ short_form: :tloc,
691
+ long_form: :translocation,
692
+ description: 'Denotes the frequency or abundance of events in which members move between locations',
693
+ return_type: :a,
694
+ signatures: [
695
+ Signature.new(:tloc, F.new(:a), E.new(:A), E.new(:A))
696
+ ]
697
+ },
698
+ tport: {
699
+ short_form: :tport,
700
+ long_form: :transportActivity,
701
+ description: 'Denotes the frequency or abundance of events in which a member directs acts to enable the directed movement of substances into, out of, within, or between cells',
702
+ return_type: :a,
703
+ signatures: [
704
+ Signature.new(:tport, F.new(:complex)),
705
+ Signature.new(:tport, F.new(:p))
706
+ ]
707
+ },
708
+ trunc: {
709
+ short_form: :trunc,
710
+ long_form: :truncation,
711
+ description: 'Indicates an abundance of proteins with truncation sequence variants',
712
+ return_type: :trunc,
713
+ signatures: [
714
+ Signature.new(:trunc, E.new(:*))
715
+ ]
716
+ }
717
+ }
718
+ FUNCTIONS.merge!(Hash[*FUNCTIONS.map {|_,v| [v[:long_form], v]}.flatten])
719
+
720
+ PARAMETER_ENCODING = {
721
+ B: [:B],
722
+ O: [:O, :B],
723
+ R: [:R, :A],
724
+ M: [:M, :R, :A],
725
+ P: [:P, :A],
726
+ G: [:G, :A],
727
+ A: [:A],
728
+ C: [:C, :A]
729
+ }
730
+
731
+ FUNCTION_TYPES = {
732
+ a: [:a],
733
+ bp: [:bp],
734
+ complex: [:complex, :a],
735
+ g: [:g, :a],
736
+ m: [:m, :r, :a],
737
+ path: [:path, :bp],
738
+ p: [:p, :a],
739
+ r: [:r, :a]
740
+ }
741
+
742
+ RELATIONSHIPS = [
743
+ :actsIn,
744
+ :analogous,
745
+ :association,
746
+ :biomarkerFor,
747
+ :causesNoChange,
748
+ :decreases,
749
+ :directlyDecreases,
750
+ :directlyIncreases,
751
+ :hasComponent, :hasComponents,
752
+ :hasMember, :hasMembers,
753
+ :hasModification,
754
+ :hasProduct,
755
+ :hasVariant,
756
+ :includes,
757
+ :increases,
758
+ :isA,
759
+ :negativeCorrelation,
760
+ :orthologous,
761
+ :positiveCorrelation,
762
+ :prognosticBiomarkerFor,
763
+ :rateLimitingStepOf,
764
+ :reactantIn,
765
+ :subProcessOf,
766
+ :transcribedTo,
767
+ :translatedTo,
768
+ :translocates
769
+ ]
770
+
771
+ RELATIONSHIPS.each do |rel|
772
+ Term.send(:define_method, rel) do |another|
773
+ s = Statement.new self
774
+ s.relationship = rel
775
+ s.object = another
776
+ s
777
+ end
778
+ end
779
+ FUNCTIONS.each do |fx, metadata|
780
+ func = Function.new(metadata)
781
+ Language.send(:define_method, fx) do |*args|
782
+ Term.new(func, *args)
783
+ end
784
+ Language.send(:define_method, metadata[:long_form]) do |*args|
785
+ Term.new(func, *args)
786
+ end
787
+ end
788
+
789
+ if BEL::Features.rdf_support?
790
+ require_relative 'rdf'
791
+
792
+ class Parameter
793
+ def to_uri
794
+ @ns.to_rdf_vocabulary[@value]
795
+ end
796
+
797
+ def to_rdf
798
+ uri = to_uri
799
+ char_enum = @enc.to_s.each_char
800
+ if block_given?
801
+ char_enum.map {|c| concept_statement(c, uri) }.each do |stmt|
802
+ yield stmt
803
+ end
804
+ else
805
+ char_enum.map { |c| concept_statement(c, uri)}
806
+ end
807
+ end
808
+
809
+ private
810
+ def concept_statement(encoding_character, uri)
811
+ case encoding_character
812
+ when 'G'
813
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.GeneConcept)
814
+ when 'R'
815
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.RNAConcept)
816
+ when 'P'
817
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.ProteinConcept)
818
+ when 'M'
819
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.MicroRNAConcept)
820
+ when 'C'
821
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.ComplexConcept)
822
+ when 'B'
823
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.BiologicalProcessConcept)
824
+ when 'A'
825
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.AbundanceConcept)
826
+ when 'O'
827
+ RUBYRDF::Statement(uri, RUBYRDF.type, BEL::RDF::BELV.PathologyConcept)
828
+ end
829
+ end
830
+ end
831
+
832
+ class Term
833
+ def to_uri
834
+ tid = to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
835
+ BEL::RDF::BELR[tid]
836
+ end
837
+
838
+ def rdf_type
839
+ if respond_to? 'fx'
840
+ if @fx.short_form == :p and @arguments.find{|x| x.is_a? Term and x.fx.short_form == :pmod}
841
+ return BEL::RDF::BELV.ModifiedProteinAbundance
842
+ end
843
+ if @fx.short_form == :p and @arguments.find{|x| x.is_a? Term and BEL::RDF::PROTEIN_VARIANT.include? x.fx}
844
+ return BEL::RDF::BELV.ProteinVariantAbundance
845
+ end
846
+
847
+ BEL::RDF::FUNCTION_TYPE[@fx.short_form] || BEL::RDF::BELV.Abundance
848
+ end
849
+ end
850
+
851
+ def to_rdf
852
+ uri = to_uri
853
+ statements = []
854
+
855
+ # rdf:type
856
+ type = rdf_type
857
+ statements << [uri, BEL::RDF::RDF.type, BEL::RDF::BELV.Term]
858
+ statements << [uri, BEL::RDF::RDF.type, type]
859
+ if BEL::RDF::ACTIVITY_TYPE.include? @fx.short_form
860
+ statements << [uri, BEL::RDF::BELV.hasActivityType, BEL::RDF::ACTIVITY_TYPE[@fx.short_form]]
861
+ end
862
+
863
+ # rdfs:label
864
+ statements << [uri, BEL::RDF::RDFS.label, to_s]
865
+
866
+ # special proteins (does not recurse into pmod)
867
+ if @fx.short_form == :p
868
+ if @arguments.find{|x| x.is_a? Term and x.fx.short_form == :pmod}
869
+ pmod = @arguments.find{|x| x.is_a? Term and x.fx.short_form == :pmod}
870
+ mod_string = pmod.arguments.map(&:to_s).join(',')
871
+ mod_type = BEL::RDF::MODIFICATION_TYPE.find {|k,v| mod_string.start_with? k}
872
+ mod_type = (mod_type ? mod_type[1] : BEL::RDF::BELV.Modification)
873
+ statements << [uri, BEL::RDF::BELV.hasModificationType, mod_type]
874
+ last = pmod.arguments.last.to_s
875
+ if last.match(/^\d+$/)
876
+ statements << [uri, BEL::RDF::BELV.hasModificationPosition, last.to_i]
877
+ end
878
+ # link root protein abundance as hasChild
879
+ root_param = @arguments.find{|x| x.is_a? Parameter}
880
+ (root_id, root_statements) = Term.new(:p, [root_param]).to_rdf
881
+ statements << [uri, BEL::RDF::BELV.hasChild, root_id]
882
+ statements += root_statements
883
+ return [uri, statements]
884
+ elsif @arguments.find{|x| x.is_a? Term and BEL::RDF::PROTEIN_VARIANT.include? x.fx}
885
+ # link root protein abundance as hasChild
886
+ root_param = @arguments.find{|x| x.is_a? Parameter}
887
+ (root_id, root_statements) = Term.new(:p, [root_param]).to_rdf
888
+ statements << [uri, BEL::RDF::BELV.hasChild, root_id]
889
+ statements += root_statements
890
+ return [uri, statements]
891
+ end
892
+ end
893
+
894
+ # BEL::RDF::BELV.hasConcept]
895
+ @arguments.find_all{ |x|
896
+ x.is_a? Parameter and x.ns != nil
897
+ }.each do |param|
898
+ concept_uri = param.ns.to_rdf_vocabulary[param.value.to_s]
899
+ statements << [uri, BEL::RDF::BELV.hasConcept, BEL::RDF::RDF::URI(Addressable::URI.encode(concept_uri))]
900
+ end
901
+
902
+ # BEL::RDF::BELV.hasChild]
903
+ @arguments.find_all{|x| x.is_a? Term}.each do |child|
904
+ (child_id, child_statements) = child.to_rdf
905
+ statements << [uri, BEL::RDF::BELV.hasChild, child_id]
906
+ statements += child_statements
907
+ end
908
+
909
+ return [uri, statements]
910
+ end
911
+ end
912
+
913
+ class Statement
914
+ def to_uri
915
+ case
916
+ when subject_only?
917
+ tid = @subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
918
+ BEL::RDF::BELR[tid]
919
+ when simple?
920
+ sub_id = @subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
921
+ obj_id = @object.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
922
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
923
+ if rel
924
+ rel = rel.path.split('/')[-1]
925
+ else
926
+ rel = @relationship.to_s
927
+ end
928
+ BEL::RDF::BELR["#{sub_id}_#{rel}_#{obj_id}"]
929
+ when nested?
930
+ sub_id = @subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
931
+ nsub_id = @object.subject.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
932
+ nobj_id = @object.object.to_s.squeeze(')').gsub(/[")\[\]]/, '').gsub(/[(:, ]/, '_')
933
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
934
+ if rel
935
+ rel = rel.path.split('/')[-1]
936
+ else
937
+ rel = @relationship.to_s
938
+ end
939
+ nrel = BEL::RDF::RELATIONSHIP_TYPE[@object.relationship.to_s]
940
+ if nrel
941
+ nrel = nrel.path.split('/')[-1]
942
+ else
943
+ nrel = @object.relationship.to_s
944
+ end
945
+ BEL::RDF::BELR["#{sub_id}_#{rel}_#{nsub_id}_#{nrel}_#{nobj_id}"]
946
+ end
947
+ end
948
+
949
+ def to_rdf
950
+ uri = to_uri
951
+ statements = []
952
+
953
+ case
954
+ when subject_only?
955
+ (sub_uri, sub_statements) = @subject.to_rdf
956
+ statements << [uri, BEL::RDF::BELV.hasSubject, sub_uri]
957
+ statements += sub_statements
958
+ when simple?
959
+ (sub_uri, sub_statements) = @subject.to_rdf
960
+ statements += sub_statements
961
+
962
+ (obj_uri, obj_statements) = @object.to_rdf
963
+ statements += obj_statements
964
+
965
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
966
+ statements << [uri, BEL::RDF::BELV.hasSubject, sub_uri]
967
+ statements << [uri, BEL::RDF::BELV.hasObject, obj_uri]
968
+ statements << [uri, BEL::RDF::BELV.hasRelationship, rel]
969
+ when nested?
970
+ (sub_uri, sub_statements) = @subject.to_rdf
971
+ (nsub_uri, nsub_statements) = @object.subject.to_rdf
972
+ (nobj_uri, nobj_statements) = @object.object.to_rdf
973
+ statements += sub_statements
974
+ statements += nsub_statements
975
+ statements += nobj_statements
976
+ rel = BEL::RDF::RELATIONSHIP_TYPE[@relationship.to_s]
977
+ nrel = BEL::RDF::RELATIONSHIP_TYPE[@object.relationship.to_s]
978
+ nuri = BEL::RDF::BELR["#{strip_prefix(nsub_uri)}_#{nrel}_#{strip_prefix(nobj_uri)}"]
979
+
980
+ # inner
981
+ statements << [nuri, BEL::RDF::BELV.hasSubject, nsub_uri]
982
+ statements << [nuri, BEL::RDF::BELV.hasObject, nobj_uri]
983
+ statements << [nuri, BEL::RDF::BELV.hasRelationship, nrel]
984
+
985
+ # outer
986
+ statements << [uri, BEL::RDF::BELV.hasSubject, sub_uri]
987
+ statements << [uri, BEL::RDF::BELV.hasObject, nuri]
988
+ statements << [uri, BEL::RDF::BELV.hasRelationship, rel]
989
+ end
990
+
991
+ # common statement triples
992
+ statements << [uri, BEL::RDF::RDF.type, BEL::RDF::BELV.Statement]
993
+ statements << [uri, RDF::RDFS.label, to_s]
994
+
995
+ # evidence
996
+ evidence_bnode = BEL::RDF::RDF::Node.uuid
997
+ statements << [evidence_bnode, BEL::RDF::RDF.type, BEL::RDF::BELV.Evidence]
998
+ statements << [uri, BEL::RDF::BELV.hasEvidence, evidence_bnode]
999
+ statements << [evidence_bnode, BEL::RDF::BELV.hasStatement, uri]
1000
+
1001
+ # citation
1002
+ citation = @annotations.delete('Citation')
1003
+ if citation
1004
+ value = citation.value.map{|x| x.gsub('"', '')}
1005
+ if citation and value[0] == 'PubMed'
1006
+ pid = value[2]
1007
+ statements << [
1008
+ evidence_bnode,
1009
+ BEL::RDF::BELV.hasCitation,
1010
+ BEL::RDF::RDF::URI(BEL::RDF::PUBMED[pid])
1011
+ ]
1012
+ end
1013
+ end
1014
+
1015
+ # evidence
1016
+ evidence_text = @annotations.delete('Evidence')
1017
+ if evidence_text
1018
+ value = evidence_text.value.gsub('"', '')
1019
+ statements << [evidence_bnode, BEL::RDF::BELV.hasEvidenceText, value]
1020
+ end
1021
+
1022
+ # annotations
1023
+ @annotations.each do |name, anno|
1024
+ name = anno.name.gsub('"', '')
1025
+
1026
+ if BEL::RDF::const_defined? name
1027
+ annotation_scheme = BEL::RDF::const_get name
1028
+ [anno.value].flatten.map{|x| x.gsub('"', '')}.each do |val|
1029
+ value_uri = BEL::RDF::RDF::URI(Addressable::URI.encode(annotation_scheme[val.to_s]))
1030
+ statements << [evidence_bnode, BEL::RDF::BELV.hasAnnotation, value_uri]
1031
+ end
1032
+ end
1033
+ end
1034
+
1035
+ return [uri, statements]
1036
+ end
1037
+
1038
+ private
1039
+
1040
+ def strip_prefix(uri)
1041
+ if uri.to_s.start_with? 'http://www.openbel.org/bel/'
1042
+ uri.to_s[28..-1]
1043
+ else
1044
+ uri
1045
+ end
1046
+ end
1047
+ end
1048
+ end
1049
+ end
1050
+ end
1051
+ # vim: ts=2 sw=2:
1052
+ # encoding: utf-8