bel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/bel.rb +6 -0
- data/lib/bel/grammar/lexer.rb +7498 -0
- data/lib/bel/grammar/parser.rb +5052 -0
- data/lib/bel/language.rb +576 -0
- data/lib/bel/namespace.rb +106 -0
- data/lib/bel/script.rb +184 -0
- metadata +148 -0
data/lib/bel/language.rb
ADDED
@@ -0,0 +1,576 @@
|
|
1
|
+
# vim: ts=2 sw=2:
|
2
|
+
|
3
|
+
module BEL
|
4
|
+
module Language
|
5
|
+
class Signature
|
6
|
+
attr_reader :fx, :arguments
|
7
|
+
def initialize(fx, *arguments)
|
8
|
+
@fx = fx
|
9
|
+
@arguments = arguments
|
10
|
+
|
11
|
+
dup_hash = {}
|
12
|
+
@arguments.each_with_index { |arg, i| (dup_hash[arg] ||= []) << i }
|
13
|
+
dup_hash.keep_if { |k, v| v.length > 1 }.values.each do |v|
|
14
|
+
first_arg = @arguments[v[0]]
|
15
|
+
if F === first_arg
|
16
|
+
replace_range = (v.first..v.last)
|
17
|
+
@arguments[replace_range] = F.new(first_arg.func_return, true)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
return false if @fx != other.fx
|
24
|
+
@arguments == other.arguments
|
25
|
+
end
|
26
|
+
|
27
|
+
def <=>(other)
|
28
|
+
return 1 if other.nil?
|
29
|
+
return -1 if @fx != other.fx
|
30
|
+
return -1 if @arguments.nil? and not other.nil?
|
31
|
+
return 1 if not @arguments.nil? and other.nil?
|
32
|
+
@arguments <=> other.arguments
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
return_type = FUNCTIONS[@fx][:return_type]
|
37
|
+
"#{@fx}(#{@arguments.map(&:to_s) * ','})#{return_type}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class F
|
42
|
+
attr_reader :func_return, :var
|
43
|
+
def initialize(func_return, var=false)
|
44
|
+
@func_return = func_return
|
45
|
+
@var = var
|
46
|
+
end
|
47
|
+
|
48
|
+
def ==(other)
|
49
|
+
return false if not other.respond_to? :func_return
|
50
|
+
|
51
|
+
@func_return == other.func_return and @var == other.var
|
52
|
+
end
|
53
|
+
|
54
|
+
alias_method :eql?, :==
|
55
|
+
|
56
|
+
def hash
|
57
|
+
[@func_return, @var].hash
|
58
|
+
end
|
59
|
+
|
60
|
+
def <=>(other)
|
61
|
+
return 1 if @var ^ other.var
|
62
|
+
|
63
|
+
tree = FUNCTION_TYPES[@func_return]
|
64
|
+
return -1 if not tree.include?(other.func_return)
|
65
|
+
-(tree.index(@func_return) <=> tree.index(other.func_return))
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
"F:#{@func_return}#{'...' if @var}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class E
|
74
|
+
attr_reader :encoding, :var
|
75
|
+
def initialize(encoding, var=false)
|
76
|
+
@encoding = encoding
|
77
|
+
@var = var
|
78
|
+
end
|
79
|
+
|
80
|
+
def <=>(other)
|
81
|
+
return 1 if @var ^ other.var
|
82
|
+
|
83
|
+
# compare for equals and wildcard case
|
84
|
+
cmp = @encoding <=> other.encoding
|
85
|
+
return cmp if cmp.zero? or (@encoding == :* or other.encoding == :*)
|
86
|
+
|
87
|
+
# compare encoding for assignability; based on array index
|
88
|
+
@encoding.to_s.each_char do |enc_char|
|
89
|
+
enc_sym = enc_char.to_sym
|
90
|
+
tree = PARAMETER_ENCODING[enc_sym]
|
91
|
+
next if not tree.include?(other.encoding)
|
92
|
+
|
93
|
+
match = -(tree.index(enc_sym) <=> tree.index(other.encoding))
|
94
|
+
return match if match >= 0
|
95
|
+
end
|
96
|
+
-1
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_s
|
100
|
+
"E:#{@encoding}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class NullE
|
105
|
+
def <=>(other)
|
106
|
+
return 0 if NullE === other
|
107
|
+
-1
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_s
|
111
|
+
"E:nil"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class Parameter
|
116
|
+
include Comparable
|
117
|
+
attr_reader :ns_def, :value, :enc, :signature
|
118
|
+
|
119
|
+
def initialize(ns_def, value, enc)
|
120
|
+
@ns_def = ns_def
|
121
|
+
@value = value
|
122
|
+
@enc = enc || ''
|
123
|
+
@signature = E.new(@enc)
|
124
|
+
end
|
125
|
+
|
126
|
+
def <=>(other)
|
127
|
+
ns_compare = ns_def <=> other.ns_def
|
128
|
+
if ns_compare == 0
|
129
|
+
value <=> other.value
|
130
|
+
else
|
131
|
+
ns_compare
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def to_s
|
136
|
+
value = @value
|
137
|
+
if value =~ %r{\W}
|
138
|
+
value = %Q{"#{value}"}
|
139
|
+
end
|
140
|
+
"#{@ns_def}:#{value}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class Statement
|
145
|
+
attr_accessor :subject, :relationship, :object
|
146
|
+
|
147
|
+
def initialize(subject, relationship=nil, object=nil)
|
148
|
+
raise ArgumentError, 'subject must not be nil' unless subject
|
149
|
+
@subject = subject
|
150
|
+
@relationship = relationship
|
151
|
+
@object = object
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class Function
|
156
|
+
attr_reader :short_form, :long_form, :return_type,
|
157
|
+
:description, :signatures
|
158
|
+
|
159
|
+
def initialize args
|
160
|
+
args.each do |k,v|
|
161
|
+
instance_variable_set("@#{k}", v) unless v.nil?
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Term
|
167
|
+
include Comparable
|
168
|
+
attr_reader :fx, :arguments, :signature
|
169
|
+
|
170
|
+
def initialize(fx, *arguments)
|
171
|
+
@fx = fx
|
172
|
+
@arguments = arguments ||= []
|
173
|
+
@signature = Signature.new(
|
174
|
+
@fx.short_form,
|
175
|
+
*@arguments.map { |arg|
|
176
|
+
case arg
|
177
|
+
when Term
|
178
|
+
F.new(arg.fx.return_type)
|
179
|
+
when Parameter
|
180
|
+
E.new(arg.enc)
|
181
|
+
when nil
|
182
|
+
NullE.new
|
183
|
+
end
|
184
|
+
})
|
185
|
+
end
|
186
|
+
|
187
|
+
def validate_signature
|
188
|
+
invalids = []
|
189
|
+
@arguments.select { |arg| Term === arg }.each do |term|
|
190
|
+
invalids << term if not term.validate_signature
|
191
|
+
end
|
192
|
+
|
193
|
+
sigs = fx.signatures
|
194
|
+
match = sigs.any? do |sig| (@signature <=> sig) >= 0 end
|
195
|
+
invalids << self if not match
|
196
|
+
if block_given? and not invalids.empty?
|
197
|
+
invalids.each do |term|
|
198
|
+
yield term, term.fx.signatures
|
199
|
+
end
|
200
|
+
end
|
201
|
+
invalids.empty?
|
202
|
+
end
|
203
|
+
|
204
|
+
def to_s
|
205
|
+
"#{@fx.short_form}(#{@arguments.map(&:to_s).join(',')})"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
FUNCTIONS = {
|
210
|
+
a: {
|
211
|
+
short_form: :a,
|
212
|
+
long_form: :abundance,
|
213
|
+
description: 'Denotes the abundance of an entity',
|
214
|
+
return_type: :a,
|
215
|
+
signatures: [
|
216
|
+
Signature.new(:a, E.new(:A))
|
217
|
+
]
|
218
|
+
},
|
219
|
+
bp: {
|
220
|
+
short_form: :bp,
|
221
|
+
long_form: :biologicalProcess,
|
222
|
+
description: 'Denotes a process or population of events',
|
223
|
+
return_type: :bp,
|
224
|
+
signatures: [
|
225
|
+
Signature.new(:bp, E.new(:B))
|
226
|
+
]
|
227
|
+
},
|
228
|
+
cat: {
|
229
|
+
short_form: :cat,
|
230
|
+
long_form: :catalyticActivity,
|
231
|
+
description: 'Denotes the frequency or abundance of events where a member acts as an enzymatic catalyst of biochecmial reactions',
|
232
|
+
return_type: :a,
|
233
|
+
signatures: [
|
234
|
+
Signature.new(:cat, F.new(:complex)),
|
235
|
+
Signature.new(:cat, F.new(:p))
|
236
|
+
]
|
237
|
+
},
|
238
|
+
sec: {
|
239
|
+
short_form: :sec,
|
240
|
+
long_form: :cellSecretion,
|
241
|
+
description: 'Denotes the frequency or abundance of events in which members of an abundance move from cells to regions outside of the cells',
|
242
|
+
return_type: :a,
|
243
|
+
signatures: [
|
244
|
+
Signature.new(:sec, F.new(:a))
|
245
|
+
]
|
246
|
+
},
|
247
|
+
surf: {
|
248
|
+
short_form: :surf,
|
249
|
+
long_form: :cellSurfaceExpression,
|
250
|
+
description: 'Denotes the frequency or abundance of events in which members of an abundance move to the surface of cells',
|
251
|
+
return_type: :a,
|
252
|
+
signatures: [
|
253
|
+
Signature.new(:surf, F.new(:a))
|
254
|
+
]
|
255
|
+
},
|
256
|
+
chap: {
|
257
|
+
short_form: :chap,
|
258
|
+
long_form: :chaperoneActivity,
|
259
|
+
description: 'Denotes the frequency or abundance of events in which a member binds to some substrate and acts as a chaperone for the substrate',
|
260
|
+
return_type: :a,
|
261
|
+
signatures: [
|
262
|
+
Signature.new(:chap, F.new(:complex)),
|
263
|
+
Signature.new(:chap, F.new(:p))
|
264
|
+
]
|
265
|
+
},
|
266
|
+
complex: {
|
267
|
+
short_form: :complex,
|
268
|
+
long_form: :complexAbundance,
|
269
|
+
description: 'Denotes the abundance of a molecular complex',
|
270
|
+
return_type: :complex,
|
271
|
+
signatures: [
|
272
|
+
Signature.new(:complex, E.new(:A)),
|
273
|
+
Signature.new(:complex, F.new(:a, true))
|
274
|
+
]
|
275
|
+
},
|
276
|
+
deg: {
|
277
|
+
short_form: :deg,
|
278
|
+
long_form: :degradation,
|
279
|
+
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',
|
280
|
+
return_type: :a,
|
281
|
+
signatures: [
|
282
|
+
Signature.new(:deg, F.new(:a))
|
283
|
+
]
|
284
|
+
},
|
285
|
+
fus: {
|
286
|
+
short_form: :fus,
|
287
|
+
long_form: :fusion,
|
288
|
+
description: 'Specifies the abundance of a protein translated from the fusion of a gene',
|
289
|
+
return_type: :fus,
|
290
|
+
signatures: [
|
291
|
+
Signature.new(:fus, E.new(:G)),
|
292
|
+
Signature.new(:fus, E.new(:G), E.new(:*), E.new(:*)),
|
293
|
+
Signature.new(:fus, E.new(:P)),
|
294
|
+
Signature.new(:fus, E.new(:P), E.new(:*), E.new(:*)),
|
295
|
+
Signature.new(:fus, E.new(:R)),
|
296
|
+
Signature.new(:fus, E.new(:R), E.new(:*), E.new(:*))
|
297
|
+
]
|
298
|
+
},
|
299
|
+
g: {
|
300
|
+
short_form: :g,
|
301
|
+
long_form: :geneAbundance,
|
302
|
+
description: 'Denotes the abundance of a gene',
|
303
|
+
return_type: :g,
|
304
|
+
signatures: [
|
305
|
+
Signature.new(:g, E.new(:G)),
|
306
|
+
Signature.new(:g, E.new(:G), F.new(:fus))
|
307
|
+
]
|
308
|
+
},
|
309
|
+
gtp: {
|
310
|
+
short_form: :gtp,
|
311
|
+
long_form: :gtpBoundActivity,
|
312
|
+
description: 'Denotes the frequency or abundance of events in which a member of a G-protein abundance is GTP-bound',
|
313
|
+
return_type: :a,
|
314
|
+
signatures: [
|
315
|
+
Signature.new(:gtp, F.new(:complex)),
|
316
|
+
Signature.new(:gtp, F.new(:p))
|
317
|
+
]
|
318
|
+
},
|
319
|
+
kin: {
|
320
|
+
short_form: :kin,
|
321
|
+
long_form: :kinaseActivity,
|
322
|
+
description: 'Denotes the frequency or abundance of events in which a member acts as a kinase, performing enzymatic phosphorylation of a substrate',
|
323
|
+
return_type: :a,
|
324
|
+
signatures: [
|
325
|
+
Signature.new(:kin, F.new(:complex)),
|
326
|
+
Signature.new(:kin, F.new(:p))
|
327
|
+
]
|
328
|
+
},
|
329
|
+
list: {
|
330
|
+
short_form: :list,
|
331
|
+
long_form: :list,
|
332
|
+
description: 'Groups a list of terms together',
|
333
|
+
return_type: :list,
|
334
|
+
signatures: [
|
335
|
+
Signature.new(:list, E.new(:A, true)),
|
336
|
+
Signature.new(:list, F.new(:a, true))
|
337
|
+
]
|
338
|
+
},
|
339
|
+
m: {
|
340
|
+
short_form: :m,
|
341
|
+
long_form: :microRNAAbundance,
|
342
|
+
description: 'Denotes the abundance of a processed, functional microRNA',
|
343
|
+
return_type: :m,
|
344
|
+
signatures: [
|
345
|
+
Signature.new(:m, E.new(:M))
|
346
|
+
]
|
347
|
+
},
|
348
|
+
act: {
|
349
|
+
short_form: :act,
|
350
|
+
long_form: :molecularActivity,
|
351
|
+
description: 'Denotes the frequency or abundance of events in which a member acts as a causal agent at the molecular scale',
|
352
|
+
return_type: :a,
|
353
|
+
signatures: [
|
354
|
+
Signature.new(:act, F.new(:a))
|
355
|
+
]
|
356
|
+
},
|
357
|
+
path: {
|
358
|
+
short_form: :path,
|
359
|
+
long_form: :pathology,
|
360
|
+
description: 'Denotes a disease or pathology process',
|
361
|
+
return_type: :path,
|
362
|
+
signatures: [
|
363
|
+
Signature.new(:path, E.new(:O))
|
364
|
+
]
|
365
|
+
},
|
366
|
+
pep: {
|
367
|
+
short_form: :pep,
|
368
|
+
long_form: :peptidaseActivity,
|
369
|
+
description: 'Denotes the frequency or abundance of events in which a member acts to cleave a protein',
|
370
|
+
return_type: :a,
|
371
|
+
signatures: [
|
372
|
+
Signature.new(:pep, F.new(:complex)),
|
373
|
+
Signature.new(:pep, F.new(:p))
|
374
|
+
]
|
375
|
+
},
|
376
|
+
phos: {
|
377
|
+
short_form: :phos,
|
378
|
+
long_form: :phosphataseActivity,
|
379
|
+
description: 'Denotes the frequency or abundance of events in which a member acts as a phosphatase',
|
380
|
+
return_type: :a,
|
381
|
+
signatures: [
|
382
|
+
Signature.new(:phos, F.new(:complex)),
|
383
|
+
Signature.new(:phos, F.new(:p))
|
384
|
+
]
|
385
|
+
},
|
386
|
+
products: {
|
387
|
+
short_form: :products,
|
388
|
+
long_form: :products,
|
389
|
+
description: 'Denotes the products of a reaction',
|
390
|
+
return_type: :products,
|
391
|
+
signatures: [
|
392
|
+
Signature.new(:products, F.new(:a))
|
393
|
+
]
|
394
|
+
},
|
395
|
+
p: {
|
396
|
+
short_form: :p,
|
397
|
+
long_form: :proteinAbundance,
|
398
|
+
description: 'Denotes the abundance of a protein',
|
399
|
+
return_type: :p,
|
400
|
+
signatures: [
|
401
|
+
Signature.new(:p, E.new(:P)),
|
402
|
+
Signature.new(:p, E.new(:P), F.new(:pmod)),
|
403
|
+
Signature.new(:p, E.new(:P), F.new(:sub)),
|
404
|
+
Signature.new(:p, E.new(:P), F.new(:fus)),
|
405
|
+
Signature.new(:p, E.new(:P), F.new(:trunc))
|
406
|
+
]
|
407
|
+
},
|
408
|
+
pmod: {
|
409
|
+
short_form: :pmod,
|
410
|
+
long_form: :proteinModification,
|
411
|
+
description: 'Denotes a covalently modified protein abundance',
|
412
|
+
return_type: :pmod,
|
413
|
+
signatures: [
|
414
|
+
Signature.new(:pmod, E.new(:*)),
|
415
|
+
Signature.new(:pmod, E.new(:*), E.new(:*)),
|
416
|
+
Signature.new(:pmod, E.new(:*), E.new(:*), E.new(:*))
|
417
|
+
]
|
418
|
+
},
|
419
|
+
reactants: {
|
420
|
+
short_form: :reactants,
|
421
|
+
long_form: :reactants,
|
422
|
+
description: 'Denotes the reactants of a reaction',
|
423
|
+
return_type: :reactants,
|
424
|
+
signatures: [
|
425
|
+
Signature.new(:reactants, F.new(:a))
|
426
|
+
]
|
427
|
+
},
|
428
|
+
rxn: {
|
429
|
+
short_form: :rxn,
|
430
|
+
long_form: :reaction,
|
431
|
+
description: 'Denotes the frequency or abundance of events in a reaction',
|
432
|
+
return_type: :a,
|
433
|
+
signatures: [
|
434
|
+
Signature.new(:rxn, F.new(:reactants), F.new(:products))
|
435
|
+
]
|
436
|
+
},
|
437
|
+
ribo: {
|
438
|
+
short_form: :ribo,
|
439
|
+
long_form: :ribosylationActivity,
|
440
|
+
description: 'Denotes the frequency or abundance of events in which a member acts to perform post-translational modification of proteins',
|
441
|
+
return_type: :a,
|
442
|
+
signatures: [
|
443
|
+
Signature.new(:ribo, F.new(:complex)),
|
444
|
+
Signature.new(:ribo, F.new(:p))
|
445
|
+
]
|
446
|
+
},
|
447
|
+
r: {
|
448
|
+
short_form: :r,
|
449
|
+
long_form: :rnaAbundance,
|
450
|
+
description: 'Denotes the abundance of a gene',
|
451
|
+
return_type: :g,
|
452
|
+
signatures: [
|
453
|
+
Signature.new(:r, E.new(:R)),
|
454
|
+
Signature.new(:r, E.new(:R), F.new(:fus))
|
455
|
+
]
|
456
|
+
},
|
457
|
+
sub: {
|
458
|
+
short_form: :sub,
|
459
|
+
long_form: :substitution,
|
460
|
+
description: 'Indicates the abundance of proteins with amino acid substitution sequence',
|
461
|
+
return_type: :sub,
|
462
|
+
signatures: [
|
463
|
+
Signature.new(:sub, E.new(:*), E.new(:*), E.new(:*))
|
464
|
+
]
|
465
|
+
},
|
466
|
+
tscript: {
|
467
|
+
short_form: :tscript,
|
468
|
+
long_form: :transcriptionalActivity,
|
469
|
+
description: 'Denotes the frequency or abundance of events in which a member directly acts to control transcription of genes',
|
470
|
+
return_type: :a,
|
471
|
+
signatures: [
|
472
|
+
Signature.new(:tscript, F.new(:complex)),
|
473
|
+
Signature.new(:tscript, F.new(:p))
|
474
|
+
]
|
475
|
+
},
|
476
|
+
tloc: {
|
477
|
+
short_form: :tloc,
|
478
|
+
long_form: :translocation,
|
479
|
+
description: 'Denotes the frequency or abundance of events in which members move between locations',
|
480
|
+
return_type: :a,
|
481
|
+
signatures: [
|
482
|
+
Signature.new(:tloc, F.new(:a), E.new(:A), E.new(:A))
|
483
|
+
]
|
484
|
+
},
|
485
|
+
tport: {
|
486
|
+
short_form: :tport,
|
487
|
+
long_form: :transportActivity,
|
488
|
+
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',
|
489
|
+
return_type: :a,
|
490
|
+
signatures: [
|
491
|
+
Signature.new(:tport, F.new(:complex)),
|
492
|
+
Signature.new(:tport, F.new(:p))
|
493
|
+
]
|
494
|
+
},
|
495
|
+
trunc: {
|
496
|
+
short_form: :trunc,
|
497
|
+
long_form: :truncation,
|
498
|
+
description: 'Indicates an abundance of proteins with truncation sequence variants',
|
499
|
+
return_type: :trunc,
|
500
|
+
signatures: [
|
501
|
+
Signature.new(:trunc, E.new(:*))
|
502
|
+
]
|
503
|
+
}
|
504
|
+
}
|
505
|
+
FUNCTIONS.merge!(Hash[*FUNCTIONS.map {|_,v| [v[:long_form], v]}.flatten])
|
506
|
+
|
507
|
+
PARAMETER_ENCODING = {
|
508
|
+
B: [:B],
|
509
|
+
O: [:O, :B],
|
510
|
+
R: [:R, :A],
|
511
|
+
M: [:M, :R, :A],
|
512
|
+
P: [:P, :A],
|
513
|
+
G: [:G, :A],
|
514
|
+
A: [:A],
|
515
|
+
C: [:C, :A]
|
516
|
+
}
|
517
|
+
|
518
|
+
FUNCTION_TYPES = {
|
519
|
+
a: [:a],
|
520
|
+
bp: [:bp],
|
521
|
+
complex: [:complex, :a],
|
522
|
+
g: [:g, :a],
|
523
|
+
m: [:m, :r, :a],
|
524
|
+
path: [:path, :bp],
|
525
|
+
p: [:p, :a],
|
526
|
+
r: [:r, :a]
|
527
|
+
}
|
528
|
+
|
529
|
+
RELATIONSHIPS = [
|
530
|
+
:actsIn,
|
531
|
+
:analogous,
|
532
|
+
:association,
|
533
|
+
:biomarkerFor,
|
534
|
+
:causesNoChange,
|
535
|
+
:decreases,
|
536
|
+
:directlyDecreases,
|
537
|
+
:directlyIncreases,
|
538
|
+
:hasComponent, :hasComponents,
|
539
|
+
:hasMember, :hasMembers,
|
540
|
+
:hasModification,
|
541
|
+
:hasProduct,
|
542
|
+
:hasVariant,
|
543
|
+
:includes,
|
544
|
+
:increases,
|
545
|
+
:isA,
|
546
|
+
:negativeCorrelation,
|
547
|
+
:orthologous,
|
548
|
+
:positiveCorrelation,
|
549
|
+
:prognosticBiomarkerFor,
|
550
|
+
:rateLimitingStepOf,
|
551
|
+
:reactantIn,
|
552
|
+
:subProcessOf,
|
553
|
+
:transcribedTo,
|
554
|
+
:translatedTo,
|
555
|
+
:translocates
|
556
|
+
]
|
557
|
+
|
558
|
+
RELATIONSHIPS.each do |rel|
|
559
|
+
Term.send(:define_method, rel) do |another|
|
560
|
+
s = Statement.new self
|
561
|
+
s.relationship = rel
|
562
|
+
s.object = another
|
563
|
+
s
|
564
|
+
end
|
565
|
+
end
|
566
|
+
FUNCTIONS.each do |fx, metadata|
|
567
|
+
func = Function.new(metadata)
|
568
|
+
Language.send(:define_method, fx) do |*args|
|
569
|
+
Term.new(func, *args)
|
570
|
+
end
|
571
|
+
Language.send(:define_method, metadata[:long_form]) do |*args|
|
572
|
+
Term.new(func, *args)
|
573
|
+
end
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|