Skip to content

[ refactor ] Symmetry of Bijection as a consequence of properties of a given Surjective function #2583

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
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
98 changes: 98 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -17,6 +17,19 @@ Bug-fixes
the record constructors `_,_` incorrectly had no declared fixity. They have been given
the fixity `infixr 4 _,_`, consistent with that of `Data.Product.Base`.

* A major overhaul of the `Function` hierarchy sees the systematic development
and use of the theory of the left inverse `from` to a given `Surjective` function
`to`, as a consequence of which we can achieve full symmetry of `Bijection`, in
`Function.Properties.Bijection`/`Function.Construct.Symmetry`, rather than the
restricted versions considered to date. NB. this is non-backwards compatible
because the types of various properties are now sharper, and some previous lemmas
are no longer present, due to the complexity their deprecation would entail.
Specifically:
- `Function.Construct.Symmetry.isBijection` no longer requires the hypothesis `Congruent ≈₂ ≈₁ f⁻¹` for the function `f⁻¹ = B.from`.
- `Function.Construct.Symmetry.isBijection-≡` is now redundant, as an instance of the above lemma, so has been deleted.
- Similarly, `Function.Construct.Symmetry.bijection` no longer requires a `Congruent` hypothesis, and `Function.Construct.Symmetry.bijection-≡` is now redundant/deleted.
- `Function.Properties.Bijection.sym-≡` is now redundant as an instance of a fully general symmetry property `Function.Properties.Bijection.sym`, hence also deleted.

Non-backwards compatible changes
--------------------------------

@@ -28,6 +41,8 @@ Non-backwards compatible changes
Minor improvements
------------------

* The definitions in `Function.Consequences.Propositional` of the form `strictlyX⇒X` have been streamlined via pattern-matching on `refl`, rather than defined by delegation to `Function.Consequences.Setoid` and the use of `cong`.

* Moved the concept `Irrelevant` of irrelevance (h-proposition) from `Relation.Nullary`
to its own dedicated module `Relation.Nullary.Irrelevant`.

@@ -116,6 +131,17 @@ Deprecated names
product-↭ ↦ Data.Nat.ListAction.Properties.product-↭
```

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

* In `Function.Properties.Surjection`:
```agda
injective⇒to⁻-cong ↦ Function.Bundles.Bijection.from-cong
```

New modules
-----------

@@ -206,6 +232,78 @@ Additions to existing modules
filter-↭ : ∀ (P? : Pred.Decidable P) → xs ↭ ys → filter P? xs ↭ filter P? ys
```

* 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.Construct.Symmetry`:
```agda
isBijection : IsBijection ≈₁ ≈₂ to → IsBijection ≈₂ ≈₁ from
bijection : 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
from-cong : Congruent _≈₂_ _≈₁_ from
from-injective : Injective _≈₂_ _≈₁_ from
from-surjective : Surjective _≈₂_ _≈₁_ from
from-bijective : Bijective _≈₂_ _≈₁_ 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
from-injective : Injective _≈₂_ _≈₁_ from
```

* In `Relation.Binary.Construct.Add.Infimum.Strict`:
```agda
<₋-accessible-⊥₋ : Acc _<₋_ ⊥₋
30 changes: 17 additions & 13 deletions src/Data/Product/Function/Dependent/Propositional.agda
Original file line number Diff line number Diff line change
@@ -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.↣.

@@ -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


@@ -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
@@ -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)
63 changes: 33 additions & 30 deletions src/Data/Product/Function/Dependent/Setoid.agda
Original file line number Diff line number Diff line change
@@ -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
@@ -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
Loading