feat(Foundations/Data): Function view for Turing tapes#499
feat(Foundations/Data): Function view for Turing tapes#499crei wants to merge 3 commits intoleanprover:mainfrom
Conversation
|
Seems like a good addition! My only comment is: Should we add tags like @[ext] or |
chenson2018
left a comment
There was a problem hiding this comment.
This looks straightforward, thanks! Just some style questions.
| obtain ⟨head₂, left₂, right₂⟩ := t₂ | ||
| have h_head : head₁ = head₂ := by simpa [get] using h_get_eq 0 | ||
| have h_right : right₁ = right₂ := by | ||
| apply StackTape.ext_get |
There was a problem hiding this comment.
Should StackTape.ext_get and this theorem have ext attributes?
There was a problem hiding this comment.
After adding the attributes to StackTape.ext and StackTape.ext_get, I can use ext1 p here, but how can I be sure that the ext tactic uses StackTape.ext_get instead of StackTape.ext?
There was a problem hiding this comment.
You're right, even if you remove both it picks up another usage of ext, so maybe this isn't helpful?
Co-authored-by: Chris Henson <46805207+chenson2018@users.noreply.github.com>
chenson2018
left a comment
There was a problem hiding this comment.
A couple more style comments.
| obtain ⟨head₁, left₁, right₁⟩ := t₁ | ||
| obtain ⟨head₂, left₂, right₂⟩ := t₂ | ||
| have h_head : head₁ = head₂ := by simpa [get] using h_get_eq 0 | ||
| have h_right : right₁ = right₂ := by | ||
| apply StackTape.ext_get | ||
| intro p | ||
| simpa [get] using h_get_eq (p + 1) | ||
| have h_left : left₁ = left₂ := by | ||
| apply StackTape.ext_get | ||
| intro p | ||
| simpa [get] using h_get_eq (Int.negSucc p) | ||
| grind |
There was a problem hiding this comment.
It seems clearer to use congr here directly rather than have grind infer this:
| obtain ⟨head₁, left₁, right₁⟩ := t₁ | |
| obtain ⟨head₂, left₂, right₂⟩ := t₂ | |
| have h_head : head₁ = head₂ := by simpa [get] using h_get_eq 0 | |
| have h_right : right₁ = right₂ := by | |
| apply StackTape.ext_get | |
| intro p | |
| simpa [get] using h_get_eq (p + 1) | |
| have h_left : left₁ = left₂ := by | |
| apply StackTape.ext_get | |
| intro p | |
| simpa [get] using h_get_eq (Int.negSucc p) | |
| grind | |
| cases t₁ | |
| congr | |
| · simpa [get] using h_get_eq 0 | |
| · apply StackTape.ext_get | |
| intro p | |
| simpa [get] using h_get_eq (Int.negSucc p) | |
| · apply StackTape.ext_get | |
| intro p | |
| simpa [get] using h_get_eq (p + 1) |
| rw [show Int.ofNat 0 - 1 = Int.negSucc 0 from rfl] | ||
| simp [StackTape.head_eq_getD] |
There was a problem hiding this comment.
For these where you have something like rw [show ... from rfl[, you can also just do
| rw [show Int.ofNat 0 - 1 = Int.negSucc 0 from rfl] | |
| simp [StackTape.head_eq_getD] | |
| simp [StackTape.head_eq_getD] | |
| rfl |
| lemma get_move_left (t : BiTape Symbol) (p : ℤ) : | ||
| (t.move_left).get p = t.get (p - 1) := by |
There was a problem hiding this comment.
Fir on one line, and some parentheses can be removed:
| lemma get_move_left (t : BiTape Symbol) (p : ℤ) : | |
| (t.move_left).get p = t.get (p - 1) := by | |
| lemma get_move_left (t : BiTape Symbol) (p : ℤ) : t.move_left.get p = t.get (p - 1) := by |
| lemma get_move_right (t : BiTape Symbol) (p : ℤ) : | ||
| (t.move_right).get p = t.get (p + 1) := by |
There was a problem hiding this comment.
| lemma get_move_right (t : BiTape Symbol) (p : ℤ) : | |
| (t.move_right).get p = t.get (p + 1) := by | |
| lemma get_move_right (t : BiTape Symbol) (p : ℤ) : t.move_right.get p = t.get (p + 1) := by |
| unfold move_right get | ||
| match p with | ||
| | Int.ofNat n => | ||
| rw [show Int.ofNat n + 1 = Int.ofNat (n + 1) by lia] |
There was a problem hiding this comment.
Is this the preferred way to do these proofs in Mathlib? I rarely work with integers, but this seems very low-level.
The central addition in this PR is
BiTape.get: it allows (integer) index-based access to the Turing tape cells.In addition, adds several lemmas that make it easier to work with
BiTapes by viewing them as functionsℤ → Option Symbol. A sequence of moves and writes translates into a sequence ofFunction.updateand thus maps everything into a domain thatsimpandgrindcan already nicely work with.