Class: Rigor::Type::Intersection

Inherits:
Object
  • Object
show all
Includes:
AcceptanceRouter, ValueSemantics
Defined in:
lib/rigor/type/intersection.rb

Overview

‘Intersection[M1, M2, …]` — value set is the meet of every member’s value set. The carrier composes refinements that share a base, in particular the catalogued ‘non-empty-lowercase-string` (= `Difference[String, “”] & Refined[String, :lowercase]`) and `non-empty-uppercase-string` shapes from [`imported-built-in-types.md`](docs/type-specification/imported-built-in-types.md). See [ADR-3](docs/adr/3-type-representation.md) for the OQ3 working decision and the rationale for keeping Intersection a thin wrapper rather than per-shape carriers.

Construction MUST go through ‘Type::Combinator.intersection` (or the per-name factories `Combinator.non_empty_lowercase_string` / `Combinator.non_empty_uppercase_string`). The factory:

  • flattens nested intersections,

  • drops ‘Top` members (Top is the identity of intersection),

  • collapses to ‘Bot` if any member is `Bot` (Bot is absorbing),

  • deduplicates structurally-equal members,

  • sorts the surviving members by ‘describe(:short)` so two structurally-equal intersections built in different orders compare equal,

  • returns ‘Top` for the empty intersection,

  • returns the lone member for a 1-element intersection (so the carrier is never inhabited by a degenerate single-member shape).

Direct ‘.new` callers MUST pass an already-normalised member list and are expected to be tests or the combinator itself.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ValueSemantics

included

Methods included from AcceptanceRouter

#accepts

Constructor Details

#initialize(members) ⇒ Intersection

Returns a new instance of Intersection.



42
43
44
45
# File 'lib/rigor/type/intersection.rb', line 42

def initialize(members)
  @members = members.dup.freeze
  freeze
end

Instance Attribute Details

#membersObject (readonly)

Returns the value of attribute members.



40
41
42
# File 'lib/rigor/type/intersection.rb', line 40

def members
  @members
end

Instance Method Details

#botObject



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

def bot
  Trinary.no
end

#describe(verbosity = :short) ⇒ Object



47
48
49
50
51
52
# File 'lib/rigor/type/intersection.rb', line 47

def describe(verbosity = :short)
  named = canonical_name
  return named if named

  members.map { |m| m.describe(verbosity) }.join(" & ")
end

#dynamicObject



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

def dynamic
  Trinary.no
end

#erase_to_rbsObject

An intersection of refinements over the same base type erases to that base. We use the first member’s erasure because the v0.0.4 catalogue (‘non-empty-lowercase-string` etc.) is restricted to same-base composition; richer cross-base intersections will need a stricter erasure rule (likely “lowest common ancestor” via the inference engine’s class hierarchy).



61
62
63
# File 'lib/rigor/type/intersection.rb', line 61

def erase_to_rbs
  members.first.erase_to_rbs
end

#inspectObject



83
84
85
# File 'lib/rigor/type/intersection.rb', line 83

def inspect
  "#<Rigor::Type::Intersection #{describe(:short)}>"
end

#topObject



65
66
67
# File 'lib/rigor/type/intersection.rb', line 65

def top
  Trinary.no
end