open import Level
open import Data.Bool hiding (_≤_ ; _<_)
open import Data.Bool.Properties using (¬-not ; not-¬)
open import Data.Nat
open import Data.Sum
open import Data.Unit
open import Data.Empty
open import Relation.Binary
open import Relation.Binary.Definitions
open import Relation.Binary.PropositionalEquality
open import Data.Product
open import Data.Vec hiding (restrict)
open import Relation.Nullary
open import Function hiding (_↔_)
open import Data.Nat.Properties using (≤-refl ; ≤-trans ; ≤-<-trans ; n≤0⇒n≡0
; n≤1+n ; m≤n⇒m<n∨m≡n ; ≡ᵇ⇒≡)
open ≡-Reasoning
open import Eser.Logic using (elimCaseLeft ; elimCaseRight)
open import Eser.Aux
open import Eser.EqRel.Definitions
open import Eser.EqRel.Conversions
module Eser.EqRel.Correspondences where
findMinZeroLemma
: (P : ℕ → Bool)
→ (P0 : P ℕ.zero ≡ true)
→ proj₁ (findMinAlwaysPoss ℕ.zero P P0) ≡ ℕ.zero
findMinZeroLemma P P0 =
let H = findMinAlwaysPoss ℕ.zero P P0
in
let ℓ≤0 = proj₁ (proj₂ H)
in
n≤0⇒n≡0 ℓ≤0
lemma1
: (R : DecEquiv)
→ (proj₁ ∘ RelToFun) R
≈
λ n → proj₁ (findMinAlwaysPoss n ((proj₁ R) n)
(((IsEquivalence.refl ∘ proj₂) R) {n}))
lemma1 R n = refl
_$$_ : NFFun → ℕ → ℕ
F $$ n = (proj₁ F) n
lemma2 : (F : NFFun) → proj₁ (FunToRel F) ≡ λ (n m : ℕ) → F $$ n ≡ᵇ F $$ m
lemma2 (f , nleq , nfix) = refl
decEqToPredEq
: {m n : ℕ}
→ ((m ≡ᵇ n) ≡ true)
→ m ≡ n
decEqToPredEq {m} {n} m≡ᵇn =
≡ᵇ⇒≡ m n (subst T (sym m≡ᵇn) tt)
predEqToDecEq
: {m n : ℕ}
→ m ≡ n
→ ((m ≡ᵇ n) ≡ true)
predEqToDecEq {ℕ.zero} refl = refl
predEqToDecEq {ℕ.suc m} refl = predEqToDecEq {m} {m} refl
predNeqToDecNeq
: {m n : ℕ}
→ m ≢ n
→ ((m ≡ᵇ n) ≡ false)
predNeqToDecNeq {m} {n} m≢n with ((m ≡ᵇ n) Data.Bool.≟ true)
... | yes m≡ᵇn = ⊥-elim (m≢n (decEqToPredEq m≡ᵇn))
... | no m≢ᵇn = ¬-not m≢ᵇn
nfIsSmallestInClass
: (f : ℕ → ℕ)
→ (nleq : NFLeq f)
→ (nfix : NFFix f)
→ (n : ℕ)
→ (H : (f n ≡ᵇ f n) ≡ true)
→ proj₁ (findMinAlwaysPoss n (λ m → f n ≡ᵇ f m) H) ≡ f n
nfIsSmallestInClass f nleq nfix ℕ.zero H =
begin
proj₁ (findMinAlwaysPoss 0 (λ m → f 0 ≡ᵇ f m) H)
≡⟨ findMinZeroLemma (λ m → f 0 ≡ᵇ f m) H ⟩
0
≡⟨ sym ( n≤0⇒n≡0 (nleq 0)) ⟩
f 0
∎
nfIsSmallestInClass f nleq nfix (ℕ.suc n) H =
let (ℓ , ℓ≤Sn , fSn≡ᵇfℓ , noSmallerℓ) =
(findMinAlwaysPoss (ℕ.suc n) (λ m → f (ℕ.suc n) ≡ᵇ f m) H)
in
let fℓ≡fSn : f ℓ ≡ f (ℕ.suc n)
fℓ≡fSn = sym (decEqToPredEq fSn≡ᵇfℓ)
in
let Sn≤ℓ : f (ℕ.suc n) ≤ ℓ
Sn≤ℓ = subst (λ x → x ≤ ℓ) fℓ≡fSn (nleq ℓ)
in
let fSn = f (ℕ.suc n)
in
let fSn≡ᵇffSn : (fSn ≡ᵇ f fSn) ≡ true
fSn≡ᵇffSn = predEqToDecEq (sym (nfix (ℕ.suc n)))
in
sym (noSmallerℓ fSn Sn≤ℓ fSn≡ᵇffSn)
lemma3
: (f : ℕ → ℕ)
→ (nleq : NFLeq f)
→ (nfix : NFFix f)
→ (R : DecEquiv)
→ (defR : proj₁ R ≡ λ (n m : ℕ) → f n ≡ᵇ f m)
→ (proj₁ ∘ RelToFun) R ≈ f
lemma3 f nleq nfix R refl n =
let H : (f n ≡ᵇ f n) ≡ true
H = ((IsEquivalence.refl ∘ proj₂) R) {n}
in
begin
(proj₁ ∘ RelToFun) R n
≡⟨ lemma1 R n ⟩
proj₁ (findMinAlwaysPoss n ((proj₁ R) n) H)
≡⟨ refl ⟩
proj₁ (findMinAlwaysPoss n (λ m → f n ≡ᵇ f m) H)
≡⟨ nfIsSmallestInClass f nleq nfix n H ⟩
f n
∎
FRFHomot : (F : NFFun) → (proj₁ ∘ RelToFun ∘ FunToRel) F ≈ proj₁ F
FRFHomot F@(f , nleq , nfix) = lemma3 f nleq nfix (FunToRel F) (lemma2 F)
oneMinPerClass
: (R : ℕ → ℕ → Bool)
→ (Req : IsEquivalence (R ⊢_~_))
→ (n m : ℕ)
→ (hₙ : R n n ≡ true)
→ (hₘ : R m m ≡ true)
→ (R n m) ≡
(
proj₁ (findMinAlwaysPoss n (R n) hₙ)
≡ᵇ
proj₁ (findMinAlwaysPoss m (R m) hₘ)
)
oneMinPerClass R Req n m hₙ hₘ
using ℓ ← (proj₁ (findMinAlwaysPoss n (R n) hₙ))
using k ← (proj₁ (findMinAlwaysPoss m (R m) hₘ))
with ((R n m) Data.Bool.≟ true)
... | yes nRm =
let symR : Symmetric (R ⊢_~_)
symR = IsEquivalence.sym Req
in
let transR : Transitive (R ⊢_~_)
transR = IsEquivalence.trans Req
in
let nRℓ : (R n ℓ ≡ true)
nRℓ = proj₁ (proj₂ (proj₂ (findMinAlwaysPoss n (R n) hₙ)))
in
let isSmallestℓn : NoSmaller ℓ (R n)
isSmallestℓn = proj₂ (proj₂ (proj₂ (findMinAlwaysPoss n (R n) hₙ)))
in
let mRℓ : (R m ℓ ≡ true)
mRℓ = transR (symR nRm) nRℓ
in
let isSmallestℓm : NoSmaller ℓ (R m)
isSmallestℓm x x≤ℓ mRx =
let nRx : (R n x ≡ true)
nRx = transR nRm mRx
in isSmallestℓn x x≤ℓ nRx
in
let isminℓm : IsMin ℓ (R m)
isminℓm = (mRℓ , isSmallestℓm)
in
let isminkm : IsMin k (R m)
isminkm = proj₂ (proj₂ (findMinAlwaysPoss m (R m) hₘ))
in
let ℓ≡k : ℓ ≡ k
ℓ≡k = minUnique ℓ k (R m) isminℓm isminkm
in
trans nRm (sym (predEqToDecEq ℓ≡k))
... | no ¬nRm with (ℓ Data.Nat.≟ k)
... | yes ℓ≡k =
let reflR : Reflexive (R ⊢_~_)
reflR = IsEquivalence.refl Req
in
let transR : Transitive (R ⊢_~_)
transR = IsEquivalence.trans Req
in
let symR : Symmetric (R ⊢_~_)
symR = IsEquivalence.sym Req
in
let nRℓ : (R n ℓ ≡ true)
nRℓ = proj₁ (proj₂ (proj₂ (findMinAlwaysPoss n (R n) hₙ)))
in
let ℓRk : (R ℓ k ≡ true)
ℓRk = subst (λ v → R ℓ v ≡ true) ℓ≡k (reflR {ℓ})
in
let kRm : (R k m ≡ true)
kRm = symR (proj₁ (proj₂ (proj₂ (findMinAlwaysPoss m (R m) hₘ))))
in
let nRm : (R n m ≡ true)
nRm = transR (transR nRℓ ℓRk) kRm
in
⊥-elim (¬nRm nRm)
... | no ℓ≢k =
let nRm≡false : (R n m) ≡ false
nRm≡false = ¬-not ¬nRm
in
let false≡[ℓ≡k] : false ≡ (ℓ ≡ᵇ k)
false≡[ℓ≡k] = sym (predNeqToDecNeq ℓ≢k)
in
trans nRm≡false false≡[ℓ≡k]
RFRLemma
: (R : DecEquiv)
→ (proj₁ ∘ FunToRel ∘ RelToFun) R
≡
λ (n m : ℕ) → (
proj₁ (findMinAlwaysPoss n (proj₁ R $ n) (IsEquivalence.refl (proj₂ R) {n}))
≡ᵇ
proj₁ (findMinAlwaysPoss m (proj₁ R $ m) (IsEquivalence.refl (proj₂ R) {m}))
)
RFRLemma R = refl
RFRHomot
: (R : DecEquiv)
→ (uncurry ∘ proj₁ ∘ FunToRel ∘ RelToFun) R ≈ (uncurry ∘ proj₁) R
RFRHomot R (n , m) =
let H₁ = RFRLemma R
in
let hₙ : (proj₁ R) n n ≡ true
hₙ = IsEquivalence.refl (proj₂ R) {n}
in
let hₘ : (proj₁ R) m m ≡ true
hₘ = IsEquivalence.refl (proj₂ R) {m}
in
let H₂ = oneMinPerClass (proj₁ R) (proj₂ R) n m hₙ hₘ
in
let H₃ = cong (λ x → (uncurry x) (n , m)) H₁
in
trans H₃ (sym H₂)
open import Eser.EqRel.LocalisiblePred
open LocalisiblePred
RelToFunPresvProps
: (P : LocalisiblePred)
→ (R : DecEquiv)
→ Prel P R ↔ AllRestr ((proj₁ ∘ RelToFun) R) (Ploc P)
RelToFunPresvProps P R = correspondence P R
applyEqArgs
: {A B C : Set}
→ {a a' : A}
→ {b b' : B}
→ (_app_ : A → B → C)
→ (a ≡ a')
→ (b ≡ b')
→ (a app b ≡ a' app b')
applyEqArgs {A} {B} {C} {a} {a'} {b} {b'} _app_ a≡a' b≡b' =
begin
a app b
≡⟨ cong (_app b) a≡a' ⟩
a' app b
≡⟨ cong (a' app_) b≡b' ⟩
a' app b'
∎
homotRestrictLift
: {f g : ℕ → ℕ}
→ (f ≈ g)
→ (n : ℕ)
→ (restrict n f) ≡ (restrict n g)
homotRestrictLift {f} {g} f≈g ℕ.zero = refl
homotRestrictLift {f} {g} f≈g (ℕ.suc n) =
let fn≡gn = f≈g n
in
let restOfVectorsEqual : restrict n f ≡ restrict n g
restOfVectorsEqual = homotRestrictLift {f} {g} f≈g n
in
applyEqArgs _∷_ fn≡gn restOfVectorsEqual
homotsPreserveAllRestrSat→
: {f g : ℕ → ℕ}
→ (f ≈ g)
→ (Ploc : LocPred)
→ AllRestr f Ploc → AllRestr g Ploc
homotsPreserveAllRestrSat→ {f} {g} f≈g Ploc AllRestrF n =
subst (λ vec → Ploc n vec) (homotRestrictLift f≈g n) (AllRestrF n)
homotsPreserveAllRestrSat
: {f g : ℕ → ℕ}
→ (f ≈ g)
→ (Ploc : LocPred)
→ AllRestr f Ploc ↔ AllRestr g Ploc
homotsPreserveAllRestrSat f≈g Ploc =
let LtoR = homotsPreserveAllRestrSat→ f≈g Ploc
in
let RtoL = homotsPreserveAllRestrSat→ (≈-sym f≈g) Ploc
in
(LtoR , RtoL)
FunToRelPresvProps→
: (P : LocalisiblePred)
→ (f : NFFun)
→ Prel P (FunToRel f)
→ AllRestr (proj₁ f) (Ploc P)
FunToRelPresvProps→ (localisiblePred Prel Ploc corresp) f PrelR =
let R : DecEquiv
R = FunToRel f
in
let H : AllRestr ((proj₁ ∘ RelToFun ∘ FunToRel) f ) Ploc
H = proj₁ (corresp R) PrelR
in
let FRFf≈f = (proj₁ ∘ RelToFun ∘ FunToRel) f ≈ (proj₁ f)
FRFf≈f = FRFHomot f
in
homotsPreserveAllRestrSat→ FRFf≈f Ploc H
FunToRelPresvProps←
: (P : LocalisiblePred)
→ (f : NFFun)
→ AllRestr (proj₁ f) (Ploc P)
→ Prel P (FunToRel f)
FunToRelPresvProps← (localisiblePred Prel Ploc corresp) f PlocF =
let R = FunToRel f
in
let f' = proj₁ (RelToFun (FunToRel f))
in
let f'≈f : f' ≈ proj₁ f
f'≈f = FRFHomot f
in
let PlocF' : AllRestr f' Ploc
PlocF' = λ n → subst (λ restr → Ploc n restr)
(homotRestrictLift {proj₁ f} {f'} (≈-sym f'≈f) n)
(PlocF n)
in
proj₂ (corresp R) PlocF'
FunToRelPresvProps
: (P : LocalisiblePred)
→ (f : NFFun)
→ Prel P (FunToRel f) ↔ AllRestr (proj₁ f) (Ploc P)
FunToRelPresvProps P f = (FunToRelPresvProps→ P f , FunToRelPresvProps← P f)