{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using `x` to Generate Values\n",
    "\n",
    "Cf. jp-reprod.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from notebook_preamble import J, V, define"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Consider the `x` combinator `x == dup i`:\n",
    "\n",
    "    [a B] x\n",
    "    [a B] a B\n",
    "\n",
    "Let `B` `swap` the `a` with the quote and run some function `[C]` on it.\n",
    "\n",
    "    [a B] a B\n",
    "    [a B] a swap [C] dip\n",
    "    a [a B]      [C] dip\n",
    "    a C [a B]\n",
    "\n",
    "Now discard the quoted `a` with `rest` and `cons` the result of `C` on `a` whatever that is:\n",
    "\n",
    "    aC [a B] rest cons\n",
    "    aC [B] cons\n",
    "    [aC B]\n",
    "\n",
    "Altogether, this is the definition of `B`:\n",
    "\n",
    "    B == swap [C] dip rest cons\n",
    "\n",
    "We can create a quoted program that generates the Natural numbers (integers 0, 1, 2, ...) by using `0` for `a` and `[dup ++]` for `[C]`:\n",
    "\n",
    "    [0 swap [dup ++] dip rest cons]\n",
    "\n",
    "Let's try it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                                           . [0 swap [dup ++] dip rest cons] x\n",
      "           [0 swap [dup ++] dip rest cons] . x\n",
      "           [0 swap [dup ++] dip rest cons] . 0 swap [dup ++] dip rest cons\n",
      "         [0 swap [dup ++] dip rest cons] 0 . swap [dup ++] dip rest cons\n",
      "         0 [0 swap [dup ++] dip rest cons] . [dup ++] dip rest cons\n",
      "0 [0 swap [dup ++] dip rest cons] [dup ++] . dip rest cons\n",
      "                                         0 . dup ++ [0 swap [dup ++] dip rest cons] rest cons\n",
      "                                       0 0 . ++ [0 swap [dup ++] dip rest cons] rest cons\n",
      "                                       0 1 . [0 swap [dup ++] dip rest cons] rest cons\n",
      "       0 1 [0 swap [dup ++] dip rest cons] . rest cons\n",
      "         0 1 [swap [dup ++] dip rest cons] . cons\n",
      "         0 [1 swap [dup ++] dip rest cons] . \n"
     ]
    }
   ],
   "source": [
    "V('[0 swap [dup ++] dip rest cons] x')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After one application of `x` the quoted program contains `1` and `0` is below it on the stack."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "J('[0 swap [dup ++] dip rest cons] x x x x x pop')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `direco`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('direco == dip rest cons')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                                    . [0 swap [dup ++] direco] x\n",
      "           [0 swap [dup ++] direco] . x\n",
      "           [0 swap [dup ++] direco] . 0 swap [dup ++] direco\n",
      "         [0 swap [dup ++] direco] 0 . swap [dup ++] direco\n",
      "         0 [0 swap [dup ++] direco] . [dup ++] direco\n",
      "0 [0 swap [dup ++] direco] [dup ++] . direco\n",
      "0 [0 swap [dup ++] direco] [dup ++] . dip rest cons\n",
      "                                  0 . dup ++ [0 swap [dup ++] direco] rest cons\n",
      "                                0 0 . ++ [0 swap [dup ++] direco] rest cons\n",
      "                                0 1 . [0 swap [dup ++] direco] rest cons\n",
      "       0 1 [0 swap [dup ++] direco] . rest cons\n",
      "         0 1 [swap [dup ++] direco] . cons\n",
      "         0 [1 swap [dup ++] direco] . \n"
     ]
    }
   ],
   "source": [
    "V('[0 swap [dup ++] direco] x')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Generating Generators\n",
    "We want to go from:\n",
    "\n",
    "    a [C] G\n",
    "\n",
    "to:\n",
    "\n",
    "    [a swap [C] direco]\n",
    "\n",
    "Working in reverse:\n",
    "\n",
    "    [a swap   [C] direco] cons\n",
    "    a [swap   [C] direco] concat\n",
    "    a [swap] [[C] direco] swap\n",
    "    a [[C] direco] [swap]\n",
    "    a [C] [direco] cons [swap]\n",
    "\n",
    "Reading from the bottom up:\n",
    "\n",
    "    G == [direco] cons [swap] swap concat cons\n",
    "    G == [direco] cons [swap] swoncat cons\n",
    "\n",
    "We can try it out:\n",
    "\n",
    "    0 [dup ++] G"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('G == [direco] cons [swap] swoncat cons')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                           . 0 [dup ++] G\n",
      "                         0 . [dup ++] G\n",
      "                0 [dup ++] . G\n",
      "                0 [dup ++] . [direco] cons [swap] swoncat cons\n",
      "       0 [dup ++] [direco] . cons [swap] swoncat cons\n",
      "       0 [[dup ++] direco] . [swap] swoncat cons\n",
      "0 [[dup ++] direco] [swap] . swoncat cons\n",
      "0 [[dup ++] direco] [swap] . swap concat cons\n",
      "0 [swap] [[dup ++] direco] . concat cons\n",
      "  0 [swap [dup ++] direco] . cons\n",
      "  [0 swap [dup ++] direco] . \n"
     ]
    }
   ],
   "source": [
    "V('0 [dup ++] G')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                                    . 0 [dup ++] G x\n",
      "                                  0 . [dup ++] G x\n",
      "                         0 [dup ++] . G x\n",
      "                         0 [dup ++] . [direco] cons [swap] swoncat cons x\n",
      "                0 [dup ++] [direco] . cons [swap] swoncat cons x\n",
      "                0 [[dup ++] direco] . [swap] swoncat cons x\n",
      "         0 [[dup ++] direco] [swap] . swoncat cons x\n",
      "         0 [[dup ++] direco] [swap] . swap concat cons x\n",
      "         0 [swap] [[dup ++] direco] . concat cons x\n",
      "           0 [swap [dup ++] direco] . cons x\n",
      "           [0 swap [dup ++] direco] . x\n",
      "           [0 swap [dup ++] direco] . 0 swap [dup ++] direco\n",
      "         [0 swap [dup ++] direco] 0 . swap [dup ++] direco\n",
      "         0 [0 swap [dup ++] direco] . [dup ++] direco\n",
      "0 [0 swap [dup ++] direco] [dup ++] . direco\n",
      "0 [0 swap [dup ++] direco] [dup ++] . dip rest cons\n",
      "                                  0 . dup ++ [0 swap [dup ++] direco] rest cons\n",
      "                                0 0 . ++ [0 swap [dup ++] direco] rest cons\n",
      "                                0 1 . [0 swap [dup ++] direco] rest cons\n",
      "       0 1 [0 swap [dup ++] direco] . rest cons\n",
      "         0 1 [swap [dup ++] direco] . cons\n",
      "         0 [1 swap [dup ++] direco] . \n"
     ]
    }
   ],
   "source": [
    "V('0 [dup ++] G x')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Powers of 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 4 8 16 32 64 128 256 [512 swap [dup 1 <<] direco]\n"
     ]
    }
   ],
   "source": [
    "J('1 [dup 1 <<] G x x x x x x x x x')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `n [x] times`\n",
    "If we have one of these quoted programs we can drive it using `times` with the `x` combinator.\n",
    "\n",
    "Let's define a word `n_range` that takes a starting integer and a count and leaves that many consecutive integers on the stack.  For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23 24 25 26 27\n"
     ]
    }
   ],
   "source": [
    "J('23 [dup ++] G 5 [x] times pop')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can use `dip` to untangle `[dup ++] G` from the arguments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23 24 25 26 27\n"
     ]
    }
   ],
   "source": [
    "J('23 5 [[dup ++] G] dip [x] times pop')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that the givens (arguments) are on the left we have the definition we're looking for:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('n_range == [[dup ++] G] dip [x] times pop')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "450 451 452 453 454 455 456 457 458 459\n"
     ]
    }
   ],
   "source": [
    "J('450 10 n_range')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is better just using the `times` combinator though..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "450 451 452 453 454 455 456 457 458 459\n"
     ]
    }
   ],
   "source": [
    "J('450 9 [dup ++] times')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Generating Multiples of Three and Five\n",
    "Look at the treatment of the Project Euler Problem One in [Developing a Program.ipynb](./Developing a Program.ipynb) and you'll see that we might be interested in generating an endless cycle of:\n",
    "\n",
    "    3 2 1 3 1 2 3\n",
    "\n",
    "To do this we want to encode the numbers as pairs of bits in a single int:\n",
    "\n",
    "        3  2  1  3  1  2  3\n",
    "    0b 11 10 01 11 01 10 11 == 14811\n",
    "\n",
    "And pick them off by masking with 3 (binary 11) and then shifting the int right two bits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('PE1.1 == dup [3 &] dip 2 >>')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                  . 14811 PE1.1\n",
      "            14811 . PE1.1\n",
      "            14811 . dup [3 &] dip 2 >>\n",
      "      14811 14811 . [3 &] dip 2 >>\n",
      "14811 14811 [3 &] . dip 2 >>\n",
      "            14811 . 3 & 14811 2 >>\n",
      "          14811 3 . & 14811 2 >>\n",
      "                3 . 14811 2 >>\n",
      "          3 14811 . 2 >>\n",
      "        3 14811 2 . >>\n",
      "           3 3702 . \n"
     ]
    }
   ],
   "source": [
    "V('14811 PE1.1')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we plug `14811` and `[PE1.1]` into our generator form..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[14811 swap [PE1.1] direco]\n"
     ]
    }
   ],
   "source": [
    "J('14811 [PE1.1] G')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 [3702 swap [PE1.1] direco]\n"
     ]
    }
   ],
   "source": [
    "J('[14811 swap [PE1.1] direco] x')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...we get a generator that works for seven cycles before it reaches zero:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 2 1 3 1 2 3 [0 swap [PE1.1] direco]\n"
     ]
    }
   ],
   "source": [
    "J('[14811 swap [PE1.1] direco] 7 [x] times')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reset at Zero\n",
    "We need a function that checks if the int has reached zero and resets it if so."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('PE1.1.check == dup [pop 14811] [] branch')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 [0 swap [PE1.1.check PE1.1] direco]\n"
     ]
    }
   ],
   "source": [
    "J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Run 466 times\n",
    "In the PE1 problem we are asked to sum all the multiples of three and five less than 1000.  It's worked out that we need to use all seven numbers sixty-six times and then four more."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "466\n"
     ]
    }
   ],
   "source": [
    "J('7 66 * 4 +')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we drive our generator 466 times and sum the stack we get 999."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 [57 swap [PE1.1.check PE1.1] dip rest cons]\n"
     ]
    }
   ],
   "source": [
    "J('[14811 swap [PE1.1.check PE1.1] dip rest cons] 466 [x] times')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "999\n"
     ]
    }
   ],
   "source": [
    "J('[14811 swap [PE1.1.check PE1.1] dip rest cons] 466 [x] times pop enstacken sum')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Project Euler Problem One"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('PE1.2 == + dup [+] dip')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can add `PE1.2` to the quoted program given to `times`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "233168\n"
     ]
    }
   ],
   "source": [
    "J('0 0 [0 swap [PE1.1.check PE1.1] direco] 466 [x [PE1.2] dip] times popop')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or using `G` we can write:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "233168\n"
     ]
    }
   ],
   "source": [
    "J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# A generator for the Fibonacci Sequence.\n",
    "Consider:\n",
    "\n",
    "    [b a F] x\n",
    "    [b a F] b a F\n",
    "\n",
    "The obvious first thing to do is just add `b` and `a`:\n",
    "\n",
    "    [b a F] b a +\n",
    "    [b a F] b+a\n",
    "\n",
    "From here we want to arrive at:\n",
    "\n",
    "    b [b+a b F]\n",
    "\n",
    "Let's start with `swons`:\n",
    "\n",
    "    [b a F] b+a swons\n",
    "    [b+a b a F]\n",
    "\n",
    "Considering this quote as a stack:\n",
    "\n",
    "    F a b b+a\n",
    "\n",
    "We want to get it to:\n",
    "\n",
    "    F b b+a b\n",
    "\n",
    "So:\n",
    "\n",
    "    F a b b+a popdd over\n",
    "    F b b+a b\n",
    "\n",
    "And therefore:\n",
    "\n",
    "    [b+a b a F] [popdd over] infra\n",
    "    [b b+a b F]\n",
    "\n",
    "And lastly:\n",
    "\n",
    "    [b b+a b F] uncons\n",
    "    b [b+a b F]\n",
    "\n",
    "Done.\n",
    "\n",
    "Putting it all together:\n",
    "\n",
    "    F == + swons [popdd over] infra uncons\n",
    "\n",
    "And:\n",
    "\n",
    "    fib_gen == [1 1 F]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('fib == + swons [popdd over] infra uncons')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('fib_gen == [1 1 fib]')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 5 8 13 21 34 55 89 [144 89 fib]\n"
     ]
    }
   ],
   "source": [
    "J('fib_gen 10 [x] times')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Project Euler Problem Two\n",
    "    By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.\n",
    "\n",
    "Now that we have a generator for the Fibonacci sequence, we need a function that adds a term in the sequence to a sum if it is even, and `pop`s it otherwise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('PE2.1 == dup 2 % [+] [pop] branch')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And a predicate function that detects when the terms in the series \"exceed four million\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('>4M == 4000000 >')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now it's straightforward to define `PE2` as a recursive function that generates terms in the Fibonacci sequence until they exceed four million and sums the even ones."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4613732\n"
     ]
    }
   ],
   "source": [
    "J('PE2')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's the collected program definitions:\n",
    "\n",
    "    fib == + swons [popdd over] infra uncons\n",
    "    fib_gen == [1 1 fib]\n",
    "\n",
    "    even == dup 2 %\n",
    "    >4M == 4000000 >\n",
    "\n",
    "    PE2.1 == even [+] [pop] branch\n",
    "    PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Even-valued Fibonacci Terms\n",
    "\n",
    "Using `o` for odd and `e` for even:\n",
    "\n",
    "    o + o = e\n",
    "    e + e = e\n",
    "    o + e = o\n",
    "\n",
    "So the Fibonacci sequence considered in terms of just parity would be:\n",
    "\n",
    "    o o e o o e o o e o o e o o e o o e\n",
    "    1 1 2 3 5 8 . . .\n",
    "\n",
    "Every third term is even.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 1 2 [3 2 fib]\n"
     ]
    }
   ],
   "source": [
    "J('[1 0 fib] x x x')  # To start the sequence with 1 1 2 3 instead of 1 2 3."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Drive the generator three times and `popop` the two odd terms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 [3 2 fib]\n"
     ]
    }
   ],
   "source": [
    "J('[1 0 fib] x x x [popop] dipd')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "define('PE2.2 == x x x [popop] dipd')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 8 34 144 610 2584 10946 46368 196418 832040 [1346269 832040 fib]\n"
     ]
    }
   ],
   "source": [
    "J('[1 0 fib] 10 [PE2.2] times')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Replace `x` with our new driver function `PE2.2` and start our `fib` generator at `1 0`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4613732\n"
     ]
    }
   ],
   "source": [
    "J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to compile these?\n",
    "You would probably start with a special version of `G`, and perhaps modifications to the default `x`?"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
