Zulip Chat Archive

Stream: maths

Topic: McCune's axiom


Patrick Massot (Jul 21 2021 at 16:11):

I'm typing lecture notes on basic algebra and I wanted to warn my readers that going too far with axiom optimization can lead to madness. I'm trying to quote one example of a single-axiom definition of groups, and I wanted to see whether there was anyway to write a proof there (I do have some masochistic students). Most papers on this topic seem to simply quote some dead specialized software, but this paper has something that claims to be a proof on Page 10. Is anyone able to decipher that page? This should be pretty easy to formalize if it is true (we could even have that in the archive folder of mathlib).

Kevin Buzzard (Jul 21 2021 at 16:31):

that looks like a fun project but I bet that the easiest way to do it is to actually fire up some of that ATP software and let it do it itself.

Patrick Massot (Jul 21 2021 at 16:33):

All this stuff was found by an ATP... which then bit-rot. And all those papers replace most proofs with "the reader should fire up our ATP".

Kevin Buzzard (Jul 21 2021 at 16:35):

import tactic

variables (G : Type)

example [group G] (x y z u : G) :
  x * (y * (((z * z⁻¹) * (u * y)⁻¹ * x))⁻¹) = u :=
  by group -- fails

I failed to do the easy way :-)

Kevin Buzzard (Jul 21 2021 at 16:35):

There are about 10 rewrite lemmas due to Knuth and Bendix which are supposed to solve that problem, right?

Patrick Massot (Jul 21 2021 at 16:35):

Hey, this is not meant to fail.

Kevin Buzzard (Jul 21 2021 at 16:35):

then maybe I made a typo

Kevin Buzzard (Jul 21 2021 at 16:36):

I did!

Patrick Massot (Jul 21 2021 at 16:36):

I did it on paper.

Kevin Buzzard (Jul 21 2021 at 16:36):

import tactic

variables (G : Type)

example [group G] (x y z u : G) :
  (x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹) = u :=
  by group

Kevin Buzzard (Jul 21 2021 at 16:36):

the other direction is left as an exercise

Patrick Massot (Jul 21 2021 at 16:36):

Indeed that's not the correct relation

Patrick Massot (Jul 21 2021 at 16:37):

import tactic

variables (G : Type)

example [group G] (x y z u : G) :
  x * (y * (((z * z⁻¹) * (u * y)⁻¹ * x)))⁻¹ = u :=
  by group -- works!

Patrick Massot (Jul 21 2021 at 16:38):

I'm late but my super crappy internet connection is showing me messages late.

Kevin Buzzard (Jul 21 2021 at 16:38):

import tactic

variables (G : Type)

example [group G] (x y z u : G) :
  (x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹) = u :=
  by group

example [has_mul G] [has_inv G] (h :  x y z u : G, (x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹) = u ) :
  group G := sorry

Mario Carneiro (Jul 21 2021 at 16:38):

Here's a setup. I failed on the first paramodulation step:

import algebra.group.basic
noncomputable theory

class mccune_group (α : Type*) extends has_mul α, has_inv α :=
(nonemp : nonempty α)
(mccune (x y z u : α) : x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹ = u)

namespace mccune_group
variables {α : Type*} [mccune_group α] (x y z u w v : α)
lemma l5 : x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹ = u := mccune _ _ _ _
lemma l7 : x * ((((y * y⁻¹) * (z * u)⁻¹) * (v * v⁻¹)) * (z * x))⁻¹ = u :=
begin
  have := l5 x y z u,
  have := l5 (v * v⁻¹) u y z,
  -- ???
  sorry
end

instance : has_one α := let x := classical.choice (@nonemp α _) in x * x⁻¹
lemma mul_assoc : (x * y) * z = x * (y * z) := sorry
lemma one_mul : 1 * x = x := sorry
lemma mul_one : x * 1 = x := sorry
lemma mul_left_inv : x⁻¹ * x = 1 := sorry

instance : group α :=
{ mul := (*), mul_assoc := mul_assoc,
  one := 1, one_mul := one_mul, mul_one := mul_one,
  inv := has_inv.inv, mul_left_inv := mul_left_inv }

Patrick Massot (Jul 21 2021 at 16:38):

Beware I think the other direction has an implicit assumption that GG is not empty.

Kevin Buzzard (Jul 21 2021 at 16:39):

for sure!

Eric Rodriguez (Jul 21 2021 at 16:39):

i thought all G had to have a 1

Eric Rodriguez (Jul 21 2021 at 16:39):

didn't know the rng debate went past ring theory

Kevin Buzzard (Jul 21 2021 at 16:39):

all groups have a 1, but we're trying to prove something is a group

Patrick Massot (Jul 21 2021 at 16:39):

And letting the other direction as an exercise is what I intend to do, but I'd like to have the answer somewhere.

Patrick Massot (Jul 21 2021 at 16:40):

Eric, one of the steps in the proof is meant to be that xy,xx1=yy1\forall x y, xx^{-1} = yy^{-1} and then, assuming GG is not empty, this common value is defined to be 11.

Kevin Buzzard (Jul 21 2021 at 16:42):

@Mario Carneiro if only we could see 6!

Mario Carneiro (Jul 21 2021 at 16:43):

The proof says that 7 is obtained by paramodulation of 5 into 5. I challenge folks to figure out what that means

Kevin Buzzard (Jul 21 2021 at 16:43):

I decided it meant substitution of 5 into 5

Patrick Massot (Jul 21 2021 at 16:44):

Yes, this is where I arrived and got stuck.

Kevin Buzzard (Jul 21 2021 at 16:44):

Perhaps the author knew that any sane person would have stopped reading by this line so he could write what he liked

Mario Carneiro (Jul 21 2021 at 16:47):

