bmg 0.18.12 → 0.18.13
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.
- checksums.yaml +4 -4
- data/lib/bmg/algebra.rb +5 -4
- data/lib/bmg/operator/autosummarize.rb +84 -36
- data/lib/bmg/operator/autowrap.rb +6 -0
- data/lib/bmg/relation/materialized.rb +11 -3
- data/lib/bmg/type.rb +9 -2
- data/lib/bmg/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ceadf8947aa041841941225e88396cc37ff7319
|
4
|
+
data.tar.gz: 9c695d3305101ff4a73bcdef5e3788648e9b2d27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70db4550decd609934e1d8d643983766b5b50b9f0354b2405dfdc710b9580a885e4754c907ed5011856e905308af9647c029f0dd612657e72b45af0465eaced2
|
7
|
+
data.tar.gz: 5ed5e7f6d1d9baa8070112a36229e8961e4b5a531acbdac808fcf1f5c008fc91ae3ceadc5c3b4c1d0ace22ca6f861074e79b6d957498740a8fba3d5e99875068
|
data/lib/bmg/algebra.rb
CHANGED
@@ -12,6 +12,7 @@ module Bmg
|
|
12
12
|
protected :_allbut
|
13
13
|
|
14
14
|
def autowrap(options = {})
|
15
|
+
return self if self.type.identity_autowrap?(options)
|
15
16
|
_autowrap self.type.autowrap(options), options
|
16
17
|
end
|
17
18
|
|
@@ -20,12 +21,12 @@ module Bmg
|
|
20
21
|
end
|
21
22
|
protected :_autowrap
|
22
23
|
|
23
|
-
def autosummarize(by = [], summarization = {})
|
24
|
-
_autosummarize
|
24
|
+
def autosummarize(by = [], summarization = {}, options = {})
|
25
|
+
_autosummarize self.type.autosummarize(by, summarization, options), by, summarization, options
|
25
26
|
end
|
26
27
|
|
27
|
-
def _autosummarize(type, by, summarization)
|
28
|
-
Operator::Autosummarize.new(type, self, by, summarization)
|
28
|
+
def _autosummarize(type, by, summarization, options)
|
29
|
+
Operator::Autosummarize.new(type, self, by, summarization, options)
|
29
30
|
end
|
30
31
|
protected :_autosummarize
|
31
32
|
|
@@ -11,16 +11,22 @@ module Bmg
|
|
11
11
|
class Autosummarize
|
12
12
|
include Operator::Unary
|
13
13
|
|
14
|
-
|
14
|
+
DEFAULT_OPTIONS = {
|
15
|
+
default: :same
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(type, operand, by, sums, options = {})
|
15
19
|
@type = type
|
16
20
|
@operand = operand
|
17
21
|
@by = by
|
18
22
|
@sums = sums.each_with_object({}){|(k,v),h| h[k] = to_summarizer(v) }
|
23
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
24
|
+
@algo = build_algo
|
19
25
|
end
|
20
26
|
|
21
27
|
protected
|
22
28
|
|
23
|
-
attr_reader :by, :sums
|
29
|
+
attr_reader :by, :sums, :options
|
24
30
|
|
25
31
|
public
|
26
32
|
|
@@ -45,17 +51,17 @@ module Bmg
|
|
45
51
|
h = {}
|
46
52
|
@operand.each do |tuple|
|
47
53
|
key = key(tuple)
|
48
|
-
h[key] ||= init(
|
49
|
-
h[key] = sum(h[key], tuple)
|
54
|
+
h[key] ||= @algo.init(tuple)
|
55
|
+
h[key] = @algo.sum(h[key], tuple)
|
50
56
|
end
|
51
57
|
h.each_pair do |k,v|
|
52
|
-
h[k] = term(v)
|
58
|
+
h[k] = @algo.term(v)
|
53
59
|
end
|
54
60
|
h.values.each(&bl)
|
55
61
|
end
|
56
62
|
|
57
63
|
def to_ast
|
58
|
-
[:autosummarize, operand.to_ast, by.dup, sums.dup]
|
64
|
+
[:autosummarize, operand.to_ast, by.dup, sums.dup, options.dup]
|
59
65
|
end
|
60
66
|
|
61
67
|
public ### for internal reasons
|
@@ -73,7 +79,7 @@ module Bmg
|
|
73
79
|
else
|
74
80
|
op = operand
|
75
81
|
op = op.restrict(bottom)
|
76
|
-
op = op.autosummarize(by, sums)
|
82
|
+
op = op.autosummarize(by, sums, options)
|
77
83
|
op = op.restrict(top)
|
78
84
|
op
|
79
85
|
end
|
@@ -87,46 +93,86 @@ module Bmg
|
|
87
93
|
|
88
94
|
private
|
89
95
|
|
96
|
+
def build_algo
|
97
|
+
case default = @options[:default]
|
98
|
+
when :same then Check.new(sums)
|
99
|
+
when :first then Trust.new(sums)
|
100
|
+
else
|
101
|
+
raise ArgumentError, "Unknown default summarizer: `#{default}`"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
90
105
|
# Returns the tuple determinant.
|
91
106
|
def key(tuple)
|
92
107
|
@by.map{|by| tuple[by] }
|
93
108
|
end
|
94
109
|
|
95
|
-
# Returns the initial tuple to use for a given determinant.
|
96
|
-
def init(key, tuple)
|
97
|
-
tuple.each_with_object({}){|(k,v),h|
|
98
|
-
h.merge!(k => summarizer(k).init(v))
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
|
-
# Returns the summarizer to use for a given key.
|
103
|
-
def summarizer(k)
|
104
|
-
@sums[k] || Same.new
|
105
|
-
end
|
106
|
-
|
107
|
-
# Sums `tuple` on `memo`, returning the new tuple to use as memo.
|
108
|
-
def sum(memo, tuple)
|
109
|
-
tuple.each_with_object(memo.dup){|(k,v),h|
|
110
|
-
h.merge!(k => summarizer(k).sum(h[k], v))
|
111
|
-
}
|
112
|
-
end
|
113
|
-
|
114
|
-
# Terminates the summarization of a given tuple.
|
115
|
-
def term(tuple)
|
116
|
-
tuple.each_with_object({}){|(k,v),h|
|
117
|
-
h.merge!(k => summarizer(k).term(v))
|
118
|
-
}
|
119
|
-
end
|
120
|
-
|
121
110
|
def to_summarizer(x)
|
122
111
|
case x
|
123
|
-
when :same then Same
|
124
|
-
when :group then DistinctList
|
112
|
+
when :same then Same::INSTANCE
|
113
|
+
when :group then DistinctList::INSTANCE
|
125
114
|
else
|
126
115
|
x
|
127
116
|
end
|
128
117
|
end
|
129
118
|
|
119
|
+
class Check
|
120
|
+
def initialize(sums)
|
121
|
+
@sums = sums
|
122
|
+
end
|
123
|
+
attr_reader :sums
|
124
|
+
|
125
|
+
def summarizer(k)
|
126
|
+
@sums[k] ||= Same::INSTANCE
|
127
|
+
end
|
128
|
+
|
129
|
+
def init(tuple)
|
130
|
+
tuple.each_with_object({}){|(k,v),h|
|
131
|
+
h.merge!(k => summarizer(k).init(v))
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
def sum(memo, tuple)
|
136
|
+
tuple.each_with_object(memo.dup){|(k,v),h|
|
137
|
+
h.merge!(k => summarizer(k).sum(h[k], v))
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def term(tuple)
|
142
|
+
tuple.each_with_object({}){|(k,v),h|
|
143
|
+
h.merge!(k => summarizer(k).term(v))
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end # class Check
|
147
|
+
|
148
|
+
class Trust
|
149
|
+
def initialize(sums)
|
150
|
+
@sums = sums
|
151
|
+
end
|
152
|
+
attr_reader :sums
|
153
|
+
|
154
|
+
# Returns the initial tuple to use for a given determinant.
|
155
|
+
def init(tuple)
|
156
|
+
sums.each_with_object(tuple.dup){|(attribute,summarizer),new_tuple|
|
157
|
+
new_tuple[attribute] = summarizer.init(tuple[attribute])
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
# Sums `tuple` on `memo`, returning the new tuple to use as memo.
|
162
|
+
def sum(memo, tuple)
|
163
|
+
sums.each_with_object(memo.dup){|(attribute,summarizer),new_tuple|
|
164
|
+
new_tuple[attribute] = summarizer.sum(memo[attribute], tuple[attribute])
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
# Terminates the summarization of a given tuple.
|
169
|
+
def term(tuple)
|
170
|
+
sums.each_with_object(tuple.dup){|(attribute,summarizer),new_tuple|
|
171
|
+
new_tuple[attribute] = summarizer.term(tuple[attribute])
|
172
|
+
}
|
173
|
+
end
|
174
|
+
end # class Trust
|
175
|
+
|
130
176
|
#
|
131
177
|
# Summarizes by enforcing that the same dependent is observed for a given
|
132
178
|
# determinant, returning the dependent as summarization.
|
@@ -138,7 +184,7 @@ module Bmg
|
|
138
184
|
end
|
139
185
|
|
140
186
|
def sum(v1, v2)
|
141
|
-
raise "Same values expected, got `#{v1}` vs. `#{v2}`" unless v1 == v2
|
187
|
+
raise TypeError, "Same values expected, got `#{v1}` vs. `#{v2}`" unless v1 == v2
|
142
188
|
v1
|
143
189
|
end
|
144
190
|
|
@@ -151,6 +197,7 @@ module Bmg
|
|
151
197
|
end
|
152
198
|
alias :to_s :inspect
|
153
199
|
|
200
|
+
INSTANCE = new
|
154
201
|
end # class Same
|
155
202
|
|
156
203
|
#
|
@@ -183,6 +230,7 @@ module Bmg
|
|
183
230
|
end
|
184
231
|
alias :to_s :inspect
|
185
232
|
|
233
|
+
INSTANCE = new
|
186
234
|
end # class DistinctList
|
187
235
|
|
188
236
|
#
|
@@ -19,14 +19,14 @@ module Bmg
|
|
19
19
|
public
|
20
20
|
|
21
21
|
def _count
|
22
|
-
|
22
|
+
_materialize._count
|
23
23
|
end
|
24
24
|
|
25
25
|
public
|
26
26
|
|
27
27
|
def each(&bl)
|
28
|
-
|
29
|
-
|
28
|
+
return to_enum unless block_given?
|
29
|
+
_materialize.each(&bl)
|
30
30
|
end
|
31
31
|
|
32
32
|
def to_ast
|
@@ -37,6 +37,14 @@ module Bmg
|
|
37
37
|
[]
|
38
38
|
end
|
39
39
|
|
40
|
+
private
|
41
|
+
|
42
|
+
def _materialize
|
43
|
+
return @operand if @operand.is_a?(Relation::InMemory)
|
44
|
+
|
45
|
+
@operand = Relation::InMemory.new(operand.type, operand.to_a)
|
46
|
+
end
|
47
|
+
|
40
48
|
end # class Materialized
|
41
49
|
end # module Relation
|
42
50
|
end # module Bmg
|
data/lib/bmg/type.rb
CHANGED
@@ -103,8 +103,15 @@ module Bmg
|
|
103
103
|
}
|
104
104
|
end
|
105
105
|
|
106
|
+
def identity_autowrap?(options)
|
107
|
+
return false unless knows_attrlist?
|
108
|
+
|
109
|
+
sep = Operator::Autowrap.separator(options)
|
110
|
+
self.attrlist.all?{|a| a.to_s.index(sep).nil? }
|
111
|
+
end
|
112
|
+
|
106
113
|
def autowrap(options)
|
107
|
-
sep =
|
114
|
+
sep = Operator::Autowrap.separator(options)
|
108
115
|
splitter = ->(a){ a.to_s.split(sep).first }
|
109
116
|
is_split = ->(a){ a.to_s.split(sep).size > 1 }
|
110
117
|
dup.tap{|x|
|
@@ -115,7 +122,7 @@ module Bmg
|
|
115
122
|
}
|
116
123
|
end
|
117
124
|
|
118
|
-
def autosummarize(by, summarization)
|
125
|
+
def autosummarize(by, summarization, options)
|
119
126
|
known_attributes!(by + summarization.keys) if typechecked? && knows_attrlist?
|
120
127
|
dup.tap{|x|
|
121
128
|
x.attrlist = nil
|
data/lib/bmg/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bmg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.18.
|
4
|
+
version: 0.18.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-01-
|
11
|
+
date: 2022-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: predicate
|