Halting Problems

Org Babel

Code Blocks

At the heart of Babel are Org code blocks. Code blocks are delimited with a special comment syntax. Here is an example code block in Elisp:

#+BEGIN_SRC elisp
  (defun mccarthy91 (n)
     "McCarthy 91 is used as a formal verification test case."
     (if (<= n 100)
         (mccarthy91 (mccarthy91 (+ n 11)))
       (- n 10)))
#+END_SRC

The basic form is simple. A chunk of code is surrounded by #+BEGIN_SRC lang#+END_SRC.

Code blocks can be modified with annotations, switches, and header arguments. The expanded structure follows

#+NAME: <name>
#+BEGIN_SRC <language> <switches> <header arguments>
 <body>
#+END_SRC

Especially useful are header arguments such as :session, :results, and :exports. Header arguments can be placed on the #+BEGIN_SRC line as follows

#+BEGIN_SRC elisp :exports code
 <body>
#+END_SRC

Or they can be placed as code block annotations as follows

#+HEADER: :exports code
#+BEGIN_SRC elisp
 <body>
#+END_SRC

Multiple header blocks can be used in either form.

#+BEGIN_SRC elisp :exports code :results replace table
 <body>
#+END_SRC

#+HEADER: :exports code
#+HEADER: :results replace table
#+BEGIN_SRC elisp
 <body>
#+END_SRC

The :exports header argument is incredibly useful. It controls how the code block is used when exporting. It can simply list its code in the exported document by using :exports code. Or it can evaluate the code and export just the results using :exports results. To include both the code and the results in the exported document use :exports both. Finally the code and the results can be excluded from the exported document using :exports none.

Code Block Variables in Elisp

Simple example shows setting a variable in a header comment.

#+NAME: square_el
#+HEADER: :var x=0
#+BEGIN_SRC elisp
  (* x x)
#+END_SRC

Now we can use #+CALL: to invoke the named code block.

#+CALL: square_el(x=6)

36

Code Block Variables in Python

Now a simple example in Python.

#+NAME: square_py
#+HEADER: :var x=0
#+BEGIN_SRC python
  return x * x
#+END_SRC

Likewise we can use #+CALL: to invoke the named Python code block.

#+CALL: square_py(x=5)

25

Inline Code Block

Code can be evaluated inline using src_lang{code}. Thus to get the current Emacs version use src_elisp{(format "%s" emacs-major-version)}. This document was prepared with Emacs 26.

Inline Code Block with Arguments

Inline code with arguments has the form src_lang[args]{code}. Thus we can assign a variable inline like so src_elisp[:var x=25]{(sqrt x)} can be used to show that \( \sqrt{25} = \) 5.0.

Named Inline Calls

Named code blocks can be called in a similar fashion and syntax used for inline code blocks. The form is call_name() or the expanded form call_name[inside-header-args](args)[end-header-args].

#+NAME: mcpython91
#+BEGIN_SRC python :var in_from_org=0 :exports none
 def mccarthy91(n):
     "McCarthy 91 is used as a formal verification test case."
     if n <= 100:
         return mccarthy91(mccarthy91(n + 11))
     else:
         return n - 10

 return mccarthy91(in_from_org)
#+END_SRC

The McCarthy 91 function with the argument 4 evaluates to 91 and with the argument 246 evaluates to 236.

Likewise the following are true

  • call_mcpython91(0) = 91
  • call_mcpython91(1) = 91
  • call_mcpython91(85) = 91
  • call_mcpython91(101) = 91
  • call_mcpython91(102) = 92
  • call_mcpython91(185) = 175

The McCarthy 91 function has the property \( \forall n \in \mathbb{N} \), if \( n \leq 100 \) then \( f(n) = 91 \) else \( f(n) = n - 10 \).

Use a Org table as Input

Take from Org Babel: Introduction.

Given this table of numbers

1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20

It is expressed in an Org file like so

#+TBLNAME: fibonacci-inputs
| 1 | 2 | 3 | 4 |  5 |  6 |  7 |  8 |  9 | 10 |
| 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 |

We can use the table named fibonacci-inputs as inputs to a Fibonacci function called while we "map" the rows' values to \( f(n) \).

  (defun fibonacci (n)
    (if (< n 2) n
      (+ (fibonacci (- n 1)) (fibonacci (- n 2)))))

  (mapcar (lambda (row)
            (mapcar #'fibonacci row)) fib-inputs)

In an Org file that looks like so

#+NAME: fibonacci-seq
#+HEADER: :exports both
#+BEGIN_SRC elisp :var fib-inputs=fibonacci-inputs
 (defun fibonacci (n)
   (if (< n 2) n
     (+ (fibonacci (- n 1)) (fibonacci (- n 2)))))

 (mapcar (lambda (row)
           (mapcar #'fibonacci row)) fib-inputs)
#+END_SRC

And produces the following table of Fibonacci numbers

1 1 2 3 5 8 13 21 34 55
1 3 8 21 55 144 377 987 2584 6765

Preview Variable or Tangle Expansion/Substitution

Use C-c C-v v or C-c C-v C-v to preview the expanded content with org-babel-expand-src-block.

Pascals Triangle in Python

Taken from a journal paper on reproducible research.

  def pascals_triangle(n):
      if n == 0:
          return [[1]]
      prev_triangle = pascals_triangle(n-1)
      prev_row = prev_triangle[n-1]
      this_row = map(sum, zip([0] + prev_row, prev_row + [0]))
      return prev_triangle + [this_row]

  return pascals_triangle(n)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

Last modified: 2020-01-20 00:00:00 +0000 UTC