Class: AdLint::Cc1::IntersectionValueDomain

Inherits:
CompositeValueDomain show all
Defined in:
lib/adlint/cc1/domain.rb

Instance Attribute Summary

Attributes inherited from CompositeValueDomain

#domain_pair

Instance Method Summary collapse

Methods inherited from CompositeValueDomain

#!=, #==, #_add_equal_to, #_add_greater_than, #_add_less_than, #_add_nil, #_add_unlimited, #_and_equal_to, #_and_greater_than, #_and_less_than, #_and_nil, #_and_unlimited, #_div_equal_to, #_div_greater_than, #_div_less_than, #_div_nil, #_div_unlimited, #_equal_equal_to, #_equal_greater_than, #_equal_less_than, #_equal_nil, #_equal_unlimited, #_intersect_equal_to?, #_intersect_greater_than?, #_intersect_less_than?, #_intersect_nil?, #_intersect_unlimited?, #_intersection_equal_to, #_intersection_greater_than, #_intersection_less_than, #_intersection_nil, #_intersection_unlimited, #_less_equal_to, #_less_greater_than, #_less_less_than, #_less_nil, #_less_unlimited, #_logical_and_equal_to, #_logical_and_greater_than, #_logical_and_less_than, #_logical_and_nil, #_logical_and_unlimited, #_logical_or_equal_to, #_logical_or_greater_than, #_logical_or_less_than, #_logical_or_nil, #_logical_or_unlimited, #_narrow_by_eq, #_narrow_by_gt, #_narrow_by_lt, #_narrow_by_ne, #_narrow_equal_to_by_eq, #_narrow_equal_to_by_gt, #_narrow_equal_to_by_lt, #_narrow_equal_to_by_ne, #_narrow_greater_than_by_eq, #_narrow_greater_than_by_gt, #_narrow_greater_than_by_lt, #_narrow_greater_than_by_ne, #_narrow_less_than_by_eq, #_narrow_less_than_by_gt, #_narrow_less_than_by_lt, #_narrow_less_than_by_ne, #_narrow_nil_by_eq, #_narrow_nil_by_gt, #_narrow_nil_by_lt, #_narrow_nil_by_ne, #_narrow_unlimited_by_eq, #_narrow_unlimited_by_gt, #_narrow_unlimited_by_lt, #_narrow_unlimited_by_ne, #_not_equal_equal_to, #_not_equal_greater_than, #_not_equal_less_than, #_not_equal_nil, #_not_equal_unlimited, #_or_equal_to, #_or_greater_than, #_or_less_than, #_or_nil, #_or_unlimited, #_shl_equal_to, #_shl_greater_than, #_shl_less_than, #_shl_nil, #_shl_unlimited, #_shr_equal_to, #_shr_greater_than, #_shr_less_than, #_shr_nil, #_shr_unlimited, #_union_equal_to, #_union_greater_than, #_union_less_than, #_union_nil, #_union_unlimited, #_xor_equal_to, #_xor_greater_than, #_xor_less_than, #_xor_nil, #_xor_unlimited, #ambiguous?, #complexity, #empty?, #initialize, #nan?, #to_defined_domain, #undefined?

Methods inherited from ValueDomain

