Zulip Chat Archive
Stream: general
Topic: Cooper's algorithm
Seul Baek (May 20 2018 at 00:19):
I've implemented Cooper's algorithm for linear integer arithmetic as a Lean tactic (https://github.com/skbaek/qelim). It's still quite limited, but it should work for simple goals.
cooper
is the completely verified tactic that is proof-producing all the way. Unfortunately, it is unusably slow.cooper_vm
is the partially verified tactic whose first step (replacing the original goal with the new quantifier-eliminated goal) is proof-producing. The second step (evaluating the new goal to a tautology) is trusted.- The tactics assume sentential goals, so you'll have to generalize variables and hypotheses before calling it.
- The implementation is based on Tobias Nipkow's paper (http://www21.in.tum.de/~nipkow/pubs/jar10.pdf).
- I've added a few test cases (qelim/lia/cooper/tests.lean) from John Harrison's book.
- Right now I'm having trouble making absolute paths work. All references to mathlib are relative.
Mario Carneiro (May 20 2018 at 00:22):
Hey! Seul's here! And he brings gifts
Mario Carneiro (May 20 2018 at 00:34):
I notice that your atom
type uses int
. This will kill your efficiency, if you are doing kernel evaluation. You should use znum
instead
Mario Carneiro (May 20 2018 at 00:38):
Re: paths, do you have a leanpkg.toml
file in your project? I don't see one, but it's important for making file resolution work
Mario Carneiro (May 20 2018 at 00:43):
For others who may not be aware: this is basically the omega
tactic everyone's been talking about, although Cooper's is a slightly different algorithm for the same problem
Andrew Ashworth (May 20 2018 at 03:35):
Thanks for releasing this! It looks like it was quite a substantial effort, with the first commit being a few months ago. I definitely want to spend some time looking over it!
Seul Baek (May 20 2018 at 21:09):
I notice that your
atom
type usesint
. This will kill your efficiency, if you are doing kernel evaluation. You should useznum
instead
Thanks for the suggestion! Maybe this is what's making cooper
so much slower than cooper_vm
.
Seul Baek (May 20 2018 at 21:13):
Re: paths, do you have a
leanpkg.toml
file in your project? I don't see one, but it's important for making file resolution work
I'm actually having problems with mathlib itself—when I clone mathlib it won't work as is, because Lean doesn't like its absolute paths for some reason. It works after I manually relativize them. This is strange because mathlib does have a leanpkg.toml
file.
Kevin Buzzard (May 20 2018 at 21:15):
You want to make mathlib a dependency for your project
Kevin Buzzard (May 20 2018 at 21:16):
if you use leanpkg and add mathlib as a dependency then it should sort out everything for you
Kevin Buzzard (May 20 2018 at 21:17):
see section 1.4.3 of the reference manual
Kevin Buzzard (May 20 2018 at 21:17):
https://leanprover.github.io/reference/using_lean.html#using-the-package-manager
Kevin Buzzard (May 20 2018 at 21:18):
I am really grateful for your work by the way, and maybe @Patrick Massot will be even more grateful -- Patrick maybe this solves some of your nat woes?
Patrick Massot (May 21 2018 at 09:18):
I hope it can help me. I need to find some time to try it.
Patrick Massot (May 21 2018 at 09:18):
Maybe I'm not trying very hard to find this time because I'm afraid I'll be disappointed
Patrick Massot (May 21 2018 at 10:17):
Any hint about how to actually import that cooper thing?
Patrick Massot (May 21 2018 at 10:18):
I tried leanpkg add skbaek/qelim
and then import
Patrick Massot (May 21 2018 at 10:18):
I tried adding a leanpkg.toml
to it
Patrick Massot (May 21 2018 at 10:18):
But import lia.cooper.main
doesn't work
Patrick Massot (May 21 2018 at 10:36):
@Mario Carneiro Did you manage to import this tactic?
Mario Carneiro (May 21 2018 at 10:37):
I haven't attempted it, no
Mario Carneiro (May 21 2018 at 10:38):
You could just copy the files into your project
Patrick Massot (May 21 2018 at 10:40):
Then all mathlib imports fail...
Patrick Massot (May 21 2018 at 10:40):
I guess we need to wait a bit more until this can be tested
Seul Baek (May 28 2018 at 19:02):
I figured out what was wrong and added a .toml file. Now you can install and use the repo using leanpkg.
Johan Commelin (May 28 2018 at 19:42):
This is cool!
Johan Commelin (May 28 2018 at 19:42):
Is it planned to merge this into mathlib? Or will it remain a separate lib?
Johan Commelin (May 28 2018 at 19:42):
I'm not sure what the planning is in general: a monolithic lib, or distributed libs
Patrick Massot (May 28 2018 at 20:13):
@Seul Baek Do you have any example of use? I can now import the lib, but haven't yet managed to proved anything using Cooper
Patrick Massot (May 28 2018 at 20:31):
actually I can prove stuff about integers (that ring
also proves), so maybe I misunderstood the scope of this tactic. I thought it would work on natural numbers
Patrick Massot (May 28 2018 at 20:32):
With nat I always get type error at eval_expr, argument has type ℕ but is expected to have type ℤ
Mario Carneiro (May 28 2018 at 20:36):
The core tactic is designed to work on int
. There are some missing preprocessing steps to prove natural number theorems
Mario Carneiro (May 28 2018 at 20:37):
Of course a nat quantifier is the same as an int quantifier with the additional assumption 0 <= n
Patrick Massot (May 28 2018 at 20:37):
What do you get in addition to ring
then?
Mario Carneiro (May 28 2018 at 20:37):
I think Seul's tactic is still more of a backend thing
Mario Carneiro (May 28 2018 at 20:38):
it needs a front end to generalize and revert quantifiers, and convert nats to ints
Patrick Massot (May 28 2018 at 20:39):
Do you know whether he's working on this?
Mario Carneiro (May 28 2018 at 20:39):
ring
will not be able to prove that \forall n : int, n <= 0 \/ n >= 1
for example
Mario Carneiro (May 28 2018 at 20:39):
Or 3 | n -> 5 | n -> 15 | n
Mario Carneiro (May 28 2018 at 20:40):
or 3 | n -> n > 0 -> n*n - n > 0
Mario Carneiro (May 28 2018 at 20:41):
oh wait actually that last one might not work because of the square
Patrick Massot (May 28 2018 at 20:41):
This sounds pretty nice
Mario Carneiro (May 28 2018 at 20:42):
but more importantly, it allows full quantifier alternation
Patrick Massot (May 28 2018 at 20:42):
But Lean doesn't let me state the divisibility stuff
Mario Carneiro (May 28 2018 at 20:42):
type 3 \| n
Patrick Massot (May 28 2018 at 20:43):
Oh, Johan will like this unicode trickery
Patrick Massot (May 28 2018 at 20:44):
example : ∀ (n : ℤ), (3 ∣ n) → (5 ∣ n) → (15 ∣ n) := by cooper
doesn't work though
Mario Carneiro (May 28 2018 at 21:10):
looking at the code, it's pretty sparse on extended syntax
Mario Carneiro (May 28 2018 at 21:11):
you have to use exists and forall and times and le
Mario Carneiro (May 28 2018 at 21:11):
I'm not even sure equality is supported
Mario Carneiro (May 28 2018 at 21:11):
so you would have to write \ex k, 3 * k <= n /\ n <= 3 * k
instead of 3 | n
Kenny Lau (May 28 2018 at 21:14):
I thought everything is decidable
Seul Baek (May 28 2018 at 21:14):
@Johan Commelin I'm not sure what'd be the best way to integrate this to other libraries in the long term. It'll stay separate for the short term for convenience of further development.
Mario Carneiro (May 28 2018 at 21:15):
actually I take it back, forall is also not supported
Mario Carneiro (May 28 2018 at 21:15):
you have to use negation and exists
Seul Baek (May 28 2018 at 21:18):
@Patrick Massot It should definitely be possible to write a preprocessor for nat, although I'm not working on it at the moment. I'm trying to first replace int
with znum
to improve efficiency.
Seul Baek (May 28 2018 at 21:22):
@Mario Carneiro forall and equality are indirectly supported by the rewriting step before calling the main quantifier elimination tactic. E.g., cooper_vm
works for forall (x: int), exists (y : int), x = 1 + y
Mario Carneiro (May 28 2018 at 21:24):
oh, I see it
Mario Carneiro (May 28 2018 at 21:24):
I guess you should add the definition of dvd in that list
Seul Baek (May 28 2018 at 21:28):
You mean the list of indirectly supported relations?
Mario Carneiro (May 28 2018 at 21:28):
yes
Mario Carneiro (May 28 2018 at 21:28):
as a simp lemma in the preprocessing
Mario Carneiro (May 28 2018 at 21:29):
something like a | b <-> ∃ c, b = a * c
Mario Carneiro (May 28 2018 at 21:29):
surprisingly not stated as a theorem that I can see, but easy to prove by refl
Seul Baek (May 28 2018 at 21:32):
Yes, I think it should be possible to do this even more directly (w/o preprocessing), since the internal syntax already includes dvd
Patrick Massot (May 29 2018 at 08:46):
Thanks Seul and Mario. I'll wait a bit more then (a tactic handling ℕ crazyness is what I really need).
Kevin Buzzard (May 29 2018 at 11:22):
surprisingly not stated as a theorem that I can see, but easy to prove by refl
Hey wait a minute! I asked for the name of a theorem recently (if a structure is made with a : A and b : B then (structure.mk a b).a = a) and you said "oh that's true by refl so it doesn't have a name"
Kevin Buzzard (May 29 2018 at 11:23):
What's the algorithm for determining whether an equality whose proofs is rfl gets blessed with a name?
Mario Carneiro (May 29 2018 at 11:31):
It doesn't usually matter, Seul is writing a tactic so he needs to have names for his automation. It's fine even if he just declares a local theorem with a particular statement he can rely on.
Mario Carneiro (May 29 2018 at 11:32):
For example there are lots of theorems in tactic.ring
that are like this - they have very particular statements to make it easy for the automation, but no one would ever use those theorems otherwise
Kevin Buzzard (May 29 2018 at 11:33):
But the other day I said "I want to do this rewrite and it's refl but I want to know the name anyway" and your response was "use show"
Kevin Buzzard (May 29 2018 at 11:33):
and I bought this at the time
Kevin Buzzard (May 29 2018 at 11:34):
but this response stinks
Mario Carneiro (May 29 2018 at 11:34):
But it's also common for definitional expansions to have a name, particularly when the definition is hidden in a typeclass
Kevin Buzzard (May 29 2018 at 11:34):
because I have to keep changing things to definitionally equal things in my head
Kevin Buzzard (May 29 2018 at 11:34):
and I am sitting at a computer
Mario Carneiro (May 29 2018 at 11:34):
for example finset.subset_iff
Kevin Buzzard (May 29 2018 at 11:34):
can I do targetted dsimp?
Kevin Buzzard (May 29 2018 at 11:35):
This is a new thread. Hang on
Last updated: Dec 20 2023 at 11:08 UTC