-
Notifications
You must be signed in to change notification settings - Fork 258
[ add ] Setoid from PartialSetoid
#2816
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One quibble, but otherwise I like this now.
| module Relation.Binary.Construct.SetoidFromPartialSetoid | ||
| {a ℓ} (S : PartialSetoid a ℓ) where | ||
|
|
||
| open import Data.Product.Base using (_,_; Σ; proj₁; proj₂) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if it would be worse, or better, to have something like
| open import Data.Product.Base using (_,_; Σ; proj₁; proj₂) | |
| open import Data.Product.Base using (_,_; Σ) | |
| renaming (proj₁ to ι; proj₂ to x≈x) |
so that subsequent definitions can exploit such 'abstract' vocabulary/notation, rather than expose the concrete projection names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or perhaps better still, remove/inline refl as below, and make
ι : Carrier → S.Carrier
ι = proj₁so that it may subsequently be exported/exportable as such?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're going to go that route (second suggestion), why not bite the bullet and make the thing a record? Post-facto adding aliases for projections is what agda-unimath does... and it eventually leads to unreadable goals.
I like the first suggestion even less.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, in a way, the record-based version is (arguably) cleaner:
record SubSetoid : Set (a ⊔ ℓ) where
field
ι : S.Carrier
refl : ι S.≈ ι
open SubSetoid public using (ι)
_≈_ : Rel SubSetoid _
_≈_ = S._≈_ on ι
-- Structure
isEquivalence : IsEquivalence _≈_
isEquivalence = record
{ refl = λ {x = x} → SubSetoid.refl x
; sym = S.sym
; trans = S.trans
}
-- Bundle
setoid : Setoid _ _
setoid = record { isEquivalence = isEquivalence }
-- Monomorphism
isRelHomomorphism : IsRelHomomorphism _≈_ S._≈_ ι
isRelHomomorphism = record { cong = id }
isRelMonomorphism : IsRelMonomorphism _≈_ S._≈_ ι
isRelMonomorphism = record { isHomomorphism = isRelHomomorphism ; injective = id }There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I certainly would argue so!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the interests of clarity: are you saying that you would prefer that it be changed in favour of the record version?
More than happy to do so if so!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I've retained Carrier as the name of the underlying type, but I suppose something else, such as SubSetoid, would work as well. Field name refl is kept hidden, so that its 'rectification' (wrt implicit quantification) as Setoid.refl is the way to access it.
| ------------------------------------------------------------------------ | ||
| -- Definitions | ||
|
|
||
| record Carrier : Set (a ⊔ ℓ) where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must say that I expected the carrier to be called Carrier (and not ι) with the record called something like 'Reflective' or some such.
Thinking some more, I think having a definition for Defined x (expanding to x S.≈ x) might make the overall definition more perspicuous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So...
Carrier(capitalised) is the carrier type; did you envisagecarrier(lower-case) for the name of its inhabitant?
I was motivated by my proposal under Substructures and quotients in theAlgebra.*hierarchy #1899 to have a standardised name which then becomes the underlying function of the homo-/mono-morphism injectingCarrierintoS.Carrier... but part of my thinking was also that the record itself doesn't merit an 'interesting' name... because it should only be exposed through itsSetoidAPI, when it would moreover, again receive the nameCarrier... (and be renamed, presumably, at any client use-site, if needed)- adding
Definedsounds a good suggestion forRelation.Binary.Definitions... DRY says we should then redefineReflexivein terms of it?
On naming, I think I was struck looking back over #2071 that the carrier type of the symmetric interior is given an 'interesting'/'informative' name, when in fact that's another case (I now think), where the record type is a concrete implementation detail which should only really be accessed/accessible via the API for the Construct being defined... esp. given that the module import path already cues the construction as that of the symmetric interior...
UPDATED: I've gone back over that last paragraph, and it doesn't any longer make sense!? Sorry for the noise!
Let me retry :
#2071 defines a construction on binary relations, not on types, whereas Carrier constructs a type towards building a Setoid, so it's not obvious that it belongs under Construct?
The operating construct on binary relations involved here is simply _on_, but I'd hesitate before putting the derived constructions as Properties of Relation.Binary.Construct.On...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
D'oh!?
I've ended up defining
subset = equaliser of kernel pair
for a/the special case of the 'inclusion'...
So it is probably better to refactor this as
kernel pair of arbitrary function (Fam again!?), and then specialise that at id?
Or: take a breath and sit on my hands for a bit...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good realization - I certainly had not spotted that. Perhaps sitting is indeed wise.
|
UPDATED:
We can discuss where this might go, if and when, ... later. |
| ------------------------------------------------------------------------ | ||
| -- Definitions | ||
|
|
||
| record Carrier : Set (a ⊔ i ⊔ ℓ) where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not happy with this record being called Carrier and its 'carrier' field being called h. To me, Carrier will always mean the underlying type of something Setoid-based. So re-using that name confounds expectations.
It feels like Carrier is instead some kind of Index-type with a distinguished point h.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not happy with this record being called
Carrierand its 'carrier' field being calledh. To me,Carrierwill always mean the underlying type of somethingSetoid-based. So re-using that name confounds expectations.
@JacquesCarette I'm reluctant to antagonise the collective wisdom of McMaster any more than I already seem to be doing over order-theoretic concepts, so I'll try to restate my position FTR, and then happily let others decide what becomes of this:
- one of the end products of this PR is precisely to establish
Carrier(therecordtype) as theCarrier(field value) of "somethingSetoidbased", namely the bundle defining the 'subset on whichfandgequalise' - it's clear you don't like the pun; fair enough, but I would never expect this type to be explicitly exported, except through the
Setoidinterface (cf. [DRY] what's the best way topublicly re-export properties/structure? #2391 ); I guess I could make itprivate, to improve matters? Alternatively, it could indeed be renamed, but as I say, I regard it as an abstract data type, existing solely to be a choice of domain for theisRelMonomorphismdefinition... viz. as a way of speaking about 'the subset on whichfandgequalise' - it's conventional, given
f, andgdefining some diagram (here: a parallel pair with domainI, as per the 'sub-thing as given by a map on indices' construction, to haveh, or perhaps better here,k(forKernel, except that old-timey category theory books tend to usehfor the universal equalising map, andkfor the corresponding coequalising map in a coequaliser diagram) define the (appropriate) unique mediating morphism (I won't debate uniqueness or otherwise here, given higher-minded, and higher-dimensional, sensitivities about 'uniqueness up to what?'); given the way thatfieldname become projection functions, that, again precisely, establishesh, or whatever we end up calling it, as a function of typeCarrier → I, and again, conventionally, in such a way as to fit the diagram of parallel arrowsf,g... - I've proposed/queried elsewhere the use of a standardised idiom for describing the eventual map
ι : Carrier → S.Carrier, as, again precisely, corresponding to 'the injection intoSof the subset on whichfandgequalise', but again, the actual name seems really neither here nor there, but for the fact that, again from thepublicexports,his never again mentioned (so its name is similarly immaterial/abstract)
I'd be quite happy to say 'puns considered harmful', and rename everything, but for the fact that these objects/constructions giving rise to the (intended for public export) definitions
_≈_isEquivalencesetoidisRelMonomorphism
do all need to be named. Perhaps it was failure of imagination on my part not to be able to come up with better ones, but in the end, I thought, it turns out mistakenly, that the ones I chose, for the reasons above, made the best 'fit'.
HTH!
It feels like
Carrieris instead some kind ofIndex-type with a distinguished pointh.
See above: h defines, as a projection, a function from Carrier to I.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making it private would go part of the way, for sure. Some puns I like, but somehow not this one.
The argument "establishing this as the Carrier of ..." doesn't go very far, as it could be extended to so many more things.
Have you considered Equalizer as the name? EqualAt, if we want a less fancy name?
This tackles one version of how to develop 'subsetoid's via PERs. Cf. #2814
Not necessarily the 'right' way to go, but still functionality which may be useful in the future
UPDATED: to live under
Relation.Binary.Construct