Skip to content
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

[Merged by Bors] - feat: variable? command for automatically adding typeclass dependencies #3162

Closed
wants to merge 15 commits into from

Conversation

kmill
Copy link
Contributor

@kmill kmill commented Mar 29, 2023

The variable? command is like variable, but whenever there is an unsatisfied typeclass problem, it inserts this problem as a new instance argument and continues.

For example, if you write

variable? [Module R M]

then, assuming there are no other instances in scope, it's as if you wrote

variable [Semiring R] [AddCommMonoid M] [Module R M]

It will not include instances that can be deduced from others in scope.

It can handle parameterized instances:

variable? (f : α → Type) [(i : α) → Module R (f i)]

There are some inherent limitations with this system. The main one is that internally variables are stored as Syntax objects, so whenever variables? discovers a missing instance argument, it has to pretty print it. If pretty printing does not round trip (for instance due to implicit arguments) then the command might fail.

As a safeguard against changes in the typeclass hierarchy, the command suggests replacing itself with a version that includes the expanded binders list, for example

variable? [Module R M] =>
  [Semiring R] [AddCommMonoid M] [Module R M]

This expanded list is elaborated separately for a defeq check on the resulting contexts. If the short version is not wanted, one can always replace everything up to and including the => with variable.


Open in Gitpod

@kmill kmill added WIP Work in progress t-meta Tactics, attributes or user commands labels Mar 29, 2023
@kmill kmill added awaiting-review The author would like community review of the PR and removed WIP Work in progress labels May 25, 2023
@semorrison
Copy link
Contributor

