Skip to content

Conversation

@BoltonBailey
Copy link
Contributor

@BoltonBailey BoltonBailey commented Jan 17, 2026

I have now marked this ready for review but it's quite a large PR, reviewers please tell me if I should reorganize things or submit in a different way.

This PR adds a model of Single Tape Turing machines, which inputs and outputs List α for a finite alphabet type α, with the following features:

  • In Cslib/Foundations/Data
    • A file for StackTape, a stack-like data structure for optional alphabet symbols that extends infinitely (in one direction) with blank (none) symbols. Represented as a finite list that tructates the infinite stream of none elements
    • A file for BiTape, a bidirectionally infinite Tape, made from two StackTape
  • In Cslib/Computability/Machines/SingleTapeTuring/Basic.lean
    • structures representing computability within a time bound, and polynomial time computability.
    • Machine that computes the identity function, c.f. Mathlib's Turing.idComputer
    • Machine that computes the composition of the function computed by two individual machines. (Mathlib currently doesn't have this)
      • Proof this machine preserves polynomial time computation

This PR was authored with the support of Claude Code and Project Numina's Lean MCP fork


My Design Notes

While Mathlib has a definition of polynomial time computability based on a more complicated model of TMs, I think it makes sense to have one based on a simple single-tape model here.

Longer term, I would like to try to create a unified framework for talking about TMs with variable amounts of tapes / stacks, so that we can eventually prove theorems about the time and space overhead incurred by switching from one model to another (e.g. 2 tape TMs simulate k-tape TMs with log overhead, 1 tape TMs simulate 2-tape TMs with quadratic overhead, 2-stack machines simulate 1 tape TMs ).

I ultimately did not reuse much if any of the Mathlib infrastructure around Tapes, because of the injectivity issue I described in the docstring.

@BoltonBailey BoltonBailey marked this pull request as draft January 17, 2026 18:18
github-merge-queue bot pushed a commit that referenced this pull request Jan 23, 2026
This PR adds `Reduction.relates{In,Within}Steps`, functions that
communicate whether a relation forms a directed path of length (at most)
`n` between two elements.

Specifically, it includes:

* Definitions of these functions
* Theorems about reflexivity and transitivity
* Theorems that track the growth of ancillary functions with respect to
the relation

These are a prerequisite to defining time bounds, perhaps for multiple
models of computation, but in particular for Turing machines, see PR
#269.

---------

Co-authored-by: Chris Henson <[email protected]>
@BoltonBailey BoltonBailey changed the title feat: Single Tape Binary Turing Machines feat: Single Tape Turing Machines Jan 23, 2026
@BoltonBailey
Copy link
Contributor Author

BoltonBailey commented Jan 30, 2026

I am experiencing some kind of CI error with mk_all, is it right that I should be changing CSLibTests.lean?

@chenson2018
Copy link
Collaborator

I am experiencing some kind of CI error with mk_all, is it right that I should be changing CSLibTests.lean?

Are you passing the --module flag?

@BoltonBailey
Copy link
Contributor Author

No, the error message just told me to run lake exe mk_all

The file 'Cslib.lean' is out of date: run lake exe mk_all to update it

@chenson2018
Copy link
Collaborator

chenson2018 commented Jan 30, 2026

No, the error message just told me to run lake exe mk_all

The file 'Cslib.lean' is out of date: run lake exe mk_all to update it

The docs upstream are likely out of date given how recent this change is.

@chenson2018
Copy link
Collaborator

It looks like you've addressed my suggestions, thank you! Do you mind identifying some of the theorems you are repeatedly passing to grind and adding annotations to them?

@BoltonBailey
Copy link
Contributor Author

Ok I have gone and added grind annotations to the point where I think I haven't used any one lemma more than once, so I guess that's the letter of what you've said. I haven't looked heavily into the different variety of grind annotations though, so I'm a bit nervous that I've left ones out, but I also don't want to add too many annotations (would that cause grind to explode or something?). LMK if you want me to do more research into how to annotate so I can give the best annotations here.

@BoltonBailey
Copy link
Contributor Author

BoltonBailey commented Jan 30, 2026

Like for example length_tail_le {α} (l : StackTape α) : l.tail.length ≤ l.length.

It would seem nice if this would be triggered whenever l.tail.length appears, but not when l.length appears, is there a way of annotating this?

Edit, I guess this is what grind_pattern is for!

@chenson2018
Copy link
Collaborator

Edit, I guess this is what grind_pattern is for!

Yeah in this case I think what you're asking for is grind_pattern length_tail_le => l.tail, which I believe is equivalent to @[grind! .].

@chenson2018
Copy link
Collaborator

chenson2018 commented Jan 31, 2026

Can you also please use scoped with the annotations you have added? (remember that if they are inconveniently nested deep in a namespace, you can add them afterward as an attribute to avoid this)

Edit: I am not sure when, but I remember hearing there will be something like simp sets to make this nicer in the future. We aggressively scope grind annotations for performance reasons.

Copy link
Collaborator

@chenson2018 chenson2018 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for the contribution! I think all my feedback has been addressed. I will wait to merge in case @fmontesi has any comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants