Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ refactor ] fixes #2568; proves full symmetry for Bijection #2569

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
cf181c4
fixes #2568
jamesmckinna Jan 28, 2025
e42c634
DRY: delegate to `Function.Consequences`
jamesmckinna Jan 29, 2025
9f86e57
refactor: delegate systematically to `Consequences` and `Structures`
jamesmckinna Jan 29, 2025
8ffbebf
add: `injective` and `isInjection` to `IsRightInverse`
jamesmckinna Jan 29, 2025
7ef3206
add: `injection : Injection From To` to `IsRightInverse`
jamesmckinna Jan 29, 2025
2f6b3c2
add: module `IsSurjective` to `Consequences`
jamesmckinna Jan 29, 2025
e6899ef
refactor: re-export from `Consequences.IsSurjective`
jamesmckinna Jan 29, 2025
3cd9e7b
refactor: use module `IsSurjective`
jamesmckinna Jan 29, 2025
eeb49e6
refactor: deprecate second definition
jamesmckinna Jan 29, 2025
520b838
refactor: deprecate `injective⇒to⁻-cong`
jamesmckinna Jan 29, 2025
8efb15d
fix: exports from `Surjection` and `Bijection`
jamesmckinna Jan 29, 2025
576610f
refactor: deprecate `injective⇒to⁻-cong`
jamesmckinna Jan 29, 2025
08fb122
fix: symmetry of `Bijection`; deprecate `sym-≡`
jamesmckinna Jan 29, 2025
c15f748
fix: deprecation via export of `sym-≡`
jamesmckinna Jan 29, 2025
cf9c04e
fix: knock-ons
jamesmckinna Jan 29, 2025
f56cd9e
fix: whitespace
jamesmckinna Jan 29, 2025
b855ebc
fix: indentation
jamesmckinna Jan 29, 2025
7fcbcb0
add: `section-cong` congruence proof
jamesmckinna Jan 30, 2025
fbc5c50
refactor: deprecate `injective⇒to⁻-cong`
jamesmckinna Jan 30, 2025
68e58cf
fix: whitespace
jamesmckinna Jan 30, 2025
6bb39ce
refactor: use `section-cong`
jamesmckinna Jan 30, 2025
72f7c78
refactor: move properties from `Symmetry` to `Consequences`; rename m…
jamesmckinna Jan 30, 2025
2bcad3b
refactor: sharpen sub-module parameterisation
jamesmckinna Jan 30, 2025
6d725fd
refactor: use module ; rectify exported names
jamesmckinna Jan 30, 2025
dfce04f
refactor: use module ; rectify exported names
jamesmckinna Jan 30, 2025
b35b5a1
refactor: fix names, deprecations for v2.3
jamesmckinna Jan 30, 2025
ace7b08
refactor: lift out `inverseʳ`
jamesmckinna Jan 30, 2025
f12d36f
refactor: lift out `strictlyInverseʳ`
jamesmckinna Jan 30, 2025
1439887
refactor: lift out `strictlyInverseʳ`
jamesmckinna Jan 30, 2025
53ab09a
refactor: propagate exports of new lemmas
jamesmckinna Jan 30, 2025
9070bfd
refactor: clean up `Bijection⇒Inverse`
jamesmckinna Jan 30, 2025
9d1bd5e
fix: deprecated definition
jamesmckinna Jan 30, 2025
3e15e99
fix: use of rectified lemma names
jamesmckinna Jan 30, 2025
679241e
fix: deprecation warning
jamesmckinna Jan 30, 2025
ad7af96
fix: dependencies
jamesmckinna Jan 30, 2025
6141208
fix: dependencies
jamesmckinna Jan 30, 2025
9cbc30d
add: `CHANGELOG`
jamesmckinna Jan 30, 2025
325c66f
fix: version numbers in deprecations
jamesmckinna Jan 30, 2025
f981711
refactor: Luke, use the force!
jamesmckinna Jan 31, 2025
629f00c
fix: streamlining
jamesmckinna Jan 31, 2025
79afa5b
fix: streamlining
jamesmckinna Jan 31, 2025
d8ec317
fix: type, and definition, of `strictlyInverseʳ`
jamesmckinna Jan 31, 2025
2326602
tweak; `import` list
jamesmckinna Feb 1, 2025
1156681
refactor: add `Setoid` version of module `Section`
jamesmckinna Feb 1, 2025
9115dd7
refactor: propagate definitions
jamesmckinna Feb 1, 2025
3c577cf
fix: update `CHANGELOG`
jamesmckinna Feb 1, 2025
8d072d6
fix: add missing entries!
jamesmckinna Feb 2, 2025
7bd938c
refactor: exploit duality; cherry-picked from #2567
jamesmckinna Feb 2, 2025
0997c71
fix: typo
jamesmckinna Feb 2, 2025
86dab2d
fix: add more fields/missing `CHANGELOG` entries!
jamesmckinna Feb 2, 2025
90b30f1
refactor: rename `section` to `from`, plus some additional `to` infra…
jamesmckinna Feb 5, 2025
519980f
refactor: rename `f` to `to` for consistency
jamesmckinna Feb 6, 2025
0e4e6c0
fix: comment on `SplitSurjection`
jamesmckinna Feb 6, 2025
1b7da0f
Merge branch 'master' into surjective-section
jamesmckinna Feb 6, 2025
d494fc9
refactor: fix names; inline definitions and use of the `Properties`
jamesmckinna Feb 7, 2025
680f750
fix: names
jamesmckinna Feb 7, 2025
e72c9e7
fix: parentheses
jamesmckinna Feb 7, 2025
62a1573
fix: names
jamesmckinna Feb 7, 2025
ea2eb99
fix: tighten imports
jamesmckinna Feb 7, 2025
c8a6e5a
fix: `variable`s, specifically `f⁻¹`
jamesmckinna Feb 8, 2025
3e37854
fix: cosmetics
jamesmckinna Feb 8, 2025
dfe1bf1
refactor: PROVISIONAL; show the effect of inlining
jamesmckinna Feb 8, 2025
a6883ff
fix_ whitespace
jamesmckinna Feb 8, 2025
098d0a3
refactor: tidy up
jamesmckinna Feb 9, 2025
2aa1806
refactor: rename `Sf` to `From`
jamesmckinna Feb 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The library has been tested using Agda 2.7.0 and 2.7.0.1.
Highlights
----------

* A major overhaul of the `Function` hierarchy sees the systematic development
and use of theory of the left inverse `from` to a given `Surjective` function
`to`, in `Function.Consequences.Section`, up to and including full symmetry of
`Bijection`, in `Function.Properties.Bijection`.

Bug-fixes
---------

Expand Down Expand Up @@ -57,6 +62,32 @@ Deprecated names
or ↦ Data.Bool.ListAction.or
any ↦ Data.Bool.ListAction.any
all ↦ Data.Bool.ListAction.all
```

* In `Function.Bundles.IsSurjection`:
```agda
to⁻ ↦ Function.Structures.IsSurjection.from
to∘to⁻ ↦ Function.Structures.IsSurjection.strictlyInverseˡ
```

* In `Function.Construct.Symmetry`:
```agda
injective ↦ Function.Consequences.Section.injective
surjective ↦ Function.Consequences.Section.surjective
bijective ↦ Function.Consequences.Section.bijective
isBijection ↦ isBijectionWithoutCongruence
isBijection-≡ ↦ isBijectionWithoutCongruence
bijection-≡ ↦ bijectionWithoutCongruence
```

* In `Function.Properties.Bijection`:
```agda
sym-≡ ↦ sym
```

* In `Function.Properties.Surjection`:
```agda
injective⇒to⁻-cong ↦ Function.Construct.Symmetry.bijectionWithoutCongruence
```

New modules
Expand Down Expand Up @@ -95,3 +126,77 @@ Additions to existing modules
quasiring : Quasiring c ℓ → Quasiring (a ⊔ c) (a ⊔ ℓ)
commutativeRing : CommutativeRing c ℓ → CommutativeRing (a ⊔ c) (a ⊔ ℓ)
```

* In `Function.Bundles.Bijection`:
```agda
from : B → A
inverseˡ : Inverseˡ _≈₁_ _≈₂_ to from
strictlyInverseˡ : StrictlyInverseˡ _≈₂_ to from
inverseʳ : Inverseʳ _≈₁_ _≈₂_ to from
strictlyInverseʳ : StrictlyInverseʳ _≈₁_ to from
```

* In `Function.Bundles.LeftInverse`:
```agda
surjective : Surjective _≈₁_ _≈₂_ to
surjection : Surjection From To
```

* In `Function.Bundles.RightInverse`:
```agda
isInjection : IsInjection to
injective : Injective _≈₁_ _≈₂_ to
injection : Injection From To
```

* In `Function.Bundles.Surjection`:
```agda
from : B → A
inverseˡ : Inverseˡ _≈₁_ _≈₂_ to from
strictlyInverseˡ : StrictlyInverseˡ _≈₂_ to from
```

* In `Function.Consequences` and `Function.Consequences.Setoid`:
the theory of the left inverse of a surjective function `to`
```agda
module Section (surj : Surjective ≈₁ ≈₂ to)
```

* In `Function.Construct.Symmetry`:
```agda
isBijectionWithoutCongruence : IsBijection ≈₁ ≈₂ to → IsBijection ≈₂ ≈₁ from
bijectionWithoutCongruence : Bijection R S → Bijection S R
```

* In `Function.Properties.Bijection`:
```agda
sym : Bijection S T → Bijection T S
```

* In `Function.Structures.IsBijection`:
```agda
from : B → A
inverseˡ : Inverseˡ _≈₁_ _≈₂_ to from
strictlyInverseˡ : StrictlyInverseˡ _≈₂_ to from
inverseʳ : Inverseʳ _≈₁_ _≈₂_ to from
strictlyInverseʳ : StrictlyInverseʳ _≈₁_ to from
```

* In `Function.Structures.IsLeftInverse`:
```agda
surjective : Surjective _≈₁_ _≈₂_ to
```

* In `Function.Structures.IsRightInverse`:
```agda
injective : Injective _≈₁_ _≈₂_ to
isInjection : IsInjection to
```

* In `Function.Structures.IsSurjection`:
```agda
from : B → A
inverseˡ : Inverseˡ _≈₁_ _≈₂_ to from
strictlyInverseˡ : StrictlyInverseˡ _≈₂_ to from
```

30 changes: 17 additions & 13 deletions src/Data/Product/Function/Dependent/Propositional.agda
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ module _ where
Σ I A ⇔ Σ J B
Σ-⇔ {B = B} I↠J A⇔B = mk⇔
(map (to I↠J) (Equivalence.to A⇔B))
(map (to⁻ I↠J) (Equivalence.from A⇔B ∘ ≡.subst B (≡.sym (proj₂ (surjective I↠J _) ≡.refl))))
(map (from I↠J) (Equivalence.from A⇔B ∘ ≡.subst B (≡.sym (proj₂ (surjective I↠J _) ≡.refl))))

-- See also Data.Product.Relation.Binary.Pointwise.Dependent.WithK.↣.

Expand Down Expand Up @@ -193,18 +193,22 @@ module _ where
to′ : Σ I A → Σ J B
to′ = map (to I↠J) (to A↠B)

backcast : ∀ {i} → B i → B (to I↠J (to⁻ I↠J i))
backcast = ≡.subst B (≡.sym (to∘to⁻ I↠J _))
backcast : ∀ {i} → B i → B (to I↠J (from I↠J i))
backcast = ≡.subst B (≡.sym (strictlyInverseˡ I↠J _))

to⁻′ : Σ J B → Σ I A
to⁻′ = map (to⁻ I↠J) (Surjection.to⁻ A↠B ∘ backcast)
from′ : Σ J B → Σ I A
from′ = map (from I↠J) (from A↠B ∘ backcast)

strictlySurjective′ : StrictlySurjective _≡_ to′
strictlySurjective′ (x , y) = to⁻′ (x , y) , Σ-≡,≡→≡
( to∘to⁻ I↠J x
, (≡.subst B (to∘to⁻ I↠J x) (to A↠B (to⁻ A↠B (backcast y))) ≡⟨ ≡.cong (≡.subst B _) (to∘to⁻ A↠B _) ⟩
≡.subst B (to∘to⁻ I↠J x) (backcast y) ≡⟨ ≡.subst-subst-sym (to∘to⁻ I↠J x) ⟩
y ∎)
strictlySurjective′ (x , y) = from′ (x , y) , Σ-≡,≡→≡
( strictlyInverseˡ I↠J x
, (begin
≡.subst B (strictlyInverseˡ I↠J x) (to A↠B (from A↠B (backcast y)))
≡⟨ ≡.cong (≡.subst B _) (strictlyInverseˡ A↠B _) ⟩
≡.subst B (strictlyInverseˡ I↠J x) (backcast y)
≡⟨ ≡.subst-subst-sym (strictlyInverseˡ I↠J x) ⟩
y
∎)
) where open ≡.≡-Reasoning


Expand Down Expand Up @@ -249,8 +253,8 @@ module _ where
Σ I A ↔ Σ J B
Σ-↔ {I = I} {J = J} {A = A} {B = B} I↔J A↔B = mk↔ₛ′
(Surjection.to surjection′)
(Surjection.to⁻ surjection′)
(Surjection.to∘to⁻ surjection′)
(Surjection.from surjection′)
(Surjection.strictlyInverseˡ surjection′)
left-inverse-of
where
open ≡.≡-Reasoning
Expand All @@ -260,7 +264,7 @@ module _ where
surjection′ : Σ I A ↠ Σ J B
surjection′ = Σ-↠ (↔⇒↠ (≃⇒↔ I≃J)) (↔⇒↠ A↔B)

left-inverse-of : ∀ p → Surjection.to⁻ surjection′ (Surjection.to surjection′ p) ≡ p
left-inverse-of : ∀ p → Surjection.from surjection′ (Surjection.to surjection′ p) ≡ p
left-inverse-of (x , y) = to Σ-≡,≡↔≡
( _≃_.left-inverse-of I≃J x
, (≡.subst A (_≃_.left-inverse-of I≃J x)
Expand Down
63 changes: 33 additions & 30 deletions src/Data/Product/Function/Dependent/Setoid.agda
Original file line number Diff line number Diff line change
Expand Up @@ -94,34 +94,37 @@ module _ where
(function (⇔⇒⟶ I⇔J) A⟶B)
(function (⇔⇒⟵ I⇔J) B⟶A)

equivalence-↪ :
(I↪J : I ↪ J) →
(∀ {i} → Equivalence (A atₛ (RightInverse.from I↪J i)) (B atₛ i)) →
Equivalence (I ×ₛ A) (J ×ₛ B)
equivalence-↪ {A = A} {B = B} I↪J A⇔B =
equivalence (RightInverse.equivalence I↪J) A→B (fromFunction A⇔B)
where
A→B : ∀ {i} → Func (A atₛ i) (B atₛ (RightInverse.to I↪J i))
A→B = record
{ to = to A⇔B ∘ cast A (RightInverse.strictlyInverseʳ I↪J _)
; cong = to-cong A⇔B ∘ cast-cong A (RightInverse.strictlyInverseʳ I↪J _)
}
module _ (I↪J : I ↪ J) where

equivalence-↠ :
(I↠J : I ↠ J) →
(∀ {x} → Equivalence (A atₛ x) (B atₛ (Surjection.to I↠J x))) →
Equivalence (I ×ₛ A) (J ×ₛ B)
equivalence-↠ {A = A} {B = B} I↠J A⇔B =
equivalence (↠⇒⇔ I↠J) B-to B-from
where
B-to : ∀ {x} → Func (A atₛ x) (B atₛ (Surjection.to I↠J x))
B-to = toFunction A⇔B
private module ItoJ = RightInverse I↪J

B-from : ∀ {y} → Func (B atₛ y) (A atₛ (Surjection.to⁻ I↠J y))
B-from = record
{ to = from A⇔B ∘ cast B (Surjection.to∘to⁻ I↠J _)
; cong = from-cong A⇔B ∘ cast-cong B (Surjection.to∘to⁻ I↠J _)
}
equivalence-↪ : (∀ {i} → Equivalence (A atₛ (ItoJ.from i)) (B atₛ i)) →
Equivalence (I ×ₛ A) (J ×ₛ B)
equivalence-↪ {A = A} {B = B} A⇔B =
equivalence ItoJ.equivalence A→B (fromFunction A⇔B)
where
A→B : ∀ {i} → Func (A atₛ i) (B atₛ (ItoJ.to i))
A→B = record
{ to = to A⇔B ∘ cast A (ItoJ.strictlyInverseʳ _)
; cong = to-cong A⇔B ∘ cast-cong A (ItoJ.strictlyInverseʳ _)
}

module _ (I↠J : I ↠ J) where

private module ItoJ = Surjection I↠J

equivalence-↠ : (∀ {x} → Equivalence (A atₛ x) (B atₛ (ItoJ.to x))) →
Equivalence (I ×ₛ A) (J ×ₛ B)
equivalence-↠ {A = A} {B = B} A⇔B = equivalence (↠⇒⇔ I↠J) B-to B-from
where
B-to : ∀ {x} → Func (A atₛ x) (B atₛ (ItoJ.to x))
B-to = toFunction A⇔B

B-from : ∀ {y} → Func (B atₛ y) (A atₛ (ItoJ.from y))
B-from = record
{ to = from A⇔B ∘ cast B (ItoJ.strictlyInverseˡ _)
; cong = from-cong A⇔B ∘ cast-cong B (ItoJ.strictlyInverseˡ _)
}

------------------------------------------------------------------------
-- Injections
Expand Down Expand Up @@ -168,12 +171,12 @@ module _ where
func : Func (I ×ₛ A) (J ×ₛ B)
func = function (Surjection.function I↠J) (Surjection.function A↠B)

to⁻′ : Carrier (J ×ₛ B) → Carrier (I ×ₛ A)
to⁻′ (j , y) = to⁻ I↠J j , to⁻ A↠B (cast B (Surjection.to∘to⁻ I↠J _) y)
from′ : Carrier (J ×ₛ B) → Carrier (I ×ₛ A)
from′ (j , y) = from I↠J j , from A↠B (cast B (strictlyInverseˡ I↠J _) y)

strictlySurj : StrictlySurjective (Func.Eq₂._≈_ func) (Func.to func)
strictlySurj (j , y) = to⁻′ (j , y) ,
to∘to⁻ I↠J j , IndexedSetoid.trans B (to∘to⁻ A↠B _) (cast-eq B (to∘to⁻ I↠J j))
strictlySurj (j , y) = from′ (j , y) ,
strictlyInverseˡ I↠J j , IndexedSetoid.trans B (strictlyInverseˡ A↠B _) (cast-eq B (strictlyInverseˡ I↠J j))

surj : Surjective (Func.Eq₁._≈_ func) (Func.Eq₂._≈_ func) (Func.to func)
surj = strictlySurjective⇒surjective (I ×ₛ A) (J ×ₛ B) (Func.cong func) strictlySurj
Expand Down
53 changes: 41 additions & 12 deletions src/Function/Bundles.agda
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@
module Function.Bundles where

open import Function.Base using (_∘_)
open import Function.Consequences.Propositional
open import Function.Definitions
import Function.Structures as FunctionStructures
open import Level using (Level; _⊔_; suc)
open import Data.Product.Base using (_,_; proj₁; proj₂)
open import Relation.Binary.Bundles using (Setoid)
open import Relation.Binary.Core using (_Preserves_⟶_)
open import Relation.Binary.PropositionalEquality.Core as ≡
using (_≡_)
import Relation.Binary.PropositionalEquality.Properties as ≡
open import Function.Consequences.Propositional
open Setoid using (isEquivalence)

private
Expand Down Expand Up @@ -113,13 +112,24 @@ module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) where
open IsSurjection isSurjection public
using
( strictlySurjective
; from
; inverseˡ
; strictlyInverseˡ
)

to⁻ : B → A
to⁻ = proj₁ ∘ surjective
to⁻ = from
{-# WARNING_ON_USAGE to⁻
"Warning: to⁻ was deprecated in v2.3.
Please use Function.Structures.IsSurjection.from instead. "
#-}

to∘to⁻ : ∀ x → to (to⁻ x) ≈₂ x
to∘to⁻ = proj₂ ∘ strictlySurjective
to∘to⁻ : StrictlyInverseˡ _≈₂_ to from
to∘to⁻ = strictlyInverseˡ
{-# WARNING_ON_USAGE to∘to⁻
"Warning: to∘to⁻ was deprecated in v2.3.
Please use Function.Structures.IsSurjection.strictlyInverseˡ instead. "
#-}


record Bijection : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) where
Expand All @@ -146,16 +156,24 @@ module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) where
; surjective = surjective
}

open Injection injection public using (isInjection)
open Surjection surjection public using (isSurjection; to⁻; strictlySurjective)
open Injection injection public
using (isInjection)
open Surjection surjection public
using (isSurjection
; strictlySurjective
; from
; inverseˡ
; strictlyInverseˡ
)

isBijection : IsBijection to
isBijection = record
{ isInjection = isInjection
; surjective = surjective
}

open IsBijection isBijection public using (module Eq₁; module Eq₂)
open IsBijection isBijection public
using (module Eq₁; module Eq₂; inverseʳ; strictlyInverseʳ)


------------------------------------------------------------------------
Expand Down Expand Up @@ -220,6 +238,8 @@ module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) where
open IsLeftInverse isLeftInverse public
using (module Eq₁; module Eq₂; strictlyInverseˡ; isSurjection)

