open import Tools.Level
import Graded.Modality.Instances.Affine
open import Graded.Modality.Variant lzero
open import Graded.Usage.Restrictions
module Graded.Modality.Instances.Affine.Examples.Good.Nr
(variant : Modality-variant)
(open Graded.Modality.Instances.Affine variant)
(UR : Usage-restrictions affineModality)
where
open import Graded.Restrictions affineModality
open import Graded.Usage.Restrictions.Natrec affineModality
open import Graded.Modality Affine
private
UR′ = nr-available-UR zero-one-many-has-nr UR
open Usage-restrictions UR′
instance
has-nr : Nr-available
has-nr = Natrec-mode-has-nr.Nr ⦃ zero-one-many-has-nr ⦄
open import Tools.Function
open import Tools.Nat using (Nat)
import Tools.Reasoning.PartialOrder
open import Tools.Product
open import Tools.Relation
open import Graded.Context affineModality
open import Graded.Context.Properties affineModality
open import Graded.Modality.Properties affineModality
open import Graded.Mode affineModality
open import Graded.Usage affineModality UR′
open import Graded.Usage.Inversion affineModality UR′
open import Graded.Usage.Properties affineModality UR′
open import Graded.Usage.Weakening affineModality UR′
open import Definition.Untyped Affine
open import Definition.Untyped.Nat affineModality
private variable
n : Nat
γ δ : Conₘ _
m : Mode
t u : Term _
private
module M = Modality affineModality
private opaque
▸ℕ : 𝟘ᶜ {n = n} ∙ ⌜ 𝟘ᵐ? ⌝ · 𝟘 ▸[ 𝟘ᵐ? ] ℕ
▸ℕ = sub ℕₘ (≤ᶜ-reflexive (≈ᶜ-refl ∙ M.·-zeroʳ _))
opaque
¬▸double : ¬ ε ▸[ 𝟙ᵐ ] double
¬▸double ▸λ+ =
case inv-usage-lam ▸λ+ of λ {
(invUsageLam {δ = ε} ▸+ ε) →
case inv-usage-natrec-has-nr ▸+ of λ {
(_ ∙ p , _ ∙ q , _ ∙ r , _
, ▸x0₁ , _ , ▸x0₂ , _ , _ ∙ 𝟙≤nr) →
case inv-usage-var ▸x0₁ of λ {
(_ ∙ p≤𝟙) →
case inv-usage-var ▸x0₂ of λ {
(_ ∙ r≤𝟙) →
case begin
𝟙 ≤⟨ 𝟙≤nr ⟩
𝟙 · r + ω · q + p ≤⟨ +-monotone (·-monotoneʳ {r = 𝟙} r≤𝟙) (+-monotoneʳ p≤𝟙) ⟩
𝟙 + ω · q + 𝟙 ≡⟨ M.+-congˡ {x = 𝟙} (M.+-comm (ω · q) _) ⟩
𝟙 + 𝟙 + ω · q ≡˘⟨ M.+-assoc 𝟙 𝟙 (ω · q) ⟩
ω ∎
of λ () }}}}
where
open Tools.Reasoning.PartialOrder ≤-poset
opaque
▸plus′ : γ ▸[ m ] t → δ ▸[ m ] u → γ +ᶜ δ ▸[ m ] plus′ t u
▸plus′ ▸t ▸u =
sub (natrecₘ {δ = 𝟘ᶜ} ▸t
(sub-≈ᶜ (sucₘ var) (≈ᶜ-refl ∙ M.·-zeroʳ _ ∙ M.·-identityʳ _))
▸u ▸ℕ)
(lemma _ _)
where
open Tools.Reasoning.PartialOrder ≤-poset
lemma′ : ∀ p q → p + q ≤ Has-nr.nr zero-one-many-has-nr 𝟘 𝟙 p 𝟘 q
lemma′ p q = begin
p + q ≈⟨ M.+-comm p q ⟩
q + p ≈˘⟨ M.+-congˡ (M.+-identityˡ p) ⟩
q + 𝟘 + p ≈˘⟨ M.+-congʳ (M.·-identityˡ q) ⟩
𝟙 · q + ω · 𝟘 + p ≡⟨⟩
Has-nr.nr zero-one-many-has-nr 𝟘 𝟙 p 𝟘 q ∎
lemma : (γ δ : Conₘ n) → γ +ᶜ δ ≤ᶜ nrᶜ ⦃ has-nr = zero-one-many-has-nr ⦄ 𝟘 𝟙 γ 𝟘ᶜ δ
lemma ε ε = ε
lemma (γ ∙ p) (δ ∙ q) = lemma γ δ ∙ lemma′ p q
opaque
▸plus : ε ▸[ 𝟙ᵐ ] plus
▸plus =
lamₘ $
lamₘ $
▸plus′ var var
opaque
unfolding f′
▸f′ : γ ▸[ m ] t → δ ▸[ m ] u → γ +ᶜ δ ▸[ m ] f′ t u
▸f′ {γ} ▸t ▸u =
sub (natrecₘ {δ = γ +ᶜ 𝟘ᶜ} ▸t
(▸plus′ (wkUsage (step (step id)) ▸t)
(sub-≈ᶜ var (≈ᶜ-refl ∙ M.·-identityʳ _ ∙ M.·-zeroʳ _)))
▸u ▸ℕ)
(lemma _ _)
where
open Tools.Reasoning.PartialOrder ≤-poset
lemma′ : ∀ p q → p + q ≤ Has-nr.nr zero-one-many-has-nr 𝟙 𝟘 p (p + 𝟘) q
lemma′ p q = begin
p + q ≡⟨ M.+-comm p q ⟩
q + p ≡˘⟨ M.∧-idem _ ⟩
(q + p) ∧ (q + p) ≡˘⟨ M.∧-congʳ (M.+-cong (M.·-identityˡ q) (M.+-identityʳ p)) ⟩
(𝟙 · q + p + 𝟘) ∧ (q + p) ≡⟨⟩
Has-nr.nr zero-one-many-has-nr 𝟙 𝟘 p (p + 𝟘) q ∎
lemma : (γ δ : Conₘ n) → γ +ᶜ δ ≤ᶜ nrᶜ ⦃ has-nr = zero-one-many-has-nr ⦄ 𝟙 𝟘 γ (γ +ᶜ 𝟘ᶜ) δ
lemma ε ε = ε
lemma (γ ∙ p) (δ ∙ q) = lemma γ δ ∙ lemma′ p q
opaque
unfolding f
▸f : ε ▸[ 𝟙ᵐ ] f
▸f = lamₘ $ lamₘ $ ▸f′ var var
opaque
▸pred′ : γ ▸[ m ] t → γ ▸[ m ] pred′ t
▸pred′ ▸t =
sub (natrecₘ {δ = 𝟘ᶜ} zeroₘ
(sub-≈ᶜ var (≈ᶜ-refl ∙ M.·-identityʳ _ ∙ M.·-zeroʳ _))
▸t ▸ℕ)
(lemma _)
where
open Tools.Reasoning.PartialOrder ≤-poset
lemma′ : ∀ p → p ≤ Has-nr.nr zero-one-many-has-nr 𝟙 𝟘 𝟘 𝟘 p
lemma′ p = begin
p ≈˘⟨ M.+-identityʳ _ ⟩
p + 𝟘 ≈˘⟨ M.∧-idem _ ⟩
(p + 𝟘) ∧ (p + 𝟘) ≈˘⟨ M.∧-congʳ (M.+-congʳ (M.·-identityˡ p)) ⟩
(𝟙 · p + 𝟘) ∧ (p + 𝟘) ≡⟨⟩
Has-nr.nr zero-one-many-has-nr 𝟙 𝟘 𝟘 𝟘 p ∎
lemma : (γ : Conₘ n) → γ ≤ᶜ nrᶜ ⦃ has-nr = zero-one-many-has-nr ⦄ 𝟙 𝟘 𝟘ᶜ 𝟘ᶜ γ
lemma ε = ε
lemma (γ ∙ p) = lemma γ ∙ lemma′ p
opaque
▸pred : ε ▸[ 𝟙ᵐ ] pred
▸pred = lamₘ $ ▸pred′ (sub-≈ᶜ var (ε ∙ M.·-identityʳ _))