Zulip Chat Archive

Stream: general

Topic: apply not working with Quotient.inductionOn?


Sina (Nov 01 2023 at 20:41):

I have the following ad-hoc example where i want to prove the associativity of addition modulo some fixed integer. Somehow exact works but not apply and i don't understand the error message failed to elaborate eliminator, expected type is not available. The relevant line is the field add_assoc in the instance of AddMonoid below.

import Mathlib.Data.Int.ModEq
open Int

abbrev Z (n : ) := 

instance mod_cong_setoid (n : ) : Setoid (Z n) :=
{
  r := Int.ModEq n,
  iseqv := ModEq.refl, ModEq.symm, ModEq.trans
}

abbrev CMod (n : ) := Quotient (mod_cong_setoid n)

namespace CMod

@[simp]
def add_aux (n : ) : Z n  Z n  CMod n := fun x y =>  x + y 

@[simp]
lemma add_aux_resp_cong (n : ) :  (a b a' b': Z n) ,  a  a'  b  b'   ( a + b  : CMod n)  =  a' + b'  :=
by
  sorry

instance add (n : ) : Add (CMod n) where
  add := Quotient.lift₂ (CMod.add_aux n) (add_aux_resp_cong n)

lemma add_assoc_aux (n : ) :  (a b c : Z n), ( a  : CMod n) +  b   +  c  =  a   + ( b  +  c ) :=
by
  sorry

instance mod_cong_add_monoid (n : ) : AddMonoid (CMod n) where
  add := Add.add
  add_assoc := by intro a b c; exact Quotient.inductionOn₃ a b c (add_assoc_aux n)
  --simp; apply Quotient.inductionOn₃ a b c;
  zero := _
  zero_add := _
  add_zero := _
  nsmul := _
  nsmul_zero := _
  nsmul_succ := _

end CMod

Eric Wieser (Nov 01 2023 at 20:46):

Use refine instead

Kyle Miller (Nov 01 2023 at 20:53):

The function Quotient.inductionOn₃ is handled specially -- it's got a complicated argument (motive) that needs help filling in when elaborating. To do this, it needs to know the expected type at this point. However, the apply tactic elaborates its argument without an expected type (this is because the way apply works is that it attempts to figure out how many additional arguments to apply, so it can't supply an expected type without knowing this number, which would be needed before elaborating). Other tactics, like exact or refine, do elaborate their arguments with the expected type.

Kyle Miller (Nov 01 2023 at 20:55):

(I suppose there could be an apply! f x y z tactic that re-elaborates with every guess...)

Mario Carneiro (Nov 01 2023 at 20:57):

Kyle Miller said:

(I suppose there could be an apply! f x y z tactic that re-elaborates with every guess...)

apply does that

Sina (Nov 01 2023 at 20:58):

@Kyle Miller
I see, thanks for explaining this. In my mind apply could do everything that exact was capable of but your explanation indicates I had a wrong presumption.

Kyle Miller (Nov 01 2023 at 21:07):

@Mario Carneiro Huh? apply f x y z elaborates f x y z exactly once, and it tacks on new metavariables using mkAppN on the elaborated expression.

Mario Carneiro (Nov 01 2023 at 21:08):

well it elaborates only once, yes, but it does try different settings for the mvars

Kyle Miller (Nov 01 2023 at 21:11):

Ok, but the point is that apply! could re-elaborate with varying numbers of trailing holes with the expected type -- you can't do that by elaborating f x y z once ahead of time.

Mario Carneiro (Nov 01 2023 at 21:11):

In theory this should be sufficient provided that the eliminator defers when it doesn't know how to create the motive


Last updated: Dec 20 2023 at 11:08 UTC