luau/prototyping/Properties/TypeNormalization.agda

409 lines
25 KiB
Agda
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{-# 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))