Zulip Chat Archive

Stream: mathlib4

Topic: Data.Fintype.Vector mathlib4#1716


Johan Commelin (Jan 20 2023 at 13:33):

On

instance Vector.fintype [Fintype α] {n : } : Fintype (Vector α n) :=
  Fintype.ofEquiv _ (Equiv.vectorEquivFin _ _).symm

I get

IR check failed at 'Fintype.ofBijective._at.Vector.fintype._spec_2._rarg', error: unknown declaration 'Pi.fintype'

Johan Commelin (Jan 20 2023 at 13:33):

Making it noncomputable of course fixes the issue. But I imagine that's not what we want.

Johan Commelin (Jan 20 2023 at 13:33):

Pi.fintype definitely does exist, as #check confirms.

Johan Commelin (Jan 20 2023 at 13:37):

Aha. Pi.fintype is noncomputable!

Eric Wieser (Jan 20 2023 at 13:38):

docs#pi.fintype, docs4#Pi.fintype

Eric Wieser (Jan 20 2023 at 13:39):

It was computable in mathlib3

Eric Wieser (Jan 20 2023 at 13:39):

What changed?

Johan Commelin (Jan 20 2023 at 13:39):

The Lean version?

Ruben Van de Velde (Jan 20 2023 at 13:39):

I've regularly had lean4 claim things needed to be noncomputable when they weren't in lean3. I haven't looked into why

Eric Wieser (Jan 20 2023 at 13:42):

Ah, this is because docs4#Multiset.recOn is noncomputable

Eric Wieser (Jan 20 2023 at 13:42):

Like all other recursors

Eric Wieser (Jan 20 2023 at 13:43):

Perhaps the thing to do is to write a recOn' with pattern matching

Eric Wieser (Jan 20 2023 at 13:44):

Actually, this comes down to computability of docs4#Multiset.rec which in turn goes down to List.rec

Johan Commelin (Jan 20 2023 at 13:57):

All is fixed. Ready for review

Johan Commelin (Jan 20 2023 at 13:57):

Modulo removing the noncomputable once List.rec is fixed, of course.

Eric Wieser (Jan 20 2023 at 14:00):

I wonder why csimp doesn't work on List.rec...

Kyle Miller (Jan 20 2023 at 14:10):

@Eric Wieser I'm not sure, but in case you want to work on making these fintypes computable, here's a computable Multiset.rec:

def rec_aux (C_0 : C 0) (C_cons :  a m, C m  C (a :: m))
    (C_cons_heq :
       a a' m b, HEq (C_cons a (a' :: m) (C_cons a' m b)) (C_cons a' (a :: m) (C_cons a m b))) :
    (l : List α)  C (Quotient.mk (isSetoid α) l)
| [] => C_0
| a::l => C_cons a l (rec_aux C_0 C_cons C_cons_heq l)

theorem rec_aux_eq :
    rec_aux C_0 C_cons C_cons_heq = @List.rec α (fun l => C l) C_0 fun a l b => C_cons a l b :=
by
  ext l
  induction l with
  | nil => rfl
  | cons a l ih => simp [rec_aux, ih]

/-- Dependent recursor on multisets.
TODO: should be @[recursor 6], but then the definition of `Multiset.pi` fails with a stack
overflow in `whnf`.
-/
protected
def rec (C_0 : C 0) (C_cons :  a m, C m  C (a :: m))
    (C_cons_heq :
       a a' m b, HEq (C_cons a (a' :: m) (C_cons a' m b)) (C_cons a' (a :: m) (C_cons a m b)))
    (m : Multiset α) : C m :=
  Quotient.hrecOn m (rec_aux C_0 C_cons C_cons_heq) fun l l' h => by
    rw [rec_aux_eq]
    exact h.rec_heq
      (fun hl _  by congr 1; exact Quot.sound hl)
      (C_cons_heq _ _ _ _)

Eric Wieser (Jan 20 2023 at 14:11):

I'd argue it would be easier to just write a computable list.rec and swap that in everywhere; I think all the derived types end up comptuable automatically

Kyle Miller (Jan 20 2023 at 14:14):

I think using recursors for computation is "wrong" though, since Lean eagerly evaluates arguments. I'm pretty sure it's not that List.rec is noncomputable, but rather that the Lean compiler is by design pushing the user away from using it for computations.

Eric Wieser (Jan 20 2023 at 14:16):

#eval (List.rec 0 (fun x xs ih => 0) ([] : List Nat) : Nat)

gives (emphasis mine)

code generator does not support recursor 'List.rec' yet, consider using 'match ... with' and/or structural recursion

which suggests this is not by design but by it not being prioritized

Notification Bot (Jan 20 2023 at 14:28):

2 messages were moved from this topic to #lean4 > csimp on recursors by Eric Wieser.

Reid Barton (Jan 20 2023 at 14:50):

It's still arguably suboptimal to use List.rec because (as Kyle alluded to) you have to evaluate the empty list case even when the list is not empty

Reid Barton (Jan 20 2023 at 14:54):

Of course it doesn't matter if you only care about "does Lean complain about noncomputable"

Eric Wieser (Jan 20 2023 at 14:55):

mathlib4#1720 makes a very large number of things computable by adding those csimp lemmas

Eric Wieser (Jan 20 2023 at 14:55):

Reid Barton said:

It's still arguably suboptimal to use List.rec because (as Kyle alluded to) you have to evaluate the empty list case even when the list is not empty

