Zulip Chat Archive

Stream: general

Topic: Mathematicians learning tactics


Kevin Buzzard (May 30 2018 at 17:12):

instance : comm_monoid ℕ+ :=
{ mul       := λ m n, m.1 * n.1, mul_pos m.2 n.2,
  mul_assoc := λ a b c, subtype.eq (mul_assoc _ _ _),
  one       := succ_pnat 0,
  one_mul   := λ a, subtype.eq (one_mul _),
  mul_one   := λ a, subtype.eq (mul_one _),
mul_comm := λ a b, subtype.eq (mul_comm _ _) }

Kevin Buzzard (May 30 2018 at 17:12):

https://github.com/leanprover/mathlib/blob/00a2eb4119d27761c8a6ee38eb1eae532cd3ac19/data/pnat.lean#L52

Kevin Buzzard (May 30 2018 at 17:12):

All of the proofs of the axioms are the same

Kevin Buzzard (May 30 2018 at 17:13):

"it's true for nat so done by subtype.eq"

Kevin Buzzard (May 30 2018 at 17:13):

Could I write that sentence as a tactic?

Kevin Buzzard (May 30 2018 at 17:13):

I don't even know if that's possible because I don't know what tactics know about names

Kevin Buzzard (May 30 2018 at 17:14):

I'm looking for a proof that defines mul and one and then says done by tactic

Kevin Buzzard (May 30 2018 at 17:16):

If I can do the above with a tactic then I think I can start to work on the tactic I actually want.

Kevin Buzzard (May 30 2018 at 17:16):

and maybe other mathematicians might like the same sort of tactics

Kevin Buzzard (May 30 2018 at 17:16):

Remember when we noticed that proving that if A and B were equiv and A was a ring then B was a ring, was actually quite annoying?

Kevin Buzzard (May 30 2018 at 17:17):

And Kenny would just knock off a proof and he'd just check all ten axioms

Kevin Buzzard (May 30 2018 at 17:17):

