Formulate Lemma0A.
parent
9a50ea5a78
commit
5e7d9371e7
|
@ -1,3 +1,4 @@
|
||||||
import Bookshelf.Sequence.Arithmetic
|
import Bookshelf.Sequence.Arithmetic
|
||||||
import Bookshelf.Sequence.Geometric
|
import Bookshelf.Sequence.Geometric
|
||||||
import Bookshelf.Tuple
|
import Bookshelf.Tuple
|
||||||
|
import Bookshelf.Vector
|
|
@ -0,0 +1,118 @@
|
||||||
|
/-
|
||||||
|
# References
|
||||||
|
|
||||||
|
1. Enderton, Herbert B. A Mathematical Introduction to Logic. 2nd ed. San Diego:
|
||||||
|
Harcourt/Academic Press, 2001.
|
||||||
|
2. Axler, Sheldon. Linear Algebra Done Right. Undergraduate Texts in
|
||||||
|
Mathematics. Cham: Springer International Publishing, 2015.
|
||||||
|
https://doi.org/10.1007/978-3-319-11080-6.
|
||||||
|
-/
|
||||||
|
|
||||||
|
import Mathlib.Tactic.Ring
|
||||||
|
|
||||||
|
universe u
|
||||||
|
|
||||||
|
/--
|
||||||
|
As described in [1], `n`-tuples are defined recursively as such:
|
||||||
|
|
||||||
|
`⟨x₁, ..., xₙ⟩ = ⟨⟨x₁, ..., xₙ₋₁⟩, xₙ⟩`
|
||||||
|
|
||||||
|
We allow for empty tuples; [2] expects this functionality.
|
||||||
|
|
||||||
|
For a `Tuple`-like type with opposite "endian", refer to `Vector`.
|
||||||
|
|
||||||
|
TODO: It would be nice to define `⟨x⟩ = x`. It's not clear to me yet how to do
|
||||||
|
so or whether I could leverage a simple isomorphism everywhere I would like
|
||||||
|
this.
|
||||||
|
-/
|
||||||
|
inductive Tuple : (α : Type u) → (size : Nat) → Type u where
|
||||||
|
| nil : Tuple α 0
|
||||||
|
| snoc : Tuple α n → α → Tuple α (n + 1)
|
||||||
|
|
||||||
|
syntax (priority := high) "t[" term,* "]" : term
|
||||||
|
|
||||||
|
macro_rules
|
||||||
|
| `(t[]) => `(Tuple.nil)
|
||||||
|
| `(t[$x]) => `(Tuple.snoc t[] $x)
|
||||||
|
| `(t[$xs:term,*, $x]) => `(Tuple.snoc t[$xs,*] $x)
|
||||||
|
|
||||||
|
namespace Tuple
|
||||||
|
|
||||||
|
theorem eq_nil : @Tuple.nil α = t[] := rfl
|
||||||
|
|
||||||
|
theorem eq_iff_singleton : (a = b) ↔ (t[a] = t[b]) := by
|
||||||
|
apply Iff.intro
|
||||||
|
· intro h; rw [h]
|
||||||
|
· intro h; injection h
|
||||||
|
|
||||||
|
theorem eq_iff_snoc {t₁ t₂ : Tuple α n}
|
||||||
|
: (a = b ∧ t₁ = t₂) ↔ (snoc t₁ a = snoc t₂ b) := by
|
||||||
|
apply Iff.intro
|
||||||
|
· intro ⟨h₁, h₂ ⟩; rw [h₁, h₂]
|
||||||
|
· intro h
|
||||||
|
injection h with _ h₁ h₂
|
||||||
|
exact And.intro h₂ h₁
|
||||||
|
|
||||||
|
/--
|
||||||
|
Implements decidable equality for `Tuple α m`, provided `a` has decidable equality.
|
||||||
|
-/
|
||||||
|
protected def hasDecEq [DecidableEq α] (t₁ t₂ : Tuple α n) : Decidable (Eq t₁ t₂) :=
|
||||||
|
match t₁, t₂ with
|
||||||
|
| t[], t[] => isTrue eq_nil
|
||||||
|
| snoc as a, snoc bs b =>
|
||||||
|
match Tuple.hasDecEq as bs with
|
||||||
|
| isFalse np => isFalse (fun h => absurd (eq_iff_snoc.mpr h).right np)
|
||||||
|
| isTrue hp =>
|
||||||
|
if hq : a = b then
|
||||||
|
isTrue (eq_iff_snoc.mp $ And.intro hq hp)
|
||||||
|
else
|
||||||
|
isFalse (fun h => absurd (eq_iff_snoc.mpr h).left hq)
|
||||||
|
|
||||||
|
instance [DecidableEq α] : DecidableEq (Tuple α n) := Tuple.hasDecEq
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the number of entries of the `Tuple`.
|
||||||
|
-/
|
||||||
|
def size (_ : Tuple α n) : Nat := n
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns all but the last entry of the `Tuple`.
|
||||||
|
-/
|
||||||
|
def init : Tuple α n → 1 ≤ n → Tuple α (n - 1)
|
||||||
|
| snoc vs _, _ => vs
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the last entry of the `Tuple`.
|
||||||
|
-/
|
||||||
|
def last : Tuple α n → 1 ≤ n → α
|
||||||
|
| snoc _ v, _ => v
|
||||||
|
|
||||||
|
/--
|
||||||
|
Prepends an entry to the start of the `Tuple`.
|
||||||
|
-/
|
||||||
|
def cons : Tuple α n → α → Tuple α (n + 1)
|
||||||
|
| t[], a => t[a]
|
||||||
|
| snoc ts t, a => snoc (cons ts a) t
|
||||||
|
|
||||||
|
/--
|
||||||
|
Join two `Tuple`s together end to end.
|
||||||
|
-/
|
||||||
|
def concat : Tuple α m → Tuple α n → Tuple α (m + n)
|
||||||
|
| t[], ts => cast (by simp) ts
|
||||||
|
| is, t[] => is
|
||||||
|
| is, snoc ts t => snoc (concat is ts) t
|
||||||
|
|
||||||
|
/--
|
||||||
|
Take the first `k` entries from the `Tuple` to form a new `Tuple`.
|
||||||
|
-/
|
||||||
|
def take (t : Tuple α n) (k : Nat) (p : 1 ≤ k ∧ k ≤ n) : Tuple α k :=
|
||||||
|
have _ : 1 ≤ n := Nat.le_trans p.left p.right
|
||||||
|
match t with
|
||||||
|
| @snoc _ n' init last => by
|
||||||
|
by_cases h : k = n' + 1
|
||||||
|
· rw [h]; exact snoc init last
|
||||||
|
· exact take init k (And.intro p.left $
|
||||||
|
have h' : k + 1 ≤ n' + 1 := Nat.lt_of_le_of_ne p.right h
|
||||||
|
by simp at h'; exact h')
|
||||||
|
|
||||||
|
end Tuple
|
|
@ -0,0 +1,54 @@
|
||||||
|
import Mathlib.Tactic.Ring
|
||||||
|
|
||||||
|
/--
|
||||||
|
A list-like structure with its size encoded in the type.
|
||||||
|
|
||||||
|
For a `Vector`-like type with opposite "endian", refer to `Tuple`.
|
||||||
|
-/
|
||||||
|
inductive Vector (α : Type u) : (size : Nat) → Type u where
|
||||||
|
| nil : Vector α 0
|
||||||
|
| cons : α → Vector α n → Vector α (n + 1)
|
||||||
|
|
||||||
|
syntax (priority := high) "v[" term,* "]" : term
|
||||||
|
|
||||||
|
macro_rules
|
||||||
|
| `(v[]) => `(Vector.nil)
|
||||||
|
| `(v[$x]) => `(Vector.cons $x v[])
|
||||||
|
| `(v[$x, $xs:term,*]) => `(Vector.cons $x v[$xs,*])
|
||||||
|
|
||||||
|
namespace Vector
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the number of entries in the `Vector`.
|
||||||
|
-/
|
||||||
|
def size (_ : Vector α n) : Nat := n
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the first entry of the `Vector`.
|
||||||
|
-/
|
||||||
|
def head : Vector α n → 1 ≤ n → α
|
||||||
|
| cons v _, _ => v
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the last entry of the `Vector`.
|
||||||
|
-/
|
||||||
|
def last (v : Vector α n) : 1 ≤ n → α :=
|
||||||
|
fun h =>
|
||||||
|
match v with
|
||||||
|
| nil => by ring_nf at h; exact h.elim
|
||||||
|
| @cons _ n' v vs => if h' : n' > 0 then vs.last h' else v
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns all but the `head` of the `Vector`.
|
||||||
|
-/
|
||||||
|
def tail : Vector α n → 1 ≤ n → Vector α (n - 1)
|
||||||
|
| cons _ vs, _ => vs
|
||||||
|
|
||||||
|
/--
|
||||||
|
Appends an entry to the end of the `Vector`.
|
||||||
|
-/
|
||||||
|
def snoc : Vector α n → α → Vector α (n + 1)
|
||||||
|
| nil, a => v[a]
|
||||||
|
| cons v vs, a => cons v (snoc vs a)
|
||||||
|
|
||||||
|
end Vector
|
|
@ -4,9 +4,9 @@ open Lake DSL
|
||||||
require mathlib from git
|
require mathlib from git
|
||||||
"https://github.com/leanprover-community/mathlib4.git"
|
"https://github.com/leanprover-community/mathlib4.git"
|
||||||
|
|
||||||
package «Common»
|
package «Bookshelf»
|
||||||
|
|
||||||
@[default_target]
|
@[default_target]
|
||||||
lean_lib «Common» {
|
lean_lib «Bookshelf» {
|
||||||
roots := #["Bookshelf"]
|
-- add library configuration options here
|
||||||
}
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
/-
|
|
||||||
# References
|
|
||||||
|
|
||||||
1. Enderton, Herbert B. A Mathematical Introduction to Logic. 2nd ed. San Diego:
|
|
||||||
Harcourt/Academic Press, 2001.
|
|
||||||
-/
|
|
|
@ -1,93 +0,0 @@
|
||||||
/-
|
|
||||||
# References
|
|
||||||
|
|
||||||
1. Enderton, Herbert B. A Mathematical Introduction to Logic. 2nd ed. San Diego:
|
|
||||||
Harcourt/Academic Press, 2001.
|
|
||||||
2. Axler, Sheldon. Linear Algebra Done Right. Undergraduate Texts in
|
|
||||||
Mathematics. Cham: Springer International Publishing, 2015.
|
|
||||||
https://doi.org/10.1007/978-3-319-11080-6.
|
|
||||||
-/
|
|
||||||
|
|
||||||
import Mathlib.Tactic.Ring
|
|
||||||
|
|
||||||
universe u
|
|
||||||
|
|
||||||
/--[1]
|
|
||||||
An `n`-tuple is defined recursively as:
|
|
||||||
|
|
||||||
`⟨x₁, ..., xₙ₊₁⟩ = ⟨⟨x₁, ..., xₙ⟩, xₙ₊₁⟩`
|
|
||||||
|
|
||||||
As [1] notes, it is useful to define `⟨x⟩ = x`. It is not clear this would be
|
|
||||||
possible in Lean though.
|
|
||||||
|
|
||||||
Though [1] does not describe a notion of an empty tuple, [2] does (though under
|
|
||||||
the name of a "list").
|
|
||||||
--/
|
|
||||||
inductive Tuple : (α : Type u) → Nat → Type u where
|
|
||||||
| nil : Tuple α 0
|
|
||||||
| snoc : {n : Nat} → Tuple α n → α → Tuple α (n + 1)
|
|
||||||
|
|
||||||
syntax (priority := high) "⟨" term,+ "⟩" : term
|
|
||||||
|
|
||||||
-- Notice the ambiguity this syntax introduces. For example, pattern `⟨a, b⟩`
|
|
||||||
-- could refer to a `2`-tuple or an `n`-tuple, where `a` is an `(n-1)`-tuple.
|
|
||||||
macro_rules
|
|
||||||
| `(⟨$x⟩) => `(Tuple.snoc Tuple.nil $x)
|
|
||||||
| `(⟨$xs:term,*, $x⟩) => `(Tuple.snoc ⟨$xs,*⟩ $x)
|
|
||||||
|
|
||||||
namespace Tuple
|
|
||||||
|
|
||||||
def length : Tuple α n → Nat
|
|
||||||
| Tuple.nil => 0
|
|
||||||
| Tuple.snoc init _ => length init + 1
|
|
||||||
|
|
||||||
theorem nil_length_zero : length (@Tuple.nil α) = 0 :=
|
|
||||||
rfl
|
|
||||||
|
|
||||||
theorem snoc_length_succ : length (Tuple.snoc init last) = length init + 1 :=
|
|
||||||
rfl
|
|
||||||
|
|
||||||
theorem tuple_length {n : Nat} (t : Tuple α n) : length t = n :=
|
|
||||||
Tuple.recOn t nil_length_zero
|
|
||||||
fun _ _ ih => by
|
|
||||||
rw [snoc_length_succ]
|
|
||||||
norm_num
|
|
||||||
exact ih
|
|
||||||
|
|
||||||
def head : {n : Nat} → Tuple α n → n ≥ 1 → α
|
|
||||||
| n + 1, Tuple.snoc init last, h => by
|
|
||||||
by_cases k : 0 = n
|
|
||||||
· exact last
|
|
||||||
· have h' : 0 ≤ n := Nat.le_of_succ_le_succ h
|
|
||||||
exact head init (Nat.lt_of_le_of_ne h' k)
|
|
||||||
|
|
||||||
def last : Tuple α n → n ≥ 1 → α
|
|
||||||
| Tuple.snoc _ last, _ => last
|
|
||||||
|
|
||||||
def index : {n : Nat} → Tuple α n → (k : Nat) → 1 ≤ k ∧ k ≤ n → α
|
|
||||||
| 0, _, m, h => by
|
|
||||||
have ff : 1 ≤ 0 := Nat.le_trans h.left h.right
|
|
||||||
ring_nf at ff
|
|
||||||
exact False.elim ff
|
|
||||||
| n + 1, Tuple.snoc init last, k, h => by
|
|
||||||
by_cases hₖ : k = n + 1
|
|
||||||
· exact last
|
|
||||||
· exact index init k $ And.intro
|
|
||||||
h.left
|
|
||||||
(Nat.le_of_lt_succ $ Nat.lt_of_le_of_ne h.right hₖ)
|
|
||||||
|
|
||||||
/-
|
|
||||||
|
|
||||||
-- TODO: Prove `eq_by_index`.
|
|
||||||
-- TODO: Prove Lemma 0A [1].
|
|
||||||
|
|
||||||
theorem eq_by_index (t₁ t₂ : Tuple α n)
|
|
||||||
: (t₁ = t₂) ↔ (∀ i : Nat, (p : 1 ≤ i ∧ i ≤ n) → index t₁ i p = index t₂ i p) := by
|
|
||||||
apply Iff.intro
|
|
||||||
· intro teq i hᵢ
|
|
||||||
sorry
|
|
||||||
· sorry
|
|
||||||
|
|
||||||
-/
|
|
||||||
|
|
||||||
end Tuple
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/-
|
||||||
|
# References
|
||||||
|
|
||||||
|
1. Enderton, Herbert B. A Mathematical Introduction to Logic. 2nd ed. San Diego:
|
||||||
|
Harcourt/Academic Press, 2001.
|
||||||
|
-/
|
||||||
|
|
||||||
|
import Bookshelf.Tuple
|
||||||
|
|
||||||
|
/--
|
||||||
|
The following describes a so-called "generic" tuple. Like in `Bookshelf.Tuple`,
|
||||||
|
an `n`-tuple is defined recursively like so:
|
||||||
|
|
||||||
|
`⟨x₁, ..., xₙ⟩ = ⟨⟨x₁, ..., xₙ₋₁⟩, xₙ⟩`
|
||||||
|
|
||||||
|
Unlike `Bookshelf.Tuple`, a "generic" tuple bends the syntax above further. For
|
||||||
|
example, both tuples above are equivalent to:
|
||||||
|
|
||||||
|
`⟨⟨x₁, ..., xₘ⟩, xₘ₊₁, ..., xₙ⟩`
|
||||||
|
|
||||||
|
for some `1 ≤ m ≤ n`. This distinction is purely syntactic, but necessary to
|
||||||
|
prove certain theorems found in [1] (e.g. `lemma_0a`).
|
||||||
|
|
||||||
|
In general, prefer `Bookshelf.Tuple`.
|
||||||
|
-/
|
||||||
|
inductive XTuple : (α : Type u) → (size : Nat × Nat) → Type u where
|
||||||
|
| nil : XTuple α (0, 0)
|
||||||
|
| snoc : XTuple α (p, q) → Tuple α r → XTuple α (p + q, r)
|
||||||
|
|
||||||
|
syntax (priority := high) "x[" term,* "]" : term
|
||||||
|
|
||||||
|
macro_rules
|
||||||
|
| `(x[]) => `(XTuple.nil)
|
||||||
|
| `(x[$x]) => `(XTuple.snoc x[] t[$x])
|
||||||
|
| `(x[x[$xs:term,*], $ys:term,*]) => `(XTuple.snoc x[$xs,*] t[$ys,*])
|
||||||
|
| `(x[$x, $xs:term,*]) => `(XTuple.snoc x[] t[$x, $xs,*])
|
||||||
|
|
||||||
|
namespace XTuple
|
||||||
|
|
||||||
|
/--
|
||||||
|
Converts an `XTuple` into "normal form".
|
||||||
|
-/
|
||||||
|
def norm : XTuple α (m, n) → Tuple α (m + n)
|
||||||
|
| x[] => t[]
|
||||||
|
| snoc x[] ts => cast (by simp) ts
|
||||||
|
| snoc is ts => is.norm.concat ts
|
||||||
|
|
||||||
|
/--
|
||||||
|
Casts a tuple indexed by `m` to one indexed by `n`.
|
||||||
|
-/
|
||||||
|
theorem cast_eq_size : (m = n) → (Tuple α m = Tuple α n) :=
|
||||||
|
fun h => by rw [h]
|
||||||
|
|
||||||
|
/--
|
||||||
|
Implements Boolean equality for `XTuple α n` provided `α` has decidable
|
||||||
|
equality.
|
||||||
|
-/
|
||||||
|
instance BEq [DecidableEq α] : BEq (XTuple α n) where
|
||||||
|
beq t₁ t₂ := t₁.norm == t₂.norm
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the number of entries in the `XTuple`.
|
||||||
|
-/
|
||||||
|
def size (_ : XTuple α n) := n
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the number of entries in the "shallowest" portion of the `XTuple`. For
|
||||||
|
example, the length of `x[x[1, 2], 3, 4]` is `3`, despite its size being `4`.
|
||||||
|
-/
|
||||||
|
def length : XTuple α n → Nat
|
||||||
|
| x[] => 0
|
||||||
|
| snoc x[] ts => ts.size
|
||||||
|
| snoc _ ts => 1 + ts.size
|
||||||
|
|
||||||
|
/--
|
||||||
|
Returns the first component of our `XTuple`. For example, the first component of
|
||||||
|
tuple `x[x[1, 2], 3, 4]` is `t[1, 2]`.
|
||||||
|
-/
|
||||||
|
def first : XTuple α (m, n) → 1 ≤ m → Tuple α m
|
||||||
|
| snoc ts _, _ => ts.norm
|
||||||
|
|
||||||
|
section
|
||||||
|
|
||||||
|
variable {k m n : Nat}
|
||||||
|
variable (p : n + (m - 1) = m + k)
|
||||||
|
variable (qₙ : 1 ≤ n)
|
||||||
|
variable (qₘ : 1 ≤ m)
|
||||||
|
|
||||||
|
namespace Lemma_0a
|
||||||
|
|
||||||
|
lemma aux1 : n = k + 1 := sorry
|
||||||
|
|
||||||
|
lemma aux2 : 1 ≤ m → 1 ≤ k + 1 ∧ k + 1 ≤ m + k := sorry
|
||||||
|
|
||||||
|
end Lemma_0a
|
||||||
|
|
||||||
|
open Lemma_0a
|
||||||
|
|
||||||
|
/--[1]
|
||||||
|
Assume that ⟨x₁, ..., xₘ⟩ = ⟨y₁, ..., yₘ, ..., yₘ₊ₖ⟩. Then x₁ = ⟨y₁, ..., yₖ₊₁⟩.
|
||||||
|
-/
|
||||||
|
theorem lemma_0a (xs : XTuple α (n, m - 1)) (ys : Tuple α (m + k))
|
||||||
|
: (cast (cast_eq_size p) xs.norm = ys)
|
||||||
|
→ (cast (cast_eq_size aux1) (xs.first qₙ) = ys.take (k + 1) (aux2 qₘ))
|
||||||
|
:= sorry
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end XTuple
|
|
@ -0,0 +1,28 @@
|
||||||
|
{"version": 4,
|
||||||
|
"packagesDir": "lake-packages",
|
||||||
|
"packages":
|
||||||
|
[{"path": {"name": "Bookshelf", "dir": "./../bookshelf"}},
|
||||||
|
{"git":
|
||||||
|
{"url": "https://github.com/leanprover-community/mathlib4.git",
|
||||||
|
"subDir?": null,
|
||||||
|
"rev": "7e974fd3806866272e9f6d9e44fa04c210a21f87",
|
||||||
|
"name": "mathlib",
|
||||||
|
"inputRev?": null}},
|
||||||
|
{"git":
|
||||||
|
{"url": "https://github.com/gebner/quote4",
|
||||||
|
"subDir?": null,
|
||||||
|
"rev": "7ac99aa3fac487bec1d5860e751b99c7418298cf",
|
||||||
|
"name": "Qq",
|
||||||
|
"inputRev?": "master"}},
|
||||||
|
{"git":
|
||||||
|
{"url": "https://github.com/JLimperg/aesop",
|
||||||
|
"subDir?": null,
|
||||||
|
"rev": "ba61f7fec6174d8c7d2796457da5a8d0b0da44c6",
|
||||||
|
"name": "aesop",
|
||||||
|
"inputRev?": "master"}},
|
||||||
|
{"git":
|
||||||
|
{"url": "https://github.com/leanprover/std4",
|
||||||
|
"subDir?": null,
|
||||||
|
"rev": "de7e2a79905a3f87cad1ad5bf57045206f9738c7",
|
||||||
|
"name": "std",
|
||||||
|
"inputRev?": "main"}}]}
|
|
@ -3,6 +3,8 @@ open Lake DSL
|
||||||
|
|
||||||
package «mathematical-introduction-logic»
|
package «mathematical-introduction-logic»
|
||||||
|
|
||||||
|
require Bookshelf from "../bookshelf"
|
||||||
|
|
||||||
@[default_target]
|
@[default_target]
|
||||||
lean_lib «MathematicalIntroductionLogic» {
|
lean_lib «MathematicalIntroductionLogic» {
|
||||||
-- add library configuration options here
|
-- add library configuration options here
|
Loading…
Reference in New Issue