Zulip Chat Archive

Stream: lean4

Topic: implemented_by and rec


Joachim Breitner (Oct 10 2023 at 19:53):

I was playing around a bit with implemented_by, to see if I can completely swap out the representation of a type (like with Array and List), but staying within lean (so not extern + C code).
But it seems that my attribute [implemented_by RArray.rec_unsafe] RArray.rec which swaps out the implementation of the recursor did not affect how a pattern matching is compiled. Are pattern matches not compiled via the types recursers, or where else did my thinking go wrong?

Joachim Breitner (Oct 10 2023 at 20:03):

Ah, I also have to override casesOn!

attribute [implemented_by RArray.casesOn_unsafe] RArray.casesOn

Joachim Breitner (Oct 10 2023 at 20:19):

So here is my attempt at defining a data type that looks like an inductive Snoc list (nice for proofs, nice for functional programming with pattern matching) but its implementation is backed by Array, and allows fast conversion to and from Array (hardly tested, though):

Of course, it’s quite scary how much unsafe there is in the code. I wonder if there could be a more principled approach to such data type refinements. Maybe what I am looking for is data type refinement like in Isabelle. Is that possible, or on the horizon?

David Thrane Christiansen (Oct 10 2023 at 20:27):

I've been thinking for some time that it might be useful to have first-class support for alternative recursors, a la Epigram. For instance, Lean's representation of Fin is non-bizarre - it's a Nat at runtime - but programming with it is manifestly less convenient than the inductive version. It would be great to be able to prove the inductive version's induction principle, and then use it with ordinary match expressions, whether by some kind of using modifier or by having Lean select the appropriate induction principle from the set of patterns employed.

This could be a nice hack for backwards compatibility too.

Joachim Breitner (Oct 10 2023 at 20:28):

That also sounds nice – then we could simply have a “snoc-view on Arrays” recursor directly, no separate type needed.

Joachim Breitner (Oct 10 2023 at 21:00):

How hard would alternative recursers be? The equation compiler would have to know which “constructors” belong to which recursor, at least in the simple case where each recursor has its own set of constructors used in patterns. Are other components involved?

David Thrane Christiansen (Oct 11 2023 at 07:46):

Not that I know of, but I'm not the one to ask

Jun Yoshida (Oct 11 2023 at 07:50):

I found a mysterious attribute recursor in the core. Although nothing uses it currently, was it created for this purpose?

David Thrane Christiansen (Oct 11 2023 at 07:50):

I'd expect a nice API to be something like:

def Fin.zero : Fin (n + 1) := ...
def Fin .succ : Fin n -> Fin (n + 1) := ...
def Fin.someOtherEliminator : {p : (n : Nat) -> Fin n -> Type u} -> ((n : Nat) -> p (n + 1) fzero) -> ...
register_matcher Fin.somOtherEliminator for Fin.zero, Fin.succ

where it would then create the corresponding casesOn and noConfusion stuff.

Eric Wieser (Oct 11 2023 at 09:18):

@Jun Yoshida: I think that attribute is used to override the recursion principle for induction and/or cases, but it doesn't work for match

Jun Yoshida (Oct 11 2023 at 10:00):

@Eric Wieser Regarding the current lean4, Std, and Mathlib repositories, I don't think any other functions use recursorAttribute, so it is not even an alternative of eliminator attribute; i.e. neither induction nor cases care recursor attribute.


Last updated: Dec 20 2023 at 11:08 UTC