Skip to content
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

Merged
merged 9 commits into from
Mar 2, 2017

Conversation

cipher1024
Copy link

No description provided.

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

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?

Copy link
Author

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

(assume h : n % 2 = 0, begin rw h, refl end)
(assume h : n % 2 = 1, begin rw h, refl end)

end bitvec

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.

Copy link
Author

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.

@@ -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)

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.

Copy link
Author

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.

@@ -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 α) :

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.

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[']?

Copy link
Author

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.

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.

end
end

lemma add_le_add_left_iff (n m k : ℕ) : n ≤ m ↔ k + n ≤ k + m

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.

Copy link
Author

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 :=

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.

Copy link
Author

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?

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.

Copy link
Author

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.

Copy link
Author

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?

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.

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] :=

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.

Copy link
Author

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

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.

Copy link
Author

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?

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.

Copy link
Author

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.

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

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 :=

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

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.

@joehendrix joehendrix merged commit ac638f2 into GaloisInc:master Mar 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants