-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat(library/nat): add exponentiation for natural numbers #1
Conversation
…forms of de Morgan’s law
…l cases assuming associativity and commutativity
…simplification rules; improve the interfaces by adding type annotations and making some parameters explicit
library/data/bitvec.lean
Outdated
protected def list_of_nat : ℕ → ℕ → list bool | ||
| 0 x := list.nil | ||
| (succ n) x := list_of_nat n (x / 2) ++ [to_bool (x % 2 = 1)] | ||
|
||
protected def of_nat : Π (n : ℕ), nat → bitvec 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.
If seems like it'd make sense to define of_nat in terms of list_of_nat, or just prove everything in terms of of_nat. Also why is list_of_nat reducible?
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're right, list_of_nat doesn't actually need to be reducible and we don't need to duplicate the definition of list_of_nat
library/data/bitvec.lean
Outdated
(assume h : n % 2 = 0, begin rw h, refl end) | ||
(assume h : n % 2 = 1, begin rw h, refl end) | ||
|
||
end bitvec |
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.
Seems confusing to end bitvec, define a theorem in bitvec, then start namespace bitvec.
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.
That's true. I'll fix it.
library/data/vector.lean
Outdated
@@ -92,6 +92,10 @@ end accum | |||
protected lemma eq {n : ℕ} : ∀ (a1 a2 : vector α n), to_list a1 = to_list a2 → a1 = a2 | |||
| ⟨x, h1⟩ ⟨.x, h2⟩ rfl := rfl | |||
|
|||
@[simp] lemma to_list_tag {n : ℕ} {xs : list α} (Pxs : list.length xs = 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.
Where is this theorem needed? It should generally happen automatically in semi reducible contexts.
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 thought I needed it but I don't.
library/init/data/list/lemmas.lean
Outdated
@@ -154,6 +158,24 @@ by induction l; simph | |||
@[simp] lemma map_reverse (f : α → β) (l : list α) : map f (reverse l) = reverse (map f l) := | |||
by induction l; simph | |||
|
|||
lemma reverse_core_append' (xs ys zs : list α) : |
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.
reverse_core_append' seems like a more useful lemma than reverse_core_append proper. Maybe just have it and combine it with nil_append as needed.
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 also noticed that Leo intentionally didn't prove any lemmas about reverse core directly. Do we need reverse_core_append[']?
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 going to check where we need it. Why does Leo not prove anything about reverse_core directly?
I can do without reverse_core_append[']. I'll take it out.
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 why, I'd guess because it's mostly viewed as an internal function just needed to implement reverse.
library/init/data/nat/lemmas.lean
Outdated
end | ||
end | ||
|
||
lemma add_le_add_left_iff (n m k : ℕ) : n ≤ m ↔ k + n ≤ k + m |
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.
Should the left and right hand sides be reversed for simplification.
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.
done
| (succ n) := by refl | ||
|
||
theorem div_le_div | ||
: ∀ {y x}, x ≤ y → ∀ z : ℕ, x / z ≤ y / z := |
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 we added a constraint that z \ne 0, then this could also be used as a simplification lemma if reoriented.
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.
Can you elaborate please? Why can't we use it for simplification as it stands?
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 was thinking it might be useful to rewrite x /z <= y / z to x <= y. If Lean's elaborate will already do that, then great. I also don't think that change is critical.
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 I see what you mean. You're suggesting I strengthen the theorem to an equivalence (with z \ne 0 as a side condition). I'll try adding
theorem div_le_div_of_le
: ∀ z : ℕ, z ≠ 0 → x / z ≤ y / z → x ≤ y
and
theorem div_le_div_iff_le
: ∀ z : ℕ, z ≠ 0 → ( x / z ≤ y / z ↔ x ≤ y )
and get back to you.
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.
Actually, I don't think that stronger theorem holds: consider x = 3, y = 2 and z = 2.
x / z = 1
y / z = 1
but 3 ≤ 2 does not hold.
I could prove a Galois connection between / and * though:
x / z ≤ y ↔ x ≤ y * z
Together with indirect equality (see below) it could provide a basis for simpler proofs about division.
theorem indirect_equality [weak_order α] (x y : α) : x = y ↔ (∀ z : α, x ≤ z ↔ y ≤ z)
Should I go ahead?
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.
Good catch; I'm not sure if the generalization matters.
library/data/bitvec.lean
Outdated
open subtype | ||
|
||
theorem bitvec.bits_to_nat_over_append (xs : list bool) (y : bool) | ||
: bitvec.bits_to_nat (xs ++ [y]) = bitvec.bits_to_nat xs * 2 + bitvec.bits_to_nat [y] := |
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.
Use consistent indention in this file for proofs.
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.
Done
|
||
end foldr | ||
|
||
section foldr_ac |
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.
Were the AC versions of these proofs actually used somewhere? It seems like versions that only depend on associativity would be more generally useful.
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 don't think I can remove commutativity from the assumptions of any of those rules. Do you have something in mind about reformulating them without commutativity?
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 was thinking associativity + identity would get similar versions, but AC has different variants. These are fine, but I still don't quite see what theorems were important for our proofs. e.g., I see sum_le is important, but doesn't appear to use this work. Conversely, the sum_foldr utility seems less clear.
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 could remove sum_foldr and sum_foldl. I put a bit more than we strictly need just so that it doesn't come out uneven. For instance, I tried to prove the same things about foldl and foldr. It allowed me to play around with the proofs and choose the one I prefer. I thought the unused theorems would still be worth keeping.
library/init/data/nat/lemmas.lean
Outdated
begin | ||
rw [div_def x z,dif_pos Hx,div_def y z,dif_pos Hy,-add_le_add_right_iff] , | ||
apply IH (y - z) Hyz_z Hxy_z | ||
end |
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.
Could we get these lemmas to match the style of the other proofs in Lean's standard library.
| (succ n) := by refl | ||
|
||
theorem div_le_div | ||
: ∀ {y x}, x ≤ y → ∀ z : ℕ, x / z ≤ y / z := |
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.
Good catch; I'm not sure if the generalization matters.
... = 1 + z - 1 : by rw -nat.add_sub_assoc Pz | ||
... = z : by rw nat.add_sub_cancel_left, | ||
have Pdiv : 0 < z ∧ z ≤ z * x + z - 1, from ⟨Pz,Pz_le_zx_z_1⟩, | ||
calc |
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'd recommend a final pass to see if these proofs can be simplified via the tactics language.
No description provided.