## Stream: general

### Topic: sum.rec

#### Reid Barton (May 01 2018 at 15:52):

I'm having a surprisingly hard time working with sum.rec. Specifically, I'm having trouble convincing Lean to give me an ordinary, non-dependent function as the result. I pasted a transcript here: https://gist.github.com/rwbarton/b6cbf07bd07afd89f8c2b4feef8cec5f

#### Kenny Lau (May 01 2018 at 15:53):

the type of the second term depends on the type of the first term though

#### Kenny Lau (May 01 2018 at 15:53):

sorry, I thought you were talking about sigma. ignore what I said.

#### Reid Barton (May 01 2018 at 15:54):

I'm especially confused that surjective ((λ a, sum.rec f g a) : α ⊕ β → γ) produces an error that seems to be complaining that the argument needs to be a non-dependent function, though I can kind of imagine how this might not be considered a bug

#### Reid Barton (May 01 2018 at 15:56):

It'd be really convenient for me if there was also a non-dependent eliminator sum.rec' : (α → γ) → (β → γ) → α ⊕ β → γ

#### Reid Barton (May 01 2018 at 15:56):

I noticed someone else came across the same issue, too:

lemma continuous_sum_rec {f : α → γ} {g : β → γ}
(hf : continuous f) (hg : continuous g) : @continuous (α ⊕ β) γ _ _ (@sum.rec α β (λ_, γ) f g) :=


#### Reid Barton (May 01 2018 at 15:58):

That whole result type should really just be continuous (sum.rec' f g).

#### Reid Barton (May 01 2018 at 16:00):

I assume the same issue arises for any other type with multiple constructors, too

#### Mario Carneiro (May 01 2018 at 17:45):

I think the problem is that sum.rec uses the eliminator strategy, meaning it relies heavily on the expected type to determine the motive, but surjective does not give a sufficiently specific expected type ?M1 -> ?M2. You can fix the issue by annotating the metavariables of surjective:

@surjective (α ⊕ β) γ (λ a, sum.rec f g a)


#### Mario Carneiro (May 01 2018 at 17:47):

The eliminator strategy makes T.rec more or less unusable when unapplied; apparently superfluous eta expansions here are important to trigger the right strategy

#### Kevin Buzzard (May 01 2018 at 18:08):

Could this also be fixed by writing a second recursor?

#### Kevin Buzzard (May 01 2018 at 18:08):

i.e. is this a problem that the interface could solve?

yes

#### Mario Carneiro (May 01 2018 at 18:09):

yes, but that would require changing lean (which generates all the inductive theorems)

#### Kenny Lau (May 01 2018 at 18:09):

I think I'm instead reading "yes but you would need to PR core"

#### Mario Carneiro (May 01 2018 at 18:10):

yes, that's what I mean

#### Kevin Buzzard (May 01 2018 at 18:12):

So you can't just write a new recursor, with a different name, which runs on top of unmodded Lean 3.4.1?

#### Mario Carneiro (May 01 2018 at 18:13):

You can, but you would have to do so for every inductive type

#### Kevin Buzzard (May 01 2018 at 18:13):

but you could solve his one specific problem with sum.rec.

#### Kevin Buzzard (May 01 2018 at 18:14):

I have to ask these stupid questions because I have no understanding of the status of these elab commands

#### Kevin Buzzard (May 01 2018 at 18:14):

all I know is that if you don't like one, you can sometimes add an @ and get another one

#### Mario Carneiro (May 01 2018 at 18:14):

Sure, or.elim already exists and sum.elim could be similar

#### Kevin Buzzard (May 01 2018 at 18:21):

example (a b c : Prop) : @or.elim a b c = @or.rec_on a b c := rfl

#### Kevin Buzzard (May 01 2018 at 18:21):

so the only way these function differ is by magic

#### Kevin Buzzard (May 01 2018 at 18:21):

as far as I am concerned

#### Kevin Buzzard (May 01 2018 at 18:22):

Aah do they have different tags?

#### Kevin Buzzard (May 01 2018 at 18:22):

Not only are they the same theorem

#### Kevin Buzzard (May 01 2018 at 18:23):

they are the same proof

#### Kevin Buzzard (May 01 2018 at 18:23):

but one is tagged [reducible]and is protected

#### Kevin Buzzard (May 01 2018 at 18:24):

[reducible] is all about how eagerly the elaborator unfolds the definition, or something...

#### Kevin Buzzard (May 01 2018 at 18:24):

protected I have no idea. Something about avoiding overloading?

#### Reid Barton (May 01 2018 at 18:26):

protected means if you wrote open or (which you probably wouldn't), then you still wouldn't get the name rec_on as a synonym for or.rec_on

#### Kevin Buzzard (May 01 2018 at 18:31):

one is a def and one is a theorem. Does this make any difference?

#### Kevin Buzzard (May 01 2018 at 18:36):

unknown identifier 'rec_on'

#### Kevin Buzzard (May 01 2018 at 18:36):

so nobody is allowed to have rec_on?

#### Kevin Buzzard (May 01 2018 at 18:45):

import set_theory.ordinal_notation
open nonote
#check rec_on
/-
rec_on :
Π (o : nonote),
?M_1 0 →
(Π (e : nonote) (n : ℕ+) (a : nonote) (h : below a e), ?M_1 e → ?M_1 a → ?M_1 (oadd e n a h)) → ?M_1 o
-/


#### Kevin Buzzard (May 01 2018 at 18:45):

Do I win five pounds?

#### Reid Barton (May 01 2018 at 18:47):

then that means that nonote.rec_on was not declared as protected

#### Kevin Buzzard (May 01 2018 at 19:04):

What is the complete list of unprotected rec_ons? And are these bugs?

#### Kenny Lau (May 01 2018 at 20:14):

/-- This is a recursor-like theorem for nonote suggesting an
inductive definition, which can't actually be defined this
way due to conflicting dependencies. -/
@[elab_as_eliminator] def rec_on {C : nonote → Sort*} (o : nonote)
(H0 : C 0)
(H1 : ∀ e n a h, C e → C a → C (oadd e n a h)) : C o :=
begin
cases o with o h, induction o with e n a IHe IHa,
{ exact H0 },
{ exact H1 ⟨e, h.fst⟩ n ⟨a, h.snd⟩ h.snd' (IHe _) (IHa _) }
end


(set_theory.ordinal_notation, line 857)

#### Kenny Lau (May 01 2018 at 20:14):

it isn't automatically generated

#### Kenny Lau (May 01 2018 at 20:15):

but indeed, @Mario Carneiro should have made it protected

Last updated: May 12 2021 at 03:23 UTC