Class: Bmg::Type

Inherits:
Object
  • Object
show all
Defined in:
lib/bmg/type.rb

Constant Summary collapse

ANY =
Type.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(predicate = Predicate.tautology) ⇒ Type

Returns a new instance of Type.

Raises:

  • (ArgumentError)


4
5
6
7
8
# File 'lib/bmg/type.rb', line 4

def initialize(predicate = Predicate.tautology)
  @predicate = predicate
  @typechecked = false
  raise ArgumentError if @predicate.nil?
end

Instance Attribute Details

#attrlistObject

Returns the value of attribute attrlist.



46
47
48
# File 'lib/bmg/type.rb', line 46

def attrlist
  @attrlist
end

#keysObject

Returns the value of attribute keys.



69
70
71
# File 'lib/bmg/type.rb', line 69

def keys
  @keys
end

#predicateObject

Returns the value of attribute predicate.



35
36
37
# File 'lib/bmg/type.rb', line 35

def predicate
  @predicate
end

Instance Method Details

#[](attribute) ⇒ Object



91
92
93
# File 'lib/bmg/type.rb', line 91

def [](attribute)
  ANY
end

#allbut(butlist) ⇒ Object



97
98
99
100
101
102
103
104
# File 'lib/bmg/type.rb', line 97

def allbut(butlist)
  known_attributes!(butlist) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = self.attrlist - butlist if knows_attrlist?
    x.predicate = Predicate.tautology
    x.keys      = self._keys.allbut(self, x, butlist) if knows_keys?
  }
end

#autosummarize(by, summarization, options) ⇒ Object



125
126
127
128
129
130
131
132
# File 'lib/bmg/type.rb', line 125

def autosummarize(by, summarization, options)
  known_attributes!(by + summarization.keys) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist = nil
    x.predicate = Predicate.tautology
    x.keys = nil
  }
end

#autowrap(options) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/bmg/type.rb', line 113

def autowrap(options)
  sep = Operator::Autowrap.separator(options)
  splitter = ->(a){ a.to_s.split(sep).first }
  is_split = ->(a){ a.to_s.split(sep).size > 1 }
  dup.tap{|x|
    x.attrlist  = self.attrlist.map(&splitter).uniq.map(&:to_sym) if knows_attrlist?
    x.keys      = self._keys.autowrap(self, x, options) if knows_keys?
    autowrapped = self.predicate.free_variables.select(&is_split)
    x.predicate = autowrapped.empty? ? self.predicate : self.predicate.and_split(autowrapped).last
  }
end

#constants(cs) ⇒ Object



134
135
136
137
138
139
140
141
# File 'lib/bmg/type.rb', line 134

def constants(cs)
  unknown_attributes!(cs.keys) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = self.attrlist + cs.keys if knows_attrlist?
    x.predicate = self.predicate & Predicate.eq(cs)
    ### keys stay the same
  }
end

#extend(extension) ⇒ Object



143
144
145
146
147
148
149
150
# File 'lib/bmg/type.rb', line 143

def extend(extension)
  unknown_attributes!(extension.keys) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = self.attrlist + extension.keys if knows_attrlist?
    x.predicate = Predicate.tautology
    ### keys stay the same (?)
  }
end

#group(attrs, as) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
# File 'lib/bmg/type.rb', line 152

def group(attrs, as)
  if typechecked? && knows_attrlist?
    known_attributes!(attrs)
    unknown_attributes!([as])
  end
  dup.tap{|x|
    x.attrlist  = self.attrlist - attrs + [as] if knows_attrlist?
    x.predicate = Predicate.tautology
    x.keys      = self._keys.group(self, x, attrs, as) if knows_keys?
  }
end

#identity_autowrap?(options) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
109
110
111
# File 'lib/bmg/type.rb', line 106

def identity_autowrap?(options)
  return false unless knows_attrlist?

  sep = Operator::Autowrap.separator(options)
  self.attrlist.all?{|a| a.to_s.index(sep).nil? }
end

#image(right, as, on, options) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
# File 'lib/bmg/type.rb', line 164

def image(right, as, on, options)
  if typechecked? && knows_attrlist?
    join_compatible!(right, on)
    unknown_attributes!([as])
  end
  dup.tap{|x|
    x.attrlist  = self.attrlist + [as] if knows_attrlist?
    x.predicate = Predicate.tautology
    x.keys      = self._keys
  }
end

#join(right, on) ⇒ Object



176
177
178
179
180
181
182
183
# File 'lib/bmg/type.rb', line 176

def join(right, on)
  join_compatible!(right, on) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = (knows_attrlist? and right.knows_attrlist?) ? (self.attrlist + right.attrlist).uniq : nil
    x.predicate = self.predicate & right.predicate
    x.keys      = (knows_keys? and right.knows_keys?) ? self._keys.join(self, x, right, on) : nil
  }
end

#knows_attrlist!Object



59
60
61
# File 'lib/bmg/type.rb', line 59

def knows_attrlist!
  raise UnknownAttributesError unless knows_attrlist?
end

#knows_attrlist?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/bmg/type.rb', line 55

def knows_attrlist?
  !self.attrlist.nil?
end

#knows_keys?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/bmg/type.rb', line 73

def knows_keys?
  !!@keys
end

#left_join(right, on, default_right_tuple) ⇒ Object



185
186
187
188
189
190
191
192
# File 'lib/bmg/type.rb', line 185

def left_join(right, on, default_right_tuple)
  join_compatible!(right, on) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = (knows_attrlist? and right.knows_attrlist?) ? (self.attrlist + right.attrlist).uniq : nil
    x.predicate = Predicate.tautology
    x.keys      = nil
  }
end

#matching(right, on) ⇒ Object



194
195
196
197
# File 'lib/bmg/type.rb', line 194

