-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Imo1970 p4 #44
Imo1970 p4 #44
Conversation
There is still an issue with type casting from N+ to N.
Do you know where it's spending the bulk of that time? |
I love this option, I can see exactly which functions are slow. At first sight it looks like ~10% of time is spent in the function that counts even numbers in the interval. I think I can actually probably remove that function altogether I found a better proof later on (counting odd numbers), and I think I can just refactor the code to use that. |
I did manage to shave off ~2 seconds from compile time by factroing out the inefficient implementation of set_option trace.profiler.threshold 1000 set_option trace.profiler true Before: 10.416134 seconds spent on the following 5 lemmas: [2.179035] lemma exactly_three_even_numbers After: 8.30901 seconds spent on the following 4 lemmas: [2.434758] lemma odd_props (n : ℕ) (the reimplementation uses a fraction of a second to implement the lemma piggy-backing on |
Optimised the code by removing lemma exactly_three_even_number s
Is there any way to manually check if the website looks good locally? I can see that the CI builds the website, but not sure if that's something that can be tested locally. |
and then open |
That's expected. |
Compfiles/Imo1970P4.lean
Outdated
intro rel1 | ||
intro rel2 | ||
intro a | ||
intro a_in_s3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can collapse these intros to a single line:
intro s3 rel1 rel2 a a_in_s3
Compfiles/Imo1970P4.lean
Outdated
intro left | ||
dsimp[Disjoint] | ||
dsimp[Finset.instHasSubset] | ||
simp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For future-proofing, non-terminal simp
invocations should be turned into simp only
. You can do this by changing into simp?
and then accepting the suggestion in the infoview.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've fixed this in this instance, and all the other instances.
Compfiles/Imo1970P4.lean
Outdated
exact mem_of_subst k s2 {1, 2, 3, 4, 6} k_in_s2 explicit_s2 | ||
intro five_div_k | ||
simp_all only [Finset.mem_insert, Finset.mem_singleton] | ||
cases k_in_explicit_s2 with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A fancier way to do this is:
obtain rfl | rfl | rfl | rfl | rfl | rfl := k_in_explicit_s2 <;> contradiction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this code do though? I don't really understand it.
If I did understand it, I think the question for me would be if it's better style than:
cases k_in_explicit_s2 with
| inl h =>
subst h
contradiction
| inr h_1 =>
cases h_1 with
| inl h =>
subst h
contradiction
| inr h_2 =>
cases h_2 with
| inl h =>
subst h
contradiction
| inr h_1 =>
cases h_1 with
| inl h =>
subst h
contradiction
| inr h_2 =>
subst h_2
contradiction
The latter uses very standard idioms (at the cost of some repetition) and is easier to read than the former.
I've put the golfed version in for now, but personally I tend to prefer code that's easy to read over code that's easy to write.
This might be different in the world of tactic-based theorem provers, as tactic-based programs are infamously difficult to read anyway (I think one pretty much has to read them with compiler in hand).
What do you think David?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, oops --- I noticed just now that I put one too many rfl
s in there. The last one is not needed.
My thought process here was as follows:
First, we can use obtain
with its pattern syntax to flatten the case analysis:
obtain h | h_1 | h_2 | h_1 | h := k_in_explicit_s2
· subst h
contradiction
· subst h_1
contradiction
· subst h_2
contradiction
· subst h_1
contradiction
· subst h
contradiction
Then we note that in all cases we are immediately doing subst h
. The rfl
keyword for obtain
does that automatically. So the above is equivalent to
obtain rfl | rfl | rfl | rfl | rfl := k_in_explicit_s2
· contradiction
· contradiction
· contradiction
· contradiction
· contradiction
Then we notice that each branch is exactly the same, so we can collapse them with the <;>
combinator:
obtain rfl | rfl | rfl | rfl | rfl := k_in_explicit_s2 <;> contradiction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very clever! I've put it in, but again if we golf code like this it might be difficult to read for beginners. (again, not sure if proof readability is as important as readability of software source code).
Compfiles/Imo1970P4.lean
Outdated
use n | ||
use n + 2 | ||
use n + 4 | ||
simp_all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid non-terminal simps. Use simp only
or simp_all only
instead.
In this particular case,
simp only [and_self, and_true]
works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I missed the simp_all's, just looked at the simps. Will fix this in the next patch.
Compfiles/Imo1970P4.lean
Outdated
use n + 2 | ||
use n + 4 | ||
simp_all | ||
· ext x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the ·
and indentation here? There is only one goal.
Compfiles/Imo1970P4.lean
Outdated
have h2 := Odd.not_two_dvd_nat h | ||
use n | ||
use n + 2 | ||
use n + 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be made more concise:
use n, n + 2, n + 4
Compfiles/Imo1970P4.lean
Outdated
· simp_all only | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please delete extraneous newlines.
Compfiles/Imo1970P4.lean
Outdated
exact X1 | ||
rw[partition] at Y1 | ||
exact Y1 | ||
exact X3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These successive exact
s indicate that the proof needs to be structured via ·
and indentation, so that it focuses on one goal at time. Looks like these subgoals were introduced after apply at_most_one n
. You should add cdot and indentation there.
Compfiles/Imo1970P4.lean
Outdated
· intro o | ||
rintro ⟨o_in_s, three_div_o⟩ | ||
rw[s_eq] at o_in_s | ||
simp_all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nonterminal simp should have an only
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've resolved this and all the others (I actually used a wrong regex to search for those earlier).
Compfiles/Imo1970P4.lean
Outdated
apply no_prime | ||
use p | ||
obtain ⟨a, b, _⟩ := H | ||
constructor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more concise way:
exact ⟨a, b⟩
Thanks! |
Hi David,
Please see below a formalisation of Imo1970 p4.
The formalisation follows the first solution from the Art of Problem Solving.
Could I suggest that for the review we use the pull request workflow (as opposed to the rebase workflow) -- it would be helpful if you could put comments in the pull request, and I can then fix the problems (and learn in the process). It will take a bit more time, but I think will help us maintain high quality codebase.
As it stands the solution takes ~20 seconds to compile, but as it's quite modular with many small lemmas, it could be optimised on a per-lemma basis. My aim just now was to get everything to typcheck, so some lemmas contain repetitive code, etc...