luau/prototyping/Properties/TypeNormalization.agda

409 lines
25 KiB
Agda
Raw Normal View History

{-# OPTIONS --rewriting #-}
module Properties.TypeNormalization where
open import Luau.Type using (Type; Scalar; nil; number; string; boolean; never; unknown; _⇒_; __; _∩_)
open import Luau.Subtyping using (Tree; Language; ¬Language; function; scalar; unknown; left; right; function-ok₁; function-ok₂; function-err; function-tgt; scalar-function; scalar-function-ok; scalar-function-err; scalar-function-tgt; function-scalar; _,_)
open import Luau.TypeNormalization using (_ⁿ_; _∩ⁿ_; _ᶠ_; _ⁿˢ_; _∩ⁿˢ_; normalize)
open import Luau.Subtyping using (_<:_; _≮:_; witness; never)
open import Properties.Subtyping using (<:-trans; <:-refl; <:-unknown; <:-never; <:--left; <:--right; <:--lub; <:-∩-left; <:-∩-right; <:-∩-glb; <:-∩-symm; <:-function; <:-function--∩; <:-function-∩-; <:-function-; <:-everything; <:-union; <:--assocl; <:--assocr; <:--symm; <:-intersect; -distl-∩-<:; -distr-∩-<:; <:--distr-∩; <:--distl-∩; ∩-distl--<:; <:-∩-distl-; <:-∩-distr-; scalar-∩-function-<:-never; scalar-≢-∩-<:-never)
-- Normal forms for types
data FunType : Type Set
data Normal : Type Set
data FunType where
_⇒_ : {S T} Normal S Normal T FunType (S T)
_∩_ : {F G} FunType F FunType G FunType (F G)
data Normal where
_⇒_ : {S T} Normal S Normal T Normal (S T)
_∩_ : {F G} FunType F FunType G Normal (F G)
__ : {S T} Normal S Scalar T Normal (S T)
never : Normal never
unknown : Normal unknown
data OptScalar : Type Set where
never : OptScalar never
number : OptScalar number
boolean : OptScalar boolean
string : OptScalar string
nil : OptScalar nil
-- Top function type
fun-top : {F} (FunType F) (F <: (never unknown))
fun-top (S T) = <:-function <:-never <:-unknown
fun-top (F G) = <:-trans <:-∩-left (fun-top F)
-- function types are inhabited
fun-function : {F} FunType F Language F function
fun-function (S T) = function
fun-function (F G) = (fun-function F , fun-function G)
fun-≮:-never : {F} FunType F (F ≮: never)
fun-≮:-never F = witness function (fun-function F) never
-- function types aren't scalars
fun-¬scalar : {F S t} (s : Scalar S) FunType F Language F t ¬Language S t
fun-¬scalar s (S T) function = scalar-function s
fun-¬scalar s (S T) (function-ok₁ p) = scalar-function-ok s
fun-¬scalar s (S T) (function-ok₂ p) = scalar-function-ok s
fun-¬scalar s (S T) (function-err p) = scalar-function-err s
fun-¬scalar s (S T) (function-tgt p) = scalar-function-tgt s
fun-¬scalar s (F G) (p₁ , p₂) = fun-¬scalar s G p₂
¬scalar-fun : {F S} FunType F (s : Scalar S) ¬Language F (scalar s)
¬scalar-fun (S T) s = function-scalar s
¬scalar-fun (F G) s = left (¬scalar-fun F s)
scalar-≮:-fun : {F S} FunType F Scalar S S ≮: F
scalar-≮:-fun F s = witness (scalar s) (scalar s) (¬scalar-fun F s)
unknown-≮:-fun : {F} FunType F unknown ≮: F
unknown-≮:-fun F = witness (scalar nil) unknown (¬scalar-fun F nil)
-- Normalization produces normal types
normal : T Normal (normalize T)
normalᶠ : {F} FunType F Normal F
normal-∪ⁿ : {S T} Normal S Normal T Normal (S ∪ⁿ T)
normal-∩ⁿ : {S T} Normal S Normal T Normal (S ∩ⁿ T)
normal-∪ⁿˢ : {S T} Normal S OptScalar T Normal (S ∪ⁿˢ T)
normal-∩ⁿˢ : {S T} Normal S Scalar T OptScalar (S ∩ⁿˢ T)
normal-∪ᶠ : {F G} FunType F FunType G FunType (F ∪ᶠ G)
normal nil = never nil
normal (S T) = (normal S) (normal T)
normal never = never
normal unknown = unknown
normal boolean = never boolean
normal number = never number
normal string = never string
normal (S T) = normal-∪ⁿ (normal S) (normal T)
normal (S T) = normal-∩ⁿ (normal S) (normal T)
normalᶠ (S T) = S T
normalᶠ (F G) = F G
normal-∪ⁿ S (T₁ T₂) = (normal-∪ⁿ S T₁) T₂
normal-∪ⁿ S never = S
normal-∪ⁿ S unknown = unknown
normal-∪ⁿ never (T U) = T U
normal-∪ⁿ never (G₁ G₂) = G₁ G₂
normal-∪ⁿ unknown (T U) = unknown
normal-∪ⁿ unknown (G₁ G₂) = unknown
normal-∪ⁿ (R S) (T U) = normalᶠ (normal-∪ᶠ (R S) (T U))
normal-∪ⁿ (R S) (G₁ G₂) = normalᶠ (normal-∪ᶠ (R S) (G₁ G₂))
normal-∪ⁿ (F₁ F₂) (T U) = normalᶠ (normal-∪ᶠ (F₁ F₂) (T U))
normal-∪ⁿ (F₁ F₂) (G₁ G₂) = normalᶠ (normal-∪ᶠ (F₁ F₂) (G₁ G₂))
normal-∪ⁿ (S₁ S₂) (T₁ T₂) = normal-∪ⁿ S₁ (T₁ T₂) S₂
normal-∪ⁿ (S₁ S₂) (G₁ G₂) = normal-∪ⁿ S₁ (G₁ G₂) S₂
normal-∩ⁿ S never = never
normal-∩ⁿ S unknown = S
normal-∩ⁿ S (T U) = normal-∪ⁿˢ (normal-∩ⁿ S T) (normal-∩ⁿˢ S U )
normal-∩ⁿ never (T U) = never
normal-∩ⁿ unknown (T U) = T U
normal-∩ⁿ (R S) (T U) = (R S) (T U)
normal-∩ⁿ (R S) (T U) = (R S) (T U)
normal-∩ⁿ (R S) (T U) = normal-∩ⁿ R (T U)
normal-∩ⁿ never (T U) = never
normal-∩ⁿ unknown (T U) = T U
normal-∩ⁿ (R S) (T U) = (R S) (T U)
normal-∩ⁿ (R S) (T U) = (R S) (T U)
normal-∩ⁿ (R S) (T U) = normal-∩ⁿ R (T U)
normal-∪ⁿˢ S never = S
normal-∪ⁿˢ never number = never number
normal-∪ⁿˢ unknown number = unknown
normal-∪ⁿˢ (R S) number = (R S) number
normal-∪ⁿˢ (R S) number = (R S) number
normal-∪ⁿˢ (R number) number = R number
normal-∪ⁿˢ (R boolean) number = normal-∪ⁿˢ R number boolean
normal-∪ⁿˢ (R string) number = normal-∪ⁿˢ R number string
normal-∪ⁿˢ (R nil) number = normal-∪ⁿˢ R number nil
normal-∪ⁿˢ never boolean = never boolean
normal-∪ⁿˢ unknown boolean = unknown
normal-∪ⁿˢ (R S) boolean = (R S) boolean
normal-∪ⁿˢ (R S) boolean = (R S) boolean
normal-∪ⁿˢ (R number) boolean = normal-∪ⁿˢ R boolean number
normal-∪ⁿˢ (R boolean) boolean = R boolean
normal-∪ⁿˢ (R string) boolean = normal-∪ⁿˢ R boolean string
normal-∪ⁿˢ (R nil) boolean = normal-∪ⁿˢ R boolean nil
normal-∪ⁿˢ never string = never string
normal-∪ⁿˢ unknown string = unknown
normal-∪ⁿˢ (R S) string = (R S) string
normal-∪ⁿˢ (R S) string = (R S) string
normal-∪ⁿˢ (R number) string = normal-∪ⁿˢ R string number
normal-∪ⁿˢ (R boolean) string = normal-∪ⁿˢ R string boolean
normal-∪ⁿˢ (R string) string = R string
normal-∪ⁿˢ (R nil) string = normal-∪ⁿˢ R string nil
normal-∪ⁿˢ never nil = never nil
normal-∪ⁿˢ unknown nil = unknown
normal-∪ⁿˢ (R S) nil = (R S) nil
normal-∪ⁿˢ (R S) nil = (R S) nil
normal-∪ⁿˢ (R number) nil = normal-∪ⁿˢ R nil number
normal-∪ⁿˢ (R boolean) nil = normal-∪ⁿˢ R nil boolean
normal-∪ⁿˢ (R string) nil = normal-∪ⁿˢ R nil string
normal-∪ⁿˢ (R nil) nil = R nil
normal-∩ⁿˢ never number = never
normal-∩ⁿˢ never boolean = never
normal-∩ⁿˢ never string = never
normal-∩ⁿˢ never nil = never
normal-∩ⁿˢ unknown number = number
normal-∩ⁿˢ unknown boolean = boolean
normal-∩ⁿˢ unknown string = string
normal-∩ⁿˢ unknown nil = nil
normal-∩ⁿˢ (R S) number = never
normal-∩ⁿˢ (R S) boolean = never
normal-∩ⁿˢ (R S) string = never
normal-∩ⁿˢ (R S) nil = never
normal-∩ⁿˢ (R S) number = never
normal-∩ⁿˢ (R S) boolean = never
normal-∩ⁿˢ (R S) string = never
normal-∩ⁿˢ (R S) nil = never
normal-∩ⁿˢ (R number) number = number
normal-∩ⁿˢ (R boolean) number = normal-∩ⁿˢ R number
normal-∩ⁿˢ (R string) number = normal-∩ⁿˢ R number
normal-∩ⁿˢ (R nil) number = normal-∩ⁿˢ R number
normal-∩ⁿˢ (R number) boolean = normal-∩ⁿˢ R boolean
normal-∩ⁿˢ (R boolean) boolean = boolean
normal-∩ⁿˢ (R string) boolean = normal-∩ⁿˢ R boolean
normal-∩ⁿˢ (R nil) boolean = normal-∩ⁿˢ R boolean
normal-∩ⁿˢ (R number) string = normal-∩ⁿˢ R string
normal-∩ⁿˢ (R boolean) string = normal-∩ⁿˢ R string
normal-∩ⁿˢ (R string) string = string
normal-∩ⁿˢ (R nil) string = normal-∩ⁿˢ R string
normal-∩ⁿˢ (R number) nil = normal-∩ⁿˢ R nil
normal-∩ⁿˢ (R boolean) nil = normal-∩ⁿˢ R nil
normal-∩ⁿˢ (R string) nil = normal-∩ⁿˢ R nil
normal-∩ⁿˢ (R nil) nil = nil
normal-∪ᶠ (R S) (T U) = (normal-∩ⁿ R T) (normal-∪ⁿ S U)
normal-∪ᶠ (R S) (G H) = normal-∪ᶠ (R S) G normal-∪ᶠ (R S) H
normal-∪ᶠ (E F) G = normal-∪ᶠ E G normal-∪ᶠ F G
scalar-∩-fun-<:-never : {F S} FunType F Scalar S (F S) <: never
scalar-∩-fun-<:-never (T U) S = scalar-∩-function-<:-never S
scalar-∩-fun-<:-never (F G) S = <:-trans (<:-intersect <:-∩-left <:-refl) (scalar-∩-fun-<:-never F S)
flipper : {S T U} ((S T) U) <: ((S U) T)
flipper = <:-trans <:--assocr (<:-trans (<:-union <:-refl <:--symm) <:--assocl)
∩-<:-∩ⁿ : {S T} Normal S Normal T (S T) <: (S ∩ⁿ T)
∩ⁿ-<:-∩ : {S T} Normal S Normal T (S ∩ⁿ T) <: (S T)
∩-<:-∩ⁿˢ : {S T} Normal S Scalar T (S T) <: (S ∩ⁿˢ T)
∩ⁿˢ-<:-∩ : {S T} Normal S Scalar T (S ∩ⁿˢ T) <: (S T)
∪ᶠ-<:- : {F G} FunType F FunType G (F ∪ᶠ G) <: (F G)
∪ⁿ-<:- : {S T} Normal S Normal T (S ∪ⁿ T) <: (S T)
-<:-∪ⁿ : {S T} Normal S Normal T (S T) <: (S ∪ⁿ T)
∪ⁿˢ-<:- : {S T} Normal S OptScalar T (S ∪ⁿˢ T) <: (S T)
-<:-∪ⁿˢ : {S T} Normal S OptScalar T (S T) <: (S ∪ⁿˢ T)
∩-<:-∩ⁿ S never = <:-∩-right
∩-<:-∩ⁿ S unknown = <:-∩-left
∩-<:-∩ⁿ S (T U) = <:-trans <:-∩-distl- (<:-trans (<:-union (∩-<:-∩ⁿ S T) (∩-<:-∩ⁿˢ S U)) (-<:-∪ⁿˢ (normal-∩ⁿ S T) (normal-∩ⁿˢ S U)) )
∩-<:-∩ⁿ never (T U) = <:-∩-left
∩-<:-∩ⁿ unknown (T U) = <:-∩-right
∩-<:-∩ⁿ (R S) (T U) = <:-refl
∩-<:-∩ⁿ (R S) (T U) = <:-refl
∩-<:-∩ⁿ (R S) (T U) = <:-trans <:-∩-distr- (<:-trans (<:-union (∩-<:-∩ⁿ R (T U)) (<:-trans <:-∩-symm (∩-<:-∩ⁿˢ (T U) S))) (<:--lub <:-refl <:-never))
∩-<:-∩ⁿ never (T U) = <:-∩-left
∩-<:-∩ⁿ unknown (T U) = <:-∩-right
∩-<:-∩ⁿ (R S) (T U) = <:-refl
∩-<:-∩ⁿ (R S) (T U) = <:-refl
∩-<:-∩ⁿ (R S) (T U) = <:-trans <:-∩-distr- (<:-trans (<:-union (∩-<:-∩ⁿ R (T U)) (<:-trans <:-∩-symm (∩-<:-∩ⁿˢ (T U) S))) (<:--lub <:-refl <:-never))
∩ⁿ-<:-∩ S never = <:-never
∩ⁿ-<:-∩ S unknown = <:-∩-glb <:-refl <:-unknown
∩ⁿ-<:-∩ S (T U) = <:-trans (∪ⁿˢ-<:- (normal-∩ⁿ S T) (normal-∩ⁿˢ S U)) (<:-trans (<:-union (∩ⁿ-<:-∩ S T) (∩ⁿˢ-<:-∩ S U)) ∩-distl--<:)
∩ⁿ-<:-∩ never (T U) = <:-never
∩ⁿ-<:-∩ unknown (T U) = <:-∩-glb <:-unknown <:-refl
∩ⁿ-<:-∩ (R S) (T U) = <:-refl
∩ⁿ-<:-∩ (R S) (T U) = <:-refl
∩ⁿ-<:-∩ (R S) (T U) = <:-trans (∩ⁿ-<:-∩ R (T U)) (<:-∩-glb (<:-trans <:-∩-left <:--left) <:-∩-right)
∩ⁿ-<:-∩ never (T U) = <:-never
∩ⁿ-<:-∩ unknown (T U) = <:-∩-glb <:-unknown <:-refl
∩ⁿ-<:-∩ (R S) (T U) = <:-refl
∩ⁿ-<:-∩ (R S) (T U) = <:-refl
∩ⁿ-<:-∩ (R S) (T U) = <:-trans (∩ⁿ-<:-∩ R (T U)) (<:-∩-glb (<:-trans <:-∩-left <:--left) <:-∩-right)
∩-<:-∩ⁿˢ never number = <:-∩-left
∩-<:-∩ⁿˢ never boolean = <:-∩-left
∩-<:-∩ⁿˢ never string = <:-∩-left
∩-<:-∩ⁿˢ never nil = <:-∩-left
∩-<:-∩ⁿˢ unknown T = <:-∩-right
∩-<:-∩ⁿˢ (R S) T = scalar-∩-fun-<:-never (R S) T
∩-<:-∩ⁿˢ (F G) T = scalar-∩-fun-<:-never (F G) T
∩-<:-∩ⁿˢ (R number) number = <:-∩-right
∩-<:-∩ⁿˢ (R boolean) number = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R number) (scalar-≢-∩-<:-never boolean number (λ ())))
∩-<:-∩ⁿˢ (R string) number = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R number) (scalar-≢-∩-<:-never string number (λ ())))
∩-<:-∩ⁿˢ (R nil) number = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R number) (scalar-≢-∩-<:-never nil number (λ ())))
∩-<:-∩ⁿˢ (R number) boolean = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R boolean) (scalar-≢-∩-<:-never number boolean (λ ())))
∩-<:-∩ⁿˢ (R boolean) boolean = <:-∩-right
∩-<:-∩ⁿˢ (R string) boolean = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R boolean) (scalar-≢-∩-<:-never string boolean (λ ())))
∩-<:-∩ⁿˢ (R nil) boolean = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R boolean) (scalar-≢-∩-<:-never nil boolean (λ ())))
∩-<:-∩ⁿˢ (R number) string = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R string) (scalar-≢-∩-<:-never number string (λ ())))
∩-<:-∩ⁿˢ (R boolean) string = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R string) (scalar-≢-∩-<:-never boolean string (λ ())))
∩-<:-∩ⁿˢ (R string) string = <:-∩-right
∩-<:-∩ⁿˢ (R nil) string = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R string) (scalar-≢-∩-<:-never nil string (λ ())))
∩-<:-∩ⁿˢ (R number) nil = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R nil) (scalar-≢-∩-<:-never number nil (λ ())))
∩-<:-∩ⁿˢ (R boolean) nil = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R nil) (scalar-≢-∩-<:-never boolean nil (λ ())))
∩-<:-∩ⁿˢ (R string) nil = <:-trans <:-∩-distr- (<:--lub (∩-<:-∩ⁿˢ R nil) (scalar-≢-∩-<:-never string nil (λ ())))
∩-<:-∩ⁿˢ (R nil) nil = <:-∩-right
∩ⁿˢ-<:-∩ never T = <:-never
∩ⁿˢ-<:-∩ unknown T = <:-∩-glb <:-unknown <:-refl
∩ⁿˢ-<:-∩ (R S) T = <:-never
∩ⁿˢ-<:-∩ (F G) T = <:-never
∩ⁿˢ-<:-∩ (R number) number = <:-∩-glb <:--right <:-refl
∩ⁿˢ-<:-∩ (R boolean) number = <:-trans (∩ⁿˢ-<:-∩ R number) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R string) number = <:-trans (∩ⁿˢ-<:-∩ R number) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R nil) number = <:-trans (∩ⁿˢ-<:-∩ R number) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R number) boolean = <:-trans (∩ⁿˢ-<:-∩ R boolean) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R boolean) boolean = <:-∩-glb <:--right <:-refl
∩ⁿˢ-<:-∩ (R string) boolean = <:-trans (∩ⁿˢ-<:-∩ R boolean) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R nil) boolean = <:-trans (∩ⁿˢ-<:-∩ R boolean) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R number) string = <:-trans (∩ⁿˢ-<:-∩ R string) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R boolean) string = <:-trans (∩ⁿˢ-<:-∩ R string) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R string) string = <:-∩-glb <:--right <:-refl
∩ⁿˢ-<:-∩ (R nil) string = <:-trans (∩ⁿˢ-<:-∩ R string) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R number) nil = <:-trans (∩ⁿˢ-<:-∩ R nil) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R boolean) nil = <:-trans (∩ⁿˢ-<:-∩ R nil) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R string) nil = <:-trans (∩ⁿˢ-<:-∩ R nil) (<:-intersect <:--left <:-refl)
∩ⁿˢ-<:-∩ (R nil) nil = <:-∩-glb <:--right <:-refl
∪ᶠ-<:- (R S) (T U) = <:-trans (<:-function (∩-<:-∩ⁿ R T) (∪ⁿ-<:- S U)) <:-function--∩
∪ᶠ-<:- (R S) (G H) = <:-trans (<:-intersect (∪ᶠ-<:- (R S) G) (∪ᶠ-<:- (R S) H)) -distl-∩-<:
∪ᶠ-<:- (E F) G = <:-trans (<:-intersect (∪ᶠ-<:- E G) (∪ᶠ-<:- F G)) -distr-∩-<:
-<:-∪ᶠ : {F G} FunType F FunType G (F G) <: (F ∪ᶠ G)
-<:-∪ᶠ (R S) (T U) = <:-trans <:-function- (<:-function (∩ⁿ-<:-∩ R T) (-<:-∪ⁿ S U))
-<:-∪ᶠ (R S) (G H) = <:-trans <:--distl-∩ (<:-intersect (-<:-∪ᶠ (R S) G) (-<:-∪ᶠ (R S) H))
-<:-∪ᶠ (E F) G = <:-trans <:--distr-∩ (<:-intersect (-<:-∪ᶠ E G) (-<:-∪ᶠ F G))
∪ⁿˢ-<:- S never = <:--left
∪ⁿˢ-<:- never number = <:-refl
∪ⁿˢ-<:- never boolean = <:-refl
∪ⁿˢ-<:- never string = <:-refl
∪ⁿˢ-<:- never nil = <:-refl
∪ⁿˢ-<:- unknown number = <:--left
∪ⁿˢ-<:- unknown boolean = <:--left
∪ⁿˢ-<:- unknown string = <:--left
∪ⁿˢ-<:- unknown nil = <:--left
∪ⁿˢ-<:- (R S) number = <:-refl
∪ⁿˢ-<:- (R S) boolean = <:-refl
∪ⁿˢ-<:- (R S) string = <:-refl
∪ⁿˢ-<:- (R S) nil = <:-refl
∪ⁿˢ-<:- (R S) number = <:-refl
∪ⁿˢ-<:- (R S) boolean = <:-refl
∪ⁿˢ-<:- (R S) string = <:-refl
∪ⁿˢ-<:- (R S) nil = <:-refl
∪ⁿˢ-<:- (R number) number = <:-union <:--left <:-refl
∪ⁿˢ-<:- (R boolean) number = <:-trans (<:-union (∪ⁿˢ-<:- R number) <:-refl) flipper
∪ⁿˢ-<:- (R string) number = <:-trans (<:-union (∪ⁿˢ-<:- R number) <:-refl) flipper
∪ⁿˢ-<:- (R nil) number = <:-trans (<:-union (∪ⁿˢ-<:- R number) <:-refl) flipper
∪ⁿˢ-<:- (R number) boolean = <:-trans (<:-union (∪ⁿˢ-<:- R boolean) <:-refl) flipper
∪ⁿˢ-<:- (R boolean) boolean = <:-union <:--left <:-refl
∪ⁿˢ-<:- (R string) boolean = <:-trans (<:-union (∪ⁿˢ-<:- R boolean) <:-refl) flipper
∪ⁿˢ-<:- (R nil) boolean = <:-trans (<:-union (∪ⁿˢ-<:- R boolean) <:-refl) flipper
∪ⁿˢ-<:- (R number) string = <:-trans (<:-union (∪ⁿˢ-<:- R string) <:-refl) flipper
∪ⁿˢ-<:- (R boolean) string = <:-trans (<:-union (∪ⁿˢ-<:- R string) <:-refl) flipper
∪ⁿˢ-<:- (R string) string = <:-union <:--left <:-refl
∪ⁿˢ-<:- (R nil) string = <:-trans (<:-union (∪ⁿˢ-<:- R string) <:-refl) flipper
∪ⁿˢ-<:- (R number) nil = <:-trans (<:-union (∪ⁿˢ-<:- R nil) <:-refl) flipper
∪ⁿˢ-<:- (R boolean) nil = <:-trans (<:-union (∪ⁿˢ-<:- R nil) <:-refl) flipper
∪ⁿˢ-<:- (R string) nil = <:-trans (<:-union (∪ⁿˢ-<:- R nil) <:-refl) flipper
∪ⁿˢ-<:- (R nil) nil = <:-union <:--left <:-refl
-<:-∪ⁿˢ T never = <:--lub <:-refl <:-never
-<:-∪ⁿˢ never number = <:-refl
-<:-∪ⁿˢ never boolean = <:-refl
-<:-∪ⁿˢ never string = <:-refl
-<:-∪ⁿˢ never nil = <:-refl
-<:-∪ⁿˢ unknown number = <:-unknown
-<:-∪ⁿˢ unknown boolean = <:-unknown
-<:-∪ⁿˢ unknown string = <:-unknown
-<:-∪ⁿˢ unknown nil = <:-unknown
-<:-∪ⁿˢ (R S) number = <:-refl
-<:-∪ⁿˢ (R S) boolean = <:-refl
-<:-∪ⁿˢ (R S) string = <:-refl
-<:-∪ⁿˢ (R S) nil = <:-refl
-<:-∪ⁿˢ (R S) number = <:-refl
-<:-∪ⁿˢ (R S) boolean = <:-refl
-<:-∪ⁿˢ (R S) string = <:-refl
-<:-∪ⁿˢ (R S) nil = <:-refl
-<:-∪ⁿˢ (R number) number = <:--lub <:-refl <:--right
-<:-∪ⁿˢ (R boolean) number = <:-trans flipper (<:-union (-<:-∪ⁿˢ R number) <:-refl)
-<:-∪ⁿˢ (R string) number = <:-trans flipper (<:-union (-<:-∪ⁿˢ R number) <:-refl)
-<:-∪ⁿˢ (R nil) number = <:-trans flipper (<:-union (-<:-∪ⁿˢ R number) <:-refl)
-<:-∪ⁿˢ (R number) boolean = <:-trans flipper (<:-union (-<:-∪ⁿˢ R boolean) <:-refl)
-<:-∪ⁿˢ (R boolean) boolean = <:--lub <:-refl <:--right
-<:-∪ⁿˢ (R string) boolean = <:-trans flipper (<:-union (-<:-∪ⁿˢ R boolean) <:-refl)
-<:-∪ⁿˢ (R nil) boolean = <:-trans flipper (<:-union (-<:-∪ⁿˢ R boolean) <:-refl)
-<:-∪ⁿˢ (R number) string = <:-trans flipper (<:-union (-<:-∪ⁿˢ R string) <:-refl)
-<:-∪ⁿˢ (R boolean) string = <:-trans flipper (<:-union (-<:-∪ⁿˢ R string) <:-refl)
-<:-∪ⁿˢ (R string) string = <:--lub <:-refl <:--right
-<:-∪ⁿˢ (R nil) string = <:-trans flipper (<:-union (-<:-∪ⁿˢ R string) <:-refl)
-<:-∪ⁿˢ (R number) nil = <:-trans flipper (<:-union (-<:-∪ⁿˢ R nil) <:-refl)
-<:-∪ⁿˢ (R boolean) nil = <:-trans flipper (<:-union (-<:-∪ⁿˢ R nil) <:-refl)
-<:-∪ⁿˢ (R string) nil = <:-trans flipper (<:-union (-<:-∪ⁿˢ R nil) <:-refl)
-<:-∪ⁿˢ (R nil) nil = <:--lub <:-refl <:--right
∪ⁿ-<:- S never = <:--left
∪ⁿ-<:- S unknown = <:--right
∪ⁿ-<:- never (T U) = <:--right
∪ⁿ-<:- unknown (T U) = <:--left
∪ⁿ-<:- (R S) (T U) = ∪ᶠ-<:- (R S) (T U)
∪ⁿ-<:- (R S) (T U) = ∪ᶠ-<:- (R S) (T U)
∪ⁿ-<:- (R S) (T U) = <:-trans (<:-union (∪ⁿ-<:- R (T U)) <:-refl) (<:--lub (<:--lub (<:-trans <:--left <:--left) <:--right) (<:-trans <:--right <:--left))
∪ⁿ-<:- never (T U) = <:--right
∪ⁿ-<:- unknown (T U) = <:--left
∪ⁿ-<:- (R S) (T U) = ∪ᶠ-<:- (R S) (T U)
∪ⁿ-<:- (R S) (T U) = ∪ᶠ-<:- (R S) (T U)
∪ⁿ-<:- (R S) (T U) = <:-trans (<:-union (∪ⁿ-<:- R (T U)) <:-refl) (<:--lub (<:--lub (<:-trans <:--left <:--left) <:--right) (<:-trans <:--right <:--left))
∪ⁿ-<:- S (T U) = <:--lub (<:-trans (∪ⁿ-<:- S T) (<:-union <:-refl <:--left)) (<:-trans <:--right <:--right)
-<:-∪ⁿ S never = <:--lub <:-refl <:-never
-<:-∪ⁿ S unknown = <:-unknown
-<:-∪ⁿ never (T U) = <:--lub <:-never <:-refl
-<:-∪ⁿ unknown (T U) = <:-unknown
-<:-∪ⁿ (R S) (T U) = -<:-∪ᶠ (R S) (T U)
-<:-∪ⁿ (R S) (T U) = -<:-∪ᶠ (R S) (T U)
-<:-∪ⁿ (R S) (T U) = <:-trans <:--assocr (<:-trans (<:-union <:-refl <:--symm) (<:-trans <:--assocl (<:-union (-<:-∪ⁿ R (T U)) <:-refl)))
-<:-∪ⁿ never (T U) = <:--lub <:-never <:-refl
-<:-∪ⁿ unknown (T U) = <:-unknown
-<:-∪ⁿ (R S) (T U) = -<:-∪ᶠ (R S) (T U)
-<:-∪ⁿ (R S) (T U) = -<:-∪ᶠ (R S) (T U)
-<:-∪ⁿ (R S) (T U) = <:-trans <:--assocr (<:-trans (<:-union <:-refl <:--symm) (<:-trans <:--assocl (<:-union (-<:-∪ⁿ R (T U)) <:-refl)))
-<:-∪ⁿ never (T U) = <:-trans <:--assocl (<:-union (-<:-∪ⁿ never T) <:-refl)
-<:-∪ⁿ unknown (T U) = <:-trans <:--assocl (<:-union (-<:-∪ⁿ unknown T) <:-refl)
-<:-∪ⁿ (R S) (T U) = <:-trans <:--assocl (<:-union (-<:-∪ⁿ (R S) T) <:-refl)
-<:-∪ⁿ (R S) (T U) = <:-trans <:--assocl (<:-union (-<:-∪ⁿ (R S) T) <:-refl)
-<:-∪ⁿ (R S) (T U) = <:-trans <:--assocl (<:-union (-<:-∪ⁿ (R S) T) <:-refl)
normalize-<: : T normalize T <: T
<:-normalize : T T <: normalize T
<:-normalize nil = <:--right
<:-normalize (S T) = <:-function (normalize-<: S) (<:-normalize T)
<:-normalize never = <:-refl
<:-normalize unknown = <:-refl
<:-normalize boolean = <:--right
<:-normalize number = <:--right
<:-normalize string = <:--right
<:-normalize (S T) = <:-trans (<:-union (<:-normalize S) (<:-normalize T)) (-<:-∪ⁿ (normal S) (normal T))
<:-normalize (S T) = <:-trans (<:-intersect (<:-normalize S) (<:-normalize T)) (∩-<:-∩ⁿ (normal S) (normal T))
normalize-<: nil = <:--lub <:-never <:-refl
normalize-<: (S T) = <:-function (<:-normalize S) (normalize-<: T)
normalize-<: never = <:-refl
normalize-<: unknown = <:-refl
normalize-<: boolean = <:--lub <:-never <:-refl
normalize-<: number = <:--lub <:-never <:-refl
normalize-<: string = <:--lub <:-never <:-refl
normalize-<: (S T) = <:-trans (∪ⁿ-<:- (normal S) (normal T)) (<:-union (normalize-<: S) (normalize-<: T))
normalize-<: (S T) = <:-trans (∩ⁿ-<:-∩ (normal S) (normal T)) (<:-intersect (normalize-<: S) (normalize-<: T))