def matching(right, on)
  join_compatible!(right, on) if typechecked? && knows_attrlist?
  self
end

#not_matching(right, on) ⇒ Object



199
200
201
202
# File 'lib/bmg/type.rb', line 199

def not_matching(right, on)
  join_compatible!(right, on) if typechecked? && knows_attrlist?
  self
end

#page(ordering, page_size, options) ⇒ Object



204
205
206
207
# File 'lib/bmg/type.rb', line 204

def page(ordering, page_size, options)
  known_attributes!(ordering.map{|(k,v)| k}) if typechecked? && knows_attrlist?
  self
end

#project(attrlist) ⇒ Object



209
210
211
212
213
214
215
216
# File 'lib/bmg/type.rb', line 209

def project(attrlist)
  known_attributes!(attrlist) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = attrlist
    x.predicate = Predicate.tautology
    x.keys      = self._keys.project(self, x, attrlist) if knows_keys?
  }
end

#rename(renaming) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/bmg/type.rb', line 218

def rename(renaming)
  if typechecked? && knows_attrlist?
    known_attributes!(renaming.keys)
    unknown_attributes!(renaming.values)
  end
  new_pred = begin
    self.predicate.rename(renaming)
  rescue Predicate::NotSupportedError => e
    Predicate.tautology
  end
  dup.tap{|x|
    x.attrlist  = self.attrlist.map{|a| renaming[a] || a } if knows_attrlist?
    x.predicate = new_pred
    x.keys      = self._keys.rename(self, x, renaming) if knows_keys?
  }
end

#restrict(predicate) ⇒ Object



235
236
237
238
239
240
241
242
# File 'lib/bmg/type.rb', line 235

def restrict(predicate)
  known_attributes!(predicate.free_variables) if typechecked? && knows_attrlist?
  dup.tap{|x|
    ### attrlist stays the same
    x.predicate = self.predicate & predicate
    x.keys      = self._keys.restrict(self, x, predicate) if knows_keys?
  }
end

#summarize(by, summarization) ⇒ Object



244
245
246
247
248
249
# File 'lib/bmg/type.rb', line 244

def summarize(by, summarization)
  dup.tap{|x|
    x.attrlist = by + summarization.keys
    x.keys     = Keys.new([by])
  }
end

#to_attrlistObject



63
64
65
# File 'lib/bmg/type.rb', line 63

def to_attrlist
  self.attrlist
end

#transform(transformation, options = {}) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/bmg/type.rb', line 251

def transform(transformation, options = {})
  transformer = TupleTransformer.new(transformation)
  if typechecked? && knows_attrlist? && transformer.knows_attrlist?
    known_attributes!(transformer.to_attrlist)
  end
  keys = if options[:key_preserving]
    self._keys
  elsif transformer.knows_attrlist? && knows_keys?
    touched_attrs = transformer.to_attrlist
    keys = self._keys.select{|k| (k & touched_attrs).empty? }
  else
    nil
  end
  pred = if transformer.knows_attrlist?
    attr_list = transformer.to_attrlist
    predicate.and_split(attr_list).last
  else
    Predicate.tautology
  end
  dup.tap{|x|
    x.keys = keys
    x.predicate = pred
  }
end

#typechecked?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/bmg/type.rb', line 17

def typechecked?
  @typechecked
end

#ungroup(attrlist) ⇒ Object



276
277
278
279
280
281
282
283
# File 'lib/bmg/type.rb', line 276

def ungroup(attrlist)
  known_attributes!(attrlist) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = nil
    x.predicate = Predicate.tautology
    x.keys      = nil
  }
end

#union(other) ⇒ Object



285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/bmg/type.rb', line 285

def union(other)
  if typechecked? && knows_attrlist? && other.knows_attrlist?
    missing = self.attrlist - other.attrlist
    raise TypeError, "Union incompatible: missing right attributes #{missing.join(', ')}" unless missing.empty?
    extra = other.attrlist - self.attrlist
    raise TypeError, "Union incompatible: missing left attributes #{extra.join(', ')}" unless extra.empty?
  end
  dup.tap{|x|
    ### attrlist stays the same
    x.predicate = self.predicate | predicate
    x.keys      = self._keys.union(self, x, other) if knows_keys?
  }
end

#unwrap(attrlist) ⇒ Object



299
300
301
302
303
304
305
306
# File 'lib/bmg/type.rb', line 299

def unwrap(attrlist)
  known_attributes!(attrlist) if typechecked? && knows_attrlist?
  dup.tap{|x|
    x.attrlist  = nil
    x.predicate = predicate.and_split(attrlist).last
    x.keys      = self._keys.unwrap(self, x, attrlist) if knows_keys?
  }
end

#with_attrlist(attrlist) ⇒ Object



49
50
51
52
53
# File 'lib/bmg/type.rb', line 49

def with_attrlist(attrlist)
  dup.tap{|x|
    x.attrlist = attrlist
  }
end

#with_keys(keys) ⇒ Object



83
84
85
86
87
# File 'lib/bmg/type.rb', line 83

def with_keys(keys)
  dup.tap{|x|
    x.keys = keys ? Keys.new(keys) : nil
  }
end

#with_predicate(predicate) ⇒ Object



38
39
40
41
42
# File 'lib/bmg/type.rb', line 38

def with_predicate(predicate)
  dup.tap{|x|
    x.predicate = predicate
  }
end

#with_typecheckObject



21
22
23
24
25
# File 'lib/bmg/type.rb', line 21

def with_typecheck
  dup.tap{|x|
    x.typechecked = true
  }
end

#without_typecheckObject



27
28
29
30
31
# File 'lib/bmg/type.rb', line 27

def without_typecheck
  dup.tap{|x|
    x.typechecked = false
  }
end