Slightly rewording the documentation of Theorem, Definition and Fixpoint - #19766
Slightly rewording the documentation of Theorem, Definition and Fixpoint#19766herbelin wants to merge 2 commits into
Conversation
jfehrle
left a comment
There was a problem hiding this comment.
Wording suggestions.
I hope you can make this more succinct as I suggest. I may well have gotten some of the details wrong--please ignore/adapt those parts.
| On its side, a theorem is a statement with a proof. One can view | ||
| the name of a theorem as a way to abbreviate the given proof, in the | ||
| same way as the name of a definition abbreviates a term. That is, in | ||
| the case of definitions (and related forms such as :cmd:`Fixpoint` or | ||
| :cmd:`CoFixpoint`), the term is the body of the definition and the | ||
| type is the type of the body. In the case of a theorem, lemma, | ||
| corollary, etc. the term is the proof and the type is the statement. |
There was a problem hiding this comment.
| On its side, a theorem is a statement with a proof. One can view | |
| the name of a theorem as a way to abbreviate the given proof, in the | |
| same way as the name of a definition abbreviates a term. That is, in | |
| the case of definitions (and related forms such as :cmd:`Fixpoint` or | |
| :cmd:`CoFixpoint`), the term is the body of the definition and the | |
| type is the type of the body. In the case of a theorem, lemma, | |
| corollary, etc. the term is the proof and the type is the statement. | |
| A theorem is a statement with a proof. The statement of the theorem | |
| is a type. The proof derives a term that has that type. References to the | |
| theorem may use its term or type, depending on the context. |
IMO this should clearly and succinctly state what a theorem is.
There was a problem hiding this comment.
What do you mean by "References to the theorem may use its term or type, depending on the context."? Otherwise ok.
I think it is also worth to insist somewhere that Definition and Theorem are just two different views at the same kind of syntactic object.
There was a problem hiding this comment.
What do you mean by "References to the theorem may use its term or type, depending on the context."? Otherwise ok.
What I meant was if you apply the theorem, the type of the theorem is used. Print theorem will show both. Maybe my thinking is still fuzzy, feel free to drop the sentence.
I think it is also worth to insist somewhere that Definition and Theorem are just two different views at the same kind of syntactic object.
Yes, a good point. I tend to forget the case where the user has to provide a proof for the Definition.
There was a problem hiding this comment.
I hope you'll at least use the first three sentences I suggest here. IMO short and sweet.
There was a problem hiding this comment.
What I meant was if you
applythe theorem, the type of the theorem is used.
The proof also is also used, in some sense. If your theorem is, say, {x : nat & x > 1} and you use this statement to eventually compute an actual nat bigger than 1, this nat is found in the proof that you applied (and it can be 2, or 3, etc. depending on the proof you give).
Maybe my thinking is still fuzzy, feel free to drop the sentence.
I would say that it is the standard usage which is ambiguous. Syntactically, there is no difference between a proof of some statement and a term of some type, that is when you apply a theorem, what you syntactically do is to apply the proof. However, in the case of a pair proof/statement, the focus is on the statement and we usually intend that the exact proof does not matter (and thus use Qed to enforce that), while in the case of a pair term/type, the focus is on the term and the type is intended to be an auxiliary re-derivable information. (Don't know if this explanaton helps.)
There was a problem hiding this comment.
Syntactically, there is no difference between a proof of some statement and a term of some type, that is when you apply a theorem, what you syntactically do is to apply the proof.
When you apply a theorem, the theorem name is inserted into the proof term of Show Proof. I expect Qed doesn't later recheck the referenced theorem--right?
|
|
||
| Moreover, definitions can be local (defined with :g:`let`) or global | ||
| (defined at top-level). |
There was a problem hiding this comment.
| Moreover, definitions can be local (defined with :g:`let`) or global | |
| (defined at top-level). |
Moved this text to the first paragraph
| In its most basic form :g:`Definition @ident := term`, the command | ||
| binds :n:`@term` to the name :n:`@ident` in the global environment, | ||
| provided that :n:`@term` is well-typed. | ||
|
|
||
| The form :n:`Definition @ident : @type := @term` checks that the type of :n:`@term` | ||
| is definitionally equal to :n:`@type`, and registers :n:`@ident` as being of type | ||
| :n:`@type`, and bound to value :n:`@term`. | ||
|
|
||
| The form :n:`Definition @ident {* @binder } : @type := @term` is equivalent to | ||
| :n:`Definition @ident : forall {* @binder }, @type := fun {* @binder } => @term` | ||
| (and similarly when one of `@term` or `@type` is omitted). | ||
|
|
There was a problem hiding this comment.
| In its most basic form :g:`Definition @ident := term`, the command | |
| binds :n:`@term` to the name :n:`@ident` in the global environment, | |
| provided that :n:`@term` is well-typed. | |
| The form :n:`Definition @ident : @type := @term` checks that the type of :n:`@term` | |
| is definitionally equal to :n:`@type`, and registers :n:`@ident` as being of type | |
| :n:`@type`, and bound to value :n:`@term`. | |
| The form :n:`Definition @ident {* @binder } : @type := @term` is equivalent to | |
| :n:`Definition @ident : forall {* @binder }, @type := fun {* @binder } => @term` | |
| (and similarly when one of `@term` or `@type` is omitted). | |
| The command | |
| binds :n:`@term` to the name :n:`@ident` in the global environment, | |
| provided that :n:`@term` is well-typed. | |
| If :n:`@type` is specified, the command checks that the type of :n:`@term` | |
| is definitionally equal to :n:`@type`. | |
| If @binder is specified, the definition is equivalent to | |
| :n:`Definition @ident : forall {* @binder }, @type := fun {* @binder } => @term` | |
| (and similarly when one of `@term` or `@type` is omitted). | |
We prefer describing the behavior of each bit of the syntax separately rather than listing multiple similar forms. It's easier for readers, who don't have to read a lot of very similar text and mentally do a diff to figure out what each bit of the syntax does.
"and registers :n:@ident as being of type :n:@type, and bound to value :n:@term" -- what is this registration? Seems like implementation detail that the user probably doesn't need to know about.
There was a problem hiding this comment.
We prefer describing the behavior of each bit of the syntax separately rather than listing multiple similar forms.
My bad, I anticipated too much. In #19301, Definition will take a with clause and we will have to take into account that there are potentially several ident/term pairs in a same Definition.
In the meantime, I reverted this part.
| In its most basic form :g:`@thm_token @ident : @type`, the command | ||
| interprets :n:`@type` as a statement and waits for a | ||
| proof. Once a proof is given and validated, a theorem bound to | ||
| :n:`@ident` and stating :n:`@type` is added to the global | ||
| environment. | ||
|
|
||
| These commands accept the :attr:`program` attribute. See :ref:`program_lemma`. | ||
| The form :n:`@thm_token @ident {* @binder } : @type := @term` is | ||
| equivalent to :n:`@thm_token @ident : forall {* @binder }, @type` | ||
| and the proof starts in the context :n:`{* @binder }`. | ||
|
|
||
| Forms using the :n:`with` clause are useful for theorems that are proved by simultaneous induction | ||
| over a mutually inductive assumption, or that assert mutually dependent | ||
| statements in some mutual coinductive type. It is equivalent to | ||
| over a mutually inductive assumption, or that assert mutually dependent coinductive | ||
| statements. It is equivalent to |
There was a problem hiding this comment.
As in the description of Definition, can we describe each syntactic item separately rather than listing multiple similar forms?
There was a problem hiding this comment.
I thought that the simpler form was easier to understand than the general uncommon form, but I'm ok to consider the general form from the very beginning.
| constraints on a special argument called the decreasing argument. This | ||
| is needed to ensure that the :cmd:`Fixpoint` definition always terminates. |
There was a problem hiding this comment.
Shouldn't this remain plural to match "constraints"?
There was a problem hiding this comment.
OK, so let's put constraints singular.
| :cmd:`Fixpoint` without the :attr:`program` attribute does not support the | ||
| :n:`wf` or :n:`measure` clauses of :n:`@fixannot`. See :ref:`program_fixpoint`. |
There was a problem hiding this comment.
This seems like useful info--did you intend to drop it?
There was a problem hiding this comment.
It is moved in the attribute paragraph.
| only through their fully qualified names rather than their | ||
| unqualified names after an :cmd:`Import`. | ||
| unqualified names, even after an :cmd:`Import`. |
There was a problem hiding this comment.
"rather than their unqualified names" seems like overkill if the previous clause says "only through their unqualified names"
…int. Also adding some missing supported attributes.
10d1810 to
9584899
Compare
herbelin
left a comment
There was a problem hiding this comment.
Thanks for the review. I pushed a new version.
Besides the new changes, hoping I don't forget anything, the pending open questions are:
- To what a theorem name refers?
- How to explain the similarity between Definitions and Theorems?
| On its side, a theorem is a statement with a proof. One can view | ||
| the name of a theorem as a way to abbreviate the given proof, in the | ||
| same way as the name of a definition abbreviates a term. That is, in | ||
| the case of definitions (and related forms such as :cmd:`Fixpoint` or | ||
| :cmd:`CoFixpoint`), the term is the body of the definition and the | ||
| type is the type of the body. In the case of a theorem, lemma, | ||
| corollary, etc. the term is the proof and the type is the statement. |
There was a problem hiding this comment.
What do you mean by "References to the theorem may use its term or type, depending on the context."? Otherwise ok.
I think it is also worth to insist somewhere that Definition and Theorem are just two different views at the same kind of syntactic object.
|
|
||
| Moreover, definitions can be local (defined with :g:`let`) or global | ||
| (defined at top-level). |
| In its most basic form :g:`Definition @ident := term`, the command | ||
| binds :n:`@term` to the name :n:`@ident` in the global environment, | ||
| provided that :n:`@term` is well-typed. | ||
|
|
||
| The form :n:`Definition @ident : @type := @term` checks that the type of :n:`@term` | ||
| is definitionally equal to :n:`@type`, and registers :n:`@ident` as being of type | ||
| :n:`@type`, and bound to value :n:`@term`. | ||
|
|
||
| The form :n:`Definition @ident {* @binder } : @type := @term` is equivalent to | ||
| :n:`Definition @ident : forall {* @binder }, @type := fun {* @binder } => @term` | ||
| (and similarly when one of `@term` or `@type` is omitted). | ||
|
|
There was a problem hiding this comment.
We prefer describing the behavior of each bit of the syntax separately rather than listing multiple similar forms.
My bad, I anticipated too much. In #19301, Definition will take a with clause and we will have to take into account that there are potentially several ident/term pairs in a same Definition.
In the meantime, I reverted this part.
| constraints on a special argument called the decreasing argument. This | ||
| is needed to ensure that the :cmd:`Fixpoint` definition always terminates. |
There was a problem hiding this comment.
OK, so let's put constraints singular.
| :cmd:`Fixpoint` without the :attr:`program` attribute does not support the | ||
| :n:`wf` or :n:`measure` clauses of :n:`@fixannot`. See :ref:`program_fixpoint`. |
There was a problem hiding this comment.
It is moved in the attribute paragraph.
| only through their fully qualified names rather than their | ||
| unqualified names after an :cmd:`Import`. | ||
| unqualified names, even after an :cmd:`Import`. |
|
|
||
| This command accepts the :attr:`bypass_check(universes)`, | ||
| :attr:`bypass_check(guard)`, :attr:`deprecated`, :attr:`warn`, and :attr:`using` attributes. | ||
| The command supports the :attr:`local`, :attr:`universes(polymorphic)`, |
There was a problem hiding this comment.
I proposed a solution which does not use the word "command".
9584899 to
697d347
Compare
|
|
||
| Definitions associate a specified term with a given name. The name can later | ||
| be replaced with its definition through :term:`δ-reduction <delta-reduction>`. |
There was a problem hiding this comment.
| Definitions associate a specified term with a given name. The name can later | |
| be replaced with its definition through :term:`δ-reduction <delta-reduction>`. | |
| Definitions and theorems are used to define terms that have a specific type. | |
| Definitions most commonly associate a specified term with a given name. | |
| Alternatively, the type may be specified instead of the term, in which case, a proof | |
| must be provided to derive the term just as for theorems. The name can later | |
| be replaced with its definition through :term:`δ-reduction <delta-reduction>`. |
The first sentence suggests they are similar. Details of their differences should go later
where Definition syntax is given (e.g. opacity and that specifying both term and type
will verify that they match). N'est-ce pas?
| On its side, a theorem is a statement with a proof. One can view | ||
| the name of a theorem as a way to abbreviate the given proof, in the | ||
| same way as the name of a definition abbreviates a term. That is, in | ||
| the case of definitions (and related forms such as :cmd:`Fixpoint` or | ||
| :cmd:`CoFixpoint`), the term is the body of the definition and the | ||
| type is the type of the body. In the case of a theorem, lemma, | ||
| corollary, etc. the term is the proof and the type is the statement. |
There was a problem hiding this comment.
I hope you'll at least use the first three sentences I suggest here. IMO short and sweet.
| which makes the defined :n:`@ident` accessible only through their fully | ||
| qualified names, even if :cmd:`Import` or its variants has been used on the | ||
| current :cmd:`Module`. | ||
| This binds :n:`@term` to the name :n:`@ident` in the global environment, |
There was a problem hiding this comment.
| This binds :n:`@term` to the name :n:`@ident` in the global environment, | |
| Binds :n:`@term` to the name :n:`@ident` in the global environment, |
| If :n:`@binder` is specified, it distributes over :n:`@term` and :n:`@type` as if they had | ||
| respectively been :n:`fun {* @binder } => @term` and :n:`forall {* @binder }, @type`. |
There was a problem hiding this comment.
| If :n:`@binder` is specified, it distributes over :n:`@term` and :n:`@type` as if they had | |
| respectively been :n:`fun {* @binder } => @term` and :n:`forall {* @binder }, @type`. | |
| If :n:`@binder` is specified, :n:`@term` and :n:`@type` are treated as if they had | |
| respectively been given as :n:`fun {* @binder } => @term` and :n:`forall {* @binder }, @type`. |
"distributes" suggest to me a reference to a distributive property, which IINM is not the case--it just has its everyday meaning.
| If :n:`@binder` is specified, this behaves as if :n:`@type` had been | ||
| :n:`forall {* @binder }, @type` and the proof starts in the context :n:`{* @binder }`. |
There was a problem hiding this comment.
| If :n:`@binder` is specified, this behaves as if :n:`@type` had been | |
| :n:`forall {* @binder }, @type` and the proof starts in the context :n:`{* @binder }`. | |
| If :n:`@binder` is specified, :n:`@type` is used as | |
| :n:`forall {* @binder }, @type` and the proof starts in the context :n:`{* @binder }`. |
"behaves" is vague; better just to state the behavior
| The basic form :n:`Fixpoint @ident {* @binder} { struct @ident } : @type := @term. | ||
| declares :n:`@ident` to be the recursive function with arguments | ||
| :n:`{* @binder}` and body :n:`@term` of type :n:`type`. |
There was a problem hiding this comment.
| The basic form :n:`Fixpoint @ident {* @binder} { struct @ident } : @type := @term. | |
| declares :n:`@ident` to be the recursive function with arguments | |
| :n:`{* @binder}` and body :n:`@term` of type :n:`type`. | |
| The form :n:`Fixpoint @ident {* @binder} { struct @ident } : @type := @term. | |
| declares :n:`@ident` as a recursive function with arguments | |
| :n:`{* @binder}` and body :n:`@term` of type :n:`type`. |
| The :n:`{struct @ident}` annotation may be left implicit, in which case | ||
| Rocq successively tries arguments from left to right until it finds one | ||
| that satisfies the decreasing condition. |
There was a problem hiding this comment.
And fails if none of the arguments satisfy the condition.
| If :n:`@decl_notation` is present, a notation is defined at the same time | ||
| (see :ref:`simultaneous-definition-and-notation`). |
There was a problem hiding this comment.
I don't understand why defining a notation is useful enough to be included in Fixpoint syntax. IINM is could also be done with a separate command. Perhaps a very short example would help.
|
The "needs: rebase" label was set more than 30 days ago. If the PR is not rebased in 30 days, it will be automatically closed. |
|
This PR was not rebased after 30 days despite the warning, it is now closed. |
This PR is preparing the changes of documentation in #19029 and #19301, to split general concerns from specific concerns and so that either of the two PR can be merged independently.