Why was the brainfuck language invented

What makes a language Turing-complete?

What are the minimal language features / structures that make Turing complete?


A Turing tarpit is a kind of esoteric programming language that strives to be Turing complete while using as few elements as possible. Brainfuck is perhaps the most famous tarpit, but there are many.

  • Iota and Jot are functional languages ​​with two and three symbols respectively, based on the SK (I) combinatorial calculation.

  • OISC (One Instruction Set Computer) denotes a type of imperative calculation that requires only one command of one or more arguments, usually "subtract and branch if they are less than or equal to zero" or "reverse, subtract and skip if they borrow" . The x86 MMU implements the previous command and is therefore Turing complete.

In general, an imperative language needs the following to be complete:

  1. A form of conditional repetition or conditional jump (e.g., +)

  2. One way of reading and writing a storage form (e.g. variables, tape)

In order for a lambda calculus-based functional language to be TC, it needs:

  1. The ability to abstract functions via arguments (e.g. lambda abstraction, quotation)

  2. The ability to apply functions to arguments (e.g. reduction)

There are of course other ways of looking at calculations, but these are common models for Turing tarpits. Note that real computers no Universal Turing machines because they do not have unlimited memory. Strictly speaking, these are “bound storage machines”. If you keep adding storage to them, they will asymptotically approach the Turing machines with electricity. Even finite memory machines and finite state machines are useful for computation. They just aren't universal .

Strictly speaking, I / O is not required for the completeness of the Turing. TC only claims that one language can to calculate You want the feature you want, not that it shows You the result. In practice, every useful language has some way of interacting with the world.

From a practical point of view, if you can translate all programs in a Turing-complete language into your language, then your language (as far as I know) must be Turing-complete. If you want to check that a language you have designed is complete, you can simply write a brainf *** to the YourLanguage compiler and prove / demonstrate that it can compile all valid BF programs.

To make things clearer, I mean that in addition to an interpreter for Your Language, you write a compiler (in any language) that can compile any BF program in Your Language (while maintaining the same semantics, of course).

A system can only be regarded as complete if it can do everything that a universal Turing machine can. Since the universal Turing machine should be able to solve every calculable function within a certain period of time, Turing complete systems can do this too.

To check that Turing is complete, you can implement a Turing machine in it. In other words, check that the following can be simulated:

  1. The ability to read and write "variables" (or any data) : Pretty self-explanatory.
  2. The ability to simulate the movement of the read / write head : It is not enough to just retrieve and save variables. It must also be possible to simulate the ability to move the head of the tape to reference other variables. This can often be simulated in programming languages ​​using array data structures (or their equivalent) or, in the case of certain languages ​​such as machine code, by using "pointers" (or their equivalent) to reference other variables.
  3. The ability to simulate a finite state machine : Although not mentioned often, Turing machines are actually a variation of the finite state machines that are widely used in AI development. Alan Turing said the purpose of states is to simulate a person's "different ways of solving problems".
  4. A "halt" state : Although it is often mentioned that a set of rules must be able to repeat itself in order to be considered complete, this is not a really good criterion because the formal definition of what an algorithm is always has to be state algorithms. If they can't close in some way, either Turing isn't complete or the algorithm isn't a computable function. Complete Turing systems, which cannot be technically locked due to the way they work (such as game consoles), circumvent this restriction by being able to "simulate" a hold state in a certain way. Not to be confused with the "hold problem", an undecidable function that it proves. "

These are the actual minimum requirements for a system that can be considered complete. Nothing more, nothing less. If it can't simulate any of these in any way, it's not complete. The methods suggested by others are only a means to an end, as there are several complete Turing systems that do not offer these functions.

Note that there is no known way to create a true complete Turing system. This is because there is no way to really simulate the boundlessness of the Turing machine's belt in physical space.

A programming language is complete when you can count on it. There are not just a number of functions that enable full speech reproduction. Therefore, the answers that say you need loops or that you need variables are wrong because there are languages ​​that have neither a nor a full speech rendition.