#!=, #%, #-, #<=, #<=>, #==, #>, #>=, #_add_equal_to, #_add_greater_than, #_add_less_than, #_add_nil, #_add_unlimited, #_and_equal_to, #_and_greater_than, #_and_less_than, #_and_nil, #_and_unlimited, #_div_equal_to, #_div_greater_than, #_div_less_than, #_div_nil, #_div_unlimited, #_equal_equal_to, #_equal_greater_than, #_equal_less_than, #_equal_nil, #_equal_unlimited, #_intersect_equal_to?, #_intersect_greater_than?, #_intersect_less_than?, #_intersect_nil?, #_intersect_unlimited?, #_intersection_equal_to, #_intersection_greater_than, #_intersection_less_than, #_intersection_nil, #_intersection_unlimited, #_less_equal_to, #_less_greater_than, #_less_less_than, #_less_nil, #_less_unlimited, #_logical_and_equal_to, #_logical_and_greater_than, #_logical_and_less_than, #_logical_and_nil, #_logical_and_unlimited, #_logical_or_equal_to, #_logical_or_greater_than, #_logical_or_less_than, #_logical_or_nil, #_logical_or_unlimited, #_narrow_by_eq, #_narrow_by_ge, #_narrow_by_gt, #_narrow_by_le, #_narrow_by_lt, #_narrow_by_ne, #_narrow_equal_to_by_eq, #_narrow_equal_to_by_gt, #_narrow_equal_to_by_lt, #_narrow_equal_to_by_ne, #_narrow_greater_than_by_eq, #_narrow_greater_than_by_gt, #_narrow_greater_than_by_lt, #_narrow_greater_than_by_ne, #_narrow_less_than_by_eq, #_narrow_less_than_by_gt, #_narrow_less_than_by_lt, #_narrow_less_than_by_ne, #_narrow_nil_by_eq, #_narrow_nil_by_gt, #_narrow_nil_by_lt, #_narrow_nil_by_ne, #_narrow_unlimited_by_eq, #_narrow_unlimited_by_gt, #_narrow_unlimited_by_lt, #_narrow_unlimited_by_ne, #_not_equal_equal_to, #_not_equal_greater_than, #_not_equal_less_than, #_not_equal_nil, #_not_equal_unlimited, #_or_equal_to, #_or_greater_than, #_or_less_than, #_or_nil, #_or_unlimited, #_shl_equal_to, #_shl_greater_than, #_shl_less_than, #_shl_nil, #_shl_unlimited, #_shr_equal_to, #_shr_greater_than, #_shr_less_than, #_shr_nil, #_shr_unlimited, #_union_equal_to, #_union_greater_than, #_union_less_than, #_union_nil, #_union_unlimited, #_widen_by_eq, #_widen_by_ge, #_widen_by_gt, #_widen_by_le, #_widen_by_lt, #_widen_by_ne, #_xor_equal_to, #_xor_greater_than, #_xor_less_than, #_xor_nil, #_xor_unlimited, #ambiguous?, #complexity, #contain?, #empty?, #eql?, #hash, #initialize, #logical_shr?, #nan?, #narrow, #to_defined_domain, #undefined?, #widen

Methods included from ValueDomainFactory

#_create_intersection, #_create_union, #clear_memos, #equal_to, #greater_than, #greater_than_or_equal_to, #less_than, #less_than_or_equal_to, #not_equal_to, #of_ambiguous, #of_false, #of_intersection, #of_nan, #of_nil, #of_true, #of_undefined, #of_union, #of_unlimited

Constructor Details

This class inherits a constructor from AdLint::Cc1::CompositeValueDomain

Instance Method Details

#!Object



6457
6458
6459
6460
# File 'lib/adlint/cc1/domain.rb', line 6457