open IsSurjection isSurjection public using (surjective)

equivalence : Equivalence
equivalence = record
{ to-cong = to-cong
Expand All @@ -236,7 +256,7 @@ module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) where
surjection = record
{ to = to
; cong = to-cong
; surjective = λ y → from y , inverseˡ
; surjective = surjective
}


Expand All @@ -246,7 +266,7 @@ module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) where
to : A → B
from : B → A
to-cong : Congruent _≈₁_ _≈₂_ to
from-cong : from Preserves _≈₂_ _≈₁_
from-cong : Congruent _≈₂_ _≈₁_ from
inverseʳ : Inverseʳ _≈₁_ _≈₂_ to from

isCongruent : IsCongruent to
Expand All @@ -264,14 +284,23 @@ module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) where
}

open IsRightInverse isRightInverse public
using (module Eq₁; module Eq₂; strictlyInverseʳ)
using (module Eq₁; module Eq₂; strictlyInverseʳ; isInjection)

open IsInjection isInjection public using (injective)

equivalence : Equivalence
equivalence = record
{ to-cong = to-cong
; from-cong = from-cong
}

injection : Injection From To
injection = record
{ to = to
; cong = to-cong
; injective = injective
}


record Inverse : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) where
field
Expand Down Expand Up @@ -370,7 +399,7 @@ module _ (From : Setoid a ℓ₁) (To : Setoid b ℓ₂) where
-- function for elements `x₁` and `x₂` are equal if `x₁ ≈ x₂` .
--
-- The difference is the `from-cong` law --- generally, the section
-- (called `Surjection.to⁻` or `SplitSurjection.from`) of a surjection
-- (called `Surjection.from` or `SplitSurjection.from`) of a surjection
-- need not respect equality, whereas it must in a split surjection.
--
-- The two notions coincide when the equivalence relation on `B` is
Expand Down
Loading