Alan Turing developed the Universal Turing Machine. If you can compile a program designed to run on the Universal Machine, then Turing is complete too. This also works indirectly, so you can say that language X is complete when all programs for complete language Y can be translated for X, since all universal Turing machine programs can be translated into a Y program.

The temporal complexity, the spatial complexity, the simple input / output format and the simple writing of programs are not included in the equation, so in theory such a machine can do all the calculations unless the calculations are stopped by power loss or earth swallowed by the sun become.

In order to prove the completeness of the language, an interpreter is usually created for each proven complete language. However, input and output methods are required for this to work, two things that are not really required for a full language. It is sufficient that your program can change its state when it starts and that you can check the memory after the program has stopped.

However, to create a successful language, it needs to be more than complete. This also applies to tarpits. I don't think BrainFuck would have been popular without and.

You can't tell if it will loop or stop.


Explanation: For some inputs, it's impossible to tell in every case (with another Turing machine) whether the thing is looping or eventually stopping unless you run it (which will give you an answer if it stops, but not when it grinds!).

That means you must be able to store a potentially unlimited amount of data - there must be an equivalent to the infinite volume, no matter how tangled! (Otherwise there are a limited number of states and you can then check to see if you've gone through that state before and eventually stop). In general, Turing machines can increase or decrease the size of their state by controllable means.

Since Turing's original Universal Turing machine has an unsolvable stopping problem, your own complete Turing machine must also have an unsolvable stopping problem.

Complete Turing systems can emulate any other complete Turing system. So if you can create an emulator for a known complete Turing system in your system, it proves that your system is also a complete Turing system.

For example, suppose you want to prove that Snakes & Ladders is complete using a board with an infinitely repeating grid pattern (with a different version on top and left). If you know that the Minsky machine is complete with 2 counters (with 2 unlimited counters and 1 state from a finite number), you can construct a corresponding map in which the X and Y positions on the grid are the current value which is 2 counter and the current path is the current state. Bang! You have just proven that Snakes & Ladders Turing are complete.

A necessary condition is a loop with a maximum number of iterations that is not determined before the iteration, or a recursion where the maximum depth of recursion is not determined before the iteration. For example, enough for ... in ... loops, as you can find them in many newer languages, Need out to make the language complete (but they have other means). Note that this does not mean a limited number of iterations or a limited recursion depth, but that the maximum iteration and recursion depth must be calculated in advance.

For example, the Ackermann function cannot be calculated in a language without these features. On the other hand, a lot of highly complex and very useful software can be written without these functions.

On the other hand, with every number of iterations and every precalculated recursion depth, it is not only possible to decide whether a program should stop or not, but rather it becomes stop.

I know this is not the formally correct answer, but if you take the 'minimum' out of 'Turing-complete' and put 'practical' back where it belongs, you'll see the most important characteristics that a programming language has of a distinguish markup language

  • variables
  • Conditions (if / then ...)
  • loopage (loop / break while ...)

come next

  • anonymous and named functions

To test these claims, start with a markup language, e.g. B. HTML. we could invent an HTML + with only variables or only with conditions (MS did this with conditional comments), or some kind of looping construct (which without conditions would probably end up like something). If you do any of these steps, HTML + will do a lot more powerful than regular HTML, but it's still more of a markup than a programming language. With each new feature, you make it less of a declarative than an imperative language.

Striving for minimalism in logic and programming is certainly important and interesting, but if I had to teach n00bies young or old what programming is and how to learn to program, I would hardly start with the full breadth and breadth of the theoretical foundations of Turing completeness . The whole essence of cooking and programming is doing things in the correct order and repeating them until they're done, just like your mom did. that sums it up for me.

On the other hand, I never finished my CS.

We use cookies and other tracking technologies to improve your browsing experience on our website, to show you personalized content and targeted ads, to analyze our website traffic, and to understand where our visitors are coming from.

By continuing, you consent to our use of cookies and other tracking technologies and affirm you're at least 16 years old or have consent from a parent or guardian.

You can read details in our Cookie policy and Privacy policy.