If you have \all x, l x = r x and \all y, P y, then paramodulation of the first into the second should mean instantiating both to l a = r a and P b, such that l a is a subterm of P b, i.e. P b = Q (l a), resulting in the theorem Q (r a). The non obvious parts are what a, b and Q should be chosen to be such that Q (r a) is the theorem you want

Kevin Buzzard (Jul 21 2021 at 16:47):

(5) has 7 variables on the LHS, and (7) has 9, but there's no way you can rewrite 5 into itself to make the number of variables only go up by 2

Kevin Buzzard (Jul 21 2021 at 16:49):

oh I see, you can first make the number go up by 8 and then down by 6

Kevin Buzzard (Jul 21 2021 at 16:49):

and the "up by 8" equation is missing line 6

Mario Carneiro (Jul 21 2021 at 16:50):

Yeah when I first heard of the McCune theorem I thought that the first few steps must be gigantic because nothing cancels for a while

Patrick Massot (Jul 21 2021 at 16:51):

I can feel I only need to wait a little longer and Mario and Kevin will do it for me. I love this place.

Kevin Buzzard (Jul 21 2021 at 16:52):

I hope it gets easier than this first line!

Mario Carneiro (Jul 21 2021 at 16:52):

maybe we will need OTTER's help after all

Mario Carneiro (Jul 21 2021 at 16:53):

plot twist: OTTER was buggy and no one noticed

Patrick Massot (Jul 21 2021 at 16:53):

Good luck resurrecting OTTER. I think you'll do it faster by hand + Lean.

Eric Rodriguez (Jul 21 2021 at 16:54):

Mario, I'm taking it that here that our ∀ y, P y is rfl?

Kevin Buzzard (Jul 21 2021 at 16:54):

surely we can just ask prover9 to do this

Patrick Massot (Jul 21 2021 at 16:55):

Good luck resurrecting prover9 then.

Kevin Buzzard (Jul 21 2021 at 16:55):

this is also dead?? These guys must use something?

Patrick Massot (Jul 21 2021 at 16:57):

It was last updated in 2009, and it doesn't run here, even on a computer that still has python2 installed.

Patrick Massot (Jul 21 2021 at 16:57):

Maybe McCune died, or he got bored with this kind of research.

Mario Carneiro (Jul 21 2021 at 16:57):

Eric Rodriguez said:

Mario, I'm taking it that here that our ∀ y, P y is rfl?

No, \all x, l x = r x and \all y, P y are two previously proven steps, specified as inputs. In the case of step 7 it is using step 5 for both

Mario Carneiro (Jul 21 2021 at 16:58):

P y is an equality too, you are substituting into both sides of it (but the fact it's an equality doesn't matter much since you are only doing equalish stuff for the other lemma)

Kevin Buzzard (Jul 21 2021 at 16:58):

There is a chance that step 6 has length 100, right?

Mario Carneiro (Jul 21 2021 at 16:59):

I think step 6 turned out not to be useful

Mario Carneiro (Jul 21 2021 at 16:59):

the numbering is gapped because the theorem was cleaned up after the fact

Kevin Buzzard (Jul 21 2021 at 17:02):

...
gcc  -O -Wall -lm -o prover9 prover9.o index_lits.o forward_subsume.o demodulate.o pred_elim.o unfold.o semantics.o giv_select.o white_black.o actions.o search.o utilities.o provers.o foffer.o ../ladr/libladr.a
/usr/bin/ld: search.o: in function `search':
search.c:(.text+0x6745): undefined reference to `round'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:66: prover9] Error 1
make[1]: Leaving directory '/home/buzzard/Downloads/crap/LADR-2009-11A/provers.src'
make: *** [Makefile:7: all] Error 2
buzzard@bob:~/Downloads/crap/LADR-2009-11A$

Any ideas?

Patrick Massot (Jul 21 2021 at 17:03):

My bet is on Mario finishing the proof before Kevin can compile that stuff.

Kevin Buzzard (Jul 21 2021 at 17:06):

prover9.png

Kevin Buzzard (Jul 21 2021 at 17:06):

now how does it work?

Kevin Buzzard (Jul 21 2021 at 17:06):

Patrick your mistake was not using Ubuntu, with its built in python2

Eric Rodriguez (Jul 21 2021 at 17:07):

image.png

Patrick Massot (Jul 21 2021 at 17:07):

Mario, I'm very disappointed.

Kevin Buzzard (Jul 21 2021 at 17:12):

How long is it supposed to take to find this two-line proof?

Eric Rodriguez (Jul 21 2021 at 17:13):

can't be that slow on modern computers

Patrick Massot (Jul 21 2021 at 17:13):

The paper spends a lot of pages explaining how to tweak the parameters of the previous software.

Eric Rodriguez (Jul 21 2021 at 17:14):

image.png

I am way too young

Kevin Buzzard (Jul 21 2021 at 17:15):

do you know what a megabyte is? We used to have them in the old days

Patrick Massot (Jul 21 2021 at 17:15):

I used to have a 486 computer :older_man:

Eric Rodriguez (Jul 21 2021 at 17:15):

is it that "MB" thing that leanproject get-cache is on about ;b

Kevin Buzzard (Jul 21 2021 at 17:16):

I used to have a 6502 computer :P

Eric Rodriguez (Jul 21 2021 at 17:17):

BBC Micro? My ICT professor loved those things, he taught us programming in its BASIC dialect actually

Eric Rodriguez (Jul 21 2021 at 17:17):

he brought one in one day and I blew one of the caps on it...

Kevin Buzzard (Jul 21 2021 at 17:18):

The one before -- an Acorn Atom, with a more primitive BASIC. Back to the point, prover9 is supposed to be giving up after 60 seconds but it's just sitting there pulsating and failing to solve the goal

Patrick Massot (Jul 21 2021 at 17:20):

I wonder whether McCune originally included all steps and then the journal editor asked for a shorten version.

Mario Carneiro (Jul 21 2021 at 17:20):

