import Graded.Modality
module Graded.Restrictions
{a} {M : Set a}
(open Graded.Modality M)
(𝕄 : Modality)
where
open Modality 𝕄
open import Tools.Bool
open import Tools.Empty
open import Tools.Function
open import Tools.Level
open import Tools.Product as Σ
open import Tools.PropositionalEquality
open import Tools.Relation as Dec
open import Tools.Sum
open import Tools.Unit
open import Graded.Modality.Properties 𝕄
open import Graded.Mode 𝕄 as Mode hiding (_≟_)
import Graded.Usage.Decidable.Assumptions as UD
open import Graded.Usage.Erased-matches
open import Graded.Usage.Restrictions 𝕄
open import Graded.Usage.Restrictions.Natrec 𝕄
import Definition.Typechecking.Decidable.Assumptions as TD
open import Definition.Typed.Restrictions 𝕄
open import Definition.Typed.Variant
open import Definition.Untyped.NotParametrised
open import Definition.Untyped.Properties.NotParametrised
private variable
TR : Type-restrictions
UR : Usage-restrictions
b : Bool
ok : T _
s : Strength
nm : Natrec-mode
no-type-restrictions : Bool → Bool → Type-restrictions
no-type-restrictions k equality-reflection = λ where
.Unit-allowed → λ _ → Lift _ ⊤
.ΠΣ-allowed → λ _ _ _ → Lift _ ⊤
.Opacity-allowed → Lift _ (¬ T equality-reflection)
.Opacity-allowed? → Lift? (¬? (T? equality-reflection))
.K-allowed → Lift _ (T k)
.[]-cong-allowed → λ _ → ¬ Trivial
.[]-cong→Erased → _
.[]-cong→¬Trivial → idᶠ
.Equality-reflection → Lift _ (T equality-reflection)
.Equality-reflection? → Lift? (T? equality-reflection)
.no-opaque-equality-reflection → (_∘→ Lift.lower) ∘→ Lift.lower
.type-variant → λ where
.Type-variant.unfolding-mode → transitive
.Type-variant.η-for-Unitʷ → false
where
open Type-restrictions
equal-binder-quantities : Type-restrictions → Type-restrictions
equal-binder-quantities R = record R
{ ΠΣ-allowed = λ b p q → ΠΣ-allowed b p q × p ≡ q
; []-cong→Erased = λ ok →
[]-cong→Erased ok .proj₁ , []-cong→Erased ok .proj₂ , refl
}
where
open Type-restrictions R
second-ΠΣ-quantities-𝟘 :
Type-restrictions → Type-restrictions
second-ΠΣ-quantities-𝟘 R = record R
{ ΠΣ-allowed = λ b p q → ΠΣ-allowed b p q × q ≡ 𝟘
; []-cong→Erased = λ ok →
[]-cong→Erased ok .proj₁ , []-cong→Erased ok .proj₂ , refl
}
where
open Type-restrictions R
second-ΠΣ-quantities-𝟘-or-ω :
Type-restrictions → Type-restrictions
second-ΠΣ-quantities-𝟘-or-ω R = record R
{ ΠΣ-allowed = λ b p q →
ΠΣ-allowed b p q ×
(p ≡ ω → q ≡ ω) ×
(p ≢ ω → q ≡ 𝟘)
; []-cong→Erased = λ ok →
[]-cong→Erased ok .proj₁
, []-cong→Erased ok .proj₂
, idᶠ
, λ _ → refl
}
where
open Type-restrictions R
strong-types-restricted′ :
(P : BinderMode → M → Set a) →
(∀ {s} → s ≢ 𝕤 → P (BMΣ s) 𝟘) →
Type-restrictions → Type-restrictions
strong-types-restricted′ P hyp R = record R
{ Unit-allowed = λ s →
Unit-allowed s × s ≢ 𝕤
; ΠΣ-allowed = λ b p q →
ΠΣ-allowed b p q × P b p
; []-cong-allowed = λ s →
[]-cong-allowed s × s ≢ 𝕤
; []-cong→Erased = λ (ok , s≢𝕤) →
([]-cong→Erased ok .proj₁ , s≢𝕤)
, []-cong→Erased ok .proj₂
, hyp s≢𝕤
; []-cong→¬Trivial =
[]-cong→¬Trivial ∘→ proj₁
}
where
open Type-restrictions R
strong-types-restricted :
Type-restrictions → Type-restrictions
strong-types-restricted =
strong-types-restricted′ (λ b p → b ≡ BMΣ 𝕤 → p ≡ 𝟙)
(λ { hyp refl → ⊥-elim $ hyp refl })
no-strong-types :
Type-restrictions → Type-restrictions
no-strong-types =
strong-types-restricted′ (λ b _ → Lift _ (b ≢ BMΣ 𝕤))
(λ hyp → lift (λ { refl → ⊥-elim $ hyp refl }))
no-erased-matches-TR : Strength → Type-restrictions → Type-restrictions
no-erased-matches-TR s TR = record TR
{ []-cong-allowed = λ s′ → []-cong-allowed s′ × s′ ≢ s
; []-cong→Erased = []-cong→Erased ∘→ proj₁
; []-cong→¬Trivial = []-cong→¬Trivial ∘→ proj₁
}
where
open Type-restrictions TR
_with-η-for-Unitʷ : Type-restrictions → Type-restrictions
TR with-η-for-Unitʷ = record TR
{ type-variant = record type-variant
{ η-for-Unitʷ = true
}
}
where
open Type-restrictions TR
[]-cong-TR : Type-restrictions → Type-restrictions
[]-cong-TR TR = record TR
{ Unit-allowed = λ s → Unit-allowed s ⊎ ¬ Trivial
; ΠΣ-allowed = λ where
(BMΣ s) p q → ΠΣ-allowed (BMΣ s) p q ⊎
¬ Trivial × p ≡ 𝟘 × q ≡ 𝟘
BMΠ p q → ΠΣ-allowed BMΠ p q
; []-cong-allowed = λ _ → ¬ Trivial
; []-cong→Erased = λ non-trivial →
inj₂ non-trivial ,
inj₂ (non-trivial , refl , refl)
; []-cong→¬Trivial = idᶠ
}
where
open Type-restrictions TR
no-[]-cong-TR : Type-restrictions → Type-restrictions
no-[]-cong-TR TR = record TR
{ []-cong-allowed = λ _ → Lift _ ⊥
; []-cong→Erased = λ ()
; []-cong→¬Trivial = λ ()
}
with-equality-reflection : Type-restrictions → Type-restrictions
with-equality-reflection TR = record TR
{ Opacity-allowed = Lift _ ⊥
; Opacity-allowed? = no (λ ())
; Equality-reflection = Lift _ ⊤
; Equality-reflection? = yes _
; no-opaque-equality-reflection = λ ()
}
no-usage-restrictions : Natrec-mode → Bool → Bool → Usage-restrictions
no-usage-restrictions nm erased sink = λ where
.natrec-mode → nm
.Prodrec-allowed-𝟙ᵐ → λ _ _ _ → Lift _ ⊤
.Unitrec-allowed-𝟙ᵐ → λ _ _ → Lift _ ⊤
.Emptyrec-allowed-𝟙ᵐ → λ _ → Lift _ ⊤
.[]-cong-allowed-mode-𝟙ᵐ → λ _ → Lift _ ⊤
.starˢ-sink → sink
.Id-erased → Lift _ (T erased)
.Id-erased? → Dec.map lift Lift.lower $
T? erased
.erased-matches-for-J → λ _ → all
.erased-matches-for-J-≤ᵉᵐ → _
.erased-matches-for-K → λ _ → all
.erased-matches-for-K-≤ᵉᵐ → _
where
open Usage-restrictions
not-all-for-𝟙ᵐ : (Mode → Erased-matches) → Mode → Erased-matches
not-all-for-𝟙ᵐ f 𝟘ᵐ = f 𝟘ᵐ
not-all-for-𝟙ᵐ f 𝟙ᵐ with f 𝟙ᵐ
… | all = some
… | em = em
not-all-erased-matches-JK : Usage-restrictions → Usage-restrictions
not-all-erased-matches-JK UR = record UR
{ erased-matches-for-J =
not-all-for-𝟙ᵐ erased-matches-for-J
; erased-matches-for-J-≤ᵉᵐ =
not-all-for-𝟙ᵐ-≤ᵉᵐ erased-matches-for-J erased-matches-for-J-≤ᵉᵐ
; erased-matches-for-K =
not-all-for-𝟙ᵐ erased-matches-for-K
; erased-matches-for-K-≤ᵉᵐ =
not-all-for-𝟙ᵐ-≤ᵉᵐ erased-matches-for-K erased-matches-for-K-≤ᵉᵐ
}
where
open Usage-restrictions UR
opaque
not-all-for-𝟙ᵐ-≤ᵉᵐ :
(f : Mode → Erased-matches) →
f 𝟙ᵐ ≤ᵉᵐ f 𝟘ᵐ[ ok ] →
not-all-for-𝟙ᵐ f 𝟙ᵐ ≤ᵉᵐ not-all-for-𝟙ᵐ f 𝟘ᵐ[ ok ]
not-all-for-𝟙ᵐ-≤ᵉᵐ f f-≤ᵉᵐ with f 𝟙ᵐ
… | all = ≤ᵉᵐ-transitive _ f-≤ᵉᵐ
… | some = f-≤ᵉᵐ
… | none = f-≤ᵉᵐ
only-some-erased-matches : Usage-restrictions → Usage-restrictions
only-some-erased-matches UR = record UR
{ Prodrec-allowed-𝟙ᵐ = λ r p q →
Prodrec-allowed-𝟙ᵐ r p q ×
(¬ Trivial → r ≢ 𝟘)
; erased-matches-for-J = λ where
𝟙ᵐ → none
𝟘ᵐ → erased-matches-for-J 𝟘ᵐ
; erased-matches-for-J-≤ᵉᵐ =
_
; erased-matches-for-K = λ where
𝟙ᵐ → none
𝟘ᵐ → erased-matches-for-K 𝟘ᵐ
; erased-matches-for-K-≤ᵉᵐ =
_
}
where
open Usage-restrictions UR
no-erased-matches-UR :
Type-restrictions → Usage-restrictions → Usage-restrictions
no-erased-matches-UR TR UR = record (only-some-erased-matches UR)
{ Unitrec-allowed-𝟙ᵐ = λ p q →
Unitrec-allowed-𝟙ᵐ p q ×
(¬ Trivial → p ≡ 𝟘 → Unitʷ-η)
}
where
open Type-restrictions TR
open Usage-restrictions UR
nr-available-UR :
Has-nr semiring-with-meet → Usage-restrictions → Usage-restrictions
nr-available-UR has-nr UR =
record UR { natrec-mode = Nr ⦃ has-nr ⦄ }
nr-not-available-glb-UR :
Has-well-behaved-GLBs semiring-with-meet →
Usage-restrictions → Usage-restrictions
nr-not-available-glb-UR ok UR =
record UR { natrec-mode = No-nr-glb ⦃ ok ⦄ }
[]-cong-UR : Usage-restrictions → Usage-restrictions
[]-cong-UR UR = record UR
{ []-cong-allowed-mode-𝟙ᵐ = λ s → []-cong-allowed-mode-𝟙ᵐ s ⊎
¬ Trivial
; erased-matches-for-J = λ _ → none
; erased-matches-for-J-≤ᵉᵐ = _
}
where
open Usage-restrictions UR
at-least-some : (Mode → Erased-matches) → Mode → Erased-matches
at-least-some f m = case f m of λ where
none → some
em → em
no-[]-cong-UR : Usage-restrictions → Usage-restrictions
no-[]-cong-UR UR = record UR
{ []-cong-allowed-mode-𝟙ᵐ = λ _ → Lift _ ⊥
; erased-matches-for-J = at-least-some erased-matches-for-J
; erased-matches-for-J-≤ᵉᵐ = at-least-some-≤ᵉᵐ
}
where
open Usage-restrictions UR
at-least-some-≤ᵉᵐ :
at-least-some erased-matches-for-J 𝟙ᵐ ≤ᵉᵐ
at-least-some erased-matches-for-J 𝟘ᵐ[ ok ]
at-least-some-≤ᵉᵐ {ok}
with erased-matches-for-J 𝟙ᵐ
| erased-matches-for-J 𝟘ᵐ[ ok ]
| erased-matches-for-J-≤ᵉᵐ ⦃ ok = ok ⦄
… | none | none | _ = _
… | none | some | _ = _
… | none | all | _ = _
… | all | none | ()
… | some | none | ()
… | not-none _ | not-none _ | r = r
Only-some-erased-matches :
Type-restrictions → Usage-restrictions → Set a
Only-some-erased-matches TR UR =
¬ Trivial →
(∀ {r p q} → Prodrec-allowed-𝟙ᵐ r p q → r ≢ 𝟘) ×
(∀ {s} → ¬ ([]-cong-allowed s)) ×
erased-matches-for-J 𝟙ᵐ ≡ none ×
erased-matches-for-K 𝟙ᵐ ≡ none
where
open Type-restrictions TR
open Usage-restrictions UR
opaque
Only-some-erased-matches-only-some-erased-matches :
∀ TR UR →
Only-some-erased-matches
(no-erased-matches-TR 𝕤 (no-erased-matches-TR 𝕨 TR))
(only-some-erased-matches UR)
Only-some-erased-matches-only-some-erased-matches _ _ 𝟙≢𝟘 =
(_$ 𝟙≢𝟘) ∘→ proj₂
, (λ where
{s = 𝕤} → (_$ refl) ∘→ proj₂
{s = 𝕨} → (_$ refl) ∘→ proj₂ ∘→ proj₁)
, refl
, refl
No-erased-matches : Type-restrictions → Usage-restrictions → Set a
No-erased-matches TR UR =
¬ Trivial →
(∀ {r p q} → Prodrec-allowed-𝟙ᵐ r p q → r ≢ 𝟘) ×
(∀ {p q} → Unitrec-allowed-𝟙ᵐ p q → p ≡ 𝟘 → Unitʷ-η) ×
(∀ {s} → ¬ ([]-cong-allowed s)) ×
erased-matches-for-J 𝟙ᵐ ≡ none ×
erased-matches-for-K 𝟙ᵐ ≡ none
where
open Type-restrictions TR
open Usage-restrictions UR
No-erased-matches-no-erased-matches :
∀ TR UR →
let TR′ = no-erased-matches-TR 𝕤 (no-erased-matches-TR 𝕨 TR) in
No-erased-matches TR′ (no-erased-matches-UR TR′ UR)
No-erased-matches-no-erased-matches TR UR 𝟙≢𝟘 =
case Only-some-erased-matches-only-some-erased-matches TR UR 𝟙≢𝟘 of λ
(pr , rest) →
(λ {_ _ _} → pr)
, (λ {_ _} → (_$ 𝟙≢𝟘) ∘→ proj₂)
, rest
opaque
Only-some-erased-matches→No-erased-matches :
∀ TR UR →
Type-restrictions.Unitʷ-η TR →
Only-some-erased-matches TR UR → No-erased-matches TR UR
Only-some-erased-matches→No-erased-matches _ _ η =
Σ.map idᶠ ((λ {_ _} _ _ → η) ,_) ∘→_
No-erased-matches′ : Type-variant → Usage-restrictions → Set a
No-erased-matches′ TV UR =
¬ Trivial →
(∀ {r p q} → Prodrec-allowed 𝟙ᵐ r p q → r ≢ 𝟘) ×
(∀ {p q} → Unitrec-allowed 𝟙ᵐ p q → p ≡ 𝟘 → Unitʷ-η) ×
(∀ {s} → ¬ ([]-cong-allowed-mode s 𝟙ᵐ)) ×
erased-matches-for-J 𝟙ᵐ ≡ none ×
erased-matches-for-K 𝟙ᵐ ≡ none
where
open Type-variant TV
open Usage-restrictions UR
opaque
Assumptions-no-type-restrictions :
Decidable (_≡_ {A = M}) →
TD.Assumptions (no-type-restrictions b false)
Assumptions-no-type-restrictions {b} dec = λ where
._≟_ → dec
.Unit-allowed? _ → yes _
.ΠΣ-allowed? _ _ _ → yes _
.K-allowed? → case singleton b of λ where
(true , refl) → yes _
(false , refl) → no (λ ())
.[]-cong-allowed? _ → case trivial? of λ where
(yes trivial) → no (_$ trivial)
(no non-trivial) → yes non-trivial
.no-equality-reflection (lift ())
where
open TD.Assumptions
opaque
Assumptions-equal-binder-quantities :
TD.Assumptions TR → TD.Assumptions (equal-binder-quantities TR)
Assumptions-equal-binder-quantities as = λ where
._≟_ → A._≟_
.Unit-allowed? → A.Unit-allowed?
.ΠΣ-allowed? b p q → A.ΠΣ-allowed? b p q ×-dec p A.≟ q
.K-allowed? → A.K-allowed?
.[]-cong-allowed? → A.[]-cong-allowed?
.no-equality-reflection → A.no-equality-reflection
where
module A = TD.Assumptions as
open TD.Assumptions
opaque
Assumptions-second-ΠΣ-quantities-𝟘 :
TD.Assumptions TR → TD.Assumptions (second-ΠΣ-quantities-𝟘 TR)
Assumptions-second-ΠΣ-quantities-𝟘 as = λ where
._≟_ → A._≟_
.Unit-allowed? → A.Unit-allowed?
.ΠΣ-allowed? b p q → A.ΠΣ-allowed? b p q ×-dec q A.≟ 𝟘
.K-allowed? → A.K-allowed?
.[]-cong-allowed? → A.[]-cong-allowed?
.no-equality-reflection → A.no-equality-reflection
where
module A = TD.Assumptions as
open TD.Assumptions
opaque
Assumptions-second-ΠΣ-quantities-𝟘-or-ω :
TD.Assumptions TR → TD.Assumptions (second-ΠΣ-quantities-𝟘-or-ω TR)
Assumptions-second-ΠΣ-quantities-𝟘-or-ω as = λ where
._≟_ → A._≟_
.Unit-allowed? → A.Unit-allowed?
.ΠΣ-allowed? b p q → A.ΠΣ-allowed? b p q
×-dec
(p A.≟ ω →-dec q A.≟ ω)
×-dec
(¬? (p A.≟ ω) →-dec q A.≟ 𝟘)
.K-allowed? → A.K-allowed?
.[]-cong-allowed? → A.[]-cong-allowed?
.no-equality-reflection → A.no-equality-reflection
where
module A = TD.Assumptions as
open TD.Assumptions
opaque
Assumptions-strong-types-restricted′ :
{P : BinderMode → M → Set a}
{ok : ∀ {s} → s ≢ 𝕤 → P (BMΣ s) 𝟘} →
(∀ b p → Dec (P b p)) →
TD.Assumptions TR →
TD.Assumptions (strong-types-restricted′ P ok TR)
Assumptions-strong-types-restricted′ P-dec as = λ where
._≟_ → A._≟_
.Unit-allowed? s → A.Unit-allowed? s
×-dec
¬? (decStrength s 𝕤)
.ΠΣ-allowed? b p q → A.ΠΣ-allowed? b p q
×-dec
P-dec b p
.K-allowed? → A.K-allowed?
.[]-cong-allowed? s → A.[]-cong-allowed? s
×-dec
¬? (decStrength s 𝕤)
.no-equality-reflection → A.no-equality-reflection
where
module A = TD.Assumptions as
open TD.Assumptions
opaque
Assumptions-strong-types-restricted :
TD.Assumptions TR → TD.Assumptions (strong-types-restricted TR)
Assumptions-strong-types-restricted as =
Assumptions-strong-types-restricted′
(λ b p → decBinderMode b (BMΣ 𝕤) →-dec p ≟ 𝟙)
as
where
open TD.Assumptions as
opaque
Assumptions-no-strong-types :
TD.Assumptions TR → TD.Assumptions (no-strong-types TR)
Assumptions-no-strong-types as =
Assumptions-strong-types-restricted′
(λ b _ → Dec.map lift Lift.lower (¬? (decBinderMode b (BMΣ 𝕤))))
as
where
open TD.Assumptions as
opaque
Assumptions-no-erased-matches-TR :
TD.Assumptions TR → TD.Assumptions (no-erased-matches-TR s TR)
Assumptions-no-erased-matches-TR {s} as = λ where
._≟_ → A._≟_
.Unit-allowed? → A.Unit-allowed?
.ΠΣ-allowed? → A.ΠΣ-allowed?
.K-allowed? → A.K-allowed?
.[]-cong-allowed? s′ → A.[]-cong-allowed? s′
×-dec
¬? (decStrength s′ s)
.no-equality-reflection → A.no-equality-reflection
where
module A = TD.Assumptions as
open TD.Assumptions
opaque
Assumptions-no-usage-restrictions :
⦃ ok : Natrec-mode-supports-usage-inference nm ⦄ →
Decidable (_≡_ {A = M}) →
UD.Assumptions (no-usage-restrictions nm b false)
Assumptions-no-usage-restrictions dec = λ where
._≟_ → dec
.Prodrec-allowed-𝟙ᵐ? _ _ _ → yes _
.Unitrec-allowed-𝟙ᵐ? _ _ → yes _
.Emptyrec-allowed-𝟙ᵐ? _ → yes _
.[]-cong-allowed-mode-𝟙ᵐ? _ → yes _
.no-sink-or-≤𝟘 → inj₁ idᶠ
where
open UD.Assumptions
opaque
Assumptions-not-all-erased-matches-JK :
UD.Assumptions UR → UD.Assumptions (not-all-erased-matches-JK UR)
Assumptions-not-all-erased-matches-JK as = λ where
._≟_ → A._≟_
.Prodrec-allowed-𝟙ᵐ? → A.Prodrec-allowed-𝟙ᵐ?
.Unitrec-allowed-𝟙ᵐ? → A.Unitrec-allowed-𝟙ᵐ?
.Emptyrec-allowed-𝟙ᵐ? → A.Emptyrec-allowed-𝟙ᵐ?
.[]-cong-allowed-mode-𝟙ᵐ? → A.[]-cong-allowed-mode-𝟙ᵐ?
.no-sink-or-≤𝟘 → A.no-sink-or-≤𝟘
where
module A = UD.Assumptions as
open UD.Assumptions
opaque
Assumptions-only-some-erased-matches :
UD.Assumptions UR → UD.Assumptions (only-some-erased-matches UR)
Assumptions-only-some-erased-matches as = λ where
._≟_ → A._≟_
.Prodrec-allowed-𝟙ᵐ? r p q → A.Prodrec-allowed-𝟙ᵐ? r p q
×-dec
(¬? trivial?
→-dec
¬? (r A.≟ 𝟘))
.Unitrec-allowed-𝟙ᵐ? → A.Unitrec-allowed-𝟙ᵐ?
.Emptyrec-allowed-𝟙ᵐ? → A.Emptyrec-allowed-𝟙ᵐ?
.[]-cong-allowed-mode-𝟙ᵐ? → A.[]-cong-allowed-mode-𝟙ᵐ?
.no-sink-or-≤𝟘 → A.no-sink-or-≤𝟘
where
module A = UD.Assumptions as
open UD.Assumptions
opaque
Assumptions-no-erased-matches-UR :
∀ TR → UD.Assumptions UR →
UD.Assumptions (no-erased-matches-UR TR UR)
Assumptions-no-erased-matches-UR TR as = λ where
._≟_ → A._≟_
.Prodrec-allowed-𝟙ᵐ? → A.Prodrec-allowed-𝟙ᵐ?
.Unitrec-allowed-𝟙ᵐ? p q → A.Unitrec-allowed-𝟙ᵐ? p q
×-dec
(¬? trivial?
→-dec
p A.≟ 𝟘
→-dec
Unitʷ-η?)
.Emptyrec-allowed-𝟙ᵐ? → A.Emptyrec-allowed-𝟙ᵐ?
.[]-cong-allowed-mode-𝟙ᵐ? → A.[]-cong-allowed-mode-𝟙ᵐ?
.no-sink-or-≤𝟘 → A.no-sink-or-≤𝟘
where
module A = UD.Assumptions (Assumptions-only-some-erased-matches as)
open UD.Assumptions
open Type-restrictions TR