Repository: agda/agda-stdlib
Pull request #2689: [add] Update PartialSetoid reasoning
Author: login: Ailrun
Labels: name: bug
Created: 2025-04-03T16:49:40Z | Merged: 2025-04-21T08:54:30Z

Resolves #2677.

This one replaces the previous reasoning type for `PartialSetoid` with one properly supporting propositional equality steps.


Diff:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba601e31d3..fe1c031294 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,12 @@ Bug-fixes
   This has been deprecated in favor or `rightInverse`, and a corrected (and
   correctly-named) function `leftInverse` has been added.
 
+* The implementation of `_IsRelatedTo_` in `Relation.Binary.Reasoning.Base.Partial`
+  has been modified to correctly support equational reasoning at the beginning and the end.
+  The detail of this issue is described in [#2677](https://github.com/agda/agda-stdlib/pull/2677). Since the names of constructors
+  of `_IsRelatedTo_` are changed and the reduction behaviour of reasoning steps
+  are changed, this modification is non-backwards compatible.
+
 Non-backwards compatible changes
 --------------------------------
 
diff --git a/src/Relation/Binary/Reasoning/Base/Partial.agda b/src/Relation/Binary/Reasoning/Base/Partial.agda
index 5da6792f64..e8e0cbc920 100644
--- a/src/Relation/Binary/Reasoning/Base/Partial.agda
+++ b/src/Relation/Binary/Reasoning/Base/Partial.agda
@@ -22,52 +22,55 @@ module Relation.Binary.Reasoning.Base.Partial
 ------------------------------------------------------------------------
 -- Definition of "related to"
 
--- This seemingly unnecessary type is used to make it possible to
--- infer arguments even if the underlying equality evaluates.
+-- This type allows us to track whether reasoning steps
+-- include _∼_ or not.
 
 infix  4 _IsRelatedTo_
 
 data _IsRelatedTo_ : A → A → Set (a ⊔ ℓ) where
-  singleStep : ∀ x → x IsRelatedTo x
-  multiStep  : ∀ {x y} (x∼y : x ∼ y) → x IsRelatedTo y
+  reflexive : ∀ {x y} → x ≡ y → x IsRelatedTo y
+  relTo     : ∀ {x y} (x∼y : x ∼ y) → x IsRelatedTo y
+
+≡-go : Trans _≡_ _IsRelatedTo_ _IsRelatedTo_
+≡-go x≡y (reflexive y≡z) = reflexive (case x≡y of λ where ≡.refl → y≡z)
+≡-go x≡y (relTo y∼z)     = relTo (case x≡y of λ where ≡.refl → y∼z)
 
 ∼-go : Trans _∼_ _IsRelatedTo_ _IsRelatedTo_
-∼-go x∼y (singleStep y) = multiStep x∼y
-∼-go x∼y (multiStep y∼z) = multiStep (trans x∼y y∼z)
+∼-go x∼y (reflexive y≡z) = relTo (case y≡z of λ where ≡.refl → x∼y)
+∼-go x∼y (relTo y∼z)     = relTo (trans x∼y y∼z)
 
 stop : Reflexive _IsRelatedTo_
-stop = singleStep _
+stop = reflexive ≡.refl
 
 ------------------------------------------------------------------------
 -- Types that are used to ensure that the final relation proved by the
 -- chain of reasoning can be converted into the required relation.
 
-data IsMultiStep {x y} : x IsRelatedTo y → Set (a ⊔ ℓ) where
-  isMultiStep : ∀ x∼y → IsMultiStep (multiStep x∼y)
+data IsRelTo {x y} : x IsRelatedTo y → Set (a ⊔ ℓ) where
+  isRelTo : ∀ x∼y → IsRelTo (relTo x∼y)
 
-IsMultiStep? : ∀ {x y} (x∼y : x IsRelatedTo y) → Dec (IsMultiStep x∼y)
-IsMultiStep? (multiStep x<y) = yes (isMultiStep x<y)
-IsMultiStep? (singleStep _)  = no λ()
+IsRelTo? : ∀ {x y} (x∼y : x IsRelatedTo y) → Dec (IsRelTo x∼y)
+IsRelTo? (relTo x∼y)   = yes (isRelTo x∼y)
+IsRelTo? (reflexive _) = no λ()
 
-extractMultiStep : ∀ {x y} {x∼y : x IsRelatedTo y} → IsMultiStep x∼y → x ∼ y
-extractMultiStep (isMultiStep x≈y) = x≈y
+extractRelTo : ∀ {x y} {x∼y : x IsRelatedTo y} → IsRelTo x∼y → x ∼ y
+extractRelTo (isRelTo x∼y) = x∼y
 
-multiStepSubRelation : SubRelation _IsRelatedTo_ _ _
-multiStepSubRelation = record
-  { IsS = IsMultiStep
-  ; IsS? = IsMultiStep?
-  ; extract = extractMultiStep
+relToSubRelation : SubRelation _IsRelatedTo_ _ _
+relToSubRelation = record
+  { IsS = IsRelTo
+  ; IsS? = IsRelTo?
+  ; extract = extractRelTo
   }
 
 ------------------------------------------------------------------------
 -- Reasoning combinators
 
-open begin-subrelation-syntax _IsRelatedTo_ multiStepSubRelation public
-open ≡-noncomputing-syntax _IsRelatedTo_ public
+open begin-subrelation-syntax _IsRelatedTo_ relToSubRelation public
+open ≡-syntax _IsRelatedTo_ ≡-go public
 open ∼-syntax _IsRelatedTo_ _IsRelatedTo_ ∼-go public
 open end-syntax _IsRelatedTo_ stop public
 
-
 ------------------------------------------------------------------------
 -- DEPRECATED NAMES
 ------------------------------------------------------------------------
@@ -79,7 +82,7 @@ open end-syntax _IsRelatedTo_ stop public
 infix  3 _∎⟨_⟩
 
 _∎⟨_⟩ : ∀ x → x ∼ x → x IsRelatedTo x
-_ ∎⟨ x∼x ⟩ = multiStep x∼x
+_ ∎⟨ x∼x ⟩ = relTo x∼x
 {-# WARNING_ON_USAGE _∎⟨_⟩
 "Warning: _∎⟨_⟩ was deprecated in v1.6.
 Please use _∎ instead if used in a chain, otherwise simply provide


Reviews:
user: login: Ailrun
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T17:00:13Z
user: login: JacquesCarette
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-04T12:10:29Z
user: login: MatthewDaggitt
body: Otherwise looks great, thanks for doing this!
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-04-10T05:50:11Z
user: login: MatthewDaggitt
body: Thanks for the changes @Ailrun. I'm happy to consider this a bugfix as this was the intended behaviour. Let's merge in v2.3.
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-21T04:27:56Z

Review comments:
diff_hunk: @@ -22,52 +22,55 @@ module Relation.Binary.Reasoning.Base.Partial
 ------------------------------------------------------------------------
 -- Definition of "related to"
 
--- This seemingly unnecessary type is used to make it possible to
--- infer arguments even if the underlying equality evaluates.
+-- This type allows us to track whether reasoning steps
+-- include _∼_ or not.
 
 infix  4 _IsRelatedTo_
 
 data _IsRelatedTo_ : A → A → Set (a ⊔ ℓ) where
-  singleStep : ∀ x → x IsRelatedTo x
-  multiStep  : ∀ {x y} (x∼y : x ∼ y) → x IsRelatedTo y
+  reflexive : ∀ {x y} → x ≡ y → x IsRelatedTo y
+  relTo     : ∀ {x y} (x∼y : x ∼ y) → x IsRelatedTo y
path: src/Relation/Binary/Reasoning/Base/Partial.agda
user: login: Ailrun
body: Rename constructors to stay closer to `Single` reasoning
created_at: 2025-04-03T17:00:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -25,6 +25,12 @@ Non-backwards compatible changes
   significantly faster. However, its reduction behaviour on open terms may have
   changed.
 
+* The implementation of `_IsRelatedTo_` in `Relation.Binary.Reasoning.Base.Partial`
+  has been modified to support equaltional reasoning at the beginning and the end.
path: CHANGELOG.md
user: login: MatthewDaggitt
body: Typo `equaltional`.
created_at: 2025-04-10T05:49:03Z
author_association: COLLABORATOR
diff_hunk: @@ -25,6 +25,12 @@ Non-backwards compatible changes
   significantly faster. However, its reduction behaviour on open terms may have
   changed.
 
+* The implementation of `_IsRelatedTo_` in `Relation.Binary.Reasoning.Base.Partial`
+  has been modified to support equaltional reasoning at the beginning and the end.
+  The detail of this issue is described in [#2677](https://github.com/agda/agda-stdlib/pull/2677). Since the names of constructors
+  of `_IsRelatedTo_` are changed and the reduction behaviour of reasoning steps
+  are changed, this modification is non-backwards compatible.
path: CHANGELOG.md
user: login: MatthewDaggitt
body: This should probably be a `bug fix`. It was certainly intended for you to be able to have equational reasoning at the start and the end!
created_at: 2025-04-10T05:49:38Z
author_association: COLLABORATOR

PR comments:
user: login: jamesmckinna
created_at: 2025-04-04T12:34:31Z
body: Just to check: do these additions/changes fix the issues identified under the original PR? 
If so, suggest closing #2677 with a comment to that effect?
author_association: COLLABORATOR
user: login: Ailrun
created_at: 2025-04-04T20:12:25Z
body: @jamesmckinna Yes, this will solve the issue by removing any eager pattern matching on propositional equality proofs. I will update this PR's description so that merging this closes the other PR. edit: The description is now updated.
author_association: CONTRIBUTOR
user: login: jamesmckinna
created_at: 2025-04-05T10:41:48Z
body: This will also need a `CHANGELOG` entry, as you've changed the API for `PartialSetoid` reasoning: under `Non-backwards-compatible changes`, or `Bug-fixes`? Shoutout to @MatthewDaggitt 
author_association: COLLABORATOR
user: login: Ailrun
created_at: 2025-04-07T18:24:29Z
body: @jamesmckinna Changelog entry is added.
author_association: CONTRIBUTOR
user: login: Ailrun
created_at: 2025-04-10T11:37:36Z
body: @MatthewDaggitt Fixed! Thanks for the comments.
author_association: CONTRIBUTOR
user: login: jamesmckinna
created_at: 2025-04-16T06:24:57Z
body: How to label this one?
* `breaking`, hence v3.0
or
* `bug`, hence maybe v2.3
author_association: COLLABORATOR
user: login: Ailrun
created_at: 2025-04-16T06:34:32Z
body: @jamesmckinna It seems like @MatthewDaggitt considers this as a bug fix. I think it is a breaking change, but since no one actually come up with an issue or a PR about the problem in #2677, maybe this one is not so impactful to become a "real" breaking change.
author_association: CONTRIBUTOR
user: login: jamesmckinna
created_at: 2025-04-16T06:39:40Z
body: For me, it's more  a case of: let's decide, then merge for v2.3, or defer to the next release...
author_association: COLLABORATOR
user: login: Ailrun
created_at: 2025-04-20T02:05:28Z
body: @jamesmckinna I'm not sure it's okay for me to say this, but let's merge this for v2.3 if no one objects.
author_association: CONTRIBUTOR