Class: Plumb::SemanticMatcher::Interval

Inherits:
Node
  • Object
show all
Defined in:
lib/plumb/semantic_matcher.rb

Instance Attribute Summary

Attributes inherited from Node

#raw

Instance Method Summary collapse

Methods inherited from Node

#equivalent?, #initialize, #intersect_with_finite_set, #nominal?, #overlap_with_finite_set, #overlap_with_numeric_literal, #overlap_with_opaque, #overlap_with_pattern, #overlap_with_text_literal, #singleton?, #subset_from_nominal, #subset_from_numeric_literal, #subset_from_opaque, #subset_from_pattern, #subset_from_text_literal, #value_domain

Constructor Details

This class inherits a constructor from Plumb::SemanticMatcher::Node

Instance Method Details

#end_within(outer) ⇒ Object



276
277
278
279
280
281
282
283
284
# File 'lib/plumb/semantic_matcher.rb', line 276

def end_within(outer)
  return Relation::PROVEN if outer.raw.end.nil?
  return Relation::DISPROVEN if raw.end.nil?

  cmp = raw.end <=> outer.raw.end
  return Relation::UNKNOWN if cmp.nil?

  Relation.from(!raw.exclude_end? && outer.raw.exclude_end? ? cmp.negative? : cmp <= 0)
end

#endpoints_within(nominal) ⇒ Object



269
270
271
272
273
274
# File 'lib/plumb/semantic_matcher.rb', line 269

def endpoints_within(nominal)
  endpoints = [raw.begin, raw.end].compact
  return Relation::UNKNOWN if endpoints.empty?

  Relation.all(endpoints.map { |endpoint| nominal.matches_value(endpoint) })
end

#error_messageObject



245
# File 'lib/plumb/semantic_matcher.rb', line 245

def error_message = "Must be within #{raw}"

#intersect(other) ⇒ Object



307
# File 'lib/plumb/semantic_matcher.rb', line 307

def intersect(other) = other.intersect_with_range(self)

#intersect_with_range(other) ⇒ Object



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/plumb/semantic_matcher.rb', line 309

def intersect_with_range(other)
  ab = raw.begin
  bb = other.raw.begin
  new_begin = ab.nil? ? bb : (bb.nil? ? ab : (ab >= bb ? ab : bb))
  ae = raw.end
  be = other.raw.end
  new_end, new_exclude =
    if ae.nil? then [be, other.raw.exclude_end?]
    elsif be.nil? then [ae, raw.exclude_end?]
    elsif ae < be then [ae, raw.exclude_end?]
    elsif be < ae then [be, other.raw.exclude_end?]
    else [ae, raw.exclude_end? || other.raw.exclude_end?]
    end
  unless new_begin.nil? || new_end.nil?
    return Merge::EMPTY if new_begin > new_end
    return Merge::EMPTY if new_begin == new_end && new_exclude
  end
  Merge.merged(self.class.new(::Range.new(new_begin, new_end, new_exclude)))
rescue ::ArgumentError, ::TypeError
  Merge::UNKNOWN
end

#kindObject



237
# File 'lib/plumb/semantic_matcher.rb', line 237

def kind = :range

#matcher_domainObject



239
240
241
242
# File 'lib/plumb/semantic_matcher.rb', line 239

def matcher_domain
  endpoint = raw.begin || raw.end
  endpoint.nil? ? [] : [SemanticMatcher.value_domain(endpoint)]
end

#matches_value(candidate) ⇒ Object



244
# File 'lib/plumb/semantic_matcher.rb', line 244

def matches_value(candidate) = Relation.from(raw === candidate)

#overlap(other) ⇒ Object



286
287
288
289
290
# File 'lib/plumb/semantic_matcher.rb', line 286

def overlap(other)
  return Relation::PROVEN if equivalent?(other)

  other.overlap_with_range(self)
end

#overlap_with_literal(other) ⇒ Object



297
# File 'lib/plumb/semantic_matcher.rb', line 297

def overlap_with_literal(other) = matches_value(other.raw)

#overlap_with_nominal(other) ⇒ Object



292
293
294
295
# File 'lib/plumb/semantic_matcher.rb', line 292

def overlap_with_nominal(other)
  endpoint = raw.begin || raw.end
  endpoint.nil? ? Relation::UNKNOWN : other.matches_value(endpoint)
end

#overlap_with_range(other) ⇒ Object



299
300
301
302
303
304
305
# File 'lib/plumb/semantic_matcher.rb', line 299

def overlap_with_range(other)
  merged = intersect_with_range(other)
  return Relation::DISPROVEN if merged.empty?
  return Relation::PROVEN if merged.merged?

  Relation::UNKNOWN
end

#subset_from_finite_set(other) ⇒ Object



254
# File 'lib/plumb/semantic_matcher.rb', line 254

def subset_from_finite_set(other) = other.members_match(self)

#subset_from_literal(other) ⇒ Object



253
# File 'lib/plumb/semantic_matcher.rb', line 253

def subset_from_literal(other) = matches_value(other.raw)

#subset_from_range(other) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/plumb/semantic_matcher.rb', line 256

def subset_from_range(other)
  lo = if raw.begin.nil?
         Relation::PROVEN
       elsif other.raw.begin.nil?
         Relation::DISPROVEN
       else
         Relation.from(raw.cover?(other.raw.begin))
       end
  Relation.all([lo, other.end_within(self)])
rescue ::ArgumentError, ::TypeError
  Relation::UNKNOWN
end

#subset_of(other) ⇒ Object



247
248
249
250
251
# File 'lib/plumb/semantic_matcher.rb', line 247

def subset_of(other)
  return Relation::PROVEN if equivalent?(other)

  other.subset_from_range(self)
end