In programming language theory, the structured program theorem, generally called the Böhm–Jacopini theorem, states that a class of control-flow graphs (historically called flowcharts in this context) can compute any computable function using only the following three control structures to combine subprograms (statements and blocks):

Sequence Executing one subprogram, and then another subprogram Selection Executing one of two subprograms according to the value of a boolean expression Iteration Repeatedly executing a subprogram as long as a boolean expression is true

More precise definitions are listed in the next section.

The structured chart subject to these constraints, particularly the loop constraint implying a single exit (as described later in this article), may however use additional variables in the form of bits (stored in an extra integer variable in the original proof) in order to keep track of information that the original program represents by the program location. The construction was based on Böhm's programming language P′′.

The theorem forms the basis of structured programming, a programming paradigm which eschews the goto statement, exclusively using other control semantics for selection and iteration.

Origin and variants In 1964, Corrado Böhm had defined a simple Turing-complete programming language (P′′), based on sequence and iteration. In a subsequent paper, Böhm and restated this result.

The structured program theorem is typically credited to that 1966 paper. Harel wrote in 1980 that the Böhm–Jacopini paper enjoyed "universal popularity", particularly with proponents of structured programming. Harel also noted that "due to its rather technical style [the 1966 Böhm–Jacopini paper] is apparently more often cited than read in detail", and after reviewing a large number of papers published up to 1980, Harel argued that the contents of the Böhm–Jacopini proof were usually misrepresented as a folk theorem that essentially contains a simpler result, a result which itself can be traced to the inception of modern computing theory in the papers of von Neumann and Kleene.

Harel also writes that the more generic name was proposed by H.D. Mills as "The Structure Theorem" in the early 1970s.

The evolution of the theorem was as follows.

1. Böhm 1964 (Program Creation / Computation)

Result Every partial recursive function can be computed by a programThe language P′′ is Turing-complete and meets the requirements. Brainfuck, a fork of P′′, is structured by design as well. using only sequence and iteration.

Notes This result focuses on program generation. Selection is not required: conditional behavior is encoded by loops. P′′ prevents unstructured control flow through language design, enforcing structure at the source. Böhm restates his results in part 2 of Böhm-Jacopini (1966).

2. Böhm–Jacopini 1966 (Program Transformation) Result Every flowchart (control-flow graph, CFG) can be transformed into a structured program using only sequence and iteration. Notes This version of the theorem focuses on program transformation. It is primarily relevant to compiler optimization, rather than to software design decisions. In part 1 of Böhm–Jacopini (1966), Jacopini proves that any control-flow graph (CFG) can be rewritten as a structured graph,A single-entry single-exit (SESE) CFG is "structured" if each subgraph is SESE. using only selection, sequence, and iteration, while preserving the original program’s structure. In part 2, Böhm shows that selection is not strictly necessary: any CFG can be transformed using only sequence and iteration.

Jacopini's proof proceeds by induction on the structure of the flow chart. Because it employed pattern matching in graphs, the proof was not really practical as a program transformation algorithm, and thus opened the door for additional research in this direction.

3. Folk Theorem (Loop-Minimal Transformation) Result Every flowchart is equivalent to a while-program with one occurrence of while-do, provided additional variables are allowed.

Notes This version of the theorem flattens the Böhm–Jacopini transformation, reducing all iteration to one single loop. Selection is reintroduced for clarity, but is theoretically optional. The folk theorem replaces the original program's control flow with a single global while loop that simulates a program counter going over all possible labels (flowchart boxes) in the original non-structured program. Harel traced the origin of this folk theorem to two papers marking the beginning of computing. One is the 1946 description of the von Neumann architecture, which explains how a program counter operates in terms of a while loop. Harel notes that the single loop used by the folk version of the structured programming theorem basically just provides operational semantics for the execution of a flowchart on a von Neumann computer. Another, even older source that Harel traced the folk version of the theorem is Stephen Kleene's normal form theorem from 1936.

p := 1 while p > 0 do if p = 1 then perform step 1 from the flowchart p := resulting successor step number of step 1 from the flowchart (0 if no successor) end if if p = 2 then perform step 2 from the flowchart p := resulting successor step number of step 2 from the flowchart (0 if no successor) end if ... if p = n then perform step n from the flowchart p := resulting successor step number of step n from the flowchart (0 if no successor) end if end while