and every proof would be funext, simp [name of thing I'm proving]

Kevin Buzzard (May 30 2018 at 17:18):

I think it's about time Kenny learnt how to write this tactic too

Mario Carneiro (May 30 2018 at 17:18):

This is somewhat similar to Simon's pi instance tactic

Kevin Buzzard (May 30 2018 at 17:18):

Can you give me a link?

Mario Carneiro (May 30 2018 at 17:19):

https://github.com/leanprover/mathlib/blob/master/algebra/pi_instances.lean

Kevin Buzzard (May 30 2018 at 17:19):

It's just the same underlying question Mario. It's some concept that is natural to us -- you exchange something with something that's equiv and then an algorithm goes off in our heads which just transfers a whole bunch of structure from one thing to the other effortlessly

Mario Carneiro (May 30 2018 at 17:19):

but to be perfectly honest, the "Kenny method", which I used also in metamath days, actually gets things done

Mario Carneiro (May 30 2018 at 17:20):

It's only after you find yourself doing exactly the same thing ~20 times that you should start considering the tactic approach

Kevin Buzzard (May 30 2018 at 17:20):

That's the point. I wonder if this is what I'm staring at.

Mario Carneiro (May 30 2018 at 17:20):

with less than that, the time it takes to figure out how to write a tactic eclipses the time it would have taken to just copy paste get it over with

Kevin Buzzard (May 30 2018 at 17:21):

I'm running into it again and again, constantly proving trivial things

Kevin Buzzard (May 30 2018 at 17:21):

and the reason I'm interested

Mario Carneiro (May 30 2018 at 17:21):

That's not the same

Kevin Buzzard (May 30 2018 at 17:21):

is that the tactic formalises something which I do naturally in my brain

Mario Carneiro (May 30 2018 at 17:21):

if it's different trivial things, the tactic won't help

Kevin Buzzard (May 30 2018 at 17:21):

and I like formalizing stuff

Mario Carneiro (May 30 2018 at 17:21):

it will handle one kind of trivial and leave untouched 60 others

Kevin Buzzard (May 30 2018 at 17:21):

This is the point at which I stop understanding

Kevin Buzzard (May 30 2018 at 17:21):

and the only way I will understand

Kevin Buzzard (May 30 2018 at 17:22):

is by trying to do it and failing

Mario Carneiro (May 30 2018 at 17:22):

How many other proofs look like the proof of comm_monoid pnat?

Kevin Buzzard (May 30 2018 at 17:22):

so I want to finally understand how difficult it is to write schoolkid.

Kevin Buzzard (May 30 2018 at 17:22):

I don't know Mario. That's what I want to find out.

Kevin Buzzard (May 30 2018 at 17:22):

Instead of saying "Mario go write schoolkid like I told you, it should be there"

Mario Carneiro (May 30 2018 at 17:23):

it should already be in your file staring back at you before you want to consider writing a tactic automating it

Kevin Buzzard (May 30 2018 at 17:23):

I should just try to write it myself

Mario Carneiro (May 30 2018 at 17:24):

Another way to put it: Tactics are a refactoring technique. You should already have a repetitive proof, and now you want to get the same thing done but easier

Reid Barton (May 30 2018 at 17:25):

I also wonder whether you really need a tactic, or just a lemma/instance "a subtype of a monoid is a monoid if it's closed under multiplication and contains the identity"

Mario Carneiro (May 30 2018 at 17:26):

^ this. In this world of automation, lemmas are unsung heroes

Andrew Ashworth (May 30 2018 at 17:56):

that might be true in this case, but i think knowing how to write a tactic is a useful and core lean skill. Even if you don't write tactics, you should understand how they work so you can understand why they fail

Andrew Ashworth (May 30 2018 at 17:57):

obviously there is chapter 8 in programming in lean. now if you don't want to write anything complicated, the way forward is to browse through how the tactics are written in core lean, starting with the most basic ones like intro.

Andrew Ashworth (May 30 2018 at 17:58):

(this is all on my to-do list as well, haha)

Andrew Ashworth (May 30 2018 at 17:59):

for references there is John Harrison's "Practical Logic and Automated Reasoning", Chlipala's "Certified Programming with Dependent Types", although in Coq, is handy

Andrew Ashworth (May 30 2018 at 18:00):

for some applications I have "Term Rewriting and All That", "Decision Procedures: An Algorithmic Point of View", "Modern Computer Algebra"

Andrew Ashworth (May 30 2018 at 18:04):

All the way at the bottom of my very sad to-do list is: "learn Isabelle and study sledgehammer and nitpick" (some other popular and useful tactics...)

Andrew Ashworth (May 30 2018 at 18:05):

since i only make progress with Lean on the weekends, I'll see you guys in a few years :)

Johan Commelin (May 30 2018 at 18:09):

But the intro tactic is written in C++, right? At least I found https://github.com/leanprover/lean/tree/dac6eec55661d3a2dab56859ffc05aef1aabb185/src/library/tactic, and it contains a lot of cpp files.

Andrew Ashworth (May 30 2018 at 18:11):

try library/init/meta/interactive.lean

meta def intro : parse ident_?  tactic unit
| none     := intro1 >> skip
| (some h) := tactic.intro h >> skip

Johan Commelin (May 30 2018 at 18:13):

So what is the relation between this lean-file and the cpp-files that I found?

Simon Hudon (May 30 2018 at 18:15):

The tactics that you found are declared in Lean as constants:

meta constant intro_core    : name → tactic expr
meta constant intron        : nat → tactic unit

That is, they do not have Lean definitions and Lean simply executes the C++ implementation when they are called.

Kevin Buzzard (May 30 2018 at 18:21):

Dumb question:

Kevin Buzzard (May 30 2018 at 18:22):

what's the quickest way to generate a complete "blank" construction of a comm_ring

Kevin Buzzard (May 30 2018 at 18:22):

I want

Kevin Buzzard (May 30 2018 at 18:22):

{mul := _,

Kevin Buzzard (May 30 2018 at 18:22):

mul_assoc := _,

Kevin Buzzard (May 30 2018 at 18:23):

etc etc

Sebastian Ullrich (May 30 2018 at 18:23):

{..}

Simon Hudon (May 30 2018 at 18:24):

You should look into pexpr.mk_structure_instance

Kevin Buzzard (May 30 2018 at 18:39):

Possibly first stupid question of many

Kevin Buzzard (May 30 2018 at 18:39):

instance semigroup [ i, semigroup $ f i] : semigroup (Π i : I, f i) :=
{ mul := begin intros, sorry end,
mul_assoc := sorry
}

Kevin Buzzard (May 30 2018 at 18:39):

I am just trying to play with structures to see how far I can get in tactic mode

Kevin Buzzard (May 30 2018 at 18:40):

but Lean doesn't like that instance

Kevin Buzzard (May 30 2018 at 18:40):

type mismatch at field 'mul_assoc'
  sorry
has type
  ∀ (a b c : Π (i : I), f i), ?m_1 (?m_1 a b) c = ?m_1 a (?m_1 b c)
but is expected to have type
  ∀ (a b c : Π (i : I), f i), a * b * c = a * (b * c)

Kevin Buzzard (May 30 2018 at 18:40):

@Sebastian Ullrich thanks -- that comment helped!

Kevin Buzzard (May 30 2018 at 18:40):

I'm still stuck though

Kevin Buzzard (May 30 2018 at 18:41):

fixed it

Kevin Buzzard (May 30 2018 at 18:41):

instance semigroup [ i, semigroup $ f i] : semigroup (Π i : I, f i) :=
{
mul_assoc := λ a b c,sorry,
mul := begin intros, sorry end,
}

Kevin Buzzard (May 30 2018 at 18:41):

I think Mario once explained to me what was going on there but I still find it confusing

Kevin Buzzard (May 30 2018 at 18:54):

I am experimenting with algebra.pi_instances

Kevin Buzzard (May 30 2018 at 18:54):

I kind of suspect that Kenny will know all the answers to my questions

Kevin Buzzard (May 30 2018 at 18:55):

@Kenny Lau what's your golf proof of instance comm_ring [∀ i, comm_ring $ f i] : comm_ring (Π i : I, f i)?

Kevin Buzzard (May 30 2018 at 18:56):

Product of commutative rings is a ring.

Kevin Buzzard (May 30 2018 at 18:56):

Do you have to write as many lines as there are axioms (plus a few more lines on top)?

Kevin Buzzard (May 30 2018 at 18:57):

Or can you do tricks -- but you can't use Simon's tactic, just stuff like simp

Kevin Buzzard (May 30 2018 at 18:57):

you can write tools

Kevin Buzzard (May 30 2018 at 18:57):

but in tactic mode, not new tactics

Kenny Lau (May 30 2018 at 19:23):

instance pi.comm_ring {I : Type*} {f : I  Type*} [ i, comm_ring $ f i] : comm_ring (Π i : I, f i) :=
by refine
{ add := λ x y i, x i + y i,
  zero := λ i, 0,
  neg := λ x i, -x i,
  mul := λ x y i, x i * y i,
  one := λ i, 1,
  .. };
{ intros, funext,
  { apply add_assoc <|> apply add_zero <|> apply zero_add
    <|> apply add_left_neg <|> apply add_comm
    <|> apply mul_assoc <|> apply mul_one <|> apply one_mul
    <|> apply left_distrib <|> apply right_distrib
    <|> apply mul_comm } }

Kevin Buzzard (May 30 2018 at 19:36):

Kenny I want to play with the add/zero/neg etc part of your code

Kevin Buzzard (May 30 2018 at 19:36):

but if I try this

Kevin Buzzard (May 30 2018 at 19:36):

instance pi.comm_ring {I : Type*} {f : I  Type*} [ i, comm_ring $ f i] : comm_ring (Π i : I, f i) :=
by refine
{ add := begin intros,sorry,end,-- λ x y i, x i + y i,
  zero := λ i, 0,
  neg := λ x i, -x i,
  mul := λ x y i, x i * y i,
  one := λ i, 1,
  .. };
{ intros, funext,
  { apply add_assoc <|> apply add_zero <|> apply zero_add
    <|> apply add_left_neg <|> apply add_comm
    <|> apply mul_assoc <|> apply mul_one <|> apply one_mul
    <|> apply left_distrib <|> apply right_distrib
    <|> apply mul_comm } }

Kenny Lau (May 30 2018 at 19:36):

how do you want to play with them?

Kevin Buzzard (May 30 2018 at 19:37):

then there's no definition of add so your tactic doesn't finish the job and the errors from this for some reason stop Lean from processing add

Kenny Lau (May 30 2018 at 19:37):

what do you want to change it to?

Kevin Buzzard (May 30 2018 at 19:37):

I want to change it into a begin end tactic

Kevin Buzzard (May 30 2018 at 19:38):

of the form "intros,funext,apply has_add.add end"

Kenny Lau (May 30 2018 at 19:38):

trust the force, Luke

Kevin Buzzard (May 30 2018 at 19:39):

Can you write a tactic which does add,zero,neg,mul and one?

Kenny Lau (May 30 2018 at 19:39):

not really

Kevin Buzzard (May 30 2018 at 19:39):

In every case it's "deduce it from the factors"

Mario Carneiro (May 30 2018 at 20:36):

I'm not clear on why we're rehashing this. You are rediscovering Simon's tactic

Kevin Buzzard (May 30 2018 at 20:42):

namespace pi
variable {I : Type}     -- The indexing type
variable {f : I  Type} -- The family of types already equiped with instances

class notation_crazy_structure_that_someone_else_wrote (α : Type) extends has_add α,
has_mul α, has_zero α, has_one α, has_neg α, has_le α :=
(a : α)
(H : a + a * 0  -1)

instance can_a_tactic_prove_me [ i, notation_crazy_structure_that_someone_else_wrote $ f i] :
notation_crazy_structure_that_someone_else_wrote (Π i : I, f i) := sorry

Kevin Buzzard (May 30 2018 at 20:42):

I'm trying to learn it

Kevin Buzzard (May 30 2018 at 20:44):

I can't prove that with pi_instance

Kevin Buzzard (May 30 2018 at 20:45):

I am hoping I can just have a proof of the form "by canonical"

Kevin Buzzard (May 30 2018 at 20:45):

I have to learn it because I can't keep pestering Simon every time I want it to do a bit more

Kevin Buzzard (May 30 2018 at 20:48):

no extra inputs or anything

Kevin Buzzard (May 30 2018 at 20:49):

because isn't it true that all that structure just transfers over completely canonically?

Kevin Buzzard (May 30 2018 at 20:50):

@Simon Hudon can pi_instance do this without being fed any extra information whatsoever?

Kevin Buzzard (May 30 2018 at 20:51):

Lean needs to get better at doing stuff which mathematicians find trivial

Simon Hudon (May 30 2018 at 20:52):

Do what specifically?

Simon Hudon (May 30 2018 at 20:52):

(deleted)

Kevin Buzzard (May 30 2018 at 20:53):

construct the instance above called can_a_tactic_prove_me

Kevin Buzzard (May 30 2018 at 20:54):

Is it possible to write a tactic which proves a goal like that without any extra prodding?

Simon Hudon (May 30 2018 at 20:54):

I think so.

Kevin Buzzard (May 30 2018 at 20:54):

By generalising your pi_instance tactic?

Simon Hudon (May 30 2018 at 20:56):

I'm working on a set of tactics to replace pi_instance. It would be the dual of cases / case which I call refine_struct/ field / apply_field. Basically, you write refine_struct { .. } ; intro ; apply_field. Maybe you'd need a bit more but you would have a generic way of referring to the field that you're looking into

Kevin Buzzard (May 30 2018 at 20:58):

oh wow!

Simon Hudon (May 30 2018 at 20:58):

I've been procrastinating with writing my dissertation and working but I should get back to it

Kevin Buzzard (May 30 2018 at 20:59):

Yes that's exactly the sort of conclusion I was coming to (that's why I was asking about ..). I wanted to do begin refine { .. },... but was having trouble with it

Kevin Buzzard (May 30 2018 at 20:59):

Well can I write these tactics somehow?

Kevin Buzzard (May 30 2018 at 20:59):

Or Kenny when he's finished doing my project?

Simon Hudon (May 30 2018 at 21:01):

It is actually some pretty tricky stuff so it would be easier for me to just do it than to explain how to do it. Although, I'd like to also write a tutorial about it

Kevin Buzzard (May 30 2018 at 21:02):

Darn it I need a route into this stuff

Simon Hudon (May 30 2018 at 21:03):

In the mean time, I have a goodie coming up: a tactic that asserts that subtractions have non-negative results (they don't hit the floor of natural numbers) and a tactic that assert that all divisors are non-null

Kevin Buzzard (May 30 2018 at 21:03):

I need to find a tactic which I can write and is somehow distantly related to what I want to be able to do with tactics

Kevin Buzzard (May 30 2018 at 21:04):

subtractions -- Patrick will be over the moon!

Simon Hudon (May 30 2018 at 21:06):

If you want, I can show you my subtraction tactic and let you figure out the version for division

Kevin Buzzard (May 30 2018 at 21:07):

I could have a look!

Kevin Buzzard (May 30 2018 at 21:07):

Somehow it's the canonical stuff that I'm interested in though

Simon Hudon (May 30 2018 at 21:08):

What do you mean by canonical?

Simon Hudon (May 30 2018 at 21:25):

Feel free to try your hand on https://gist.github.com/cipher1024/72af1694ce395d7162bab1a72c1f9c56

Patrick Massot (May 31 2018 at 07:09):

Thanks Simon! I'll have a very close look at that (but probably not today :disappointed: )


Last updated: Dec 20 2023 at 11:08 UTC