bel 0.3.0.beta1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -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')
data/ext/mri/libbel.c ADDED
@@ -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
data/lib/bel.rb ADDED
@@ -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