def !
  new_sub_doms = domain_pair.map { |dom| !dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#&(rhs_dom) ⇒ Object



6428
6429
6430
6431
6432
6433
6434
6435
# File 'lib/adlint/cc1/domain.rb', line 6428

def &(rhs_dom)
  if rhs_max = rhs_dom.max_value
    ValueDomain.greater_than_or_equal_to(0, logical_shr?).intersection(
      ValueDomain.less_than_or_equal_to(rhs_max, logical_shr?))
  else
    ValueDomain.greater_than_or_equal_to(0, logical_shr?)
  end
end

#*(rhs_dom) ⇒ Object



6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
# File 'lib/adlint/cc1/domain.rb', line 6343

def *(rhs_dom)
  # NOTE: Multiplication of LessThanValueDomain or GreaterThanValueDomain
  #       always makes UnlimitedValueDomain when the domain contains both
  #       positive and negative values.
  #       So, multiplication of IntersectionValueDomain cannot be defined
  #       in the same manner as other arithmetics.
  if rhs_dom.kind_of?(IntersectionValueDomain)
    lhs_dom = self

    lval = [
      (n = lhs_dom.min_value).integer? ? n - 1 : n - Float::EPSILON,
      (n = lhs_dom.max_value).integer? ? n + 1 : n + Float::EPSILON
    ]
    labs = lval.map { |val| val.abs }.sort

    rval = [
      (n = rhs_dom.min_value).integer? ? n - 1 : n - Float::EPSILON,
      (n = rhs_dom.max_value).integer? ? n + 1 : n + Float::EPSILON
    ]
    rabs = rval.map { |val| val.abs }.sort

    comp = lambda { |op, nums| nums.all? { |num| num.__send__(op, 0) } }
    only_negative, only_positive = comp.curry[:<], comp.curry[:>=]

    case lval
    when only_positive
      case rval
      when only_positive
        _mul_only_positive_and_only_positive(lval, labs, rval, rabs)
      when only_negative
        _mul_only_positive_and_only_negative(lval, labs, rval, rabs)
      else
        _mul_only_positive_and_positive_negative(lval, labs, rval, rabs)
      end
    when only_negative
      case rval
      when only_positive
        _mul_only_positive_and_only_negative(rval, rabs, lval, labs)
      when only_negative
        _mul_only_negative_and_only_negative(lval, labs, rval, rabs)
      else
        _mul_only_negative_and_positive_negative(lval, labs, rval, rabs)
      end
    else
      _mul_positive_negative_and_positive_negative(lval, labs, rval, rabs)
    end
  else
    rhs_dom * self
  end
end

#+(rhs_dom) ⇒ Object



6338
6339
6340
6341
# File 'lib/adlint/cc1/domain.rb', line 6338

def +(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs + rhs_dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#+@Object



6328
6329
6330
6331
# File 'lib/adlint/cc1/domain.rb', line 6328

def +@
  new_sub_doms = domain_pair.map { |dom| +dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#-@Object



6333
6334
6335
6336
# File 'lib/adlint/cc1/domain.rb', line 6333

def -@
  new_sub_doms = domain_pair.map { |dom| -dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#/(rhs_dom) ⇒ Object



6423
6424
6425
6426
# File 'lib/adlint/cc1/domain.rb', line 6423

def /(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs / rhs_dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#<(rhs_dom) ⇒ Object



6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
# File 'lib/adlint/cc1/domain.rb', line 6462

def <(rhs_dom)
  # NOTE: The intersection value domain must be a close-domain (--<===>--).
  if intersect?(rhs_dom)
    if rhs_dom.max_value && rhs_dom.max_value == min_value
      ValueDomain.of_false(logical_shr?)
    else
      ValueDomain.of_unlimited(logical_shr?)
    end
  else
    # NOTE: When value domains are not intersected, the RHS value domain is
    #       in the left or right of the LHS intersection value domain.
    if rhs_dom.min_value && max_value < rhs_dom.min_value
      # NOTE: The RHS value domain is in the right of the LHS intersection
      #       value domain.
      ValueDomain.of_true(logical_shr?)
    else
      # NOTE: The RHS value domain is in the left of the LHS intersection
      #       value domain.
      ValueDomain.of_false(logical_shr?)
    end
  end
end

#<<(rhs_dom) ⇒ Object



6447
6448
6449
6450
# File 'lib/adlint/cc1/domain.rb', line 6447

def <<(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs << rhs_dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#>>(rhs_dom) ⇒ Object



6452
6453
6454
6455
# File 'lib/adlint/cc1/domain.rb', line 6452

def >>(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs >> rhs_dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#^(rhs_dom) ⇒ Object



6442
6443
6444
6445
# File 'lib/adlint/cc1/domain.rb', line 6442

def ^(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs ^ rhs_dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#_contain_equal_to?(lhs_dom, rhs_dom = self) ⇒ Boolean

Returns:

  • (Boolean)


6283
6284
6285
# File 'lib/adlint/cc1/domain.rb', line 6283

def _contain_equal_to?(lhs_dom, rhs_dom = self)
  rhs_dom.domain_pair.any? { |rhs| lhs_dom.contain_value_domain?(rhs) }
end

#_contain_greater_than?(lhs_dom, rhs_dom = self) ⇒ Boolean

Returns:

  • (Boolean)


6291
6292
6293
# File 'lib/adlint/cc1/domain.rb', line 6291

def _contain_greater_than?(lhs_dom, rhs_dom = self)
  rhs_dom.domain_pair.any? { |rhs| lhs_dom.contain_value_domain?(rhs) }
end

#_contain_intersection?(lhs_dom, rhs_dom = self) ⇒ Boolean

Returns:

  • (Boolean)


6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
# File 'lib/adlint/cc1/domain.rb', line 6295

def _contain_intersection?(lhs_dom, rhs_dom = self)
  lhs_fst, lhs_snd = lhs_dom.domain_pair
  rhs_fst, rhs_snd = rhs_dom.domain_pair
  case
  when lhs_fst.contain_value_domain?(rhs_fst) &&
       lhs_snd.contain_value_domain?(rhs_snd)
    true
  when lhs_fst.contain_value_domain?(rhs_snd) &&
       lhs_snd.contain_value_domain?(rhs_fst)
    true
  else
    false
  end
end

#_contain_less_than?(lhs_dom, rhs_dom = self) ⇒ Boolean

Returns:

  • (Boolean)


6287
6288
6289
# File 'lib/adlint/cc1/domain.rb', line 6287

def _contain_less_than?(lhs_dom, rhs_dom = self)
  rhs_dom.domain_pair.any? { |rhs| lhs_dom.contain_value_domain?(rhs) }
end

#_contain_nil?(lhs_dom, rhs_dom = self) ⇒ Boolean

Returns:

  • (Boolean)


6275
6276
6277
# File 'lib/adlint/cc1/domain.rb', line 6275

def _contain_nil?(lhs_dom, rhs_dom = self)
  false
end

#_contain_union?(lhs_dom, rhs_dom = self) ⇒ Boolean

Returns:

  • (Boolean)


6310
6311
6312
# File 'lib/adlint/cc1/domain.rb', line 6310

def _contain_union?(lhs_dom, rhs_dom = self)
  lhs_dom.domain_pair.any? { |lhs| lhs.contain_value_domain?(rhs_dom) }
end

#_contain_unlimited?(lhs_dom, rhs_dom = self) ⇒ Boolean

Returns:

  • (Boolean)


6279
6280
6281
# File 'lib/adlint/cc1/domain.rb', line 6279

def _contain_unlimited?(lhs_dom, rhs_dom = self)
  true
end

#_mul_equal_to(lhs_dom, rhs_dom = self) ⇒ Object



6408
6409
6410
6411
# File 'lib/adlint/cc1/domain.rb', line 6408

def _mul_equal_to(lhs_dom, rhs_dom = self)
  new_sub_doms = rhs_dom.domain_pair.map { |rhs| lhs_dom * rhs }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#_mul_greater_than(lhs_dom, rhs_dom = self) ⇒ Object



6418
6419
6420
6421
# File 'lib/adlint/cc1/domain.rb', line 6418

def _mul_greater_than(lhs_dom, rhs_dom = self)
  new_sub_doms = rhs_dom.domain_pair.map { |rhs| lhs_dom * rhs }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#_mul_less_than(lhs_dom, rhs_dom = self) ⇒ Object



6413
6414
6415
6416
# File 'lib/adlint/cc1/domain.rb', line 6413

def _mul_less_than(lhs_dom, rhs_dom = self)
  new_sub_doms = rhs_dom.domain_pair.map { |rhs| lhs_dom * rhs }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#_mul_nil(lhs_dom, rhs_dom = self) ⇒ Object



6394
6395
6396
6397
6398
6399
# File 'lib/adlint/cc1/domain.rb', line 6394

def _mul_nil(lhs_dom, rhs_dom = self)
  # NOTE: NilValueDomain contains no values.
  #       So, any arithmetic operation with NilValueDomain makes
  #       NilValueDomain.
  lhs_dom
end

#_mul_unlimited(lhs_dom, rhs_dom = self) ⇒ Object



6401
6402
6403
6404
6405
6406
# File 'lib/adlint/cc1/domain.rb', line 6401

def _mul_unlimited(lhs_dom, rhs_dom = self)
  # NOTE: UnlimitedValueDomain contains everything.
  #       So, this arithmetic operation with UnlimitedValueDomain makes
  #       UnlimitedValueDomain.
  lhs_dom
end

#coerce_to_integerObject



6522
6523
6524
6525
# File 'lib/adlint/cc1/domain.rb', line 6522

def coerce_to_integer
  new_sub_doms = domain_pair.map { |dom| dom.coerce_to_integer }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#coerce_to_realObject



6527
6528
6529
6530
# File 'lib/adlint/cc1/domain.rb', line 6527

def coerce_to_real
  new_sub_doms = domain_pair.map { |dom| dom.coerce_to_real }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#contain_value_domain?(rhs_dom) ⇒ Boolean

Returns:

  • (Boolean)


6271
6272
6273
# File 'lib/adlint/cc1/domain.rb', line 6271

def contain_value_domain?(rhs_dom)
  rhs_dom._contain_intersection?(self)
end

#each_sampleObject



6546
6547
6548
6549
6550
6551
# File 'lib/adlint/cc1/domain.rb', line 6546

def each_sample
  return to_enum(:each_sample) unless block_given?
  domain_pair.map { |d| d.each_sample.to_a }.flatten.uniq.each do |sample|
    yield(sample) if contain?(sample)
  end
end

#intersect?(rhs_dom) ⇒ Boolean

Returns:

  • (Boolean)


6314
6315
6316
# File 'lib/adlint/cc1/domain.rb', line 6314

def intersect?(rhs_dom)
  domain_pair.all? { |lhs| lhs.intersect?(rhs_dom) }
end

#intersection(rhs_dom) ⇒ Object



6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
# File 'lib/adlint/cc1/domain.rb', line 6495

def intersection(rhs_dom)
  if rhs_dom.kind_of?(UnionValueDomain)
    return rhs_dom.intersection(self)
  end

  case
  when contain_value_domain?(rhs_dom)
    rhs_dom
  when rhs_dom.contain_value_domain?(self)
    self
  else
    new_sub_doms = domain_pair.map { |lhs| lhs.intersection(rhs_dom) }
    ValueDomain.of_intersection(*new_sub_doms)
  end
end

#inversionObject



6318
6319
6320
6321
# File 'lib/adlint/cc1/domain.rb', line 6318

def inversion
  new_sub_doms = domain_pair.map { |dom| dom.inversion }
  new_sub_doms.first.union(new_sub_doms.last)
end

#logical_and(rhs_dom) ⇒ Object



6485
6486
6487
6488
# File 'lib/adlint/cc1/domain.rb', line 6485

def logical_and(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs.logical_and(rhs_dom) }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#logical_or(rhs_dom) ⇒ Object



6490
6491
6492
6493
# File 'lib/adlint/cc1/domain.rb', line 6490

def logical_or(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs.logical_or(rhs_dom) }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#max_valueObject



6539
6540
6541
6542
6543
# File 'lib/adlint/cc1/domain.rb', line 6539

def max_value
  # NOTE: Intersection-value-domain must be a close-domain (---<=====>---).
  #       So, max-value is defined by the higher lower-than value domain.
  domain_pair.map { |dom| dom.max_value }.compact.max
end

#min_valueObject



6532
6533
6534
6535
6536
# File 'lib/adlint/cc1/domain.rb', line 6532

def min_value
  # NOTE: Intersection-value-domain must be a close-domain (---<=====>---).
  #       So, min-value is defined by the lower greater-than value domain.
  domain_pair.map { |dom| dom.min_value }.compact.min
end

#to_sObject



6553
6554
6555
# File 'lib/adlint/cc1/domain.rb', line 6553

def to_s
  "(#{domain_pair.first.to_s} && #{domain_pair.last.to_s})"
end

#union(rhs_dom) ⇒ Object



6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
# File 'lib/adlint/cc1/domain.rb', line 6511

def union(rhs_dom)
  case
  when contain_value_domain?(rhs_dom)
    self
  when rhs_dom.contain_value_domain?(self)
    rhs_dom
  else
    ValueDomain.of_union(self, rhs_dom)
  end
end

#|(rhs_dom) ⇒ Object



6437
6438
6439
6440
# File 'lib/adlint/cc1/domain.rb', line 6437

def |(rhs_dom)
  new_sub_doms = domain_pair.map { |lhs| lhs | rhs_dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end

#~Object



6323
6324
6325
6326
# File 'lib/adlint/cc1/domain.rb', line 6323

def ~
  new_sub_doms = domain_pair.map { |dom| ~dom }
  new_sub_doms.first.intersection(new_sub_doms.last)
end