luau/prototyping/Properties/TypeSaturation.agda

434 lines
28 KiB
Agda
Raw Normal View History

{-# OPTIONS --rewriting #-}
module Properties.TypeSaturation where
open import Agda.Builtin.Equality using (_≡_; refl)
open import FFI.Data.Either using (Either; Left; Right)
open import Luau.Subtyping using (Tree; Language; ¬Language; _<:_; _≮:_; witness; scalar; function; function-err; function-ok; function-ok₁; function-ok₂; scalar-function; _,_; never)
open import Luau.Type using (Type; _⇒_; _∩_; __; never; unknown)
open import Luau.TypeNormalization using (_∩ⁿ_; _ⁿ_)
open import Luau.TypeSaturation using (_⋓_; _⋒_; _∩ᵘ_; _∩ⁱ_; -saturate; ∩-saturate; saturate)
open import Properties.Subtyping using (dec-language; language-comp; <:-impl-⊇; <:-refl; <:-trans; <:-trans-≮:; <:-impl-¬≮: ; <:-never; <:-unknown; <:-function; <:-union; <:--symm; <:--left; <:--right; <:--lub; <:--assocl; <:--assocr; <:-intersect; <:-∩-symm; <:-∩-left; <:-∩-right; <:-∩-glb; ≮:-function-left; ≮:-function-right; <:-function-∩-; <:-function-∩-∩; <:-∩-assocl; <:-∩-assocr; ∩-<:-; <:-∩-distl-; ∩-distl--<:; <:-∩-distr-; ∩-distr--<:)
open import Properties.TypeNormalization using (Normal; FunType; _⇒_; _∩_; __; never; unknown; normal-∪ⁿ; normal-∩ⁿ; ∪ⁿ-<:-; -<:-∪ⁿ; ∩ⁿ-<:-∩; ∩-<:-∩ⁿ)
open import Properties.Contradiction using (CONTRADICTION)
open import Properties.Functions using (_∘_)
-- Saturation preserves normalization
normal-⋒ : {F G} FunType F FunType G FunType (F G)
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
normal-⋓ : {F G} FunType F FunType G FunType (F G)
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
normal-∩-saturate : {F} FunType F FunType (∩-saturate F)
normal-∩-saturate (S T) = S T
normal-∩-saturate (F G) = (normal-∩-saturate F normal-∩-saturate G) normal-⋒ (normal-∩-saturate F) (normal-∩-saturate G)
normal--saturate : {F} FunType F FunType (-saturate F)
normal--saturate (S T) = S T
normal--saturate (F G) = (normal--saturate F normal--saturate G) normal-⋓ (normal--saturate F) (normal--saturate G)
normal-saturate : {F} FunType F FunType (saturate F)
normal-saturate F = normal--saturate (normal-∩-saturate F)
-- Saturation resects subtyping
-saturate-<: : {F} FunType F -saturate F <: F
-saturate-<: (S T) = <:-refl
-saturate-<: (F G) = <:-trans <:-∩-left (<:-intersect (-saturate-<: F) (-saturate-<: G))
∩-saturate-<: : {F} FunType F ∩-saturate F <: F
∩-saturate-<: (S T) = <:-refl
∩-saturate-<: (F G) = <:-trans <:-∩-left (<:-intersect (∩-saturate-<: F) (∩-saturate-<: G))
saturate-<: : {F} FunType F saturate F <: F
saturate-<: F = <:-trans (-saturate-<: (normal-∩-saturate F)) (∩-saturate-<: F)
∩-<:-⋓ : {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 (<:-∩-glb (<:-intersect <:-refl <:-∩-left) (<:-intersect <:-refl <:-∩-right)) (<:-intersect (∩-<:-⋓ (R S) G) (∩-<:-⋓ (R S) H))
∩-<:-⋓ (E F) G = <:-trans (<:-∩-glb (<:-intersect <:-∩-left <:-refl) (<:-intersect <:-∩-right <:-refl)) (<:-intersect (∩-<:-⋓ E G) (∩-<:-⋓ F G))
∩-<:-⋒ : {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 (<:-∩-glb (<:-intersect <:-refl <:-∩-left) (<:-intersect <:-refl <:-∩-right)) (<:-intersect (∩-<:-⋒ (R S) G) (∩-<:-⋒ (R S) H))
∩-<:-⋒ (E F) G = <:-trans (<:-∩-glb (<:-intersect <:-∩-left <:-refl) (<:-intersect <:-∩-right <:-refl)) (<:-intersect (∩-<:-⋒ E G) (∩-<:-⋒ F G))
<:--saturate : {F} FunType F F <: -saturate F
<:--saturate (S T) = <:-refl
<:--saturate (F G) = <:-∩-glb (<:-intersect (<:--saturate F) (<:--saturate G)) (<:-trans (<:-intersect (<:--saturate F) (<:--saturate G)) (∩-<:-⋓ (normal--saturate F) (normal--saturate G)))
<:-∩-saturate : {F} FunType F F <: ∩-saturate F
<:-∩-saturate (S T) = <:-refl
<:-∩-saturate (F G) = <:-∩-glb (<:-intersect (<:-∩-saturate F) (<:-∩-saturate G)) (<:-trans (<:-intersect (<:-∩-saturate F) (<:-∩-saturate G)) (∩-<:-⋒ (normal-∩-saturate F) (normal-∩-saturate G)))
<:-saturate : {F} FunType F F <: saturate F
<:-saturate F = <:-trans (<:-∩-saturate F) (<:--saturate (normal-∩-saturate F))
-- Overloads F is the set of overloads of F
data Overloads : Type Type Set where
here : {S T} Overloads (S T) (S T)
left : {S T F G} Overloads F (S T) Overloads (F G) (S T)
right : {S T F G} Overloads G (S T) Overloads (F G) (S T)
normal-overload-src : {F S T} FunType F Overloads F (S T) Normal S
normal-overload-src (S T) here = S
normal-overload-src (F G) (left o) = normal-overload-src F o
normal-overload-src (F G) (right o) = normal-overload-src G o
normal-overload-tgt : {F S T} FunType F Overloads F (S T) Normal T
normal-overload-tgt (S T) here = T
normal-overload-tgt (F G) (left o) = normal-overload-tgt F o
normal-overload-tgt (F G) (right o) = normal-overload-tgt G o
-- An inductive presentation of the overloads of F ⋓ G
data -Lift (P Q : Type Set) : Type Set where
union : {R S T U}
P (R S)
Q (T U)
--------------------
-Lift P Q ((R T) (S U))
-- An inductive presentation of the overloads of F ⋒ G
data ∩-Lift (P Q : Type Set) : Type Set where
intersect : {R S T U}
P (R S)
Q (T U)
--------------------
∩-Lift P Q ((R T) (S U))
-- An inductive presentation of the overloads of -saturate F
data -Saturate (P : Type Set) : Type Set where
base : {S T}
P (S T)
--------------------
-Saturate P (S T)
union : {R S T U}
-Saturate P (R S)
-Saturate P (T U)
--------------------
-Saturate P ((R T) (S U))
-- An inductive presentation of the overloads of ∩-saturate F
data ∩-Saturate (P : Type Set) : Type Set where
base : {S T}
P (S T)
--------------------
∩-Saturate P (S T)
intersect : {R S T U}
∩-Saturate P (R S)
∩-Saturate P (T U)
--------------------
∩-Saturate P ((R T) (S U))
-- The <:-up-closure of a set of function types
data <:-Close (P : Type Set) : Type Set where
defn : {R S T U}
P (S T)
R <: S
T <: U
------------------
<:-Close P (R U)
-- F ⊆ᵒ G whenever every overload of F is an overload of G
_⊆ᵒ_ : Type Type Set
F ⊆ᵒ G = {S T} Overloads F (S T) Overloads G (S T)
-- F <:ᵒ G when every overload of G is a supertype of an overload of F
_<:ᵒ_ : Type Type Set
_<:ᵒ_ F G = {S T} Overloads G (S T) <:-Close (Overloads F) (S T)
-- P ⊂: Q when any type in P is a subtype of some type in Q
_⊂:_ : (Type Set) (Type Set) Set
P ⊂: Q = {S T} P (S T) <:-Close Q (S T)
-- <:-Close is a monad
just : {P S T} P (S T) <:-Close P (S T)
just p = defn p <:-refl <:-refl
infixl 5 _>>=_ _>>=ˡ_ _>>=ʳ_
_>>=_ : {P Q S T} <:-Close P (S T) (P ⊂: Q) <:-Close Q (S T)
(defn p p₁ p₂) >>= P⊂Q with P⊂Q p
(defn p p₁ p₂) >>= P⊂Q | defn q q₁ q₂ = defn q (<:-trans p₁ q₁) (<:-trans q₂ p₂)
_>>=ˡ_ : {P R S T} <:-Close P (S T) (R <: S) <:-Close P (R T)
(defn p p₁ p₂) >>=ˡ q = defn p (<:-trans q p₁) p₂
_>>=ʳ_ : {P S T U} <:-Close P (S T) (T <: U) <:-Close P (S U)
(defn p p₁ p₂) >>=ʳ q = defn p p₁ (<:-trans p₂ q)
-- Properties of ⊂:
⊂:-refl : {P} P ⊂: P
:-refl p = just p
_[]_ : {P Q R S T U} <:-Close P (R S) <:-Close Q (T U) <:-Close (-Lift P Q) ((R T) (S U))
(defn p p₁ p₂) [] (defn q q₁ q₂) = defn (union p q) (<:-union p₁ q₁) (<:-union p₂ q₂)
_[∩]_ : {P Q R S T U} <:-Close P (R S) <:-Close Q (T U) <:-Close (∩-Lift P Q) ((R T) (S U))
(defn p p₁ p₂) [∩] (defn q q₁ q₂) = defn (intersect p q) (<:-intersect p₁ q₁) (<:-intersect p₂ q₂)
⊂:-∩-saturate-inj : {P} P ⊂: ∩-Saturate P
:-∩-saturate-inj p = defn (base p) <:-refl <:-refl
⊂:--saturate-inj : {P} P ⊂: -Saturate P
:--saturate-inj p = just (base p)
⊂:-∩-lift-saturate : {P} ∩-Lift (∩-Saturate P) (∩-Saturate P) ⊂: ∩-Saturate P
:-∩-lift-saturate (intersect p q) = just (intersect p q)
⊂:--lift-saturate : {P} -Lift (-Saturate P) (-Saturate P) ⊂: -Saturate P
:--lift-saturate (union p q) = just (union p q)
⊂:-∩-lift : {P Q R S} (P ⊂: Q) (R ⊂: S) (∩-Lift P R ⊂: ∩-Lift Q S)
:-∩-lift P⊂Q R⊂S (intersect n o) = P⊂Q n [∩] R⊂S o
⊂:--lift : {P Q R S} (P ⊂: Q) (R ⊂: S) (-Lift P R ⊂: -Lift Q S)
:--lift P⊂Q R⊂S (union n o) = P⊂Q n [] R⊂S o
⊂:-∩-saturate : {P Q} (P ⊂: Q) (∩-Saturate P ⊂: ∩-Saturate Q)
:-∩-saturate P⊂Q (base p) = P⊂Q p >>= ⊂:-∩-saturate-inj
:-∩-saturate P⊂Q (intersect p q) = (⊂:-∩-saturate P⊂Q p [∩] ⊂:-∩-saturate P⊂Q q) >>= ⊂:-∩-lift-saturate
⊂:--saturate : {P Q} (P ⊂: Q) (-Saturate P ⊂: -Saturate Q)
:--saturate P⊂Q (base p) = P⊂Q p >>= ⊂:--saturate-inj
:--saturate P⊂Q (union p q) = (⊂:--saturate P⊂Q p [] ⊂:--saturate P⊂Q q) >>= ⊂:--lift-saturate
⊂:-∩-saturate-indn : {P Q} (P ⊂: Q) (∩-Lift Q Q ⊂: Q) (∩-Saturate P ⊂: Q)
:-∩-saturate-indn P⊂Q QQ⊂Q (base p) = P⊂Q p
:-∩-saturate-indn P⊂Q QQ⊂Q (intersect p q) = (⊂:-∩-saturate-indn P⊂Q QQ⊂Q p [∩] ⊂:-∩-saturate-indn P⊂Q QQ⊂Q q) >>= QQ⊂Q
⊂:--saturate-indn : {P Q} (P ⊂: Q) (-Lift Q Q ⊂: Q) (-Saturate P ⊂: Q)
:--saturate-indn P⊂Q QQ⊂Q (base p) = P⊂Q p
:--saturate-indn P⊂Q QQ⊂Q (union p q) = (⊂:--saturate-indn P⊂Q QQ⊂Q p [] ⊂:--saturate-indn P⊂Q QQ⊂Q q) >>= QQ⊂Q
-saturate-resp-∩-saturation : {P} (∩-Lift P P ⊂: P) (∩-Lift (-Saturate P) (-Saturate P) ⊂: -Saturate P)
-saturate-resp-∩-saturation ∩P⊂P (intersect (base p) (base q)) = ∩P⊂P (intersect p q) >>= ⊂:--saturate-inj
-saturate-resp-∩-saturation ∩P⊂P (intersect p (union q q₁)) = (-saturate-resp-∩-saturation ∩P⊂P (intersect p q) [] -saturate-resp-∩-saturation ∩P⊂P (intersect p q₁)) >>= ⊂:--lift-saturate >>=ˡ <:-∩-distl- >>=ʳ ∩-distl--<:
-saturate-resp-∩-saturation ∩P⊂P (intersect (union p p₁) q) = (-saturate-resp-∩-saturation ∩P⊂P (intersect p q) [] -saturate-resp-∩-saturation ∩P⊂P (intersect p₁ q)) >>= ⊂:--lift-saturate >>=ˡ <:-∩-distr- >>=ʳ ∩-distr--<:
ov-language : {F t} FunType F ( {S T} Overloads F (S T) Language (S T) t) Language F t
ov-language (S T) p = p here
ov-language (F G) p = (ov-language F (p left) , ov-language G (p right))
ov-<: : {F R S T U} FunType F Overloads F (R S) ((R S) <: (T U)) F <: (T U)
ov-<: F here p = p
ov-<: (F G) (left o) p = <:-trans <:-∩-left (ov-<: F o p)
ov-<: (F G) (right o) p = <:-trans <:-∩-right (ov-<: G o p)
<:ᵒ-impl-<: : {F G} FunType F FunType G (F <:ᵒ G) (F <: G)
<:ᵒ-impl-<: F (T U) F<G with F<G here
<:ᵒ-impl-<: F (T U) F<G | defn o o₁ o₂ = ov-<: F o (<:-function o₁ o₂)
<:ᵒ-impl-<: F (G H) F<G = <:-∩-glb (<:ᵒ-impl-<: F G (F<G left)) (<:ᵒ-impl-<: F H (F<G right))
⊂:-overloads-left : {F G} Overloads F ⊂: Overloads (F G)
:-overloads-left p = just (left p)
⊂:-overloads-right : {F G} Overloads G ⊂: Overloads (F G)
:-overloads-right p = just (right p)
⊂:-overloads-⋒ : {F G} FunType F FunType G ∩-Lift (Overloads F) (Overloads G) ⊂: Overloads (F G)
:-overloads-⋒ (R S) (T U) (intersect here here) = defn here (∩-<:-∩ⁿ R T) (∩ⁿ-<:-∩ S U)
:-overloads-⋒ (R S) (G H) (intersect here (left o)) = ⊂:-overloads-⋒ (R S) G (intersect here o) >>= ⊂:-overloads-left
:-overloads-⋒ (R S) (G H) (intersect here (right o)) = ⊂:-overloads-⋒ (R S) H (intersect here o) >>= ⊂:-overloads-right
:-overloads-⋒ (E F) G (intersect (left n) o) = ⊂:-overloads-⋒ E G (intersect n o) >>= ⊂:-overloads-left
:-overloads-⋒ (E F) G (intersect (right n) o) = ⊂:-overloads-⋒ F G (intersect n o) >>= ⊂:-overloads-right
⊂:-⋒-overloads : {F G} FunType F FunType G Overloads (F G) ⊂: ∩-Lift (Overloads F) (Overloads G)
:-⋒-overloads (R S) (T U) here = defn (intersect here here) (∩ⁿ-<:-∩ R T) (∩-<:-∩ⁿ S U)
:-⋒-overloads (R S) (G H) (left o) = ⊂:-⋒-overloads (R S) G o >>= ⊂:-∩-lift ⊂:-refl ⊂:-overloads-left
:-⋒-overloads (R S) (G H) (right o) = ⊂:-⋒-overloads (R S) H o >>= ⊂:-∩-lift ⊂:-refl ⊂:-overloads-right
:-⋒-overloads (E F) G (left o) = ⊂:-⋒-overloads E G o >>= ⊂:-∩-lift ⊂:-overloads-left ⊂:-refl
:-⋒-overloads (E F) G (right o) = ⊂:-⋒-overloads F G o >>= ⊂:-∩-lift ⊂:-overloads-right ⊂:-refl
⊂:-overloads-⋓ : {F G} FunType F FunType G -Lift (Overloads F) (Overloads G) ⊂: Overloads (F G)
:-overloads-⋓ (R S) (T U) (union here here) = defn here (-<:-∪ⁿ R T) (∪ⁿ-<:- S U)
:-overloads-⋓ (R S) (G H) (union here (left o)) = ⊂:-overloads-⋓ (R S) G (union here o) >>= ⊂:-overloads-left
:-overloads-⋓ (R S) (G H) (union here (right o)) = ⊂:-overloads-⋓ (R S) H (union here o) >>= ⊂:-overloads-right
:-overloads-⋓ (E F) G (union (left n) o) = ⊂:-overloads-⋓ E G (union n o) >>= ⊂:-overloads-left
:-overloads-⋓ (E F) G (union (right n) o) = ⊂:-overloads-⋓ F G (union n o) >>= ⊂:-overloads-right
⊂:-⋓-overloads : {F G} FunType F FunType G Overloads (F G) ⊂: -Lift (Overloads F) (Overloads G)
:-⋓-overloads (R S) (T U) here = defn (union here here) (∪ⁿ-<:- R T) (-<:-∪ⁿ S U)
:-⋓-overloads (R S) (G H) (left o) = ⊂:-⋓-overloads (R S) G o >>= ⊂:--lift ⊂:-refl ⊂:-overloads-left
:-⋓-overloads (R S) (G H) (right o) = ⊂:-⋓-overloads (R S) H o >>= ⊂:--lift ⊂:-refl ⊂:-overloads-right
:-⋓-overloads (E F) G (left o) = ⊂:-⋓-overloads E G o >>= ⊂:--lift ⊂:-overloads-left ⊂:-refl
:-⋓-overloads (E F) G (right o) = ⊂:-⋓-overloads F G o >>= ⊂:--lift ⊂:-overloads-right ⊂:-refl
-saturate-overloads : {F} FunType F Overloads (-saturate F) ⊂: -Saturate (Overloads F)
-saturate-overloads (S T) here = just (base here)
-saturate-overloads (F G) (left (left o)) = -saturate-overloads F o >>= ⊂:--saturate ⊂:-overloads-left
-saturate-overloads (F G) (left (right o)) = -saturate-overloads G o >>= ⊂:--saturate ⊂:-overloads-right
-saturate-overloads (F G) (right o) =
:-⋓-overloads (normal--saturate F) (normal--saturate G) o >>=
:--lift (-saturate-overloads F) (-saturate-overloads G) >>=
:--lift (⊂:--saturate ⊂:-overloads-left) (⊂:--saturate ⊂:-overloads-right) >>=
:--lift-saturate
overloads--saturate : {F} FunType F -Saturate (Overloads F) ⊂: Overloads (-saturate F)
overloads--saturate F = ⊂:--saturate-indn (inj F) (step F) where
inj : {F} FunType F Overloads F ⊂: Overloads (-saturate F)
inj (S T) here = just here
inj (F G) (left p) = inj F p >>= ⊂:-overloads-left >>= ⊂:-overloads-left
inj (F G) (right p) = inj G p >>= ⊂:-overloads-right >>= ⊂:-overloads-left
step : {F} FunType F -Lift (Overloads (-saturate F)) (Overloads (-saturate F)) ⊂: Overloads (-saturate F)
step (S T) (union here here) = defn here (<:--lub <:-refl <:-refl) <:--left
step (F G) (union (left (left p)) (left (left q))) = step F (union p q) >>= ⊂:-overloads-left >>= ⊂:-overloads-left
step (F G) (union (left (left p)) (left (right q))) = ⊂:-overloads-⋓ (normal--saturate F) (normal--saturate G) (union p q) >>= ⊂:-overloads-right
step (F G) (union (left (right p)) (left (left q))) = ⊂:-overloads-⋓ (normal--saturate F) (normal--saturate G) (union q p) >>= ⊂:-overloads-right >>=ˡ <:--symm >>=ʳ <:--symm
step (F G) (union (left (right p)) (left (right q))) = step G (union p q) >>= ⊂:-overloads-right >>= ⊂:-overloads-left
step (F G) (union p (right q)) with ⊂:-⋓-overloads (normal--saturate F) (normal--saturate G) q
step (F G) (union (left (left p)) (right q)) | defn (union q₁ q₂) q₃ q₄ =
(step F (union p q₁) [] just q₂) >>=
:-overloads-⋓ (normal--saturate F) (normal--saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-union <:-refl q₃) <:--assocl >>=ʳ
<:-trans <:--assocr (<:-union <:-refl q₄)
step (F G) (union (left (right p)) (right q)) | defn (union q₁ q₂) q₃ q₄ =
(just q₁ [] step G (union p q₂)) >>=
:-overloads-⋓ (normal--saturate F) (normal--saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-union <:-refl q₃) (<:--lub (<:-trans <:--left <:--right) (<:--lub <:--left (<:-trans <:--right <:--right))) >>=ʳ
<:-trans (<:--lub (<:-trans <:--left <:--right) (<:--lub <:--left (<:-trans <:--right <:--right))) (<:-union <:-refl q₄)
step (F G) (union (right p) (right q)) | defn (union q₁ q₂) q₃ q₄ with ⊂:-⋓-overloads (normal--saturate F) (normal--saturate G) p
step (F G) (union (right p) (right q)) | defn (union q₁ q₂) q₃ q₄ | defn (union p₁ p₂) p₃ p₄ =
(step F (union p₁ q₁) [] step G (union p₂ q₂)) >>=
:-overloads-⋓ (normal--saturate F) (normal--saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-union p₃ q₃) (<:--lub (<:-union <:--left <:--left) (<:-union <:--right <:--right)) >>=ʳ
<:-trans (<:--lub (<:-union <:--left <:--left) (<:-union <:--right <:--right)) (<:-union p₄ q₄)
step (F G) (union (right p) q) with ⊂:-⋓-overloads (normal--saturate F) (normal--saturate G) p
step (F G) (union (right p) (left (left q))) | defn (union p₁ p₂) p₃ p₄ =
(step F (union p₁ q) [] just p₂) >>=
:-overloads-⋓ (normal--saturate F) (normal--saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-union p₃ <:-refl) (<:--lub (<:-union <:--left <:-refl) (<:-trans <:--right <:--left)) >>=ʳ
<:-trans (<:--lub (<:-union <:--left <:-refl) (<:-trans <:--right <:--left)) (<:-union p₄ <:-refl)
step (F G) (union (right p) (left (right q))) | defn (union p₁ p₂) p₃ p₄ =
(just p₁ [] step G (union p₂ q)) >>=
:-overloads-⋓ (normal--saturate F) (normal--saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-union p₃ <:-refl) <:--assocr >>=ʳ
<:-trans <:--assocl (<:-union p₄ <:-refl)
step (F G) (union (right p) (right q)) | defn (union p₁ p₂) p₃ p₄ with ⊂:-⋓-overloads (normal--saturate F) (normal--saturate G) q
step (F G) (union (right p) (right q)) | defn (union p₁ p₂) p₃ p₄ | defn (union q₁ q₂) q₃ q₄ =
(step F (union p₁ q₁) [] step G (union p₂ q₂)) >>=
:-overloads-⋓ (normal--saturate F) (normal--saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-union p₃ q₃) (<:--lub (<:-union <:--left <:--left) (<:-union <:--right <:--right)) >>=ʳ
<:-trans (<:--lub (<:-union <:--left <:--left) (<:-union <:--right <:--right)) (<:-union p₄ q₄)
-saturated : {F} FunType F -Lift (Overloads (-saturate F)) (Overloads (-saturate F)) ⊂: Overloads (-saturate F)
-saturated F o =
:--lift (-saturate-overloads F) (-saturate-overloads F) o >>=
:--lift-saturate >>=
overloads--saturate F
∩-saturate-overloads : {F} FunType F Overloads (∩-saturate F) ⊂: ∩-Saturate (Overloads F)
∩-saturate-overloads (S T) here = just (base here)
∩-saturate-overloads (F G) (left (left o)) = ∩-saturate-overloads F o >>= ⊂:-∩-saturate ⊂:-overloads-left
∩-saturate-overloads (F G) (left (right o)) = ∩-saturate-overloads G o >>= ⊂:-∩-saturate ⊂:-overloads-right
∩-saturate-overloads (F G) (right o) =
:-⋒-overloads (normal-∩-saturate F) (normal-∩-saturate G) o >>=
:-∩-lift (∩-saturate-overloads F) (∩-saturate-overloads G) >>=
:-∩-lift (⊂:-∩-saturate ⊂:-overloads-left) (⊂:-∩-saturate ⊂:-overloads-right) >>=
:-∩-lift-saturate
overloads-∩-saturate : {F} FunType F ∩-Saturate (Overloads F) ⊂: Overloads (∩-saturate F)
overloads-∩-saturate F = ⊂:-∩-saturate-indn (inj F) (step F) where
inj : {F} FunType F Overloads F ⊂: Overloads (∩-saturate F)
inj (S T) here = just here
inj (F G) (left p) = inj F p >>= ⊂:-overloads-left >>= ⊂:-overloads-left
inj (F G) (right p) = inj G p >>= ⊂:-overloads-right >>= ⊂:-overloads-left
step : {F} FunType F ∩-Lift (Overloads (∩-saturate F)) (Overloads (∩-saturate F)) ⊂: Overloads (∩-saturate F)
step (S T) (intersect here here) = defn here <:-∩-left (<:-∩-glb <:-refl <:-refl)
step (F G) (intersect (left (left p)) (left (left q))) = step F (intersect p q) >>= ⊂:-overloads-left >>= ⊂:-overloads-left
step (F G) (intersect (left (left p)) (left (right q))) = ⊂:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) (intersect p q) >>= ⊂:-overloads-right
step (F G) (intersect (left (right p)) (left (left q))) = ⊂:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) (intersect q p) >>= ⊂:-overloads-right >>=ˡ <:-∩-symm >>=ʳ <:-∩-symm
step (F G) (intersect (left (right p)) (left (right q))) = step G (intersect p q) >>= ⊂:-overloads-right >>= ⊂:-overloads-left
step (F G) (intersect (right p) q) with ⊂:-⋒-overloads (normal-∩-saturate F) (normal-∩-saturate G) p
step (F G) (intersect (right p) (left (left q))) | defn (intersect p₁ p₂) p₃ p₄ =
(step F (intersect p₁ q) [∩] just p₂) >>=
:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-intersect p₃ <:-refl) (<:-∩-glb (<:-intersect <:-∩-left <:-refl) (<:-trans <:-∩-left <:-∩-right)) >>=ʳ
<:-trans (<:-∩-glb (<:-intersect <:-∩-left <:-refl) (<:-trans <:-∩-left <:-∩-right)) (<:-intersect p₄ <:-refl)
step (F G) (intersect (right p) (left (right q))) | defn (intersect p₁ p₂) p₃ p₄ =
(just p₁ [∩] step G (intersect p₂ q)) >>=
:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-intersect p₃ <:-refl) <:-∩-assocr >>=ʳ
<:-trans <:-∩-assocl (<:-intersect p₄ <:-refl)
step (F G) (intersect (right p) (right q)) | defn (intersect p₁ p₂) p₃ p₄ with ⊂:-⋒-overloads (normal-∩-saturate F) (normal-∩-saturate G) q
step (F G) (intersect (right p) (right q)) | defn (intersect p₁ p₂) p₃ p₄ | defn (intersect q₁ q₂) q₃ q₄ =
(step F (intersect p₁ q₁) [∩] step G (intersect p₂ q₂)) >>=
:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-intersect p₃ q₃) (<:-∩-glb (<:-intersect <:-∩-left <:-∩-left) (<:-intersect <:-∩-right <:-∩-right)) >>=ʳ
<:-trans (<:-∩-glb (<:-intersect <:-∩-left <:-∩-left) (<:-intersect <:-∩-right <:-∩-right)) (<:-intersect p₄ q₄)
step (F G) (intersect p (right q)) with ⊂:-⋒-overloads (normal-∩-saturate F) (normal-∩-saturate G) q
step (F G) (intersect (left (left p)) (right q)) | defn (intersect q₁ q₂) q₃ q₄ =
(step F (intersect p q₁) [∩] just q₂) >>=
:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-intersect <:-refl q₃) <:-∩-assocl >>=ʳ
<:-trans <:-∩-assocr (<:-intersect <:-refl q₄)
step (F G) (intersect (left (right p)) (right q)) | defn (intersect q₁ q₂) q₃ q₄ =
(just q₁ [∩] step G (intersect p q₂) ) >>=
:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-intersect <:-refl q₃) (<:-∩-glb (<:-trans <:-∩-right <:-∩-left) (<:-∩-glb <:-∩-left (<:-trans <:-∩-right <:-∩-right))) >>=ʳ
<:-∩-glb (<:-trans <:-∩-right <:-∩-left) (<:-trans (<:-∩-glb <:-∩-left (<:-trans <:-∩-right <:-∩-right)) q₄)
step (F G) (intersect (right p) (right q)) | defn (intersect q₁ q₂) q₃ q₄ with ⊂:-⋒-overloads (normal-∩-saturate F) (normal-∩-saturate G) p
step (F G) (intersect (right p) (right q)) | defn (intersect q₁ q₂) q₃ q₄ | defn (intersect p₁ p₂) p₃ p₄ =
(step F (intersect p₁ q₁) [∩] step G (intersect p₂ q₂)) >>=
:-overloads-⋒ (normal-∩-saturate F) (normal-∩-saturate G) >>=
:-overloads-right >>=ˡ
<:-trans (<:-intersect p₃ q₃) (<:-∩-glb (<:-intersect <:-∩-left <:-∩-left) (<:-intersect <:-∩-right <:-∩-right)) >>=ʳ
<:-trans (<:-∩-glb (<:-intersect <:-∩-left <:-∩-left) (<:-intersect <:-∩-right <:-∩-right)) (<:-intersect p₄ q₄)
saturate-overloads : {F} FunType F Overloads (saturate F) ⊂: -Saturate (∩-Saturate (Overloads F))
saturate-overloads F o = -saturate-overloads (normal-∩-saturate F) o >>= (⊂:--saturate (∩-saturate-overloads F))
overloads-saturate : {F} FunType F -Saturate (∩-Saturate (Overloads F)) ⊂: Overloads (saturate F)
overloads-saturate F o = ⊂:--saturate (overloads-∩-saturate F) o >>= overloads--saturate (normal-∩-saturate F)
-- Saturated F whenever
-- * if F has overloads (R ⇒ S) and (T ⇒ U) then F has an overload which is a subtype of ((R ∩ T) ⇒ (S ∩ U))
-- * ditto union
data Saturated (F : Type) : Set where
defn :
( {R S T U} Overloads F (R S) Overloads F (T U) <:-Close (Overloads F) ((R T) (S U)))
( {R S T U} Overloads F (R S) Overloads F (T U) <:-Close (Overloads F) ((R T) (S U)))
-----------
Saturated F
-- saturated F is saturated!
saturated : {F} FunType F Saturated (saturate F)
saturated F = defn
(λ n o (saturate-overloads F n [∩] saturate-overloads F o) >>= -saturate-resp-∩-saturation ⊂:-∩-lift-saturate >>= overloads-saturate F)
(λ n o -saturated (normal-∩-saturate F) (union n o))