bel 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +4 -2
- data/bin/bel +60 -3
- data/lib/bel/completion_rule.rb +2 -2
- data/lib/bel/evidence_model.rb +5 -0
- data/lib/bel/evidence_model/bel_parameter.rb +1 -6
- data/lib/bel/evidence_model/buffering_evidence_combiner.rb +182 -0
- data/lib/bel/evidence_model/evidence.rb +21 -0
- data/lib/bel/evidence_model/hash_map_references.rb +33 -0
- data/lib/bel/evidence_model/map_references.rb +30 -0
- data/lib/bel/evidence_model/map_references_combiner.rb +30 -0
- data/lib/bel/evidence_model/streaming_evidence_combiner.rb +37 -0
- data/lib/bel/evidence_model/util.rb +84 -0
- data/lib/bel/gen.rb +7 -3
- data/lib/bel/gen/annotation.rb +5 -2
- data/lib/bel/gen/evidence.rb +10 -4
- data/lib/bel/gen/namespace.rb +37 -0
- data/lib/bel/gen/parameter.rb +71 -0
- data/lib/bel/gen/sample_resources.rb +52 -0
- data/lib/bel/gen/statement.rb +33 -0
- data/lib/bel/gen/term.rb +33 -0
- data/lib/bel/language.rb +4 -4
- data/lib/bel/libbel/library_resolver.rb +1 -1
- data/lib/bel/namespace.rb +3 -3
- data/lib/bel/quoting.rb +218 -14
- data/lib/bel/translator.rb +11 -3
- data/lib/bel/translator/plugins/bel_script/bel_citation_serialization.rb +2 -2
- data/lib/bel/translator/plugins/bel_script/bel_discrete_serialization.rb +1 -1
- data/lib/bel/translator/plugins/bel_script/bel_yielder.rb +32 -21
- data/lib/bel/translator/plugins/bel_script/evidence_serialization.rb +11 -10
- data/lib/bel/translator/plugins/bel_script/evidence_yielder.rb +2 -2
- data/lib/bel/translator/plugins/bel_script/translator.rb +1 -1
- data/lib/bel/translator/plugins/json_evidence/translator.rb +5 -1
- data/lib/bel/translator/plugins/rdf/monkey_patch.rb +4 -0
- data/lib/bel/translator/plugins/xbel/evidence_handler.rb +23 -12
- data/lib/bel/translator/plugins/xbel/evidence_yielder.rb +1 -1
- data/lib/bel/translator/plugins/xbel/translator.rb +4 -4
- data/lib/bel/translator/plugins/xbel/xbel_yielder.rb +24 -7
- data/lib/bel/util.rb +55 -21
- data/lib/bel/version.rb +1 -1
- metadata +13 -3
- data/lib/bel/gen/bel_expression.rb +0 -128
@@ -60,19 +60,20 @@ module BEL::Translator::Plugins::BelScript::EvidenceSerialization
|
|
60
60
|
|
61
61
|
Hash[
|
62
62
|
experiment_context.
|
63
|
-
sort_by { |obj| obj[:name] }.
|
63
|
+
sort_by { |obj| obj[:name].to_sym }.
|
64
64
|
map { |obj|
|
65
|
-
|
65
|
+
name = obj[:name].to_sym
|
66
|
+
value = obj[:value]
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
value_s =
|
69
|
+
if value.respond_to? :map
|
70
|
+
"{#{value.map { |v| quote(v) }.join(', ')}}"
|
71
|
+
else
|
72
|
+
quote(value)
|
73
|
+
end
|
73
74
|
|
74
|
-
|
75
|
-
|
75
|
+
[name, value_s]
|
76
|
+
}
|
76
77
|
]
|
77
78
|
end
|
78
79
|
end
|
@@ -13,7 +13,7 @@ module BEL::Translator::Plugins
|
|
13
13
|
'Evidence' => true,
|
14
14
|
}
|
15
15
|
|
16
|
-
def initialize(data)
|
16
|
+
def initialize(data, options = {})
|
17
17
|
@data = data
|
18
18
|
@references = References.new
|
19
19
|
@metadata = Metadata.new
|
@@ -53,7 +53,7 @@ module BEL::Translator::Plugins
|
|
53
53
|
if fields.respond_to? :each
|
54
54
|
evidence.citation = Citation.new(
|
55
55
|
fields.map { |field|
|
56
|
-
|
56
|
+
unquote(field)
|
57
57
|
}.to_a
|
58
58
|
)
|
59
59
|
end
|
@@ -72,7 +72,7 @@ module BEL::Translator::Plugins
|
|
72
72
|
EVIDENCE_ROOT => {
|
73
73
|
:bel_statement => hash[:bel_statement].to_s,
|
74
74
|
:citation => hash[:citation],
|
75
|
-
:summary_text => hash[:summary_text],
|
75
|
+
:summary_text => escape_newlines(hash[:summary_text]),
|
76
76
|
:experiment_context => hash[:experiment_context],
|
77
77
|
:references => hash[:references],
|
78
78
|
:metadata => hash[:metadata].to_a
|
@@ -101,6 +101,10 @@ module BEL::Translator::Plugins
|
|
101
101
|
obj.is_a? ::BEL::Model::Statement
|
102
102
|
}.first
|
103
103
|
end
|
104
|
+
|
105
|
+
def escape_newlines(value)
|
106
|
+
value.gsub(/\n/, "\\n").gsub(/\r/, "\\r")
|
107
|
+
end
|
104
108
|
end
|
105
109
|
end
|
106
110
|
end
|
@@ -34,6 +34,10 @@ module BELRDF
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def to_rdf(graph_name = nil)
|
37
|
+
# resolve encoding to make rdf:type assertions
|
38
|
+
if !@enc && @ns.is_a?(BEL::Namespace::NamespaceDefinition)
|
39
|
+
@enc = @ns[@value].enc
|
40
|
+
end
|
37
41
|
uri = to_uri
|
38
42
|
encodings = ['A'].concat(@enc.to_s.each_char.to_a).uniq
|
39
43
|
encodings.map! { |enc| concept_statement(enc, uri, graph_name)}
|
@@ -193,19 +193,10 @@ module BEL::Translator::Plugins
|
|
193
193
|
|
194
194
|
def start_parameter(attributes)
|
195
195
|
if stack_top == :term
|
196
|
-
ns_id = attr_value(attributes, NS)
|
197
|
-
# XXX Hitting a SystemStackError on line 174 (inside call).
|
198
|
-
# Example: large_corpus.xbel
|
199
|
-
ns_sym = ns_id.to_sym
|
200
|
-
namespace_reference = @evidence.references.namespaces.find { |ns|
|
201
|
-
ns[:keyword] == ns_sym
|
202
|
-
}
|
203
196
|
ns =
|
204
|
-
if
|
205
|
-
|
206
|
-
|
207
|
-
:url => namespace_reference[:uri]
|
208
|
-
}
|
197
|
+
if has_attr?(attributes, NS)
|
198
|
+
ns_id = attr_value(attributes, NS)
|
199
|
+
namespace_reference(ns_id, @evidence)
|
209
200
|
else
|
210
201
|
nil
|
211
202
|
end
|
@@ -479,6 +470,26 @@ module BEL::Translator::Plugins
|
|
479
470
|
def attr_value(attributes, attr_name)
|
480
471
|
attributes["bel:#{attr_name}"]
|
481
472
|
end
|
473
|
+
|
474
|
+
def has_attr?(attributes, attr_name)
|
475
|
+
attributes.has_key?("bel:#{attr_name}")
|
476
|
+
end
|
477
|
+
|
478
|
+
def namespace_reference(ns_id, evidence)
|
479
|
+
ns_id = ns_id.to_sym
|
480
|
+
namespace_reference = evidence.references.namespaces.find { |ns|
|
481
|
+
ns[:keyword] == ns_id
|
482
|
+
}
|
483
|
+
|
484
|
+
if namespace_reference
|
485
|
+
{
|
486
|
+
:prefix => namespace_reference[:keyword],
|
487
|
+
:url => namespace_reference[:uri]
|
488
|
+
}
|
489
|
+
else
|
490
|
+
nil
|
491
|
+
end
|
492
|
+
end
|
482
493
|
end
|
483
494
|
end
|
484
495
|
end
|
@@ -10,23 +10,23 @@ module BEL::Translator::Plugins
|
|
10
10
|
include ::BEL::Translator
|
11
11
|
|
12
12
|
def read(data, options = {})
|
13
|
-
EvidenceYielder.new(data)
|
13
|
+
EvidenceYielder.new(data, options)
|
14
14
|
end
|
15
15
|
|
16
16
|
def write(objects, writer = StringIO.new, options = {})
|
17
17
|
if block_given?
|
18
|
-
XBELYielder.new(objects).each { |xml_data|
|
18
|
+
XBELYielder.new(objects, options).each { |xml_data|
|
19
19
|
yield xml_data
|
20
20
|
}
|
21
21
|
else
|
22
22
|
if writer
|
23
|
-
XBELYielder.new(objects).each { |xml_data|
|
23
|
+
XBELYielder.new(objects, options).each { |xml_data|
|
24
24
|
writer << xml_data
|
25
25
|
writer.flush
|
26
26
|
}
|
27
27
|
writer
|
28
28
|
else
|
29
|
-
XBELYielder.new(objects)
|
29
|
+
XBELYielder.new(objects, options)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -10,11 +10,28 @@ module BEL::Translator::Plugins
|
|
10
10
|
FUNCTIONS = ::BEL::Language::FUNCTIONS
|
11
11
|
|
12
12
|
def initialize(data, options = {})
|
13
|
-
@data
|
13
|
+
@data = data
|
14
|
+
@annotation_reference_map = options.fetch(:annotation_reference_map, nil)
|
15
|
+
@namespace_reference_map = options.fetch(:namespace_reference_map, nil)
|
14
16
|
end
|
15
17
|
|
16
18
|
def each
|
17
19
|
if block_given?
|
20
|
+
combiner =
|
21
|
+
if @streaming
|
22
|
+
BEL::Model::StreamingEvidenceCombiner.new(@data)
|
23
|
+
elsif @annotation_reference_map && @namespace_reference_map
|
24
|
+
BEL::Model::MapReferencesCombiner.new(
|
25
|
+
@data,
|
26
|
+
BEL::Model::HashMapReferences.new(
|
27
|
+
@annotation_reference_map,
|
28
|
+
@namespace_reference_map
|
29
|
+
)
|
30
|
+
)
|
31
|
+
else
|
32
|
+
BEL::Model::BufferingEvidenceCombiner.new(@data)
|
33
|
+
end
|
34
|
+
|
18
35
|
header_flag = true
|
19
36
|
|
20
37
|
# yield <document>
|
@@ -23,7 +40,7 @@ module BEL::Translator::Plugins
|
|
23
40
|
|
24
41
|
el_statement_group = nil
|
25
42
|
evidence_count = 0
|
26
|
-
|
43
|
+
combiner.each { |evidence|
|
27
44
|
if header_flag
|
28
45
|
# document header
|
29
46
|
el_statement_group = XBELYielder.statement_group
|
@@ -32,10 +49,10 @@ module BEL::Translator::Plugins
|
|
32
49
|
XBELYielder.header(evidence.metadata.document_header)
|
33
50
|
)
|
34
51
|
yield element_string(
|
35
|
-
XBELYielder.namespace_definitions(
|
52
|
+
XBELYielder.namespace_definitions(combiner.namespace_references)
|
36
53
|
)
|
37
54
|
yield element_string(
|
38
|
-
XBELYielder.annotation_definitions(
|
55
|
+
XBELYielder.annotation_definitions(combiner.annotation_references)
|
39
56
|
)
|
40
57
|
|
41
58
|
yield start_element_string(el_statement_group)
|
@@ -330,11 +347,11 @@ module BEL::Translator::Plugins
|
|
330
347
|
def self.namespace_definitions(list)
|
331
348
|
el_nd = REXML::Element.new('bel:namespaceGroup')
|
332
349
|
list.each do |namespace|
|
333
|
-
keyword, uri
|
334
|
-
el
|
350
|
+
keyword, uri = namespace.values_at(:keyword, :uri).map(&:to_s)
|
351
|
+
el = REXML::Element.new('bel:namespace')
|
352
|
+
|
335
353
|
el.add_attribute 'bel:prefix', keyword
|
336
354
|
el.add_attribute 'bel:resourceLocation', uri
|
337
|
-
|
338
355
|
el_nd.add_element(el)
|
339
356
|
end
|
340
357
|
|
data/lib/bel/util.rb
CHANGED
@@ -19,28 +19,33 @@ module BEL
|
|
19
19
|
# (e.g. lung disease|O) and a database value identifier for a BEL annotation
|
20
20
|
# file (e.g. lung|UBERON_0002048).
|
21
21
|
def self.read_resource(url)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
22
|
+
@@url_content_cache ||= {}
|
23
|
+
@@url_content_cache.fetch(url) {
|
24
|
+
resource_lines = BEL::read_lines(url)
|
25
|
+
|
26
|
+
# Drop until the delimiter line and extract the delimiter, e.g.
|
27
|
+
# DelimiterString=|
|
28
|
+
delimiter_line = resource_lines.take(100).find { |l| l.start_with?("DelimiterString") }
|
29
|
+
delimiter =
|
30
|
+
if delimiter_line
|
31
|
+
delimiter_line.strip.split('=')[1]
|
32
|
+
else
|
33
|
+
DEFAULT_RESOURCE_VALUE_DELIMITER
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
# Extract resource values based on the delimiter.
|
37
|
+
resource_values = Hash[
|
38
|
+
resource_lines.
|
39
|
+
drop_while { |l| !l.start_with?("[Values]") }.
|
40
|
+
drop(1).
|
41
|
+
map { |s|
|
42
|
+
val_enc = s.strip!.split(delimiter).map(&:to_sym)
|
43
|
+
val_enc[0..1]
|
44
|
+
}
|
45
|
+
]
|
46
|
+
@@url_content_cache[url] = resource_values
|
47
|
+
resource_values
|
48
|
+
}
|
44
49
|
end
|
45
50
|
|
46
51
|
def self.read_all(reference, options = {})
|
@@ -76,6 +81,35 @@ module BEL
|
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
84
|
+
def self.keys_to_symbols(obj)
|
85
|
+
self.object_convert(:key, obj) { |key| key.to_sym }
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.object_convert(type, source, &block)
|
89
|
+
case source
|
90
|
+
when Array
|
91
|
+
source.inject([]) { |new, v|
|
92
|
+
new << object_convert(type, v, &block)
|
93
|
+
new
|
94
|
+
}
|
95
|
+
when Hash
|
96
|
+
source.inject({}) { |new, (k,v)|
|
97
|
+
if type == :key || k.is_a?(type)
|
98
|
+
k = block.call(k)
|
99
|
+
end
|
100
|
+
|
101
|
+
new[k] = object_convert(type, v, &block)
|
102
|
+
new
|
103
|
+
}
|
104
|
+
else
|
105
|
+
if type != :key && source.is_a?(type)
|
106
|
+
block.call(source)
|
107
|
+
else
|
108
|
+
source
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
79
113
|
# PRIVATE
|
80
114
|
|
81
115
|
def self.multi_open(reference, options = {})
|
data/lib/bel/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Bargnesi
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2016-
|
14
|
+
date: 2016-03-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: ffi
|
@@ -82,18 +82,28 @@ files:
|
|
82
82
|
- lib/bel/evidence_model/bel_parameter.rb
|
83
83
|
- lib/bel/evidence_model/bel_statement.rb
|
84
84
|
- lib/bel/evidence_model/bel_term.rb
|
85
|
+
- lib/bel/evidence_model/buffering_evidence_combiner.rb
|
85
86
|
- lib/bel/evidence_model/citation.rb
|
86
87
|
- lib/bel/evidence_model/evidence.rb
|
87
88
|
- lib/bel/evidence_model/experiment_context.rb
|
89
|
+
- lib/bel/evidence_model/hash_map_references.rb
|
90
|
+
- lib/bel/evidence_model/map_references.rb
|
91
|
+
- lib/bel/evidence_model/map_references_combiner.rb
|
88
92
|
- lib/bel/evidence_model/metadata.rb
|
89
93
|
- lib/bel/evidence_model/references.rb
|
94
|
+
- lib/bel/evidence_model/streaming_evidence_combiner.rb
|
90
95
|
- lib/bel/evidence_model/summary_text.rb
|
96
|
+
- lib/bel/evidence_model/util.rb
|
91
97
|
- lib/bel/gen.rb
|
92
98
|
- lib/bel/gen/annotation.rb
|
93
|
-
- lib/bel/gen/bel_expression.rb
|
94
99
|
- lib/bel/gen/citation.rb
|
95
100
|
- lib/bel/gen/document_header.rb
|
96
101
|
- lib/bel/gen/evidence.rb
|
102
|
+
- lib/bel/gen/namespace.rb
|
103
|
+
- lib/bel/gen/parameter.rb
|
104
|
+
- lib/bel/gen/sample_resources.rb
|
105
|
+
- lib/bel/gen/statement.rb
|
106
|
+
- lib/bel/gen/term.rb
|
97
107
|
- lib/bel/json.rb
|
98
108
|
- lib/bel/json/adapter/multi_json.rb
|
99
109
|
- lib/bel/json/adapter/oj.rb
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'bel'
|
2
|
-
require_relative '../gen'
|
3
|
-
BEL::Gen.soft_require('rantly')
|
4
|
-
|
5
|
-
module BEL
|
6
|
-
module Gen
|
7
|
-
|
8
|
-
# The {Expression} module defines methods that generate random BEL
|
9
|
-
# {BEL::Model::Parameter parameters}, {BEL::Model::Term terms}, and
|
10
|
-
# {BEL::Model::Statement statements}.
|
11
|
-
module Expression
|
12
|
-
include BEL::Quoting
|
13
|
-
|
14
|
-
# Array of the latest OpenBEL {BEL::Namespace::NamespaceDefinition}.
|
15
|
-
NAMESPACES = BEL::Namespace::NAMESPACE_LATEST.map { |prefix, (url, rdf_uri)|
|
16
|
-
BEL::Namespace::NamespaceDefinition.new(prefix, url, rdf_uri)
|
17
|
-
}
|
18
|
-
|
19
|
-
# Array of all BEL 1.0 functions including both short and long form.
|
20
|
-
FUNCTIONS = BEL::Language::FUNCTIONS.map { |_, fx|
|
21
|
-
[ fx[:short_form], fx[:long_form] ]
|
22
|
-
}.flatten.sort.uniq
|
23
|
-
|
24
|
-
# Array of all BEL 1.0 relationships including both short and long form.
|
25
|
-
RELATIONSHIPS = BEL::Language::RELATIONSHIPS.each.to_a.flatten.sort.uniq
|
26
|
-
|
27
|
-
# Retrieve the namespaces chosen during use of {#namespace}.
|
28
|
-
# @return [Hash] hash of namespace prefix => {BEL::Namespace::NamespaceDefinition}
|
29
|
-
def referenced_namespaces
|
30
|
-
@referenced_namespaces ||= Hash[
|
31
|
-
NAMESPACES.map { |ns| [ns.prefix, ns] }
|
32
|
-
]
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns a randomly chosen namespace.
|
36
|
-
# @return [BEL::Namespace::NamespaceDefinition] a random namespace
|
37
|
-
def namespace
|
38
|
-
ns = Rantly {
|
39
|
-
choose(*NAMESPACES)
|
40
|
-
}
|
41
|
-
referenced_namespaces[ns.prefix] = ns
|
42
|
-
ns
|
43
|
-
end
|
44
|
-
|
45
|
-
# Returns a BEL parameter from a random namespace. The value will be
|
46
|
-
# randomly sample from the chosen namespace.
|
47
|
-
#
|
48
|
-
# @return [BEL::Model::Parameter] a parameter chosen from a namespace
|
49
|
-
def bel_parameter_with_namespace
|
50
|
-
ns = namespace
|
51
|
-
value = ns.values.keys.sample
|
52
|
-
enc = ns.values[value]
|
53
|
-
BEL::Model::Parameter.new(
|
54
|
-
ns,
|
55
|
-
value.to_s,
|
56
|
-
enc
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
# Returns a BEL parameter without a namespace. The value will be
|
61
|
-
# a random string.
|
62
|
-
#
|
63
|
-
# @return [BEL::Model::Parameter] a parameter without a namespace
|
64
|
-
def bel_parameter_without_namespace
|
65
|
-
value = Rantly.value {
|
66
|
-
sized(range(3,10)) {
|
67
|
-
string(/[[:alnum:]]|[[:blank:]]|[[:punct:]]/)
|
68
|
-
}
|
69
|
-
}
|
70
|
-
BEL::Model::Parameter.new(
|
71
|
-
nil,
|
72
|
-
value,
|
73
|
-
:A
|
74
|
-
)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns a BEL parameter that may or may not have a namespace.
|
78
|
-
#
|
79
|
-
# Note: This method has a better chance of selecting a BEL parameter
|
80
|
-
# from a namespace.
|
81
|
-
#
|
82
|
-
# @see #bel_parameter_with_namespace
|
83
|
-
# @see #bel_parameter_without_namespace
|
84
|
-
# @return [BEL::Model::Parameter] a parameter that may or may not have
|
85
|
-
# a namespace
|
86
|
-
def bel_parameter
|
87
|
-
with_namespace = bel_parameter_with_namespace
|
88
|
-
without_namespace = bel_parameter_without_namespace
|
89
|
-
Rantly {
|
90
|
-
freq(
|
91
|
-
[5, :literal, with_namespace],
|
92
|
-
[1, :literal, without_namespace],
|
93
|
-
)
|
94
|
-
}
|
95
|
-
end
|
96
|
-
|
97
|
-
# Returns a randomly chosen function.
|
98
|
-
# @return [Symbol] the function label (short or long form)
|
99
|
-
def function
|
100
|
-
Rantly {
|
101
|
-
choose(*FUNCTIONS)
|
102
|
-
}
|
103
|
-
end
|
104
|
-
|
105
|
-
# Returns a randomly chosen relationship.
|
106
|
-
# @return [Symbol] the relationship label (short or long form)
|
107
|
-
def relationship
|
108
|
-
Rantly {
|
109
|
-
choose(*RELATIONSHIPS)
|
110
|
-
}
|
111
|
-
end
|
112
|
-
|
113
|
-
# Returns a randomly constructed BEL term.
|
114
|
-
# @return [String] the term label
|
115
|
-
def bel_term
|
116
|
-
"#{function}(#{bel_parameter})"
|
117
|
-
end
|
118
|
-
|
119
|
-
# Returns a randomly constructed BEL statement.
|
120
|
-
# @return [String] the statement label
|
121
|
-
def bel_statement
|
122
|
-
sub = bel_term
|
123
|
-
obj = bel_term
|
124
|
-
"#{sub} #{relationship} #{obj}"
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|