-
Notifications
You must be signed in to change notification settings - Fork 5
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
Setoid instances #10
base: main
Are you sure you want to change the base?
Setoid instances #10
Conversation
Thanks, Jakub! I think we will need this category. |
Great. Perhaps this constraint was needed at one time and then no longer. |
:D ! |
Where was this functionality in the pre-2.0 agda-stdlib? |
I think it was Function.Equality.⇨. |
does that mean my explanation is incomprehensible? I don't know what you mean by that smiley |
51b19fc
to
d2e0e75
Compare
Thank you! That's the definition I was trying to remember. Do you have any idea why it was removed? |
I was trying to look up the relevant agda-categories commit history in hopes to figure out more. I know nothing for sure but my guess it was just forgotten. Note that Jacques already opened this as an stdlib PR with |
I meant I liked what you did. |
There are a lot of opportunities to use standard categorical operations here. Did you consider doing so? |
Not really, it was mostly mechanistic translation from Function instances. I do however think that might be the case to cracking What did occur to me after this is that |
4d5381f
to
6f2619f
Compare
I've tried this exercise and it blew my mind ;) see, comments attached to a related commit: 78e655a |
Terrific! It sounds like you’re having the experience I hoped you would. Start with poetic rephrasings, see what new hints appear, and follow where the beauty seems to lead. |
For properties to transfer, equivalence on the homomorphism’s source must be defined as equivalence of homomorphic images. When the homomorphism maps representations to their meanings, this definition of equivalence is necessary (I think) for non-leaky abstraction. What notion or notions of morphism equivalence make sense in a Setoid category? |
From commit 78e655a:
I’m glad that you found this surprise yourself and that you enjoy the gift! I’ve stumbled onto such homomorphic gems often enough that I now know to dig for them. Finding them in logic/proofs is even more satisfying than in implementations, further rewarding the switch from Haskell to Agda. |
IIUC that is exactly the case for equivalence in category of setoids: |
If we want equational properties (laws etc) to transfer backward through An alternative is to use a homomorphism going the other way: specify the function category (“Set”) via a homomorphism to the setoid category rather than vice versa. |
b3a92c6
to
79b4672
Compare
79b4672
to
b347c48
Compare
Forgot to add this one previously. It's not included in the `Felix.Instances.Function` as the rest of the Function directory.
381c3fb
to
445490e
Compare
src/Felix/Instances/Setoid/Raw.agda
Outdated
distributive = record | ||
{ distribˡ⁻¹ = record | ||
{ to = λ (a , bc) → [ inj₁ ∘ᵈ (a ,_) , inj₂ ∘ᵈ (a ,_) ] bc | ||
; cong = λ where | ||
(a₁≈a₂ , inj₁ b₁≈b₂) → inj₁ (a₁≈a₂ , b₁≈b₂) | ||
(a₁≈a₂ , inj₂ c₁≈c₂) → inj₂ (a₁≈a₂ , c₁≈c₂) | ||
} | ||
; distribʳ⁻¹ = record | ||
{ to = λ (bc , a) → [ inj₁ ∘ᵈ (_, a) , inj₂ ∘ᵈ (_, a) ] bc | ||
; cong = λ where | ||
(inj₁ b₁≈b₂ , a₁≈a₂) → inj₁ (b₁≈b₂ , a₁≈a₂) | ||
(inj₂ c₁≈c₂ , a₁≈a₂) → inj₂ (c₁≈c₂ , a₁≈a₂) | ||
} | ||
} |
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.
How tidy could these definitions become if rewritten via the categorical vocabulary?
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.
oh, I took me way too long to notice, still can't replace cong
one as I can't guide Agda to pick proper instances, which I myself don't know in full details. I was hoping agda would figure it out. All I see is the pattern for distribl/r
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.
Ok, the issue here is that constructors (inj₁
/inj₂
) used at cong
are coming from Pointwise
and we don't have any category instance that would use this as coproducts*. I've tried using map
from that module but I have trouble convincing Agda is complaining about stuff that I don't know how to solve.
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.
Ok, the issue here is that constructors (
inj₁
/inj₂
) used atcong
are coming fromPointwise
[...]
I don't know, and I like this question a lot! If we come up with a good answer, this whole Setoid category might come out beautifully.
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.
Note that categorical products and coproducts in Rels
are necessarily (isomorphic to) sum types.
distributive = record | ||
{ distribˡ∘distribˡ⁻¹ = λ where | ||
{A} {B} {C} (_ , inj₁ _) → Setoid.refl (A ×ₛ (B ⊎ₛ C)) | ||
{A} {B} {C} (_ , inj₂ _) → Setoid.refl (A ×ₛ (B ⊎ₛ C)) | ||
; distribˡ⁻¹∘distribˡ = λ where | ||
{A} {B} {C} (inj₁ _) → Setoid.refl ((A ×ₛ B) ⊎ₛ (A ×ₛ C)) | ||
{A} {B} {C} (inj₂ _) → Setoid.refl ((A ×ₛ B) ⊎ₛ (A ×ₛ C)) | ||
; distribʳ∘distribʳ⁻¹ = λ where | ||
{A} {B} {C} (inj₁ _ , _) → Setoid.refl ((B ⊎ₛ C) ×ₛ A) | ||
{A} {B} {C} (inj₂ _ , _) → Setoid.refl ((B ⊎ₛ C) ×ₛ A) | ||
; distribʳ⁻¹∘distribʳ = λ where | ||
{A} {B} {C} (inj₁ _) → Setoid.refl ((B ×ₛ A) ⊎ₛ (C ×ₛ A)) | ||
{A} {B} {C} (inj₂ _) → Setoid.refl ((B ×ₛ A) ⊎ₛ (C ×ₛ A)) | ||
} |
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.
How pretty could these proofs look if expressed via categorical vocabulary?
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.
basically variation of the (Setoid.refl ▿ Setoid.refl) ∘ exr
but the level inference for proper categorical instances are killing me
src/Felix/Instances/Setoid/Type.agda
Outdated
coproducts = record | ||
{ ⊥ = record | ||
{ Carrier = ⊥′ | ||
; _≈_ = λ _ _ → ⊤′ |
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.
This one feels a little off to me. How about you?
Following discussion we had last week I've started to define those instances and it occurred to me that they would make nice addition to the base library. I've removed requirement for `Products (Set q)` instance from lawful `CartesianClosed`. It seems it wasn't used anywhere and I didn't know what that would be here. Provided instances quantify `Level`s individually as they're different for different typeclasses. Quantifiyng that at the module level would mean that we wouldn't be able to substitute it differently. For example: `Products` can use `Setoid c ℓ` as `obj`. But `Exponentials` require that `obj` is `Setoid (c ⊔ ℓ) (c ⊔ ℓ)`, which in turns requires `Products` for the same `obj`. Fixing `c` and `ℓ` at the module would prohibit `Exponentials` to get required `Products`. One module (`Function.Construct.Setoid`) was copied from agda-categories, and there it was copied from old standard library, as it got removed from the 2.0 version.
Actually I don't use that much _categorical operators_, as I couldn't get proper categorical instances to work. That is, Setoid categorical laws are functions in the category of (Agda) function and types. However I couldn't figure out the Level of Set that I should set to `Felix.Instance.Function` in order to use those operators in laws definitions. So I settled for next best thing and used standard library provided functions. And oh boy, did I got surprised by the results. Taking for example the `▵≈` law from the `Cartesian`. It holds by `<_,_>` (which is the definition of _▵_ in category of functions and types)! This has completely stunned me. Law for the categorical operator holds by the definition of this operator in different category! I find it amazing! The same holds for `curry` in the `CartesianClosed`, *but* I couldn't figure it out for `∘≈` in the `Category`. I wonder why? I wonder if this has something to do with the fact that there is trivial homomorphism from the category of `Setoid`s to category of function and types via `⟦_⟧ = Func.to`? In order to make `CartesianClosed` simplification to work I needed to make argument to `Setoid` of setoid functions explicit. Unfortunately in the upcoming PR it is implicit.
By using categorical operations I don't have to come up with `cong` proof manually. It will be composed instead. I don't know however if this definition is good one, so it'll be commented out for the time being.
445490e
to
6a0a811
Compare
Following discussion we had last week I've started to define those
instances and it occurred to me that they would make nice addition to
the base library.
I've removed requirement for
Products (Set q)
instance from lawfulCartesianClosed
. It seems it wasn't used anywhere and I didn't knowwhat that would be here.
Provided instances quantify
Level
s individually as they're differentfor different typeclasses. Quantifiyng that at the module level would
mean that we wouldn't be able to substitute it differently. For
example:
Products
can useSetoid c ℓ
asobj
. ButExponentials
require thatobj
isSetoid (c ⊔ ℓ) (c ⊔ ℓ)
, whichin turns requires
Products
for the sameobj
. Fixingc
andℓ
at the module would prohibit
Exponentials
to get requiredProducts
.One module (
Function.Construct.Setoid
) was copied fromagda-categories, and there it was copied from old standard library, as
it got removed from the 2.0 version.
Last commit is my attempt at defining
Traced
, but I can't quite get itwork. See the commit comment.