aboutsummaryrefslogblamecommitdiffstats
path: root/docs/type-hierarchy.puml
blob: c53a96569ee192fbf0c4fb19dc2981c1df5b5fce (plain) (tree)
































































































































































































































































































                                                            
@startuml type-hierarchy
!theme plain
title Type System: Stratified Universes & Types as Relations

package "Universe Stratification" {
  class "Universe₀" as U0 {
    Base values
    Examples: 3, -5, 3.14, true, "hello"
    The set of all runtime values
  }

  class "Universe₁" as U1 {
    Type relations (classify values)
    Examples: natural, integer, real, boolean
    Each type is a relation over Universe₀
    Type relations are infinite relations
  }

  class "Universe₂" as U2 {
    Type of type relations
    The classifier of type relations
    Prevents self-reference paradoxes
  }

  class "Universe₃" as U3 {
    Meta-type level
    Type : Universe₂ : Universe₃
  }

  U0 : Universe₁
  U1 : Universe₂
  U2 : Universe₃
  U3 : Universe₄

  note right of U1
    **Stratification prevents Russell's Paradox**
    Type relations live in Universe₁
    and classify values in Universe₀.
    A type cannot contain itself.

    natural : Universe₁
    3 ∈ natural (3 ∈ Universe₀)
    But: natural ∉ natural ✗ (universe mismatch)
  end note
}

package "Supertypes (Universe₁)" {
  class Number {
    Membership: number[X] where X : Universe₀
    Definition: Union of all numeric types
    number[X] :- natural[X]; integer[X];
                 rational[X]; real[X].
    Allows polymorphism over numeric types
    Universe level: Universe₁
  }

  class Scalar {
    Membership: scalar[X] where X : Universe₀
    Definition: Atomic (non-composite) values
    scalar[X] :- number[X]; boolean[X]; string[X].
    Universe level: Universe₁
  }
}

package "Numeric Type Relations (Universe₁)" {
  class Naturals {
    Membership: natural[X] where X : Universe₀
    Criteria:
    - X is erlang:integer()
    - X >= 0
    Cardinality: aleph_zero
    Generator: 0, 1, 2, 3, ...
    Universe level: Universe₁
  }

  class Integers {
    Membership: integer[X] where X : Universe₀
    Criteria:
    - X is erlang:integer()
    Cardinality: aleph_zero
    Generator: 0, 1, -1, 2, -2, ...
    Universe level: Universe₁
  }

  class Rationals {
    Membership: rational[X] where X : Universe₀
    Criteria:
    - X is (P, Q)
    - integer[P], integer[Q]
    - Q ≠ 0
    Cardinality: aleph_zero
    Generator: Stern-Brocot tree
    Universe level: Universe₁
  }

  class Reals {
    Membership: real[X] where X : Universe₀
    Criteria:
    - X is erlang:float()
    Cardinality: continuum
    Generator: IEEE 754 floats
    Universe level: Universe₁
  }
}

package "Other Primitive Types (Universe₁)" {
  class Strings {
    Membership: string[X] where X : Universe₀
    Criteria:
    - X is erlang:string()
    Cardinality: aleph_zero
    Ordering: by length, then lexicographic
    Universe level: Universe₁
  }

  class Booleans {
    Membership: boolean[X] where X : Universe₀
    Criteria:
    - X is erlang:boolean()
    - X ∈ {true, false}
    Cardinality: 2
    Universe level: Universe₁
  }
}

package "Constrained Type Relations (Universe₁)" {
  class PositiveIntegers {
    Definition: positive_int[X] where X : Universe₀
    Criteria:
    - integer[X]
    - X > 0
    Relation: positive_int ⊆ integer
    Universe level: Universe₁
  }

  class BoundedInt {
    Definition: bounded_int[X, Min, Max]
    where X : Universe₀
    Criteria:
    - integer[X]
    - Min ≤ X ≤ Max
    Relation: bounded_int ⊆ integer
    Universe level: Universe₁
  }

  class NonEmptyStrings {
    Definition: non_empty_string[X]
    where X : Universe₀
    Criteria:
    - string[X]
    - length(X) > 0
    Relation: non_empty_string ⊆ string
    Universe level: Universe₁
  }
}

package "Composite Type Relations (Universe₁)" {
  class Complex {
    Definition (Karuta-style):
    complex[X] where X : Universe₀
    complex[X] :-
      X is (A, B),
      real[A], real[B].

    Interpretation:
    - (A, B) where A is real part
    - B is imaginary part
    Relation: complex ⊆ real × real
    Universe level: Universe₁
  }

  class Employee {
    Definition:
    employee[X] where X : Universe₀
    employee[X] :-
      X is (Name, Age, Salary),
      non_empty_string[Name],
      positive_int[Age],
      positive_int[Salary].

    Relation: employee ⊆ string × ℕ⁺ × ℕ⁺
    Universe level: Universe₁
  }
}

' Universe stratification relationships
U1 --> U0 : classifies values in
U2 --> U1 : types type relations
U3 --> U2 : meta-level

' All type relations live in Universe₁
U1 ..> Number : contains
U1 ..> Naturals : contains
U1 ..> Integers : contains
U1 ..> Rationals : contains
U1 ..> Reals : contains
U1 ..> Booleans : contains
U1 ..> Strings : contains
U1 ..> Scalar : contains

' Type relation hierarchy (within Universe₁)
Number <|-- Naturals : ⊇
Number <|-- Integers : ⊇
Number <|-- Rationals : ⊇
Number <|-- Reals : ⊇

Number <|-- Scalar : ⊇
Booleans <|-- Scalar : ⊇
Strings <|-- Scalar : ⊇

' Subset relations among numeric types
Naturals .up.|> Integers : ⊆
Integers .up.|> Rationals : ⊆
Rationals .up.|> Reals : ⊆

' Constrained types
Integers .down.|> PositiveIntegers : ⊇
Integers .down.|> BoundedInt : ⊇
Strings .down.|> NonEmptyStrings : ⊇

' Composite types (also in Universe₁)
Number .down.|> Complex : number × number
Complex : (view: pair of numbers)

Scalar .down.|> Employee : scalar × scalar × scalar
Employee : (view: string × nat × nat)

note right of Complex
  **Views as Type Relations:**
  Types can be defined as relational views
  over other type relations.

  Example using supertype:
  complex[C] :- C is (R, I),
                number[R], number[I].

  Or more specifically:
  complex[C] :- C is (R, I),
                real[R], real[I].

  Views can use supertypes for flexibility!
  All views live in Universe₁.
end note

note left of Number
  **Core Principle:** Every type is a relation
  Type checking = membership checking in relations
  T1 <: T2 iff T1 ⊆ T2 (subset relation)

  **Supertypes enable polymorphism:**
  A function can accept number[X] and work
  with naturals, integers, rationals, or reals.

  **Universe Levels:**
  All type relations: Universe₁
  All values: Universe₀
  Type of types: Universe₂

  **Erlang Type Mapping:**
  natural → integer() + (≥ 0)
  integer → integer()
  rational → {integer(), integer()}
  real → float()
  string → string()
  boolean → boolean()
end note

note bottom of U0
  **Avoiding Russell's Paradox:**

  Like F*, Domino uses predicative universe
  stratification. The key invariant:

  Type u#i : Type u#(i+1)

  In Domino:
  - Values (3, "hello", true) : Universe₀
  - Type relations (natural, string) : Universe₁
  - Type : Universe₂

  This prevents:
  natural ∈ natural (universe mismatch!)

  A type relation cannot be a member of itself.
  All type relations classify values in Universe₀
  but exist at Universe₁.
end note

@enduml