diff options
Diffstat (limited to 'Common')
| -rw-r--r-- | Common/Countable.lean | 9 | ||||
| -rw-r--r-- | Common/Finite.lean | 186 | ||||
| -rw-r--r-- | Common/HashSet.lean | 123 | ||||
| -rw-r--r-- | Common/Parsing.lean | 2 |
4 files changed, 1 insertions, 319 deletions
diff --git a/Common/Countable.lean b/Common/Countable.lean deleted file mode 100644 index e19db99..0000000 --- a/Common/Countable.lean +++ /dev/null @@ -1,9 +0,0 @@ -import Common.Finite - -class Countable (α : Type u) where - enumerate : α → Nat - injective {a b : α} : enumerate a = enumerate b → a = b - -instance {α : Type u} [Finite α] : Countable α where - enumerate := Fin.val ∘ Finite.enumerate - injective := Finite.injective ∘ Fin.val_inj.mp diff --git a/Common/Finite.lean b/Common/Finite.lean deleted file mode 100644 index 95f90a0..0000000 --- a/Common/Finite.lean +++ /dev/null @@ -1,186 +0,0 @@ -import Std.Data.HashSet -import Common.Nat - -class Finite (α : Type u) where - cardinality : Nat - enumerate : α → Fin cardinality - nth : Fin cardinality → α - nth_inverse_enumerate : nth ∘ enumerate = id - enumerate_inverse_nth : enumerate ∘ nth = id - -theorem Finite.surjective {α : Type u} [Finite α] {a b : Fin (Finite.cardinality α)} : nth a = nth b → a = b := λh₃ ↦ - have h₁ := Finite.enumerate_inverse_nth (α := α) - have h₄ := congrArg enumerate h₃ - have h₂ : ∀(x : Fin (Finite.cardinality α)), (enumerate ∘ nth) x = x := λ_↦h₁.substr rfl - have h₅ := Function.comp_apply.subst (h₂ a).symm - have h₆ := Function.comp_apply.subst (h₂ b).symm - h₅.substr $ h₆.substr h₄ - -theorem Finite.injective {α : Type u} [Finite α] {a b : α} : enumerate a = enumerate b → a = b := λh₁↦ - have h₂ := Finite.nth_inverse_enumerate (α := α) - have h₃ := congrArg nth h₁ - have h₄ : ∀(x : α), (nth ∘ enumerate) x = x := λ_↦h₂.substr rfl - have h₅ := Function.comp_apply.subst (h₄ a).symm - have h₆ := Function.comp_apply.subst (h₄ b).symm - h₅.substr $ h₆.substr h₃ - -def Finite.tuple_enumerate {α : Type u} [Finite α] {β : Type v} [Finite β] (x : α × β) : Fin ((Finite.cardinality α) * (Finite.cardinality β)) := - let (a, b) := x - let idxa := (Finite.enumerate a) - let idxb := (Finite.enumerate b) - let idx := idxa.val + (Finite.cardinality α) * idxb.val - have h : idx < (Finite.cardinality α) * (Finite.cardinality β) := - Nat.two_d_coordinate_to_index_lt_size idxa.isLt idxb.isLt - ⟨idx,h⟩ - -def Finite.tuple_nth {α : Type u} [Finite α] {β : Type v} [Finite β] (idx : Fin ((Finite.cardinality α) * (Finite.cardinality β))) := - let idxav := idx % (Finite.cardinality α) - let idxbv := idx / (Finite.cardinality α) - have h₁ : Finite.cardinality α > 0 := - if h : 0 = Finite.cardinality α then - have : cardinality α * cardinality β = 0 := h.subst (motive := λx↦x*cardinality β = 0) $ Nat.zero_mul (cardinality β) - (Fin.cast this idx).elim0 - else - Nat.pos_of_ne_zero (Ne.symm h) - let idxa : Fin (Finite.cardinality α) := ⟨idxav, Nat.mod_lt _ h₁⟩ - let idxb : Fin (Finite.cardinality β):= ⟨idxbv, Nat.div_lt_of_lt_mul idx.isLt⟩ - (Finite.nth idxa, Finite.nth idxb) - -theorem Finite.tuple_nth_inverse_enumerate {α : Type u} [Finite α] {β : Type v} [Finite β] : Finite.tuple_nth (α := α) (β := β) ∘ Finite.tuple_enumerate (α := α) (β := β) = id := by - unfold Finite.tuple_enumerate Finite.tuple_nth - funext - simp - congr - case h.e_fst x => - simp[Nat.mod_eq_of_lt] - rw[←Function.comp_apply (f := Finite.nth) (x := x.fst), Finite.nth_inverse_enumerate] - rfl - case h.e_snd x => - have h₁ : (↑(Finite.enumerate x.fst) + (Finite.cardinality α) * ↑(Finite.enumerate x.snd)) / Finite.cardinality α = ↑(Finite.enumerate x.snd) := by - rw[Nat.add_mul_div_left] - simp[Nat.div_eq_of_lt] - exact Nat.zero_lt_of_lt (Finite.enumerate x.fst).isLt - simp[h₁] - rw[←Function.comp_apply (f := Finite.nth) (x := x.snd), Finite.nth_inverse_enumerate] - rfl - -theorem Finite.tuple_enumerate_inerse_nth {α : Type u} [Finite α] {β : Type v} [Finite β] : Finite.tuple_enumerate (α := α) (β := β) ∘ Finite.tuple_nth (α := α) (β := β) = id := by - funext - unfold Finite.tuple_enumerate Finite.tuple_nth - simp - rename_i x - rw[Fin.eq_mk_iff_val_eq] - simp - rw[←Function.comp_apply (f := Finite.enumerate), Finite.enumerate_inverse_nth] - rw[←Function.comp_apply (f := Finite.enumerate), Finite.enumerate_inverse_nth] - simp[Nat.mod_add_div] - -instance {α : Type u} [Finite α] {β : Type v} [Finite β] : Finite (Prod α β) where - cardinality := (Finite.cardinality α) * (Finite.cardinality β) - enumerate := Finite.tuple_enumerate - nth := Finite.tuple_nth - enumerate_inverse_nth := Finite.tuple_enumerate_inerse_nth - nth_inverse_enumerate := Finite.tuple_nth_inverse_enumerate - -theorem Finite.forall_nth {α : Type u} [Finite α] (p : α → Prop) (h₁ : ∀(o : Fin (Finite.cardinality α)), p (Finite.nth o)) : ∀(a : α), p a := λa↦ - have : p ((nth ∘ enumerate) a) := Function.comp_apply.substr $ h₁ (Finite.enumerate a) - Finite.nth_inverse_enumerate.subst (motive := λx ↦ p (x a)) this - -def Finite.set (α : Type u) [Finite α] [BEq α] [Hashable α] : Std.HashSet α := - match h: (Finite.cardinality α) with - | 0 => Std.HashSet.empty - | l+1 => set_worker Std.HashSet.empty ⟨l,h.substr (p := λx ↦ l < x) $ Nat.lt.base l⟩ -where set_worker (set : Std.HashSet α) (n : Fin (Finite.cardinality α)) : Std.HashSet α := - let e := Finite.nth n - let set := set.insert e - match n with - | ⟨0,_⟩ => set - | ⟨m+1,h₁⟩ => set_worker set ⟨m, Nat.lt_of_succ_lt h₁⟩ - -protected theorem Finite.set_worker_contains_self' (α : Type u) [Finite α] [BEq α] [Hashable α] [LawfulBEq α] (a : α) (oldSet : Std.HashSet α) (h₁ : oldSet.contains a) (n : Fin (Finite.cardinality α)) : (Finite.set.set_worker α oldSet n).contains a := by - cases n - case mk n h₂ => - induction n generalizing oldSet - case zero => unfold set.set_worker; simp[h₁] - case succ m hm => - unfold set.set_worker - exact hm (oldSet.insert (nth ⟨m + 1, h₂⟩)) (by simp[h₁]) (Nat.lt_of_succ_lt h₂) - -protected theorem Finite.set_worker_contains_self (α : Type u) [Finite α] [BEq α] [Hashable α] [LawfulBEq α] : ∀ (a : α) (set : Std.HashSet α), (Finite.set.set_worker α set (Finite.enumerate a)).contains a := by - intros a oldSet - unfold set.set_worker - rw[←Function.comp_apply (f := nth), Finite.nth_inverse_enumerate, id_def] - split - case h_1 => apply Std.HashSet.contains_insert_self - case h_2 => - apply Finite.set_worker_contains_self' - exact Std.HashSet.contains_insert_self - -protected theorem Finite.set_worker_contains (α : Type u) [Finite α] [BEq α] [Hashable α] [LawfulBEq α] : ∀ (a : α) (set : Std.HashSet α) (o : Nat) (h₁ : Finite.enumerate a + o < Finite.cardinality α), (Finite.set.set_worker α set ⟨Finite.enumerate a + o, h₁⟩).contains a := by - intros a oldSet offset h₁ - induction offset generalizing oldSet - case zero => - exact Finite.set_worker_contains_self _ _ _ - case succ p hi => - unfold set.set_worker - simp - have : ↑(enumerate a) + p < cardinality α := Nat.lt_of_succ_lt $ (Nat.add_assoc (enumerate a) p 1).substr h₁ - exact hi (oldSet.insert (nth ⟨↑(enumerate a) + (p + 1), h₁⟩)) this - -theorem Finite.set_contains (α : Type u) [Finite α] [BEq α] [Hashable α] [LawfulBEq α] : ∀ (a : α), (Finite.set α).contains a := λa ↦ by - unfold set - split - case h_1 h => exact (Fin.cast h $ Finite.enumerate a).elim0 - case h_2 l h => - let o := l - enumerate a - have h₁ : (Finite.enumerate a).val + o = l := by omega - have h₂ := Finite.set_worker_contains _ a Std.HashSet.empty o (by omega) - simp[h₁] at h₂ - assumption - -protected theorem Finite.set_worker_size (α : Type u) [Finite α] [BEq α] [Hashable α] [LawfulBEq α] -: ∀(set : Std.HashSet α) (n : Fin (Finite.cardinality α)) (_ : ∀(x : Fin (Finite.cardinality α)) (_ : x ≤ n), - ¬set.contains (Finite.nth x)), (Finite.set.set_worker α set n).size = set.size + n + 1 -:= by - intros set n h₂ - simp at h₂ - unfold Finite.set.set_worker - cases n - case mk n h₁ => - split - case h_1 m isLt he => - simp at he - simp[Std.HashSet.size_insert, Std.HashSet.mem_iff_contains, h₂, he] - case h_2 m isLt he => - simp - have h₄ : m < n := have : n = m.succ := Fin.val_eq_of_eq he; this.substr (Nat.lt_succ_self m) - have h₅ : ∀ (x : Fin (cardinality α)), x ≤ ⟨m, Nat.lt_of_succ_lt isLt⟩ → ¬(set.insert (nth ⟨n, h₁⟩)).contains (nth x) = true := by - simp - intros x hx - constructor - case right => exact h₂ x (Nat.le_trans hx (Nat.le_of_lt h₄)) - case left => - have h₅ : x ≠ ⟨n, h₁⟩ := Fin.ne_of_val_ne $ Nat.ne_of_lt $ Nat.lt_of_le_of_lt hx h₄ - have h₆ := Finite.surjective (α := α) (a := x) (b := ⟨n,h₁⟩) - exact Ne.symm (h₅ ∘ h₆) - have h₃ := Finite.set_worker_size α (set.insert (nth ⟨n, h₁⟩)) ⟨m, Nat.lt_of_succ_lt isLt⟩ (h₅) - rw[h₃] - simp at he - simp[he, Std.HashSet.size_insert] - split - case isFalse => rw[Nat.add_assoc, Nat.add_comm 1 m] - case isTrue hx => - subst n - have h₂ := h₂ ⟨m+1,h₁⟩ (Fin.le_refl _) - have hx := Std.HashSet.mem_iff_contains.mp hx - exact absurd hx (Bool.eq_false_iff.mp h₂) -termination_by _ n => n.val - -theorem Finite.set_size_eq_cardinality (α : Type u) [Finite α] [BEq α] [Hashable α] [LawfulBEq α] : (Finite.set α).size = Finite.cardinality α := by - unfold set - split - case h_1 h => exact Std.HashSet.size_empty.substr h.symm - case h_2 l h => - rewrite(occs := .pos [3])[h] - have := Finite.set_worker_size α Std.HashSet.empty ⟨l,h.substr $ Nat.lt_succ_self l⟩ (λx _↦Bool.eq_false_iff.mp (Std.HashSet.contains_empty (a:=Finite.nth x))) - simp only [this, Std.HashSet.size_empty, Nat.zero_add] diff --git a/Common/HashSet.lean b/Common/HashSet.lean deleted file mode 100644 index 3271121..0000000 --- a/Common/HashSet.lean +++ /dev/null @@ -1,123 +0,0 @@ -import Std.Data.HashSet -import Common.Finite - - -open Std.HashSet -namespace Std.HashSet - -theorem erase_not_mem {α : Type u} [BEq α] [Hashable α] [LawfulBEq α] (set : HashSet α) (a : α) : a ∉ (set.erase a) := by - simp only [HashSet.mem_iff_contains, HashSet.contains_erase, beq_self_eq_true, Bool.not_true, Bool.false_and, Bool.false_eq_true, not_false_eq_true] - -theorem erase_not_mem_of_not_mem {α : Type u} [BEq α] [Hashable α] [LawfulBEq α] (set : HashSet α) {a : α} (b : α) (h₁ : a ∉ set) : a ∉ (set.erase b) := by - intro h₂ - rw[HashSet.mem_erase] at h₂ - exact absurd h₂.right h₁ - -protected theorem size_le_finite_worker_size (α : Type u) [Finite α] [BEq α] [Hashable α] [LawfulBEq α] : ∀ (set : Std.HashSet α) (n : Fin (Finite.cardinality α)) (_h₁ : ∀(o : Fin (Finite.cardinality α)) (_h : o > n), Finite.nth o ∉ set), set.size ≤ (Finite.set.set_worker α HashSet.empty n).size := by - intros set n h₁ - cases n - case mk n h₂ => - cases n - case zero => - have h₃ : (Finite.set.set_worker α empty ⟨0,h₂⟩).size = 1 := by simp[Finite.set.set_worker, HashSet.size_insert] - rw[h₃] - cases h₄ : set.contains (Finite.nth ⟨0,h₂⟩) - case false => - have h₅ : ∀(o : Fin (Finite.cardinality α)), Finite.nth o ∉ set := by - simp[←Bool.not_eq_true, ←HashSet.mem_iff_contains] at h₄ - intro o - cases o - case mk o ho => - cases o - case zero => exact h₄ - case succ oo => exact h₁ ⟨oo+1, ho⟩ (Nat.succ_pos oo) - have h₆ : ∀(a : α), a∉set := Finite.forall_nth (λx ↦ x∉set) h₅ - have h₇ : set.isEmpty = true := HashSet.isEmpty_iff_forall_not_mem.mpr h₆ - have h₈ : true = (set.size == 0) := HashSet.isEmpty_eq_size_eq_zero.subst h₇.symm - have h₈ : set.size = 0 := beq_iff_eq.mp h₈.symm - rw[h₈] - exact Nat.zero_le _ - case true => - --show that the set from which we erase (nth 0) has size 0, just like in case false. - --then show that, since we removed one element, set.size equals 1. - let rset := set.erase $ Finite.nth ⟨0,h₂⟩ - have h₅ : (Finite.nth ⟨0,h₂⟩) ∉ rset := erase_not_mem set (Finite.nth ⟨0,h₂⟩) - have h₆ : ∀(o : Fin (Finite.cardinality α)), Finite.nth o ∉ rset := by - intro o - cases o - case mk o ho => - cases o - case zero => exact h₅ - case succ oo => exact erase_not_mem_of_not_mem set _ $ h₁ ⟨oo+1, ho⟩ (Nat.succ_pos oo) - have h₇ : ∀(a : α), a∉rset := Finite.forall_nth (λx ↦ x∉rset) h₆ - have h₈ : rset.isEmpty = true := HashSet.isEmpty_iff_forall_not_mem.mpr h₇ - have h₉ : true = (rset.size == 0) := HashSet.isEmpty_eq_size_eq_zero.subst h₈.symm - have h₉ : rset.size = 0 := beq_iff_eq.mp h₉.symm - have h₁₀ : set.size ≤ rset.size + 1 := HashSet.size_le_size_erase - rw[h₉, Nat.zero_add] at h₁₀ - assumption - case succ m => - --erase (nth m) from the set and recurse. - --then show that the current set can only be larger by 1, and therefore fulfills the goal - --HashSet.size_le_size_erase - let rset := set.erase $ Finite.nth ⟨m+1,h₂⟩ - have h₃ : (Finite.nth ⟨m+1,h₂⟩) ∉ rset := erase_not_mem set (Finite.nth ⟨m+1,h₂⟩) - have h₄ : ∀(o : Fin (Finite.cardinality α)) (h₄ : o > ⟨m,Nat.lt_of_succ_lt h₂⟩), Finite.nth o ∉ rset := by - intros o h₄ - cases o - case mk o h₅ => - cases h₆ : o == (m+1) <;> simp at h₆ - case true => - simp only[h₆] - exact erase_not_mem set $ Finite.nth ⟨m+1, h₂⟩ - case false => - have h₆ : o > m+1 := by simp at h₄; omega - exact erase_not_mem_of_not_mem _ _ (h₁ ⟨o,h₅⟩ h₆) - have h₅ := Std.HashSet.size_le_finite_worker_size α rset ⟨m, Nat.lt_of_succ_lt h₂⟩ h₄ - have h₆ : (Finite.set.set_worker α empty ⟨m, Nat.lt_of_succ_lt h₂⟩).size = empty.size + m + 1 := - Finite.set_worker_size α empty ⟨m, Nat.lt_of_succ_lt h₂⟩ (λa _ ↦Bool.eq_false_iff.mp $ HashSet.contains_empty (a := Finite.nth a)) - have h₇ : (Finite.set.set_worker α empty ⟨m+1,h₂⟩).size = empty.size + (m + 1) + 1 := - Finite.set_worker_size α empty ⟨m+1,h₂⟩ (λa _ ↦Bool.eq_false_iff.mp $ HashSet.contains_empty (a := Finite.nth a)) - have h₈ := HashSet.size_le_size_erase (m := set) (k:=Finite.nth ⟨m+1,h₂⟩) - simp[h₆] at h₅ - simp[h₇] - exact Nat.le_trans h₈ (Nat.succ_le_succ h₅) - -theorem size_le_finite_set_size {α : Type u} [Finite α] [BEq α] [LawfulBEq α] [Hashable α] (set : Std.HashSet α) : set.size ≤ (Finite.set α).size := by - unfold Finite.set - split - case h_1 h₁ => - if h : set.isEmpty then - have := HashSet.isEmpty_eq_size_eq_zero (m := set) - simp[h] at this - simp[this] - else - have := HashSet.isEmpty_eq_false_iff_exists_mem.mp (Bool.eq_false_iff.mpr h) - cases this - case intro x hx => - let xx := Finite.enumerate x - exact (Fin.cast h₁ xx).elim0 - case h_2 l h => - exact Std.HashSet.size_le_finite_worker_size α set ⟨l,h.substr $ Nat.lt_succ_self l⟩ (λa hx ↦ - by - have h₁ := a.isLt - simp_arith[h] at h₁ - have h₂ : a > l := Fin.lt_iff_val_lt_val.mp hx - exact absurd h₁ (Nat.not_le.mpr h₂) - ) - -theorem size_le_finite_cardinality {α : Type u} [Finite α] [BEq α] [LawfulBEq α] [Hashable α] (set : Std.HashSet α) : set.size ≤ Finite.cardinality α := - (Finite.set_size_eq_cardinality α).subst (size_le_finite_set_size set) - -theorem size_lt_finite_cardinality_of_not_mem {α : Type u} [Finite α] [BEq α] [LawfulBEq α] [Hashable α] (set : Std.HashSet α) (h₁ : ∃(a : α), a ∉ set) : set.size < Finite.cardinality α := by - have h₂ : set.size ≤ Finite.cardinality α := size_le_finite_cardinality set - cases h₁ - case intro e h₁ => - let iset := set.insert e - have h₂ : iset.size = set.size + 1 := by - have := HashSet.size_insert (m := set) (k := e) - simp[h₁] at this - assumption - have h₃ : iset.size ≤ Finite.cardinality α := size_le_finite_cardinality iset - rw[h₂] at h₃ - exact Nat.lt_of_succ_le h₃ diff --git a/Common/Parsing.lean b/Common/Parsing.lean index d878639..d68a313 100644 --- a/Common/Parsing.lean +++ b/Common/Parsing.lean @@ -2,7 +2,7 @@ import Common.List import Common.Nat -import Common.Finite +import LeanAStar.Finite namespace Parsing |
