.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/vm/foundations/plot_05_structured_programming.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_vm_foundations_plot_05_structured_programming.py: Structured programming: sequence, selection, iteration (Böhm and Jacopini 1966) =============================================================================== Böhm and Jacopini proved that any flowchart can be rewritten using only three constructs: doing things in sequence, choosing between two branches, and repeating while a condition holds. On a stack machine those are simply straight-line code, a conditional jump (``JZ``) and a backward jump (``JMP``). The assembler lets us write them with labels instead of addresses. What to look for ---------------- The loop computes ``1 + 2 + ... + n`` and agrees with Gauss's formula. The backward jump is what makes iteration possible, and also what makes the running time depend on the input: the gas used grows linearly with n. The history behind this experiment: :doc:`/history/vm_breakthroughs`. .. GENERATED FROM PYTHON SOURCE LINES 23-25 A loop written with labels -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 25-67 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk source = """ # Sum 1 + 2 + ... + n, with n in slot 0 and the sum in slot 1. loop: # iteration: test, body, jump back LOAD 0 JZ done # selection: leave when n reaches 0 LOAD 1 LOAD 0 ADD STORE 1 # sequence: sum = sum + n LOAD 0 PUSH 1 SUB STORE 0 # n = n - 1 JMP loop done: STOP """ program = bk.vm.assemble(source) for address, instruction in enumerate(program): print(address, instruction) sizes = [0, 1, 5, 10, 20, 40, 80] gas = [] for n in sizes: result = bk.vm.execute(program, storage={0: n}) assert result.storage.get(1, 0) == n * (n + 1) // 2 gas.append(result.gas_used) print(gas) assert all( b - a == (sizes[i + 1] - sizes[i]) * 11 for i, (a, b) in enumerate(zip(gas, gas[1:], strict=False)) ) fig, ax = plt.subplots(figsize=(6, 4)) ax.plot(sizes, gas, "o-") ax.set(xlabel="n", ylabel="gas used", title="11 instructions per iteration") fig.tight_layout() .. image-sg:: /api/gallery/vm/foundations/images/sphx_glr_plot_05_structured_programming_001.png :alt: 11 instructions per iteration :srcset: /api/gallery/vm/foundations/images/sphx_glr_plot_05_structured_programming_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none 0 ('LOAD', 0) 1 ('JZ', 11) 2 ('LOAD', 1) 3 ('LOAD', 0) 4 ('ADD', None) 5 ('STORE', 1) 6 ('LOAD', 0) 7 ('PUSH', 1) 8 ('SUB', None) 9 ('STORE', 0) 10 ('JMP', 0) 11 ('STOP', None) [3, 14, 58, 113, 223, 443, 883] .. GENERATED FROM PYTHON SOURCE LINES 68-73 Exercise -------- Add a selection inside the body so that only even numbers are added. (The machine has no MOD: compute ``n - 2 * (n / 2)``.) Which of the three constructs did you use, and where? .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.094 seconds) .. _sphx_glr_download_api_gallery_vm_foundations_plot_05_structured_programming.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/vm/foundations/plot_05_structured_programming.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_05_structured_programming.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_05_structured_programming.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_05_structured_programming.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_