Zulip Chat Archive

Stream: new members

Topic: type mismatch


Kenny Lau (Feb 27 2019 at 09:03):

has type
  @is_ring_hom.{u (max v u)} R (Π (b : ι), @ideal.quotient.{u} R _inst_1 (f b)) (@comm_ring.to_ring.{u} R _inst_1)
    (@pi.ring.{v u} ι (λ (b : ι), @ideal.quotient.{u} R _inst_1 (f b))
       (λ (i : ι),
          @comm_ring.to_ring.{u} (@ideal.quotient.{u} R _inst_1 (f i)) (@ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
    (λ (x : R) (b : ι), @ideal.quotient.mk.{u} R _inst_1 (f b) x)
but is expected to have type
  @is_ring_hom.{u (max v u)} R (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i)) (@comm_ring.to_ring.{u} R _inst_1)
    (@comm_ring.to_ring.{(max v u)} (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
       (@pi.comm_ring.{v u} ι (λ (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
          (λ (i : ι), @ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
    (λ (r : R) (i : ι), @ideal.quotient.mk.{u} R _inst_1 (f i) r)

Kenny Lau (Feb 27 2019 at 09:04):

have (@pi.ring.{v u} ι (λ (b : ι), @ideal.quotient.{u} R _inst_1 (f b))
       (λ (i : ι),
          @comm_ring.to_ring.{u} (@ideal.quotient.{u} R _inst_1 (f i)) (@ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
=
(@comm_ring.to_ring.{(max v u)} (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
       (@pi.comm_ring.{v u} ι (λ (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
          (λ (i : ι), @ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
, from rfl,

but this works

Kevin Buzzard (Feb 27 2019 at 09:04):

Is this thread supposed to be comprehensible to anyone but you?

Kenny Lau (Feb 27 2019 at 09:05):

type mismatch at application
  quotient.lift (⨅ (i : ι), f i) (λ (r : R) (i : ι), quotient.mk (f i) r)
term
  pi.is_ring_hom_pi (λ (i : ι) (r : R), quotient.mk (f i) r)
has type
  is_ring_hom (λ (x : R) (b : ι), quotient.mk (f b) x)
but is expected to have type
  is_ring_hom (λ (r : R) (i : ι), quotient.mk (f i) r)

Kenny Lau (Feb 27 2019 at 09:05):

is this more comprehensible?

Patrick Massot (Feb 27 2019 at 09:05):

Kenny should have a private stream all for himself

Kevin Buzzard (Feb 27 2019 at 09:05):

What is your question Kenny? I don't think that other people are going to be carefully scanning your output of pp.all true.

Kenny Lau (Feb 27 2019 at 09:06):

well, my question is that, clearly they are equal!

Patrick Massot (Feb 27 2019 at 09:06):

Is that a question?

Kevin Buzzard (Feb 27 2019 at 09:06):

Well Lean says they're not so they're not.

Kevin Buzzard (Feb 27 2019 at 09:06):

But because we have no way of reproducing the error, how can anyone else help?

Kenny Lau (Feb 27 2019 at 09:06):

then the question is, why does Lean not know that they are equal?

Kevin Buzzard (Feb 27 2019 at 09:06):

you're the only person who can answer that until you post a lot more context

Kenny Lau (Feb 27 2019 at 09:06):

import algebra.pi_instances ring_theory.ideal_operations

universes u v

variables {R : Type u} [comm_ring R] {ι : Type v}

open lattice

namespace ideal

def to_prod (f : ι  ideal R) : ( i, f i).quotient  Π i, (f i).quotient :=
@@quotient.lift _ _ ( i, f i) (λ r i, ideal.quotient.mk (f i) r)
  (pi.is_ring_hom_pi _ : is_ring_hom (λ (r : R) (i : ι), quotient.mk (f i) r))
  _

end ideal

Patrick Massot (Feb 27 2019 at 09:07):

We can sympathize, this is probably what we should do

Kevin Buzzard (Feb 27 2019 at 09:07):

After his last post we can now try to help :-)

Kevin Buzzard (Feb 27 2019 at 09:08):

So they're not the same because the implicit terms are different.

Kenny Lau (Feb 27 2019 at 09:10):

but they're defeq

Kenny Lau (Feb 27 2019 at 09:10):

as seen in my second post

Kevin Buzzard (Feb 27 2019 at 09:12):

Indeed, you have now explained the question coherently.

Kevin Buzzard (Feb 27 2019 at 09:13):

import algebra.pi_instances ring_theory.ideal_operations

universes u v

variables {R : Type u} [comm_ring R] {ι : Type v}

open lattice

namespace ideal

set_option pp.all true
def to_prod (f : ι  ideal R) : ( i, f i).quotient  Π i, (f i).quotient :=
begin
  have : @is_ring_hom.{u (max v u)} R (Π (b : ι), @ideal.quotient.{u} R _inst_1 (f b)) (@comm_ring.to_ring.{u} R _inst_1)
    (@pi.ring.{v u} ι (λ (b : ι), @ideal.quotient.{u} R _inst_1 (f b))
       (λ (i : ι),
          @comm_ring.to_ring.{u} (@ideal.quotient.{u} R _inst_1 (f i)) (@ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
    (λ (x : R) (b : ι), @ideal.quotient.mk.{u} R _inst_1 (f b) x)
    =
@is_ring_hom.{u (max v u)} R (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i)) (@comm_ring.to_ring.{u} R _inst_1)
    (@comm_ring.to_ring.{(max v u)} (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
       (@pi.comm_ring.{v u} ι (λ (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
          (λ (i : ι), @ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
    (λ (r : R) (i : ι), @ideal.quotient.mk.{u} R _inst_1 (f i) r) := rfl,

exact @@quotient.lift _ _ ( i, f i) (λ r i, ideal.quotient.mk (f i) r)
  (pi.is_ring_hom_pi _ : is_ring_hom (λ (r : R) (i : ι), quotient.mk (f i) r))
  _
  /-
  type mismatch at application
  @ideal.quotient.lift.{u (max v u)} R (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i)) _inst_1
    (@pi.comm_ring.{v u} ι (λ (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
       (λ (i : ι), @ideal.quotient.comm_ring.{u} R _inst_1 (f i)))
    (@lattice.infi.{u v+1} (@ideal.{u} R _inst_1) ι
       (@submodule.lattice.has_Inf.{u u} R R (@comm_ring.to_ring.{u} R _inst_1)
          (@ring.to_add_comm_group.{u} R (@comm_ring.to_ring.{u} R _inst_1))
          (@ring.to_module.{u} R (@comm_ring.to_ring.{u} R _inst_1)))
       (λ (i : ι), f i))
    (λ (r : R) (i : ι), @ideal.quotient.mk.{u} R _inst_1 (f i) r)
    (@pi.is_ring_hom_pi.{v u u} ι (λ (a : ι), @ideal.quotient.{u} R _inst_1 (f a))
       (λ (i : ι),
          @comm_ring.to_ring.{u} (@ideal.quotient.{u} R _inst_1 (f i)) (@ideal.quotient.comm_ring.{u} R _inst_1 (f i)))
       R
       (@comm_ring.to_ring.{u} R _inst_1)
       (λ (i : ι) (r : R), @ideal.quotient.mk.{u} R _inst_1 (f i) r)
       (λ (a : ι), @ideal.quotient.is_ring_hom_mk.{u} R _inst_1 (f a)))
term
  @pi.is_ring_hom_pi.{v u u} ι (λ (a : ι), @ideal.quotient.{u} R _inst_1 (f a))
    (λ (i : ι),
       @comm_ring.to_ring.{u} (@ideal.quotient.{u} R _inst_1 (f i)) (@ideal.quotient.comm_ring.{u} R _inst_1 (f i)))
    R
    (@comm_ring.to_ring.{u} R _inst_1)
    (λ (i : ι) (r : R), @ideal.quotient.mk.{u} R _inst_1 (f i) r)
    (λ (a : ι), @ideal.quotient.is_ring_hom_mk.{u} R _inst_1 (f a))
has type
  @is_ring_hom.{u (max v u)} R (Π (b : ι), @ideal.quotient.{u} R _inst_1 (f b)) (@comm_ring.to_ring.{u} R _inst_1)
    (@pi.ring.{v u} ι (λ (b : ι), @ideal.quotient.{u} R _inst_1 (f b))
       (λ (i : ι),
          @comm_ring.to_ring.{u} (@ideal.quotient.{u} R _inst_1 (f i)) (@ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
    (λ (x : R) (b : ι), @ideal.quotient.mk.{u} R _inst_1 (f b) x)
but is expected to have type
  @is_ring_hom.{u (max v u)} R (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i)) (@comm_ring.to_ring.{u} R _inst_1)
    (@comm_ring.to_ring.{(max v u)} (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
       (@pi.comm_ring.{v u} ι (λ (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
          (λ (i : ι), @ideal.quotient.comm_ring.{u} R _inst_1 (f i))))
    (λ (r : R) (i : ι), @ideal.quotient.mk.{u} R _inst_1 (f i) r)
    -/

end

end ideal

Kevin Buzzard (Feb 27 2019 at 09:13):

I recommend you fill in the _

Kenny Lau (Feb 27 2019 at 09:14):

wat

Kevin Buzzard (Feb 27 2019 at 09:14):

but what do I know

Kevin Buzzard (Feb 27 2019 at 09:15):

Maybe some elaboration is taking place in the wrong order or some such nonsense

Kevin Buzzard (Feb 27 2019 at 09:17):

Do you understand why

exact @ideal.quotient.lift.{u (max v u)} R (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i)) _inst_1
    (@pi.comm_ring.{v u} ι (λ (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
       (λ (i : ι), @ideal.quotient.comm_ring.{u} R _inst_1 (f i)))
    (@lattice.infi.{u v+1} (@ideal.{u} R _inst_1) ι
       (@submodule.lattice.has_Inf.{u u} R R (@comm_ring.to_ring.{u} R _inst_1)
          (@ring.to_add_comm_group.{u} R (@comm_ring.to_ring.{u} R _inst_1))
          (@ring.to_module.{u} R (@comm_ring.to_ring.{u} R _inst_1)))
       (λ (i : ι), f i))
    (λ (r : R) (i : ι), @ideal.quotient.mk.{u} R _inst_1 (f i) r)
    (@pi.is_ring_hom_pi.{v u u} ι (λ (a : ι), @ideal.quotient.{u} R _inst_1 (f a))
       (λ (i : ι),
          @comm_ring.to_ring.{u} (@ideal.quotient.{u} R _inst_1 (f i)) (@ideal.quotient.comm_ring.{u} R _inst_1 (f i)))
       R
       (@comm_ring.to_ring.{u} R _inst_1)
       (λ (i : ι) (r : R), @ideal.quotient.mk.{u} R _inst_1 (f i) r)
       (λ (a : ι), @ideal.quotient.is_ring_hom_mk.{u} R _inst_1 (f a)))

doesn't work? I have to go and give a lecture on p-adic geometry so I can't think about this any more but this would be one way of trying to fill in the _s to see if that's the issue.

Kevin Buzzard (Feb 27 2019 at 09:17):

i.e. look at what the term fully elaborates to and try that instead. I just must have failed somehow.

Kevin Buzzard (Feb 27 2019 at 09:17):

[my error was "you got it wrong" not "these are not defeq"]

Kenny Lau (Feb 27 2019 at 09:24):

finally this "worked":

import algebra.pi_instances ring_theory.ideal_operations

universes u v

variables {R : Type u} [comm_ring R] {ι : Type v}

open lattice

namespace ideal

def to_pi (f : ι  ideal R) (r : R) : Π i, (f i).quotient :=
λ i, ideal.quotient.mk (f i) r

instance (f : ι  ideal R) : is_ring_hom (to_pi f) :=
pi.is_ring_hom_pi _

def to_prod (f : ι  ideal R) : ( i, f i).quotient  Π i, (f i).quotient :=
@ideal.quotient.lift.{u (max v u)} R (Π (i : ι), @ideal.quotient.{u} R _inst_1 (f i)) _inst_1
    (@pi.comm_ring.{v u} ι (λ (i : ι), @ideal.quotient.{u} R _inst_1 (f i))
       (λ (i : ι), @ideal.quotient.comm_ring.{u} R _inst_1 (f i)))
    (@lattice.infi.{u v+1} (@ideal.{u} R _inst_1) ι
       (@submodule.lattice.has_Inf.{u u} R R (@comm_ring.to_ring.{u} R _inst_1)
          (@ring.to_add_comm_group.{u} R (@comm_ring.to_ring.{u} R _inst_1))
          (@ring.to_module.{u} R (@comm_ring.to_ring.{u} R _inst_1)))
       (λ (i : ι), f i))
    (@ideal.to_pi.{u v} R _inst_1 ι f)
    (@ideal.is_ring_hom.{u v} R _inst_1 ι f)
  (λ r hr, funext $ λ i, quotient.eq_zero_iff_mem.2 $ mem_Inf.1 hr i, rfl)

end ideal

Kenny Lau (Feb 27 2019 at 09:26):

minimzed to:

def to_prod (f : ι  ideal R) : ( i, f i).quotient  Π i, (f i).quotient :=
@@ideal.quotient.lift _ _ ( i, f i) (ideal.to_pi f)
    (@ideal.is_ring_hom.{u v} R _ ι f)
  (λ r hr, funext $ λ i, quotient.eq_zero_iff_mem.2 $ mem_Inf.1 hr i, rfl)

Kenny Lau (Feb 27 2019 at 09:26):

in (@ideal.is_ring_hom.{u v} R _ ι f), turning ι into underscore creates the error

Kenny Lau (Feb 27 2019 at 09:27):

the R is also essential

Kevin Buzzard (Feb 27 2019 at 14:04):

So it's some elaborator nonsense, or do you think it's a bug?

Kevin Buzzard (Feb 27 2019 at 14:04):

Let's try to debug it!

Kevin Buzzard (Feb 27 2019 at 14:05):

Sebastian once told us some set_option to see the rfl machine trying to prove rfl

Kevin Buzzard (Feb 27 2019 at 14:05):

I think it was in the thread where he wrote "got into office" "checks Zulip" "leaves office again"

Ashvni Narayanan (Sep 01 2020 at 13:44):

I am trying to show that the principal fractional ideals form a subgroup of the group of fractional ideals.

import linear_algebra.finite_dimensional
import ring_theory.ideal.basic
import algebra.field
import ring_theory.subring
import ring_theory.integral_closure
import ring_theory.fractional_ideal
import data.rat.basic
import ring_theory.algebra
import ring_theory.algebraic

open function
open_locale classical big_operators

class number_field (K : Type*) :=
   (fld : field K)
   (alg : algebra  K)
   (fd : finite_dimensional  K)

def number_ring (K : Type*) [number_field K] := @integral_closure  K _ (@field.to_comm_ring K _inst_1.fld) _

noncomputable theory
open_locale classical

open finite_dimensional
namespace number_field
variables (K : Type*) [number_field K]
variables [g : fraction_map (number_ring K) K ]

def principal_fractional_ideal := { P : ring.fractional_ideal g //  a : (number_ring K), submodule.is_principal P.1 }

instance is_group : group (ring.fractional_ideal g) := sorry,

instance is_subgroup : subgroup (ring.fractional_ideal g) :=
begin
  use (principal_fractional_ideal g),
end

The last proof gives me the error

type mismatch at application
  principal_fractional_ideal g
term
  g
has type
  fraction_map (number_ring K) K : Type u_1
but is expected to have type
  Type ? : Type (?+1)
state:
K : Type u_1,
_inst_1 : number_field K,
g : fraction_map (number_ring K) K
 subgroup (ring.fractional_ideal g)

Any help is appreciated, thank you!

Adam Topaz (Sep 01 2020 at 13:50):

Sounds like you're missing an underscore before the g.

Adam Topaz (Sep 01 2020 at 13:57):

Your code is not compiling for me :-/

Adam Topaz (Sep 01 2020 at 14:06):

Okay, looks like there were a bunch of issues.
Here's a hacked together fix.

import linear_algebra.finite_dimensional
import ring_theory.ideal.basic
import algebra.field
import ring_theory.subring
import ring_theory.integral_closure
import ring_theory.fractional_ideal
import data.rat.basic
import ring_theory.algebra
import ring_theory.algebraic

open function
open_locale classical big_operators

class number_field (K : Type*) :=
   (fld : field K)
   (alg : algebra  K)
   (fd : finite_dimensional  K)

namespace number_field
variables (K : Type*) [number_field K]
instance : field K := number_field.fld
instance : algebra  K := number_field.alg
instance : finite_dimensional  K := number_field.fd
end number_field

def number_ring (K : Type*) [number_field K] := @integral_closure  K _ (@field.to_comm_ring K _inst_1.fld) _

noncomputable theory
open_locale classical

open finite_dimensional
namespace number_field
variables (K : Type*) [number_field K]
variables (g : fraction_map (number_ring K) K)

def principal_fractional_ideal := { P : ring.fractional_ideal g |  a : (number_ring K), submodule.is_principal P.1 }

instance is_group : group (ring.fractional_ideal g) := sorry,

#check principal_fractional_ideal

instance is_subgroup : subgroup (ring.fractional_ideal g) :=
{ carrier := principal_fractional_ideal _ g,
  one_mem' := _,
  mul_mem' := _,
  inv_mem' := _ }

Adam Topaz (Sep 01 2020 at 14:07):

Note that subgroup takes a set as its carrier, whereas you defined a principal_fractional_ideal as a subtype.
Also, the field, algebra, etc. instances were not recognized since you didn't extend these classes in your definition of number field.

Ashvni Narayanan (Sep 01 2020 at 15:51):

Ah, I see. It seems like the _ is K. So essentially I needed g to be explicit. Thank you!

Adam Topaz (Sep 01 2020 at 15:53):

You need to make KK implicit :) (lean will figure out KK from gg)

Ashvni Narayanan (Sep 01 2020 at 16:05):

Adam Topaz said:

You need to make KK implicit :) (lean will figure out KK from gg)

Ah alright, thank you!

Alex Zhang (Jun 10 2021 at 07:28):

Why is there a type mismatch problem in the following code?

constants {α : Type*} (r : α  α  Prop)

section

parameter  transr :  {x y z}, r x y  r y z  r x z

variables {a b c d e : α}

theorem t1 (h₁ : r a b) (h₂ : r b c) (h₃ : r c d) : r a d :=
transr (transr h₁ h₂) h₃

end

Eric Wieser (Jun 10 2021 at 07:41):

What's the error message?

Kyle Miller (Jun 10 2021 at 07:46):

It's somehow coming from the universe variable for α

The error message:

15:9: type mismatch at application
  transr h₁
term
  h₁
has type
  r a b
but is expected to have type
  r ?m_1 ?m_2

but with set_option pp.universes true it's

15:1: type mismatch at application
  transr  h₃
term
  h₃
has type
  r.{u_6 u_7} c d
but is expected to have type
  r.{u_2 u_3} ?m_1 ?m_2

Kyle Miller (Jun 10 2021 at 07:47):

This is fine:

theorem t1 {α : Type*} (r : α  α  Prop) (transr :  {x y z : α}, r x y  r y z  r x z)
  {a b c d e : α} (h₁ : r a b) (h₂ : r b c) (h₃ : r c d) : r a d :=
transr (transr h₁ h₂) h₃

Kyle Miller (Jun 10 2021 at 07:48):

and so is this:

variables {α : Type*} (r : α  α  Prop) (transr :  {x y z : α}, r x y  r y z  r x z)

theorem t1 {a b c d e : α} (h₁ : r a b) (h₂ : r b c) (h₃ : r c d) : r a d :=
transr (transr h₁ h₂) h₃

Kyle Miller (Jun 10 2021 at 07:49):

If you're wanting to use constants, then one thing that seems to fix it is to put things into a specific type universe:

constants {α : Type} (r : α  α  Prop)

Alex Zhang (Jun 10 2021 at 07:54):

I don't understand... why does the mismatch error occur :(
Could anyone give me an explanation?

Eric Wieser (Jun 10 2021 at 07:58):

Mixing constants and parameters like that is kind of strange

Eric Wieser (Jun 10 2021 at 08:00):

"there exists some global r that is impossible to prove anything about" + "allow the user to supply a proof that r is transitive" seems like nonsense to me

Eric Wieser (Jun 10 2021 at 08:01):

Probably they should both be variables

Johan Commelin (Jun 10 2021 at 08:03):

I think constants should have been delayed till the final chapter of #tpil. It's rare that one should need it. Mathlib never uses it.

Alex Zhang (Jun 10 2021 at 08:05):

Eric Wieser said:

Mixing constants and parameters like that is kind of strange

Yes, I mixed them purely for the purpose of learning their functionality.
According to Johan, I don't need to study "constant" then :)

Johan Commelin (Jun 10 2021 at 08:07):

Unless you are interested in adding new axioms to your foundations. In some sense, every use of constant should be viewed with a lot of suspicion.

Johan Commelin (Jun 10 2021 at 08:08):

Because it can make the whole project inconsistent.

Mario Carneiro (Jun 10 2021 at 08:08):

constant x : T is approximately equivalent to def x : T := sorry

Johan Commelin (Jun 10 2021 at 08:08):

With the difference that the latter contains the word sorry :stuck_out_tongue_wink:

Mario Carneiro (Jun 10 2021 at 08:09):

constant is for people who don't apologize for their actions

Kevin Buzzard (Jun 10 2021 at 08:37):

and, by the looks of things, want to generate universe mismatches

Alex Zhang (Jun 20 2021 at 14:34):

How can I fix the type mismatch problem in the following definition?

universe u

inductive vector (α : Type u) :   Type u
| nil {} : vector 0
| cons   : Π {n}, α  vector n  vector (n+1)

namespace vector
local notation h :: t := cons h t

def append {α : Type*} : Π {n m : }, vector α n  vector α m  vector α (n+m)
| 0 m v w := w

end vector

Kevin Buzzard (Jun 20 2021 at 14:35):

The easiest way to fix it is to define vector alpha n as {L : list alpha | L.length = n}.

Alex Zhang (Jun 20 2021 at 14:38):

Yes, I know that I can change the definition. As I am studying the contents of the reference book and trying various exercises, I would like to keep the above definition, which is used in the book.

Kevin Buzzard (Jun 20 2021 at 14:38):

Mathematically this is the same object, and it turns out that when it comes to implementation issues you have quickly run into the problem with the inductive definition, which is why I'm suggesting that you avoid it completely. As an "end user" of vectors all you need is an API for vectors, so because I can define things like nil and cons and append for my suggested definition, which I can, you do not need to care about these subtle implementation issues, which are matters for computer scientists.

Kevin Buzzard (Jun 20 2021 at 14:39):

"Sticking to the book" is a big mistake. This is not how to formalise mathematics.

Kevin Buzzard (Jun 20 2021 at 14:42):

def append {α : Type*} : Π {n m : }, vector α n  vector α m  vector α (n+m)
| 0 m v w := begin have h : 0 + m = m := nat.zero_add m, rw h, exact w, end

Kevin Buzzard (Jun 20 2021 at 14:43):

This compiles. But your problems are only just beginning.

Kevin Buzzard (Jun 20 2021 at 14:43):

The problem is that rw introduces an eq.rec into the definition, which means that it will be hard to work with in practice.

Adam Topaz (Jun 20 2021 at 14:44):

(deleted)

Adam Topaz (Jun 20 2021 at 14:44):

I think this is what you're going for?

Adam Topaz (Jun 20 2021 at 14:45):

sorry that's backwards

Adam Topaz (Jun 20 2021 at 14:47):

I think this is better?

universe u

inductive vector (α : Type u) :   Type u
| nil {} : vector 0
| cons   : Π {n}, α  vector n  vector (n+1)

namespace vector
local notation h :: t := cons h t

def append {α : Type*} : Π {n m : }, vector α n  vector α m  vector α (m + n)
| 0 m _ w := w
| (n+1) m (cons h v) w := cons h (append v w)

end vector

Kevin Buzzard (Jun 20 2021 at 14:47):

Adam has cheated because he has switched the natural which you're doing induction on and is now abusing Lean's definitional equality. He has used the fact that although 0 + m = m is true because of a theorem (it uses induction and hence the proof mentions nat.rec), m + 0 = m is true by definition and this fact can be abused. If Lean were to change its definition of nat then Adam's construction might stop working. what I am trying to emphasize is that you are running into questions which are "non-mathematical" here -- the answer depends on more than the objects you're working with, it depends on precisely how they have been implemented, and mathematics should not depend on such things.

Adam Topaz (Jun 20 2021 at 14:47):

Yes, I should have mentioned that :)

Kevin Buzzard (Jun 20 2021 at 14:49):

Update: Adam has edited his post and is now cheating in a new way, he has changed your n + m to m + n. The fact that this is an issue should be a red flag, although unfortunately sometimes in mathematics we have to resort to dirty tricks like this, which is exactly why mathematicians like Adam know these tricks.

Adam Topaz (Jun 20 2021 at 14:50):

Just to clarify: I agree with everything Kevin said in this case, but I mentioned that code in case you wanted an example of using the equation compiler

Adam Topaz (Jun 20 2021 at 14:54):

A better cheat would be to change your inductive definition of vector so that append can actually match the recursive definition of addition of natural numbers.

Alex Zhang (Jun 20 2021 at 14:58):

@Adam Topaz Could you show exact code of the "better cheat"?

Adam Topaz (Jun 20 2021 at 14:58):

Oh, you can just cons on the right instead of the left

Adam Topaz (Jun 20 2021 at 14:59):

Sorry, I'm away from the computer now so I can't write any code

Kevin Buzzard (Jun 20 2021 at 15:05):

The problem is that nat "appends on the right" (succ n := n+1 by definition) but list "appends on the left" (append [h] tl := h :: tl by definition). What is happening here is that if F is a function taking values in types, and a = b by definition, then F a = F b by definition, however if a = b is only true because of a theorem, then F a = F b is true because of an axiom eq.rec, and this axiom needs to be invoked whenever you move from F a to F b, which can be extremely inconvenient in Lean's type theory because of the way things are set up. Hence you either decide to see the red flags and try a new design decision, or you press on and then you have to start thinking hard about which things are true by definition and which things are only true because of theorems, which can be problematic (and can change without warning).

Alex Zhang (Aug 05 2021 at 19:38):

import tactic
theorem test {I J : Type*}:
 {K : Type*}, 1 = 1 :=
begin
  refine ⟨(I × J), _⟩,
end

This reports error :

type mismatch at application
  Exists.intro (I × J)
term
  I × J
has type
  Type (max u_1 u_2) : Type (max (u_1+1) (u_2+1))
but is expected to have type
  Type u_3 : Type (u_3+1)

Why should there be a type mismatch problem in this example? How can I fix it?

Alex Zhang (Aug 05 2021 at 19:41):

Perhaps I should give an explicit universe...

Alex Zhang (Aug 05 2021 at 19:42):

This is ok

theorem {u} test {I J : Type u}:
 {K : Type u}, 1 = 1 :=
begin
  refine I × I, _⟩,
end

Eric Rodriguez (Aug 05 2021 at 20:45):

this is the example/def vs lemma/theorem stuff we talked about before; the type of a theorem is immutable after it's set, whilst universe metavariables can change in an example/def.


Last updated: Dec 20 2023 at 11:08 UTC