I would guess that in almost all cases the empty list case is entirely trivial anyway, so evaluation costs very little

Reid Barton (Jan 20 2023 at 14:58):

It should also be noted (as usual) that this "computability" is not the same as being able to reduce things

Eric Wieser (Jan 20 2023 at 15:00):

Presumably both List.rec and Nat.rec already reduce correctly

Kevin Buzzard (Jan 20 2023 at 15:47):

On the other hand this "computability" will make porting easier, with fewer confusing errors.

Eric Wieser (Jan 20 2023 at 15:50):

Notably there are some Decidable instances that describe some algorithms on lists. It's pretty silly to say "oh, this algorithm is just as noncomputable as using choice would be".

Chris Hughes (Jan 20 2023 at 16:05):

https://github.com/leanprover-community/mathlib4/pull/1728

Chris Hughes (Jan 20 2023 at 16:06):

I made this on a fork because I wasn't planning on PRing it, but maybe I should PR from a branch of leanprover-community for CI

Chris Hughes (Jan 20 2023 at 16:16):

CI seems to have kicked in now so I'll leave it

Johan Commelin (Jan 20 2023 at 16:18):

@Chris Hughes Can you also fix Data.Fintype.Vector please?

Reid Barton (Jan 20 2023 at 16:18):

does Lean 4 still give an error when you mark something noncomputable that's computable?

Reid Barton (Jan 20 2023 at 16:19):

Eric Wieser said:

Notably there are some Decidable instances that describe some algorithms on lists. It's pretty silly to say "oh, this algorithm is just as noncomputable as using choice would be".

AFAIK we don't ever evaluate Decidable instances (that's not how dec_trivial works)

Johan Commelin (Jan 20 2023 at 16:24):

This rg noncomputable | rg orting gives

Mathlib/Data/Multiset/Basic.lean:noncomputable -- Porting note: added
Mathlib/Data/Multiset/Basic.lean:noncomputable -- Porting note: added
Mathlib/Data/Multiset/Basic.lean:noncomputable -- Porting note: added
Mathlib/Data/Multiset/Basic.lean:noncomputable -- Porting note: added
Mathlib/Data/Multiset/Sections.lean:-- Porting note: `Sections` depends on `recOn` which is noncomputable.
Mathlib/Data/Multiset/Pi.lean:--Porting note: Added noncomputable
Mathlib/Data/Finset/Pi.lean:--Porting note: marked noncomputable
Mathlib/Data/Fin/Basic.lean:--Porting note: marked noncomputable
Mathlib/Data/Fin/Tuple/Basic.lean:-- Porting note: I made this noncomputable because Lean seemed to think it should be
Mathlib/Data/Vector/Basic.lean:-- porting notes: requires noncomputable
Mathlib/Data/Vector/Basic.lean:-- porting notes: requires noncomputable
Mathlib/Data/Vector/Basic.lean:-- porting notes: requires noncomputable
Mathlib/Data/PNat/Basic.lean:-- Porting note: added `noncomputable` because of
Mathlib/Data/Fintype/Pi.lean:--Porting note: added noncomputable
Mathlib/Data/Fintype/Pi.lean:--Porting note: added noncomputable
Mathlib/Data/Set/Basic.lean:-- Porting note: remove `noncomputable` later
Mathlib/Algebra/Group/Units.lean:-- Porting note: `to_additive` doesn't carry over `noncomputable` so we make an explicit defn
Mathlib/Algebra/FreeMonoid/Basic.lean:-- Porting note: added noncomputable
Mathlib/Order/RelClasses.lean:-- Porting note: WellFounded.fix is noncomputable, at 2022-10-29 lean
Mathlib/Order/RelClasses.lean:-- Porting note: WellFounded.fix is noncomputable, at 2022-10-29 lean
Mathlib/Order/RelClasses.lean:-- Porting note: WellFounded.fix is noncomputable, at 2022-10-29 lean
Mathlib/Control/Fix.lean:-- porting note: added noncomputable, because WellFounded.fix is noncomputable (for now?)
Mathlib/Control/Fix.lean:-- porting note: added noncomputable, because WellFounded.fix is noncomputable (for now?)
Mathlib/Control/Fix.lean:-- porting note: added noncomputable, because WellFounded.fix is noncomputable (for now?)

Johan Commelin (Jan 20 2023 at 16:25):

I'm on a train, so this was on an ancient master (from 12 hrs ago, or so)

Eric Wieser (Jan 20 2023 at 16:55):

I think I have most of those removed my PR

Eric Wieser (Jan 20 2023 at 17:48):

I think it's just the WellFounded.fix things that remain noncomputable

Eric Wieser (Jan 20 2023 at 17:50):

Reid Barton said:

AFAIK we don't ever evaluate Decidable instances (that's not how dec_trivial works)

Oh, that's a very good point. I guess it's still nice for metaprograms, but the application is admittedly niche.

Mario Carneiro (Jan 20 2023 at 18:25):

Eric Wieser said:

I think it's just the WellFounded.fix things that remain noncomputable

I recall early in the ad-hoc phase I did something similar to your List.recC for WellFounded.fix - you can just add a csimp lemma and then anything using WellFounded.fix will be computable

Eric Wieser (Jan 20 2023 at 18:29):

Oh, I wasn't aware it was possible to write one


Last updated: Dec 20 2023 at 11:08 UTC