feat(Computability/MultiTapeTM): input/output tape predicates#162
feat(Computability/MultiTapeTM): input/output tape predicates#162SamuelSchlesinger wants to merge 2 commits into
Conversation
| -/ | ||
| def canonicalInputTape (s : List Symbol) (p : ℤ) : BiTape Symbol := | ||
| if 0 ≤ p then canonicalInputTapeNat s p.toNat | ||
| else ⟨none, ∅, StackTape.map_some s⟩ |
There was a problem hiding this comment.
It's a bit surprising to me that this cuts off for negative numbers but not for positive numbers beyond the input length. is that intended, or should this be the equivalent of move_int (mk₁ s) p?
| further in direction `d` without returning first. The condition is finitary — both the | ||
| reachability relation and the existential in `MovesOffBlankInDir` range over finite types. | ||
| -/ | ||
| def IsBoundedInDirectionOnTape |
There was a problem hiding this comment.
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?
| in `t` steps has its tape-`0` content in canonical shape `canonicalInputTape s p` for some | ||
| integer position `p ∈ [-1, s.length]`. In particular, the head on tape `0` stays within | ||
| one cell of the input region throughout the trace. -/ | ||
| theorem HasInputTape.head_position_bounded |
There was a problem hiding this comment.
I haven't read through the full file, but I think I understood that this machinery starts with the initial configuration. I try to avoid tm.initCfg because it makes a lot of assumptions that makes the theorems that use it unusable for composition (all tapes except the first are empty, for example). If instead, we just assume "we start with a configuration where the head is inside the input", the theorem could be directly applied in a proof for tm composition.
…position bound Adds read-only input and write-only output tape abstractions for multi-tape Turing machines, plus a proof that the input-tape head position stays within [-1, |input|] across reachable configurations. - StackTape/BiTape: migrated `*_nil` lemmas into BiTape, extended StackTape API used by the new invariants. - MultiTapeTM.HasInputTape / HasOutputTape: predicates characterising read-only input and write-only output tapes. - HeadBoundInvariantAt: Prop-valued structure carrying the position bound, canonical-tape equality, and left/right reachability chains; .initCfg and .step lemmas prove inductivity. - HasInputTape.step_tape0_decompose: factors a step through its predecessor state, eliminating `change`-tactic gymnastics in invariant-preservation proofs. - head_position_bounded: quantitative head-position bound derived from the invariant via iter_step.
2e68228 to
057aa4b
Compare
057aa4b to
697ee60
Compare
| For machines with designated input and output tapes: | ||
|
|
||
| * `MultiTapeTM.HasInputTape`: tape `0` is write-preserving, with a syntactic head-bound | ||
| condition that rules out two consecutive same-direction off-end moves |
There was a problem hiding this comment.
Maybe add: In other words, the machine will not modify the input tape contents and the head will move at most one cell outside the written area. (not 100% happy with the wording)
| * `MultiTapeTM.HasInputTape`: tape `0` is write-preserving, with a syntactic head-bound | ||
| condition that rules out two consecutive same-direction off-end moves | ||
| * `MultiTapeTM.HasOutputTape`: in a machine with at least two tapes, the last tape is write-only | ||
| (`Stmt.IsWriteOnly` on every transition) |
There was a problem hiding this comment.
maybe add: , i.e. after each write, the head moves one cell to the right and does not move otherwise.
|
|
||
| end MultiTapeTM | ||
|
|
||
| /-! |
There was a problem hiding this comment.
Maybe this should all move to a different file?
| t.move_int 0 = t := by | ||
| simp [move_int] | ||
|
|
||
| @[simp] |
There was a problem hiding this comment.
I'm not sure I would make this a simp. I think it's more useful to have simp lemmas that combine compositions:
((t.move_int -1).move_int x).move_int 1 = t.move_int (-1 + x + 1)
On the other hand, maybe transforming everything into the function-view first would be best, then move_right etc is not useful anyway.
| rw [← Equiv.Perm.mul_apply, ← zpow_add, add_comm] | ||
|
|
||
| @[simp] | ||
| lemma move_int_nil (delta : ℤ) : (nil : BiTape Symbol).move_int delta = nil := by |
There was a problem hiding this comment.
I think this could be more easily proven by turning nil into its function view. Although I realize we don't have that here yet....
| /-- | ||
| A predicate preserved by every step of `r` is preserved along any chain of `r`-steps. | ||
| -/ | ||
| lemma RelatesInSteps.invariant {a b : α} {n : ℕ} {P : α → Prop} |
There was a problem hiding this comment.
naming: Maybe mention the word "transitivity"?
| For `n < s.length`, the head reads `some s[n]`; for `n ≥ s.length`, the head reads | ||
| `none`. | ||
| -/ | ||
| def canonicalInputTapeNat (s : List Symbol) (n : ℕ) : BiTape Symbol := |
There was a problem hiding this comment.
I think with move_int, all of the definitions here are redundant. I think it would be better to directly work with (BiTape.mk₁ s).move_int n instead.
| dictated by `tm.tr q`. The intermediate `tm.step ⟨some q, cfg.tapes⟩ = some cfg'` form is | ||
| handy for feeding `MoveThenStaysOnBlank.move`, whose constructor destructures `cfg`. | ||
| -/ | ||
| lemma HasInputTape.step_tape0_decompose |
There was a problem hiding this comment.
I think this lemma and probably some others in this file are overly complicated.
| remains empty. Use `HasOutputTape.relatesInSteps_outputTapeContents` when the stronger | ||
| canonical output shape is needed. | ||
| -/ | ||
| lemma HasOutputTape.relatesInSteps_right_empty |
There was a problem hiding this comment.
I found it easier to work with tm.configs instead of RelatesInSteps - on the other hand, tm.configs only works for deterministic machines...
The stuff we talked about in Discord.