-
Notifications
You must be signed in to change notification settings - Fork 197
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
Using new syntax for typeclass instance declarations #2262
Conversation
Be aware that |
To do both, there is |
Regarding the boxed type classes, let's make those opaque to type class search, which is probably the original motivation. |
Thanks, I didn't realize the coercions were reversible, so these changes have more semantic consequences than I realized. Luckily there was only one breakage (in |
Our current lower bound is 8.19 so you should check that we aren't introducing many warnings. The Another comment would be to separate each kind of change so that we can better bisect the issue when there are future issues. Making the commits more atomic can help with review and future debugging pain. |
@Alizter That warning is still in place, so I just didn't use |
Changing the typeclasses to opaque didn't fix the breakage in |
I have determined that the breakage in If one writes This is a bit surprising to me because I'm not sure what the search could be doing. |
You can mark a |
Why do you think they chose to make reversible coercions the default for record projections? Do you think that is a sensible default for record projections? |
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.
It's great to get this cleaned up.
But again I have to point out that you combined many different things into one commit, which made it much harder to review than necessary. Any time you are doing a bunch of rote changes, any change that does not follow the pattern should be put in a separate commit. And if you are doing more than one kind of rote change, each kind should be in a separate commit. This makes it very easy for us to focus on the changes that are more important to review. In addition, as Ali pointed out, it allows us in the future to determine which kind of change broke something or caused a slow down.
So you should break this up into multiple commits. From memory, I can recall at least five categories of changes: ::
, :>
, unboxing Classes, changing Lemma + Existing Instance to Instance, and whitespace. There may have been one or two more changes that would also deserve their own commits. Oh, right, there is the new Class in the Categories library, and however that ends up being done should be in its own commit.
|
||
When we move to polyproj, it won't anymore. *) | ||
|
||
Existing Class is_structure_homomorphism. |
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 wasn't a class before, so this is a change to semantics. Presumably it has no instances, since it wasn't a class, so this should have no effect, but then it seems misleading to declare it a class.
It looks to me like the next part of this file is making a separate database to work around that issue preventing it from being made a class? If so, maybe the right thing to do for now is to not make this a class, but to change the comment to something like "It now works to make [is_structure_homomorphism] a class using [display the line], but taking advantage of that would require some other changes to the library." @JasonGross Is that a fair summary?
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 need to go back and look at this more carefully, I don't remember what istrunc_is_structure_homomorphism
was before the class declaration. I guess it would have been best to create an issue pointing out that this code now works in recent versions of Coq and ask how we can take advantage of this.
@@ -558,6 +558,6 @@ Section pseudo. | |||
- destruct (pseudo_order_antisym y z (ltyz , ltzy)). | |||
Qed. | |||
|
|||
Existing Instance lt_transitive. | |||
#[export] Existing Instance lt_transitive. |
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'll comment more generally on this, but this change should be in a separate commit.
@@ -358,13 +350,12 @@ rewrite <-(pos_unconjugate L e),<-Qpos_mult_assoc. | |||
apply (lipschitz f L),xi. | |||
Qed. | |||
|
|||
Lemma uniform_continuous@{} mu `{!Uniform@{UA UB} f mu} : Continuous f. | |||
Instance uniform_continuous@{} mu `{!Uniform@{UA UB} f mu} : Continuous f | 5. |
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.
Is this missing an #[export]
like the previous result? Also, this is a different kind of change and should be in a different commit.
Definition diagram_sigma {G : Graph} {D : Diagram G} (E : DDiagram D) | ||
: Diagram G. | ||
Proof. | ||
srapply Build_Diagram. | ||
- intro i. | ||
exact {x : D i & E (i; x)}. | ||
- intros i j g x. simpl in *. | ||
exists (D _f g x.1). | ||
exact (@arr _ E (i; x.1) (j; D _f g x.1) (g; idpath) x.2). | ||
Defined. | ||
|
||
(** A dependent diagram is said equifibered if all its fibers are equivalences. *) | ||
|
||
Class Equifibered {G : Graph} {D : Diagram G} (E : DDiagram D) := { |
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.
Please don't mix whitespace changes in.
|
||
Existing Instance isequiv_Htpy_path. | ||
Typeclasses Opaque HasMorExt. |
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 generates a warning, but I can't see the full message in the diff view.
Existing Instance isequiv_cat_equiv_path. | ||
:= isequiv_cat_equiv_path :: forall a b, IsEquiv (@cat_equiv_path A _ _ _ _ _ a b). | ||
|
||
Typeclasses Opaque IsUnivalent1Cat. |
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.
Another warning.
Yes, that's fair. I apologize and I will redo the commit. When I am going through lots of small changes like this where I end up reading through hundreds of files, inevitably I see other some changes that I think would be a good idea. I don't want to forget about them and lose track of them so I put them into same commit so they don't get lost. I guess I should keep track of the changes a better way, I could create multiple small branches or create an issue with a checklist of the changes I want to make. I will do my best to keep the material more organized. |
I tend to just make the changes, but in the UI I use when creating a commit, I scan through the changes and select which ones to add to the commit. In this case, I would scan through for the ones that don't match the rote pattern and apply their to their own commit(s). After a few iterations, what's left is the bulk, which I can easily put into the main commit. By manually choosing what to put into each commit, I also would notice if I unintentionally changed whitespace or other things, and could revert those then. If some of the changes conflict, then this doesn't work so easily, so I would just make notes to come back to line XX of file YY later. |
Is this magit? I sometimes use magit but I forgot it has that ability to work with sub file sized chunks in git |
Yes, it's magit. I think just about any git UI will let you select which chunks to commit, but magit even lets you select regions within a chunk. |
In Coq 8.17, concise syntax was added to make a record projection into a typeclass instance, rather than writing "Existing Instance" after the record definition. This PR systematically replaces
Existing Instance proj1
withproj1 :: ClassType
throughout the library.I also replaced
Coercion proj1 : Record >-> FieldType
with the syntaxproj1 :> FieldType
where I noticed it.While going through the classes I found two classes with a single field. I replaced these classes with "unboxed" classes which do not define a record type, they are definitionally equivalent to their field. This reduces term size because you do not need a constructor, it also shortens the proofs because you don't need to
rapply constructor
.There was one breakage in
ClassifyingSpace.v
due to the coercionCoercion equiv_fun : Equiv >-> Funclass
being marked as reversible, but I'm not sure the mechanics of this infinite search during unification.At several points there is a comment saying
I didn't understand this comment, as AFAIK there is no way to declare a record field as an instance and as a coercion at once, one can use
:>
or::
but not both, one still needs to add a line declaring the field as aCoercion
orExisting Instance
.By the way, by default when you write
proj1 :: ClassType
, it declaresproj1
with the#[export]
attribute, but one can put other attributes like#[global]
or#[local]
directly inline in the record definition as well, also hint priorities can be written inline. The syntax is flexible.