Patrick Massot said:

Mario, I'm very disappointed.

Don't count your chickens before they hatch; I haven't seen a proof of l7 yet

Kevin Buzzard (Jul 21 2021 at 17:20):

"remove 50% of steps because all arguments here are clearly trivial"

Patrick Massot (Jul 21 2021 at 17:21):

Maybe there was a page number limit from the beginning, as in computer science proceedings.

Kevin Buzzard (Jul 21 2021 at 17:35):

1 x * ((((y * y') * (z * u)') * (w * w')) * (z * x))' = u # label(non_clause) # label(goal).  [goal].
2 x * (y * (((z * z') * (u * y)') * x))' = u.  [assumption].
3 c1 * ((((c2 * c2') * (c3 * c4)') * (c5 * c5')) * (c3 * c1))' != c4.  [deny(1)].
5 x * ((((y * y') * (z * u)') * (w * w')) * (z * x))' = u.  [para(2(a,1),2(a,1,2,1,2,1))].
6 $F.  [resolve(5,a,3,a)].

Kevin Buzzard (Jul 21 2021 at 17:36):

My mistake was that I used \-1 for inverse, and the terminal was full of "hey this is not ASCII!" errors

Kevin Buzzard (Jul 21 2021 at 17:38):

lol does this help?

Eric Rodriguez (Jul 21 2021 at 17:38):

I also got some length otter output: https://gist.github.com/ericrbg/199c0679656f7a394b42dc0cf6a11fe4

Kevin Buzzard (Jul 21 2021 at 17:39):

I think the only new information is that the hint 5 -> 5 has been expanded to para(2(a,1),2(a,1,2,1,2,1))

Kevin Buzzard (Jul 21 2021 at 17:40):

well Eric's answer is certainly more information

Kevin Buzzard (Jul 21 2021 at 17:41):

half of me is wondering whether these so-called "provers" just print out junk randomly, on the basis that humans are never going to actually check this stuff

Eric Rodriguez (Jul 21 2021 at 17:41):

yeah I have absolutely no clue what it did if I'm honest

Kevin Buzzard (Jul 21 2021 at 17:41):

https://www.karlin.mff.cuni.cz/~stanovsk/math/bruck_wm.pdf is my favourite computer proof

Eric Rodriguez (Jul 21 2021 at 17:42):

half of the time I spent was turning the damn thing out of infix to prefix form

Eric Rodriguez (Jul 21 2021 at 17:42):

Kevin Buzzard said:

https://www.karlin.mff.cuni.cz/~stanovsk/math/bruck_wm.pdf is my favourite computer proof

what is that trying to prove?!

Kevin Buzzard (Jul 21 2021 at 17:43):

Every Bruck loop with abelian inner mapping group has nilpotency class at most 2. The actual statement being proved is on the first page of the 1000 page pdf

Eric Wieser (Jul 21 2021 at 17:44):

Eric Rodriguez said:

half of the time I spent was turning the damn thing out of infix to prefix form

notation `f(`x`,`y`)` := id (x * y)
notation `h(`x`)` := id (x⁻¹)

helps with that

Eric Wieser (Jul 21 2021 at 17:44):

Then you can use dsimp to throw away the awful notation

Kevin Buzzard (Jul 21 2021 at 17:48):

From the manual: "para(47(a,1),28(a,1,2,2,1)) -- paramodulate from the clause 47 into clause 28 at the positions shown. "

Bhavik Mehta (Jul 21 2021 at 17:48):

import tactic

class mccune_group (α : Type*) extends has_mul α, has_inv α :=
(mccune (x y z u : α) : x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹ = u)

namespace mccune_group
variables {α : Type*} [mccune_group α] (x y z u w v : α)

lemma l5 : x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹ = u := mccune _ _ _ _

lemma l7 : x * ((((y * y⁻¹) * (z * u)⁻¹) * (v * v⁻¹)) * (z * x))⁻¹ = u :=
begin
  set q := ((y * y⁻¹) * (z * u)⁻¹) * (v * v⁻¹),
  rw l5 (v * v⁻¹) u y z,
  rw l5 x q v u,
end

end mccune_group

I haven't followed this thread but here's the first line

Kevin Buzzard (Jul 21 2021 at 17:48):

Discord FTW

Bhavik Mehta (Jul 21 2021 at 17:49):

Exactly as claimed, it is just paramodulation

Eric Wieser (Jul 21 2021 at 17:50):

Why does it fail without the set line?

Kevin Buzzard (Jul 21 2021 at 17:50):

I got it first, the proof is just para(2(a,1),2(a,1,2,1,2,1))

Eric Wieser (Jul 21 2021 at 17:50):

(deleted)

Bhavik Mehta (Jul 21 2021 at 17:51):

Eric Wieser said:

Why does it fail without the set line?

I'm sure it's possible without that, with some more targeted rewrites, but it does the job :)

Kevin Buzzard (Jul 21 2021 at 17:53):

Next level:

lemma l9 : (x * ((y * (z * z⁻¹)) * (u * x))⁻¹) = (((v * v⁻¹) *(y * u)⁻¹) * (w * w⁻¹)) :=
begin
  sorry
end

Kevin Buzzard (Jul 21 2021 at 17:53):

hint: use l5 and l7

Eric Wieser (Jul 21 2021 at 17:53):

A shorter version of l7 requiring less intuition:

lemma l7 : x * ((((y * y⁻¹) * (z * u)⁻¹) * (v * v⁻¹)) * (z * x))⁻¹ = u :=
begin
  convert l5 _ _ _ _,
  rw l5,
end

Kevin Buzzard (Jul 21 2021 at 17:54):

I had been trying with convert before I decided to go for the prover9 option (it was on my job list to play around with an ATP at some point in my life)

Eric Wieser (Jul 21 2021 at 17:54):

lemma l9 : (x * ((y * (z * z⁻¹)) * (u * x))⁻¹) = (((v * v⁻¹) *(y * u)⁻¹) * (w * w⁻¹)) :=
begin
  convert l7 _ _ _ _ _,
  rw l5,
end

Bhavik Mehta (Jul 21 2021 at 17:55):

You beat me to it by a second, Eric! :grinning:

Eric Wieser (Jul 21 2021 at 17:55):

So A -> B means convert B, rw A?

Eric Rodriguez (Jul 21 2021 at 17:55):

Kevin Buzzard said:

hint: use l5 and l7

this is most textbook hints summed up

Bhavik Mehta (Jul 21 2021 at 17:55):

I think a more faithful translation might be rewrite with the inverse of A at a specific place so that B applies

Bhavik Mehta (Jul 21 2021 at 17:56):

But pragmatically it seems like convert, rw does the trick

Eric Wieser (Jul 21 2021 at 17:56):

If my claim is true this should get us all the way to l15, and then we have to know what : means

Bhavik Mehta (Jul 21 2021 at 17:57):

: supposedly means simplify using that axiom

Kevin Buzzard (Jul 21 2021 at 17:57):

lemma l10 : (((y * y⁻¹)*(((z*z⁻¹)*(u*x)⁻¹)*u)⁻¹)*(v*v⁻¹))=x :=
begin
  sorry
end

Kevin Buzzard (Jul 21 2021 at 17:57):

hint: 7 -> 9

Eric Wieser (Jul 21 2021 at 17:57):

Damn

Bhavik Mehta (Jul 21 2021 at 17:58):

Eric's magic incantation doesn't do it :(

Eric Wieser (Jul 21 2021 at 17:59):

lemma l10 : (((y * y⁻¹)*(((z*z⁻¹)*(u*x)⁻¹)*u)⁻¹)*(v*v⁻¹))=x :=
begin
  rw l9,
  apply l7,
  exact x,
  exact z,
end

Eric Wieser (Jul 21 2021 at 17:59):

I don't know where those exacts came from, since it seems they have no requirements?

Yaël Dillies (Jul 21 2021 at 18:01):

What does refine spit out?

Eric Rodriguez (Jul 21 2021 at 18:02):

lemma l12 : (((x * x⁻¹)*y⁻¹⁻¹)*(z*z⁻¹))=y :=
begin
  convert l10,
  rw l10,
  exact x
end

Bhavik Mehta (Jul 21 2021 at 18:04):

Hmm that doesn't seem to work for me...

Kevin Buzzard (Jul 21 2021 at 18:05):

I think Eric R must have implicit variables

Bhavik Mehta (Jul 21 2021 at 18:05):

lemma l14 : ((x*x⁻¹)*(y*z)⁻¹)=((u*u⁻¹)*(y*z)⁻¹) := -- [10 -> 5]
begin
  convert l5 _ _ _ _,
  rw l10,
  exact x,
end

Eric Rodriguez (Jul 21 2021 at 18:05):

oh I made implicits everywhere so just stick some _ s

Kevin Buzzard (Jul 21 2021 at 18:06):

Eric we're live streaming on the discord

Bhavik Mehta (Jul 21 2021 at 18:06):

lemma l15 : ((x*x⁻¹)*y⁻¹) = ((z*z⁻¹)*y⁻¹) := -- [12 -> 14 : 12]
begin
  convert l14 _ _ _ _,
  rw l12,
  exact x,
  exact z,
  rw l12,
end

Eric Wieser (Jul 21 2021 at 18:08):

Do any of these exacts matter?

Bhavik Mehta (Jul 21 2021 at 18:08):

Their values don't, but they are important

Bhavik Mehta (Jul 21 2021 at 18:08):

In l15 after the first line it just wants that y is a product of two things

Bhavik Mehta (Jul 21 2021 at 18:08):

and here l12 says that it is, and it doesn't matter what the two things are; they just need to be given

Patrick Massot (Jul 21 2021 at 18:10):

I love that creative use of convert.

Kevin Buzzard (Jul 21 2021 at 18:11):

Yes, it reminded me of that comment that Lean was supposed to be bridging the gap between ATP and ITP

Patrick Massot (Jul 21 2021 at 18:12):

Of course we know that unification is a huge crucial piece of the puzzle. But we're not used it seeing it used in such a spectacular way.

Patrick Massot (Jul 21 2021 at 18:16):

Let me ping @Simon Hudon who wrote convert (at least the original implementation, see this thread).

Bhavik Mehta (Jul 21 2021 at 18:17):

lemma l17 : u * u⁻¹ = v * v⁻¹ := -- [15 → 5 : 5]
begin
  rw l5 u u⁻¹ u (v * v⁻¹),
  rw l15 v _,
  rw l5,
end

Bhavik Mehta (Jul 21 2021 at 18:19):

lemma l19 : x * x⁻¹ = ((y * y⁻¹) * (z * z⁻¹)⁻¹) := -- [17 → 15]
begin
  rw [l15],
  exact l17 _ _,
end

I'll stop with the constant updates, but I'm working on this in the discord with Kevin

Eric Wieser (Jul 21 2021 at 18:32):

How many lines are there total?

Bhavik Mehta (Jul 21 2021 at 18:33):

Getting past 100, but I'm also adding notations and simp lemmas to make the proofs easier

Eric Wieser (Jul 21 2021 at 18:34):

(I mean in the LaTeX proof not lines of lean code, to be clear)

Eric Rodriguez (Jul 21 2021 at 18:39):

is the plan to PR this to mathlib?

Eric Wieser (Jul 21 2021 at 18:40):

It probably would be nice in archive if it doesn't make it to src

Eric Wieser (Jul 21 2021 at 18:40):

(oh, I see Patrick already suggested archive at the start of the thread)

Simon Hudon (Jul 21 2021 at 18:46):

@Patrick Massot thanks for pinging me! It is indeed a pretty cool use of convert. I wonder if we could avoid all those superfluous _. We could make it more like apply and just automatically insert all the _ it will take

Eric Wieser (Jul 21 2021 at 19:22):

Yes, my main criticism of convert is that if you don't give enough arguments you get a nonsense goal state that doesn't even typecheck like a + b = b + a = ∀ c, c + b = b + a

Bhavik Mehta (Jul 21 2021 at 19:25):

Well technically it does typecheck, they're both Props

Eric Wieser (Jul 21 2021 at 19:53):

Ah you're right, the case I'm thinking of has another =

Kevin Buzzard (Jul 21 2021 at 20:48):

import tactic

class mccune_group (α : Type*) extends has_mul α, has_inv α :=
(mccune (x y z u : α) : x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹ = u)

namespace mccune_group
variables {α : Type*} [mccune_group α] (x y z u w v : α)

lemma l5 : x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹ = u := mccune _ _ _ _

lemma l7 : x * ((((y * y⁻¹) * (z * u)⁻¹) * (v * v⁻¹)) * (z * x))⁻¹ = u :=
begin
  convert l5 _ _ _ _,
  rw l5,
end

lemma l9 : (x * ((y * (z * z⁻¹)) * (u * x))⁻¹) = (((v * v⁻¹) *(y * u)⁻¹) * (w * w⁻¹)) :=
begin
  convert l7 _ _ _ _ _,
  rw l5,
end

lemma l10 : (((y * y⁻¹)*(((z*z⁻¹)*(u*x)⁻¹)*u)⁻¹)*(v*v⁻¹))=x :=
begin
  rw l9,
  apply l7,
  exact x, exact x,
end

lemma l12 : (((x*x⁻¹)*y⁻¹⁻¹)*(z*z⁻¹)) = y := -- [10 -> 10]
begin
  convert l10 _ _ _ _ _,
  rw l10,
  exact x
end

lemma l14 : ((x*x⁻¹)*(y*z)⁻¹)=((u*u⁻¹)*(y*z)⁻¹) := -- [10 -> 5]
begin
    convert l5 _ _ _ _,
  rw l10,
  exact x,
end

lemma l15 : ((x*x⁻¹)*y⁻¹) = ((z*z⁻¹)*y⁻¹) := -- [12 -> 14 : 12]
begin
    convert l14 _ _ _ _,
  rw l12,
  exact x,
  exact z,
  rw l12,
end

lemma l17 : u * u⁻¹ = v * v⁻¹ := -- [15 → 5 : 5]
begin
  rw l5 u u⁻¹ u (v * v⁻¹),
  rw l15 v _,
  rw l5,
end

lemma l19 : x * x⁻¹ = ((y * y⁻¹) * (z * z⁻¹)⁻¹) := -- [17 → 15]
begin
  rw [l15],
  exact l17 _ _,
end

lemma l20 : (((x * x⁻¹) * ((y * y⁻¹)*z)⁻¹)*(u*u⁻¹)) = z⁻¹ := -- [17 → 10]
begin
  sorry
end

lemma l22 : (x * (y⁻¹ * ((z*z⁻¹)*x))⁻¹) = y := -- [17 → 5]
begin
  sorry
end

lemma l25 : (x*((u*u⁻¹)⁻¹⁻¹*(w*x))⁻¹)=w⁻¹ := -- [19 → 7:20]
sorry

lemma l32 : ((x*x⁻¹)⁻¹*(y⁻¹*(z*z⁻¹))⁻¹) = y := -- [17 → 22]
sorry

lemma l34 : (x⁻¹*((y*y⁻¹)⁻¹⁻¹*(z*z⁻¹))⁻¹)=x⁻¹ := -- [17->25]
sorry

lemma l36 : ((y*y⁻¹)*(x*(z*z⁻¹)⁻¹⁻¹)⁻¹)⁻¹=x := -- [5->25]
sorry

lemma l44 : (x*((y*y⁻¹)⁻¹⁻¹*(z*z⁻¹))⁻¹)=x := -- [36 ->34:36]
sorry

lemma l48 : ((x*x⁻¹)⁻¹⁻¹*(y*y⁻¹))=(z*z⁻¹) := -- [44->17]
sorry

lemma l52 : (x*(y*y⁻¹)⁻¹)=x := -- [52->10:20]
sorry

lemma l57 : ((z*z⁻¹)⁻¹*u)⁻¹⁻¹=u := -- [52->10:20]
sorry

lemma l62 : (x⁻¹*(y*y⁻¹))⁻¹=x⁻¹⁻¹ := --[32->57]
sorry

lemma l65 : (y*((z*z⁻¹)*(x*y)⁻¹))⁻¹=x⁻¹⁻¹ := --[5->57:52]
sorry

lemma l76 : (x*(y*y⁻¹))⁻¹=x⁻¹ := -- [57->62:57]
sorry

lemma l88 : ((x*x⁻¹)⁻¹*y⁻¹⁻¹)=y := -- [65->32]
sorry

lemma l92 : ((u*u⁻¹)*y⁻¹)⁻¹=y := -- [65->20:12,76]
sorry

lemma l116 : (y*(u*u⁻¹))=y := -- 76-32:76,88
sorry

lemma l126 : ((y*z)*z⁻¹)=y := -- 76->5:92
sorry

lemma l201 : (x*y⁻¹⁻¹)=(x*y) := -- 126 -> 126
sorry

lemma l207 : ((x*x⁻¹)*z)=z := -- 19 -> 126:52,201
sorry

lemma l215 : (x*(y*((x*y)⁻¹*u)))=u := -- 5->126:207,201
sorry

lemma l227 : y⁻¹⁻¹ = y := -- [126->36:207,52]
sorry

lemma l229 : (z*x)⁻¹=x⁻¹*z⁻¹ := -- 126->25:227,207
sorry

lemma l239 : (x*((x⁻¹*u)*y))=u*y := -- [126->5:207,229,229,227,227]
sorry

lemma l260 : ((x*y)*z)=(x*(y*z)) := -- [215->215:229,229,229,227,227,239]
sorry

example (α : Type) [h : inhabited α] : group α  mccune_group α :=
{ to_fun := by introI i; exact
  { mul := (*),
    inv := has_inv.inv,
    mccune := by intros; group },
  inv_fun := by introI i; exact
  { mul := (*),
    mul_assoc := l260,
    one := arbitrary α * (arbitrary α)⁻¹,
    one_mul := l207 _,
    mul_one := λ _, l116 _ _,
    npow := sorry,
    npow_zero' := sorry,
    npow_succ' := sorry,
    inv := has_inv.inv,
    div := sorry,
    div_eq_mul_inv := sorry,
    gpow := sorry,
    gpow_zero' := sorry,
    gpow_succ' := sorry,
    gpow_neg' := sorry, -- there should be a constructor which fills in the last 9 sorries
    mul_left_inv := begin sorry end }, -- unfortunately `l17` is mul_right_inv
    left_inv := begin sorry end, -- need "two groups structures on G are equal iff they have the same mul"
    right_inv := begin intro h2, cases h2, simp, sorry end, -- need an ext for mccune_groups
  }

end mccune_group

Kevin Buzzard (Jul 21 2021 at 20:49):

Bhavik is up to l126

Mario Carneiro (Jul 21 2021 at 20:50):

Why didn't I need all that junk in the group constructor here?

Mario Carneiro (Jul 21 2021 at 20:50):

I don't think I'm on a relevantly old mathlib

Kevin Buzzard (Jul 21 2021 at 20:50):

I just used the bottom but one hole-filler

Kevin Buzzard (Jul 21 2021 at 20:52):

oh it's because

(gpow :   G  G := gpow_rec)
(gpow_zero' :  (a : G), gpow 0 a = 1 . try_refl_tac)
(gpow_succ' :
   (n : ) (a : G), gpow (int.of_nat n.succ) a = a * gpow (int.of_nat n) a  . try_refl_tac)
(gpow_neg' :
   (n : ) (a : G), gpow (-[1+ n]) a = (gpow n.succ a) ⁻¹ . try_refl_tac)

they all have default values, which "generate a skeleton for the structure under construction" doesn't ignore.

Mario Carneiro (Jul 21 2021 at 20:52):

you shouldn't need an ext for mccune groups, it's trivial

Mario Carneiro (Jul 21 2021 at 20:52):

cases, cases, refl should work

Kevin Buzzard (Jul 21 2021 at 20:53):

Bhavik's code diverges from this too, I think I'll leave it here and he can post his final answer later when he's cracked 126

Bhavik Mehta (Jul 22 2021 at 04:36):

Pretty mucky:

import tactic

class mccune_group (α : Type*) extends has_mul α, has_inv α, inhabited α :=
(mccune (x y z u : α) : x * (y * (((z * z⁻¹) * (u * y)⁻¹) * x))⁻¹ = u)

namespace mccune_group
variables {α : Type*} [mccune_group α] (x y z u w v : α)

lemma l5 : x * (y * (z * z⁻¹ * (u * y)⁻¹ * x))⁻¹ = u := mccune _ _ _ _

lemma l7 : x * (y * y⁻¹ * (z * u)⁻¹ * (v * v⁻¹) * (z * x))⁻¹ = u :=
by simpa [l5 (v * v⁻¹)] using l5 x (y * y⁻¹ * (z * u)⁻¹ * (v * v⁻¹)) v u

lemma l9 : x * (y * (z * z⁻¹) * (u * x))⁻¹ = v * v⁻¹ * (y * u)⁻¹ * (w * w⁻¹) :=
by simpa [l5 (w * w⁻¹)] using l7 x w u (v * v⁻¹ * (y * u)⁻¹ * (w * w⁻¹)) z

lemma l10 : y * y⁻¹ * (z * z⁻¹ * (u * x)⁻¹ * u)⁻¹ * (v * v⁻¹) = x :=
by simpa [l9 _ _ _ u v y] using l7 x z u x z

lemma l12 : x * x⁻¹ * y⁻¹⁻¹ * (z * z⁻¹) = y :=
by simpa [l10] using l10 y x x (y * y⁻¹ * (y * y⁻¹)⁻¹) z

lemma l14 : (x * x⁻¹) * (y * z)⁻¹ = u * u⁻¹ * (y * z)⁻¹ := -- [10 -> 5]
begin
  convert l5 _ _ _ _,
  rw l10,
  exact x,
end

lemma l15 : (x * x⁻¹) * y⁻¹ = (z * z⁻¹) * y⁻¹ :=
by simpa [l12] using l14 x ((x * x⁻¹) * y⁻¹⁻¹) (z * z⁻¹) z

lemma l17 : u * u⁻¹ = v * v⁻¹ := -- [15 → 5 : 5]
begin
  rw l5 u u⁻¹ u (v * v⁻¹),
  rw l15 v _,
  rw l5,
end

instance : has_one α := default α * (default α)⁻¹

@[simp] lemma l17' : u * u⁻¹ = 1 := l17 _ _

lemma l10' : (1 * ((1 * (u * x)⁻¹) * u)⁻¹) * 1 = x := l10 _ _ _ _ _

lemma l20' : (1 * (1*z)⁻¹)*1 = z⁻¹ :=
begin
  convert l10' _ _,
  rw l17',
  rw l17',
end

lemma l5' : x * (y * ((1 * (u * y)⁻¹) * x))⁻¹ = u := l5 _ _ _ _

lemma l22' : x * (y⁻¹ * (1 * x))⁻¹ = y := -- [17 → 5]
by { convert l5' _ _ y, simp }

lemma l7' : x * (((1 * (z * u)⁻¹) * 1) * (z * x))⁻¹ = u := l7 _ _ _ _ _

lemma l25' : x * (1⁻¹⁻¹ * (w * x))⁻¹ = w⁻¹ := -- [19 → 7:20]
begin
  convert l7' _ _ _,
  rw l17',
  convert (l20' _).symm,
  simp,
end

lemma l32' : 1⁻¹ * (y⁻¹ * 1)⁻¹ = y := -- [17 → 22]
begin
  convert l22' (1 : α)⁻¹ y,
  simp
end

lemma l34' : x⁻¹ * (1⁻¹⁻¹ * 1)⁻¹ = x⁻¹ := by simpa using l25' x⁻¹ x

lemma l36' : (1 * (x * 1⁻¹⁻¹)⁻¹)⁻¹ = x :=
begin
  convert l5' _ _ _,
  rw l25',
  exact x
end

lemma l44' : x * (1⁻¹⁻¹ * 1)⁻¹ = x := by simpa [l36'] using l34' (1 * (x * 1⁻¹⁻¹)⁻¹)
lemma l48' : (1 : α)⁻¹⁻¹ * 1 = 1 := by simpa using (l44' ((1 : α)⁻¹⁻¹ * 1)).symm
lemma l52' : x * 1⁻¹ = x := by simpa [l48'] using l44' x
lemma l57' : (1⁻¹ * u)⁻¹⁻¹ = u := by simpa [l52', l20'] using l10' u 1⁻¹

lemma l62' : (x⁻¹ * 1)⁻¹ = x⁻¹⁻¹ :=
by simpa [l32'] using (l57' (x⁻¹ * 1)⁻¹).symm

lemma l76' : (x * 1)⁻¹ = x⁻¹ := by simpa [l57'] using l62' (1⁻¹ * x)⁻¹

lemma l88' : 1⁻¹ * x⁻¹⁻¹ = x :=
by simpa [l76'] using l32' x

@[simp] lemma l116' : y * 1 = y :=
begin
  have := l88' (y * 1),
  rw l76' at this,
  rw l88' at this,
  exact this.symm
end

@[simp] lemma one_inv_inv : (1 : α)⁻¹⁻¹ = 1 :=
by simpa using l48'

@[simp] lemma one_inv : (1 : α)⁻¹ = 1 :=
by simpa using l88' (1 : α)

lemma l92' : (1 * y⁻¹)⁻¹ = y :=
by simpa using l36' y

lemma l126' : (y * z) * z⁻¹ = y :=
begin
  have := l5' ((1 : α) * (y * z)⁻¹)⁻¹ z y,
  rw l17' at this,
  simpa [l92'] using this,
end

lemma l201 : x * y⁻¹⁻¹ = x * y :=
by simpa [l126' x y] using l126' (x * y) y⁻¹

@[simp] lemma l207' : 1 * z = z :=
by simpa [l201] using l126' z z⁻¹

@[simp] lemma l227 : y⁻¹⁻¹ = y :=
by simpa using l201 1 y

@[simp] lemma inv_mul : x⁻¹ * x = 1 :=
by simpa using l17' x⁻¹

lemma l229 : (z * x)⁻¹ = x⁻¹ * z⁻¹ := -- 126->25:227,207
by simpa [l126'] using (l25' x⁻¹ (z * x)).symm

lemma thingy : x * (x⁻¹ * z) = z := -- [126->5:207,229,229,227,227]
begin
  have := l5' x z⁻¹ z,
  simp only [one_inv, l17', l207'] at this,
  rw [l229, l227] at this,
  exact this,
end

lemma l239 : x * ((x⁻¹ * u) * y) = u * y := -- [126->5:207,229,229,227,227]
by simpa [l229, l126'] using l5' x y⁻¹ (u * y)

lemma l260 : (x * y) * z = x * (y * z) := -- [215->215:229,229,229,227,227,239]
begin
  rw l239 x⁻¹ z y,
  rw thingy,
  simp
end

instance : group α :=
{ mul_assoc := l260,
  one_mul := by simp,
  mul_one := by simp,
  mul_left_inv := λ x, inv_mul _,
  ..(by apply_instance : has_one α),
  ..(by apply_instance : has_mul α),
  ..(by apply_instance : has_inv α) }

end mccune_group

Bhavik Mehta (Jul 22 2021 at 04:37):

For some of the later ones I made new lemmas instead of the ones from the paper because they made more sense to me

Patrick Massot (Jul 22 2021 at 09:28):

Thank you very much for your patience Bhavik. This stuff is pretty fascinating in its own very weird way.

Eric Wieser (Jul 22 2021 at 09:39):

Interesting enough for the archive, right?

Bhavik Mehta (Jul 22 2021 at 15:17):

#8399

Bhavik Mehta (Jul 22 2021 at 17:26):

For fun I did the abelian version too (theorem 2 from the paper Patrick linked):

class mccune_comm_group (α : Type*) extends has_mul α, has_inv α, inhabited α :=
(mccune (x y z : α) : x * y * z * (x * z)⁻¹ = y)

namespace mccune_comm_group
variables {α : Type*} [mccune_comm_group α] (x y z u v w : α)

lemma l10 : x * y * (z * x * u * y)⁻¹ = (z * u)⁻¹ :=
by simpa [mccune] using mccune (z * x * u) (z * u)⁻¹ y

lemma l12 : x * (y * x * (y * z)⁻¹)⁻¹ = z := by simpa [mccune] using mccune (y * x) z (y * z)⁻¹
lemma l16 : x * (y * z)⁻¹ * x⁻¹ = (y * z)⁻¹ := by simpa [mccune] using l10 x (y * z)⁻¹ y z
lemma l18 : (y * (z * (y * z * x)⁻¹))⁻¹ = x :=
by simpa [l10] using l12 (z * (y * z * x)⁻¹) (y * z) x
lemma l23 : (x * y * (x * (y * z))⁻¹)⁻¹ = z := by simpa [l10] using l18 z (x * y) (y * z)
lemma l37 : x * y * x⁻¹ = y := by simpa [l23] using l16 x (x * x) (x * (x * y))⁻¹
lemma l39 : (z * y * (z * x)⁻¹)⁻¹ = x * y⁻¹ := by simpa [l12] using (l16 y (z * y) (z * x)⁻¹).symm
lemma l41 : x * (y * x * z)⁻¹ = (y * z)⁻¹ := by simpa [mccune] using l16 (y * x * z) y z
lemma l43 : x * (z * x⁻¹) = z := by simpa [l39] using l12 x x z
lemma l51 : (x * (x * z)⁻¹)⁻¹ = z := by simpa [l41] using l18 z x x
lemma l53 : x * (y * x)⁻¹ = y⁻¹ := by simpa [l37] using l37 (y * x) y⁻¹
lemma l55 : (y * z)⁻¹ = y⁻¹ * z⁻¹ := by simpa [l53, l37] using (l10 z (y * z)⁻¹ y z).symm
lemma l58 : x * y * z * x⁻¹ * y⁻¹ = z := by simpa [l37] using mccune (x * y) z x⁻¹
lemma l60 : x * (y⁻¹ * y⁻¹⁻¹) = x := by simpa [l37, l55] using mccune y x y⁻¹
lemma l64 : x⁻¹ * (x⁻¹⁻¹ * y⁻¹⁻¹) = y := by simpa [l55] using l51 x y
@[simp] lemma l85 : x⁻¹⁻¹ = x := by simpa [l43] using l64 x x
lemma l92 : x⁻¹ * (x * y) = y := by simpa using l64 x y
lemma l94 : x * (y⁻¹ * y) = x := by simpa using l60 x y
lemma l101 : x * (x⁻¹ * y) = y := by simpa using l92 x⁻¹ y
lemma l108 : x * y = y * x := by simpa [l92] using l37 y⁻¹ (y * x)
lemma l114 : x * (y * y⁻¹) = x := by simpa using l94 x y⁻¹
lemma l136 : x * x⁻¹ = y * y⁻¹ := by simpa [l114] using l101 x (y * y⁻¹)
lemma l172 : z * x * y * z⁻¹ = x * y := by simpa [l58] using (l43 x (z * x * y * z⁻¹)).symm
lemma l184 : x * y * z = z * x * y := by simpa [l92 z x] using l172 (z * x) y z⁻¹
lemma l244 : x * y * z = x * (y * z) := by simpa [l184 y] using (l108 x (y * z)).symm

/-- Every McCune comm group is a comm group. -/
instance : comm_group α :=
{ mul_assoc := l244,
  one := default α * (default α)⁻¹,
  mul_one := λ x, l114 x _,
  mul_comm := l108,
  mul_left_inv := λ x, (l108 _ x).trans (l136 x (default α)),
  one_mul := λ x, by rw [l108, l114],
  ..(by apply_instance : has_mul α),
  ..(by apply_instance : has_inv α) }

end mccune_comm_group

Oliver Nash (Jul 22 2021 at 17:52):

I never fully believed these axioms until you did this! Amazing work.

Kevin Buzzard (Jul 22 2021 at 17:53):

You didn't believe the computer??

Oliver Nash (Jul 22 2021 at 17:54):

I had my doubts. Perhaps if I’d read the literature, they would have evaporated. (Or not!)

Bhavik Mehta (Jul 22 2021 at 18:13):

Since I'm on a roll with these, I'm now doing the Robbins conjecture too in the discord

Mario Carneiro (Jul 22 2021 at 19:22):

If you are taking requests, you should try doing Meredith's axiom and Wolfram's axiom too

Adam Topaz (Jul 22 2021 at 19:25):

@Mario Carneiro do you know if there is such a minimal axiom for rings?

Yaël Dillies (Jul 22 2021 at 19:31):

Wanna create archive/minimal_axiom/? :wink:

Julian Külshammer (Jul 22 2021 at 19:42):

When I started with Lean, I did the much easier independent vector space axioms from https://www.cambridge.org/core/journals/mathematical-gazette/article/abs/independent-axioms-for-vector-spaces/0D49E4127F5F5EBC788A4AF36E95F07E#

Mario Carneiro (Jul 22 2021 at 19:47):

@Adam Topaz I wouldn't be surprised if there is one out there, but I haven't heard of any

Patrick Massot (Jul 22 2021 at 20:08):

Oliver Nash said:

I never fully believed these axioms until you did this! Amazing work.

Once you start to think a bit about the proof, the unbelievable part is that any simplification will occur without knowing associativity. Even the first lemma is still a miracle for me (you can see more information using the version of the proof that I posted in the PR review).

Bhavik Mehta (Jul 23 2021 at 04:28):

def robbins_conjecture {α : Type*} [has_sup α] [has_compl α] [inhabited α]
  [is_commutative α ()] [is_associative α ()]
  (robbins_axiom :  (x y : α), ((x  y)  (x  y)) = x) :
  boolean_algebra α :=

works! It's about 5x longer than the McCune group and about 10x longer than the McCune abelian group versions (and roughly the same scale of latex proof and time spent)

Jasmin Blanchette (Jul 24 2021 at 19:42):

Mario Carneiro said:

The proof says that 7 is obtained by paramodulation of 5 into 5. I challenge folks to figure out what that means

This is a paramodulation (or superposition) inference from and to the same clause. E.g. if you have a = b \/ p a, doing such a paramodulation might yield a = b \/ a = b \/ p b.


Last updated: Dec 20 2023 at 11:08 UTC