Donald Knuth criticized this form of the proof, which results in pseudocode like the one above, by pointing out that the structure of the original program is completely lost in this transformation. Similarly, Bruce Ian Mills wrote about this approach that "The spirit of block structure is a style, not a language. By simulating a von Neumann machine, we can produce the behavior of any spaghetti code within the confines of a block-structured language. This does not prevent it from being spaghetti."

4. Modern Textbook Statement Structured programming is frequently stated as Result Every partial recursive function can be computed by a structured program using (selection, ) sequence and iteration; moreover, with suitable encodings of control state, a single while loop suffices. Notes This combines:

Böhm (1964) – who proved that for every partial recursive function there exists a (structured) program P′′ which computes it — establishing the existence of an algorithm rather than rewriting an existing one; Böhm–Jacopini (1966) – which shows that any existing program or flowchart can be rewritten using only selection, sequence, and iteration (with selection in fact redundant); The folklore single-loop result, showing that iteration can be reduced to one loop via explicit control-state encoding.

5. Reversible version The Reversible Structured Program Theorem is an important concept in the field of reversible computing. It posits that any computation achievable by a reversible program can also be accomplished through a reversible program using only a structured combination of control-flow constructs such as sequences, selections, and iterations. Any computation achievable by a traditional, irreversible program can also be accomplished through a reversible program, but with the additional constraint that each step must be reversible and some extra output. Furthermore, any reversible unstructured program can also be accomplished through a structured reversible program with only one iteration without any extra output. This theorem lays the foundational principles for constructing reversible algorithms within a structured programming framework.

For the Structured Program Theorem, both local and global methods of proof are known. However, for its reversible version, while a global method of proof is recognized, a local approach similar to that undertaken by Böhm and Jacopini is not yet known. This distinction is an example that underscores the challenges and nuances in establishing the foundations of reversible computing compared to traditional computing paradigms.

Implications and refinements The Böhm–Jacopini proof did not settle the question of whether to adopt structured programming for software development, partly because the construction was more likely to obscure a program than to improve it. On the contrary, it signaled the beginning of the debate. Edsger Dijkstra's famous letter, Go To Statement Considered Harmful, followed in 1968.

Some academics took a purist approach to the Böhm–Jacopini result and argued that even instructions like break and return from the middle of loops are bad practice as they are not needed in the Böhm–Jacopini proof, and thus they advocated that all loops should have a single exit point. This purist approach is embodied in the Pascal programming language (designed in 1968–1969), which up to the mid-1990s was the preferred tool for teaching introductory programming classes in academia.

Edward Yourdon notes that in the 1970s there was even philosophical opposition to transforming unstructured programs into structured ones by automated means, based on the argument that one needed to think in structured programming fashion from the get go. The pragmatic counterpoint was that such transformations benefited a large body of existing programs. Among the first proposals for an automated transformation was a 1971 paper by Edward Ashcroft and Zohar Manna.

The direct application of the Böhm–Jacopini theorem may result in additional local variables being introduced in the structured chart, and may also result in some code duplication. The latter issue is called the loop-and-a-half problem in this context. Pascal is affected by both of these problems, and according to empirical studies cited by Eric S. Roberts, student programmers had difficulty formulating correct solutions in Pascal for several simple problems, including writing a function for searching an element in an array. A 1980 study by Henry Shapiro cited by Roberts found that using only the Pascal-provided control structures, the correct solution was given by only 20% of the subjects, while no subject wrote incorrect code for this problem if allowed to write a return from the middle of a loop.

In 1973, S. Rao Kosaraju proved that it is possible to avoid adding additional variables in structured programming, as long as arbitrary-depth, multi-level breaks from loops are allowed. Furthermore, Kosaraju proved that a strict hierarchy of programs exists, nowadays called the Kosaraju hierarchy, in that for every integer n, there exists a program containing a multi-level break of depth n that cannot be rewritten as program with multi-level breaks of depth less than n (without introducing additional variables). Kosaraju cites the multi-level break construct to the BLISS programming language. The multi-level breaks, in the form a leave label keyword were actually introduced in the BLISS-11 version of that language; the original BLISS only had single-level breaks. The BLISS family of languages didn't provide an unrestricted goto. The Java programming language would later follow this approach as well.