Jesper Cockx
11 years ago
Dear Agda people,
While experimenting with reflection in Agda, I implemented a version of the
'rewrite' keyword as a tactic (i.e. a function Term -> Term). For example,
instead of using the build-in rewrite like this
test : (x y : â) â (x + y) + 0 â¡ y + (x + 0)
test x y
rewrite +-right-identity x
| +-right-identity (x + y)
| +-comm x y
= refl
you can use the rewrite' tactic like this:
testâ² : (x y : â) â (x + y) + 0 â¡ y + (x + 0)
testâ² x y =
tactic (rewriteâ² (quoteTerm (+-right-identity x)))
| tactic (rewriteâ² (quoteTerm (+-right-identity (x + y))))
| tactic (rewriteâ² (quoteTerm (+-comm x y)))
| refl
(Full code in the attachment.) The tactic version is somewhat more verbose,
but it has the big (IMO) advantage of not relying on any build-in
mechanics. In fact, test' normalizes to the following:
λ x y â
subst (λ z â x + y + 0 â¡ y + z) (sym (+-right-identity x))
(subst (λ z â z â¡ y + x) (sym (+-right-identity (x + y)))
(subst (λ z â z â¡ y + x) (sym (+-comm x y)) refl))
I think this is pretty sweet, so a big thank you to the people who've made
this possible. I also have some questions for you:
* Are there any other examples of tactics like this in Agda?
* Is there a library that provides basic reflection functions beyond
Reflection.agda in the standard library, for example for shifting and
substitution?
* Also, do you think that tactics are a good style of programming/proving
that we should promote in the future?
If the answer to the last question is 'yes', then here are some features
that I'd very much like to have in Agda (a way to look at the current
context, datatype reflection, ...), but maybe that's better left for a
discussion at AIM in two weeks.
Cheers,
Jesper Cockx
While experimenting with reflection in Agda, I implemented a version of the
'rewrite' keyword as a tactic (i.e. a function Term -> Term). For example,
instead of using the build-in rewrite like this
test : (x y : â) â (x + y) + 0 â¡ y + (x + 0)
test x y
rewrite +-right-identity x
| +-right-identity (x + y)
| +-comm x y
= refl
you can use the rewrite' tactic like this:
testâ² : (x y : â) â (x + y) + 0 â¡ y + (x + 0)
testâ² x y =
tactic (rewriteâ² (quoteTerm (+-right-identity x)))
| tactic (rewriteâ² (quoteTerm (+-right-identity (x + y))))
| tactic (rewriteâ² (quoteTerm (+-comm x y)))
| refl
(Full code in the attachment.) The tactic version is somewhat more verbose,
but it has the big (IMO) advantage of not relying on any build-in
mechanics. In fact, test' normalizes to the following:
λ x y â
subst (λ z â x + y + 0 â¡ y + z) (sym (+-right-identity x))
(subst (λ z â z â¡ y + x) (sym (+-right-identity (x + y)))
(subst (λ z â z â¡ y + x) (sym (+-comm x y)) refl))
I think this is pretty sweet, so a big thank you to the people who've made
this possible. I also have some questions for you:
* Are there any other examples of tactics like this in Agda?
* Is there a library that provides basic reflection functions beyond
Reflection.agda in the standard library, for example for shifting and
substitution?
* Also, do you think that tactics are a good style of programming/proving
that we should promote in the future?
If the answer to the last question is 'yes', then here are some features
that I'd very much like to have in Agda (a way to look at the current
context, datatype reflection, ...), but maybe that's better left for a
discussion at AIM in two weeks.
Cheers,
Jesper Cockx