-
Notifications
You must be signed in to change notification settings - Fork 0
feat(Computability/MultiTapeTM): input/output tape predicates #162
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
base: multi-tape-tm
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ Authors: Bolton Bailey | |
| module | ||
|
|
||
| public import Cslib.Foundations.Data.StackTape | ||
| public import Mathlib.Algebra.Group.End | ||
| public import Mathlib.Computability.TuringMachine.Tape | ||
| public import Mathlib.Data.Finset.Attr | ||
| public import Mathlib.Tactic.SetLike | ||
|
|
@@ -44,6 +45,7 @@ namespace Turing | |
| A structure for bidirectionally-infinite Turing machine tapes | ||
| that eventually take on blank `none` values | ||
| -/ | ||
| @[ext] | ||
| structure BiTape (Symbol : Type) where | ||
| /-- The symbol currently under the tape head -/ | ||
| head : Option Symbol | ||
|
|
@@ -114,13 +116,95 @@ lemma move_left_move_right (t : BiTape Symbol) : t.move_left.move_right = t := b | |
| lemma move_right_move_left (t : BiTape Symbol) : t.move_right.move_left = t := by | ||
| simp [move_left, move_right] | ||
|
|
||
| @[simp] | ||
| lemma move_left_nil : (nil : BiTape Symbol).move_left = nil := rfl | ||
|
|
||
| @[simp] | ||
| lemma move_right_nil : (nil : BiTape Symbol).move_right = nil := rfl | ||
|
|
||
| @[simp] | ||
| lemma optionMove_nil (m : Option Dir) : (nil : BiTape Symbol).optionMove m = nil := by | ||
| cases m with | ||
| | none => rfl | ||
| | some d => cases d <;> rfl | ||
|
|
||
| /-- The right-move equivalence, with inverse `move_left`. -/ | ||
| def moveEquiv : Equiv.Perm (BiTape Symbol) where | ||
| toFun := move_right | ||
| invFun := move_left | ||
| left_inv := move_right_move_left | ||
| right_inv := move_left_move_right | ||
|
|
||
| /-- Move the head by an integer amount of cells: positive values move right, negative | ||
| values move left. -/ | ||
| def move_int (t : BiTape Symbol) (delta : ℤ) : BiTape Symbol := | ||
| (moveEquiv ^ delta) t | ||
|
|
||
| @[simp] | ||
| lemma move_int_zero_eq_id (t : BiTape Symbol) : | ||
| t.move_int 0 = t := by | ||
| simp [move_int] | ||
|
|
||
| @[simp] | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I would make this a simp. I think it's more useful to have simp lemmas that combine compositions: On the other hand, maybe transforming everything into the function-view first would be best, then |
||
| lemma move_int_one_eq_move_right (t : BiTape Symbol) : | ||
| t.move_int 1 = t.move_right := by | ||
| simp [move_int, moveEquiv] | ||
|
|
||
| @[simp] | ||
| lemma move_int_neg_one_eq_move_left (t : BiTape Symbol) : | ||
| t.move_int (-1) = t.move_left := by | ||
| simp [move_int, moveEquiv] | ||
|
|
||
| @[simp] | ||
| lemma move_int_move_right (t : BiTape Symbol) (delta : ℤ) : | ||
| (t.move_int delta).move_right = t.move_int (delta + 1) := by | ||
| change moveEquiv ((moveEquiv ^ delta) t) = (moveEquiv ^ (delta + 1)) t | ||
| rw [← Equiv.Perm.mul_apply, ← zpow_one_add, add_comm] | ||
|
|
||
| @[simp] | ||
| lemma move_int_move_left (t : BiTape Symbol) (delta : ℤ) : | ||
| (t.move_int delta).move_left = t.move_int (delta - 1) := by | ||
| change (moveEquiv (Symbol := Symbol))⁻¹ ((moveEquiv ^ delta) t) = | ||
| (moveEquiv ^ (delta - 1)) t | ||
| rw [← Equiv.Perm.mul_apply, ← zpow_neg_one, ← zpow_add] | ||
| rw [show -1 + delta = delta - 1 by omega] | ||
|
|
||
| @[simp] | ||
| lemma move_int_move_int (t : BiTape Symbol) (delta₁ delta₂ : ℤ) : | ||
| (t.move_int delta₁).move_int delta₂ = t.move_int (delta₁ + delta₂) := by | ||
| change (moveEquiv ^ delta₂) ((moveEquiv ^ delta₁) t) = | ||
| (moveEquiv ^ (delta₁ + delta₂)) t | ||
| rw [← Equiv.Perm.mul_apply, ← zpow_add, add_comm] | ||
|
|
||
| @[simp] | ||
| lemma move_int_nil (delta : ℤ) : (nil : BiTape Symbol).move_int delta = nil := by | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this could be more easily proven by turning |
||
| cases delta with | ||
| | ofNat n => | ||
| induction n with | ||
| | zero => simp | ||
| | succ n ih => | ||
| rw [show Int.ofNat (n + 1) = (Int.ofNat n : ℤ) + 1 by | ||
| simp [Int.natCast_succ]] | ||
| rw [← move_int_move_right, ih, move_right_nil] | ||
| | negSucc n => | ||
| induction n with | ||
| | zero => simp | ||
| | succ n ih => | ||
| rw [show Int.negSucc (n + 1) = Int.negSucc n - 1 by | ||
| rw [Int.negSucc_eq, Int.negSucc_eq] | ||
| omega] | ||
| rw [← move_int_move_left, ih, move_left_nil] | ||
|
|
||
| end Move | ||
|
|
||
| /-- | ||
| Write a value under the head of the `BiTape`. | ||
| -/ | ||
| def write (t : BiTape Symbol) (a : Option Symbol) : BiTape Symbol := { t with head := a } | ||
|
|
||
| @[simp] | ||
| lemma write_head (t : BiTape Symbol) : t.write t.head = t := rfl | ||
|
|
||
| /-- | ||
| The space used by a `BiTape` is the number of symbols | ||
| between and including the head, and leftmost and rightmost non-blank symbols on the `BiTape`. | ||
|
|
||
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.
This all assumes that we do not write on the first tape. Do you think this could be more self-contained by adding this to MoveThenStays?