open import Level using (Level; _⊔_) open import Function open import Data.Empty open import Data.Unit.Polymorphic open import Data.Nat as ℕ hiding (_⊔_) open import Data.Nat.Properties using (<⇒≤; ≤⇒≯) open import Data.Product open import Data.Irrelevant open import Data.Sum open import Data.Fin as F open import Data.Fin.Properties as F open import Data.Fin.Induction open import Induction.WellFounded open import Relation.Binary.Definitions using (Tri; tri<; tri≈; tri>) open import Relation.Binary.PropositionalEquality import Relation.Binary.Reasoning.Setoid as ReasonSetoid open import Relation.Nullary hiding (Irrelevant; Recomputable) open import Relation.Unary using (Pred; Recomputable) open import Relation.Unary.Consequences open import Algebra hiding (Invertible) open import Algebra.Apartness import Algebra.Properties.Ring as RingProps import Algebra.Definitions as ADefs private variable c ℓ ℓ₁ ℓ₂ : Level A B : Set ℓ m n : ℕ i j k : Fin n i≢j→si≢sj : i ≢ j → F.suc i ≢ F.suc j i≢j→si≢sj i≢j refl = i≢j refl IsInj₁ : ∀ {a b} {A : Set a} {B : Set b} → A ⊎ B → Set _ IsInj₁ (inj₁ _) = ⊤ IsInj₁ (inj₂ _) = ⊥ fromIsInj₁ : ∀ {a b} {A : Set a} {B : Set b} {a⊎b : A ⊎ B} → IsInj₁ a⊎b → A fromIsInj₁ {a⊎b = inj₁ x} _ = x record Σ′ (A : Set ℓ) (B : A → Set ℓ₁) : Set (ℓ ⊔ ℓ₁) where constructor _∙∙_ field fst′′ : A .snd′′ : B fst′′ open Σ′ public IsInj₂ : ∀ {a b} {A : Set a} {B : Set b} → A ⊎ B → Set _ IsInj₂ (inj₁ _) = ⊥ IsInj₂ (inj₂ _) = ⊤ fromIsInj₂ : ∀ {a b} {A : Set a} {B : Set b} {a⊎b : A ⊎ B} → IsInj₂ a⊎b → B fromIsInj₂ {a⊎b = inj₂ x} _ = x split : (a⊎b : A ⊎ B) → Σ′ A (λ a → inj₁ a ≡ a⊎b) ⊎ Σ′ B λ b → inj₂ b ≡ a⊎b split (inj₁ x) = inj₁ (x ∙∙ refl) split (inj₂ y) = inj₂ (y ∙∙ refl) inj< : {i j : Fin n} → i F.< j → inject₁ i F.< inject₁ j inj< {_} {zero} {suc j} (s≤s i<j) = s≤s z≤n inj< {_} {suc i} {suc j} (s≤s i<j) = s≤s (inj< i<j) inj<from : ∀ (i : Fin n) → inject₁ i F.< fromℕ n inj<from zero = s≤s z≤n inj<from (suc i) = s≤s (inj<from i) cong≤ˡ : ∀ {i j k : ℕ} → i ℕ.≤ j → j ≡ k → i ℕ.≤ k cong≤ˡ p refl = p cong≤ʳ : ∀ {i j k : ℕ} → j ≡ k → i ℕ.≤ j → i ℕ.≤ k cong≤ʳ refl p = p cong≤ʳ₂ : ∀ {i j k : ℕ} → i ≡ j → i ℕ.≤ k → j ℕ.≤ k cong≤ʳ₂ refl p = p lowerMaximum : (i : Fin (suc n)) (i≢n : i ≢ fromℕ n) → Fin n lowerMaximum {zero} zero i≢n = ⊥-elim (i≢n refl) lowerMaximum {suc n} zero i≢n = zero lowerMaximum {suc n} (suc i) i≢n = suc (lowerMaximum i (λ i≡n → i≢n (cong suc i≡n))) lowerMaximumInjective : {i j : Fin (suc n)} {i≢n : i ≢ fromℕ n} {j≢n : j ≢ fromℕ n} → lowerMaximum i i≢n ≡ lowerMaximum j j≢n → i ≡ j lowerMaximumInjective {zero} {zero} {zero} {i≢n} {j≢n} leqn = refl lowerMaximumInjective {suc n} {zero} {zero} {i≢n} {j≢n} leqn = refl lowerMaximumInjective {suc n} {suc i} {suc j} {i≢n} {j≢n} leqn = cong suc (lowerMaximumInjective (suc-injective leqn)) finSuc : Fin n → Fin (suc n) finSuc zero = zero finSuc (suc p) = suc (finSuc p) finSuc≢fromℕ : {i : Fin n} → finSuc i ≢ fromℕ n finSuc≢fromℕ {_} {zero} () finSuc≢fromℕ {_} {suc i} eqn = finSuc≢fromℕ (suc-injective eqn) lowerMaximum≡p : {p : Fin (suc n)} (fp≢n : finSuc p ≢ F.suc (fromℕ n)) → lowerMaximum (finSuc p) fp≢n ≡ p lowerMaximum≡p {p = zero} fp≢n = refl lowerMaximum≡p {suc n} {p = suc p} fp≢n = cong suc (lowerMaximum≡p λ fp≡n → fp≢n (cong suc fp≡n)) isMaximum : Fin n → Set isMaximum {suc n} = _≡ fromℕ n isMaximum? : (p : Fin n) → Dec (isMaximum p) isMaximum? {suc n} = F._≟ fromℕ n maximum≥all : {i j : Fin n} → isMaximum i → i F.≥ j maximum≥all {suc n} {zero} {zero} imax = z≤n maximum≥all {suc zero} {zero} {suc ()} refl maximum≥all {suc (suc n)} {zero} {suc j} () maximum≥all {suc n} {suc i} {zero} imax = z≤n maximum≥all {suc (suc n)} {suc i} {suc j} imax = s≤s (maximum≥all (suc-injective imax)) _max⊎>_ : (i j : Fin n) → Set i max⊎> j = isMaximum i × isMaximum j ⊎ i F.> j Fin⊤ : ℕ → Set Fin⊤ n = Fin n ⊎ ⊤ ≤∧s≢⇒≤ : ∀ {m n} → m ℕ.≤ suc n → m ≢ suc n → m ℕ.≤ n ≤∧s≢⇒≤ {_} {n} z≤n q = z≤n ≤∧s≢⇒≤ {suc _} {zero} (s≤s z≤n) q = ⊥-elim (q refl) ≤∧s≢⇒≤ {suc _} {suc n} (s≤s p) q = s≤s (≤∧s≢⇒≤ p λ where refl → q refl) i>j→i≢j : i F.> j → i ≢ inject₁ j i>j→i≢j i>j refl = <⇒≢ (≤̄⇒inject₁< i>j) refl i>j→i≥j : ∀ {i} {j : Fin n} → i F.≥ suc j → i F.≥ inject₁ j i>j→i≥j = ≤-trans (<⇒≤ (≤̄⇒inject₁< ≤-refl)) i>j→i>injJ : i F.> j → i F.> inject₁ j i>j→i>injJ = cong≤ʳ₂ (cong suc (sym (toℕ-inject₁ _))) <→Σinject : ∀ {i j : Fin (suc n)} → i F.< j → Σ[ k ∈ Fin n ] inject₁ k ≡ i <→Σinject {suc n} {zero} {suc j} i<j = zero , refl <→Σinject {suc n} {i = suc i} {suc j} (s≤s i<j) = let (p , q) = <→Σinject {i = i} {j} i<j in suc p , cong suc q punchOut-fromℕ : ∀ {i : Fin (suc n)} (n≢i : fromℕ n ≢ i) → toℕ (punchOut n≢i) ≡ toℕ i punchOut-fromℕ {zero} {zero } n≢i = ⊥-elim (n≢i refl) punchOut-fromℕ {suc n} {zero } n≢i = refl punchOut-fromℕ {suc n} {suc i} n≢i = cong suc (punchOut-fromℕ λ where refl → n≢i refl) punchIn-fromℕ : (i : Fin n) → toℕ (punchIn (fromℕ _) i) ≡ toℕ i punchIn-fromℕ zero = refl punchIn-fromℕ (suc i) = cong suc (punchIn-fromℕ i) >-weakInduction-endingFrom : ∀ (P : Pred (Fin (suc n)) ℓ) → ∀ {i} → P i → (∀ j → P (suc j) → P (inject₁ j)) → ∀ {j} → j F.≤ i → P j >-weakInduction-endingFrom {n} P {i} Pi Pᵢ₊₁⇒Pᵢ {j} j≤i = induct (>-wellFounded _) (F.<-cmp i j) j≤i where induct : ∀ {j} → Acc F._>_ j → Tri (i F.< j) (i ≡ j) (i F.> j) → j F.≤ i → P j induct (acc rs) (tri≈ _ refl _) j≤i = Pi induct (acc rs) (tri< i>j _ _) j≤i with () ← ≤⇒≯ j≤i i>j induct {j} (acc rs) (tri> _ _ i>j) _ = subst P isj≡j (Pᵢ₊₁⇒Pᵢ sj PSj) where sj×≡ : Σ[ k ∈ Fin n ] inject₁ k ≡ j sj×≡ = <→Σinject i>j sj = sj×≡ .proj₁ isj≡j : inject₁ sj ≡ j isj≡j = sj×≡ .proj₂ sj>j : suc sj F.> j sj>j = subst (suc sj F.>_) isj≡j (≤̄⇒inject₁< {i = sj} {j = sj} (≤-refl {x = sj})) sj≤i : suc sj F.≤ i sj≤i = subst (λ x → suc x ℕ.≤ toℕ i) (trans (sym (cong toℕ isj≡j)) (toℕ-inject₁ sj)) i>j PSj : P (suc sj) PSj = induct (rs sj>j) (F.<-cmp i (suc sj)) sj≤i ≤Rec : Recomputable (F._≤_ {_} {n} i) ≤Rec = dec⇒recomputable (F._≤?_ _) suc-pred : n ℕ.> 0 → ℕ.suc (ℕ.pred n) ≡ n suc-pred (s≤s {n = zero} z≤n) = refl suc-pred (s≤s {n = suc n} z≤n) rewrite suc-pred ((s≤s {n = n} z≤n)) = refl module hFieldProps (hField : HeytingField c ℓ₁ ℓ₂) where open module HF = HeytingField hField open HeytingCommutativeRing heytingCommutativeRing using (commutativeRing) open CommutativeRing commutativeRing using (ring) open ADefs _≈_ using (Invertible) open ReasonSetoid HF.setoid open RingProps ring private variable x y : Carrier tightʳ : x # y → ¬ x ≈ y tightʳ p q = tight _ _ .proj₂ q p tightBoth : x # y → x ≈ y → A tightBoth x#y x≈y = contradiction x≈y (tightʳ x#y) x#0→x⁻¹*x≈1 : (x#0 : x # 0#) → #⇒invertible x#0 .proj₁ HF.* x ≈ 1# x#0→x⁻¹*x≈1 {x} x#0 = helper (#⇒invertible x#0) where helper : (hf@(x⁻¹ , _) : Invertible 1# HF._*_ (x HF.- 0#)) → x⁻¹ HF.* x ≈ 1# helper (x⁻¹ , x⁻¹*x≈1 , _) = begin x⁻¹ HF.* x ≈˘⟨ *-congˡ (+-identityʳ _) ⟩ x⁻¹ HF.* (x HF.+ 0#) ≈˘⟨ *-congˡ (+-congˡ -0#≈0#) ⟩ x⁻¹ HF.* (x HF.- 0#) ≈⟨ x⁻¹*x≈1 ⟩ 1# ∎