We probably should have a discussion on zulip about whether it is acceptable to leave variable! in code. I hope/think the answer should be yes (it's easy to remove later if we change our mind, so we might as well try it out?), but if the answer is no we'd probably want to make ? the default mode.

@jcommelin
Copy link
Member

jcommelin commented Jun 2, 2023

Does it check whether [Semiring R] is already deducible in the current context?

Answer: yes

I figured out from the tests that this is happening. I think it would be good to add a sentence about this in the docstring.

@semorrison
Copy link
Contributor

I finally asked on zulip for opinions on leaving variable! in committed code.

test/Variable!.lean Outdated Show resolved Hide resolved
@eric-wieser
Copy link
Member

eric-wieser commented Jun 5, 2023

This seems to trick it:

variable!? (A : ℕ → Type) [∀ i : ℕ, Module R (A i)] [∀ i : ℕ, Algebra S (A i)]

giving

variable (A : ℕ → Type) [Semiring R] [(i : ℕ) → AddCommMonoid (A i)] [∀ i : ℕ, Module R (A i)]
  [CommSemiring S] [(i : ℕ) → Semiring (A i)] [∀ i : ℕ, Algebra S (A i)]

which has two different add operations on A i

@kmill kmill changed the title feat: variable! command for automatically adding typeclass dependencies feat: variable? command for automatically adding typeclass dependencies Jun 14, 2023
@kmill
Copy link
Contributor Author

kmill commented Jun 14, 2023

I've done some cleanup and switched it to be variable?, so it's situated more as an informational command.

@eric-wieser Your example also applies to

variable? [Module R A] [Algebra S A]

I'm not sure there's a good way to fix it since it processes variables left-to-right and it doesn't check that previous binders can be inferred from successive ones. I've at least left this in the test file.

@kmill
Copy link
Contributor Author

kmill commented Jun 15, 2023

Now the command suggests an expansion like variable? [Module R M] => [Semiring R] [AddCommMonoid M] [Module R M] to save the expanded form to help the reader and to improve maintainability.

@semorrison
Copy link
Contributor

Two suggestions about the documentation, otherwise let's try it out!

bors d+

@bors
Copy link

bors bot commented Jun 21, 2023

✌️ kmill can now approve this pull request. To approve and merge a pull request, simply reply with bors r+. More detailed instructions are available here.

@github-actions github-actions bot added delegated and removed awaiting-review The author would like community review of the PR labels Jun 21, 2023
@kmill
Copy link
Contributor Author

kmill commented Jun 21, 2023

bors r+

@github-actions github-actions bot added the ready-to-merge This PR has been sent to bors. label Jun 21, 2023
bors bot pushed a commit that referenced this pull request Jun 21, 2023
…cies (#3162)

The `variable?` command is like `variable`, but whenever there is an unsatisfied typeclass problem, it inserts this problem as a new instance argument and continues.

For example, if you write
```
variable? [Module R M]
```
then, assuming there are no other instances in scope, it's as if you wrote
```
variable [Semiring R] [AddCommMonoid M] [Module R M]
```
It will not include instances that can be deduced from others in scope.

It can handle parameterized instances:
```
variable? (f : α → Type) [(i : α) → Module R (f i)]
```

There are some inherent limitations with this system. The main one is that internally variables are stored as Syntax objects, so whenever `variables?` discovers a missing instance argument, it has to pretty print it. If pretty printing does not round trip (for instance due to implicit arguments) then the command might fail.

As a safeguard against changes in the typeclass hierarchy, the command suggests replacing itself with a version that includes the expanded binders list, for example
```
variable? [Module R M] =>
  [Semiring R] [AddCommMonoid M] [Module R M]
```
This expanded list is elaborated separately for a defeq check on the resulting contexts. If the short version is not wanted, one can always replace everything up to and including the `=>` with `variable`.
@bors
Copy link

bors bot commented Jun 21, 2023

Pull request successfully merged into master.

Build succeeded!

The publicly hosted instance of bors-ng is deprecated and will go away soon.

If you want to self-host your own instance, instructions are here.
For more help, visit the forum.

If you want to switch to GitHub's built-in merge queue, visit their help page.

@bors bors bot changed the title feat: variable? command for automatically adding typeclass dependencies [Merged by Bors] - feat: variable? command for automatically adding typeclass dependencies Jun 21, 2023
@bors bors bot closed this Jun 21, 2023
@bors bors bot deleted the kmill_variable branch June 21, 2023 19:45
alexkeizer pushed a commit that referenced this pull request Jun 22, 2023
…cies (#3162)

The `variable?` command is like `variable`, but whenever there is an unsatisfied typeclass problem, it inserts this problem as a new instance argument and continues.

For example, if you write
```
variable? [Module R M]
```
then, assuming there are no other instances in scope, it's as if you wrote
```
variable [Semiring R] [AddCommMonoid M] [Module R M]
```
It will not include instances that can be deduced from others in scope.

It can handle parameterized instances:
```
variable? (f : α → Type) [(i : α) → Module R (f i)]
```

There are some inherent limitations with this system. The main one is that internally variables are stored as Syntax objects, so whenever `variables?` discovers a missing instance argument, it has to pretty print it. If pretty printing does not round trip (for instance due to implicit arguments) then the command might fail.

As a safeguard against changes in the typeclass hierarchy, the command suggests replacing itself with a version that includes the expanded binders list, for example
```
variable? [Module R M] =>
  [Semiring R] [AddCommMonoid M] [Module R M]
```
This expanded list is elaborated separately for a defeq check on the resulting contexts. If the short version is not wanted, one can always replace everything up to and including the `=>` with `variable`.
semorrison pushed a commit that referenced this pull request Jun 23, 2023
…cies (#3162)

The `variable?` command is like `variable`, but whenever there is an unsatisfied typeclass problem, it inserts this problem as a new instance argument and continues.

For example, if you write
```
variable? [Module R M]
```
then, assuming there are no other instances in scope, it's as if you wrote
```
variable [Semiring R] [AddCommMonoid M] [Module R M]
```
It will not include instances that can be deduced from others in scope.

It can handle parameterized instances:
```
variable? (f : α → Type) [(i : α) → Module R (f i)]
```

There are some inherent limitations with this system. The main one is that internally variables are stored as Syntax objects, so whenever `variables?` discovers a missing instance argument, it has to pretty print it. If pretty printing does not round trip (for instance due to implicit arguments) then the command might fail.

As a safeguard against changes in the typeclass hierarchy, the command suggests replacing itself with a version that includes the expanded binders list, for example
```
variable? [Module R M] =>
  [Semiring R] [AddCommMonoid M] [Module R M]
```
This expanded list is elaborated separately for a defeq check on the resulting contexts. If the short version is not wanted, one can always replace everything up to and including the `=>` with `variable`.
semorrison pushed a commit that referenced this pull request Jun 23, 2023
…cies (#3162)

The `variable?` command is like `variable`, but whenever there is an unsatisfied typeclass problem, it inserts this problem as a new instance argument and continues.

For example, if you write
```
variable? [Module R M]
```
then, assuming there are no other instances in scope, it's as if you wrote
```
variable [Semiring R] [AddCommMonoid M] [Module R M]
```
It will not include instances that can be deduced from others in scope.

It can handle parameterized instances:
```
variable? (f : α → Type) [(i : α) → Module R (f i)]
```

There are some inherent limitations with this system. The main one is that internally variables are stored as Syntax objects, so whenever `variables?` discovers a missing instance argument, it has to pretty print it. If pretty printing does not round trip (for instance due to implicit arguments) then the command might fail.

As a safeguard against changes in the typeclass hierarchy, the command suggests replacing itself with a version that includes the expanded binders list, for example
```
variable? [Module R M] =>
  [Semiring R] [AddCommMonoid M] [Module R M]
```
This expanded list is elaborated separately for a defeq check on the resulting contexts. If the short version is not wanted, one can always replace everything up to and including the `=>` with `variable`.
semorrison pushed a commit that referenced this pull request Jun 25, 2023
…cies (#3162)

The `variable?` command is like `variable`, but whenever there is an unsatisfied typeclass problem, it inserts this problem as a new instance argument and continues.

For example, if you write
```
variable? [Module R M]
```
then, assuming there are no other instances in scope, it's as if you wrote
```
variable [Semiring R] [AddCommMonoid M] [Module R M]
```
It will not include instances that can be deduced from others in scope.

It can handle parameterized instances:
```
variable? (f : α → Type) [(i : α) → Module R (f i)]
```

There are some inherent limitations with this system. The main one is that internally variables are stored as Syntax objects, so whenever `variables?` discovers a missing instance argument, it has to pretty print it. If pretty printing does not round trip (for instance due to implicit arguments) then the command might fail.

As a safeguard against changes in the typeclass hierarchy, the command suggests replacing itself with a version that includes the expanded binders list, for example
```
variable? [Module R M] =>
  [Semiring R] [AddCommMonoid M] [Module R M]
```
This expanded list is elaborated separately for a defeq check on the resulting contexts. If the short version is not wanted, one can always replace everything up to and including the `=>` with `variable`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
delegated ready-to-merge This PR has been sent to bors. t-meta Tactics, attributes or user commands
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants