Files
ioccc/2012/tromp/index.html
T
Landon Curt Noll a2e351d175 move Thanks for the help link under About
We move the "_Thanks for the help_" out from under the "Entries"
menu and under the "About" menu to better balance the menus.
Besides, "_Thanks for the help_" is more **about** the IOCCC itself.
2024-10-25 20:28:13 -07:00

943 lines
40 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- START: two lines up starts content from: inc/top.default.html -->
<!-- END: this line ends content from: inc/top.default.html -->
<!-- START: this line starts content from: inc/head.default.html -->
<head>
<link rel="stylesheet" href="../../ioccc.css">
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>2012/tromp - Most functional</title>
<link rel="icon" type="image/x-icon" href="../../favicon.ico">
<meta name="description" content="2012 IOCCC entry tromp - Most functional">
<meta name="keywords" content="IOCCC, 2012, IOCCC 2012, IOCCC entry, tromp, Most functional">
</head>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- END: this line ends content from: inc/head.default.html -->
<!-- -->
<!-- This web page was formed via the tool: bin/readme2index.sh -->
<!-- The content of main section of this web page came from: 2012/tromp/README.md -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2012/tromp/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2012/tromp/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2012/tromp/README.md !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- Markdown content was converted into HTML via the tool: bin/md2html.sh -->
<!-- START: this line starts content from: inc/body.default.html -->
<body>
<!-- END: this line ends content from: inc/body.default.html -->
<!-- START: this line starts content from: inc/topbar.default.html -->
<div class="theader">
<nav class="topbar">
<div class="container">
<div class="logo">
<a href="../../index.html" class="logo-link">
IOCCC
</a>
</div>
<div class="topbar-items">
<div class="item">
<span class="item-header">
Entries
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../years.html" class="sub-item-link">
Winning entries
</a>
</div>
<div class="outfit-font">
<a href="../../authors.html" class="sub-item-link">
Winning authors
</a>
</div>
<div class="outfit-font">
<a href="../../location.html" class="sub-item-link">
Location of authors
</a>
</div>
<div class="outfit-font">
<a href="../../bugs.html" class="sub-item-link">
Bugs and (mis)features
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_an_entry" class="sub-item-link">
Fixing entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_author" class="sub-item-link">
Updating author info
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
Status
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../news.html" class="sub-item-link">
News
</a>
</div>
<div class="outfit-font">
<a href="../../status.html" class="sub-item-link">
Contest status
</a>
</div>
<div class="outfit-font">
<a href="../../next/index.html" class="sub-item-link">
Rules and guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../markdown.html" class="sub-item-link">
Markdown guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../SECURITY.html" class="sub-item-link">
Security policy
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
FAQ
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../faq.html" class="sub-item-link">
Frequently Asked Questions
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#submit" class="sub-item-link">
How to enter
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#compiling" class="sub-item-link">
Compiling entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#running_entries" class="sub-item-link">
Running entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#help" class="sub-item-link">
How to help
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
About
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../index.html" class="sub-item-link">
Home page
</a>
</div>
<div class="outfit-font">
<a href="../../about.html" class="sub-item-link">
About the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../judges.html" class="sub-item-link">
The Judges
</a>
</div>
<div class="outfit-font">
<a href="../../thanks-for-help.html" class="sub-item-link">
Thanks for the help
</a>
</div>
<div class="outfit-font">
<a href="../../contact.html" class="sub-item-link">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</nav>
<div class="header-mobile-menu">
<noscript>
<a href="../../nojs-menu.html" class="topbar-js-label">
Please Enable JavaScript
</a>
</noscript>
<button id="header-open-menu-button" class="topbar-mobile-menu">
<img
src="../../png/hamburger-icon-open.png"
alt="hamburger style menu icon - open state"
width=48
height=48>
</button>
<button id="header-close-menu-button" class="hide-content">
<img
src="../../png/hamburger-icon-closed.png"
alt="hamburger style menu icon - closed state"
width=48
height=48>
</button>
<div id="mobile-menu-panel" class="hide-content">
<div class="mobile-menu-container">
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Entries
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../years.html">
Winning entries
</a>
<a class="mobile-submenu-item" href="../../authors.html">
Winning authors
</a>
<a class="mobile-submenu-item" href="../../location.html">
Location of authors
</a>
<a class="mobile-submenu-item" href="../../bugs.html">
Bugs and (mis)features
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_an_entry">
Fixing entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_author">
Updating author info
</a>
<a class="mobile-submenu-item" href="../../thanks-for-help.html">
Thanks for the help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Status
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../news.html">
News
</a>
<a class="mobile-submenu-item" href="../../status.html">
Contest status
</a>
<a class="mobile-submenu-item" href="../../next/index.html">
Rules and guidelines
</a>
<a class="mobile-submenu-item" href="../../markdown.html">
Markdown guidelines
</a>
<a class="mobile-submenu-item" href="../../SECURITY.html">
Security policy
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
FAQ
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../faq.html">
Frequently Asked Questions
</a>
<a class="mobile-submenu-item" href="../../faq.html#submit">
How to enter
</a>
<a class="mobile-submenu-item" href="../../faq.html#compiling">
Compiling entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#running_entries">
Running entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#help">
How to help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
About
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../index.html">
Home page
</a>
<a class="mobile-submenu-item" href="../../about.html">
About the IOCCC
</a>
<a class="mobile-submenu-item" href="../../judges.html">
The Judges
</a>
<a class="mobile-submenu-item" href="../../contact.html">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var headerOpenMenuButton = document.getElementById("header-open-menu-button");
var headerCloseMenuButton = document.getElementById("header-close-menu-button");
var mobileMenuPanel = document.getElementById("mobile-menu-panel");
headerOpenMenuButton.addEventListener("click", () => {
headerOpenMenuButton.classList.remove("topbar-mobile-menu");
headerOpenMenuButton.classList.add("hide-content");
headerCloseMenuButton.classList.remove("hide-content");
headerCloseMenuButton.classList.add("topbar-mobile-menu");
mobileMenuPanel.classList.remove("hide-content");
mobileMenuPanel.classList.add("topbar-mobile-panel");
});
headerCloseMenuButton.addEventListener("click", () => {
headerCloseMenuButton.classList.remove("topbar-mobile-menu");
headerCloseMenuButton.classList.add("hide-content");
mobileMenuPanel.classList.add("hide-content");
mobileMenuPanel.classList.remove("topbar-mobile-panel");
headerOpenMenuButton.classList.add("topbar-mobile-menu");
headerOpenMenuButton.classList.remove("hide-content");
});
</script>
<!-- END: this line ends content from: inc/topbar.default.html -->
<!-- START: this line starts content from: inc/header.default.html -->
<div class="header">
<a href="../../2011/zucker/index.html">
<img src="../../png/ioccc.png"
alt="IOCCC image by Matt Zucker"
width=300
height=110>
</a>
<h1>The International Obfuscated C Code Contest</h1>
<h2>2012/tromp - Most functional</h2>
<h3>Lambda interpreter</h3>
</div>
<!-- END: this line ends content from: inc/header.default.html -->
<!-- START: this line starts content from: inc/navbar.mid.html -->
<div class="navbar">
<a class="Left" href="../omoikane/index.html">&larr; 2012/omoikane</a>
<a class="Left" href="../index.html">&uarr; 2012 &uarr;</a>
<a class="Left" href="../vik/index.html">2012/vik &rarr;</a>
<a class="Right" href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/tromp.c">C code</a>
<a class="Right" href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/Makefile">Makefile</a>
<a class="Right" href="#inventory">Inventory</a>
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2012%2Ftromp%2Findex.html">&#x2713;</a>
</div>
<!-- END: this line ends content from: inc/navbar.mid.html -->
<!-- START: this line starts content from: inc/before-content.default.html -->
<div class="content" id="content">
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-author.sh -->
<h2 id="author">Author:</h2>
<ul>
<li>Name: <a href="../../authors.html#John_Tromp">John Tromp</a><br>
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)</li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
<!-- END: this line ends content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- BEFORE: 1st line of markdown file: 2012/tromp/README.md -->
<h2 id="to-build">To build:</h2>
<pre><code> make all # On a 64-bit machine (default)
make tromp32 # On a 32-bit machine</code></pre>
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
<p>The current status of this entry is:</p>
<blockquote>
<p><strong>STATUS: INABIAF - please DO NOT fix</strong></p>
</blockquote>
<p>For more detailed information see <a href="../../bugs.html#2012_tromp">2012/tromp in bugs.html</a>.</p>
<h2 id="to-use">To use:</h2>
<pre><code> ./tromp [-b]</code></pre>
<p>Use <code>./tromp32</code> as you would <code>./tromp</code> if on a 32-bit machine.</p>
<h2 id="to-use-1">To use:</h2>
<pre><code> cat ascii-prog.blc data | ./tromp -b
cat binary-prog.Blc data | ./tromp</code></pre>
<h2 id="try">Try:</h2>
<pre><code> ./try.sh</code></pre>
<h2 id="judges-remarks">Judges’ remarks:</h2>
<p>The judges dare to say that the data files this entry is processing
are more obfuscated than the entry itself.</p>
<h2 id="authors-remarks">Author’s remarks:</h2>
<p>This program celebrates the close connection between obfuscation and conciseness,
by implementing the most concise language known, BLC:
<a href="https://tromp.github.io/cl/Binary_lambda_calculus.html">Binary Lambda Calculus</a>.</p>
<p><a href="https://tromp.github.io/cl/Binary_lambda_calculus.html">BLC</a> was developed to
make <a href="https://en.wikipedia.org/wiki/Algorithmic_information_theory">Algorithmic Information
Theory</a>, the
theory of smallest programs, more concrete. It starts with the simplest model of
computation, the <a href="https://en.wikipedia.org/wiki/Lambda_calculus">lambda
calculus</a>, and adds the minimum
amount of machinery to enable binary input and output.</p>
<p>More specifically, it defines a universal machine, which, from an input stream
of bits, parses the binary encoding of a <a href="https://en.wikipedia.org/wiki/Lambda_calculus">lambda
calculus</a> term, applies that to
the remainder of input (translated to a lazy list of
<a href="https://en.wikipedia.org/wiki/Boolean_algebra">booleans</a>, which have a standard
representation in lambda calculus), and translates the evaluated result back
into a stream of bits to be output.</p>
<p>Lambda is encoded as 00, application as 01, and the variable bound by the <code>n</code>th
enclosing lambda (denoted <code>n</code> in so-called <a href="https://en.wikipedia.org/wiki/De_Bruijn_notation">De Bruijn</a>
notation) as <code>1^{n}0</code>.
That’s all there is to
<a href="https://tromp.github.io/cl/Binary_lambda_calculus.html">BLC</a>!</p>
<p>For example the encoding of lambda term <code>S = \x \y \z (x z) (y z)</code>,
with <a href="https://en.wikipedia.org/wiki/De_Bruijn_notation">De Bruijn notation</a>:</p>
<pre><code> \ \ \ (3 1) (2 1)`, is `00 00 00 01 01 1110 10 01 110 10</code></pre>
<p>In the closely related
<a href="https://tromp.github.io/cl/Binary_lambda_calculus.html#BLC8:_byte_sized_I.2FO">BLC8</a>
language, I/O is byte oriented, translating between a stream of bytes and a list
of length-8 lists of <a href="https://en.wikipedia.org/wiki/Boolean_algebra">booleans</a>.</p>
<p>The submission implements the universal machine in the most concise manner conceivable.
It lacks <code>#define</code>s and <code>#include</code>s, and compiles to a (stripped) executable of
under 6K in size.</p>
<p>Without arguments, it runs in byte mode, using standard input and output.
With one (arbitrary) argument, it runs in bit mode, using only the least significant
bit of input, and using characters <code>0</code> and <code>1</code> for output.</p>
<p>The program uses the following exit codes:</p>
<pre><code> 0: OK; result is a finite list
5: Out of term space
6: Out of memory
1,2,3,4,8,9: result not in list form</code></pre>
<p>The size of the term space is fixed at compile time with <code>-DA</code>.</p>
<h3 id="a-half-byte-cat">A half byte <code>cat</code></h3>
<p>The shortest (closed) lambda calculus term is <code>\x x (\ 1</code> in
<a href="https://en.wikipedia.org/wiki/De_Bruijn_notation">De Bruijn</a> notation which is the
identity function. When its encoding <code>0010</code> is fed into the universal machine,
it will simply copy the input to the output (well, not that simply, since each
byte is smashed to bits and rebuilt from scratch). Voila: a half byte cat:</p>
<pre><code> $ echo &quot; Hello, world&quot; | ./tromp
Hello, world</code></pre>
<p>Since the least significant 4 bits of the first byte are just arbitrary padding
that is ignored by the program, any character from ASCII 32 (space) through 47
(<code>/</code>) will do, e.g.:</p>
<pre><code> $ echo &quot;*Hello, world&quot; | ./tromp
Hello, world</code></pre>
<h3 id="bad-programs">Bad programs</h3>
<p>If the input doesn’t start with a valid program, that is,
if the interpreter reaches end-of-file during program parsing,
it will crash in some way. E.g. the following might dump core:</p>
<pre><code> echo -n &quot;U&quot; | ./tromp</code></pre>
<p>Furthermore, the interpreter requires the initial encoded lambda term to be
closed, that is, variable <code>n</code> can only appear within at least <code>n</code> enclosing
lambdas. For instance, here the term <code>\ 5</code> is not closed, causing the
interpreter to crash when looking into a null-pointer environment:</p>
<pre><code> echo &quot;&gt;Hello, world&quot; | ./tromp</code></pre>
<p>will likely dump core.</p>
<p>Since these properties can be checked when creating
<a href="https://tromp.github.io/cl/Binary_lambda_calculus.html">BLC</a> programs,
the interpreter doesn’t bother checking for it.</p>
<h3 id="a-self-interpreter">A Self Interpreter</h3>
<p>The <a href="https://tromp.github.io/cl/Binary_lambda_calculus.html">BLC</a> universal
machine may be small at 650 bytes of C (952 bytes including layout), but written
as a self interpreter in BLC it is downright minuscule at 232 bits (29 bytes):</p>
<pre><code> 01010001
10100000
00010101
10000000
00011110
00010111
11100111
10000101
11001111
000000111
10000101101
1011100111110
000111110000101
11101001 11010010
11001110 00011011
00001011 11100001
11110000 11100110
11110111 11001111
01110110 00011001
00011010 00011010</code></pre>
<p>The byte oriented BLC8 version weighs in at 43 bytes (shown in hexadecimal).</p>
<pre><code> 19468
05580
05f00
bfe5f
85f3f
03c2d
b9fc3f8
5e9d65e5f
0decb f0fc3
9befe 185f7
0b7fb 00cf6
7bb03 91a1a
</code></pre>
<pre><code> $ (cat uni8.Blc; echo &quot; Ni hao&quot;) | ./tromp
Ni hao</code></pre>
<h3 id="a-prime-number-sieve">A prime number sieve</h3>
<p>Even shorter than the self-interpreter is this prime number sieve in 167 bits
(under 21 bytes):</p>
<pre><code> 000100011001100101000110100
000000101100000100100010101
11110111 101001000
11010000 111001101
000000000010110111001110011
11111011110000000011111001
10111000
00010110
0000110110
</code></pre>
<p>The <code>n</code>th bit in the output indicates whether n is prime:</p>
<pre><code> $ cat primes.blc | ./tromp -b | head -c 70
0011010100010100010100010000010100000100010100010000010000010100000100</code></pre>
<p>For those who prefer to digest their primes in decimal, there is <code>oddindices.Blc</code>,
which will print the indices of all odd characters (with
<a href="https://en.wikipedia.org/wiki/Bit_numbering">LSB</a> = 1)
separated by a given character:</p>
<pre><code> $ (cat oddindices.Blc; echo -n &quot; &quot;; cat primes.blc | ./tromp -b) | ./tromp | head -c 70
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97</code></pre>
<h3 id="a-space-filling-program">A Space filling program</h3>
<p>The program <code>hilbert.Blc</code>, at 143 bytes, is a very twisty “one-liner” (shown in hexadecimal):</p>
<pre><code> 1818181 8111154 6806041 55ff041
9d f9 de 16 ff fe 5f 3f
ef f615ff9 46 84 058117e 05
cb fe bc bf
ee86cb9 4681600 5c0bfac bfbf71a
85 e0 5c f4
14d5fe0 8180b048d0800e078 016445f
fe 5f
f7 ffffe5fff2fc 02f7ad97f5bf ff
ff bf ff ca af ff
7817ffa df76695 4680601 57f7e16
05 c1
3fe80b2 2c18581 bfe5c10 42ff805
de ec 06 c2 c0 c0
60 8191a00167fb cbcfdf65f7c0 a20</code></pre>
<p>It expects <code>n</code> arbitrary characters of input, and draws a space filling <a href="https://en.wikipedia.org/wiki/Hilbert_curve">Hilbert
curve</a> of order <code>n</code>:</p>
<pre><code> $ (cat hilbert.Blc; echo -n &quot;1&quot;) | ./tromp
_
| |
$ (cat hilbert.Blc; echo -n &quot;12&quot;) | ./tromp
_ _
| |_| |
|_ _|
_| |_
$ (cat hilbert.Blc; echo -n &quot;123&quot;) | ./tromp
_ _ _ _
| |_| | | |_| |
|_ _| |_ _|
_| |_____| |_
| ___ ___ |
|_| _| |_ |_|
_ |_ _| _
| |___| |___| |
$ (cat hilbert.Blc; echo -n &quot;1234&quot;) | ./tromp
_ _ _ _ _ _ _ _
| |_| | | |_| | | |_| | | |_| |
|_ _| |_ _| |_ _| |_ _|
_| |_____| |_ _| |_____| |_
| ___ ___ | | ___ ___ |
|_| _| |_ |_| |_| _| |_ |_|
_ |_ _| _ _ |_ _| _
| |___| |___| |_| |___| |___| |
|_ ___ ___ ___ ___ _|
_| |_ |_| _| |_ |_| _| |_
| _ | _ |_ _| _ | _ |
|_| |_| | |___| |___| | |_| |_|
_ _ | ___ ___ | _ _
| |_| | |_| _| |_ |_| | |_| |
|_ _| _ |_ _| _ |_ _|
_| |___| |___| |___| |___| |_</code></pre>
<h3 id="a-brainfuck-interpreter">A <a href="https://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a> interpreter</h3>
<p>The smallest known BF interpreter is written in… you guessed it,
<a href="https://tromp.github.io/cl/Binary_lambda_calculus.html">BLC</a>,
coming in at 112 bytes (including 3 bits of padding):</p>
<pre><code> $ od -t x4 bf.Blc
0000000 01a15144 02d55584 223070b7 00f032ff
0000020 7f85f9bf 956fe15e c0ee7d7f 006854e5
0000040 fbfd5558 fd5745e0 b6f0fbeb 07d62ff0
0000060 d7736fe1 c0bc14f1 1f2eff0b 17666fa1
0000100 2fef5be8 ff13ffcf 2034cae1 0bd0c80a
0000120 e51fee99 6a5a7fff ff0fff1f d0049d87
0000140 db0500ab 3bb74023 b0c0cc28 10740e6c
0000160</code></pre>
<p>It expects its input to consist of a
<a href="https://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a> program
(looking only at bits <code>0</code>, <code>1</code> and <code>4</code> to distinguish among <code>,-.+&lt;&gt;][</code>)
followed by a <code>]</code>, followed by the input for the Brainfuck program.</p>
<pre><code> $ more hw.bf
++++++++++[&gt;+++++++&gt;++++++++++&gt;+++&gt;+&lt;&lt;&lt;&lt;-]&gt;++.&gt;+.+++++++..+++.&gt;++.&lt;&lt;+++++++++++++++.&gt;.+++.------.--------.&gt;+.&gt;.]
$ cat bf.Blc hw.bf | ./tromp
Hello World!</code></pre>
<p>Curiously, the interpreter <code>bf.Blc</code> is the exact same size as <code>hw.bf</code>.</p>
<h3 id="a-blc-assembler">A BLC assembler</h3>
<p>Writing BLC programs can be made slightly less painful with this parser that
translates single-letter-variable lambda calculus into BLC:</p>
<pre><code> $ echo &quot;\f\x f (f (f x))&quot; &gt; three
$ cat parse.Blc three | ./tromp
000001110011100111010</code></pre>
<h3 id="converting-between-bits-and-bytes">Converting between bits and bytes</h3>
<p>The program <code>inflate.Blc</code> and its inverse <code>deflate.Blc</code> allow us to translate between
BLC and BLC8. If you assemble a byte oriented program, you’ll need to compact it
into BLC8:</p>
<p>So we could assemble an input reversing program as</p>
<pre><code> echo &quot;\a a ((\b b b) (\b \c \d \e d (b b) (\f f c e))) (\b \c c)&quot; &gt; reverse
cat parse.Blc reverse | ./tromp &gt; reverse.blc</code></pre>
<p>and change it to BLC8 with</p>
<pre><code> $ cat deflate.Blc reverse.blc | ./tromp &gt; rev.Blc
$ wc rev.Blc
0 1 9 rev.Blc</code></pre>
<p>and then try it out with:</p>
<pre><code> $ cat rev.Blc - | ./tromp
Hello, world!
^D
!dlrow ,olleH</code></pre>
<h3 id="symbolic-lambda-calculus-reduction">Symbolic Lambda Calculus reduction</h3>
<p>BLC8 program <code>symbolic.Blc</code> shows individual reduction steps on symbolic lambda terms.
Here it is used to show the calculation of 2^3 in Church numerals:</p>
<pre><code> $ echo &quot;(\f\x f (f (f x))) (\f\x f (f x))&quot; &gt; threetwo
$ cat parse.Blc threetwo | ./tromp &gt; threetwo.blc
$ cat symbolic.Blc threetwo.blc | ./tromp
(\a \b a (a (a b))) (\a \b a (a b))
\a (\b \c b (b c)) ((\b \c b (b c)) ((\b \c b (b c)) a))
\a \b (\c \d c (c d)) ((\c \d c (c d)) a) ((\c \d c (c d)) ((\c \d c (c d)) a) b)
\a \b (\c (\d \e d (d e)) a ((\d \e d (d e)) a c)) ((\c \d c (c d)) ((\c \d c (c d)) a) b)
\a \b (\c \d c (c d)) a ((\c \d c (c d)) a ((\c \d c (c d)) ((\c \d c (c d)) a) b))
\a \b (\c a (a c)) ((\c \d c (c d)) a ((\c \d c (c d)) ((\c \d c (c d)) a) b))
\a \b a (a ((\c \d c (c d)) a ((\c \d c (c d)) ((\c \d c (c d)) a) b)))
\a \b a (a ((\c a (a c)) ((\c \d c (c d)) ((\c \d c (c d)) a) b)))
\a \b a (a (a (a ((\c \d c (c d)) ((\c \d c (c d)) a) b))))
\a \b a (a (a (a ((\c (\d \e d (d e)) a ((\d \e d (d e)) a c)) b))))
\a \b a (a (a (a ((\c \d c (c d)) a ((\c \d c (c d)) a b)))))
\a \b a (a (a (a ((\c a (a c)) ((\c \d c (c d)) a b)))))
\a \b a (a (a (a (a (a ((\c \d c (c d)) a b))))))
\a \b a (a (a (a (a (a ((\c a (a c)) b))))))
\a \b a (a (a (a (a (a (a (a b)))))))</code></pre>
<p>As expected, the resulting normal form is <a href="https://en.wikipedia.org/wiki/Church_encoding">Church
numeral</a> 8.</p>
<p>Taking only the first line of output gives us a sort of BLC disassembler, an
exact inverse of the above assembler. The prime number sieve disassembles as
follows:</p>
<pre><code> $ cat symbolic.Blc primes.blc | ./tromp | head -1
\a (\b b (b ((\c c c) (\c \d \e e (\f \g g) ((\f c c f ((\g g g) (\g f (g g)))) (\f \g \h \i i g (h (d f))))) (\c \d \e b (e c))))) (\b \c c (\d \e d) b)</code></pre>
<p>Hardly any less obfuscated…</p>
<p>The last line of</p>
<pre><code> cat symbolic.Blc primes.blc | ./tromp | head -16</code></pre>
<p>starts out as</p>
<pre><code> \a \b b (\c \d c) (\c c (\d \e d) (\d d (\e \f f) (\e e (\f \g g) ((\f (\g \h \i</code></pre>
<p>The <code>\a</code> is for ignoring the rest of the input (to which the universal machine
applies the decoded lambda term). The <code>\b b (..) (...)</code> is the list constructor,
usually called <code>cons</code>, applied to a head (a list element) and a tail (another list).
In this case the element is <code>(\c \d c)</code>, which represents the boolean true, and
which we use to represent a 0 bit. This is the bit that says 0 is not prime.
The next list element (following another <code>cons</code>) is <code>(\d \e d)</code>. Another 0 bit,
this time saying that 1 is not prime. The third list element is <code>(\e \f f)</code>,
a 1 bit, confirming our suspicion that 2 is prime. As is the next number,
according to <code>(\f \g g)</code>. We can see that the tail after the first 4 elements
is still subject to further reduction. The bit for number 4 will show up
for the first time in line 30, as <code>(\g \h g)</code>, or 0, as the result of zeroing
out all multiples of the first prime, 2.</p>
<p>Since my computer reaches swap hell before line 40, we can’t see the next bit arriving,
at least not in this symbolic reduction.</p>
<h3 id="performance">Performance</h3>
<p>Performance is quite decent, and amazingly good for such a tiny implementation,
being roughly 50% slower than a Haskell implementation of the universal machine
using so-called <a href="https://en.wikipedia.org/wiki/Higher-order_abstract_syntax">Higher Order Abstract
Syntax</a> which relies on the highly optimized
Haskell runtime system for evaluation. Of course individual BLC programs running
under the interpreter perform much worse than that same program written in Haskell.</p>
<p>Our interpreter copes well with extra levels of interpretation:</p>
<pre><code> $ time cat primes.blc | ./tromp -b | head -c 210 &gt; /dev/null
real 0m0.043s
$ time cat uni.blc primes.blc | ./tromp -b | head -c 210 &gt; /dev/null
real 0m0.191s
$ time cat uni.blc uni.blc primes.blc | ./tromp -b | head -c 210 &gt; /dev/null
real 0m1.919s
$ time cat uni.blc uni.blc uni.blc primes.blc | ./tromp -b | head -c 210 &gt; /dev/null
real 0m23.514s
$ time cat uni.blc uni.blc uni.blc uni.blc primes.blc | ./tromp -b | head -c 210 &gt; /dev/null
real 4m52.700s</code></pre>
<h3 id="obfuscation">Obfuscation</h3>
<p>Obfuscation is due entirely to conciseness. Some questions to ponder:</p>
<p>Which of the term space codes <code>0</code>, <code>1</code>, <code>2</code>, <code>3</code> serve multiple purposes?</p>
<p>Why is the environment pointer pointing into the term space?</p>
<p>What does the test <code>u+m&amp;1?</code> do?</p>
<p>How does the program reach exit code 0?</p>
<p>And how do any of those BLC programs work?</p>
<h3 id="portability">Portability</h3>
<p>The program freely (without casting) converts between <code>int</code> and <code>int *</code>, causing
many warnings;</p>
<pre><code> note: expected &#39;int *&#39; but argument is of type &#39;int&#39;
warning: assignment from incompatible pointer type
warning: assignment makes integer from pointer without a cast
warning: assignment makes pointer from integer without a cast
warning: incompatible implicit declaration of built-in function &#39;calloc&#39;
warning: incompatible implicit declaration of built-in function &#39;exit&#39;
warning: passing argument 1 of &#39;d&#39; makes pointer from integer without a cast
warning: passing argument 1 of &#39;p&#39; makes pointer from integer without a cast
warning: pointer/integer type mismatch in conditional expression</code></pre>
<p>Avoiding these would make the program substantially longer,
and detract from its single minded focus on conciseness.</p>
<p>It implicitly declares functions <code>read(2)</code>, <code>write(2)</code>, <code>exit(3)</code> and
<code>calloc(3)</code>, the latter two incompatibly. 32 bit and 64 bit executables are
separate <a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/Makefile">Makefile</a> targets, involving a change from <code>int</code> to <code>long</code>
and from a hardcoded sizeof of 4 to 8.</p>
<p>The program has been tested to work correctly on Linux/Solaris/MacOSX both in 32
and 64 bits.</p>
<h3 id="acknowledgements">Acknowledgements</h3>
<p>Christopher Hendrie, Bertram Felgenhauer, Alex Stangl, Seong-hoon Kang,
and <a href="../../authors.html#Yusuke_Endoh">Yusuke Endoh</a> have contributed ideas and
suggestions for improvement.</p>
<h3 id="references">References</h3>
<p>Binary Lambda Calculus -
<a href="https://tromp.github.io/cl/Binary_lambda_calculus.html" class="uri">https://tromp.github.io/cl/Binary_lambda_calculus.html</a></p>
<p>G J Chaitin, Algorithmic information theory, Volume I,
Cambridge Tracts in Theoretical Computer Science, Cambridge University Press, October 1987.
<a href="https://web.archive.org/web/20121125233450/https://www.cs.auckland.ac.nz/~chaitin/cup.html" class="uri">https://web.archive.org/web/20121125233450/https://www.cs.auckland.ac.nz/~chaitin/cup.html</a></p>
<p>Jean-Louis Krivine. 2007.
A call-by-name lambda-calculus machine
Higher Order Symbol. Comput. 20, 3 (September 2007), 199-207.
<a href="http://www.pps.univ-paris-diderot.fr/~krivine/articles/lazymach.pdf" class="uri">http://www.pps.univ-paris-diderot.fr/~krivine/articles/lazymach.pdf</a></p>
<h3 id="notice-to-those-who-wish-for-a-greater-challenge">NOTICE to those who wish for a greater challenge:</h3>
<p><strong>If you want a greater challenge, don’t read any further</strong>:
just try to understand the program via the source.</p>
<p>If you get stuck, come back and read below for additional hints and information.</p>
<h3 id="how-this-entry-works">How this entry works:</h3>
<p>See the file <a href="how.html">how.html</a>.</p>
<!--
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<!-- AFTER: last line of markdown file: 2012/tromp/README.md -->
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
<div id="inventory">
<h1 id="inventory-for-2012tromp">Inventory for 2012/tromp</h1>
</div>
<h2 id="primary-files">Primary files</h2>
<ul>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/tromp.c">tromp.c</a> - entry source code</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/Makefile">Makefile</a> - entry Makefile</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/tromp.orig.c">tromp.orig.c</a> - original source code</li>
<li><a href="how.html">how.html</a> - author supplied obfuscation information</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/primes.pl">primes.pl</a> - post process entry output to print primes</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/try.sh">try.sh</a> - script to try entry</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/hw.bf">hw.bf</a> - hello world brainfuck source code</li>
</ul>
<h2 id="secondary-files">Secondary files</h2>
<ul>
<li><a href="2012_tromp.tar.bz2">2012_tromp.tar.bz2</a> - download entry tarball</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/README.md">README.md</a> - markdown source for this web page</li>
<li><a href="bf.Blc">bf.Blc</a> - sample input</li>
<li><a href="deflate.Blc">deflate.Blc</a> - sample input</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/.entry.json">.entry.json</a> - entry summary and manifest in JSON</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
<li><a href="hilbert.Blc">hilbert.Blc</a> - sample input</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/how.md">how.md</a> - markdown source for how.html</li>
<li><a href="inflate.Blc">inflate.Blc</a> - sample input</li>
<li><a href="oddindices.Blc">oddindices.Blc</a> - sample input</li>
<li><a href="parse.Blc">parse.Blc</a> - sample input</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2012/tromp/.path">.path</a> - directory path from top level directory</li>
<li><a href="primes.blc">primes.blc</a> - sample input</li>
<li><a href="symbolic.Blc">symbolic.Blc</a> - sample input</li>
<li><a href="uni8.Blc">uni8.Blc</a> - sample input</li>
<li><a href="uni.blc">uni.blc</a> - sample input</li>
<li><a href="index.html">index.html</a> - this web page</li>
</ul>
<hr style="width:10%;text-align:left;margin-left:0">
<h4>
Jump to: <a href="#">top</a>
</h4>
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
<!-- END: this line ends content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
</div>
<!-- END: this line ends content from: inc/after-content.default.html -->
<!-- START: this line starts content from: inc/footer.inventory.html -->
<!--
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<div class="footer">
<div id="copyright"><h3>Copyright &copy; 1984-2024 by Landon Curt Noll:
<a href="https://creativecommons.org/faq/#what-does-some-rights-reserved-mean"
target="_blank"
rel="license noopener noreferrer">Some Rights Reserved</a></h3>
<p>
This work is <b>licensed by Landon Curt Noll</b> under
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1"
target="_blank"
rel="license noopener noreferrer"
style="display:inline-block;">CC BY-SA 4.0</a></b>.
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/cc.png"
alt="cc inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/by.png"
alt="person inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/sa.png"
alt="arrow looping back on itself inside circle symbol"><br>
You should <b>carefully review</b> the
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode.en"
target="_blank"
rel="license noopener noreferrer">CC BY-SA 4.0 LEGAL CODE</a></b>
before using the licensed material.<br>
You may wish to review the
<b><a href="../../license.html"
target="_blank"
rel="license noopener noreferrer">highlights of some of the key features and terms</a></b>
of <b>CC BY-SA 4.0</b>.<br>
</p>
</div>
<div id="coda"><h3>Coda</h3>
<p>
<a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2012%2Ftromp%2Findex.html" rel="nofollow">Nu HTML check this web page</a><br>
<a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a><br>
</p>
</div>
</div>
<!-- END: this line ends content from: inc/footer.inventory.html -->
<!-- START: this line starts content from: inc/bottom.default.html -->
</body>
</html>
<!-- END: this line ends content from: inc/bottom.default.html -->