-
Notifications
You must be signed in to change notification settings - Fork 298
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
[Merged by Bors] - feat(computability): strong reducibility and degrees #1203
Conversation
I think this one is ready to merge in terms of content. @digama0 what do you think? (I'm sure you can squeeze these proofs!) More can be proved once we have the parameter theorem. |
Could you update this to match the new doc requirements? (https://github.com/leanprover-community/mathlib/blob/master/docs/contribute/doc.md) |
src/computability/partrec_code.lean
Outdated
@@ -506,6 +512,19 @@ theorem curry_prim : primrec₂ curry := | |||
comp_prim.comp primrec.fst $ | |||
pair_prim.comp (const_prim.comp primrec.snd) (primrec.const code.id) | |||
|
|||
theorem one_one_curry {c₁ c₂ n₁ n₂} (h : curry c₁ n₁ = curry c₂ n₂) : c₁ = c₂ ∧ n₁ = n₂ := |
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.
The name seems a bit nonconventional. I would actually be inclined to call this one injective_curry
, and the other one injective_curry'
or similar; we've never used one-one to refer to injectivity before in mathlib.
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.
Fixed!
src/computability/partrec_code.lean
Outdated
λ a b h, (@one_one_curry _ _ 0 0 $ by rw h).1 | ||
|
||
theorem s_m_n (c n x) : ∃ f : code → ℕ → code, | ||
function.injective f ∧ computable₂ f ∧ eval (f c n) x = eval c (mkpair n 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.
Is injectivity like this a part of S_m^n? It's a bit weird to have injectivity of a binary curried function relative to one of its arguments.
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.
Also, n and x are quantified in the wrong place here. They should be in the third conjunct, since we want to say that f has a certain behavior on any input values n,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.
Ah, that's a shame. I copy-pasted eval_curry
without thinking about it.
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.
Recursion theorists usually want it to be injective for better reducibility purposes, but as you said it's unnatural to have it relative to one of its arguments. I have removed the condition, but left the injectivity as a separate theorem.
src/computability/reduce.lean
Outdated
λ x y h, ⟨h.2, h.1⟩, | ||
λ x y z h₁ h₂, ⟨transitive_one_one_reducible h₁.1 h₂.1, transitive_one_one_reducible h₂.2 h₁.2⟩⟩ | ||
|
||
instance many_one_equiv_setoid {α} [primcodable α] : setoid (set α) := |
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 shouldn't be an instance
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.
If I don't make this an instance then I have to provide it to the quotient.lift
proofs below, which is fine but looks a bit awkward. Is there any particular reason that you think this shouldn't be an instance?
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 make it a local instance, but the problem is that the typeclass problem is not domain specific but the solution is. This instance will equip any set anywhere with the many one equiv, which is unlikely to be the right one if you are doing ring theory, say.
src/computability/reduce.lean
Outdated
|
||
def many_one_degree {α} [primcodable α] := quotient (@many_one_equiv_setoid α _) | ||
|
||
def disjoin (p q : set ℕ) : set ℕ := (λ x, 2 * x) '' p ∪ (λ x, 2 * x + 1) '' q |
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 would like to see this generalized over other types. Rather than coding everything over nats, this would look much better if the domain is simply a sum type, and the primcodable instance will do all the odd/even interleaving work.
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 would also like to make things as general as possible, but just like Rice's theorem, the classical results are almost always about nats. I feel that we can go with nats for now, and if the generalized version turns out to be useful for other theories, then we do the refactoring.
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 actually am claiming that the work you are doing now can be done easier with sum types, even setting aside any possible future benefits of generalization. sum.inl
is primrec, which replaces your theorems about 2x and 2x+1.
Also, many_one_equiv
and friends can be stated with different types on the left and right, although of course the setoid instance can't.
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 agree that sum type naturally interleaves things, but then we end up having something like set (ℕ ⊕ ℕ)
when trying to instantiate them with nats. That looks a bit weird to me when I just want to reason about predicates on natural numbers. We could prove some translation theorems, though.
src/computability/reduce.lean
Outdated
lemma add1 : primrec (nat.unpaired (λ x y, nat.succ y)) := | ||
by simp [primrec₂.unpaired, primrec.comp₂ primrec.succ primrec₂.right] | ||
|
||
lemma double : primrec (λ n, 2 * n) := |
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 am concerned that this theorem is not a trivial consequence of the primrec library. It should be the composition of primrec_mul and primrec_const
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 one drives me crazy. I'm still not sure how to prove it elegantly. Apparently I haven't fully understood the primrec library :(
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 should not be using nat.primrec
, that is only for bootstrapping. primrec
also works on functions from nat to nat and has a lot more theorems
@minchaowu I pushed a bunch of changes regarding type generalization. The disjoin operator builds a bigger type, but for the join semilattice of degrees, we need to map it back into a single type, which only works if the type is nat (or more generally, denumerable). This is done via the |
@digama0 This looks fancy. No objections from me. I like it. |
I think this is still waiting for doc strings on all definitions. I'd love to see the header doc expanded also, at the very least to mention the main definitions and results in the file. |
At a recent maintainers meeting, it was decided that aside from documentation, this PR could be merged. I rebased the PR and repaired it, and documented the main file, I could not get up the motivation to document Mario's whole computability development, but I added headers and a reference to his ITP paper to three of the main files, which should help. |
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 think this good enough to be merged. I'll leave the last word to @digama0 as boss of the computability theory.
Is there a reason to consider degrees on a given type α
? This makes it awkward to use ≤
on degrees because you want to compare degrees on different types. I would have thought that many_one_degree α
is isomorphic to many_one_degree ℕ
and that the extra parameter is kind of pointless.
-- local attribute [instance] many_one_equiv_setoid | ||
|
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.
-- local attribute [instance] many_one_equiv_setoid |
quotient.lift_on₂' d₁ d₂ (λ a b, a ≤₀ b) | ||
(λ a b c d h₁ h₂, propext $ (h₁.le_congr_left).trans (h₂.le_congr_right)) | ||
|
||
instance many_one_degree.has_le {α} [primcodable α] : has_le (many_one_degree α) := ⟨many_one_degree.le⟩ |
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'm not sure if it is a good idea to have two ways to compare degrees (i.e., .le
and ≤
). Unfortunately the .le
is more general than ≤
.
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
Co-Authored-By: Gabriel Ebner <gebner@gebner.org>
I think this PR has already been reviewed, so I don't have much to add. We can revisit bors r+ |
Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Jeremy Avigad <avigad@cmu.edu>
Pull request successfully merged into master. Build succeeded: |
…unity#1203) Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Jeremy Avigad <avigad@cmu.edu>
…unity#1203) Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Jeremy Avigad <avigad@cmu.edu>
…eter (#2630) The file `reduce.lean` defines many-one degrees for computable reductions. At the moment every primcodable type `α` has a separate type of degrees `many_one_degree α`. This is completely antithetical to the notion of degrees, which are introduced to classify problems up to many-one equivalence. This PR defines a single `many_one_degree` type that lives in `Type 0`. We use the `ulower` infrastructure from #2574 which shows that every type is computably equivalent to a subset of natural numbers. The function `many_one_degree.of` which assigns to every set of a primcodable type a degree is still universe polymorphic. In particular, we show that `of p = of q ↔ many_one_equiv p q`, etc. in maximal generality, where `p` and `q` are subsets of different types in different universes. See previous discussion at #1203.
…eter (#2630) The file `reduce.lean` defines many-one degrees for computable reductions. At the moment every primcodable type `α` has a separate type of degrees `many_one_degree α`. This is completely antithetical to the notion of degrees, which are introduced to classify problems up to many-one equivalence. This PR defines a single `many_one_degree` type that lives in `Type 0`. We use the `ulower` infrastructure from #2574 which shows that every type is computably equivalent to a subset of natural numbers. The function `many_one_degree.of` which assigns to every set of a primcodable type a degree is still universe polymorphic. In particular, we show that `of p = of q ↔ many_one_equiv p q`, etc. in maximal generality, where `p` and `q` are subsets of different types in different universes. See previous discussion at #1203.
…unity#1203) Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Jeremy Avigad <avigad@cmu.edu>
TO CONTRIBUTORS:
Make sure you have:
If this PR is related to a discussion on Zulip, please include a link in the discussion.
For reviewers: code review check list