--- /dev/null
+<!DOCTYPE html>
+<html>
+<head><meta charset="utf-8" />
+
+<title>Square_Spiral</title>
+
+<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
+
+
+
+<style type="text/css">
+ /*!
+*
+* Twitter Bootstrap
+*
+*/
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+[hidden],
+template {
+ display: none;
+}
+a {
+ background-color: transparent;
+}
+a:active,
+a:hover {
+ outline: 0;
+}
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+b,
+strong {
+ font-weight: bold;
+}
+dfn {
+ font-style: italic;
+}
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+mark {
+ background: #ff0;
+ color: #000;
+}
+small {
+ font-size: 80%;
+}
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+sup {
+ top: -0.5em;
+}
+sub {
+ bottom: -0.25em;
+}
+img {
+ border: 0;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 1em 40px;
+}
+hr {
+ box-sizing: content-box;
+ height: 0;
+}
+pre {
+ overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit;
+ font: inherit;
+ margin: 0;
+}
+button {
+ overflow: visible;
+}
+button,
+select {
+ text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+input {
+ line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box;
+ padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: textfield;
+ box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+legend {
+ border: 0;
+ padding: 0;
+}
+textarea {
+ overflow: auto;
+}
+optgroup {
+ font-weight: bold;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+td,
+th {
+ padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ background: transparent !important;
+ box-shadow: none !important;
+ text-shadow: none !important;
+ }
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+ pre,
+ blockquote {
+ border: 1px solid #999;
+ page-break-inside: avoid;
+ }
+ thead {
+ display: table-header-group;
+ }
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+ img {
+ max-width: 100% !important;
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+ .navbar {
+ display: none;
+ }
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+ .label {
+ border: 1px solid #000;
+ }
+ .table {
+ border-collapse: collapse !important;
+ }
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+@font-face {
+ font-family: 'Glyphicons Halflings';
+ src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot');
+ src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.glyphicon-asterisk:before {
+ content: "\002a";
+}
+.glyphicon-plus:before {
+ content: "\002b";
+}
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+.glyphicon-minus:before {
+ content: "\2212";
+}
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+.glyphicon-glass:before {
+ content: "\e001";
+}
+.glyphicon-music:before {
+ content: "\e002";
+}
+.glyphicon-search:before {
+ content: "\e003";
+}
+.glyphicon-heart:before {
+ content: "\e005";
+}
+.glyphicon-star:before {
+ content: "\e006";
+}
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+.glyphicon-user:before {
+ content: "\e008";
+}
+.glyphicon-film:before {
+ content: "\e009";
+}
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+.glyphicon-th:before {
+ content: "\e011";
+}
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+.glyphicon-ok:before {
+ content: "\e013";
+}
+.glyphicon-remove:before {
+ content: "\e014";
+}
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+.glyphicon-off:before {
+ content: "\e017";
+}
+.glyphicon-signal:before {
+ content: "\e018";
+}
+.glyphicon-cog:before {
+ content: "\e019";
+}
+.glyphicon-trash:before {
+ content: "\e020";
+}
+.glyphicon-home:before {
+ content: "\e021";
+}
+.glyphicon-file:before {
+ content: "\e022";
+}
+.glyphicon-time:before {
+ content: "\e023";
+}
+.glyphicon-road:before {
+ content: "\e024";
+}
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+.glyphicon-download:before {
+ content: "\e026";
+}
+.glyphicon-upload:before {
+ content: "\e027";
+}
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+.glyphicon-lock:before {
+ content: "\e033";
+}
+.glyphicon-flag:before {
+ content: "\e034";
+}
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+.glyphicon-tag:before {
+ content: "\e041";
+}
+.glyphicon-tags:before {
+ content: "\e042";
+}
+.glyphicon-book:before {
+ content: "\e043";
+}
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+.glyphicon-print:before {
+ content: "\e045";
+}
+.glyphicon-camera:before {
+ content: "\e046";
+}
+.glyphicon-font:before {
+ content: "\e047";
+}
+.glyphicon-bold:before {
+ content: "\e048";
+}
+.glyphicon-italic:before {
+ content: "\e049";
+}
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+.glyphicon-list:before {
+ content: "\e056";
+}
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+.glyphicon-picture:before {
+ content: "\e060";
+}
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+.glyphicon-tint:before {
+ content: "\e064";
+}
+.glyphicon-edit:before {
+ content: "\e065";
+}
+.glyphicon-share:before {
+ content: "\e066";
+}
+.glyphicon-check:before {
+ content: "\e067";
+}
+.glyphicon-move:before {
+ content: "\e068";
+}
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+.glyphicon-backward:before {
+ content: "\e071";
+}
+.glyphicon-play:before {
+ content: "\e072";
+}
+.glyphicon-pause:before {
+ content: "\e073";
+}
+.glyphicon-stop:before {
+ content: "\e074";
+}
+.glyphicon-forward:before {
+ content: "\e075";
+}
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+.glyphicon-eject:before {
+ content: "\e078";
+}
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+.glyphicon-gift:before {
+ content: "\e102";
+}
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+.glyphicon-fire:before {
+ content: "\e104";
+}
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+.glyphicon-plane:before {
+ content: "\e108";
+}
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+.glyphicon-random:before {
+ content: "\e110";
+}
+.glyphicon-comment:before {
+ content: "\e111";
+}
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+.glyphicon-bell:before {
+ content: "\e123";
+}
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+.glyphicon-globe:before {
+ content: "\e135";
+}
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+.glyphicon-filter:before {
+ content: "\e138";
+}
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+.glyphicon-link:before {
+ content: "\e144";
+}
+.glyphicon-phone:before {
+ content: "\e145";
+}
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+.glyphicon-usd:before {
+ content: "\e148";
+}
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+.glyphicon-sort:before {
+ content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+.glyphicon-expand:before {
+ content: "\e158";
+}
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+.glyphicon-flash:before {
+ content: "\e162";
+}
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+.glyphicon-record:before {
+ content: "\e165";
+}
+.glyphicon-save:before {
+ content: "\e166";
+}
+.glyphicon-open:before {
+ content: "\e167";
+}
+.glyphicon-saved:before {
+ content: "\e168";
+}
+.glyphicon-import:before {
+ content: "\e169";
+}
+.glyphicon-export:before {
+ content: "\e170";
+}
+.glyphicon-send:before {
+ content: "\e171";
+}
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+.glyphicon-header:before {
+ content: "\e180";
+}
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+.glyphicon-tower:before {
+ content: "\e184";
+}
+.glyphicon-stats:before {
+ content: "\e185";
+}
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+.glyphicon-cd:before {
+ content: "\e201";
+}
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+.glyphicon-copy:before {
+ content: "\e205";
+}
+.glyphicon-paste:before {
+ content: "\e206";
+}
+.glyphicon-alert:before {
+ content: "\e209";
+}
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+.glyphicon-king:before {
+ content: "\e211";
+}
+.glyphicon-queen:before {
+ content: "\e212";
+}
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+.glyphicon-knight:before {
+ content: "\e215";
+}
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+.glyphicon-bed:before {
+ content: "\e219";
+}
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+.glyphicon-erase:before {
+ content: "\e221";
+}
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+.glyphicon-btc:before {
+ content: "\e227";
+}
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+.glyphicon-scale:before {
+ content: "\e230";
+}
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+.glyphicon-education:before {
+ content: "\e233";
+}
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+.glyphicon-oil:before {
+ content: "\e238";
+}
+.glyphicon-grain:before {
+ content: "\e239";
+}
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+.glyphicon-console:before {
+ content: "\e254";
+}
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html {
+ font-size: 10px;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #000;
+ background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+a {
+ color: #337ab7;
+ text-decoration: none;
+}
+a:hover,
+a:focus {
+ color: #23527c;
+ text-decoration: underline;
+}
+a:focus {
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+figure {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+.img-rounded {
+ border-radius: 3px;
+}
+.img-thumbnail {
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 2px;
+ -webkit-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+}
+.img-circle {
+ border-radius: 50%;
+}
+hr {
+ margin-top: 18px;
+ margin-bottom: 18px;
+ border: 0;
+ border-top: 1px solid #eeeeee;
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ margin: -1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+[role="button"] {
+ cursor: pointer;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777777;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 18px;
+ margin-bottom: 9px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 9px;
+ margin-bottom: 9px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+h1,
+.h1 {
+ font-size: 33px;
+}
+h2,
+.h2 {
+ font-size: 27px;
+}
+h3,
+.h3 {
+ font-size: 23px;
+}
+h4,
+.h4 {
+ font-size: 17px;
+}
+h5,
+.h5 {
+ font-size: 13px;
+}
+h6,
+.h6 {
+ font-size: 12px;
+}
+p {
+ margin: 0 0 9px;
+}
+.lead {
+ margin-bottom: 18px;
+ font-size: 14px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+@media (min-width: 768px) {
+ .lead {
+ font-size: 19.5px;
+ }
+}
+small,
+.small {
+ font-size: 92%;
+}
+mark,
+.mark {
+ background-color: #fcf8e3;
+ padding: .2em;
+}
+.text-left {
+ text-align: left;
+}
+.text-right {
+ text-align: right;
+}
+.text-center {
+ text-align: center;
+}
+.text-justify {
+ text-align: justify;
+}
+.text-nowrap {
+ white-space: nowrap;
+}
+.text-lowercase {
+ text-transform: lowercase;
+}
+.text-uppercase {
+ text-transform: uppercase;
+}
+.text-capitalize {
+ text-transform: capitalize;
+}
+.text-muted {
+ color: #777777;
+}
+.text-primary {
+ color: #337ab7;
+}
+a.text-primary:hover,
+a.text-primary:focus {
+ color: #286090;
+}
+.text-success {
+ color: #3c763d;
+}
+a.text-success:hover,
+a.text-success:focus {
+ color: #2b542c;
+}
+.text-info {
+ color: #31708f;
+}
+a.text-info:hover,
+a.text-info:focus {
+ color: #245269;
+}
+.text-warning {
+ color: #8a6d3b;
+}
+a.text-warning:hover,
+a.text-warning:focus {
+ color: #66512c;
+}
+.text-danger {
+ color: #a94442;
+}
+a.text-danger:hover,
+a.text-danger:focus {
+ color: #843534;
+}
+.bg-primary {
+ color: #fff;
+ background-color: #337ab7;
+}
+a.bg-primary:hover,
+a.bg-primary:focus {
+ background-color: #286090;
+}
+.bg-success {
+ background-color: #dff0d8;
+}
+a.bg-success:hover,
+a.bg-success:focus {
+ background-color: #c1e2b3;
+}
+.bg-info {
+ background-color: #d9edf7;
+}
+a.bg-info:hover,
+a.bg-info:focus {
+ background-color: #afd9ee;
+}
+.bg-warning {
+ background-color: #fcf8e3;
+}
+a.bg-warning:hover,
+a.bg-warning:focus {
+ background-color: #f7ecb5;
+}
+.bg-danger {
+ background-color: #f2dede;
+}
+a.bg-danger:hover,
+a.bg-danger:focus {
+ background-color: #e4b9b9;
+}
+.page-header {
+ padding-bottom: 8px;
+ margin: 36px 0 18px;
+ border-bottom: 1px solid #eeeeee;
+}
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 9px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline {
+ padding-left: 0;
+ list-style: none;
+ margin-left: -5px;
+}
+.list-inline > li {
+ display: inline-block;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+dl {
+ margin-top: 0;
+ margin-bottom: 18px;
+}
+dt,
+dd {
+ line-height: 1.42857143;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 0;
+}
+@media (min-width: 541px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ clear: left;
+ text-align: right;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777777;
+}
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+blockquote {
+ padding: 9px 18px;
+ margin: 0 0 18px;
+ font-size: inherit;
+ border-left: 5px solid #eeeeee;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777777;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ border-right: 5px solid #eeeeee;
+ border-left: 0;
+ text-align: right;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+address {
+ margin-bottom: 18px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace;
+}
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 2px;
+}
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #888;
+ background-color: transparent;
+ border-radius: 1px;
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ box-shadow: none;
+}
+pre {
+ display: block;
+ padding: 8.5px;
+ margin: 0 0 9px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ word-break: break-all;
+ word-wrap: break-word;
+ color: #333333;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 2px;
+}
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+.container {
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: 0px;
+ padding-right: 0px;
+}
+@media (min-width: 768px) {
+ .container {
+ width: 768px;
+ }
+}
+@media (min-width: 992px) {
+ .container {
+ width: 940px;
+ }
+}
+@media (min-width: 1200px) {
+ .container {
+ width: 1140px;
+ }
+}
+.container-fluid {
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: 0px;
+ padding-right: 0px;
+}
+.row {
+ margin-left: 0px;
+ margin-right: 0px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-left: 0px;
+ padding-right: 0px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+.col-xs-12 {
+ width: 100%;
+}
+.col-xs-11 {
+ width: 91.66666667%;
+}
+.col-xs-10 {
+ width: 83.33333333%;
+}
+.col-xs-9 {
+ width: 75%;
+}
+.col-xs-8 {
+ width: 66.66666667%;
+}
+.col-xs-7 {
+ width: 58.33333333%;
+}
+.col-xs-6 {
+ width: 50%;
+}
+.col-xs-5 {
+ width: 41.66666667%;
+}
+.col-xs-4 {
+ width: 33.33333333%;
+}
+.col-xs-3 {
+ width: 25%;
+}
+.col-xs-2 {
+ width: 16.66666667%;
+}
+.col-xs-1 {
+ width: 8.33333333%;
+}
+.col-xs-pull-12 {
+ right: 100%;
+}
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+.col-xs-pull-9 {
+ right: 75%;
+}
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+.col-xs-pull-6 {
+ right: 50%;
+}
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+.col-xs-pull-3 {
+ right: 25%;
+}
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+.col-xs-pull-0 {
+ right: auto;
+}
+.col-xs-push-12 {
+ left: 100%;
+}
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+.col-xs-push-9 {
+ left: 75%;
+}
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+.col-xs-push-6 {
+ left: 50%;
+}
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+.col-xs-push-3 {
+ left: 25%;
+}
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+.col-xs-push-0 {
+ left: auto;
+}
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+ margin-left: 0%;
+}
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+ .col-sm-3 {
+ width: 25%;
+ }
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-sm-pull-0 {
+ right: auto;
+ }
+ .col-sm-push-12 {
+ left: 100%;
+ }
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+ .col-sm-push-9 {
+ left: 75%;
+ }
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+ .col-sm-push-6 {
+ left: 50%;
+ }
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+ .col-sm-push-3 {
+ left: 25%;
+ }
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+ .col-sm-push-0 {
+ left: auto;
+ }
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-sm-offset-0 {
+ margin-left: 0%;
+ }
+}
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+ .col-md-pull-12 {
+ right: 100%;
+ }
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-md-pull-9 {
+ right: 75%;
+ }
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-md-pull-6 {
+ right: 50%;
+ }
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-md-pull-3 {
+ right: 25%;
+ }
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-md-pull-0 {
+ right: auto;
+ }
+ .col-md-push-12 {
+ left: 100%;
+ }
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+ .col-md-push-9 {
+ left: 75%;
+ }
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+ .col-md-push-6 {
+ left: 50%;
+ }
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+ .col-md-push-3 {
+ left: 25%;
+ }
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+ .col-md-push-0 {
+ left: auto;
+ }
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-md-offset-0 {
+ margin-left: 0%;
+ }
+}
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+ .col-lg-9 {
+ width: 75%;
+ }
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-lg-pull-0 {
+ right: auto;
+ }
+ .col-lg-push-12 {
+ left: 100%;
+ }
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+ .col-lg-push-9 {
+ left: 75%;
+ }
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+ .col-lg-push-6 {
+ left: 50%;
+ }
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+ .col-lg-push-3 {
+ left: 25%;
+ }
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+ .col-lg-push-0 {
+ left: auto;
+ }
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-lg-offset-0 {
+ margin-left: 0%;
+ }
+}
+table {
+ background-color: transparent;
+}
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777777;
+ text-align: left;
+}
+th {
+ text-align: left;
+}
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 18px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd;
+}
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+.table > tbody + tbody {
+ border-top: 2px solid #ddd;
+}
+.table .table {
+ background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+.table-bordered {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+ position: static;
+ float: none;
+ display: table-column;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ float: none;
+ display: table-cell;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
+}
+.table-responsive {
+ overflow-x: auto;
+ min-height: 0.01%;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 13.5px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd;
+ }
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+fieldset {
+ padding: 0;
+ margin: 0;
+ border: 0;
+ min-width: 0;
+}
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 18px;
+ font-size: 19.5px;
+ line-height: inherit;
+ color: #333333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+input[type="file"] {
+ display: block;
+}
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+select[multiple],
+select[size] {
+ height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #555555;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ height: 32px;
+ padding: 6px 12px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #555555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 2px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+ color: #999;
+}
+.form-control::-webkit-input-placeholder {
+ color: #999;
+}
+.form-control::-ms-expand {
+ border: 0;
+ background-color: transparent;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #eeeeee;
+ opacity: 1;
+}
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+textarea.form-control {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: none;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"].form-control,
+ input[type="time"].form-control,
+ input[type="datetime-local"].form-control,
+ input[type="month"].form-control {
+ line-height: 32px;
+ }
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 45px;
+ }
+}
+.form-group {
+ margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+ min-height: 18px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-left: -20px;
+ margin-top: 4px \9;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ vertical-align: middle;
+ font-weight: normal;
+ cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+.form-control-static {
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+ min-height: 31px;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-left: 0;
+ padding-right: 0;
+}
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 1px;
+}
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 1px;
+}
+.form-group-sm select.form-control {
+ height: 30px;
+ line-height: 30px;
+}
+.form-group-sm textarea.form-control,
+.form-group-sm select[multiple].form-control {
+ height: auto;
+}
+.form-group-sm .form-control-static {
+ height: 30px;
+ min-height: 30px;
+ padding: 6px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.input-lg {
+ height: 45px;
+ padding: 10px 16px;
+ font-size: 17px;
+ line-height: 1.3333333;
+ border-radius: 3px;
+}
+select.input-lg {
+ height: 45px;
+ line-height: 45px;
+}
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+.form-group-lg .form-control {
+ height: 45px;
+ padding: 10px 16px;
+ font-size: 17px;
+ line-height: 1.3333333;
+ border-radius: 3px;
+}
+.form-group-lg select.form-control {
+ height: 45px;
+ line-height: 45px;
+}
+.form-group-lg textarea.form-control,
+.form-group-lg select[multiple].form-control {
+ height: auto;
+}
+.form-group-lg .form-control-static {
+ height: 45px;
+ min-height: 35px;
+ padding: 11px 16px;
+ font-size: 17px;
+ line-height: 1.3333333;
+}
+.has-feedback {
+ position: relative;
+}
+.has-feedback .form-control {
+ padding-right: 40px;
+}
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 32px;
+ height: 32px;
+ line-height: 32px;
+ text-align: center;
+ pointer-events: none;
+}
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+ width: 45px;
+ height: 45px;
+ line-height: 45px;
+}
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #3c763d;
+}
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+ color: #3c763d;
+ border-color: #3c763d;
+ background-color: #dff0d8;
+}
+.has-success .form-control-feedback {
+ color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #8a6d3b;
+}
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ border-color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+.has-warning .form-control-feedback {
+ color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #a94442;
+}
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+ color: #a94442;
+ border-color: #a94442;
+ background-color: #f2dede;
+}
+.has-error .form-control-feedback {
+ color: #a94442;
+}
+.has-feedback label ~ .form-control-feedback {
+ top: 23px;
+}
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #404040;
+}
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 7px;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 25px;
+}
+.form-horizontal .form-group {
+ margin-left: 0px;
+ margin-right: 0px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ text-align: right;
+ margin-bottom: 0;
+ padding-top: 7px;
+ }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 0px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 11px;
+ font-size: 17px;
+ }
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ font-size: 12px;
+ }
+}
+.btn {
+ display: inline-block;
+ margin-bottom: 0;
+ font-weight: normal;
+ text-align: center;
+ vertical-align: middle;
+ touch-action: manipulation;
+ cursor: pointer;
+ background-image: none;
+ border: 1px solid transparent;
+ white-space: nowrap;
+ padding: 6px 12px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ border-radius: 2px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #333;
+ text-decoration: none;
+}
+.btn:active,
+.btn.active {
+ outline: 0;
+ background-image: none;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ opacity: 0.65;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+.btn-default:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default .badge {
+ color: #fff;
+ background-color: #333;
+}
+.btn-primary {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+ color: #fff;
+ background-color: #286090;
+ border-color: #122b40;
+}
+.btn-primary:hover {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+ color: #fff;
+ background-color: #204d74;
+ border-color: #122b40;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+.btn-success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+.btn-info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+.btn-warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+.btn-danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+.btn-link {
+ color: #337ab7;
+ font-weight: normal;
+ border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+ color: #23527c;
+ text-decoration: underline;
+ background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777777;
+ text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 17px;
+ line-height: 1.3333333;
+ border-radius: 3px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 1px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 1px;
+}
+.btn-block {
+ display: block;
+ width: 100%;
+}
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity 0.15s linear;
+ -o-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
+}
+.fade.in {
+ opacity: 1;
+}
+.collapse {
+ display: none;
+}
+.collapse.in {
+ display: block;
+}
+tr.collapse.in {
+ display: table-row;
+}
+tbody.collapse.in {
+ display: table-row-group;
+}
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-property: height, visibility;
+ transition-property: height, visibility;
+ -webkit-transition-duration: 0.35s;
+ transition-duration: 0.35s;
+ -webkit-transition-timing-function: ease;
+ transition-timing-function: ease;
+}
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-top: 4px solid \9;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+.dropup,
+.dropdown {
+ position: relative;
+}
+.dropdown-toggle:focus {
+ outline: 0;
+}
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ list-style: none;
+ font-size: 13px;
+ text-align: left;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ border-radius: 2px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ background-clip: padding-box;
+}
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 8px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333333;
+ white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ text-decoration: none;
+ color: #262626;
+ background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #fff;
+ text-decoration: none;
+ outline: 0;
+ background-color: #337ab7;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777777;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+ cursor: not-allowed;
+}
+.open > .dropdown-menu {
+ display: block;
+}
+.open > a {
+ outline: 0;
+}
+.dropdown-menu-right {
+ left: auto;
+ right: 0;
+}
+.dropdown-menu-left {
+ left: 0;
+ right: auto;
+}
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777777;
+ white-space: nowrap;
+}
+.dropdown-backdrop {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ top: 0;
+ z-index: 990;
+}
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ border-top: 0;
+ border-bottom: 4px dashed;
+ border-bottom: 4px solid \9;
+ content: "";
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+@media (min-width: 541px) {
+ .navbar-right .dropdown-menu {
+ left: auto;
+ right: 0;
+ }
+ .navbar-right .dropdown-menu-left {
+ left: 0;
+ right: auto;
+ }
+}
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+.btn-toolbar {
+ margin-left: -5px;
+}
+.btn-toolbar .btn,
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+ padding-left: 8px;
+ padding-right: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-left: 12px;
+ padding-right: 12px;
+}
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn .caret {
+ margin-left: 0;
+}
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-right-radius: 2px;
+ border-top-left-radius: 2px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+ border-bottom-right-radius: 2px;
+ border-bottom-left-radius: 2px;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ float: none;
+ display: table-cell;
+ width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+.input-group[class*="col-"] {
+ float: none;
+ padding-left: 0;
+ padding-right: 0;
+}
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+.input-group .form-control:focus {
+ z-index: 3;
+}
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 45px;
+ padding: 10px 16px;
+ font-size: 17px;
+ line-height: 1.3333333;
+ border-radius: 3px;
+}
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 45px;
+ line-height: 45px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 1px;
+}
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555555;
+ text-align: center;
+ background-color: #eeeeee;
+ border: 1px solid #ccc;
+ border-radius: 2px;
+}
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 1px;
+}
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 17px;
+ border-radius: 3px;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+.input-group-addon:first-child {
+ border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+.input-group-addon:last-child {
+ border-left: 0;
+}
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+.input-group-btn > .btn {
+ position: relative;
+}
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ z-index: 2;
+ margin-left: -1px;
+}
+.nav {
+ margin-bottom: 0;
+ padding-left: 0;
+ list-style: none;
+}
+.nav > li {
+ position: relative;
+ display: block;
+}
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+.nav > li.disabled > a {
+ color: #777777;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777777;
+ text-decoration: none;
+ background-color: transparent;
+ cursor: not-allowed;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eeeeee;
+ border-color: #337ab7;
+}
+.nav .nav-divider {
+ height: 1px;
+ margin: 8px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.nav > li > a > img {
+ max-width: none;
+}
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 2px 2px 0 0;
+}
+.nav-tabs > li > a:hover {
+ border-color: #eeeeee #eeeeee #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555555;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+ cursor: default;
+}
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+.nav-tabs.nav-justified > li > a {
+ text-align: center;
+ margin-bottom: 5px;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 2px;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 2px 2px 0 0;
+ }
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.nav-pills > li {
+ float: left;
+}
+.nav-pills > li > a {
+ border-radius: 2px;
+}
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #fff;
+ background-color: #337ab7;
+}
+.nav-stacked > li {
+ float: none;
+}
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+.nav-justified {
+ width: 100%;
+}
+.nav-justified > li {
+ float: none;
+}
+.nav-justified > li > a {
+ text-align: center;
+ margin-bottom: 5px;
+}
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 2px;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 2px 2px 0 0;
+ }
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.tab-content > .tab-pane {
+ display: none;
+}
+.tab-content > .active {
+ display: block;
+}
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+.navbar {
+ position: relative;
+ min-height: 30px;
+ margin-bottom: 18px;
+ border: 1px solid transparent;
+}
+@media (min-width: 541px) {
+ .navbar {
+ border-radius: 2px;
+ }
+}
+@media (min-width: 541px) {
+ .navbar-header {
+ float: left;
+ }
+}
+.navbar-collapse {
+ overflow-x: visible;
+ padding-right: 0px;
+ padding-left: 0px;
+ border-top: 1px solid transparent;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
+ -webkit-overflow-scrolling: touch;
+}
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+@media (min-width: 541px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ box-shadow: none;
+ }
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-left: 0;
+ padding-right: 0;
+ }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+@media (max-device-width: 540px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: 0px;
+ margin-left: 0px;
+}
+@media (min-width: 541px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+@media (min-width: 541px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+@media (min-width: 541px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+.navbar-brand {
+ float: left;
+ padding: 6px 0px;
+ font-size: 17px;
+ line-height: 18px;
+ height: 30px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+.navbar-brand > img {
+ display: block;
+}
+@media (min-width: 541px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: 0px;
+ }
+}
+.navbar-toggle {
+ position: relative;
+ float: right;
+ margin-right: 0px;
+ padding: 9px 10px;
+ margin-top: -2px;
+ margin-bottom: -2px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 2px;
+}
+.navbar-toggle:focus {
+ outline: 0;
+}
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+@media (min-width: 541px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+.navbar-nav {
+ margin: 3px 0px;
+}
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 18px;
+}
+@media (max-width: 540px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ box-shadow: none;
+ }
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 18px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+@media (min-width: 541px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+ .navbar-nav > li {
+ float: left;
+ }
+ .navbar-nav > li > a {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ }
+}
+.navbar-form {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding: 10px 0px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+@media (max-width: 540px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+@media (min-width: 541px) {
+ .navbar-form {
+ width: auto;
+ border: 0;
+ margin-left: 0;
+ margin-right: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-right-radius: 2px;
+ border-top-left-radius: 2px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.navbar-btn {
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+.navbar-btn.btn-sm {
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+.navbar-btn.btn-xs {
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+.navbar-text {
+ margin-top: 6px;
+ margin-bottom: 6px;
+}
+@media (min-width: 541px) {
+ .navbar-text {
+ float: left;
+ margin-left: 0px;
+ margin-right: 0px;
+ }
+}
+@media (min-width: 541px) {
+ .navbar-left {
+ float: left !important;
+ float: left;
+ }
+ .navbar-right {
+ float: right !important;
+ float: right;
+ margin-right: 0px;
+ }
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+ color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #5e5e5e;
+ background-color: transparent;
+}
+.navbar-default .navbar-text {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #333;
+ background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+ border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ background-color: #e7e7e7;
+ color: #555;
+}
+@media (max-width: 540px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #777;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #333;
+ background-color: transparent;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+}
+.navbar-default .navbar-link {
+ color: #777;
+}
+.navbar-default .navbar-link:hover {
+ color: #333;
+}
+.navbar-default .btn-link {
+ color: #777;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+ border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ background-color: #080808;
+ color: #fff;
+}
+@media (max-width: 540px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+ }
+}
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-link:hover {
+ color: #fff;
+}
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 18px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 2px;
+}
+.breadcrumb > li {
+ display: inline-block;
+}
+.breadcrumb > li + li:before {
+ content: "/\00a0";
+ padding: 0 5px;
+ color: #5e5e5e;
+}
+.breadcrumb > .active {
+ color: #777777;
+}
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 18px 0;
+ border-radius: 2px;
+}
+.pagination > li {
+ display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ line-height: 1.42857143;
+ text-decoration: none;
+ color: #337ab7;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ margin-left: -1px;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ z-index: 2;
+ color: #23527c;
+ background-color: #eeeeee;
+ border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 3;
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+ cursor: default;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777777;
+ background-color: #fff;
+ border-color: #ddd;
+ cursor: not-allowed;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 17px;
+ line-height: 1.3333333;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-bottom-left-radius: 3px;
+ border-top-left-radius: 3px;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-bottom-right-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-bottom-left-radius: 1px;
+ border-top-left-radius: 1px;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-bottom-right-radius: 1px;
+ border-top-right-radius: 1px;
+}
+.pager {
+ padding-left: 0;
+ margin: 18px 0;
+ list-style: none;
+ text-align: center;
+}
+.pager li {
+ display: inline;
+}
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777777;
+ background-color: #fff;
+ cursor: not-allowed;
+}
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.label:empty {
+ display: none;
+}
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+.label-default {
+ background-color: #777777;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+.label-primary {
+ background-color: #337ab7;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #286090;
+}
+.label-success {
+ background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+.label-info {
+ background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+.label-warning {
+ background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+.label-danger {
+ background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ color: #fff;
+ line-height: 1;
+ vertical-align: middle;
+ white-space: nowrap;
+ text-align: center;
+ background-color: #777777;
+ border-radius: 10px;
+}
+.badge:empty {
+ display: none;
+}
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.list-group-item > .badge {
+ float: right;
+}
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+.jumbotron {
+ padding-top: 30px;
+ padding-bottom: 30px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eeeeee;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 20px;
+ font-weight: 200;
+}
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+.container .jumbotron,
+.container-fluid .jumbotron {
+ border-radius: 3px;
+ padding-left: 0px;
+ padding-right: 0px;
+}
+.jumbotron .container {
+ max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding-top: 48px;
+ padding-bottom: 48px;
+ }
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-left: 60px;
+ padding-right: 60px;
+ }
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 59px;
+ }
+}
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 18px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 2px;
+ -webkit-transition: border 0.2s ease-in-out;
+ -o-transition: border 0.2s ease-in-out;
+ transition: border 0.2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+ margin-left: auto;
+ margin-right: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #337ab7;
+}
+.thumbnail .caption {
+ padding: 9px;
+ color: #000;
+}
+.alert {
+ padding: 15px;
+ margin-bottom: 18px;
+ border: 1px solid transparent;
+ border-radius: 2px;
+}
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+.alert .alert-link {
+ font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+.alert > p + p {
+ margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+.alert-success {
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+ color: #3c763d;
+}
+.alert-success hr {
+ border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+ color: #2b542c;
+}
+.alert-info {
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+ color: #31708f;
+}
+.alert-info hr {
+ border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+ color: #245269;
+}
+.alert-warning {
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+ color: #8a6d3b;
+}
+.alert-warning hr {
+ border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+ color: #66512c;
+}
+.alert-danger {
+ background-color: #f2dede;
+ border-color: #ebccd1;
+ color: #a94442;
+}
+.alert-danger hr {
+ border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+ color: #843534;
+}
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+.progress {
+ overflow: hidden;
+ height: 18px;
+ margin-bottom: 18px;
+ background-color: #f5f5f5;
+ border-radius: 2px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+.progress-bar {
+ float: left;
+ width: 0%;
+ height: 100%;
+ font-size: 12px;
+ line-height: 18px;
+ color: #fff;
+ text-align: center;
+ background-color: #337ab7;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -webkit-transition: width 0.6s ease;
+ -o-transition: width 0.6s ease;
+ transition: width 0.6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.media {
+ margin-top: 15px;
+}
+.media:first-child {
+ margin-top: 0;
+}
+.media,
+.media-body {
+ zoom: 1;
+ overflow: hidden;
+}
+.media-body {
+ width: 10000px;
+}
+.media-object {
+ display: block;
+}
+.media-object.img-thumbnail {
+ max-width: none;
+}
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+.media-middle {
+ vertical-align: middle;
+}
+.media-bottom {
+ vertical-align: bottom;
+}
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+.list-group {
+ margin-bottom: 20px;
+ padding-left: 0;
+}
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.list-group-item:first-child {
+ border-top-right-radius: 2px;
+ border-top-left-radius: 2px;
+}
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 2px;
+ border-bottom-left-radius: 2px;
+}
+a.list-group-item,
+button.list-group-item {
+ color: #555;
+}
+a.list-group-item .list-group-item-heading,
+button.list-group-item .list-group-item-heading {
+ color: #333;
+}
+a.list-group-item:hover,
+button.list-group-item:hover,
+a.list-group-item:focus,
+button.list-group-item:focus {
+ text-decoration: none;
+ color: #555;
+ background-color: #f5f5f5;
+}
+button.list-group-item {
+ width: 100%;
+ text-align: left;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ background-color: #eeeeee;
+ color: #777777;
+ cursor: not-allowed;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777777;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #c7ddef;
+}
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+}
+a.list-group-item-success,
+button.list-group-item-success {
+ color: #3c763d;
+}
+a.list-group-item-success .list-group-item-heading,
+button.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-success:hover,
+button.list-group-item-success:hover,
+a.list-group-item-success:focus,
+button.list-group-item-success:focus {
+ color: #3c763d;
+ background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+button.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+button.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus,
+button.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d;
+}
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7;
+}
+a.list-group-item-info,
+button.list-group-item-info {
+ color: #31708f;
+}
+a.list-group-item-info .list-group-item-heading,
+button.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-info:hover,
+button.list-group-item-info:hover,
+a.list-group-item-info:focus,
+button.list-group-item-info:focus {
+ color: #31708f;
+ background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+button.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+button.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus,
+button.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f;
+}
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+a.list-group-item-warning,
+button.list-group-item-warning {
+ color: #8a6d3b;
+}
+a.list-group-item-warning .list-group-item-heading,
+button.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-warning:hover,
+button.list-group-item-warning:hover,
+a.list-group-item-warning:focus,
+button.list-group-item-warning:focus {
+ color: #8a6d3b;
+ background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+button.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+button.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus,
+button.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b;
+}
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede;
+}
+a.list-group-item-danger,
+button.list-group-item-danger {
+ color: #a94442;
+}
+a.list-group-item-danger .list-group-item-heading,
+button.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-danger:hover,
+button.list-group-item-danger:hover,
+a.list-group-item-danger:focus,
+button.list-group-item-danger:focus {
+ color: #a94442;
+ background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+button.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+button.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus,
+button.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442;
+}
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+.panel {
+ margin-bottom: 18px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 2px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+.panel-body {
+ padding: 15px;
+}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-right-radius: 1px;
+ border-top-left-radius: 1px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 15px;
+ color: inherit;
+}
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 1px;
+ border-bottom-left-radius: 1px;
+}
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-right-radius: 1px;
+ border-top-left-radius: 1px;
+}
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 1px;
+ border-bottom-left-radius: 1px;
+}
+.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+}
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-left: 15px;
+ padding-right: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-right-radius: 1px;
+ border-top-left-radius: 1px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 1px;
+ border-top-right-radius: 1px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 1px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 1px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 1px;
+ border-bottom-left-radius: 1px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-left-radius: 1px;
+ border-bottom-right-radius: 1px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 1px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 1px;
+}
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #ddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+.panel > .table-responsive {
+ border: 0;
+ margin-bottom: 0;
+}
+.panel-group {
+ margin-bottom: 18px;
+}
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 2px;
+}
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #ddd;
+}
+.panel-group .panel-footer {
+ border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd;
+}
+.panel-default {
+ border-color: #ddd;
+}
+.panel-default > .panel-heading {
+ color: #333333;
+ background-color: #f5f5f5;
+ border-color: #ddd;
+}
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd;
+}
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333333;
+}
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd;
+}
+.panel-primary {
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337ab7;
+}
+.panel-primary > .panel-heading .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337ab7;
+}
+.panel-success {
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6;
+}
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d;
+}
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6;
+}
+.panel-info {
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1;
+}
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f;
+}
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1;
+}
+.panel-warning {
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc;
+}
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b;
+}
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc;
+}
+.panel-danger {
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1;
+}
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442;
+}
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1;
+}
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ height: 100%;
+ width: 100%;
+ border: 0;
+}
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 2px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, 0.15);
+}
+.well-lg {
+ padding: 24px;
+ border-radius: 3px;
+}
+.well-sm {
+ padding: 9px;
+ border-radius: 1px;
+}
+.close {
+ float: right;
+ font-size: 19.5px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ opacity: 0.2;
+ filter: alpha(opacity=20);
+}
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+button.close {
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+ -webkit-appearance: none;
+}
+.modal-open {
+ overflow: hidden;
+}
+.modal {
+ display: none;
+ overflow: hidden;
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+.modal.fade .modal-dialog {
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+ -webkit-transition: -webkit-transform 0.3s ease-out;
+ -moz-transition: -moz-transform 0.3s ease-out;
+ -o-transition: -o-transform 0.3s ease-out;
+ transition: transform 0.3s ease-out;
+}
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 3px;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+ background-clip: padding-box;
+ outline: 0;
+}
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000;
+}
+.modal-backdrop.fade {
+ opacity: 0;
+ filter: alpha(opacity=0);
+}
+.modal-backdrop.in {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+ margin-top: -2px;
+}
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+ margin-left: 5px;
+ margin-bottom: 0;
+}
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+ }
+ .modal-sm {
+ width: 300px;
+ }
+}
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ letter-spacing: normal;
+ line-break: auto;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ white-space: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ font-size: 12px;
+ opacity: 0;
+ filter: alpha(opacity=0);
+}
+.tooltip.in {
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+.tooltip.top {
+ margin-top: -3px;
+ padding: 5px 0;
+}
+.tooltip.right {
+ margin-left: 3px;
+ padding: 0 5px;
+}
+.tooltip.bottom {
+ margin-top: 3px;
+ padding: 5px 0;
+}
+.tooltip.left {
+ margin-left: -3px;
+ padding: 0 5px;
+}
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 2px;
+}
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-left .tooltip-arrow {
+ bottom: 0;
+ right: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000;
+}
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000;
+}
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ letter-spacing: normal;
+ line-break: auto;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ white-space: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ font-size: 13px;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 3px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+}
+.popover.top {
+ margin-top: -10px;
+}
+.popover.right {
+ margin-left: 10px;
+}
+.popover.bottom {
+ margin-top: 10px;
+}
+.popover.left {
+ margin-left: -10px;
+}
+.popover-title {
+ margin: 0;
+ padding: 8px 14px;
+ font-size: 13px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 2px 2px 0 0;
+}
+.popover-content {
+ padding: 9px 14px;
+}
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.popover > .arrow {
+ border-width: 11px;
+}
+.popover > .arrow:after {
+ border-width: 10px;
+ content: "";
+}
+.popover.top > .arrow {
+ left: 50%;
+ margin-left: -11px;
+ border-bottom-width: 0;
+ border-top-color: #999999;
+ border-top-color: rgba(0, 0, 0, 0.25);
+ bottom: -11px;
+}
+.popover.top > .arrow:after {
+ content: " ";
+ bottom: 1px;
+ margin-left: -10px;
+ border-bottom-width: 0;
+ border-top-color: #fff;
+}
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-left-width: 0;
+ border-right-color: #999999;
+ border-right-color: rgba(0, 0, 0, 0.25);
+}
+.popover.right > .arrow:after {
+ content: " ";
+ left: 1px;
+ bottom: -10px;
+ border-left-width: 0;
+ border-right-color: #fff;
+}
+.popover.bottom > .arrow {
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999999;
+ border-bottom-color: rgba(0, 0, 0, 0.25);
+ top: -11px;
+}
+.popover.bottom > .arrow:after {
+ content: " ";
+ top: 1px;
+ margin-left: -10px;
+ border-top-width: 0;
+ border-bottom-color: #fff;
+}
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999999;
+ border-left-color: rgba(0, 0, 0, 0.25);
+}
+.popover.left > .arrow:after {
+ content: " ";
+ right: 1px;
+ border-right-width: 0;
+ border-left-color: #fff;
+ bottom: -10px;
+}
+.carousel {
+ position: relative;
+}
+.carousel-inner {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+}
+.carousel-inner > .item {
+ display: none;
+ position: relative;
+ -webkit-transition: 0.6s ease-in-out left;
+ -o-transition: 0.6s ease-in-out left;
+ transition: 0.6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform 0.6s ease-in-out;
+ -moz-transition: -moz-transform 0.6s ease-in-out;
+ -o-transition: -o-transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out;
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000px;
+ -moz-perspective: 1000px;
+ perspective: 1000px;
+ }
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ left: 0;
+ }
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ left: 0;
+ }
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ left: 0;
+ }
+}
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+.carousel-inner > .active {
+ left: 0;
+}
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+.carousel-inner > .next {
+ left: 100%;
+}
+.carousel-inner > .prev {
+ left: -100%;
+}
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+.carousel-inner > .active.left {
+ left: -100%;
+}
+.carousel-inner > .active.right {
+ left: 100%;
+}
+.carousel-control {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 15%;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+ background-color: rgba(0, 0, 0, 0);
+}
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+}
+.carousel-control.right {
+ left: auto;
+ right: 0;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+}
+.carousel-control:hover,
+.carousel-control:focus {
+ outline: 0;
+ color: #fff;
+ text-decoration: none;
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ margin-top: -10px;
+ z-index: 5;
+ display: inline-block;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ line-height: 1;
+ font-family: serif;
+}
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ margin-left: -30%;
+ padding-left: 0;
+ list-style: none;
+ text-align: center;
+}
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ border: 1px solid #fff;
+ border-radius: 10px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+}
+.carousel-indicators .active {
+ margin: 0;
+ width: 12px;
+ height: 12px;
+ background-color: #fff;
+}
+.carousel-caption {
+ position: absolute;
+ left: 15%;
+ right: 15%;
+ bottom: 20px;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+}
+.carousel-caption .btn {
+ text-shadow: none;
+}
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -10px;
+ font-size: 30px;
+ }
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -10px;
+ }
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -10px;
+ }
+ .carousel-caption {
+ left: 20%;
+ right: 20%;
+ padding-bottom: 30px;
+ }
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-header:before,
+.modal-header:after,
+.modal-footer:before,
+.modal-footer:after,
+.item_buttons:before,
+.item_buttons:after {
+ content: " ";
+ display: table;
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-header:after,
+.modal-footer:after,
+.item_buttons:after {
+ clear: both;
+}
+.center-block {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.hidden {
+ display: none !important;
+}
+.affix {
+ position: fixed;
+}
+@-ms-viewport {
+ width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+ table.visible-xs {
+ display: table !important;
+ }
+ tr.visible-xs {
+ display: table-row !important;
+ }
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+ table.visible-sm {
+ display: table !important;
+ }
+ tr.visible-sm {
+ display: table-row !important;
+ }
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+ table.visible-md {
+ display: table !important;
+ }
+ tr.visible-md {
+ display: table-row !important;
+ }
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+ table.visible-lg {
+ display: table !important;
+ }
+ tr.visible-lg {
+ display: table-row !important;
+ }
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+.visible-print {
+ display: none !important;
+}
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+ table.visible-print {
+ display: table !important;
+ }
+ tr.visible-print {
+ display: table-row !important;
+ }
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+.visible-print-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+/*!
+*
+* Font Awesome
+*
+*/
+/*!
+ * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+/* FONT PATH
+ * -------------------------- */
+@font-face {
+ font-family: 'FontAwesome';
+ src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?v=4.7.0');
+ src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../components/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../components/font-awesome/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../components/font-awesome/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+.fa {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+/* makes the font 33% larger relative to the icon container */
+.fa-lg {
+ font-size: 1.33333333em;
+ line-height: 0.75em;
+ vertical-align: -15%;
+}
+.fa-2x {
+ font-size: 2em;
+}
+.fa-3x {
+ font-size: 3em;
+}
+.fa-4x {
+ font-size: 4em;
+}
+.fa-5x {
+ font-size: 5em;
+}
+.fa-fw {
+ width: 1.28571429em;
+ text-align: center;
+}
+.fa-ul {
+ padding-left: 0;
+ margin-left: 2.14285714em;
+ list-style-type: none;
+}
+.fa-ul > li {
+ position: relative;
+}
+.fa-li {
+ position: absolute;
+ left: -2.14285714em;
+ width: 2.14285714em;
+ top: 0.14285714em;
+ text-align: center;
+}
+.fa-li.fa-lg {
+ left: -1.85714286em;
+}
+.fa-border {
+ padding: .2em .25em .15em;
+ border: solid 0.08em #eee;
+ border-radius: .1em;
+}
+.fa-pull-left {
+ float: left;
+}
+.fa-pull-right {
+ float: right;
+}
+.fa.fa-pull-left {
+ margin-right: .3em;
+}
+.fa.fa-pull-right {
+ margin-left: .3em;
+}
+/* Deprecated as of 4.4.0 */
+.pull-right {
+ float: right;
+}
+.pull-left {
+ float: left;
+}
+.fa.pull-left {
+ margin-right: .3em;
+}
+.fa.pull-right {
+ margin-left: .3em;
+}
+.fa-spin {
+ -webkit-animation: fa-spin 2s infinite linear;
+ animation: fa-spin 2s infinite linear;
+}
+.fa-pulse {
+ -webkit-animation: fa-spin 1s infinite steps(8);
+ animation: fa-spin 1s infinite steps(8);
+}
+@-webkit-keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+@keyframes fa-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+.fa-rotate-90 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
+ -webkit-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+.fa-rotate-180 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.fa-rotate-270 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
+ -webkit-transform: rotate(270deg);
+ -ms-transform: rotate(270deg);
+ transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
+ -webkit-transform: scale(-1, 1);
+ -ms-transform: scale(-1, 1);
+ transform: scale(-1, 1);
+}
+.fa-flip-vertical {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
+ -webkit-transform: scale(1, -1);
+ -ms-transform: scale(1, -1);
+ transform: scale(1, -1);
+}
+:root .fa-rotate-90,
+:root .fa-rotate-180,
+:root .fa-rotate-270,
+:root .fa-flip-horizontal,
+:root .fa-flip-vertical {
+ filter: none;
+}
+.fa-stack {
+ position: relative;
+ display: inline-block;
+ width: 2em;
+ height: 2em;
+ line-height: 2em;
+ vertical-align: middle;
+}
+.fa-stack-1x,
+.fa-stack-2x {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+.fa-stack-1x {
+ line-height: inherit;
+}
+.fa-stack-2x {
+ font-size: 2em;
+}
+.fa-inverse {
+ color: #fff;
+}
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+.fa-glass:before {
+ content: "\f000";
+}
+.fa-music:before {
+ content: "\f001";
+}
+.fa-search:before {
+ content: "\f002";
+}
+.fa-envelope-o:before {
+ content: "\f003";
+}
+.fa-heart:before {
+ content: "\f004";
+}
+.fa-star:before {
+ content: "\f005";
+}
+.fa-star-o:before {
+ content: "\f006";
+}
+.fa-user:before {
+ content: "\f007";
+}
+.fa-film:before {
+ content: "\f008";
+}
+.fa-th-large:before {
+ content: "\f009";
+}
+.fa-th:before {
+ content: "\f00a";
+}
+.fa-th-list:before {
+ content: "\f00b";
+}
+.fa-check:before {
+ content: "\f00c";
+}
+.fa-remove:before,
+.fa-close:before,
+.fa-times:before {
+ content: "\f00d";
+}
+.fa-search-plus:before {
+ content: "\f00e";
+}
+.fa-search-minus:before {
+ content: "\f010";
+}
+.fa-power-off:before {
+ content: "\f011";
+}
+.fa-signal:before {
+ content: "\f012";
+}
+.fa-gear:before,
+.fa-cog:before {
+ content: "\f013";
+}
+.fa-trash-o:before {
+ content: "\f014";
+}
+.fa-home:before {
+ content: "\f015";
+}
+.fa-file-o:before {
+ content: "\f016";
+}
+.fa-clock-o:before {
+ content: "\f017";
+}
+.fa-road:before {
+ content: "\f018";
+}
+.fa-download:before {
+ content: "\f019";
+}
+.fa-arrow-circle-o-down:before {
+ content: "\f01a";
+}
+.fa-arrow-circle-o-up:before {
+ content: "\f01b";
+}
+.fa-inbox:before {
+ content: "\f01c";
+}
+.fa-play-circle-o:before {
+ content: "\f01d";
+}
+.fa-rotate-right:before,
+.fa-repeat:before {
+ content: "\f01e";
+}
+.fa-refresh:before {
+ content: "\f021";
+}
+.fa-list-alt:before {
+ content: "\f022";
+}
+.fa-lock:before {
+ content: "\f023";
+}
+.fa-flag:before {
+ content: "\f024";
+}
+.fa-headphones:before {
+ content: "\f025";
+}
+.fa-volume-off:before {
+ content: "\f026";
+}
+.fa-volume-down:before {
+ content: "\f027";
+}
+.fa-volume-up:before {
+ content: "\f028";
+}
+.fa-qrcode:before {
+ content: "\f029";
+}
+.fa-barcode:before {
+ content: "\f02a";
+}
+.fa-tag:before {
+ content: "\f02b";
+}
+.fa-tags:before {
+ content: "\f02c";
+}
+.fa-book:before {
+ content: "\f02d";
+}
+.fa-bookmark:before {
+ content: "\f02e";
+}
+.fa-print:before {
+ content: "\f02f";
+}
+.fa-camera:before {
+ content: "\f030";
+}
+.fa-font:before {
+ content: "\f031";
+}
+.fa-bold:before {
+ content: "\f032";
+}
+.fa-italic:before {
+ content: "\f033";
+}
+.fa-text-height:before {
+ content: "\f034";
+}
+.fa-text-width:before {
+ content: "\f035";
+}
+.fa-align-left:before {
+ content: "\f036";
+}
+.fa-align-center:before {
+ content: "\f037";
+}
+.fa-align-right:before {
+ content: "\f038";
+}
+.fa-align-justify:before {
+ content: "\f039";
+}
+.fa-list:before {
+ content: "\f03a";
+}
+.fa-dedent:before,
+.fa-outdent:before {
+ content: "\f03b";
+}
+.fa-indent:before {
+ content: "\f03c";
+}
+.fa-video-camera:before {
+ content: "\f03d";
+}
+.fa-photo:before,
+.fa-image:before,
+.fa-picture-o:before {
+ content: "\f03e";
+}
+.fa-pencil:before {
+ content: "\f040";
+}
+.fa-map-marker:before {
+ content: "\f041";
+}
+.fa-adjust:before {
+ content: "\f042";
+}
+.fa-tint:before {
+ content: "\f043";
+}
+.fa-edit:before,
+.fa-pencil-square-o:before {
+ content: "\f044";
+}
+.fa-share-square-o:before {
+ content: "\f045";
+}
+.fa-check-square-o:before {
+ content: "\f046";
+}
+.fa-arrows:before {
+ content: "\f047";
+}
+.fa-step-backward:before {
+ content: "\f048";
+}
+.fa-fast-backward:before {
+ content: "\f049";
+}
+.fa-backward:before {
+ content: "\f04a";
+}
+.fa-play:before {
+ content: "\f04b";
+}
+.fa-pause:before {
+ content: "\f04c";
+}
+.fa-stop:before {
+ content: "\f04d";
+}
+.fa-forward:before {
+ content: "\f04e";
+}
+.fa-fast-forward:before {
+ content: "\f050";
+}
+.fa-step-forward:before {
+ content: "\f051";
+}
+.fa-eject:before {
+ content: "\f052";
+}
+.fa-chevron-left:before {
+ content: "\f053";
+}
+.fa-chevron-right:before {
+ content: "\f054";
+}
+.fa-plus-circle:before {
+ content: "\f055";
+}
+.fa-minus-circle:before {
+ content: "\f056";
+}
+.fa-times-circle:before {
+ content: "\f057";
+}
+.fa-check-circle:before {
+ content: "\f058";
+}
+.fa-question-circle:before {
+ content: "\f059";
+}
+.fa-info-circle:before {
+ content: "\f05a";
+}
+.fa-crosshairs:before {
+ content: "\f05b";
+}
+.fa-times-circle-o:before {
+ content: "\f05c";
+}
+.fa-check-circle-o:before {
+ content: "\f05d";
+}
+.fa-ban:before {
+ content: "\f05e";
+}
+.fa-arrow-left:before {
+ content: "\f060";
+}
+.fa-arrow-right:before {
+ content: "\f061";
+}
+.fa-arrow-up:before {
+ content: "\f062";
+}
+.fa-arrow-down:before {
+ content: "\f063";
+}
+.fa-mail-forward:before,
+.fa-share:before {
+ content: "\f064";
+}
+.fa-expand:before {
+ content: "\f065";
+}
+.fa-compress:before {
+ content: "\f066";
+}
+.fa-plus:before {
+ content: "\f067";
+}
+.fa-minus:before {
+ content: "\f068";
+}
+.fa-asterisk:before {
+ content: "\f069";
+}
+.fa-exclamation-circle:before {
+ content: "\f06a";
+}
+.fa-gift:before {
+ content: "\f06b";
+}
+.fa-leaf:before {
+ content: "\f06c";
+}
+.fa-fire:before {
+ content: "\f06d";
+}
+.fa-eye:before {
+ content: "\f06e";
+}
+.fa-eye-slash:before {
+ content: "\f070";
+}
+.fa-warning:before,
+.fa-exclamation-triangle:before {
+ content: "\f071";
+}
+.fa-plane:before {
+ content: "\f072";
+}
+.fa-calendar:before {
+ content: "\f073";
+}
+.fa-random:before {
+ content: "\f074";
+}
+.fa-comment:before {
+ content: "\f075";
+}
+.fa-magnet:before {
+ content: "\f076";
+}
+.fa-chevron-up:before {
+ content: "\f077";
+}
+.fa-chevron-down:before {
+ content: "\f078";
+}
+.fa-retweet:before {
+ content: "\f079";
+}
+.fa-shopping-cart:before {
+ content: "\f07a";
+}
+.fa-folder:before {
+ content: "\f07b";
+}
+.fa-folder-open:before {
+ content: "\f07c";
+}
+.fa-arrows-v:before {
+ content: "\f07d";
+}
+.fa-arrows-h:before {
+ content: "\f07e";
+}
+.fa-bar-chart-o:before,
+.fa-bar-chart:before {
+ content: "\f080";
+}
+.fa-twitter-square:before {
+ content: "\f081";
+}
+.fa-facebook-square:before {
+ content: "\f082";
+}
+.fa-camera-retro:before {
+ content: "\f083";
+}
+.fa-key:before {
+ content: "\f084";
+}
+.fa-gears:before,
+.fa-cogs:before {
+ content: "\f085";
+}
+.fa-comments:before {
+ content: "\f086";
+}
+.fa-thumbs-o-up:before {
+ content: "\f087";
+}
+.fa-thumbs-o-down:before {
+ content: "\f088";
+}
+.fa-star-half:before {
+ content: "\f089";
+}
+.fa-heart-o:before {
+ content: "\f08a";
+}
+.fa-sign-out:before {
+ content: "\f08b";
+}
+.fa-linkedin-square:before {
+ content: "\f08c";
+}
+.fa-thumb-tack:before {
+ content: "\f08d";
+}
+.fa-external-link:before {
+ content: "\f08e";
+}
+.fa-sign-in:before {
+ content: "\f090";
+}
+.fa-trophy:before {
+ content: "\f091";
+}
+.fa-github-square:before {
+ content: "\f092";
+}
+.fa-upload:before {
+ content: "\f093";
+}
+.fa-lemon-o:before {
+ content: "\f094";
+}
+.fa-phone:before {
+ content: "\f095";
+}
+.fa-square-o:before {
+ content: "\f096";
+}
+.fa-bookmark-o:before {
+ content: "\f097";
+}
+.fa-phone-square:before {
+ content: "\f098";
+}
+.fa-twitter:before {
+ content: "\f099";
+}
+.fa-facebook-f:before,
+.fa-facebook:before {
+ content: "\f09a";
+}
+.fa-github:before {
+ content: "\f09b";
+}
+.fa-unlock:before {
+ content: "\f09c";
+}
+.fa-credit-card:before {
+ content: "\f09d";
+}
+.fa-feed:before,
+.fa-rss:before {
+ content: "\f09e";
+}
+.fa-hdd-o:before {
+ content: "\f0a0";
+}
+.fa-bullhorn:before {
+ content: "\f0a1";
+}
+.fa-bell:before {
+ content: "\f0f3";
+}
+.fa-certificate:before {
+ content: "\f0a3";
+}
+.fa-hand-o-right:before {
+ content: "\f0a4";
+}
+.fa-hand-o-left:before {
+ content: "\f0a5";
+}
+.fa-hand-o-up:before {
+ content: "\f0a6";
+}
+.fa-hand-o-down:before {
+ content: "\f0a7";
+}
+.fa-arrow-circle-left:before {
+ content: "\f0a8";
+}
+.fa-arrow-circle-right:before {
+ content: "\f0a9";
+}
+.fa-arrow-circle-up:before {
+ content: "\f0aa";
+}
+.fa-arrow-circle-down:before {
+ content: "\f0ab";
+}
+.fa-globe:before {
+ content: "\f0ac";
+}
+.fa-wrench:before {
+ content: "\f0ad";
+}
+.fa-tasks:before {
+ content: "\f0ae";
+}
+.fa-filter:before {
+ content: "\f0b0";
+}
+.fa-briefcase:before {
+ content: "\f0b1";
+}
+.fa-arrows-alt:before {
+ content: "\f0b2";
+}
+.fa-group:before,
+.fa-users:before {
+ content: "\f0c0";
+}
+.fa-chain:before,
+.fa-link:before {
+ content: "\f0c1";
+}
+.fa-cloud:before {
+ content: "\f0c2";
+}
+.fa-flask:before {
+ content: "\f0c3";
+}
+.fa-cut:before,
+.fa-scissors:before {
+ content: "\f0c4";
+}
+.fa-copy:before,
+.fa-files-o:before {
+ content: "\f0c5";
+}
+.fa-paperclip:before {
+ content: "\f0c6";
+}
+.fa-save:before,
+.fa-floppy-o:before {
+ content: "\f0c7";
+}
+.fa-square:before {
+ content: "\f0c8";
+}
+.fa-navicon:before,
+.fa-reorder:before,
+.fa-bars:before {
+ content: "\f0c9";
+}
+.fa-list-ul:before {
+ content: "\f0ca";
+}
+.fa-list-ol:before {
+ content: "\f0cb";
+}
+.fa-strikethrough:before {
+ content: "\f0cc";
+}
+.fa-underline:before {
+ content: "\f0cd";
+}
+.fa-table:before {
+ content: "\f0ce";
+}
+.fa-magic:before {
+ content: "\f0d0";
+}
+.fa-truck:before {
+ content: "\f0d1";
+}
+.fa-pinterest:before {
+ content: "\f0d2";
+}
+.fa-pinterest-square:before {
+ content: "\f0d3";
+}
+.fa-google-plus-square:before {
+ content: "\f0d4";
+}
+.fa-google-plus:before {
+ content: "\f0d5";
+}
+.fa-money:before {
+ content: "\f0d6";
+}
+.fa-caret-down:before {
+ content: "\f0d7";
+}
+.fa-caret-up:before {
+ content: "\f0d8";
+}
+.fa-caret-left:before {
+ content: "\f0d9";
+}
+.fa-caret-right:before {
+ content: "\f0da";
+}
+.fa-columns:before {
+ content: "\f0db";
+}
+.fa-unsorted:before,
+.fa-sort:before {
+ content: "\f0dc";
+}
+.fa-sort-down:before,
+.fa-sort-desc:before {
+ content: "\f0dd";
+}
+.fa-sort-up:before,
+.fa-sort-asc:before {
+ content: "\f0de";
+}
+.fa-envelope:before {
+ content: "\f0e0";
+}
+.fa-linkedin:before {
+ content: "\f0e1";
+}
+.fa-rotate-left:before,
+.fa-undo:before {
+ content: "\f0e2";
+}
+.fa-legal:before,
+.fa-gavel:before {
+ content: "\f0e3";
+}
+.fa-dashboard:before,
+.fa-tachometer:before {
+ content: "\f0e4";
+}
+.fa-comment-o:before {
+ content: "\f0e5";
+}
+.fa-comments-o:before {
+ content: "\f0e6";
+}
+.fa-flash:before,
+.fa-bolt:before {
+ content: "\f0e7";
+}
+.fa-sitemap:before {
+ content: "\f0e8";
+}
+.fa-umbrella:before {
+ content: "\f0e9";
+}
+.fa-paste:before,
+.fa-clipboard:before {
+ content: "\f0ea";
+}
+.fa-lightbulb-o:before {
+ content: "\f0eb";
+}
+.fa-exchange:before {
+ content: "\f0ec";
+}
+.fa-cloud-download:before {
+ content: "\f0ed";
+}
+.fa-cloud-upload:before {
+ content: "\f0ee";
+}
+.fa-user-md:before {
+ content: "\f0f0";
+}
+.fa-stethoscope:before {
+ content: "\f0f1";
+}
+.fa-suitcase:before {
+ content: "\f0f2";
+}
+.fa-bell-o:before {
+ content: "\f0a2";
+}
+.fa-coffee:before {
+ content: "\f0f4";
+}
+.fa-cutlery:before {
+ content: "\f0f5";
+}
+.fa-file-text-o:before {
+ content: "\f0f6";
+}
+.fa-building-o:before {
+ content: "\f0f7";
+}
+.fa-hospital-o:before {
+ content: "\f0f8";
+}
+.fa-ambulance:before {
+ content: "\f0f9";
+}
+.fa-medkit:before {
+ content: "\f0fa";
+}
+.fa-fighter-jet:before {
+ content: "\f0fb";
+}
+.fa-beer:before {
+ content: "\f0fc";
+}
+.fa-h-square:before {
+ content: "\f0fd";
+}
+.fa-plus-square:before {
+ content: "\f0fe";
+}
+.fa-angle-double-left:before {
+ content: "\f100";
+}
+.fa-angle-double-right:before {
+ content: "\f101";
+}
+.fa-angle-double-up:before {
+ content: "\f102";
+}
+.fa-angle-double-down:before {
+ content: "\f103";
+}
+.fa-angle-left:before {
+ content: "\f104";
+}
+.fa-angle-right:before {
+ content: "\f105";
+}
+.fa-angle-up:before {
+ content: "\f106";
+}
+.fa-angle-down:before {
+ content: "\f107";
+}
+.fa-desktop:before {
+ content: "\f108";
+}
+.fa-laptop:before {
+ content: "\f109";
+}
+.fa-tablet:before {
+ content: "\f10a";
+}
+.fa-mobile-phone:before,
+.fa-mobile:before {
+ content: "\f10b";
+}
+.fa-circle-o:before {
+ content: "\f10c";
+}
+.fa-quote-left:before {
+ content: "\f10d";
+}
+.fa-quote-right:before {
+ content: "\f10e";
+}
+.fa-spinner:before {
+ content: "\f110";
+}
+.fa-circle:before {
+ content: "\f111";
+}
+.fa-mail-reply:before,
+.fa-reply:before {
+ content: "\f112";
+}
+.fa-github-alt:before {
+ content: "\f113";
+}
+.fa-folder-o:before {
+ content: "\f114";
+}
+.fa-folder-open-o:before {
+ content: "\f115";
+}
+.fa-smile-o:before {
+ content: "\f118";
+}
+.fa-frown-o:before {
+ content: "\f119";
+}
+.fa-meh-o:before {
+ content: "\f11a";
+}
+.fa-gamepad:before {
+ content: "\f11b";
+}
+.fa-keyboard-o:before {
+ content: "\f11c";
+}
+.fa-flag-o:before {
+ content: "\f11d";
+}
+.fa-flag-checkered:before {
+ content: "\f11e";
+}
+.fa-terminal:before {
+ content: "\f120";
+}
+.fa-code:before {
+ content: "\f121";
+}
+.fa-mail-reply-all:before,
+.fa-reply-all:before {
+ content: "\f122";
+}
+.fa-star-half-empty:before,
+.fa-star-half-full:before,
+.fa-star-half-o:before {
+ content: "\f123";
+}
+.fa-location-arrow:before {
+ content: "\f124";
+}
+.fa-crop:before {
+ content: "\f125";
+}
+.fa-code-fork:before {
+ content: "\f126";
+}
+.fa-unlink:before,
+.fa-chain-broken:before {
+ content: "\f127";
+}
+.fa-question:before {
+ content: "\f128";
+}
+.fa-info:before {
+ content: "\f129";
+}
+.fa-exclamation:before {
+ content: "\f12a";
+}
+.fa-superscript:before {
+ content: "\f12b";
+}
+.fa-subscript:before {
+ content: "\f12c";
+}
+.fa-eraser:before {
+ content: "\f12d";
+}
+.fa-puzzle-piece:before {
+ content: "\f12e";
+}
+.fa-microphone:before {
+ content: "\f130";
+}
+.fa-microphone-slash:before {
+ content: "\f131";
+}
+.fa-shield:before {
+ content: "\f132";
+}
+.fa-calendar-o:before {
+ content: "\f133";
+}
+.fa-fire-extinguisher:before {
+ content: "\f134";
+}
+.fa-rocket:before {
+ content: "\f135";
+}
+.fa-maxcdn:before {
+ content: "\f136";
+}
+.fa-chevron-circle-left:before {
+ content: "\f137";
+}
+.fa-chevron-circle-right:before {
+ content: "\f138";
+}
+.fa-chevron-circle-up:before {
+ content: "\f139";
+}
+.fa-chevron-circle-down:before {
+ content: "\f13a";
+}
+.fa-html5:before {
+ content: "\f13b";
+}
+.fa-css3:before {
+ content: "\f13c";
+}
+.fa-anchor:before {
+ content: "\f13d";
+}
+.fa-unlock-alt:before {
+ content: "\f13e";
+}
+.fa-bullseye:before {
+ content: "\f140";
+}
+.fa-ellipsis-h:before {
+ content: "\f141";
+}
+.fa-ellipsis-v:before {
+ content: "\f142";
+}
+.fa-rss-square:before {
+ content: "\f143";
+}
+.fa-play-circle:before {
+ content: "\f144";
+}
+.fa-ticket:before {
+ content: "\f145";
+}
+.fa-minus-square:before {
+ content: "\f146";
+}
+.fa-minus-square-o:before {
+ content: "\f147";
+}
+.fa-level-up:before {
+ content: "\f148";
+}
+.fa-level-down:before {
+ content: "\f149";
+}
+.fa-check-square:before {
+ content: "\f14a";
+}
+.fa-pencil-square:before {
+ content: "\f14b";
+}
+.fa-external-link-square:before {
+ content: "\f14c";
+}
+.fa-share-square:before {
+ content: "\f14d";
+}
+.fa-compass:before {
+ content: "\f14e";
+}
+.fa-toggle-down:before,
+.fa-caret-square-o-down:before {
+ content: "\f150";
+}
+.fa-toggle-up:before,
+.fa-caret-square-o-up:before {
+ content: "\f151";
+}
+.fa-toggle-right:before,
+.fa-caret-square-o-right:before {
+ content: "\f152";
+}
+.fa-euro:before,
+.fa-eur:before {
+ content: "\f153";
+}
+.fa-gbp:before {
+ content: "\f154";
+}
+.fa-dollar:before,
+.fa-usd:before {
+ content: "\f155";
+}
+.fa-rupee:before,
+.fa-inr:before {
+ content: "\f156";
+}
+.fa-cny:before,
+.fa-rmb:before,
+.fa-yen:before,
+.fa-jpy:before {
+ content: "\f157";
+}
+.fa-ruble:before,
+.fa-rouble:before,
+.fa-rub:before {
+ content: "\f158";
+}
+.fa-won:before,
+.fa-krw:before {
+ content: "\f159";
+}
+.fa-bitcoin:before,
+.fa-btc:before {
+ content: "\f15a";
+}
+.fa-file:before {
+ content: "\f15b";
+}
+.fa-file-text:before {
+ content: "\f15c";
+}
+.fa-sort-alpha-asc:before {
+ content: "\f15d";
+}
+.fa-sort-alpha-desc:before {
+ content: "\f15e";
+}
+.fa-sort-amount-asc:before {
+ content: "\f160";
+}
+.fa-sort-amount-desc:before {
+ content: "\f161";
+}
+.fa-sort-numeric-asc:before {
+ content: "\f162";
+}
+.fa-sort-numeric-desc:before {
+ content: "\f163";
+}
+.fa-thumbs-up:before {
+ content: "\f164";
+}
+.fa-thumbs-down:before {
+ content: "\f165";
+}
+.fa-youtube-square:before {
+ content: "\f166";
+}
+.fa-youtube:before {
+ content: "\f167";
+}
+.fa-xing:before {
+ content: "\f168";
+}
+.fa-xing-square:before {
+ content: "\f169";
+}
+.fa-youtube-play:before {
+ content: "\f16a";
+}
+.fa-dropbox:before {
+ content: "\f16b";
+}
+.fa-stack-overflow:before {
+ content: "\f16c";
+}
+.fa-instagram:before {
+ content: "\f16d";
+}
+.fa-flickr:before {
+ content: "\f16e";
+}
+.fa-adn:before {
+ content: "\f170";
+}
+.fa-bitbucket:before {
+ content: "\f171";
+}
+.fa-bitbucket-square:before {
+ content: "\f172";
+}
+.fa-tumblr:before {
+ content: "\f173";
+}
+.fa-tumblr-square:before {
+ content: "\f174";
+}
+.fa-long-arrow-down:before {
+ content: "\f175";
+}
+.fa-long-arrow-up:before {
+ content: "\f176";
+}
+.fa-long-arrow-left:before {
+ content: "\f177";
+}
+.fa-long-arrow-right:before {
+ content: "\f178";
+}
+.fa-apple:before {
+ content: "\f179";
+}
+.fa-windows:before {
+ content: "\f17a";
+}
+.fa-android:before {
+ content: "\f17b";
+}
+.fa-linux:before {
+ content: "\f17c";
+}
+.fa-dribbble:before {
+ content: "\f17d";
+}
+.fa-skype:before {
+ content: "\f17e";
+}
+.fa-foursquare:before {
+ content: "\f180";
+}
+.fa-trello:before {
+ content: "\f181";
+}
+.fa-female:before {
+ content: "\f182";
+}
+.fa-male:before {
+ content: "\f183";
+}
+.fa-gittip:before,
+.fa-gratipay:before {
+ content: "\f184";
+}
+.fa-sun-o:before {
+ content: "\f185";
+}
+.fa-moon-o:before {
+ content: "\f186";
+}
+.fa-archive:before {
+ content: "\f187";
+}
+.fa-bug:before {
+ content: "\f188";
+}
+.fa-vk:before {
+ content: "\f189";
+}
+.fa-weibo:before {
+ content: "\f18a";
+}
+.fa-renren:before {
+ content: "\f18b";
+}
+.fa-pagelines:before {
+ content: "\f18c";
+}
+.fa-stack-exchange:before {
+ content: "\f18d";
+}
+.fa-arrow-circle-o-right:before {
+ content: "\f18e";
+}
+.fa-arrow-circle-o-left:before {
+ content: "\f190";
+}
+.fa-toggle-left:before,
+.fa-caret-square-o-left:before {
+ content: "\f191";
+}
+.fa-dot-circle-o:before {
+ content: "\f192";
+}
+.fa-wheelchair:before {
+ content: "\f193";
+}
+.fa-vimeo-square:before {
+ content: "\f194";
+}
+.fa-turkish-lira:before,
+.fa-try:before {
+ content: "\f195";
+}
+.fa-plus-square-o:before {
+ content: "\f196";
+}
+.fa-space-shuttle:before {
+ content: "\f197";
+}
+.fa-slack:before {
+ content: "\f198";
+}
+.fa-envelope-square:before {
+ content: "\f199";
+}
+.fa-wordpress:before {
+ content: "\f19a";
+}
+.fa-openid:before {
+ content: "\f19b";
+}
+.fa-institution:before,
+.fa-bank:before,
+.fa-university:before {
+ content: "\f19c";
+}
+.fa-mortar-board:before,
+.fa-graduation-cap:before {
+ content: "\f19d";
+}
+.fa-yahoo:before {
+ content: "\f19e";
+}
+.fa-google:before {
+ content: "\f1a0";
+}
+.fa-reddit:before {
+ content: "\f1a1";
+}
+.fa-reddit-square:before {
+ content: "\f1a2";
+}
+.fa-stumbleupon-circle:before {
+ content: "\f1a3";
+}
+.fa-stumbleupon:before {
+ content: "\f1a4";
+}
+.fa-delicious:before {
+ content: "\f1a5";
+}
+.fa-digg:before {
+ content: "\f1a6";
+}
+.fa-pied-piper-pp:before {
+ content: "\f1a7";
+}
+.fa-pied-piper-alt:before {
+ content: "\f1a8";
+}
+.fa-drupal:before {
+ content: "\f1a9";
+}
+.fa-joomla:before {
+ content: "\f1aa";
+}
+.fa-language:before {
+ content: "\f1ab";
+}
+.fa-fax:before {
+ content: "\f1ac";
+}
+.fa-building:before {
+ content: "\f1ad";
+}
+.fa-child:before {
+ content: "\f1ae";
+}
+.fa-paw:before {
+ content: "\f1b0";
+}
+.fa-spoon:before {
+ content: "\f1b1";
+}
+.fa-cube:before {
+ content: "\f1b2";
+}
+.fa-cubes:before {
+ content: "\f1b3";
+}
+.fa-behance:before {
+ content: "\f1b4";
+}
+.fa-behance-square:before {
+ content: "\f1b5";
+}
+.fa-steam:before {
+ content: "\f1b6";
+}
+.fa-steam-square:before {
+ content: "\f1b7";
+}
+.fa-recycle:before {
+ content: "\f1b8";
+}
+.fa-automobile:before,
+.fa-car:before {
+ content: "\f1b9";
+}
+.fa-cab:before,
+.fa-taxi:before {
+ content: "\f1ba";
+}
+.fa-tree:before {
+ content: "\f1bb";
+}
+.fa-spotify:before {
+ content: "\f1bc";
+}
+.fa-deviantart:before {
+ content: "\f1bd";
+}
+.fa-soundcloud:before {
+ content: "\f1be";
+}
+.fa-database:before {
+ content: "\f1c0";
+}
+.fa-file-pdf-o:before {
+ content: "\f1c1";
+}
+.fa-file-word-o:before {
+ content: "\f1c2";
+}
+.fa-file-excel-o:before {
+ content: "\f1c3";
+}
+.fa-file-powerpoint-o:before {
+ content: "\f1c4";
+}
+.fa-file-photo-o:before,
+.fa-file-picture-o:before,
+.fa-file-image-o:before {
+ content: "\f1c5";
+}
+.fa-file-zip-o:before,
+.fa-file-archive-o:before {
+ content: "\f1c6";
+}
+.fa-file-sound-o:before,
+.fa-file-audio-o:before {
+ content: "\f1c7";
+}
+.fa-file-movie-o:before,
+.fa-file-video-o:before {
+ content: "\f1c8";
+}
+.fa-file-code-o:before {
+ content: "\f1c9";
+}
+.fa-vine:before {
+ content: "\f1ca";
+}
+.fa-codepen:before {
+ content: "\f1cb";
+}
+.fa-jsfiddle:before {
+ content: "\f1cc";
+}
+.fa-life-bouy:before,
+.fa-life-buoy:before,
+.fa-life-saver:before,
+.fa-support:before,
+.fa-life-ring:before {
+ content: "\f1cd";
+}
+.fa-circle-o-notch:before {
+ content: "\f1ce";
+}
+.fa-ra:before,
+.fa-resistance:before,
+.fa-rebel:before {
+ content: "\f1d0";
+}
+.fa-ge:before,
+.fa-empire:before {
+ content: "\f1d1";
+}
+.fa-git-square:before {
+ content: "\f1d2";
+}
+.fa-git:before {
+ content: "\f1d3";
+}
+.fa-y-combinator-square:before,
+.fa-yc-square:before,
+.fa-hacker-news:before {
+ content: "\f1d4";
+}
+.fa-tencent-weibo:before {
+ content: "\f1d5";
+}
+.fa-qq:before {
+ content: "\f1d6";
+}
+.fa-wechat:before,
+.fa-weixin:before {
+ content: "\f1d7";
+}
+.fa-send:before,
+.fa-paper-plane:before {
+ content: "\f1d8";
+}
+.fa-send-o:before,
+.fa-paper-plane-o:before {
+ content: "\f1d9";
+}
+.fa-history:before {
+ content: "\f1da";
+}
+.fa-circle-thin:before {
+ content: "\f1db";
+}
+.fa-header:before {
+ content: "\f1dc";
+}
+.fa-paragraph:before {
+ content: "\f1dd";
+}
+.fa-sliders:before {
+ content: "\f1de";
+}
+.fa-share-alt:before {
+ content: "\f1e0";
+}
+.fa-share-alt-square:before {
+ content: "\f1e1";
+}
+.fa-bomb:before {
+ content: "\f1e2";
+}
+.fa-soccer-ball-o:before,
+.fa-futbol-o:before {
+ content: "\f1e3";
+}
+.fa-tty:before {
+ content: "\f1e4";
+}
+.fa-binoculars:before {
+ content: "\f1e5";
+}
+.fa-plug:before {
+ content: "\f1e6";
+}
+.fa-slideshare:before {
+ content: "\f1e7";
+}
+.fa-twitch:before {
+ content: "\f1e8";
+}
+.fa-yelp:before {
+ content: "\f1e9";
+}
+.fa-newspaper-o:before {
+ content: "\f1ea";
+}
+.fa-wifi:before {
+ content: "\f1eb";
+}
+.fa-calculator:before {
+ content: "\f1ec";
+}
+.fa-paypal:before {
+ content: "\f1ed";
+}
+.fa-google-wallet:before {
+ content: "\f1ee";
+}
+.fa-cc-visa:before {
+ content: "\f1f0";
+}
+.fa-cc-mastercard:before {
+ content: "\f1f1";
+}
+.fa-cc-discover:before {
+ content: "\f1f2";
+}
+.fa-cc-amex:before {
+ content: "\f1f3";
+}
+.fa-cc-paypal:before {
+ content: "\f1f4";
+}
+.fa-cc-stripe:before {
+ content: "\f1f5";
+}
+.fa-bell-slash:before {
+ content: "\f1f6";
+}
+.fa-bell-slash-o:before {
+ content: "\f1f7";
+}
+.fa-trash:before {
+ content: "\f1f8";
+}
+.fa-copyright:before {
+ content: "\f1f9";
+}
+.fa-at:before {
+ content: "\f1fa";
+}
+.fa-eyedropper:before {
+ content: "\f1fb";
+}
+.fa-paint-brush:before {
+ content: "\f1fc";
+}
+.fa-birthday-cake:before {
+ content: "\f1fd";
+}
+.fa-area-chart:before {
+ content: "\f1fe";
+}
+.fa-pie-chart:before {
+ content: "\f200";
+}
+.fa-line-chart:before {
+ content: "\f201";
+}
+.fa-lastfm:before {
+ content: "\f202";
+}
+.fa-lastfm-square:before {
+ content: "\f203";
+}
+.fa-toggle-off:before {
+ content: "\f204";
+}
+.fa-toggle-on:before {
+ content: "\f205";
+}
+.fa-bicycle:before {
+ content: "\f206";
+}
+.fa-bus:before {
+ content: "\f207";
+}
+.fa-ioxhost:before {
+ content: "\f208";
+}
+.fa-angellist:before {
+ content: "\f209";
+}
+.fa-cc:before {
+ content: "\f20a";
+}
+.fa-shekel:before,
+.fa-sheqel:before,
+.fa-ils:before {
+ content: "\f20b";
+}
+.fa-meanpath:before {
+ content: "\f20c";
+}
+.fa-buysellads:before {
+ content: "\f20d";
+}
+.fa-connectdevelop:before {
+ content: "\f20e";
+}
+.fa-dashcube:before {
+ content: "\f210";
+}
+.fa-forumbee:before {
+ content: "\f211";
+}
+.fa-leanpub:before {
+ content: "\f212";
+}
+.fa-sellsy:before {
+ content: "\f213";
+}
+.fa-shirtsinbulk:before {
+ content: "\f214";
+}
+.fa-simplybuilt:before {
+ content: "\f215";
+}
+.fa-skyatlas:before {
+ content: "\f216";
+}
+.fa-cart-plus:before {
+ content: "\f217";
+}
+.fa-cart-arrow-down:before {
+ content: "\f218";
+}
+.fa-diamond:before {
+ content: "\f219";
+}
+.fa-ship:before {
+ content: "\f21a";
+}
+.fa-user-secret:before {
+ content: "\f21b";
+}
+.fa-motorcycle:before {
+ content: "\f21c";
+}
+.fa-street-view:before {
+ content: "\f21d";
+}
+.fa-heartbeat:before {
+ content: "\f21e";
+}
+.fa-venus:before {
+ content: "\f221";
+}
+.fa-mars:before {
+ content: "\f222";
+}
+.fa-mercury:before {
+ content: "\f223";
+}
+.fa-intersex:before,
+.fa-transgender:before {
+ content: "\f224";
+}
+.fa-transgender-alt:before {
+ content: "\f225";
+}
+.fa-venus-double:before {
+ content: "\f226";
+}
+.fa-mars-double:before {
+ content: "\f227";
+}
+.fa-venus-mars:before {
+ content: "\f228";
+}
+.fa-mars-stroke:before {
+ content: "\f229";
+}
+.fa-mars-stroke-v:before {
+ content: "\f22a";
+}
+.fa-mars-stroke-h:before {
+ content: "\f22b";
+}
+.fa-neuter:before {
+ content: "\f22c";
+}
+.fa-genderless:before {
+ content: "\f22d";
+}
+.fa-facebook-official:before {
+ content: "\f230";
+}
+.fa-pinterest-p:before {
+ content: "\f231";
+}
+.fa-whatsapp:before {
+ content: "\f232";
+}
+.fa-server:before {
+ content: "\f233";
+}
+.fa-user-plus:before {
+ content: "\f234";
+}
+.fa-user-times:before {
+ content: "\f235";
+}
+.fa-hotel:before,
+.fa-bed:before {
+ content: "\f236";
+}
+.fa-viacoin:before {
+ content: "\f237";
+}
+.fa-train:before {
+ content: "\f238";
+}
+.fa-subway:before {
+ content: "\f239";
+}
+.fa-medium:before {
+ content: "\f23a";
+}
+.fa-yc:before,
+.fa-y-combinator:before {
+ content: "\f23b";
+}
+.fa-optin-monster:before {
+ content: "\f23c";
+}
+.fa-opencart:before {
+ content: "\f23d";
+}
+.fa-expeditedssl:before {
+ content: "\f23e";
+}
+.fa-battery-4:before,
+.fa-battery:before,
+.fa-battery-full:before {
+ content: "\f240";
+}
+.fa-battery-3:before,
+.fa-battery-three-quarters:before {
+ content: "\f241";
+}
+.fa-battery-2:before,
+.fa-battery-half:before {
+ content: "\f242";
+}
+.fa-battery-1:before,
+.fa-battery-quarter:before {
+ content: "\f243";
+}
+.fa-battery-0:before,
+.fa-battery-empty:before {
+ content: "\f244";
+}
+.fa-mouse-pointer:before {
+ content: "\f245";
+}
+.fa-i-cursor:before {
+ content: "\f246";
+}
+.fa-object-group:before {
+ content: "\f247";
+}
+.fa-object-ungroup:before {
+ content: "\f248";
+}
+.fa-sticky-note:before {
+ content: "\f249";
+}
+.fa-sticky-note-o:before {
+ content: "\f24a";
+}
+.fa-cc-jcb:before {
+ content: "\f24b";
+}
+.fa-cc-diners-club:before {
+ content: "\f24c";
+}
+.fa-clone:before {
+ content: "\f24d";
+}
+.fa-balance-scale:before {
+ content: "\f24e";
+}
+.fa-hourglass-o:before {
+ content: "\f250";
+}
+.fa-hourglass-1:before,
+.fa-hourglass-start:before {
+ content: "\f251";
+}
+.fa-hourglass-2:before,
+.fa-hourglass-half:before {
+ content: "\f252";
+}
+.fa-hourglass-3:before,
+.fa-hourglass-end:before {
+ content: "\f253";
+}
+.fa-hourglass:before {
+ content: "\f254";
+}
+.fa-hand-grab-o:before,
+.fa-hand-rock-o:before {
+ content: "\f255";
+}
+.fa-hand-stop-o:before,
+.fa-hand-paper-o:before {
+ content: "\f256";
+}
+.fa-hand-scissors-o:before {
+ content: "\f257";
+}
+.fa-hand-lizard-o:before {
+ content: "\f258";
+}
+.fa-hand-spock-o:before {
+ content: "\f259";
+}
+.fa-hand-pointer-o:before {
+ content: "\f25a";
+}
+.fa-hand-peace-o:before {
+ content: "\f25b";
+}
+.fa-trademark:before {
+ content: "\f25c";
+}
+.fa-registered:before {
+ content: "\f25d";
+}
+.fa-creative-commons:before {
+ content: "\f25e";
+}
+.fa-gg:before {
+ content: "\f260";
+}
+.fa-gg-circle:before {
+ content: "\f261";
+}
+.fa-tripadvisor:before {
+ content: "\f262";
+}
+.fa-odnoklassniki:before {
+ content: "\f263";
+}
+.fa-odnoklassniki-square:before {
+ content: "\f264";
+}
+.fa-get-pocket:before {
+ content: "\f265";
+}
+.fa-wikipedia-w:before {
+ content: "\f266";
+}
+.fa-safari:before {
+ content: "\f267";
+}
+.fa-chrome:before {
+ content: "\f268";
+}
+.fa-firefox:before {
+ content: "\f269";
+}
+.fa-opera:before {
+ content: "\f26a";
+}
+.fa-internet-explorer:before {
+ content: "\f26b";
+}
+.fa-tv:before,
+.fa-television:before {
+ content: "\f26c";
+}
+.fa-contao:before {
+ content: "\f26d";
+}
+.fa-500px:before {
+ content: "\f26e";
+}
+.fa-amazon:before {
+ content: "\f270";
+}
+.fa-calendar-plus-o:before {
+ content: "\f271";
+}
+.fa-calendar-minus-o:before {
+ content: "\f272";
+}
+.fa-calendar-times-o:before {
+ content: "\f273";
+}
+.fa-calendar-check-o:before {
+ content: "\f274";
+}
+.fa-industry:before {
+ content: "\f275";
+}
+.fa-map-pin:before {
+ content: "\f276";
+}
+.fa-map-signs:before {
+ content: "\f277";
+}
+.fa-map-o:before {
+ content: "\f278";
+}
+.fa-map:before {
+ content: "\f279";
+}
+.fa-commenting:before {
+ content: "\f27a";
+}
+.fa-commenting-o:before {
+ content: "\f27b";
+}
+.fa-houzz:before {
+ content: "\f27c";
+}
+.fa-vimeo:before {
+ content: "\f27d";
+}
+.fa-black-tie:before {
+ content: "\f27e";
+}
+.fa-fonticons:before {
+ content: "\f280";
+}
+.fa-reddit-alien:before {
+ content: "\f281";
+}
+.fa-edge:before {
+ content: "\f282";
+}
+.fa-credit-card-alt:before {
+ content: "\f283";
+}
+.fa-codiepie:before {
+ content: "\f284";
+}
+.fa-modx:before {
+ content: "\f285";
+}
+.fa-fort-awesome:before {
+ content: "\f286";
+}
+.fa-usb:before {
+ content: "\f287";
+}
+.fa-product-hunt:before {
+ content: "\f288";
+}
+.fa-mixcloud:before {
+ content: "\f289";
+}
+.fa-scribd:before {
+ content: "\f28a";
+}
+.fa-pause-circle:before {
+ content: "\f28b";
+}
+.fa-pause-circle-o:before {
+ content: "\f28c";
+}
+.fa-stop-circle:before {
+ content: "\f28d";
+}
+.fa-stop-circle-o:before {
+ content: "\f28e";
+}
+.fa-shopping-bag:before {
+ content: "\f290";
+}
+.fa-shopping-basket:before {
+ content: "\f291";
+}
+.fa-hashtag:before {
+ content: "\f292";
+}
+.fa-bluetooth:before {
+ content: "\f293";
+}
+.fa-bluetooth-b:before {
+ content: "\f294";
+}
+.fa-percent:before {
+ content: "\f295";
+}
+.fa-gitlab:before {
+ content: "\f296";
+}
+.fa-wpbeginner:before {
+ content: "\f297";
+}
+.fa-wpforms:before {
+ content: "\f298";
+}
+.fa-envira:before {
+ content: "\f299";
+}
+.fa-universal-access:before {
+ content: "\f29a";
+}
+.fa-wheelchair-alt:before {
+ content: "\f29b";
+}
+.fa-question-circle-o:before {
+ content: "\f29c";
+}
+.fa-blind:before {
+ content: "\f29d";
+}
+.fa-audio-description:before {
+ content: "\f29e";
+}
+.fa-volume-control-phone:before {
+ content: "\f2a0";
+}
+.fa-braille:before {
+ content: "\f2a1";
+}
+.fa-assistive-listening-systems:before {
+ content: "\f2a2";
+}
+.fa-asl-interpreting:before,
+.fa-american-sign-language-interpreting:before {
+ content: "\f2a3";
+}
+.fa-deafness:before,
+.fa-hard-of-hearing:before,
+.fa-deaf:before {
+ content: "\f2a4";
+}
+.fa-glide:before {
+ content: "\f2a5";
+}
+.fa-glide-g:before {
+ content: "\f2a6";
+}
+.fa-signing:before,
+.fa-sign-language:before {
+ content: "\f2a7";
+}
+.fa-low-vision:before {
+ content: "\f2a8";
+}
+.fa-viadeo:before {
+ content: "\f2a9";
+}
+.fa-viadeo-square:before {
+ content: "\f2aa";
+}
+.fa-snapchat:before {
+ content: "\f2ab";
+}
+.fa-snapchat-ghost:before {
+ content: "\f2ac";
+}
+.fa-snapchat-square:before {
+ content: "\f2ad";
+}
+.fa-pied-piper:before {
+ content: "\f2ae";
+}
+.fa-first-order:before {
+ content: "\f2b0";
+}
+.fa-yoast:before {
+ content: "\f2b1";
+}
+.fa-themeisle:before {
+ content: "\f2b2";
+}
+.fa-google-plus-circle:before,
+.fa-google-plus-official:before {
+ content: "\f2b3";
+}
+.fa-fa:before,
+.fa-font-awesome:before {
+ content: "\f2b4";
+}
+.fa-handshake-o:before {
+ content: "\f2b5";
+}
+.fa-envelope-open:before {
+ content: "\f2b6";
+}
+.fa-envelope-open-o:before {
+ content: "\f2b7";
+}
+.fa-linode:before {
+ content: "\f2b8";
+}
+.fa-address-book:before {
+ content: "\f2b9";
+}
+.fa-address-book-o:before {
+ content: "\f2ba";
+}
+.fa-vcard:before,
+.fa-address-card:before {
+ content: "\f2bb";
+}
+.fa-vcard-o:before,
+.fa-address-card-o:before {
+ content: "\f2bc";
+}
+.fa-user-circle:before {
+ content: "\f2bd";
+}
+.fa-user-circle-o:before {
+ content: "\f2be";
+}
+.fa-user-o:before {
+ content: "\f2c0";
+}
+.fa-id-badge:before {
+ content: "\f2c1";
+}
+.fa-drivers-license:before,
+.fa-id-card:before {
+ content: "\f2c2";
+}
+.fa-drivers-license-o:before,
+.fa-id-card-o:before {
+ content: "\f2c3";
+}
+.fa-quora:before {
+ content: "\f2c4";
+}
+.fa-free-code-camp:before {
+ content: "\f2c5";
+}
+.fa-telegram:before {
+ content: "\f2c6";
+}
+.fa-thermometer-4:before,
+.fa-thermometer:before,
+.fa-thermometer-full:before {
+ content: "\f2c7";
+}
+.fa-thermometer-3:before,
+.fa-thermometer-three-quarters:before {
+ content: "\f2c8";
+}
+.fa-thermometer-2:before,
+.fa-thermometer-half:before {
+ content: "\f2c9";
+}
+.fa-thermometer-1:before,
+.fa-thermometer-quarter:before {
+ content: "\f2ca";
+}
+.fa-thermometer-0:before,
+.fa-thermometer-empty:before {
+ content: "\f2cb";
+}
+.fa-shower:before {
+ content: "\f2cc";
+}
+.fa-bathtub:before,
+.fa-s15:before,
+.fa-bath:before {
+ content: "\f2cd";
+}
+.fa-podcast:before {
+ content: "\f2ce";
+}
+.fa-window-maximize:before {
+ content: "\f2d0";
+}
+.fa-window-minimize:before {
+ content: "\f2d1";
+}
+.fa-window-restore:before {
+ content: "\f2d2";
+}
+.fa-times-rectangle:before,
+.fa-window-close:before {
+ content: "\f2d3";
+}
+.fa-times-rectangle-o:before,
+.fa-window-close-o:before {
+ content: "\f2d4";
+}
+.fa-bandcamp:before {
+ content: "\f2d5";
+}
+.fa-grav:before {
+ content: "\f2d6";
+}
+.fa-etsy:before {
+ content: "\f2d7";
+}
+.fa-imdb:before {
+ content: "\f2d8";
+}
+.fa-ravelry:before {
+ content: "\f2d9";
+}
+.fa-eercast:before {
+ content: "\f2da";
+}
+.fa-microchip:before {
+ content: "\f2db";
+}
+.fa-snowflake-o:before {
+ content: "\f2dc";
+}
+.fa-superpowers:before {
+ content: "\f2dd";
+}
+.fa-wpexplorer:before {
+ content: "\f2de";
+}
+.fa-meetup:before {
+ content: "\f2e0";
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+/*!
+*
+* IPython base
+*
+*/
+.modal.fade .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+code {
+ color: #000;
+}
+pre {
+ font-size: inherit;
+ line-height: inherit;
+}
+label {
+ font-weight: normal;
+}
+/* Make the page background atleast 100% the height of the view port */
+/* Make the page itself atleast 70% the height of the view port */
+.border-box-sizing {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+.corner-all {
+ border-radius: 2px;
+}
+.no-padding {
+ padding: 0px;
+}
+/* Flexible box model classes */
+/* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
+/* This file is a compatability layer. It allows the usage of flexible box
+model layouts accross multiple browsers, including older browsers. The newest,
+universal implementation of the flexible box model is used when available (see
+`Modern browsers` comments below). Browsers that are known to implement this
+new spec completely include:
+
+ Firefox 28.0+
+ Chrome 29.0+
+ Internet Explorer 11+
+ Opera 17.0+
+
+Browsers not listed, including Safari, are supported via the styling under the
+`Old browsers` comments below.
+*/
+.hbox {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: horizontal;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+}
+.hbox > * {
+ /* Old browsers */
+ -webkit-box-flex: 0;
+ -moz-box-flex: 0;
+ box-flex: 0;
+ /* Modern browsers */
+ flex: none;
+}
+.vbox {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+}
+.vbox > * {
+ /* Old browsers */
+ -webkit-box-flex: 0;
+ -moz-box-flex: 0;
+ box-flex: 0;
+ /* Modern browsers */
+ flex: none;
+}
+.hbox.reverse,
+.vbox.reverse,
+.reverse {
+ /* Old browsers */
+ -webkit-box-direction: reverse;
+ -moz-box-direction: reverse;
+ box-direction: reverse;
+ /* Modern browsers */
+ flex-direction: row-reverse;
+}
+.hbox.box-flex0,
+.vbox.box-flex0,
+.box-flex0 {
+ /* Old browsers */
+ -webkit-box-flex: 0;
+ -moz-box-flex: 0;
+ box-flex: 0;
+ /* Modern browsers */
+ flex: none;
+ width: auto;
+}
+.hbox.box-flex1,
+.vbox.box-flex1,
+.box-flex1 {
+ /* Old browsers */
+ -webkit-box-flex: 1;
+ -moz-box-flex: 1;
+ box-flex: 1;
+ /* Modern browsers */
+ flex: 1;
+}
+.hbox.box-flex,
+.vbox.box-flex,
+.box-flex {
+ /* Old browsers */
+ /* Old browsers */
+ -webkit-box-flex: 1;
+ -moz-box-flex: 1;
+ box-flex: 1;
+ /* Modern browsers */
+ flex: 1;
+}
+.hbox.box-flex2,
+.vbox.box-flex2,
+.box-flex2 {
+ /* Old browsers */
+ -webkit-box-flex: 2;
+ -moz-box-flex: 2;
+ box-flex: 2;
+ /* Modern browsers */
+ flex: 2;
+}
+.box-group1 {
+ /* Deprecated */
+ -webkit-box-flex-group: 1;
+ -moz-box-flex-group: 1;
+ box-flex-group: 1;
+}
+.box-group2 {
+ /* Deprecated */
+ -webkit-box-flex-group: 2;
+ -moz-box-flex-group: 2;
+ box-flex-group: 2;
+}
+.hbox.start,
+.vbox.start,
+.start {
+ /* Old browsers */
+ -webkit-box-pack: start;
+ -moz-box-pack: start;
+ box-pack: start;
+ /* Modern browsers */
+ justify-content: flex-start;
+}
+.hbox.end,
+.vbox.end,
+.end {
+ /* Old browsers */
+ -webkit-box-pack: end;
+ -moz-box-pack: end;
+ box-pack: end;
+ /* Modern browsers */
+ justify-content: flex-end;
+}
+.hbox.center,
+.vbox.center,
+.center {
+ /* Old browsers */
+ -webkit-box-pack: center;
+ -moz-box-pack: center;
+ box-pack: center;
+ /* Modern browsers */
+ justify-content: center;
+}
+.hbox.baseline,
+.vbox.baseline,
+.baseline {
+ /* Old browsers */
+ -webkit-box-pack: baseline;
+ -moz-box-pack: baseline;
+ box-pack: baseline;
+ /* Modern browsers */
+ justify-content: baseline;
+}
+.hbox.stretch,
+.vbox.stretch,
+.stretch {
+ /* Old browsers */
+ -webkit-box-pack: stretch;
+ -moz-box-pack: stretch;
+ box-pack: stretch;
+ /* Modern browsers */
+ justify-content: stretch;
+}
+.hbox.align-start,
+.vbox.align-start,
+.align-start {
+ /* Old browsers */
+ -webkit-box-align: start;
+ -moz-box-align: start;
+ box-align: start;
+ /* Modern browsers */
+ align-items: flex-start;
+}
+.hbox.align-end,
+.vbox.align-end,
+.align-end {
+ /* Old browsers */
+ -webkit-box-align: end;
+ -moz-box-align: end;
+ box-align: end;
+ /* Modern browsers */
+ align-items: flex-end;
+}
+.hbox.align-center,
+.vbox.align-center,
+.align-center {
+ /* Old browsers */
+ -webkit-box-align: center;
+ -moz-box-align: center;
+ box-align: center;
+ /* Modern browsers */
+ align-items: center;
+}
+.hbox.align-baseline,
+.vbox.align-baseline,
+.align-baseline {
+ /* Old browsers */
+ -webkit-box-align: baseline;
+ -moz-box-align: baseline;
+ box-align: baseline;
+ /* Modern browsers */
+ align-items: baseline;
+}
+.hbox.align-stretch,
+.vbox.align-stretch,
+.align-stretch {
+ /* Old browsers */
+ -webkit-box-align: stretch;
+ -moz-box-align: stretch;
+ box-align: stretch;
+ /* Modern browsers */
+ align-items: stretch;
+}
+div.error {
+ margin: 2em;
+ text-align: center;
+}
+div.error > h1 {
+ font-size: 500%;
+ line-height: normal;
+}
+div.error > p {
+ font-size: 200%;
+ line-height: normal;
+}
+div.traceback-wrapper {
+ text-align: left;
+ max-width: 800px;
+ margin: auto;
+}
+div.traceback-wrapper pre.traceback {
+ max-height: 600px;
+ overflow: auto;
+}
+/**
+ * Primary styles
+ *
+ * Author: Jupyter Development Team
+ */
+body {
+ background-color: #fff;
+ /* This makes sure that the body covers the entire window and needs to
+ be in a different element than the display: box in wrapper below */
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+ overflow: visible;
+}
+body > #header {
+ /* Initially hidden to prevent FLOUC */
+ display: none;
+ background-color: #fff;
+ /* Display over codemirror */
+ position: relative;
+ z-index: 100;
+}
+body > #header #header-container {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ padding: 5px;
+ padding-bottom: 5px;
+ padding-top: 5px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+body > #header .header-bar {
+ width: 100%;
+ height: 1px;
+ background: #e7e7e7;
+ margin-bottom: -1px;
+}
+@media print {
+ body > #header {
+ display: none !important;
+ }
+}
+#header-spacer {
+ width: 100%;
+ visibility: hidden;
+}
+@media print {
+ #header-spacer {
+ display: none;
+ }
+}
+#ipython_notebook {
+ padding-left: 0px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+[dir="rtl"] #ipython_notebook {
+ margin-right: 10px;
+ margin-left: 0;
+}
+[dir="rtl"] #ipython_notebook.pull-left {
+ float: right !important;
+ float: right;
+}
+.flex-spacer {
+ flex: 1;
+}
+#noscript {
+ width: auto;
+ padding-top: 16px;
+ padding-bottom: 16px;
+ text-align: center;
+ font-size: 22px;
+ color: red;
+ font-weight: bold;
+}
+#ipython_notebook img {
+ height: 28px;
+}
+#site {
+ width: 100%;
+ display: none;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ overflow: auto;
+}
+@media print {
+ #site {
+ height: auto !important;
+ }
+}
+/* Smaller buttons */
+.ui-button .ui-button-text {
+ padding: 0.2em 0.8em;
+ font-size: 77%;
+}
+input.ui-button {
+ padding: 0.3em 0.9em;
+}
+span#kernel_logo_widget {
+ margin: 0 10px;
+}
+span#login_widget {
+ float: right;
+}
+[dir="rtl"] span#login_widget {
+ float: left;
+}
+span#login_widget > .button,
+#logout {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+span#login_widget > .button:focus,
+#logout:focus,
+span#login_widget > .button.focus,
+#logout.focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+span#login_widget > .button:hover,
+#logout:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+span#login_widget > .button:active,
+#logout:active,
+span#login_widget > .button.active,
+#logout.active,
+.open > .dropdown-togglespan#login_widget > .button,
+.open > .dropdown-toggle#logout {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+span#login_widget > .button:active:hover,
+#logout:active:hover,
+span#login_widget > .button.active:hover,
+#logout.active:hover,
+.open > .dropdown-togglespan#login_widget > .button:hover,
+.open > .dropdown-toggle#logout:hover,
+span#login_widget > .button:active:focus,
+#logout:active:focus,
+span#login_widget > .button.active:focus,
+#logout.active:focus,
+.open > .dropdown-togglespan#login_widget > .button:focus,
+.open > .dropdown-toggle#logout:focus,
+span#login_widget > .button:active.focus,
+#logout:active.focus,
+span#login_widget > .button.active.focus,
+#logout.active.focus,
+.open > .dropdown-togglespan#login_widget > .button.focus,
+.open > .dropdown-toggle#logout.focus {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+span#login_widget > .button:active,
+#logout:active,
+span#login_widget > .button.active,
+#logout.active,
+.open > .dropdown-togglespan#login_widget > .button,
+.open > .dropdown-toggle#logout {
+ background-image: none;
+}
+span#login_widget > .button.disabled:hover,
+#logout.disabled:hover,
+span#login_widget > .button[disabled]:hover,
+#logout[disabled]:hover,
+fieldset[disabled] span#login_widget > .button:hover,
+fieldset[disabled] #logout:hover,
+span#login_widget > .button.disabled:focus,
+#logout.disabled:focus,
+span#login_widget > .button[disabled]:focus,
+#logout[disabled]:focus,
+fieldset[disabled] span#login_widget > .button:focus,
+fieldset[disabled] #logout:focus,
+span#login_widget > .button.disabled.focus,
+#logout.disabled.focus,
+span#login_widget > .button[disabled].focus,
+#logout[disabled].focus,
+fieldset[disabled] span#login_widget > .button.focus,
+fieldset[disabled] #logout.focus {
+ background-color: #fff;
+ border-color: #ccc;
+}
+span#login_widget > .button .badge,
+#logout .badge {
+ color: #fff;
+ background-color: #333;
+}
+.nav-header {
+ text-transform: none;
+}
+#header > span {
+ margin-top: 10px;
+}
+.modal_stretch .modal-dialog {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ min-height: 80vh;
+}
+.modal_stretch .modal-dialog .modal-body {
+ max-height: calc(100vh - 200px);
+ overflow: auto;
+ flex: 1;
+}
+.modal-header {
+ cursor: move;
+}
+@media (min-width: 768px) {
+ .modal .modal-dialog {
+ width: 700px;
+ }
+}
+@media (min-width: 768px) {
+ select.form-control {
+ margin-left: 12px;
+ margin-right: 12px;
+ }
+}
+/*!
+*
+* IPython auth
+*
+*/
+.center-nav {
+ display: inline-block;
+ margin-bottom: -4px;
+}
+[dir="rtl"] .center-nav form.pull-left {
+ float: right !important;
+ float: right;
+}
+[dir="rtl"] .center-nav .navbar-text {
+ float: right;
+}
+[dir="rtl"] .navbar-inner {
+ text-align: right;
+}
+[dir="rtl"] div.text-left {
+ text-align: right;
+}
+/*!
+*
+* IPython tree view
+*
+*/
+/* We need an invisible input field on top of the sentense*/
+/* "Drag file onto the list ..." */
+.alternate_upload {
+ background-color: none;
+ display: inline;
+}
+.alternate_upload.form {
+ padding: 0;
+ margin: 0;
+}
+.alternate_upload input.fileinput {
+ position: absolute;
+ display: block;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ cursor: pointer;
+ opacity: 0;
+ z-index: 2;
+}
+.alternate_upload .btn-xs > input.fileinput {
+ margin: -1px -5px;
+}
+.alternate_upload .btn-upload {
+ position: relative;
+ height: 22px;
+}
+::-webkit-file-upload-button {
+ cursor: pointer;
+}
+/**
+ * Primary styles
+ *
+ * Author: Jupyter Development Team
+ */
+ul#tabs {
+ margin-bottom: 4px;
+}
+ul#tabs a {
+ padding-top: 6px;
+ padding-bottom: 4px;
+}
+[dir="rtl"] ul#tabs.nav-tabs > li {
+ float: right;
+}
+[dir="rtl"] ul#tabs.nav.nav-tabs {
+ padding-right: 0;
+}
+ul.breadcrumb a:focus,
+ul.breadcrumb a:hover {
+ text-decoration: none;
+}
+ul.breadcrumb i.icon-home {
+ font-size: 16px;
+ margin-right: 4px;
+}
+ul.breadcrumb span {
+ color: #5e5e5e;
+}
+.list_toolbar {
+ padding: 4px 0 4px 0;
+ vertical-align: middle;
+}
+.list_toolbar .tree-buttons {
+ padding-top: 1px;
+}
+[dir="rtl"] .list_toolbar .tree-buttons .pull-right {
+ float: left !important;
+ float: left;
+}
+[dir="rtl"] .list_toolbar .col-sm-4,
+[dir="rtl"] .list_toolbar .col-sm-8 {
+ float: right;
+}
+.dynamic-buttons {
+ padding-top: 3px;
+ display: inline-block;
+}
+.list_toolbar [class*="span"] {
+ min-height: 24px;
+}
+.list_header {
+ font-weight: bold;
+ background-color: #EEE;
+}
+.list_placeholder {
+ font-weight: bold;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-left: 7px;
+ padding-right: 7px;
+}
+.list_container {
+ margin-top: 4px;
+ margin-bottom: 20px;
+ border: 1px solid #ddd;
+ border-radius: 2px;
+}
+.list_container > div {
+ border-bottom: 1px solid #ddd;
+}
+.list_container > div:hover .list-item {
+ background-color: red;
+}
+.list_container > div:last-child {
+ border: none;
+}
+.list_item:hover .list_item {
+ background-color: #ddd;
+}
+.list_item a {
+ text-decoration: none;
+}
+.list_item:hover {
+ background-color: #fafafa;
+}
+.list_header > div,
+.list_item > div {
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-left: 7px;
+ padding-right: 7px;
+ line-height: 22px;
+}
+.list_header > div input,
+.list_item > div input {
+ margin-right: 7px;
+ margin-left: 14px;
+ vertical-align: text-bottom;
+ line-height: 22px;
+ position: relative;
+ top: -1px;
+}
+.list_header > div .item_link,
+.list_item > div .item_link {
+ margin-left: -1px;
+ vertical-align: baseline;
+ line-height: 22px;
+}
+[dir="rtl"] .list_item > div input {
+ margin-right: 0;
+}
+.new-file input[type=checkbox] {
+ visibility: hidden;
+}
+.item_name {
+ line-height: 22px;
+ height: 24px;
+}
+.item_icon {
+ font-size: 14px;
+ color: #5e5e5e;
+ margin-right: 7px;
+ margin-left: 7px;
+ line-height: 22px;
+ vertical-align: baseline;
+}
+.item_modified {
+ margin-right: 7px;
+ margin-left: 7px;
+}
+[dir="rtl"] .item_modified.pull-right {
+ float: left !important;
+ float: left;
+}
+.item_buttons {
+ line-height: 1em;
+ margin-left: -5px;
+}
+.item_buttons .btn,
+.item_buttons .btn-group,
+.item_buttons .input-group {
+ float: left;
+}
+.item_buttons > .btn,
+.item_buttons > .btn-group,
+.item_buttons > .input-group {
+ margin-left: 5px;
+}
+.item_buttons .btn {
+ min-width: 13ex;
+}
+.item_buttons .running-indicator {
+ padding-top: 4px;
+ color: #5cb85c;
+}
+.item_buttons .kernel-name {
+ padding-top: 4px;
+ color: #5bc0de;
+ margin-right: 7px;
+ float: left;
+}
+[dir="rtl"] .item_buttons.pull-right {
+ float: left !important;
+ float: left;
+}
+[dir="rtl"] .item_buttons .kernel-name {
+ margin-left: 7px;
+ float: right;
+}
+.toolbar_info {
+ height: 24px;
+ line-height: 24px;
+}
+.list_item input:not([type=checkbox]) {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ height: 22px;
+ line-height: 14px;
+ margin: 0px;
+}
+.highlight_text {
+ color: blue;
+}
+#project_name {
+ display: inline-block;
+ padding-left: 7px;
+ margin-left: -2px;
+}
+#project_name > .breadcrumb {
+ padding: 0px;
+ margin-bottom: 0px;
+ background-color: transparent;
+ font-weight: bold;
+}
+.sort_button {
+ display: inline-block;
+ padding-left: 7px;
+}
+[dir="rtl"] .sort_button.pull-right {
+ float: left !important;
+ float: left;
+}
+#tree-selector {
+ padding-right: 0px;
+}
+#button-select-all {
+ min-width: 50px;
+}
+[dir="rtl"] #button-select-all.btn {
+ float: right ;
+}
+#select-all {
+ margin-left: 7px;
+ margin-right: 2px;
+ margin-top: 2px;
+ height: 16px;
+}
+[dir="rtl"] #select-all.pull-left {
+ float: right !important;
+ float: right;
+}
+.menu_icon {
+ margin-right: 2px;
+}
+.tab-content .row {
+ margin-left: 0px;
+ margin-right: 0px;
+}
+.folder_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f114";
+}
+.folder_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.folder_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.folder_icon:before.pull-left {
+ margin-right: .3em;
+}
+.folder_icon:before.pull-right {
+ margin-left: .3em;
+}
+.notebook_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f02d";
+ position: relative;
+ top: -1px;
+}
+.notebook_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.notebook_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.notebook_icon:before.pull-left {
+ margin-right: .3em;
+}
+.notebook_icon:before.pull-right {
+ margin-left: .3em;
+}
+.running_notebook_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f02d";
+ position: relative;
+ top: -1px;
+ color: #5cb85c;
+}
+.running_notebook_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.running_notebook_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.running_notebook_icon:before.pull-left {
+ margin-right: .3em;
+}
+.running_notebook_icon:before.pull-right {
+ margin-left: .3em;
+}
+.file_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f016";
+ position: relative;
+ top: -2px;
+}
+.file_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.file_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.file_icon:before.pull-left {
+ margin-right: .3em;
+}
+.file_icon:before.pull-right {
+ margin-left: .3em;
+}
+#notebook_toolbar .pull-right {
+ padding-top: 0px;
+ margin-right: -1px;
+}
+ul#new-menu {
+ left: auto;
+ right: 0;
+}
+#new-menu .dropdown-header {
+ font-size: 10px;
+ border-bottom: 1px solid #e5e5e5;
+ padding: 0 0 3px;
+ margin: -3px 20px 0;
+}
+.kernel-menu-icon {
+ padding-right: 12px;
+ width: 24px;
+ content: "\f096";
+}
+.kernel-menu-icon:before {
+ content: "\f096";
+}
+.kernel-menu-icon-current:before {
+ content: "\f00c";
+}
+#tab_content {
+ padding-top: 20px;
+}
+#running .panel-group .panel {
+ margin-top: 3px;
+ margin-bottom: 1em;
+}
+#running .panel-group .panel .panel-heading {
+ background-color: #EEE;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ padding-left: 7px;
+ padding-right: 7px;
+ line-height: 22px;
+}
+#running .panel-group .panel .panel-heading a:focus,
+#running .panel-group .panel .panel-heading a:hover {
+ text-decoration: none;
+}
+#running .panel-group .panel .panel-body {
+ padding: 0px;
+}
+#running .panel-group .panel .panel-body .list_container {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ border: 0px;
+ border-radius: 0px;
+}
+#running .panel-group .panel .panel-body .list_container .list_item {
+ border-bottom: 1px solid #ddd;
+}
+#running .panel-group .panel .panel-body .list_container .list_item:last-child {
+ border-bottom: 0px;
+}
+.delete-button {
+ display: none;
+}
+.duplicate-button {
+ display: none;
+}
+.rename-button {
+ display: none;
+}
+.move-button {
+ display: none;
+}
+.download-button {
+ display: none;
+}
+.shutdown-button {
+ display: none;
+}
+.dynamic-instructions {
+ display: inline-block;
+ padding-top: 4px;
+}
+/*!
+*
+* IPython text editor webapp
+*
+*/
+.selected-keymap i.fa {
+ padding: 0px 5px;
+}
+.selected-keymap i.fa:before {
+ content: "\f00c";
+}
+#mode-menu {
+ overflow: auto;
+ max-height: 20em;
+}
+.edit_app #header {
+ -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+}
+.edit_app #menubar .navbar {
+ /* Use a negative 1 bottom margin, so the border overlaps the border of the
+ header */
+ margin-bottom: -1px;
+}
+.dirty-indicator {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ width: 20px;
+}
+.dirty-indicator.fa-pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator.fa-pull-right {
+ margin-left: .3em;
+}
+.dirty-indicator.pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator.pull-right {
+ margin-left: .3em;
+}
+.dirty-indicator-dirty {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ width: 20px;
+}
+.dirty-indicator-dirty.fa-pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator-dirty.fa-pull-right {
+ margin-left: .3em;
+}
+.dirty-indicator-dirty.pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator-dirty.pull-right {
+ margin-left: .3em;
+}
+.dirty-indicator-clean {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ width: 20px;
+}
+.dirty-indicator-clean.fa-pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator-clean.fa-pull-right {
+ margin-left: .3em;
+}
+.dirty-indicator-clean.pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator-clean.pull-right {
+ margin-left: .3em;
+}
+.dirty-indicator-clean:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f00c";
+}
+.dirty-indicator-clean:before.fa-pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator-clean:before.fa-pull-right {
+ margin-left: .3em;
+}
+.dirty-indicator-clean:before.pull-left {
+ margin-right: .3em;
+}
+.dirty-indicator-clean:before.pull-right {
+ margin-left: .3em;
+}
+#filename {
+ font-size: 16pt;
+ display: table;
+ padding: 0px 5px;
+}
+#current-mode {
+ padding-left: 5px;
+ padding-right: 5px;
+}
+#texteditor-backdrop {
+ padding-top: 20px;
+ padding-bottom: 20px;
+}
+@media not print {
+ #texteditor-backdrop {
+ background-color: #EEE;
+ }
+}
+@media print {
+ #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
+ #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
+ background-color: #fff;
+ }
+}
+@media not print {
+ #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
+ #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
+ background-color: #fff;
+ }
+}
+@media not print {
+ #texteditor-backdrop #texteditor-container {
+ padding: 0px;
+ background-color: #fff;
+ -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ }
+}
+.CodeMirror-dialog {
+ background-color: #fff;
+}
+/*!
+*
+* IPython notebook
+*
+*/
+/* CSS font colors for translated ANSI escape sequences */
+/* The color values are a mix of
+ http://www.xcolors.net/dl/baskerville-ivorylight and
+ http://www.xcolors.net/dl/euphrasia */
+.ansi-black-fg {
+ color: #3E424D;
+}
+.ansi-black-bg {
+ background-color: #3E424D;
+}
+.ansi-black-intense-fg {
+ color: #282C36;
+}
+.ansi-black-intense-bg {
+ background-color: #282C36;
+}
+.ansi-red-fg {
+ color: #E75C58;
+}
+.ansi-red-bg {
+ background-color: #E75C58;
+}
+.ansi-red-intense-fg {
+ color: #B22B31;
+}
+.ansi-red-intense-bg {
+ background-color: #B22B31;
+}
+.ansi-green-fg {
+ color: #00A250;
+}
+.ansi-green-bg {
+ background-color: #00A250;
+}
+.ansi-green-intense-fg {
+ color: #007427;
+}
+.ansi-green-intense-bg {
+ background-color: #007427;
+}
+.ansi-yellow-fg {
+ color: #DDB62B;
+}
+.ansi-yellow-bg {
+ background-color: #DDB62B;
+}
+.ansi-yellow-intense-fg {
+ color: #B27D12;
+}
+.ansi-yellow-intense-bg {
+ background-color: #B27D12;
+}
+.ansi-blue-fg {
+ color: #208FFB;
+}
+.ansi-blue-bg {
+ background-color: #208FFB;
+}
+.ansi-blue-intense-fg {
+ color: #0065CA;
+}
+.ansi-blue-intense-bg {
+ background-color: #0065CA;
+}
+.ansi-magenta-fg {
+ color: #D160C4;
+}
+.ansi-magenta-bg {
+ background-color: #D160C4;
+}
+.ansi-magenta-intense-fg {
+ color: #A03196;
+}
+.ansi-magenta-intense-bg {
+ background-color: #A03196;
+}
+.ansi-cyan-fg {
+ color: #60C6C8;
+}
+.ansi-cyan-bg {
+ background-color: #60C6C8;
+}
+.ansi-cyan-intense-fg {
+ color: #258F8F;
+}
+.ansi-cyan-intense-bg {
+ background-color: #258F8F;
+}
+.ansi-white-fg {
+ color: #C5C1B4;
+}
+.ansi-white-bg {
+ background-color: #C5C1B4;
+}
+.ansi-white-intense-fg {
+ color: #A1A6B2;
+}
+.ansi-white-intense-bg {
+ background-color: #A1A6B2;
+}
+.ansi-default-inverse-fg {
+ color: #FFFFFF;
+}
+.ansi-default-inverse-bg {
+ background-color: #000000;
+}
+.ansi-bold {
+ font-weight: bold;
+}
+.ansi-underline {
+ text-decoration: underline;
+}
+/* The following styles are deprecated an will be removed in a future version */
+.ansibold {
+ font-weight: bold;
+}
+.ansi-inverse {
+ outline: 0.5px dotted;
+}
+/* use dark versions for foreground, to improve visibility */
+.ansiblack {
+ color: black;
+}
+.ansired {
+ color: darkred;
+}
+.ansigreen {
+ color: darkgreen;
+}
+.ansiyellow {
+ color: #c4a000;
+}
+.ansiblue {
+ color: darkblue;
+}
+.ansipurple {
+ color: darkviolet;
+}
+.ansicyan {
+ color: steelblue;
+}
+.ansigray {
+ color: gray;
+}
+/* and light for background, for the same reason */
+.ansibgblack {
+ background-color: black;
+}
+.ansibgred {
+ background-color: red;
+}
+.ansibggreen {
+ background-color: green;
+}
+.ansibgyellow {
+ background-color: yellow;
+}
+.ansibgblue {
+ background-color: blue;
+}
+.ansibgpurple {
+ background-color: magenta;
+}
+.ansibgcyan {
+ background-color: cyan;
+}
+.ansibggray {
+ background-color: gray;
+}
+div.cell {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ border-radius: 2px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ border-width: 1px;
+ border-style: solid;
+ border-color: transparent;
+ width: 100%;
+ padding: 5px;
+ /* This acts as a spacer between cells, that is outside the border */
+ margin: 0px;
+ outline: none;
+ position: relative;
+ overflow: visible;
+}
+div.cell:before {
+ position: absolute;
+ display: block;
+ top: -1px;
+ left: -1px;
+ width: 5px;
+ height: calc(100% + 2px);
+ content: '';
+ background: transparent;
+}
+div.cell.jupyter-soft-selected {
+ border-left-color: #E3F2FD;
+ border-left-width: 1px;
+ padding-left: 5px;
+ border-right-color: #E3F2FD;
+ border-right-width: 1px;
+ background: #E3F2FD;
+}
+@media print {
+ div.cell.jupyter-soft-selected {
+ border-color: transparent;
+ }
+}
+div.cell.selected,
+div.cell.selected.jupyter-soft-selected {
+ border-color: #ababab;
+}
+div.cell.selected:before,
+div.cell.selected.jupyter-soft-selected:before {
+ position: absolute;
+ display: block;
+ top: -1px;
+ left: -1px;
+ width: 5px;
+ height: calc(100% + 2px);
+ content: '';
+ background: #42A5F5;
+}
+@media print {
+ div.cell.selected,
+ div.cell.selected.jupyter-soft-selected {
+ border-color: transparent;
+ }
+}
+.edit_mode div.cell.selected {
+ border-color: #66BB6A;
+}
+.edit_mode div.cell.selected:before {
+ position: absolute;
+ display: block;
+ top: -1px;
+ left: -1px;
+ width: 5px;
+ height: calc(100% + 2px);
+ content: '';
+ background: #66BB6A;
+}
+@media print {
+ .edit_mode div.cell.selected {
+ border-color: transparent;
+ }
+}
+.prompt {
+ /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
+ min-width: 14ex;
+ /* This padding is tuned to match the padding on the CodeMirror editor. */
+ padding: 0.4em;
+ margin: 0px;
+ font-family: monospace;
+ text-align: right;
+ /* This has to match that of the the CodeMirror class line-height below */
+ line-height: 1.21429em;
+ /* Don't highlight prompt number selection */
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ /* Use default cursor */
+ cursor: default;
+}
+@media (max-width: 540px) {
+ .prompt {
+ text-align: left;
+ }
+}
+div.inner_cell {
+ min-width: 0;
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ /* Old browsers */
+ -webkit-box-flex: 1;
+ -moz-box-flex: 1;
+ box-flex: 1;
+ /* Modern browsers */
+ flex: 1;
+}
+/* input_area and input_prompt must match in top border and margin for alignment */
+div.input_area {
+ border: 1px solid #cfcfcf;
+ border-radius: 2px;
+ background: #f7f7f7;
+ line-height: 1.21429em;
+}
+/* This is needed so that empty prompt areas can collapse to zero height when there
+ is no content in the output_subarea and the prompt. The main purpose of this is
+ to make sure that empty JavaScript output_subareas have no height. */
+div.prompt:empty {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+div.unrecognized_cell {
+ padding: 5px 5px 5px 0px;
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: horizontal;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+}
+div.unrecognized_cell .inner_cell {
+ border-radius: 2px;
+ padding: 5px;
+ font-weight: bold;
+ color: red;
+ border: 1px solid #cfcfcf;
+ background: #eaeaea;
+}
+div.unrecognized_cell .inner_cell a {
+ color: inherit;
+ text-decoration: none;
+}
+div.unrecognized_cell .inner_cell a:hover {
+ color: inherit;
+ text-decoration: none;
+}
+@media (max-width: 540px) {
+ div.unrecognized_cell > div.prompt {
+ display: none;
+ }
+}
+div.code_cell {
+ /* avoid page breaking on code cells when printing */
+}
+@media print {
+ div.code_cell {
+ page-break-inside: avoid;
+ }
+}
+/* any special styling for code cells that are currently running goes here */
+div.input {
+ page-break-inside: avoid;
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: horizontal;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+}
+@media (max-width: 540px) {
+ div.input {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ }
+}
+/* input_area and input_prompt must match in top border and margin for alignment */
+div.input_prompt {
+ color: #303F9F;
+ border-top: 1px solid transparent;
+}
+div.input_area > div.highlight {
+ margin: 0.4em;
+ border: none;
+ padding: 0px;
+ background-color: transparent;
+}
+div.input_area > div.highlight > pre {
+ margin: 0px;
+ border: none;
+ padding: 0px;
+ background-color: transparent;
+}
+/* The following gets added to the <head> if it is detected that the user has a
+ * monospace font with inconsistent normal/bold/italic height. See
+ * notebookmain.js. Such fonts will have keywords vertically offset with
+ * respect to the rest of the text. The user should select a better font.
+ * See: https://github.com/ipython/ipython/issues/1503
+ *
+ * .CodeMirror span {
+ * vertical-align: bottom;
+ * }
+ */
+.CodeMirror {
+ line-height: 1.21429em;
+ /* Changed from 1em to our global default */
+ font-size: 14px;
+ height: auto;
+ /* Changed to auto to autogrow */
+ background: none;
+ /* Changed from white to allow our bg to show through */
+}
+.CodeMirror-scroll {
+ /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
+ /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
+ overflow-y: hidden;
+ overflow-x: auto;
+}
+.CodeMirror-lines {
+ /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
+ /* we have set a different line-height and want this to scale with that. */
+ /* Note that this should set vertical padding only, since CodeMirror assumes
+ that horizontal padding will be set on CodeMirror pre */
+ padding: 0.4em 0;
+}
+.CodeMirror-linenumber {
+ padding: 0 8px 0 4px;
+}
+.CodeMirror-gutters {
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
+}
+.CodeMirror pre {
+ /* In CM3 this went to 4px from 0 in CM2. This sets horizontal padding only,
+ use .CodeMirror-lines for vertical */
+ padding: 0 0.4em;
+ border: 0;
+ border-radius: 0;
+}
+.CodeMirror-cursor {
+ border-left: 1.4px solid black;
+}
+@media screen and (min-width: 2138px) and (max-width: 4319px) {
+ .CodeMirror-cursor {
+ border-left: 2px solid black;
+ }
+}
+@media screen and (min-width: 4320px) {
+ .CodeMirror-cursor {
+ border-left: 4px solid black;
+ }
+}
+/*
+
+Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
+Adapted from GitHub theme
+
+*/
+.highlight-base {
+ color: #000;
+}
+.highlight-variable {
+ color: #000;
+}
+.highlight-variable-2 {
+ color: #1a1a1a;
+}
+.highlight-variable-3 {
+ color: #333333;
+}
+.highlight-string {
+ color: #BA2121;
+}
+.highlight-comment {
+ color: #408080;
+ font-style: italic;
+}
+.highlight-number {
+ color: #080;
+}
+.highlight-atom {
+ color: #88F;
+}
+.highlight-keyword {
+ color: #008000;
+ font-weight: bold;
+}
+.highlight-builtin {
+ color: #008000;
+}
+.highlight-error {
+ color: #f00;
+}
+.highlight-operator {
+ color: #AA22FF;
+ font-weight: bold;
+}
+.highlight-meta {
+ color: #AA22FF;
+}
+/* previously not defined, copying from default codemirror */
+.highlight-def {
+ color: #00f;
+}
+.highlight-string-2 {
+ color: #f50;
+}
+.highlight-qualifier {
+ color: #555;
+}
+.highlight-bracket {
+ color: #997;
+}
+.highlight-tag {
+ color: #170;
+}
+.highlight-attribute {
+ color: #00c;
+}
+.highlight-header {
+ color: blue;
+}
+.highlight-quote {
+ color: #090;
+}
+.highlight-link {
+ color: #00c;
+}
+/* apply the same style to codemirror */
+.cm-s-ipython span.cm-keyword {
+ color: #008000;
+ font-weight: bold;
+}
+.cm-s-ipython span.cm-atom {
+ color: #88F;
+}
+.cm-s-ipython span.cm-number {
+ color: #080;
+}
+.cm-s-ipython span.cm-def {
+ color: #00f;
+}
+.cm-s-ipython span.cm-variable {
+ color: #000;
+}
+.cm-s-ipython span.cm-operator {
+ color: #AA22FF;
+ font-weight: bold;
+}
+.cm-s-ipython span.cm-variable-2 {
+ color: #1a1a1a;
+}
+.cm-s-ipython span.cm-variable-3 {
+ color: #333333;
+}
+.cm-s-ipython span.cm-comment {
+ color: #408080;
+ font-style: italic;
+}
+.cm-s-ipython span.cm-string {
+ color: #BA2121;
+}
+.cm-s-ipython span.cm-string-2 {
+ color: #f50;
+}
+.cm-s-ipython span.cm-meta {
+ color: #AA22FF;
+}
+.cm-s-ipython span.cm-qualifier {
+ color: #555;
+}
+.cm-s-ipython span.cm-builtin {
+ color: #008000;
+}
+.cm-s-ipython span.cm-bracket {
+ color: #997;
+}
+.cm-s-ipython span.cm-tag {
+ color: #170;
+}
+.cm-s-ipython span.cm-attribute {
+ color: #00c;
+}
+.cm-s-ipython span.cm-header {
+ color: blue;
+}
+.cm-s-ipython span.cm-quote {
+ color: #090;
+}
+.cm-s-ipython span.cm-link {
+ color: #00c;
+}
+.cm-s-ipython span.cm-error {
+ color: #f00;
+}
+.cm-s-ipython span.cm-tab {
+ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
+ background-position: right;
+ background-repeat: no-repeat;
+}
+div.output_wrapper {
+ /* this position must be relative to enable descendents to be absolute within it */
+ position: relative;
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ z-index: 1;
+}
+/* class for the output area when it should be height-limited */
+div.output_scroll {
+ /* ideally, this would be max-height, but FF barfs all over that */
+ height: 24em;
+ /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
+ width: 100%;
+ overflow: auto;
+ border-radius: 2px;
+ -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
+ box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
+ display: block;
+}
+/* output div while it is collapsed */
+div.output_collapsed {
+ margin: 0px;
+ padding: 0px;
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+}
+div.out_prompt_overlay {
+ height: 100%;
+ padding: 0px 0.4em;
+ position: absolute;
+ border-radius: 2px;
+}
+div.out_prompt_overlay:hover {
+ /* use inner shadow to get border that is computed the same on WebKit/FF */
+ -webkit-box-shadow: inset 0 0 1px #000;
+ box-shadow: inset 0 0 1px #000;
+ background: rgba(240, 240, 240, 0.5);
+}
+div.output_prompt {
+ color: #D84315;
+}
+/* This class is the outer container of all output sections. */
+div.output_area {
+ padding: 0px;
+ page-break-inside: avoid;
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: horizontal;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+}
+div.output_area .MathJax_Display {
+ text-align: left !important;
+}
+div.output_area .rendered_html table {
+ margin-left: 0;
+ margin-right: 0;
+}
+div.output_area .rendered_html img {
+ margin-left: 0;
+ margin-right: 0;
+}
+div.output_area img,
+div.output_area svg {
+ max-width: 100%;
+ height: auto;
+}
+div.output_area img.unconfined,
+div.output_area svg.unconfined {
+ max-width: none;
+}
+div.output_area .mglyph > img {
+ max-width: none;
+}
+/* This is needed to protect the pre formating from global settings such
+ as that of bootstrap */
+.output {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+}
+@media (max-width: 540px) {
+ div.output_area {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: vertical;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ }
+}
+div.output_area pre {
+ margin: 0;
+ padding: 1px 0 1px 0;
+ border: 0;
+ vertical-align: baseline;
+ color: black;
+ background-color: transparent;
+ border-radius: 0;
+}
+/* This class is for the output subarea inside the output_area and after
+ the prompt div. */
+div.output_subarea {
+ overflow-x: auto;
+ padding: 0.4em;
+ /* Old browsers */
+ -webkit-box-flex: 1;
+ -moz-box-flex: 1;
+ box-flex: 1;
+ /* Modern browsers */
+ flex: 1;
+ max-width: calc(100% - 14ex);
+}
+div.output_scroll div.output_subarea {
+ overflow-x: visible;
+}
+/* The rest of the output_* classes are for special styling of the different
+ output types */
+/* all text output has this class: */
+div.output_text {
+ text-align: left;
+ color: #000;
+ /* This has to match that of the the CodeMirror class line-height below */
+ line-height: 1.21429em;
+}
+/* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
+div.output_stderr {
+ background: #fdd;
+ /* very light red background for stderr */
+}
+div.output_latex {
+ text-align: left;
+}
+/* Empty output_javascript divs should have no height */
+div.output_javascript:empty {
+ padding: 0;
+}
+.js-error {
+ color: darkred;
+}
+/* raw_input styles */
+div.raw_input_container {
+ line-height: 1.21429em;
+ padding-top: 5px;
+}
+pre.raw_input_prompt {
+ /* nothing needed here. */
+}
+input.raw_input {
+ font-family: monospace;
+ font-size: inherit;
+ color: inherit;
+ width: auto;
+ /* make sure input baseline aligns with prompt */
+ vertical-align: baseline;
+ /* padding + margin = 0.5em between prompt and cursor */
+ padding: 0em 0.25em;
+ margin: 0em 0.25em;
+}
+input.raw_input:focus {
+ box-shadow: none;
+}
+p.p-space {
+ margin-bottom: 10px;
+}
+div.output_unrecognized {
+ padding: 5px;
+ font-weight: bold;
+ color: red;
+}
+div.output_unrecognized a {
+ color: inherit;
+ text-decoration: none;
+}
+div.output_unrecognized a:hover {
+ color: inherit;
+ text-decoration: none;
+}
+.rendered_html {
+ color: #000;
+ /* any extras will just be numbers: */
+}
+.rendered_html em {
+ font-style: italic;
+}
+.rendered_html strong {
+ font-weight: bold;
+}
+.rendered_html u {
+ text-decoration: underline;
+}
+.rendered_html :link {
+ text-decoration: underline;
+}
+.rendered_html :visited {
+ text-decoration: underline;
+}
+.rendered_html h1 {
+ font-size: 185.7%;
+ margin: 1.08em 0 0 0;
+ font-weight: bold;
+ line-height: 1.0;
+}
+.rendered_html h2 {
+ font-size: 157.1%;
+ margin: 1.27em 0 0 0;
+ font-weight: bold;
+ line-height: 1.0;
+}
+.rendered_html h3 {
+ font-size: 128.6%;
+ margin: 1.55em 0 0 0;
+ font-weight: bold;
+ line-height: 1.0;
+}
+.rendered_html h4 {
+ font-size: 100%;
+ margin: 2em 0 0 0;
+ font-weight: bold;
+ line-height: 1.0;
+}
+.rendered_html h5 {
+ font-size: 100%;
+ margin: 2em 0 0 0;
+ font-weight: bold;
+ line-height: 1.0;
+ font-style: italic;
+}
+.rendered_html h6 {
+ font-size: 100%;
+ margin: 2em 0 0 0;
+ font-weight: bold;
+ line-height: 1.0;
+ font-style: italic;
+}
+.rendered_html h1:first-child {
+ margin-top: 0.538em;
+}
+.rendered_html h2:first-child {
+ margin-top: 0.636em;
+}
+.rendered_html h3:first-child {
+ margin-top: 0.777em;
+}
+.rendered_html h4:first-child {
+ margin-top: 1em;
+}
+.rendered_html h5:first-child {
+ margin-top: 1em;
+}
+.rendered_html h6:first-child {
+ margin-top: 1em;
+}
+.rendered_html ul:not(.list-inline),
+.rendered_html ol:not(.list-inline) {
+ padding-left: 2em;
+}
+.rendered_html ul {
+ list-style: disc;
+}
+.rendered_html ul ul {
+ list-style: square;
+ margin-top: 0;
+}
+.rendered_html ul ul ul {
+ list-style: circle;
+}
+.rendered_html ol {
+ list-style: decimal;
+}
+.rendered_html ol ol {
+ list-style: upper-alpha;
+ margin-top: 0;
+}
+.rendered_html ol ol ol {
+ list-style: lower-alpha;
+}
+.rendered_html ol ol ol ol {
+ list-style: lower-roman;
+}
+.rendered_html ol ol ol ol ol {
+ list-style: decimal;
+}
+.rendered_html * + ul {
+ margin-top: 1em;
+}
+.rendered_html * + ol {
+ margin-top: 1em;
+}
+.rendered_html hr {
+ color: black;
+ background-color: black;
+}
+.rendered_html pre {
+ margin: 1em 2em;
+ padding: 0px;
+ background-color: #fff;
+}
+.rendered_html code {
+ background-color: #eff0f1;
+}
+.rendered_html p code {
+ padding: 1px 5px;
+}
+.rendered_html pre code {
+ background-color: #fff;
+}
+.rendered_html pre,
+.rendered_html code {
+ border: 0;
+ color: #000;
+ font-size: 100%;
+}
+.rendered_html blockquote {
+ margin: 1em 2em;
+}
+.rendered_html table {
+ margin-left: auto;
+ margin-right: auto;
+ border: none;
+ border-collapse: collapse;
+ border-spacing: 0;
+ color: black;
+ font-size: 12px;
+ table-layout: fixed;
+}
+.rendered_html thead {
+ border-bottom: 1px solid black;
+ vertical-align: bottom;
+}
+.rendered_html tr,
+.rendered_html th,
+.rendered_html td {
+ text-align: right;
+ vertical-align: middle;
+ padding: 0.5em 0.5em;
+ line-height: normal;
+ white-space: normal;
+ max-width: none;
+ border: none;
+}
+.rendered_html th {
+ font-weight: bold;
+}
+.rendered_html tbody tr:nth-child(odd) {
+ background: #f5f5f5;
+}
+.rendered_html tbody tr:hover {
+ background: rgba(66, 165, 245, 0.2);
+}
+.rendered_html * + table {
+ margin-top: 1em;
+}
+.rendered_html p {
+ text-align: left;
+}
+.rendered_html * + p {
+ margin-top: 1em;
+}
+.rendered_html img {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+.rendered_html * + img {
+ margin-top: 1em;
+}
+.rendered_html img,
+.rendered_html svg {
+ max-width: 100%;
+ height: auto;
+}
+.rendered_html img.unconfined,
+.rendered_html svg.unconfined {
+ max-width: none;
+}
+.rendered_html .alert {
+ margin-bottom: initial;
+}
+.rendered_html * + .alert {
+ margin-top: 1em;
+}
+[dir="rtl"] .rendered_html p {
+ text-align: right;
+}
+div.text_cell {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: horizontal;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+}
+@media (max-width: 540px) {
+ div.text_cell > div.prompt {
+ display: none;
+ }
+}
+div.text_cell_render {
+ /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
+ outline: none;
+ resize: none;
+ width: inherit;
+ border-style: none;
+ padding: 0.5em 0.5em 0.5em 0.4em;
+ color: #000;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+a.anchor-link:link {
+ text-decoration: none;
+ padding: 0px 20px;
+ visibility: hidden;
+}
+h1:hover .anchor-link,
+h2:hover .anchor-link,
+h3:hover .anchor-link,
+h4:hover .anchor-link,
+h5:hover .anchor-link,
+h6:hover .anchor-link {
+ visibility: visible;
+}
+.text_cell.rendered .input_area {
+ display: none;
+}
+.text_cell.rendered .rendered_html {
+ overflow-x: auto;
+ overflow-y: hidden;
+}
+.text_cell.rendered .rendered_html tr,
+.text_cell.rendered .rendered_html th,
+.text_cell.rendered .rendered_html td {
+ max-width: none;
+}
+.text_cell.unrendered .text_cell_render {
+ display: none;
+}
+.text_cell .dropzone .input_area {
+ border: 2px dashed #bababa;
+ margin: -1px;
+}
+.cm-header-1,
+.cm-header-2,
+.cm-header-3,
+.cm-header-4,
+.cm-header-5,
+.cm-header-6 {
+ font-weight: bold;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+.cm-header-1 {
+ font-size: 185.7%;
+}
+.cm-header-2 {
+ font-size: 157.1%;
+}
+.cm-header-3 {
+ font-size: 128.6%;
+}
+.cm-header-4 {
+ font-size: 110%;
+}
+.cm-header-5 {
+ font-size: 100%;
+ font-style: italic;
+}
+.cm-header-6 {
+ font-size: 100%;
+ font-style: italic;
+}
+/*!
+*
+* IPython notebook webapp
+*
+*/
+@media (max-width: 767px) {
+ .notebook_app {
+ padding-left: 0px;
+ padding-right: 0px;
+ }
+}
+#ipython-main-app {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ height: 100%;
+}
+div#notebook_panel {
+ margin: 0px;
+ padding: 0px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ height: 100%;
+}
+div#notebook {
+ font-size: 14px;
+ line-height: 20px;
+ overflow-y: hidden;
+ overflow-x: auto;
+ width: 100%;
+ /* This spaces the page away from the edge of the notebook area */
+ padding-top: 20px;
+ margin: 0px;
+ outline: none;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ min-height: 100%;
+}
+@media not print {
+ #notebook-container {
+ padding: 15px;
+ background-color: #fff;
+ min-height: 0;
+ -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ }
+}
+@media print {
+ #notebook-container {
+ width: 100%;
+ }
+}
+div.ui-widget-content {
+ border: 1px solid #ababab;
+ outline: none;
+}
+pre.dialog {
+ background-color: #f7f7f7;
+ border: 1px solid #ddd;
+ border-radius: 2px;
+ padding: 0.4em;
+ padding-left: 2em;
+}
+p.dialog {
+ padding: 0.2em;
+}
+/* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems
+ to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do.
+ */
+pre,
+code,
+kbd,
+samp {
+ white-space: pre-wrap;
+}
+#fonttest {
+ font-family: monospace;
+}
+p {
+ margin-bottom: 0;
+}
+.end_space {
+ min-height: 100px;
+ transition: height .2s ease;
+}
+.notebook_app > #header {
+ -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+}
+@media not print {
+ .notebook_app {
+ background-color: #EEE;
+ }
+}
+kbd {
+ border-style: solid;
+ border-width: 1px;
+ box-shadow: none;
+ margin: 2px;
+ padding-left: 2px;
+ padding-right: 2px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+.jupyter-keybindings {
+ padding: 1px;
+ line-height: 24px;
+ border-bottom: 1px solid gray;
+}
+.jupyter-keybindings input {
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+.jupyter-keybindings i {
+ padding: 6px;
+}
+.well code {
+ background-color: #ffffff;
+ border-color: #ababab;
+ border-width: 1px;
+ border-style: solid;
+ padding: 2px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+/* CSS for the cell toolbar */
+.celltoolbar {
+ border: thin solid #CFCFCF;
+ border-bottom: none;
+ background: #EEE;
+ border-radius: 2px 2px 0px 0px;
+ width: 100%;
+ height: 29px;
+ padding-right: 4px;
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: horizontal;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+ /* Old browsers */
+ -webkit-box-pack: end;
+ -moz-box-pack: end;
+ box-pack: end;
+ /* Modern browsers */
+ justify-content: flex-end;
+ display: -webkit-flex;
+}
+@media print {
+ .celltoolbar {
+ display: none;
+ }
+}
+.ctb_hideshow {
+ display: none;
+ vertical-align: bottom;
+}
+/* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
+ Cell toolbars are only shown when the ctb_global_show class is also set.
+*/
+.ctb_global_show .ctb_show.ctb_hideshow {
+ display: block;
+}
+.ctb_global_show .ctb_show + .input_area,
+.ctb_global_show .ctb_show + div.text_cell_input,
+.ctb_global_show .ctb_show ~ div.text_cell_render {
+ border-top-right-radius: 0px;
+ border-top-left-radius: 0px;
+}
+.ctb_global_show .ctb_show ~ div.text_cell_render {
+ border: 1px solid #cfcfcf;
+}
+.celltoolbar {
+ font-size: 87%;
+ padding-top: 3px;
+}
+.celltoolbar select {
+ display: block;
+ width: 100%;
+ height: 32px;
+ padding: 6px 12px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #555555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 2px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 1px;
+ width: inherit;
+ font-size: inherit;
+ height: 22px;
+ padding: 0px;
+ display: inline-block;
+}
+.celltoolbar select:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+.celltoolbar select::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.celltoolbar select:-ms-input-placeholder {
+ color: #999;
+}
+.celltoolbar select::-webkit-input-placeholder {
+ color: #999;
+}
+.celltoolbar select::-ms-expand {
+ border: 0;
+ background-color: transparent;
+}
+.celltoolbar select[disabled],
+.celltoolbar select[readonly],
+fieldset[disabled] .celltoolbar select {
+ background-color: #eeeeee;
+ opacity: 1;
+}
+.celltoolbar select[disabled],
+fieldset[disabled] .celltoolbar select {
+ cursor: not-allowed;
+}
+textarea.celltoolbar select {
+ height: auto;
+}
+select.celltoolbar select {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.celltoolbar select,
+select[multiple].celltoolbar select {
+ height: auto;
+}
+.celltoolbar label {
+ margin-left: 5px;
+ margin-right: 5px;
+}
+.tags_button_container {
+ width: 100%;
+ display: flex;
+}
+.tag-container {
+ display: flex;
+ flex-direction: row;
+ flex-grow: 1;
+ overflow: hidden;
+ position: relative;
+}
+.tag-container > * {
+ margin: 0 4px;
+}
+.remove-tag-btn {
+ margin-left: 4px;
+}
+.tags-input {
+ display: flex;
+}
+.cell-tag:last-child:after {
+ content: "";
+ position: absolute;
+ right: 0;
+ width: 40px;
+ height: 100%;
+ /* Fade to background color of cell toolbar */
+ background: linear-gradient(to right, rgba(0, 0, 0, 0), #EEE);
+}
+.tags-input > * {
+ margin-left: 4px;
+}
+.cell-tag,
+.tags-input input,
+.tags-input button {
+ display: block;
+ width: 100%;
+ height: 32px;
+ padding: 6px 12px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #555555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 2px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 1px;
+ box-shadow: none;
+ width: inherit;
+ font-size: inherit;
+ height: 22px;
+ line-height: 22px;
+ padding: 0px 4px;
+ display: inline-block;
+}
+.cell-tag:focus,
+.tags-input input:focus,
+.tags-input button:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+.cell-tag::-moz-placeholder,
+.tags-input input::-moz-placeholder,
+.tags-input button::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.cell-tag:-ms-input-placeholder,
+.tags-input input:-ms-input-placeholder,
+.tags-input button:-ms-input-placeholder {
+ color: #999;
+}
+.cell-tag::-webkit-input-placeholder,
+.tags-input input::-webkit-input-placeholder,
+.tags-input button::-webkit-input-placeholder {
+ color: #999;
+}
+.cell-tag::-ms-expand,
+.tags-input input::-ms-expand,
+.tags-input button::-ms-expand {
+ border: 0;
+ background-color: transparent;
+}
+.cell-tag[disabled],
+.tags-input input[disabled],
+.tags-input button[disabled],
+.cell-tag[readonly],
+.tags-input input[readonly],
+.tags-input button[readonly],
+fieldset[disabled] .cell-tag,
+fieldset[disabled] .tags-input input,
+fieldset[disabled] .tags-input button {
+ background-color: #eeeeee;
+ opacity: 1;
+}
+.cell-tag[disabled],
+.tags-input input[disabled],
+.tags-input button[disabled],
+fieldset[disabled] .cell-tag,
+fieldset[disabled] .tags-input input,
+fieldset[disabled] .tags-input button {
+ cursor: not-allowed;
+}
+textarea.cell-tag,
+textarea.tags-input input,
+textarea.tags-input button {
+ height: auto;
+}
+select.cell-tag,
+select.tags-input input,
+select.tags-input button {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.cell-tag,
+textarea.tags-input input,
+textarea.tags-input button,
+select[multiple].cell-tag,
+select[multiple].tags-input input,
+select[multiple].tags-input button {
+ height: auto;
+}
+.cell-tag,
+.tags-input button {
+ padding: 0px 4px;
+}
+.cell-tag {
+ background-color: #fff;
+ white-space: nowrap;
+}
+.tags-input input[type=text]:focus {
+ outline: none;
+ box-shadow: none;
+ border-color: #ccc;
+}
+.completions {
+ position: absolute;
+ z-index: 110;
+ overflow: hidden;
+ border: 1px solid #ababab;
+ border-radius: 2px;
+ -webkit-box-shadow: 0px 6px 10px -1px #adadad;
+ box-shadow: 0px 6px 10px -1px #adadad;
+ line-height: 1;
+}
+.completions select {
+ background: white;
+ outline: none;
+ border: none;
+ padding: 0px;
+ margin: 0px;
+ overflow: auto;
+ font-family: monospace;
+ font-size: 110%;
+ color: #000;
+ width: auto;
+}
+.completions select option.context {
+ color: #286090;
+}
+#kernel_logo_widget .current_kernel_logo {
+ display: none;
+ margin-top: -1px;
+ margin-bottom: -1px;
+ width: 32px;
+ height: 32px;
+}
+[dir="rtl"] #kernel_logo_widget {
+ float: left !important;
+ float: left;
+}
+.modal .modal-body .move-path {
+ display: flex;
+ flex-direction: row;
+ justify-content: space;
+ align-items: center;
+}
+.modal .modal-body .move-path .server-root {
+ padding-right: 20px;
+}
+.modal .modal-body .move-path .path-input {
+ flex: 1;
+}
+#menubar {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ margin-top: 1px;
+}
+#menubar .navbar {
+ border-top: 1px;
+ border-radius: 0px 0px 2px 2px;
+ margin-bottom: 0px;
+}
+#menubar .navbar-toggle {
+ float: left;
+ padding-top: 7px;
+ padding-bottom: 7px;
+ border: none;
+}
+#menubar .navbar-collapse {
+ clear: left;
+}
+[dir="rtl"] #menubar .navbar-toggle {
+ float: right;
+}
+[dir="rtl"] #menubar .navbar-collapse {
+ clear: right;
+}
+[dir="rtl"] #menubar .navbar-nav {
+ float: right;
+}
+[dir="rtl"] #menubar .nav {
+ padding-right: 0px;
+}
+[dir="rtl"] #menubar .navbar-nav > li {
+ float: right;
+}
+[dir="rtl"] #menubar .navbar-right {
+ float: left !important;
+}
+[dir="rtl"] ul.dropdown-menu {
+ text-align: right;
+ left: auto;
+}
+[dir="rtl"] ul#new-menu.dropdown-menu {
+ right: auto;
+ left: 0;
+}
+.nav-wrapper {
+ border-bottom: 1px solid #e7e7e7;
+}
+i.menu-icon {
+ padding-top: 4px;
+}
+[dir="rtl"] i.menu-icon.pull-right {
+ float: left !important;
+ float: left;
+}
+ul#help_menu li a {
+ overflow: hidden;
+ padding-right: 2.2em;
+}
+ul#help_menu li a i {
+ margin-right: -1.2em;
+}
+[dir="rtl"] ul#help_menu li a {
+ padding-left: 2.2em;
+}
+[dir="rtl"] ul#help_menu li a i {
+ margin-right: 0;
+ margin-left: -1.2em;
+}
+[dir="rtl"] ul#help_menu li a i.pull-right {
+ float: left !important;
+ float: left;
+}
+.dropdown-submenu {
+ position: relative;
+}
+.dropdown-submenu > .dropdown-menu {
+ top: 0;
+ left: 100%;
+ margin-top: -6px;
+ margin-left: -1px;
+}
+[dir="rtl"] .dropdown-submenu > .dropdown-menu {
+ right: 100%;
+ margin-right: -1px;
+}
+.dropdown-submenu:hover > .dropdown-menu {
+ display: block;
+}
+.dropdown-submenu > a:after {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ display: block;
+ content: "\f0da";
+ float: right;
+ color: #333333;
+ margin-top: 2px;
+ margin-right: -10px;
+}
+.dropdown-submenu > a:after.fa-pull-left {
+ margin-right: .3em;
+}
+.dropdown-submenu > a:after.fa-pull-right {
+ margin-left: .3em;
+}
+.dropdown-submenu > a:after.pull-left {
+ margin-right: .3em;
+}
+.dropdown-submenu > a:after.pull-right {
+ margin-left: .3em;
+}
+[dir="rtl"] .dropdown-submenu > a:after {
+ float: left;
+ content: "\f0d9";
+ margin-right: 0;
+ margin-left: -10px;
+}
+.dropdown-submenu:hover > a:after {
+ color: #262626;
+}
+.dropdown-submenu.pull-left {
+ float: none;
+}
+.dropdown-submenu.pull-left > .dropdown-menu {
+ left: -100%;
+ margin-left: 10px;
+}
+#notification_area {
+ float: right !important;
+ float: right;
+ z-index: 10;
+}
+[dir="rtl"] #notification_area {
+ float: left !important;
+ float: left;
+}
+.indicator_area {
+ float: right !important;
+ float: right;
+ color: #777;
+ margin-left: 5px;
+ margin-right: 5px;
+ width: 11px;
+ z-index: 10;
+ text-align: center;
+ width: auto;
+}
+[dir="rtl"] .indicator_area {
+ float: left !important;
+ float: left;
+}
+#kernel_indicator {
+ float: right !important;
+ float: right;
+ color: #777;
+ margin-left: 5px;
+ margin-right: 5px;
+ width: 11px;
+ z-index: 10;
+ text-align: center;
+ width: auto;
+ border-left: 1px solid;
+}
+#kernel_indicator .kernel_indicator_name {
+ padding-left: 5px;
+ padding-right: 5px;
+}
+[dir="rtl"] #kernel_indicator {
+ float: left !important;
+ float: left;
+ border-left: 0;
+ border-right: 1px solid;
+}
+#modal_indicator {
+ float: right !important;
+ float: right;
+ color: #777;
+ margin-left: 5px;
+ margin-right: 5px;
+ width: 11px;
+ z-index: 10;
+ text-align: center;
+ width: auto;
+}
+[dir="rtl"] #modal_indicator {
+ float: left !important;
+ float: left;
+}
+#readonly-indicator {
+ float: right !important;
+ float: right;
+ color: #777;
+ margin-left: 5px;
+ margin-right: 5px;
+ width: 11px;
+ z-index: 10;
+ text-align: center;
+ width: auto;
+ margin-top: 2px;
+ margin-bottom: 0px;
+ margin-left: 0px;
+ margin-right: 0px;
+ display: none;
+}
+.modal_indicator:before {
+ width: 1.28571429em;
+ text-align: center;
+}
+.edit_mode .modal_indicator:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f040";
+}
+.edit_mode .modal_indicator:before.fa-pull-left {
+ margin-right: .3em;
+}
+.edit_mode .modal_indicator:before.fa-pull-right {
+ margin-left: .3em;
+}
+.edit_mode .modal_indicator:before.pull-left {
+ margin-right: .3em;
+}
+.edit_mode .modal_indicator:before.pull-right {
+ margin-left: .3em;
+}
+.command_mode .modal_indicator:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: ' ';
+}
+.command_mode .modal_indicator:before.fa-pull-left {
+ margin-right: .3em;
+}
+.command_mode .modal_indicator:before.fa-pull-right {
+ margin-left: .3em;
+}
+.command_mode .modal_indicator:before.pull-left {
+ margin-right: .3em;
+}
+.command_mode .modal_indicator:before.pull-right {
+ margin-left: .3em;
+}
+.kernel_idle_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f10c";
+}
+.kernel_idle_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.kernel_idle_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.kernel_idle_icon:before.pull-left {
+ margin-right: .3em;
+}
+.kernel_idle_icon:before.pull-right {
+ margin-left: .3em;
+}
+.kernel_busy_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f111";
+}
+.kernel_busy_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.kernel_busy_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.kernel_busy_icon:before.pull-left {
+ margin-right: .3em;
+}
+.kernel_busy_icon:before.pull-right {
+ margin-left: .3em;
+}
+.kernel_dead_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f1e2";
+}
+.kernel_dead_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.kernel_dead_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.kernel_dead_icon:before.pull-left {
+ margin-right: .3em;
+}
+.kernel_dead_icon:before.pull-right {
+ margin-left: .3em;
+}
+.kernel_disconnected_icon:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f127";
+}
+.kernel_disconnected_icon:before.fa-pull-left {
+ margin-right: .3em;
+}
+.kernel_disconnected_icon:before.fa-pull-right {
+ margin-left: .3em;
+}
+.kernel_disconnected_icon:before.pull-left {
+ margin-right: .3em;
+}
+.kernel_disconnected_icon:before.pull-right {
+ margin-left: .3em;
+}
+.notification_widget {
+ color: #777;
+ z-index: 10;
+ background: rgba(240, 240, 240, 0.5);
+ margin-right: 4px;
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+.notification_widget:focus,
+.notification_widget.focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+.notification_widget:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.notification_widget:active,
+.notification_widget.active,
+.open > .dropdown-toggle.notification_widget {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.notification_widget:active:hover,
+.notification_widget.active:hover,
+.open > .dropdown-toggle.notification_widget:hover,
+.notification_widget:active:focus,
+.notification_widget.active:focus,
+.open > .dropdown-toggle.notification_widget:focus,
+.notification_widget:active.focus,
+.notification_widget.active.focus,
+.open > .dropdown-toggle.notification_widget.focus {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+.notification_widget:active,
+.notification_widget.active,
+.open > .dropdown-toggle.notification_widget {
+ background-image: none;
+}
+.notification_widget.disabled:hover,
+.notification_widget[disabled]:hover,
+fieldset[disabled] .notification_widget:hover,
+.notification_widget.disabled:focus,
+.notification_widget[disabled]:focus,
+fieldset[disabled] .notification_widget:focus,
+.notification_widget.disabled.focus,
+.notification_widget[disabled].focus,
+fieldset[disabled] .notification_widget.focus {
+ background-color: #fff;
+ border-color: #ccc;
+}
+.notification_widget .badge {
+ color: #fff;
+ background-color: #333;
+}
+.notification_widget.warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.notification_widget.warning:focus,
+.notification_widget.warning.focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+.notification_widget.warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.notification_widget.warning:active,
+.notification_widget.warning.active,
+.open > .dropdown-toggle.notification_widget.warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.notification_widget.warning:active:hover,
+.notification_widget.warning.active:hover,
+.open > .dropdown-toggle.notification_widget.warning:hover,
+.notification_widget.warning:active:focus,
+.notification_widget.warning.active:focus,
+.open > .dropdown-toggle.notification_widget.warning:focus,
+.notification_widget.warning:active.focus,
+.notification_widget.warning.active.focus,
+.open > .dropdown-toggle.notification_widget.warning.focus {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+.notification_widget.warning:active,
+.notification_widget.warning.active,
+.open > .dropdown-toggle.notification_widget.warning {
+ background-image: none;
+}
+.notification_widget.warning.disabled:hover,
+.notification_widget.warning[disabled]:hover,
+fieldset[disabled] .notification_widget.warning:hover,
+.notification_widget.warning.disabled:focus,
+.notification_widget.warning[disabled]:focus,
+fieldset[disabled] .notification_widget.warning:focus,
+.notification_widget.warning.disabled.focus,
+.notification_widget.warning[disabled].focus,
+fieldset[disabled] .notification_widget.warning.focus {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.notification_widget.warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+.notification_widget.success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.notification_widget.success:focus,
+.notification_widget.success.focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+.notification_widget.success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.notification_widget.success:active,
+.notification_widget.success.active,
+.open > .dropdown-toggle.notification_widget.success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.notification_widget.success:active:hover,
+.notification_widget.success.active:hover,
+.open > .dropdown-toggle.notification_widget.success:hover,
+.notification_widget.success:active:focus,
+.notification_widget.success.active:focus,
+.open > .dropdown-toggle.notification_widget.success:focus,
+.notification_widget.success:active.focus,
+.notification_widget.success.active.focus,
+.open > .dropdown-toggle.notification_widget.success.focus {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625;
+}
+.notification_widget.success:active,
+.notification_widget.success.active,
+.open > .dropdown-toggle.notification_widget.success {
+ background-image: none;
+}
+.notification_widget.success.disabled:hover,
+.notification_widget.success[disabled]:hover,
+fieldset[disabled] .notification_widget.success:hover,
+.notification_widget.success.disabled:focus,
+.notification_widget.success[disabled]:focus,
+fieldset[disabled] .notification_widget.success:focus,
+.notification_widget.success.disabled.focus,
+.notification_widget.success[disabled].focus,
+fieldset[disabled] .notification_widget.success.focus {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.notification_widget.success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+.notification_widget.info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.notification_widget.info:focus,
+.notification_widget.info.focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+.notification_widget.info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.notification_widget.info:active,
+.notification_widget.info.active,
+.open > .dropdown-toggle.notification_widget.info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.notification_widget.info:active:hover,
+.notification_widget.info.active:hover,
+.open > .dropdown-toggle.notification_widget.info:hover,
+.notification_widget.info:active:focus,
+.notification_widget.info.active:focus,
+.open > .dropdown-toggle.notification_widget.info:focus,
+.notification_widget.info:active.focus,
+.notification_widget.info.active.focus,
+.open > .dropdown-toggle.notification_widget.info.focus {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+.notification_widget.info:active,
+.notification_widget.info.active,
+.open > .dropdown-toggle.notification_widget.info {
+ background-image: none;
+}
+.notification_widget.info.disabled:hover,
+.notification_widget.info[disabled]:hover,
+fieldset[disabled] .notification_widget.info:hover,
+.notification_widget.info.disabled:focus,
+.notification_widget.info[disabled]:focus,
+fieldset[disabled] .notification_widget.info:focus,
+.notification_widget.info.disabled.focus,
+.notification_widget.info[disabled].focus,
+fieldset[disabled] .notification_widget.info.focus {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.notification_widget.info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+.notification_widget.danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.notification_widget.danger:focus,
+.notification_widget.danger.focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+.notification_widget.danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.notification_widget.danger:active,
+.notification_widget.danger.active,
+.open > .dropdown-toggle.notification_widget.danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.notification_widget.danger:active:hover,
+.notification_widget.danger.active:hover,
+.open > .dropdown-toggle.notification_widget.danger:hover,
+.notification_widget.danger:active:focus,
+.notification_widget.danger.active:focus,
+.open > .dropdown-toggle.notification_widget.danger:focus,
+.notification_widget.danger:active.focus,
+.notification_widget.danger.active.focus,
+.open > .dropdown-toggle.notification_widget.danger.focus {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+.notification_widget.danger:active,
+.notification_widget.danger.active,
+.open > .dropdown-toggle.notification_widget.danger {
+ background-image: none;
+}
+.notification_widget.danger.disabled:hover,
+.notification_widget.danger[disabled]:hover,
+fieldset[disabled] .notification_widget.danger:hover,
+.notification_widget.danger.disabled:focus,
+.notification_widget.danger[disabled]:focus,
+fieldset[disabled] .notification_widget.danger:focus,
+.notification_widget.danger.disabled.focus,
+.notification_widget.danger[disabled].focus,
+fieldset[disabled] .notification_widget.danger.focus {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.notification_widget.danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+div#pager {
+ background-color: #fff;
+ font-size: 14px;
+ line-height: 20px;
+ overflow: hidden;
+ display: none;
+ position: fixed;
+ bottom: 0px;
+ width: 100%;
+ max-height: 50%;
+ padding-top: 8px;
+ -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ /* Display over codemirror */
+ z-index: 100;
+ /* Hack which prevents jquery ui resizable from changing top. */
+ top: auto !important;
+}
+div#pager pre {
+ line-height: 1.21429em;
+ color: #000;
+ background-color: #f7f7f7;
+ padding: 0.4em;
+}
+div#pager #pager-button-area {
+ position: absolute;
+ top: 8px;
+ right: 20px;
+}
+div#pager #pager-contents {
+ position: relative;
+ overflow: auto;
+ width: 100%;
+ height: 100%;
+}
+div#pager #pager-contents #pager-container {
+ position: relative;
+ padding: 15px 0px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+div#pager .ui-resizable-handle {
+ top: 0px;
+ height: 8px;
+ background: #f7f7f7;
+ border-top: 1px solid #cfcfcf;
+ border-bottom: 1px solid #cfcfcf;
+ /* This injects handle bars (a short, wide = symbol) for
+ the resize handle. */
+}
+div#pager .ui-resizable-handle::after {
+ content: '';
+ top: 2px;
+ left: 50%;
+ height: 3px;
+ width: 30px;
+ margin-left: -15px;
+ position: absolute;
+ border-top: 1px solid #cfcfcf;
+}
+.quickhelp {
+ /* Old browsers */
+ display: -webkit-box;
+ -webkit-box-orient: horizontal;
+ -webkit-box-align: stretch;
+ display: -moz-box;
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+ display: box;
+ box-orient: horizontal;
+ box-align: stretch;
+ /* Modern browsers */
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+ line-height: 1.8em;
+}
+.shortcut_key {
+ display: inline-block;
+ width: 21ex;
+ text-align: right;
+ font-family: monospace;
+}
+.shortcut_descr {
+ display: inline-block;
+ /* Old browsers */
+ -webkit-box-flex: 1;
+ -moz-box-flex: 1;
+ box-flex: 1;
+ /* Modern browsers */
+ flex: 1;
+}
+span.save_widget {
+ height: 30px;
+ margin-top: 4px;
+ display: flex;
+ justify-content: flex-start;
+ align-items: baseline;
+ width: 50%;
+ flex: 1;
+}
+span.save_widget span.filename {
+ height: 100%;
+ line-height: 1em;
+ margin-left: 16px;
+ border: none;
+ font-size: 146.5%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ border-radius: 2px;
+}
+span.save_widget span.filename:hover {
+ background-color: #e6e6e6;
+}
+[dir="rtl"] span.save_widget.pull-left {
+ float: right !important;
+ float: right;
+}
+[dir="rtl"] span.save_widget span.filename {
+ margin-left: 0;
+ margin-right: 16px;
+}
+span.checkpoint_status,
+span.autosave_status {
+ font-size: small;
+ white-space: nowrap;
+ padding: 0 5px;
+}
+@media (max-width: 767px) {
+ span.save_widget {
+ font-size: small;
+ padding: 0 0 0 5px;
+ }
+ span.checkpoint_status,
+ span.autosave_status {
+ display: none;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ span.checkpoint_status {
+ display: none;
+ }
+ span.autosave_status {
+ font-size: x-small;
+ }
+}
+.toolbar {
+ padding: 0px;
+ margin-left: -5px;
+ margin-top: 2px;
+ margin-bottom: 5px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+.toolbar select,
+.toolbar label {
+ width: auto;
+ vertical-align: middle;
+ margin-right: 2px;
+ margin-bottom: 0px;
+ display: inline;
+ font-size: 92%;
+ margin-left: 0.3em;
+ margin-right: 0.3em;
+ padding: 0px;
+ padding-top: 3px;
+}
+.toolbar .btn {
+ padding: 2px 8px;
+}
+.toolbar .btn-group {
+ margin-top: 0px;
+ margin-left: 5px;
+}
+.toolbar-btn-label {
+ margin-left: 6px;
+}
+#maintoolbar {
+ margin-bottom: -3px;
+ margin-top: -8px;
+ border: 0px;
+ min-height: 27px;
+ margin-left: 0px;
+ padding-top: 11px;
+ padding-bottom: 3px;
+}
+#maintoolbar .navbar-text {
+ float: none;
+ vertical-align: middle;
+ text-align: right;
+ margin-left: 5px;
+ margin-right: 0px;
+ margin-top: 0px;
+}
+.select-xs {
+ height: 24px;
+}
+[dir="rtl"] .btn-group > .btn,
+.btn-group-vertical > .btn {
+ float: right;
+}
+.pulse,
+.dropdown-menu > li > a.pulse,
+li.pulse > a.dropdown-toggle,
+li.pulse.open > a.dropdown-toggle {
+ background-color: #F37626;
+ color: white;
+}
+/**
+ * Primary styles
+ *
+ * Author: Jupyter Development Team
+ */
+/** WARNING IF YOU ARE EDITTING THIS FILE, if this is a .css file, It has a lot
+ * of chance of beeing generated from the ../less/[samename].less file, you can
+ * try to get back the less file by reverting somme commit in history
+ **/
+/*
+ * We'll try to get something pretty, so we
+ * have some strange css to have the scroll bar on
+ * the left with fix button on the top right of the tooltip
+ */
+@-moz-keyframes fadeOut {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+@-webkit-keyframes fadeOut {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+@-moz-keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+@-webkit-keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+/*properties of tooltip after "expand"*/
+.bigtooltip {
+ overflow: auto;
+ height: 200px;
+ -webkit-transition-property: height;
+ -webkit-transition-duration: 500ms;
+ -moz-transition-property: height;
+ -moz-transition-duration: 500ms;
+ transition-property: height;
+ transition-duration: 500ms;
+}
+/*properties of tooltip before "expand"*/
+.smalltooltip {
+ -webkit-transition-property: height;
+ -webkit-transition-duration: 500ms;
+ -moz-transition-property: height;
+ -moz-transition-duration: 500ms;
+ transition-property: height;
+ transition-duration: 500ms;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ height: 80px;
+}
+.tooltipbuttons {
+ position: absolute;
+ padding-right: 15px;
+ top: 0px;
+ right: 0px;
+}
+.tooltiptext {
+ /*avoid the button to overlap on some docstring*/
+ padding-right: 30px;
+}
+.ipython_tooltip {
+ max-width: 700px;
+ /*fade-in animation when inserted*/
+ -webkit-animation: fadeOut 400ms;
+ -moz-animation: fadeOut 400ms;
+ animation: fadeOut 400ms;
+ -webkit-animation: fadeIn 400ms;
+ -moz-animation: fadeIn 400ms;
+ animation: fadeIn 400ms;
+ vertical-align: middle;
+ background-color: #f7f7f7;
+ overflow: visible;
+ border: #ababab 1px solid;
+ outline: none;
+ padding: 3px;
+ margin: 0px;
+ padding-left: 7px;
+ font-family: monospace;
+ min-height: 50px;
+ -moz-box-shadow: 0px 6px 10px -1px #adadad;
+ -webkit-box-shadow: 0px 6px 10px -1px #adadad;
+ box-shadow: 0px 6px 10px -1px #adadad;
+ border-radius: 2px;
+ position: absolute;
+ z-index: 1000;
+}
+.ipython_tooltip a {
+ float: right;
+}
+.ipython_tooltip .tooltiptext pre {
+ border: 0;
+ border-radius: 0;
+ font-size: 100%;
+ background-color: #f7f7f7;
+}
+.pretooltiparrow {
+ left: 0px;
+ margin: 0px;
+ top: -16px;
+ width: 40px;
+ height: 16px;
+ overflow: hidden;
+ position: absolute;
+}
+.pretooltiparrow:before {
+ background-color: #f7f7f7;
+ border: 1px #ababab solid;
+ z-index: 11;
+ content: "";
+ position: absolute;
+ left: 15px;
+ top: 10px;
+ width: 25px;
+ height: 25px;
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+}
+ul.typeahead-list i {
+ margin-left: -10px;
+ width: 18px;
+}
+[dir="rtl"] ul.typeahead-list i {
+ margin-left: 0;
+ margin-right: -10px;
+}
+ul.typeahead-list {
+ max-height: 80vh;
+ overflow: auto;
+}
+ul.typeahead-list > li > a {
+ /** Firefox bug **/
+ /* see https://github.com/jupyter/notebook/issues/559 */
+ white-space: normal;
+}
+ul.typeahead-list > li > a.pull-right {
+ float: left !important;
+ float: left;
+}
+[dir="rtl"] .typeahead-list {
+ text-align: right;
+}
+.cmd-palette .modal-body {
+ padding: 7px;
+}
+.cmd-palette form {
+ background: white;
+}
+.cmd-palette input {
+ outline: none;
+}
+.no-shortcut {
+ min-width: 20px;
+ color: transparent;
+}
+[dir="rtl"] .no-shortcut.pull-right {
+ float: left !important;
+ float: left;
+}
+[dir="rtl"] .command-shortcut.pull-right {
+ float: left !important;
+ float: left;
+}
+.command-shortcut:before {
+ content: "(command mode)";
+ padding-right: 3px;
+ color: #777777;
+}
+.edit-shortcut:before {
+ content: "(edit)";
+ padding-right: 3px;
+ color: #777777;
+}
+[dir="rtl"] .edit-shortcut.pull-right {
+ float: left !important;
+ float: left;
+}
+#find-and-replace #replace-preview .match,
+#find-and-replace #replace-preview .insert {
+ background-color: #BBDEFB;
+ border-color: #90CAF9;
+ border-style: solid;
+ border-width: 1px;
+ border-radius: 0px;
+}
+[dir="ltr"] #find-and-replace .input-group-btn + .form-control {
+ border-left: none;
+}
+[dir="rtl"] #find-and-replace .input-group-btn + .form-control {
+ border-right: none;
+}
+#find-and-replace #replace-preview .replace .match {
+ background-color: #FFCDD2;
+ border-color: #EF9A9A;
+ border-radius: 0px;
+}
+#find-and-replace #replace-preview .replace .insert {
+ background-color: #C8E6C9;
+ border-color: #A5D6A7;
+ border-radius: 0px;
+}
+#find-and-replace #replace-preview {
+ max-height: 60vh;
+ overflow: auto;
+}
+#find-and-replace #replace-preview pre {
+ padding: 5px 10px;
+}
+.terminal-app {
+ background: #EEE;
+}
+.terminal-app #header {
+ background: #fff;
+ -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+ box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
+}
+.terminal-app .terminal {
+ width: 100%;
+ float: left;
+ font-family: monospace;
+ color: white;
+ background: black;
+ padding: 0.4em;
+ border-radius: 2px;
+ -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
+ box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
+}
+.terminal-app .terminal,
+.terminal-app .terminal dummy-screen {
+ line-height: 1em;
+ font-size: 14px;
+}
+.terminal-app .terminal .xterm-rows {
+ padding: 10px;
+}
+.terminal-app .terminal-cursor {
+ color: black;
+ background: white;
+}
+.terminal-app #terminado-container {
+ margin-top: 20px;
+}
+/*# sourceMappingURL=style.min.css.map */
+ </style>
+<style type="text/css">
+ .highlight .hll { background-color: #ffffcc }
+.highlight { background: #f8f8f8; }
+.highlight .c { color: #408080; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #008000; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
+.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #008000 } /* Keyword.Pseudo */
+.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #B00040 } /* Keyword.Type */
+.highlight .m { color: #666666 } /* Literal.Number */
+.highlight .s { color: #BA2121 } /* Literal.String */
+.highlight .na { color: #7D9029 } /* Name.Attribute */
+.highlight .nb { color: #008000 } /* Name.Builtin */
+.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.highlight .no { color: #880000 } /* Name.Constant */
+.highlight .nd { color: #AA22FF } /* Name.Decorator */
+.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #0000FF } /* Name.Function */
+.highlight .nl { color: #A0A000 } /* Name.Label */
+.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #19177C } /* Name.Variable */
+.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mb { color: #666666 } /* Literal.Number.Bin */
+.highlight .mf { color: #666666 } /* Literal.Number.Float */
+.highlight .mh { color: #666666 } /* Literal.Number.Hex */
+.highlight .mi { color: #666666 } /* Literal.Number.Integer */
+.highlight .mo { color: #666666 } /* Literal.Number.Oct */
+.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
+.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
+.highlight .sc { color: #BA2121 } /* Literal.String.Char */
+.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
+.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
+.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
+.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.highlight .sx { color: #008000 } /* Literal.String.Other */
+.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
+.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
+.highlight .ss { color: #19177C } /* Literal.String.Symbol */
+.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #0000FF } /* Name.Function.Magic */
+.highlight .vc { color: #19177C } /* Name.Variable.Class */
+.highlight .vg { color: #19177C } /* Name.Variable.Global */
+.highlight .vi { color: #19177C } /* Name.Variable.Instance */
+.highlight .vm { color: #19177C } /* Name.Variable.Magic */
+.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
+ </style>
+
+
+<style type="text/css">
+/* Overrides of notebook CSS for static HTML export */
+body {
+ overflow: visible;
+ padding: 8px;
+}
+
+div#notebook {
+ overflow: visible;
+ border-top: none;
+}@media print {
+ div.cell {
+ display: block;
+ page-break-inside: avoid;
+ }
+ div.output_wrapper {
+ display: block;
+ page-break-inside: avoid;
+ }
+ div.output {
+ display: block;
+ page-break-inside: avoid;
+ }
+}
+</style>
+
+<!-- Custom stylesheet, it must be in the same directory as the html file -->
+<link rel="stylesheet" href="custom.css">
+
+<!-- Loading mathjax macro -->
+<!-- Load mathjax -->
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS_HTML"></script>
+ <!-- MathJax configuration -->
+ <script type="text/x-mathjax-config">
+ MathJax.Hub.Config({
+ tex2jax: {
+ inlineMath: [ ['$','$'], ["\\(","\\)"] ],
+ displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
+ processEscapes: true,
+ processEnvironments: true
+ },
+ // Center justify equations in code and markdown cells. Elsewhere
+ // we use CSS to left justify single line equations in code cells.
+ displayAlign: 'center',
+ "HTML-CSS": {
+ styles: {'.MathJax_Display': {"margin": 0}},
+ linebreaks: { automatic: true }
+ }
+ });
+ </script>
+ <!-- End of mathjax configuration --></head>
+<body>
+ <div tabindex="-1" id="notebook" class="border-box-sizing">
+ <div class="container" id="notebook-container">
+
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [1]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h1 id="Square-Spiral-Example-Joy-Code">Square Spiral Example Joy Code<a class="anchor-link" href="#Square-Spiral-Example-Joy-Code">¶</a></h1>
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>Here is the example of Joy code from the <code>README</code> file:</p>
+
+<pre><code>[[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+
+</code></pre>
+<p>It might seem unreadable but with a little familiarity it becomes just as
+legible as any other notation. Some layout helps:</p>
+
+<pre><code>[ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+]
+[[ !-] [[++]] [[--]] ifte dip]
+[[pop !-] [--] [++] ifte ]
+ifte
+
+</code></pre>
+<p>This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral).</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h2 id="Original-Form">Original Form<a class="anchor-link" href="#Original-Form">¶</a></h2><p>It's adapted from <a href="https://stackoverflow.com/questions/398299/looping-in-a-spiral/31864777#31864777">the original code on StackOverflow</a>:</p>
+<blockquote><p>If all you're trying to do is generate the first N points in the spiral
+(without the original problem's constraint of masking to an N x M
+region), the code becomes very simple:</p>
+</blockquote>
+
+<pre><code>void spiral(const int N)
+{
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+}</code></pre>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h2 id="Translation-to-Joy">Translation to Joy<a class="anchor-link" href="#Translation-to-Joy">¶</a></h2><p>I'm going to make a function that take two ints (<code>x</code> and <code>y</code>) and
+generates the next pair, we'll turn it into a generator later using the
+<code>x</code> combinator.</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h3 id="First-Boolean-Predicate">First Boolean Predicate<a class="anchor-link" href="#First-Boolean-Predicate">¶</a></h3><p>We need a function that computes <code>abs(x) <= abs(y)</code>, we can use <code>ii</code> to
+apply <code>abs</code> to both values and then compare them
+with <code><=</code>:</p>
+
+<pre><code>[abs] ii <=
+
+</code></pre>
+<p>I've defined two short-circuiting Boolean combinators <code>&&</code> and <code>||</code> that
+each accept two quoted predicate programs, run the first, and
+conditionally run the second only if required (to compute the final
+Boolean value). They run their predicate arguments <code>nullary</code>.</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [2]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'&& [nullary] cons [nullary [0]] dip branch'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'|| [nullary] cons [nullary] dip [1] branch'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>Given those, we can define <code>x != y || x >= 0</code> as:</p>
+
+<pre><code>[<>] [pop 0 >=] ||
+
+</code></pre>
+<p>And <code>(abs(x) <= abs(y) && (x != y || x >= 0))</code> as:</p>
+
+<pre><code>[[abs] ii <=] [[<>] [pop 0 >=] ||] &&
+
+</code></pre>
+<p>It's a little rough, but, as I say, with a little familiarity it becomes
+legible.</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h3 id="The-Increment-/-Decrement-Branches">The Increment / Decrement Branches<a class="anchor-link" href="#The-Increment-/-Decrement-Branches">¶</a></h3><p>Turning to the branches of the main <code>if</code> statement:</p>
+
+<pre><code>x += ((y >= 0) ? 1 : -1);
+
+</code></pre>
+<p>Rewrite as a hybrid (pseudo-code) <code>ifte</code> expression:</p>
+
+<pre><code>[y >= 0] [x += 1] [X -= 1] ifte
+
+</code></pre>
+<p>Change each C phrase to Joy code:</p>
+
+<pre><code>[0 >=] [[++] dip] [[--] dip] ifte
+
+</code></pre>
+<p>Factor out the dip from each branch:</p>
+
+<pre><code>[0 >=] [[++]] [[--]] ifte dip
+
+</code></pre>
+<p>Similar logic applies to the other branch:</p>
+
+<pre><code>y += ((x >= 0) ? -1 : 1);
+
+[x >= 0] [y -= 1] [y += 1] ifte
+
+[pop 0 >=] [--] [++] ifte</code></pre>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h3 id=""Not-Negative"">"Not Negative"<a class="anchor-link" href="#"Not-Negative"">¶</a></h3>
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [3]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'!- 0 >='</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h2 id="Putting-the-Pieces-Together">Putting the Pieces Together<a class="anchor-link" href="#Putting-the-Pieces-Together">¶</a></h2><p>We can assemble the three functions we just defined in quotes and give
+them them to the <code>ifte</code> combinator. With some arrangement to show off
+the symmetry of the two branches, we have:</p>
+
+<pre><code>[[[abs] ii <=] [[<>] [pop !-] ||] &&]
+[[ !-] [[++]] [[--]] ifte dip]
+[[pop !-] [--] [++] ifte ]
+ifte
+
+</code></pre>
+<p>As I was writing this up I realized that, since the <code>&&</code> combinator
+doesn't consume the stack (below its quoted args), I can unquote the
+predicate, swap the branches, and use the <code>branch</code> combinator instead of
+<code>ifte</code>:</p>
+
+<pre><code>[[abs] ii <=] [[<>] [pop !-] ||] &&
+[[pop !-] [--] [++] ifte ]
+[[ !-] [[++]] [[--]] ifte dip]
+branch</code></pre>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [4]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>Let's try it out:</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [5]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 spiral_next'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+ <div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>1 0
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [6]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 0 spiral_next'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+ <div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>1 -1
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [7]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 -1 spiral_next'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+ <div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>0 -1
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [8]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 -1 spiral_next'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+ <div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>-1 -1
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h2 id="Turning-it-into-a-Generator-with-x">Turning it into a Generator with <code>x</code><a class="anchor-link" href="#Turning-it-into-a-Generator-with-x">¶</a></h2><p>It can be used with the x combinator to make a kind of generator for
+spiral square coordinates.</p>
+<p>We can use <code>codireco</code> to make a generator</p>
+
+<pre><code>codireco ::= cons dip rest cons
+
+</code></pre>
+<p>It will look like this:</p>
+
+<pre><code>[value [F] codireco]
+
+</code></pre>
+<p>Here's a trace of how it works:</p>
+
+<pre><code> [0 [dup ++] codireco] . x
+ [0 [dup ++] codireco] . 0 [dup ++] codireco
+ [0 [dup ++] codireco] 0 . [dup ++] codireco
+[0 [dup ++] codireco] 0 [dup ++] . codireco
+[0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
+[0 [dup ++] codireco] [0 dup ++] . dip rest cons
+ . 0 dup ++ [0 [dup ++] codireco] rest cons
+ 0 . dup ++ [0 [dup ++] codireco] rest cons
+ 0 0 . ++ [0 [dup ++] codireco] rest cons
+ 0 1 . [0 [dup ++] codireco] rest cons
+ 0 1 [0 [dup ++] codireco] . rest cons
+ 0 1 [[dup ++] codireco] . cons
+ 0 [1 [dup ++] codireco] . </code></pre>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>But first we have to change the <code>spiral_next</code> function to work on a
+quoted pair of integers, and leave a copy of the pair on the stack.
+From:</p>
+
+<pre><code> y x spiral_next
+---------------------
+ y' x'
+
+</code></pre>
+<p>to:</p>
+
+<pre><code> [x y] [spiral_next] infra
+-------------------------------
+ [x' y']</code></pre>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [9]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 0] [spiral_next] infra'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+ <div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>[0 1]
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>So our generator is:</p>
+
+<pre><code>[[x y] [dup [spiral_next] infra] codireco]
+
+</code></pre>
+<p>Or rather:</p>
+
+<pre><code>[[0 0] [dup [spiral_next] infra] codireco]
+
+</code></pre>
+<p>There is a function <code>make_generator</code> that will build the generator for us
+out of the value and stepper function:</p>
+
+<pre><code> [0 0] [dup [spiral_next] infra] make_generator
+----------------------------------------------------
+ [[0 0] [dup [spiral_next] infra] codireco]</code></pre>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>Here it is in action:</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [10]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 0] [dup [spiral_next] infra] make_generator x x x x pop'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+ <div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>[0 0] [0 1] [-1 1] [-1 0]
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>Four <code>x</code> combinators, four pairs of coordinates.</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div><div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h2 id="Conclusion">Conclusion<a class="anchor-link" href="#Conclusion">¶</a></h2><p>So that's an example of Joy code. It's a straightforward translation of
+the original. It's a little long for a single definition, you might
+break it up like so:</p>
+
+<pre><code> _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+
+ _spn_T ::= [ !-] [[++]] [[--]] ifte dip
+ _spn_E ::= [pop !-] [--] [++] ifte
+
+spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+
+</code></pre>
+<p>This way it's easy to see that the function is a branch with two
+quasi-symmetrical paths.</p>
+<p>We then used this function to make a simple generator of coordinate
+pairs, where the next pair in the series can be generated at any time by
+using the <code>x</code> combinator on the generator (which is just a quoted
+expression containing a copy of the current pair and the "stepper
+function" to generate the next pair from that.)</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [11]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'_spn_T [!-] [[++]] [[--]] ifte dip'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'_spn_E [pop !-] [--] [++] ifte'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'spiral_next _spn_P [_spn_E] [_spn_T] branch'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In [12]:</div>
+<div class="inner_cell">
+ <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'23 18 spiral_next'</span><span class="p">)</span>
+</pre></div>
+
+ </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+ <div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre> . 23 18 spiral_next
+ 23 . 18 spiral_next
+ 23 18 . spiral_next
+ 23 18 . _spn_P [_spn_E] [_spn_T] branch
+ 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
+ 23 18 . 0 [_spn_E] [_spn_T] branch
+ 23 18 0 . [_spn_E] [_spn_T] branch
+ 23 18 0 [_spn_E] . [_spn_T] branch
+ 23 18 0 [_spn_E] [_spn_T] . branch
+ 23 18 . _spn_E
+ 23 18 . [pop !-] [--] [++] ifte
+ 23 18 [pop !-] . [--] [++] ifte
+ 23 18 [pop !-] [--] . [++] ifte
+ 23 18 [pop !-] [--] [++] . ifte
+ 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
+ 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
+ 23 18 [pop !-] . nullary not [--] [++] branch
+ 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
+ 23 18 . stack [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
+ 23 18 . pop !- [18 23] swaack first not [--] [++] branch
+ 23 . !- [18 23] swaack first not [--] [++] branch
+ 23 . 0 >= [18 23] swaack first not [--] [++] branch
+ 23 0 . >= [18 23] swaack first not [--] [++] branch
+ True . [18 23] swaack first not [--] [++] branch
+ True [18 23] . swaack first not [--] [++] branch
+ 23 18 [True] . first not [--] [++] branch
+ 23 18 True . not [--] [++] branch
+ 23 18 False . [--] [++] branch
+ 23 18 False [--] . [++] branch
+ 23 18 False [--] [++] . branch
+ 23 18 . --
+ 23 17 .
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+ </div>
+ </div>
+</body>
+
+
+
+
+</html>
--- /dev/null
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from notebook_preamble import J, V, define"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Square Spiral Example Joy Code"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "Here is the example of Joy code from the `README` file:\n",
+ "\n",
+ " [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte\n",
+ "\n",
+ "It might seem unreadable but with a little familiarity it becomes just as\n",
+ "legible as any other notation. Some layout helps:\n",
+ "\n",
+ " [ [[abs] ii <=]\n",
+ " [\n",
+ " [<>] [pop !-] ||\n",
+ " ] &&\n",
+ " ]\n",
+ " [[ !-] [[++]] [[--]] ifte dip]\n",
+ " [[pop !-] [--] [++] ifte ]\n",
+ " ifte\n",
+ "\n",
+ "This function accepts two integers on the stack and increments or\n",
+ "decrements one of them such that the new pair of numbers is the next\n",
+ "coordinate pair in a square spiral (like the kind used to construct an\n",
+ "Ulam Spiral). \n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Original Form\n",
+ "\n",
+ "It's adapted from [the original code on StackOverflow](https://stackoverflow.com/questions/398299/looping-in-a-spiral/31864777#31864777):\n",
+ "\n",
+ "\n",
+ "> If all you're trying to do is generate the first N points in the spiral\n",
+ "> (without the original problem's constraint of masking to an N x M\n",
+ "> region), the code becomes very simple:\n",
+ "\n",
+ " void spiral(const int N)\n",
+ " {\n",
+ " int x = 0;\n",
+ " int y = 0;\n",
+ " for(int i = 0; i < N; ++i)\n",
+ " {\n",
+ " cout << x << '\\t' << y << '\\n';\n",
+ " if(abs(x) <= abs(y) && (x != y || x >= 0))\n",
+ " x += ((y >= 0) ? 1 : -1);\n",
+ " else\n",
+ " y += ((x >= 0) ? -1 : 1);\n",
+ " }\n",
+ " }"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Translation to Joy\n",
+ "\n",
+ "I'm going to make a function that take two ints (`x` and `y`) and\n",
+ "generates the next pair, we'll turn it into a generator later using the\n",
+ "`x` combinator."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### First Boolean Predicate\n",
+ "\n",
+ "We need a function that computes `abs(x) <= abs(y)`, we can use `ii` to\n",
+ "apply `abs` to both values and then compare them\n",
+ "with `<=`:\n",
+ "\n",
+ " [abs] ii <=\n",
+ "\n",
+ "I've defined two short-circuiting Boolean combinators `&&` and `||` that\n",
+ "each accept two quoted predicate programs, run the first, and\n",
+ "conditionally run the second only if required (to compute the final\n",
+ "Boolean value). They run their predicate arguments `nullary`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "define('&& [nullary] cons [nullary [0]] dip branch')\n",
+ "define('|| [nullary] cons [nullary] dip [1] branch')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Given those, we can define `x != y || x >= 0` as:\n",
+ "\n",
+ " [<>] [pop 0 >=] ||\n",
+ "\n",
+ "And `(abs(x) <= abs(y) && (x != y || x >= 0))` as:\n",
+ "\n",
+ " [[abs] ii <=] [[<>] [pop 0 >=] ||] &&\n",
+ "\n",
+ "It's a little rough, but, as I say, with a little familiarity it becomes\n",
+ "legible."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### The Increment / Decrement Branches\n",
+ "\n",
+ "Turning to the branches of the main `if` statement:\n",
+ "\n",
+ " x += ((y >= 0) ? 1 : -1);\n",
+ "\n",
+ "Rewrite as a hybrid (pseudo-code) `ifte` expression:\n",
+ "\n",
+ " [y >= 0] [x += 1] [X -= 1] ifte\n",
+ "\n",
+ "Change each C phrase to Joy code:\n",
+ "\n",
+ " [0 >=] [[++] dip] [[--] dip] ifte\n",
+ "\n",
+ "Factor out the dip from each branch:\n",
+ "\n",
+ " [0 >=] [[++]] [[--]] ifte dip\n",
+ "\n",
+ "Similar logic applies to the other branch:\n",
+ "\n",
+ " y += ((x >= 0) ? -1 : 1);\n",
+ "\n",
+ " [x >= 0] [y -= 1] [y += 1] ifte\n",
+ "\n",
+ " [pop 0 >=] [--] [++] ifte"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### \"Not Negative\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "define('!- 0 >=')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Putting the Pieces Together\n",
+ "\n",
+ "We can assemble the three functions we just defined in quotes and give\n",
+ "them them to the `ifte` combinator. With some arrangement to show off\n",
+ "the symmetry of the two branches, we have:\n",
+ "\n",
+ " [[[abs] ii <=] [[<>] [pop !-] ||] &&]\n",
+ " [[ !-] [[++]] [[--]] ifte dip]\n",
+ " [[pop !-] [--] [++] ifte ]\n",
+ " ifte\n",
+ "\n",
+ "As I was writing this up I realized that, since the `&&` combinator\n",
+ "doesn't consume the stack (below its quoted args), I can unquote the\n",
+ "predicate, swap the branches, and use the `branch` combinator instead of\n",
+ "`ifte`:\n",
+ "\n",
+ " [[abs] ii <=] [[<>] [pop !-] ||] &&\n",
+ " [[pop !-] [--] [++] ifte ]\n",
+ " [[ !-] [[++]] [[--]] ifte dip]\n",
+ " branch"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Let's try it out:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 0\n"
+ ]
+ }
+ ],
+ "source": [
+ "J('0 0 spiral_next')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 -1\n"
+ ]
+ }
+ ],
+ "source": [
+ "J('1 0 spiral_next')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0 -1\n"
+ ]
+ }
+ ],
+ "source": [
+ "J('1 -1 spiral_next')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-1 -1\n"
+ ]
+ }
+ ],
+ "source": [
+ "J('0 -1 spiral_next')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Turning it into a Generator with `x`\n",
+ "\n",
+ "It can be used with the x combinator to make a kind of generator for\n",
+ "spiral square coordinates.\n",
+ "\n",
+ "\n",
+ "We can use `codireco` to make a generator\n",
+ "\n",
+ " codireco ::= cons dip rest cons\n",
+ "\n",
+ "It will look like this:\n",
+ "\n",
+ " [value [F] codireco]\n",
+ "\n",
+ "Here's a trace of how it works:\n",
+ "\n",
+ " [0 [dup ++] codireco] . x\n",
+ " [0 [dup ++] codireco] . 0 [dup ++] codireco\n",
+ " [0 [dup ++] codireco] 0 . [dup ++] codireco\n",
+ " [0 [dup ++] codireco] 0 [dup ++] . codireco\n",
+ " [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons\n",
+ " [0 [dup ++] codireco] [0 dup ++] . dip rest cons\n",
+ " . 0 dup ++ [0 [dup ++] codireco] rest cons\n",
+ " 0 . dup ++ [0 [dup ++] codireco] rest cons\n",
+ " 0 0 . ++ [0 [dup ++] codireco] rest cons\n",
+ " 0 1 . [0 [dup ++] codireco] rest cons\n",
+ " 0 1 [0 [dup ++] codireco] . rest cons\n",
+ " 0 1 [[dup ++] codireco] . cons\n",
+ " 0 [1 [dup ++] codireco] . "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "But first we have to change the `spiral_next` function to work on a\n",
+ "quoted pair of integers, and leave a copy of the pair on the stack.\n",
+ "From:\n",
+ "\n",
+ " y x spiral_next\n",
+ " ---------------------\n",
+ " y' x'\n",
+ "\n",
+ "to:\n",
+ "\n",
+ " [x y] [spiral_next] infra\n",
+ " -------------------------------\n",
+ " [x' y']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[0 1]\n"
+ ]
+ }
+ ],
+ "source": [
+ "J('[0 0] [spiral_next] infra')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "So our generator is:\n",
+ "\n",
+ " [[x y] [dup [spiral_next] infra] codireco]\n",
+ "\n",
+ "Or rather:\n",
+ "\n",
+ " [[0 0] [dup [spiral_next] infra] codireco]\n",
+ "\n",
+ "There is a function `make_generator` that will build the generator for us\n",
+ "out of the value and stepper function:\n",
+ "\n",
+ " [0 0] [dup [spiral_next] infra] make_generator\n",
+ " ----------------------------------------------------\n",
+ " [[0 0] [dup [spiral_next] infra] codireco]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Here it is in action:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[0 0] [0 1] [-1 1] [-1 0]\n"
+ ]
+ }
+ ],
+ "source": [
+ "J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Four `x` combinators, four pairs of coordinates."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Conclusion\n",
+ "\n",
+ "So that's an example of Joy code. It's a straightforward translation of\n",
+ "the original. It's a little long for a single definition, you might\n",
+ "break it up like so:\n",
+ "\n",
+ " _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&\n",
+ "\n",
+ " _spn_T ::= [ !-] [[++]] [[--]] ifte dip\n",
+ " _spn_E ::= [pop !-] [--] [++] ifte\n",
+ "\n",
+ " spiral_next ::= _spn_P [_spn_E] [_spn_T] branch\n",
+ "\n",
+ "This way it's easy to see that the function is a branch with two\n",
+ "quasi-symmetrical paths.\n",
+ "\n",
+ "We then used this function to make a simple generator of coordinate\n",
+ "pairs, where the next pair in the series can be generated at any time by\n",
+ "using the `x` combinator on the generator (which is just a quoted\n",
+ "expression containing a copy of the current pair and the \"stepper\n",
+ "function\" to generate the next pair from that.)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')\n",
+ "define('_spn_T [!-] [[++]] [[--]] ifte dip')\n",
+ "define('_spn_E [pop !-] [--] [++] ifte')\n",
+ "define('spiral_next _spn_P [_spn_E] [_spn_T] branch')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " . 23 18 spiral_next\n",
+ " 23 . 18 spiral_next\n",
+ " 23 18 . spiral_next\n",
+ " 23 18 . _spn_P [_spn_E] [_spn_T] branch\n",
+ " 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch\n",
+ "23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch\n",
+ " 23 18 . 0 [_spn_E] [_spn_T] branch\n",
+ " 23 18 0 . [_spn_E] [_spn_T] branch\n",
+ " 23 18 0 [_spn_E] . [_spn_T] branch\n",
+ " 23 18 0 [_spn_E] [_spn_T] . branch\n",
+ " 23 18 . _spn_E\n",
+ " 23 18 . [pop !-] [--] [++] ifte\n",
+ " 23 18 [pop !-] . [--] [++] ifte\n",
+ " 23 18 [pop !-] [--] . [++] ifte\n",
+ " 23 18 [pop !-] [--] [++] . ifte\n",
+ " 23 18 [pop !-] [--] [++] . [nullary not] dipd branch\n",
+ " 23 18 [pop !-] [--] [++] [nullary not] . dipd branch\n",
+ " 23 18 [pop !-] . nullary not [--] [++] branch\n",
+ " 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch\n",
+ " 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch\n",
+ " 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch\n",
+ " 23 18 . stack [pop !-] infra first not [--] [++] branch\n",
+ " 23 18 [18 23] . [pop !-] infra first not [--] [++] branch\n",
+ " 23 18 [18 23] [pop !-] . infra first not [--] [++] branch\n",
+ " 23 18 . pop !- [18 23] swaack first not [--] [++] branch\n",
+ " 23 . !- [18 23] swaack first not [--] [++] branch\n",
+ " 23 . 0 >= [18 23] swaack first not [--] [++] branch\n",
+ " 23 0 . >= [18 23] swaack first not [--] [++] branch\n",
+ " True . [18 23] swaack first not [--] [++] branch\n",
+ " True [18 23] . swaack first not [--] [++] branch\n",
+ " 23 18 [True] . first not [--] [++] branch\n",
+ " 23 18 True . not [--] [++] branch\n",
+ " 23 18 False . [--] [++] branch\n",
+ " 23 18 False [--] . [++] branch\n",
+ " 23 18 False [--] [++] . branch\n",
+ " 23 18 . --\n",
+ " 23 17 . \n"
+ ]
+ }
+ ],
+ "source": [
+ "V('23 18 spiral_next')"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
--- /dev/null
+```python
+from notebook_preamble import J, V, define
+```
+
+# Square Spiral Example Joy Code
+
+
+Here is the example of Joy code from the `README` file:
+
+ [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+
+It might seem unreadable but with a little familiarity it becomes just as
+legible as any other notation. Some layout helps:
+
+ [ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+ ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral).
+
+
+
+## Original Form
+
+It's adapted from [the original code on StackOverflow](https://stackoverflow.com/questions/398299/looping-in-a-spiral/31864777#31864777):
+
+
+> If all you're trying to do is generate the first N points in the spiral
+> (without the original problem's constraint of masking to an N x M
+> region), the code becomes very simple:
+
+ void spiral(const int N)
+ {
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+ }
+
+## Translation to Joy
+
+I'm going to make a function that take two ints (`x` and `y`) and
+generates the next pair, we'll turn it into a generator later using the
+`x` combinator.
+
+### First Boolean Predicate
+
+We need a function that computes `abs(x) <= abs(y)`, we can use `ii` to
+apply `abs` to both values and then compare them
+with `<=`:
+
+ [abs] ii <=
+
+I've defined two short-circuiting Boolean combinators `&&` and `||` that
+each accept two quoted predicate programs, run the first, and
+conditionally run the second only if required (to compute the final
+Boolean value). They run their predicate arguments `nullary`.
+
+
+```python
+define('&& [nullary] cons [nullary [0]] dip branch')
+define('|| [nullary] cons [nullary] dip [1] branch')
+```
+
+Given those, we can define `x != y || x >= 0` as:
+
+ [<>] [pop 0 >=] ||
+
+And `(abs(x) <= abs(y) && (x != y || x >= 0))` as:
+
+ [[abs] ii <=] [[<>] [pop 0 >=] ||] &&
+
+It's a little rough, but, as I say, with a little familiarity it becomes
+legible.
+
+### The Increment / Decrement Branches
+
+Turning to the branches of the main `if` statement:
+
+ x += ((y >= 0) ? 1 : -1);
+
+Rewrite as a hybrid (pseudo-code) `ifte` expression:
+
+ [y >= 0] [x += 1] [X -= 1] ifte
+
+Change each C phrase to Joy code:
+
+ [0 >=] [[++] dip] [[--] dip] ifte
+
+Factor out the dip from each branch:
+
+ [0 >=] [[++]] [[--]] ifte dip
+
+Similar logic applies to the other branch:
+
+ y += ((x >= 0) ? -1 : 1);
+
+ [x >= 0] [y -= 1] [y += 1] ifte
+
+ [pop 0 >=] [--] [++] ifte
+
+### "Not Negative"
+
+
+```python
+define('!- 0 >=')
+```
+
+## Putting the Pieces Together
+
+We can assemble the three functions we just defined in quotes and give
+them them to the `ifte` combinator. With some arrangement to show off
+the symmetry of the two branches, we have:
+
+ [[[abs] ii <=] [[<>] [pop !-] ||] &&]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+As I was writing this up I realized that, since the `&&` combinator
+doesn't consume the stack (below its quoted args), I can unquote the
+predicate, swap the branches, and use the `branch` combinator instead of
+`ifte`:
+
+ [[abs] ii <=] [[<>] [pop !-] ||] &&
+ [[pop !-] [--] [++] ifte ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ branch
+
+
+```python
+define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')
+```
+
+Let's try it out:
+
+
+```python
+J('0 0 spiral_next')
+```
+
+ 1 0
+
+
+
+```python
+J('1 0 spiral_next')
+```
+
+ 1 -1
+
+
+
+```python
+J('1 -1 spiral_next')
+```
+
+ 0 -1
+
+
+
+```python
+J('0 -1 spiral_next')
+```
+
+ -1 -1
+
+
+## Turning it into a Generator with `x`
+
+It can be used with the x combinator to make a kind of generator for
+spiral square coordinates.
+
+
+We can use `codireco` to make a generator
+
+ codireco ::= cons dip rest cons
+
+It will look like this:
+
+ [value [F] codireco]
+
+Here's a trace of how it works:
+
+ [0 [dup ++] codireco] . x
+ [0 [dup ++] codireco] . 0 [dup ++] codireco
+ [0 [dup ++] codireco] 0 . [dup ++] codireco
+ [0 [dup ++] codireco] 0 [dup ++] . codireco
+ [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
+ [0 [dup ++] codireco] [0 dup ++] . dip rest cons
+ . 0 dup ++ [0 [dup ++] codireco] rest cons
+ 0 . dup ++ [0 [dup ++] codireco] rest cons
+ 0 0 . ++ [0 [dup ++] codireco] rest cons
+ 0 1 . [0 [dup ++] codireco] rest cons
+ 0 1 [0 [dup ++] codireco] . rest cons
+ 0 1 [[dup ++] codireco] . cons
+ 0 [1 [dup ++] codireco] .
+
+But first we have to change the `spiral_next` function to work on a
+quoted pair of integers, and leave a copy of the pair on the stack.
+From:
+
+ y x spiral_next
+ ---------------------
+ y' x'
+
+to:
+
+ [x y] [spiral_next] infra
+ -------------------------------
+ [x' y']
+
+
+```python
+J('[0 0] [spiral_next] infra')
+```
+
+ [0 1]
+
+
+So our generator is:
+
+ [[x y] [dup [spiral_next] infra] codireco]
+
+Or rather:
+
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+There is a function `make_generator` that will build the generator for us
+out of the value and stepper function:
+
+ [0 0] [dup [spiral_next] infra] make_generator
+ ----------------------------------------------------
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+Here it is in action:
+
+
+```python
+J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')
+```
+
+ [0 0] [0 1] [-1 1] [-1 0]
+
+
+Four `x` combinators, four pairs of coordinates.
+
+## Conclusion
+
+So that's an example of Joy code. It's a straightforward translation of
+the original. It's a little long for a single definition, you might
+break it up like so:
+
+ _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+
+ _spn_T ::= [ !-] [[++]] [[--]] ifte dip
+ _spn_E ::= [pop !-] [--] [++] ifte
+
+ spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+
+This way it's easy to see that the function is a branch with two
+quasi-symmetrical paths.
+
+We then used this function to make a simple generator of coordinate
+pairs, where the next pair in the series can be generated at any time by
+using the `x` combinator on the generator (which is just a quoted
+expression containing a copy of the current pair and the "stepper
+function" to generate the next pair from that.)
+
+
+```python
+define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')
+define('_spn_T [!-] [[++]] [[--]] ifte dip')
+define('_spn_E [pop !-] [--] [++] ifte')
+define('spiral_next _spn_P [_spn_E] [_spn_T] branch')
+```
+
+
+```python
+V('23 18 spiral_next')
+```
+
+ . 23 18 spiral_next
+ 23 . 18 spiral_next
+ 23 18 . spiral_next
+ 23 18 . _spn_P [_spn_E] [_spn_T] branch
+ 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
+ 23 18 . 0 [_spn_E] [_spn_T] branch
+ 23 18 0 . [_spn_E] [_spn_T] branch
+ 23 18 0 [_spn_E] . [_spn_T] branch
+ 23 18 0 [_spn_E] [_spn_T] . branch
+ 23 18 . _spn_E
+ 23 18 . [pop !-] [--] [++] ifte
+ 23 18 [pop !-] . [--] [++] ifte
+ 23 18 [pop !-] [--] . [++] ifte
+ 23 18 [pop !-] [--] [++] . ifte
+ 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
+ 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
+ 23 18 [pop !-] . nullary not [--] [++] branch
+ 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
+ 23 18 . stack [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
+ 23 18 . pop !- [18 23] swaack first not [--] [++] branch
+ 23 . !- [18 23] swaack first not [--] [++] branch
+ 23 . 0 >= [18 23] swaack first not [--] [++] branch
+ 23 0 . >= [18 23] swaack first not [--] [++] branch
+ True . [18 23] swaack first not [--] [++] branch
+ True [18 23] . swaack first not [--] [++] branch
+ 23 18 [True] . first not [--] [++] branch
+ 23 18 True . not [--] [++] branch
+ 23 18 False . [--] [++] branch
+ 23 18 False [--] . [++] branch
+ 23 18 False [--] [++] . branch
+ 23 18 . --
+ 23 17 .
+
--- /dev/null
+.. code:: ipython3
+
+ from notebook_preamble import J, V, define
+
+Square Spiral Example Joy Code
+==============================
+
+Here is the example of Joy code from the ``README`` file:
+
+::
+
+ [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+
+It might seem unreadable but with a little familiarity it becomes just
+as legible as any other notation. Some layout helps:
+
+::
+
+ [ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+ ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral).
+
+Original Form
+-------------
+
+It's adapted from `the original code on
+StackOverflow <https://stackoverflow.com/questions/398299/looping-in-a-spiral/31864777#31864777>`__:
+
+ If all you're trying to do is generate the first N points in the
+ spiral (without the original problem's constraint of masking to an N
+ x M region), the code becomes very simple:
+
+::
+
+ void spiral(const int N)
+ {
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+ }
+
+Translation to Joy
+------------------
+
+I'm going to make a function that take two ints (``x`` and ``y``) and
+generates the next pair, we'll turn it into a generator later using the
+``x`` combinator.
+
+First Boolean Predicate
+~~~~~~~~~~~~~~~~~~~~~~~
+
+We need a function that computes ``abs(x) <= abs(y)``, we can use ``ii``
+to apply ``abs`` to both values and then compare them with ``<=``:
+
+::
+
+ [abs] ii <=
+
+I've defined two short-circuiting Boolean combinators ``&&`` and ``||``
+that each accept two quoted predicate programs, run the first, and
+conditionally run the second only if required (to compute the final
+Boolean value). They run their predicate arguments ``nullary``.
+
+.. code:: ipython3
+
+ define('&& [nullary] cons [nullary [0]] dip branch')
+ define('|| [nullary] cons [nullary] dip [1] branch')
+
+Given those, we can define ``x != y || x >= 0`` as:
+
+::
+
+ [<>] [pop 0 >=] ||
+
+And ``(abs(x) <= abs(y) && (x != y || x >= 0))`` as:
+
+::
+
+ [[abs] ii <=] [[<>] [pop 0 >=] ||] &&
+
+It's a little rough, but, as I say, with a little familiarity it becomes
+legible.
+
+The Increment / Decrement Branches
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Turning to the branches of the main ``if`` statement:
+
+::
+
+ x += ((y >= 0) ? 1 : -1);
+
+Rewrite as a hybrid (pseudo-code) ``ifte`` expression:
+
+::
+
+ [y >= 0] [x += 1] [X -= 1] ifte
+
+Change each C phrase to Joy code:
+
+::
+
+ [0 >=] [[++] dip] [[--] dip] ifte
+
+Factor out the dip from each branch:
+
+::
+
+ [0 >=] [[++]] [[--]] ifte dip
+
+Similar logic applies to the other branch:
+
+::
+
+ y += ((x >= 0) ? -1 : 1);
+
+ [x >= 0] [y -= 1] [y += 1] ifte
+
+ [pop 0 >=] [--] [++] ifte
+
+"Not Negative"
+~~~~~~~~~~~~~~
+
+.. code:: ipython3
+
+ define('!- 0 >=')
+
+Putting the Pieces Together
+---------------------------
+
+We can assemble the three functions we just defined in quotes and give
+them them to the ``ifte`` combinator. With some arrangement to show off
+the symmetry of the two branches, we have:
+
+::
+
+ [[[abs] ii <=] [[<>] [pop !-] ||] &&]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+As I was writing this up I realized that, since the ``&&`` combinator
+doesn't consume the stack (below its quoted args), I can unquote the
+predicate, swap the branches, and use the ``branch`` combinator instead
+of ``ifte``:
+
+::
+
+ [[abs] ii <=] [[<>] [pop !-] ||] &&
+ [[pop !-] [--] [++] ifte ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ branch
+
+.. code:: ipython3
+
+ define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')
+
+Let's try it out:
+
+.. code:: ipython3
+
+ J('0 0 spiral_next')
+
+
+.. parsed-literal::
+
+ 1 0
+
+
+.. code:: ipython3
+
+ J('1 0 spiral_next')
+
+
+.. parsed-literal::
+
+ 1 -1
+
+
+.. code:: ipython3
+
+ J('1 -1 spiral_next')
+
+
+.. parsed-literal::
+
+ 0 -1
+
+
+.. code:: ipython3
+
+ J('0 -1 spiral_next')
+
+
+.. parsed-literal::
+
+ -1 -1
+
+
+Turning it into a Generator with ``x``
+--------------------------------------
+
+It can be used with the x combinator to make a kind of generator for
+spiral square coordinates.
+
+We can use ``codireco`` to make a generator
+
+::
+
+ codireco ::= cons dip rest cons
+
+It will look like this:
+
+::
+
+ [value [F] codireco]
+
+Here's a trace of how it works:
+
+::
+
+ [0 [dup ++] codireco] . x
+ [0 [dup ++] codireco] . 0 [dup ++] codireco
+ [0 [dup ++] codireco] 0 . [dup ++] codireco
+ [0 [dup ++] codireco] 0 [dup ++] . codireco
+ [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
+ [0 [dup ++] codireco] [0 dup ++] . dip rest cons
+ . 0 dup ++ [0 [dup ++] codireco] rest cons
+ 0 . dup ++ [0 [dup ++] codireco] rest cons
+ 0 0 . ++ [0 [dup ++] codireco] rest cons
+ 0 1 . [0 [dup ++] codireco] rest cons
+ 0 1 [0 [dup ++] codireco] . rest cons
+ 0 1 [[dup ++] codireco] . cons
+ 0 [1 [dup ++] codireco] .
+
+But first we have to change the ``spiral_next`` function to work on a
+quoted pair of integers, and leave a copy of the pair on the stack.
+From:
+
+::
+
+ y x spiral_next
+ ---------------------
+ y' x'
+
+to:
+
+::
+
+ [x y] [spiral_next] infra
+ -------------------------------
+ [x' y']
+
+.. code:: ipython3
+
+ J('[0 0] [spiral_next] infra')
+
+
+.. parsed-literal::
+
+ [0 1]
+
+
+So our generator is:
+
+::
+
+ [[x y] [dup [spiral_next] infra] codireco]
+
+Or rather:
+
+::
+
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+There is a function ``make_generator`` that will build the generator for
+us out of the value and stepper function:
+
+::
+
+ [0 0] [dup [spiral_next] infra] make_generator
+ ----------------------------------------------------
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+Here it is in action:
+
+.. code:: ipython3
+
+ J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')
+
+
+.. parsed-literal::
+
+ [0 0] [0 1] [-1 1] [-1 0]
+
+
+Four ``x`` combinators, four pairs of coordinates.
+
+Conclusion
+----------
+
+So that's an example of Joy code. It's a straightforward translation of
+the original. It's a little long for a single definition, you might
+break it up like so:
+
+::
+
+ _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+
+ _spn_T ::= [ !-] [[++]] [[--]] ifte dip
+ _spn_E ::= [pop !-] [--] [++] ifte
+
+ spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+
+This way it's easy to see that the function is a branch with two
+quasi-symmetrical paths.
+
+We then used this function to make a simple generator of coordinate
+pairs, where the next pair in the series can be generated at any time by
+using the ``x`` combinator on the generator (which is just a quoted
+expression containing a copy of the current pair and the "stepper
+function" to generate the next pair from that.)
+
+.. code:: ipython3
+
+ define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')
+ define('_spn_T [!-] [[++]] [[--]] ifte dip')
+ define('_spn_E [pop !-] [--] [++] ifte')
+ define('spiral_next _spn_P [_spn_E] [_spn_T] branch')
+
+.. code:: ipython3
+
+ V('23 18 spiral_next')
+
+
+.. parsed-literal::
+
+ . 23 18 spiral_next
+ 23 . 18 spiral_next
+ 23 18 . spiral_next
+ 23 18 . _spn_P [_spn_E] [_spn_T] branch
+ 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
+ 23 18 . 0 [_spn_E] [_spn_T] branch
+ 23 18 0 . [_spn_E] [_spn_T] branch
+ 23 18 0 [_spn_E] . [_spn_T] branch
+ 23 18 0 [_spn_E] [_spn_T] . branch
+ 23 18 . _spn_E
+ 23 18 . [pop !-] [--] [++] ifte
+ 23 18 [pop !-] . [--] [++] ifte
+ 23 18 [pop !-] [--] . [++] ifte
+ 23 18 [pop !-] [--] [++] . ifte
+ 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
+ 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
+ 23 18 [pop !-] . nullary not [--] [++] branch
+ 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
+ 23 18 . stack [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
+ 23 18 . pop !- [18 23] swaack first not [--] [++] branch
+ 23 . !- [18 23] swaack first not [--] [++] branch
+ 23 . 0 >= [18 23] swaack first not [--] [++] branch
+ 23 0 . >= [18 23] swaack first not [--] [++] branch
+ True . [18 23] swaack first not [--] [++] branch
+ True [18 23] . swaack first not [--] [++] branch
+ 23 18 [True] . first not [--] [++] branch
+ 23 18 True . not [--] [++] branch
+ 23 18 False . [--] [++] branch
+ 23 18 False [--] . [++] branch
+ 23 18 False [--] [++] . branch
+ 23 18 . --
+ 23 17 .
+
.. _Concatinative: https://en.wikipedia.org/wiki/Concatenative_programming_language
+Example Code
+--------------------------------------------------
+
+Here is an example of Joy code::
+
+ [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+
+It might seem unreadable but with a little familiarity it becomes just as
+legible as any other notation. Some layout helps::
+
+ [ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+ ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral). For more information see :doc:`notebooks/Square_Spiral`
+
+
Quick Start
--------------------------------------------------
Implementation
--------------
-.. code:: python
+.. code:: ipython2
from functools import partial as curry
from itertools import product
The empty set and the set of just the empty string.
-.. code:: python
+.. code:: ipython2
phi = frozenset() # ϕ
y = frozenset({''}) # λ
I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
look like ``0`` and ``1`` (zero and one) respectively.
-.. code:: python
+.. code:: ipython2
syms = O, l = frozenset({'0'}), frozenset({'1'})
Where ``R`` and ``S`` stand for *regular expressions*.
-.. code:: python
+.. code:: ipython2
AND, CONS, KSTAR, NOT, OR = 'and cons * not or'.split() # Tags are just strings.
String Representation of RE Datastructures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def stringy(re):
'''
I = (0|1)*
-.. code:: python
+.. code:: ipython2
I = (KSTAR, (OR, O, l))
-.. code:: python
+.. code:: ipython2
print stringy(I)
Note that it contains one of everything.
-.. code:: python
+.. code:: ipython2
a = (CONS, I, (CONS, l, (CONS, l, (CONS, l, I))))
b = (CONS, I, (CONS, O, l))
c = (CONS, l, (KSTAR, l))
it = (AND, a, (NOT, (OR, b, c)))
-.. code:: python
+.. code:: ipython2
print stringy(it)
Let’s get that auxiliary predicate function ``δ`` out of the way.
-.. code:: python
+.. code:: ipython2
def nully(R):
'''
but does waaaay too much work because the expressions grow each
derivation.
-.. code:: python
+.. code:: ipython2
def D(symbol):
Compaction Rules
~~~~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def _compaction_rule(relation, one, zero, a, b):
return (
An elegant symmetry.
-.. code:: python
+.. code:: ipython2
# R ∧ I = I ∧ R = R
# R ∧ ϕ = ϕ ∧ R = ϕ
computed. RE datastructures are immutable and the ``derv()`` functions
are *pure* so this is fine.
-.. code:: python
+.. code:: ipython2
class Memo(object):
This version uses the rules above to perform compaction. It keeps the
expressions from growing too large.
-.. code:: python
+.. code:: ipython2
def D_compaction(symbol):
(FIXME: redo.)
-.. code:: python
+.. code:: ipython2
o, z = D_compaction('0'), D_compaction('1')
REs = set()
Says, “Three or more 1’s and not ending in 01 nor composed of all 1’s.”
-.. figure:: omg.svg
- :alt: State Machine Graph
+.. figure:: attachment:omg.svg
+ :alt: omg.svg
- State Machine Graph
+ omg.svg
Start at ``a`` and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with
in the way that the ``.111.`` on the left-hand side of the ``&``
disappears once it has been matched.
-.. code:: python
+.. code:: ipython2
from collections import defaultdict
from pprint import pprint
from string import ascii_lowercase
-.. code:: python
+.. code:: ipython2
d0, d1 = D_compaction('0'), D_compaction('1')
``explore()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def explore(re):
return table, accepting
-.. code:: python
+.. code:: ipython2
table, accepting = explore(it)
table
-.. code:: python
+.. code:: ipython2
accepting
Once we have the FSM table and the set of accepting states we can
generate the diagram above.
-.. code:: python
+.. code:: ipython2
_template = '''\
digraph finite_state_machine {
)
)
-.. code:: python
+.. code:: ipython2
print make_graph(table, accepting)
Python has no GOTO statement but we can fake it with a “trampoline”
function.
-.. code:: python
+.. code:: ipython2
def trampoline(input_, jump_from, accepting):
I = iter(input_)
Little helpers to process the iterator of our data (a “stream” of “1”
and “0” characters, not bits.)
-.. code:: python
+.. code:: ipython2
getch = lambda I: int(next(I))
branches in assembly and that the state names are branch destination
labels.)
-.. code:: python
+.. code:: ipython2
a = lambda I: c if getch(I) else b
b = lambda I: _0(I) or d
``h = g`` and we could eliminate one in the code but ``h`` is an
accepting state and ``g`` isn’t.
-.. code:: python
+.. code:: ipython2
def acceptable(input_):
return trampoline(input_, a, {h, i})
-.. code:: python
+.. code:: ipython2
for n in range(2**5):
s = bin(n)[2:]
Cf. jp-reprod.html
-.. code:: python
+.. code:: ipython2
from notebook_preamble import J, V, define
Let’s try it:
-.. code:: python
+.. code:: ipython2
V('[0 swap [dup ++] dip rest cons] x')
After one application of ``x`` the quoted program contains ``1`` and
``0`` is below it on the stack.
-.. code:: python
+.. code:: ipython2
J('[0 swap [dup ++] dip rest cons] x x x x x pop')
``direco``
----------
-.. code:: python
+.. code:: ipython2
define('direco == dip rest cons')
-.. code:: python
+.. code:: ipython2
V('[0 swap [dup ++] direco] x')
G == [direco] cons [swap] swap concat cons
G == [direco] cons [swap] swoncat cons
-.. code:: python
+.. code:: ipython2
define('G == [direco] cons [swap] swoncat cons')
Let’s try it out:
-.. code:: python
+.. code:: ipython2
J('0 [dup ++] G')
[0 swap [dup ++] direco]
-.. code:: python
+.. code:: ipython2
J('0 [dup ++] G x x x pop')
Powers of 2
~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
J('1 [dup 1 <<] G x x x x x x x x x pop')
If we have one of these quoted programs we can drive it using ``times``
with the ``x`` combinator.
-.. code:: python
+.. code:: ipython2
J('23 [dup ++] G 5 [x] times')
And pick them off by masking with 3 (binary 11) and then shifting the
int right two bits.
-.. code:: python
+.. code:: ipython2
define('PE1.1 == dup [3 &] dip 2 >>')
-.. code:: python
+.. code:: ipython2
V('14811 PE1.1')
If we plug ``14811`` and ``[PE1.1]`` into our generator form…
-.. code:: python
+.. code:: ipython2
J('14811 [PE1.1] G')
…we get a generator that works for seven cycles before it reaches zero:
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1] direco] 7 [x] times')
We need a function that checks if the int has reached zero and resets it
if so.
-.. code:: python
+.. code:: ipython2
define('PE1.1.check == dup [pop 14811] [] branch')
-.. code:: python
+.. code:: ipython2
J('14811 [PE1.1.check PE1.1] G')
[14811 swap [PE1.1.check PE1.1] direco]
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')
five less than 1000. It’s worked out that we need to use all seven
numbers sixty-six times and then four more.
-.. code:: python
+.. code:: ipython2
J('7 66 * 4 +')
If we drive our generator 466 times and sum the stack we get 999.
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times')
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] direco]
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum')
Project Euler Problem One
-------------------------
-.. code:: python
+.. code:: ipython2
define('PE1.2 == + dup [+] dip')
Now we can add ``PE1.2`` to the quoted program given to ``G``.
-.. code:: python
+.. code:: ipython2
J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
F == + [popdd over] cons infra uncons
fib_gen == [1 1 F]
-.. code:: python
+.. code:: ipython2
define('fib == + [popdd over] cons infra uncons')
-.. code:: python
+.. code:: ipython2
define('fib_gen == [1 1 fib]')
-.. code:: python
+.. code:: ipython2
J('fib_gen 10 [x] times')
function that adds a term in the sequence to a sum if it is even, and
``pop``\ s it otherwise.
-.. code:: python
+.. code:: ipython2
define('PE2.1 == dup 2 % [+] [pop] branch')
And a predicate function that detects when the terms in the series
“exceed four million”.
-.. code:: python
+.. code:: ipython2
define('>4M == 4000000 >')
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.
-.. code:: python
+.. code:: ipython2
define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')
-.. code:: python
+.. code:: ipython2
J('PE2')
Every third term is even.
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] x x x') # To start the sequence with 1 1 2 3 instead of 1 2 3.
Drive the generator three times and ``popop`` the two odd terms.
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] x x x [popop] dipd')
2 [3 2 fib]
-.. code:: python
+.. code:: ipython2
define('PE2.2 == x x x [popop] dipd')
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] 10 [PE2.2] times')
Replace ``x`` with our new driver function ``PE2.2`` and start our
``fib`` generator at ``1 0``.
-.. code:: python
+.. code:: ipython2
J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')
An Interesting Variation
------------------------
-.. code:: python
+.. code:: ipython2
define('codireco == cons dip rest cons')
-.. code:: python
+.. code:: ipython2
V('[0 [dup ++] codireco] x')
0 [1 [dup ++] codireco] .
-.. code:: python
+.. code:: ipython2
define('G == [codireco] cons cons')
-.. code:: python
+.. code:: ipython2
J('230 [dup ++] G 5 [x] times pop')
Cf. `"Why Functional Programming Matters" by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
-.. code:: python
+.. code:: ipython3
from notebook_preamble import J, V, define
1 [23 over / + 2 /] [dup] swoncat make_generator
1 [dup 23 over / + 2 /] make_generator
-.. code:: python
+.. code:: ipython3
define('gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator')
-.. code:: python
+.. code:: ipython3
J('23 gsra')
Let's drive the generator a few time (with the ``x`` combinator) and
square the approximation to see how well it works...
-.. code:: python
+.. code:: ipython3
J('23 gsra 6 [x popd] times first sqr')
abs(a-b) ε <=
(abs(a-b)<=ε)
-.. code:: python
+.. code:: ipython3
define('_within_P [first - abs] dip <=')
[b G] first
b
-.. code:: python
+.. code:: ipython3
define('_within_B roll< popop first')
b [c G] ε within
-.. code:: python
+.. code:: ipython3
define('_within_R [popd x] dip')
[a G] x ε ...
a [b G] ε ...
-.. code:: python
+.. code:: ipython3
define('within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec')
define('sqrt gsra within')
Try it out...
-.. code:: python
+.. code:: ipython3
J('36 sqrt')
6.0
-.. code:: python
+.. code:: ipython3
J('23 sqrt')
Check it.
-.. code:: python
+.. code:: ipython3
4.795831523312719**2
-.. code:: python
+.. code:: ipython3
from math import sqrt
a contingent existence predicated on the disciplined use of these
functions on otherwise undistinguished Joy datastructures.)
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V, define, DefinitionWrapper
Tree-new == swap [[] []] cons cons
-.. code:: python
+.. code:: ipython2
define('Tree-new == swap [[] []] cons cons')
-.. code:: python
+.. code:: ipython2
J('"v" "k" Tree-new')
P < == pop roll> pop first <
P == pop roll> pop first
-.. code:: python
+.. code:: ipython2
define('P == pop roll> pop first')
-.. code:: python
+.. code:: ipython2
J('["old_key" 23 [] []] 17 "new_key" ["..."] P')
T == cons cons [dipdd] cons infra
-.. code:: python
+.. code:: ipython2
define('T == cons cons [dipdd] cons infra')
-.. code:: python
+.. code:: ipython2
J('["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T')
[key_n value_n left right] value key [Tree-add] E
[key_n value_n left right] value key [Tree-add] [P <] [Te] [Ee] ifte
-.. code:: python
+.. code:: ipython2
define('E == [P <] [Te] [Ee] ifte')
Te == cons cons [dipd] cons infra
-.. code:: python
+.. code:: ipython2
define('Te == cons cons [dipd] cons infra')
-.. code:: python
+.. code:: ipython2
J('["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te')
key new_value [ left right] cons cons
[key new_value left right]
-.. code:: python
+.. code:: ipython2
define('Ee == pop swap roll< rest rest cons cons')
-.. code:: python
+.. code:: ipython2
J('["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee')
Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-.. code:: python
+.. code:: ipython2
define('Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec')
Examples
~~~~~~~~
-.. code:: python
+.. code:: ipython2
J('[] 23 "b" Tree-add') # Initial
['b' 23 [] []]
-.. code:: python
+.. code:: ipython2
J('["b" 23 [] []] 88 "c" Tree-add') # Greater than
['b' 23 [] ['c' 88 [] []]]
-.. code:: python
+.. code:: ipython2
J('["b" 23 [] []] 88 "a" Tree-add') # Less than
['b' 23 ['a' 88 [] []] []]
-.. code:: python
+.. code:: ipython2
J('["b" 23 [] []] 88 "b" Tree-add') # Equal to
['b' 88 [] []]
-.. code:: python
+.. code:: ipython2
J('[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add') # Series.
['b' 23 ['a' 88 [] []] ['c' 44 [] []]]
-.. code:: python
+.. code:: ipython2
J('[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step')
------------------------- a < b
L
-.. code:: python
+.. code:: ipython2
J("1 0 ['G'] ['E'] ['L'] cmp")
'G'
-.. code:: python
+.. code:: ipython2
J("1 1 ['G'] ['E'] ['L'] cmp")
'E'
-.. code:: python
+.. code:: ipython2
J("0 1 ['G'] ['E'] ['L'] cmp")
P == over [popop popop first] nullary
-.. code:: python
+.. code:: ipython2
define('P == over [popop popop first] nullary')
Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec
-.. code:: python
+.. code:: ipython2
define('Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec')
-.. code:: python
+.. code:: ipython2
J('[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add') # Still works.
Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
-.. code:: python
+.. code:: ipython2
define('Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec')
Examples
~~~~~~~~
-.. code:: python
+.. code:: ipython2
J('[] [foo] Tree-iter') # It doesn't matter what F is as it won't be used.
-.. code:: python
+.. code:: ipython2
J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter")
'b' 'a' 'c'
-.. code:: python
+.. code:: ipython2
J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter")
`:math:`O(\log_2 N)` <https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2>`__
time.
-.. code:: python
+.. code:: ipython2
J('[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step')
[3 0 [2 0 [] []] [9 0 [5 0 [4 0 [] []] [8 0 [6 0 [] [7 0 [] []]] []]] []]]
-.. code:: python
+.. code:: ipython2
define('to_set == [] swap [0 swap Tree-add] step')
-.. code:: python
+.. code:: ipython2
J('[3 9 5 2 8 6 7 8 4] to_set')
And with that we can write a little program ``unique`` to remove
duplicate items from a list.
-.. code:: python
+.. code:: ipython2
define('unique == [to_set [first] Tree-iter] cons run')
-.. code:: python
+.. code:: ipython2
J('[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique') # Filter duplicate items.
Now we can sort sequences.
-.. code:: python
+.. code:: ipython2
#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')
-.. code:: python
+.. code:: ipython2
J('[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order')
Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
-.. code:: python
+.. code:: ipython2
# I don't want to deal with name conflicts with the above so I'm inlining everything here.
# The original Joy system has "hide" which is a meta-command which allows you to use named
] genrec
''')
-.. code:: python
+.. code:: ipython2
J('["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get')
'mike not in tree'
-.. code:: python
+.. code:: ipython2
J('["gary" 23 [] []] "gary" [popop "err"] Tree-get')
23
-.. code:: python
+.. code:: ipython2
J('''
2
-.. code:: python
+.. code:: ipython2
J('''
By the standards of the code I’ve written so far, this is a *huge* Joy
program.
-.. code:: python
+.. code:: ipython2
DefinitionWrapper.add_definitions('''
first_two == uncons uncons pop
Tree-Delete == [pop not] [pop] [R0] [R1] genrec
''', D)
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete ")
['a' 23 [] ['b' 88 [] []]]
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete ")
['a' 23 [] ['c' 44 [] []]]
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete ")
['b' 88 [] ['c' 44 [] []]]
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete ")
['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]
-.. code:: python
+.. code:: ipython2
J('[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step')
[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]]
-.. code:: python
+.. code:: ipython2
J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete ")
[4 0 [2 0 [1 0 [] []] []] [6 0 [5 0 [] []] [7 0 [] []]]]
-.. code:: python
+.. code:: ipython2
J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete ")
-.. code:: python
+.. code:: ipython2
from notebook_preamble import J, V, define
The three arguments are to the left, so we can “chop off” everything to
the right and say it’s the definition of the ``quadratic`` function:
-.. code:: python
+.. code:: ipython2
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
Let’s try it out:
-.. code:: python
+.. code:: ipython2
J('3 1 1 quadratic')
by incorporating the values on the stack. Then that program runs and you
get the results. This is pretty typical of Joy code.
-.. code:: python
+.. code:: ipython2
V('-5 1 4 quadratic')
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, DefinitionWrapper, J, V, define
It may be helpful to see this function implemented in imperative Python
code.
-.. code:: python
+.. code:: ipython2
def hylomorphism(c, F, P, G):
'''Return a hylomorphism function H.'''
hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
-.. code:: python
+.. code:: ipython2
define('hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec')
- ``[G]`` is ``[-- dup]``
- ``[F]`` is ``[+]``
-.. code:: python
+.. code:: ipython2
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
Let’s try it:
-.. code:: python
+.. code:: ipython2
J('5 triangular_number')
10
-.. code:: python
+.. code:: ipython2
J('[0 1 2 3 4 5 6] [triangular_number] map')
A == [P] [] [G] [swons] hylomorphism
-``range`` et. al.
-~~~~~~~~~~~~~~~~~
-
-An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
+``range`` et. al. An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each of the above variations can be used to make four slightly different
``range`` functions.
H1 == [P] [pop c] [G] [dip F] genrec
== [0 <=] [pop []] [-- dup] [dip swons] genrec
-.. code:: python
+.. code:: ipython2
define('range == [0 <=] [] [-- dup] [swons] hylomorphism')
-.. code:: python
+.. code:: ipython2
J('5 range')
H2 == c swap [P] [pop] [G [F] dip] primrec
== [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
-.. code:: python
+.. code:: ipython2
define('range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec')
-.. code:: python
+.. code:: ipython2
J('5 range_reverse')
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
== [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
-.. code:: python
+.. code:: ipython2
define('ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec')
-.. code:: python
+.. code:: ipython2
J('5 ranger')
H4 == c swap [P] [pop] [[F] dupdip G ] primrec
== [] swap [0 <=] [pop] [[swons] dupdip --] primrec
-.. code:: python
+.. code:: ipython2
define('ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec')
-.. code:: python
+.. code:: ipython2
J('5 ranger_reverse')
C == [not] c [uncons swap] [F] hylomorphism
-.. code:: python
+.. code:: ipython2
define('swuncons == uncons swap') # Awkward name.
sum == [not] 0 [swuncons] [+] hylomorphism
-.. code:: python
+.. code:: ipython2
define('sum == [not] 0 [swuncons] [+] hylomorphism')
-.. code:: python
+.. code:: ipython2
J('[5 4 3 2 1] sum')
The ``step`` combinator will usually be better to use than
``catamorphism``.
-.. code:: python
+.. code:: ipython2
J('[step] help')
-.. code:: python
+.. code:: ipython2
define('sum == 0 swap [+] step')
-.. code:: python
+.. code:: ipython2
J('[5 4 3 2 1] sum')
G == --
P == 1 <=
-.. code:: python
+.. code:: ipython2
define('factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec')
-.. code:: python
+.. code:: ipython2
J('5 factorial')
G == rest dup
P == not
-.. code:: python
+.. code:: ipython2
define('tails == [] swap [not] [pop] [rest dup [swons] dip] primrec')
-.. code:: python
+.. code:: ipython2
J('[1 2 3] tails')
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V
A long trace
------------
-.. code:: python
+.. code:: ipython2
V('[23 18] average')
``size`` we can use a “compiled” version hand-written in Python to speed
up evaluation and make the trace more readable.
-.. code:: python
+.. code:: ipython2
from joy.library import SimpleFunctionWrapper
from joy.utils.stack import iter_stack
Now we replace the old version in the dictionary with the new version,
and re-evaluate the expression.
-.. code:: python
+.. code:: ipython2
D['size'] = size
You can see that ``size`` now executes in a single step.
-.. code:: python
+.. code:: ipython2
V('[23 18] average')
--- /dev/null
+.. code:: ipython3
+
+ from notebook_preamble import J, V, define
+
+Square Spiral Example Joy Code
+==============================
+
+Here is the example of Joy code from the ``README`` file:
+
+::
+
+ [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+
+It might seem unreadable but with a little familiarity it becomes just
+as legible as any other notation. Some layout helps:
+
+::
+
+ [ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+ ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral).
+
+Original Form
+-------------
+
+It's adapted from `the original code on
+StackOverflow <https://stackoverflow.com/questions/398299/looping-in-a-spiral/31864777#31864777>`__:
+
+ If all you're trying to do is generate the first N points in the
+ spiral (without the original problem's constraint of masking to an N
+ x M region), the code becomes very simple:
+
+::
+
+ void spiral(const int N)
+ {
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+ }
+
+Translation to Joy
+------------------
+
+I'm going to make a function that take two ints (``x`` and ``y``) and
+generates the next pair, we'll turn it into a generator later using the
+``x`` combinator.
+
+First Boolean Predicate
+~~~~~~~~~~~~~~~~~~~~~~~
+
+We need a function that computes ``abs(x) <= abs(y)``, we can use ``ii``
+to apply ``abs`` to both values and then compare them with ``<=``:
+
+::
+
+ [abs] ii <=
+
+I've defined two short-circuiting Boolean combinators ``&&`` and ``||``
+that each accept two quoted predicate programs, run the first, and
+conditionally run the second only if required (to compute the final
+Boolean value). They run their predicate arguments ``nullary``.
+
+.. code:: ipython3
+
+ define('&& [nullary] cons [nullary [0]] dip branch')
+ define('|| [nullary] cons [nullary] dip [1] branch')
+
+Given those, we can define ``x != y || x >= 0`` as:
+
+::
+
+ [<>] [pop 0 >=] ||
+
+And ``(abs(x) <= abs(y) && (x != y || x >= 0))`` as:
+
+::
+
+ [[abs] ii <=] [[<>] [pop 0 >=] ||] &&
+
+It's a little rough, but, as I say, with a little familiarity it becomes
+legible.
+
+The Increment / Decrement Branches
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Turning to the branches of the main ``if`` statement:
+
+::
+
+ x += ((y >= 0) ? 1 : -1);
+
+Rewrite as a hybrid (pseudo-code) ``ifte`` expression:
+
+::
+
+ [y >= 0] [x += 1] [X -= 1] ifte
+
+Change each C phrase to Joy code:
+
+::
+
+ [0 >=] [[++] dip] [[--] dip] ifte
+
+Factor out the dip from each branch:
+
+::
+
+ [0 >=] [[++]] [[--]] ifte dip
+
+Similar logic applies to the other branch:
+
+::
+
+ y += ((x >= 0) ? -1 : 1);
+
+ [x >= 0] [y -= 1] [y += 1] ifte
+
+ [pop 0 >=] [--] [++] ifte
+
+"Not Negative"
+~~~~~~~~~~~~~~
+
+.. code:: ipython3
+
+ define('!- 0 >=')
+
+Putting the Pieces Together
+---------------------------
+
+We can assemble the three functions we just defined in quotes and give
+them them to the ``ifte`` combinator. With some arrangement to show off
+the symmetry of the two branches, we have:
+
+::
+
+ [[[abs] ii <=] [[<>] [pop !-] ||] &&]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+As I was writing this up I realized that, since the ``&&`` combinator
+doesn't consume the stack (below its quoted args), I can unquote the
+predicate, swap the branches, and use the ``branch`` combinator instead
+of ``ifte``:
+
+::
+
+ [[abs] ii <=] [[<>] [pop !-] ||] &&
+ [[pop !-] [--] [++] ifte ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ branch
+
+.. code:: ipython3
+
+ define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')
+
+Let's try it out:
+
+.. code:: ipython3
+
+ J('0 0 spiral_next')
+
+
+.. parsed-literal::
+
+ 1 0
+
+
+.. code:: ipython3
+
+ J('1 0 spiral_next')
+
+
+.. parsed-literal::
+
+ 1 -1
+
+
+.. code:: ipython3
+
+ J('1 -1 spiral_next')
+
+
+.. parsed-literal::
+
+ 0 -1
+
+
+.. code:: ipython3
+
+ J('0 -1 spiral_next')
+
+
+.. parsed-literal::
+
+ -1 -1
+
+
+Turning it into a Generator with ``x``
+--------------------------------------
+
+It can be used with the x combinator to make a kind of generator for
+spiral square coordinates.
+
+We can use ``codireco`` to make a generator
+
+::
+
+ codireco ::= cons dip rest cons
+
+It will look like this:
+
+::
+
+ [value [F] codireco]
+
+Here's a trace of how it works:
+
+::
+
+ [0 [dup ++] codireco] . x
+ [0 [dup ++] codireco] . 0 [dup ++] codireco
+ [0 [dup ++] codireco] 0 . [dup ++] codireco
+ [0 [dup ++] codireco] 0 [dup ++] . codireco
+ [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
+ [0 [dup ++] codireco] [0 dup ++] . dip rest cons
+ . 0 dup ++ [0 [dup ++] codireco] rest cons
+ 0 . dup ++ [0 [dup ++] codireco] rest cons
+ 0 0 . ++ [0 [dup ++] codireco] rest cons
+ 0 1 . [0 [dup ++] codireco] rest cons
+ 0 1 [0 [dup ++] codireco] . rest cons
+ 0 1 [[dup ++] codireco] . cons
+ 0 [1 [dup ++] codireco] .
+
+But first we have to change the ``spiral_next`` function to work on a
+quoted pair of integers, and leave a copy of the pair on the stack.
+From:
+
+::
+
+ y x spiral_next
+ ---------------------
+ y' x'
+
+to:
+
+::
+
+ [x y] [spiral_next] infra
+ -------------------------------
+ [x' y']
+
+.. code:: ipython3
+
+ J('[0 0] [spiral_next] infra')
+
+
+.. parsed-literal::
+
+ [0 1]
+
+
+So our generator is:
+
+::
+
+ [[x y] [dup [spiral_next] infra] codireco]
+
+Or rather:
+
+::
+
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+There is a function ``make_generator`` that will build the generator for
+us out of the value and stepper function:
+
+::
+
+ [0 0] [dup [spiral_next] infra] make_generator
+ ----------------------------------------------------
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+Here it is in action:
+
+.. code:: ipython3
+
+ J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')
+
+
+.. parsed-literal::
+
+ [0 0] [0 1] [-1 1] [-1 0]
+
+
+Four ``x`` combinators, four pairs of coordinates.
+
+Conclusion
+----------
+
+So that's an example of Joy code. It's a straightforward translation of
+the original. It's a little long for a single definition, you might
+break it up like so:
+
+::
+
+ _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+
+ _spn_T ::= [ !-] [[++]] [[--]] ifte dip
+ _spn_E ::= [pop !-] [--] [++] ifte
+
+ spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+
+This way it's easy to see that the function is a branch with two
+quasi-symmetrical paths.
+
+We then used this function to make a simple generator of coordinate
+pairs, where the next pair in the series can be generated at any time by
+using the ``x`` combinator on the generator (which is just a quoted
+expression containing a copy of the current pair and the "stepper
+function" to generate the next pair from that.)
+
+.. code:: ipython3
+
+ define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')
+ define('_spn_T [!-] [[++]] [[--]] ifte dip')
+ define('_spn_E [pop !-] [--] [++] ifte')
+ define('spiral_next _spn_P [_spn_E] [_spn_T] branch')
+
+.. code:: ipython3
+
+ V('23 18 spiral_next')
+
+
+.. parsed-literal::
+
+ . 23 18 spiral_next
+ 23 . 18 spiral_next
+ 23 18 . spiral_next
+ 23 18 . _spn_P [_spn_E] [_spn_T] branch
+ 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
+ 23 18 . 0 [_spn_E] [_spn_T] branch
+ 23 18 0 . [_spn_E] [_spn_T] branch
+ 23 18 0 [_spn_E] . [_spn_T] branch
+ 23 18 0 [_spn_E] [_spn_T] . branch
+ 23 18 . _spn_E
+ 23 18 . [pop !-] [--] [++] ifte
+ 23 18 [pop !-] . [--] [++] ifte
+ 23 18 [pop !-] [--] . [++] ifte
+ 23 18 [pop !-] [--] [++] . ifte
+ 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
+ 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
+ 23 18 [pop !-] . nullary not [--] [++] branch
+ 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
+ 23 18 . stack [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
+ 23 18 . pop !- [18 23] swaack first not [--] [++] branch
+ 23 . !- [18 23] swaack first not [--] [++] branch
+ 23 . 0 >= [18 23] swaack first not [--] [++] branch
+ 23 0 . >= [18 23] swaack first not [--] [++] branch
+ True . [18 23] swaack first not [--] [++] branch
+ True [18 23] . swaack first not [--] [++] branch
+ 23 18 [True] . first not [--] [++] branch
+ 23 18 True . not [--] [++] branch
+ 23 18 False . [--] [++] branch
+ 23 18 False [--] . [++] branch
+ 23 18 False [--] [++] . branch
+ 23 18 . --
+ 23 17 .
+
Define ``treestep``
-------------------
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V, define, DefinitionWrapper
-.. code:: python
+.. code:: ipython2
DefinitionWrapper.add_definitions('''
sumtree == [pop 0] [] [sum +] treestep
-.. code:: python
+.. code:: ipython2
define('sumtree == [pop 0] [] [sum +] treestep')
------------------------------------
0
-.. code:: python
+.. code:: ipython2
J('[] sumtree') # Empty tree.
n m +
n+m
-.. code:: python
+.. code:: ipython2
J('[23] sumtree') # No child trees.
23
-.. code:: python
+.. code:: ipython2
J('[23 []] sumtree') # Child tree, empty.
23
-.. code:: python
+.. code:: ipython2
J('[23 [2 [4]] [3]] sumtree') # Non-empty child trees.
32
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] sumtree') # Etc...
49
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep') # Alternate "spelling".
49
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep') # Replace each node.
[23 [23 [23] [23]] [23] [23 []]]
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep')
[1 [1 [1] [1]] [1] [1 []]]
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree')
6
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep') # Combine replace and sum into one function.
6
-.. code:: python
+.. code:: ipython2
J('[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep') # Combine replace and sum into one function.
This doesn’t quite work:
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep')
[] [first] [flatten cons] treestep
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep')
[] [i roll< swons concat] [first] treestep
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep')
[key value] N [left right] [K] C
-.. code:: python
+.. code:: ipython2
J('[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind')
Iteration through the nodes
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind')
Sum the nodes’ keys.
-.. code:: python
+.. code:: ipython2
J('0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind')
Rebuild the tree using ``map`` (imitating ``treestep``.)
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind')
To me, that seems simpler than the ``genrec`` version.
-.. code:: python
+.. code:: ipython2
DefinitionWrapper.add_definitions('''
''', D)
-.. code:: python
+.. code:: ipython2
J('''\
15
-.. code:: python
+.. code:: ipython2
J('''\
Type Checking
=============
-.. code:: python
+.. code:: ipython2
import logging, sys
level=logging.INFO,
)
-.. code:: python
+.. code:: ipython2
from joy.utils.types import (
doc_from_stack_effect,
JoyTypeError,
)
-.. code:: python
+.. code:: ipython2
D = FUNCTIONS.copy()
del D['product']
An Example
----------
-.. code:: python
+.. code:: ipython2
fi, fo = infer(pop, swap, rolldown, rrest, ccons)[0]
40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(fi, fo)
([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1])
-.. code:: python
+.. code:: ipython2
from joy.parser import text_to_expression
from joy.utils.stack import stack_to_string
-.. code:: python
+.. code:: ipython2
e = text_to_expression('0 1 2 [3 4]') # reverse order
print stack_to_string(e)
[3 4] 2 1 0
-.. code:: python
+.. code:: ipython2
u = unify(e, fi)[0]
u
-.. code:: python
+.. code:: ipython2
g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
Unification Works “in Reverse”
------------------------------
-.. code:: python
+.. code:: ipython2
e = text_to_expression('[2 3]')
-.. code:: python
+.. code:: ipython2
u = unify(e, fo)[0] # output side, not input side
u
-.. code:: python
+.. code:: ipython2
g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
Failing a Check
---------------
-.. code:: python
+.. code:: ipython2
fi, fo = infer(dup, mul)[0]
31 (i1 -- i2) ∘
-.. code:: python
+.. code:: ipython2
e = text_to_expression('"two"')
print stack_to_string(e)
'two'
-.. code:: python
+.. code:: ipython2
try:
unify(e, fi)
The simplest way to “compile” this function would be something like:
-.. code:: python
+.. code:: ipython2
def poswrd(s, e, d):
return rolldown(*swap(*pop(s, e, d)))
We should be able to directly write out a Python function like:
-.. code:: python
+.. code:: ipython2
def poswrd(stack):
(_, (a, (b, (c, stack)))) = stack
From this stack effect comment it should be possible to construct the
following Python code:
-.. code:: python
+.. code:: ipython2
def F(stack):
(_, (d, (c, ((a, (b, S0)), stack)))) = stack
I’m going to use pairs of tuples of type descriptors, which will be
integers or tuples of type descriptors:
-.. code:: python
+.. code:: ipython2
roll_dn = (1, 2, 3), (2, 3, 1)
``compose()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def compose(f, g):
``unify()``
~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
``update()``
~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def update(s, term):
if not isinstance(term, tuple):
``relabel()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def relabel(left, right):
return left, _1000(right)
``delabel()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def delabel(f):
s = {u: i for i, u in enumerate(sorted(_unique(f)))}
stack effect comments and returns their composition (or raises and
exception if they can’t be composed due to type conflicts.)
-.. code:: python
+.. code:: ipython2
def C(f, g):
f, g = relabel(f, g)
Let’s try it out.
-.. code:: python
+.. code:: ipython2
C(pop, swap)
-.. code:: python
+.. code:: ipython2
C(C(pop, swap), roll_dn)
-.. code:: python
+.. code:: ipython2
C(swap, roll_dn)
-.. code:: python
+.. code:: ipython2
C(pop, C(swap, roll_dn))
-.. code:: python
+.. code:: ipython2
poswrd = reduce(C, (pop, swap, roll_dn))
poswrd
manipulate stacks. We use a cons-list of tuples and give the tails their
own numbers. Then everything above already works.
-.. code:: python
+.. code:: ipython2
rest = ((1, 2),), (2,)
cons = (1, 2), ((1, 2),)
-.. code:: python
+.. code:: ipython2
C(poswrd, rest)
0: 0,
}
-.. code:: python
+.. code:: ipython2
F = reduce(C, (pop, swap, roll_dn, rest, rest, cons, cons))
However, if we try to compose e.g. ``cons`` and ``uncons`` it won’t
work:
-.. code:: python
+.. code:: ipython2
uncons = ((1, 2),), (1, 2)
-.. code:: python
+.. code:: ipython2
try:
C(cons, uncons)
the case when both terms are tuples. We just have to add a clause to
deal with this recursively:
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
return s
-.. code:: python
+.. code:: ipython2
C(cons, uncons)
Now consider the Python function we would like to derive:
-.. code:: python
+.. code:: ipython2
def F_python(stack):
(_, (d, (c, ((a, (b, S0)), stack)))) = stack
And compare it to the input stack effect comment tuple we just computed:
-.. code:: python
+.. code:: ipython2
F[0]
And the return tuple
-.. code:: python
+.. code:: ipython2
F[1]
We want to substitute Python identifiers for the integers. I’m going to
repurpose ``joy.parser.Symbol`` class for this:
-.. code:: python
+.. code:: ipython2
from collections import defaultdict
from joy.parser import Symbol
in how this code works that related to stuff later in the notebook, so
you should skip it for now and read it later if you’re interested.
-.. code:: python
+.. code:: ipython2
def doc_from_stack_effect(inputs, outputs):
return '(%s--%s)' % (
underscore suffix distiguishes it from the built-in ``compile()``
function.)
-.. code:: python
+.. code:: ipython2
def compile_(name, f, doc=None):
if doc is None:
Here it is in action:
-.. code:: python
+.. code:: ipython2
source = compile_('F', F)
Compare:
-.. code:: python
+.. code:: ipython2
def F_python(stack):
(_, (d, (c, ((a, (b, S0)), stack)))) = stack
Next steps:
-.. code:: python
+.. code:: ipython2
L = {}
Let’s try it out:
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V
from joy.library import SimpleFunctionWrapper
-.. code:: python
+.. code:: ipython2
D['F'] = SimpleFunctionWrapper(L['F'])
-.. code:: python
+.. code:: ipython2
J('[4 5 ...] 2 3 1 F')
We can use ``compile_()`` to generate many primitives in the library
from their stack effect comments:
-.. code:: python
+.. code:: ipython2
def defs():
return locals()
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(defs().items()):
print
to establish domain ordering, as well as other handy behaviour that will
make it fairly easy to reuse most of the code above.
-.. code:: python
+.. code:: ipython2
class AnyJoyType(object):
Mess with it a little:
-.. code:: python
+.. code:: ipython2
from itertools import permutations
“Any” types can be specialized to numbers and stacks, but not vice
versa:
-.. code:: python
+.. code:: ipython2
for a, b in permutations((A[0], N[0], S[0]), 2):
print a, '>=', b, '->', a >= b
Tower <https://en.wikipedia.org/wiki/Numerical_tower>`__ of *numbers* >
*floats* > *integers* works as well (but we’re not going to use it yet):
-.. code:: python
+.. code:: ipython2
for a, b in permutations((A[0], N[0], FloatJoyType(0), IntJoyType(0)), 2):
print a, '>=', b, '->', a >= b
Typing ``sqr``
~~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
dup = (A[1],), (A[1], A[1])
mul = (N[1], N[2]), (N[3],)
-.. code:: python
+.. code:: ipython2
dup
-.. code:: python
+.. code:: ipython2
mul
Re-labeling still works fine:
-.. code:: python
+.. code:: ipython2
foo = relabel(dup, mul)
The ``delabel()`` function needs an overhaul. It now has to keep track
of how many labels of each domain it has “seen”.
-.. code:: python
+.. code:: ipython2
from collections import Counter
return tuple(delabel(inner, seen, c) for inner in f)
-.. code:: python
+.. code:: ipython2
delabel(foo)
``unify()`` version 3
^^^^^^^^^^^^^^^^^^^^^
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
Rewrite the stack effect comments:
-.. code:: python
+.. code:: ipython2
def defs():
return locals()
-.. code:: python
+.. code:: ipython2
DEFS = defs()
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(DEFS.items()):
print name, '=', doc_from_stack_effect(*stack_effect_comment)
uncons = ([a1 .1.] -- a1 [.1.])
-.. code:: python
+.. code:: ipython2
globals().update(DEFS)
Compose ``dup`` and ``mul``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code:: python
+.. code:: ipython2
C(dup, mul)
Revisit the ``F`` function, works fine.
-.. code:: python
+.. code:: ipython2
F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
F
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*F)
Some otherwise inefficient functions are no longer to be feared. We can
also get the effect of combinators in some limited cases.
-.. code:: python
+.. code:: ipython2
def neato(*funcs):
print doc_from_stack_effect(*reduce(C, funcs))
-.. code:: python
+.. code:: ipython2
# e.g. [swap] dip
neato(rollup, swap, rolldown)
(a1 a2 a3 -- a2 a1 a3)
-.. code:: python
+.. code:: ipython2
# e.g. [popop] dipd
neato(popdd, rolldown, pop)
(a1 a2 a3 a4 -- a3 a4)
-.. code:: python
+.. code:: ipython2
# Reverse the order of the top three items.
neato(rollup, swap)
Because the type labels represent themselves as valid Python identifiers
the ``compile_()`` function doesn’t need to generate them anymore:
-.. code:: python
+.. code:: ipython2
def compile_(name, f, doc=None):
inputs, outputs = f
%s = stack
return %s''' % (name, doc, i, o)
-.. code:: python
+.. code:: ipython2
print compile_('F', F)
But it cannot magically create new functions that involve e.g. math and
such. Note that this is *not* a ``sqr`` function implementation:
-.. code:: python
+.. code:: ipython2
print compile_('sqr', C(dup, mul))
``AnyJoyType`` and ``StackJoyType`` labels in their stack effect
comments. We can write a function to check that:
-.. code:: python
+.. code:: ipython2
from itertools import imap
def compilable(f):
return isinstance(f, tuple) and all(imap(compilable, f)) or stacky(f)
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(defs().items()):
if compilable(stack_effect_comment):
``joy.utils.stack.concat`` work with our stack effect comment cons-list
tuples.)
-.. code:: python
+.. code:: ipython2
def compose(f, g):
(f_in, f_out), (g_in, g_out) = f, g
I don’t want to rewrite all the defs myself, so I’ll write a little
conversion function instead. This is programmer’s laziness.
-.. code:: python
+.. code:: ipython2
def sequence_to_stack(seq, stack=StackJoyType(23)):
for item in seq: stack = item, stack
NEW_DEFS['swaack'] = (S[1], S[0]), (S[0], S[1])
globals().update(NEW_DEFS)
-.. code:: python
+.. code:: ipython2
C(stack, uncons)
-.. code:: python
+.. code:: ipython2
reduce(C, (stack, uncons, uncons))
Clunky junk, but it will suffice for now.
-.. code:: python
+.. code:: ipython2
def doc_from_stack_effect(inputs, outputs):
switch = [False] # Do we need to display the '...' for the rest of the main stack?
a.append(end)
return '[%s]' % ' '.join(a)
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(NEW_DEFS.items()):
print name, '=', doc_from_stack_effect(*stack_effect_comment)
uncons = ([a1 .1.] -- a1 [.1.])
-.. code:: python
+.. code:: ipython2
print ; print doc_from_stack_effect(*stack)
print ; print doc_from_stack_effect(*C(stack, uncons))
(... a1 -- ... a1 [a1 ...])
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*C(ccons, stack))
(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
-.. code:: python
+.. code:: ipython2
Q = C(ccons, stack)
This makes the ``compile_()`` function pretty simple as the stack effect
comments are now already in the form needed for the Python code:
-.. code:: python
+.. code:: ipython2
def compile_(name, f, doc=None):
i, o = f
%s = stack
return %s''' % (name, doc, i, o)
-.. code:: python
+.. code:: ipython2
print compile_('Q', Q)
-.. code:: python
+.. code:: ipython2
unstack = (S[1], S[0]), S[1]
enstacken = S[0], (S[0], S[1])
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*unstack)
([.1.] --)
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*enstacken)
(-- [.0.])
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*C(cons, unstack))
(a1 [.1.] -- a1)
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*C(cons, enstacken))
(a1 [.1.] -- [[a1 .1.] .2.])
-.. code:: python
+.. code:: ipython2
C(cons, unstack)
…
-.. code:: python
+.. code:: ipython2
class IntJoyType(NumberJoyType): prefix = 'i'
F = map(FloatJoyType, _R)
I = map(IntJoyType, _R)
-.. code:: python
+.. code:: ipython2
muls = [
((I[2], (I[1], S[0])), (I[3], S[0])),
((F[2], (F[1], S[0])), (F[3], S[0])),
]
-.. code:: python
+.. code:: ipython2
for f in muls:
print doc_from_stack_effect(*f)
(f1 f2 -- f3)
-.. code:: python
+.. code:: ipython2
for f in muls:
try:
(a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
-.. code:: python
+.. code:: ipython2
from itertools import product
def MC(F, G):
return sorted(set(meta_compose(F, G)))
-.. code:: python
+.. code:: ipython2
for f in MC([dup], [mul]):
print doc_from_stack_effect(*f)
(n1 -- n2)
-.. code:: python
+.. code:: ipython2
for f in MC([dup], muls):
print doc_from_stack_effect(*f)
{c: a, d: b, .1.: .0.}
{c: a, d: e, .1.: A* b .0.}
-.. code:: python
+.. code:: ipython2
class KleeneStar(object):
Can now return multiple results…
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
def stacky(thing):
return thing.__class__ in {AnyJoyType, StackJoyType}
-.. code:: python
+.. code:: ipython2
a = (As[1], S[1])
a
-.. code:: python
+.. code:: ipython2
b = (A[1], S[2])
b
-.. code:: python
+.. code:: ipython2
for result in unify(b, a):
print result, '->', update(result, a), update(result, b)
{a1: a10001, s2: (a1*, s1)} -> (a1*, s1) (a10001, (a1*, s1))
-.. code:: python
+.. code:: ipython2
for result in unify(a, b):
print result, '->', update(result, a), update(result, b)
(a1*, s1) [a1*] (a2, (a1*, s1)) [a2 a1*]
-.. code:: python
+.. code:: ipython2
sum_ = ((Ns[1], S[1]), S[0]), (N[0], S[0])
([n1* .1.] -- n0)
-.. code:: python
+.. code:: ipython2
f = (N[1], (N[2], (N[3], S[1]))), S[0]
(-- [n1 n2 n3 .1.])
-.. code:: python
+.. code:: ipython2
for result in unify(sum_[0], f):
print result, '->', update(result, sum_[1])
This function has to be modified to yield multiple results.
-.. code:: python
+.. code:: ipython2
def compose(f, g):
(f_in, f_out), (g_in, g_out) = f, g
-.. code:: python
+.. code:: ipython2
def meta_compose(F, G):
for f, g in product(F, G):
for fg in compose(f, g):
yield delabel(fg)
-.. code:: python
+.. code:: ipython2
for f in MC([dup], muls):
print doc_from_stack_effect(*f)
(i1 -- i2)
-.. code:: python
+.. code:: ipython2
([n1* .1.] -- [n1* .1.] n1)
-.. code:: python
+.. code:: ipython2
(n1 [n1* .1.] -- n2)
-.. code:: python
+.. code:: ipython2
sum_ = (((N[1], (Ns[1], S[1])), S[0]), (N[0], S[0]))
print doc_from_stack_effect(*cons),
(a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
-.. code:: python
+.. code:: ipython2
a = (A[4], (As[1], (A[3], S[1])))
a
-.. code:: python
+.. code:: ipython2
b = (A[1], (A[2], S[2]))
b
-.. code:: python
+.. code:: ipython2
for result in unify(b, a):
print result
{a1: a4, s2: (a1*, (a3, s1)), a2: a10003}
-.. code:: python
+.. code:: ipython2
for result in unify(a, b):
print result
and be used by the hybrid inferencer/interpreter. They have to store a
name and a list of stack effects.
-.. code:: python
+.. code:: ipython2
class FunctionJoyType(AnyJoyType):
For non-combinator functions the stack effects list contains stack
effect comments (represented by pairs of cons-lists as described above.)
-.. code:: python
+.. code:: ipython2
class SymbolJoyType(FunctionJoyType):
prefix = 'F'
For combinators the list contains Python functions.
-.. code:: python
+.. code:: ipython2
class CombinatorJoyType(FunctionJoyType):
For simple combinators that have only one effect (like ``dip``) you only
need one function and it can be the combinator itself.
-.. code:: python
+.. code:: ipython2
import joy.library
have to write functions that each implement the action of one of the
effects.
-.. code:: python
+.. code:: ipython2
def branch_true(stack, expression, dictionary):
(then, (else_, (flag, stack))) = stack
losing useful information. This was a straightforward, if awkward,
modification to the call structure of ``meta_compose()`` et. al.
-.. code:: python
+.. code:: ipython2
ID = S[0], S[0] # Identity function.
``SymbolJoyType`` objects, and some combinators. Here is an example of
output from the current code :
-.. code:: python
+.. code:: ipython2
1/0 # (Don't try to run this cell! It's not going to work. This is "read only" code heh..)
Anyhow, type *checking* is a few easy steps away.
-.. code:: python
+.. code:: ipython2
def _ge(self, other):
return (issubclass(other.__class__, self.__class__)
Given a datastructure on the stack we can navigate through it, modify
it, and rebuild it using the “zipper” technique.
-.. code:: python
+.. code:: ipython2
from notebook_preamble import J, V, define
`trees <https://en.wikipedia.org/wiki/Tree_%28data_structure%29>`__ out
of sequences.
-.. code:: python
+.. code:: ipython2
J('[1 [2 [3 4 25 6] 7] 8]')
these a lot it would make sense to write Python versions for efficiency,
but see below.
-.. code:: python
+.. code:: ipython2
define('z-down == [] swap uncons swap')
define('z-up == swons swap shunt')
define('z-right == [swons] cons dip uncons swap')
define('z-left == swons [uncons swap] dip swap')
-.. code:: python
+.. code:: ipython2
V('[1 [2 [3 4 25 6] 7] 8] z-down')
[] [[2 [3 4 25 6] 7] 8] 1 .
-.. code:: python
+.. code:: ipython2
V('[] [[2 [3 4 25 6] 7] 8] 1 z-right')
[1] [8] [2 [3 4 25 6] 7] .
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2 [3 4 25 6] 7] z-down')
[1] [8] [] [[3 4 25 6] 7] 2
-.. code:: python
+.. code:: ipython2
J('[1] [8] [] [[3 4 25 6] 7] 2 z-right')
[1] [8] [2] [7] [3 4 25 6]
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [3 4 25 6] z-down')
[1] [8] [2] [7] [] [4 25 6] 3
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [] [4 25 6] 3 z-right')
[1] [8] [2] [7] [3] [25 6] 4
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [3] [25 6] 4 z-right')
[1] [8] [2] [7] [4 3] [6] 25
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [4 3] [6] 25 sqr')
[1] [8] [2] [7] [4 3] [6] 625
-.. code:: python
+.. code:: ipython2
V('[1] [8] [2] [7] [4 3] [6] 625 z-up')
[1] [8] [2] [7] [3 4 625 6] .
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [3 4 625 6] z-up')
[1] [8] [2 [3 4 625 6] 7]
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2 [3 4 625 6] 7] z-up')
In Joy we have the ``dip`` and ``infra`` combinators which can “target”
or “address” any particular item in a Joy tree structure.
-.. code:: python
+.. code:: ipython2
V('[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra')
The ``Z`` function isn’t hard to make.
-.. code:: python
+.. code:: ipython2
define('Z == [[] cons cons] step i')
Here it is in action in a simplified scenario.
-.. code:: python
+.. code:: ipython2
V('1 [2 3 4] Z')
And here it is doing the main thing.
-.. code:: python
+.. code:: ipython2
J('[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z')
Treestep
Generator_Programs
Newton-Raphson
+ Square_Spiral
Zipper
Types
TypeChecking
to run just fine on my modern Linux machine!) But I also hope that you
can read and understand the Python code and play with the implementation
itself.</p>
+<section id="example-code">
+<h2>Example Code<a class="headerlink" href="#example-code" title="Permalink to this headline">¶</a></h2>
+<p>Here is an example of Joy code:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+</pre></div>
+</div>
+<p>It might seem unreadable but with a little familiarity it becomes just as
+legible as any other notation. Some layout helps:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+]
+[[ !-] [[++]] [[--]] ifte dip]
+[[pop !-] [--] [++] ifte ]
+ifte
+</pre></div>
+</div>
+<p>This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral). For more information see <a class="reference internal" href="notebooks/Square_Spiral.html"><span class="doc">Square Spiral Example Joy Code</span></a></p>
+</section>
<section id="quick-start">
<h2>Quick Start<a class="headerlink" href="#quick-start" title="Permalink to this headline">¶</a></h2>
<p>Install from <a class="reference external" href="https://pypi.org/project/Thun/">PyPI</a> in the usual way:</p>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Newton-Raphson.html">Newton’s method</a></li>
+<li class="toctree-l2"><a class="reference internal" href="notebooks/Square_Spiral.html">Square Spiral Example Joy Code</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/TypeChecking.html">Type Checking</a></li>
</section>
<section id="implementation">
<h2>Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">partial</span> <span class="k">as</span> <span class="n">curry</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">partial</span> <span class="k">as</span> <span class="n">curry</span>
<span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">product</span>
</pre></div>
</div>
<section id="and">
<h3><code class="docutils literal notranslate"><span class="pre">ϕ</span></code> and <code class="docutils literal notranslate"><span class="pre">λ</span></code><a class="headerlink" href="#and" title="Permalink to this headline">¶</a></h3>
<p>The empty set and the set of just the empty string.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">phi</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">()</span> <span class="c1"># ϕ</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">phi</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">()</span> <span class="c1"># ϕ</span>
<span class="n">y</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">''</span><span class="p">})</span> <span class="c1"># λ</span>
</pre></div>
</div>
alphabet with two symbols (if you had to.)</p>
<p>I chose the names <code class="docutils literal notranslate"><span class="pre">O</span></code> and <code class="docutils literal notranslate"><span class="pre">l</span></code> (uppercase “o” and lowercase “L”) to
look like <code class="docutils literal notranslate"><span class="pre">0</span></code> and <code class="docutils literal notranslate"><span class="pre">1</span></code> (zero and one) respectively.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">syms</span> <span class="o">=</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'0'</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'1'</span><span class="p">})</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">syms</span> <span class="o">=</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'0'</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'1'</span><span class="p">})</span>
</pre></div>
</div>
</section>
</pre></div>
</div>
<p>Where <code class="docutils literal notranslate"><span class="pre">R</span></code> and <code class="docutils literal notranslate"><span class="pre">S</span></code> stand for <em>regular expressions</em>.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">AND</span><span class="p">,</span> <span class="n">CONS</span><span class="p">,</span> <span class="n">KSTAR</span><span class="p">,</span> <span class="n">NOT</span><span class="p">,</span> <span class="n">OR</span> <span class="o">=</span> <span class="s1">'and cons * not or'</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="c1"># Tags are just strings.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">AND</span><span class="p">,</span> <span class="n">CONS</span><span class="p">,</span> <span class="n">KSTAR</span><span class="p">,</span> <span class="n">NOT</span><span class="p">,</span> <span class="n">OR</span> <span class="o">=</span> <span class="s1">'and cons * not or'</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="c1"># Tags are just strings.</span>
</pre></div>
</div>
<p>Because they are formed of <code class="docutils literal notranslate"><span class="pre">frozenset</span></code>, <code class="docutils literal notranslate"><span class="pre">tuple</span></code> and <code class="docutils literal notranslate"><span class="pre">str</span></code> objects
</section>
<section id="string-representation-of-re-datastructures">
<h3>String Representation of RE Datastructures<a class="headerlink" href="#string-representation-of-re-datastructures" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
<span class="sd">'''</span>
<span class="sd"> Return a nice string repr for a regular expression datastructure.</span>
<span class="sd"> '''</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="o">|</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">I</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">I</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">.</span>
</pre></div>
</div>
<p>Note that it contains one of everything.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">I</span><span class="p">))))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">I</span><span class="p">))))</span>
<span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="n">it</span> <span class="o">=</span> <span class="p">(</span><span class="n">AND</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">NOT</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">)))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">')</span>
<section id="nully">
<h3><code class="docutils literal notranslate"><span class="pre">nully()</span></code><a class="headerlink" href="#nully" title="Permalink to this headline">¶</a></h3>
<p>Let’s get that auxiliary predicate function <code class="docutils literal notranslate"><span class="pre">δ</span></code> out of the way.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">nully</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">nully</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
<span class="sd">'''</span>
<span class="sd"> δ - Return λ if λ ⊆ R otherwise ϕ.</span>
<span class="sd"> '''</span>
<p>This is the straightforward version with no “compaction”. It works fine,
but does waaaay too much work because the expressions grow each
derivation.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">derv</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
</section>
<section id="compaction-rules">
<h3>Compaction Rules<a class="headerlink" href="#compaction-rules" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_compaction_rule</span><span class="p">(</span><span class="n">relation</span><span class="p">,</span> <span class="n">one</span><span class="p">,</span> <span class="n">zero</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_compaction_rule</span><span class="p">(</span><span class="n">relation</span><span class="p">,</span> <span class="n">one</span><span class="p">,</span> <span class="n">zero</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="n">b</span> <span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="n">one</span> <span class="k">else</span> <span class="c1"># R*1 = 1*R = R</span>
<span class="n">a</span> <span class="k">if</span> <span class="n">b</span> <span class="o">==</span> <span class="n">one</span> <span class="k">else</span>
</pre></div>
</div>
<p>An elegant symmetry.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># R ∧ I = I ∧ R = R</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># R ∧ I = I ∧ R = R</span>
<span class="c1"># R ∧ ϕ = ϕ ∧ R = ϕ</span>
<span class="n">_and</span> <span class="o">=</span> <span class="n">curry</span><span class="p">(</span><span class="n">_compaction_rule</span><span class="p">,</span> <span class="n">AND</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">phi</span><span class="p">)</span>
<p>We can save re-processing by remembering results we have already
computed. RE datastructures are immutable and the <code class="docutils literal notranslate"><span class="pre">derv()</span></code> functions
are <em>pure</em> so this is fine.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Memo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Memo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">f</span> <span class="o">=</span> <span class="n">f</span>
<h3>With “Compaction”<a class="headerlink" href="#with-compaction" title="Permalink to this headline">¶</a></h3>
<p>This version uses the rules above to perform compaction. It keeps the
expressions from growing too large.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D_compaction</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D_compaction</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<span class="nd">@Memo</span>
<span class="k">def</span> <span class="nf">derv</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
<section id="lets-try-it-out">
<h2>Let’s try it out…<a class="headerlink" href="#lets-try-it-out" title="Permalink to this headline">¶</a></h2>
<p>(FIXME: redo.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">o</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">o</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
<span class="n">REs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">5</span>
<span class="n">names</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">product</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)])))</span>
</div>
<p>Says, “Three or more 1’s and not ending in 01 nor composed of all 1’s.”</p>
<figure class="align-default" id="id2">
-<img alt="State Machine Graph" src="../_images/omg.svg" /><figcaption>
-<p><span class="caption-text">State Machine Graph</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
+<img alt="omg.svg" src="notebooks/attachment:omg.svg" /><figcaption>
+<p><span class="caption-text">omg.svg</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<p>Start at <code class="docutils literal notranslate"><span class="pre">a</span></code> and follow the transition arrows according to their
<p>You can see the one-way nature of the <code class="docutils literal notranslate"><span class="pre">g</span></code> state and the <code class="docutils literal notranslate"><span class="pre">hij</span></code> “trap”
in the way that the <code class="docutils literal notranslate"><span class="pre">.111.</span></code> on the left-hand side of the <code class="docutils literal notranslate"><span class="pre">&</span></code>
disappears once it has been matched.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="kn">from</span> <span class="nn">pprint</span> <span class="kn">import</span> <span class="n">pprint</span>
<span class="kn">from</span> <span class="nn">string</span> <span class="kn">import</span> <span class="n">ascii_lowercase</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">d0</span><span class="p">,</span> <span class="n">d1</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">d0</span><span class="p">,</span> <span class="n">d1</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="explore">
<h3><code class="docutils literal notranslate"><span class="pre">explore()</span></code><a class="headerlink" href="#explore" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
<span class="c1"># Don't have more than 26 states...</span>
<span class="n">names</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">ascii_lowercase</span><span class="p">)</span><span class="o">.</span><span class="n">next</span><span class="p">)</span>
<span class="k">return</span> <span class="n">table</span><span class="p">,</span> <span class="n">accepting</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span> <span class="o">=</span> <span class="n">explore</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span> <span class="o">=</span> <span class="n">explore</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="n">table</span>
</pre></div>
</div>
<span class="p">(</span><span class="s1">'j'</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">'h'</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">accepting</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">accepting</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">'h'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">}</span>
<h3>Generate Diagram<a class="headerlink" href="#generate-diagram" title="Permalink to this headline">¶</a></h3>
<p>Once we have the FSM table and the set of accepting states we can
generate the diagram above.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">_template</span> <span class="o">=</span> <span class="s1">'''</span><span class="se">\</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">_template</span> <span class="o">=</span> <span class="s1">'''</span><span class="se">\</span>
<span class="s1">digraph finite_state_machine {</span>
<span class="s1"> rankdir=LR;</span>
<span class="s1"> size="8,5"</span>
<span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">make_graph</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">make_graph</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">digraph</span> <span class="n">finite_state_machine</span> <span class="p">{</span>
<h4>Trampoline Function<a class="headerlink" href="#trampoline-function" title="Permalink to this headline">¶</a></h4>
<p>Python has no GOTO statement but we can fake it with a “trampoline”
function.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">jump_from</span><span class="p">,</span> <span class="n">accepting</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">jump_from</span><span class="p">,</span> <span class="n">accepting</span><span class="p">):</span>
<span class="n">I</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">input_</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<h4>Stream Functions<a class="headerlink" href="#stream-functions" title="Permalink to this headline">¶</a></h4>
<p>Little helpers to process the iterator of our data (a “stream” of “1”
and “0” characters, not bits.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">getch</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">getch</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_1</span><span class="p">(</span><span class="n">I</span><span class="p">):</span>
code. (You have to imagine that these are GOTO statements in C or
branches in assembly and that the state names are branch destination
labels.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">c</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">c</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">b</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">_0</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="ow">or</span> <span class="n">d</span>
<span class="n">c</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">e</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">d</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">f</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<p>Note that the implementations of <code class="docutils literal notranslate"><span class="pre">h</span></code> and <code class="docutils literal notranslate"><span class="pre">g</span></code> are identical ergo
<code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">=</span> <span class="pre">g</span></code> and we could eliminate one in the code but <code class="docutils literal notranslate"><span class="pre">h</span></code> is an
accepting state and <code class="docutils literal notranslate"><span class="pre">g</span></code> isn’t.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">acceptable</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">acceptable</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
<span class="k">return</span> <span class="n">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="p">{</span><span class="n">h</span><span class="p">,</span> <span class="n">i</span><span class="p">})</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="nb">bin</span><span class="p">(</span><span class="n">n</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]</span>
<span class="nb">print</span> <span class="s1">'</span><span class="si">%05s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">s</span><span class="p">,</span> <span class="n">acceptable</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
</pre></div>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html">Square Spiral Example Joy Code</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<section id="using-x-to-generate-values">
<h1>Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values<a class="headerlink" href="#using-x-to-generate-values" title="Permalink to this headline">¶</a></h1>
<p>Cf. jp-reprod.html</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<p>Consider the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator:</p>
</pre></div>
</div>
<p>Let’s try it:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">dip</span> <span class="n">rest</span> <span class="n">cons</span><span class="p">]</span> <span class="n">x</span>
</div>
<p>After one application of <code class="docutils literal notranslate"><span class="pre">x</span></code> the quoted program contains <code class="docutils literal notranslate"><span class="pre">1</span></code> and
<code class="docutils literal notranslate"><span class="pre">0</span></code> is below it on the stack.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x x x x x pop'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x x x x x pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span>
</div>
<section id="direco">
<h2><code class="docutils literal notranslate"><span class="pre">direco</span></code><a class="headerlink" href="#direco" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'direco == dip rest cons'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'direco == dip rest cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] direco] x'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] direco] x'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span> <span class="n">x</span>
<span class="n">G</span> <span class="o">==</span> <span class="p">[</span><span class="n">direco</span><span class="p">]</span> <span class="n">cons</span> <span class="p">[</span><span class="n">swap</span><span class="p">]</span> <span class="n">swoncat</span> <span class="n">cons</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [direco] cons [swap] swoncat cons'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [direco] cons [swap] swoncat cons'</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G x x x pop'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G x x x pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span>
</div>
<section id="powers-of-2">
<h3>Powers of 2<a class="headerlink" href="#powers-of-2" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [dup 1 <<] G x x x x x x x x x pop'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [dup 1 <<] G x x x x x x x x x pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">4</span> <span class="mi">8</span> <span class="mi">16</span> <span class="mi">32</span> <span class="mi">64</span> <span class="mi">128</span> <span class="mi">256</span>
<h3><code class="docutils literal notranslate"><span class="pre">[x]</span> <span class="pre">times</span></code><a class="headerlink" href="#x-times" title="Permalink to this headline">¶</a></h3>
<p>If we have one of these quoted programs we can drive it using <code class="docutils literal notranslate"><span class="pre">times</span></code>
with the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 [dup ++] G 5 [x] times'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 [dup ++] G 5 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span> <span class="mi">24</span> <span class="mi">25</span> <span class="mi">26</span> <span class="mi">27</span> <span class="p">[</span><span class="mi">28</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</div>
<p>And pick them off by masking with 3 (binary 11) and then shifting the
int right two bits.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1 == dup [3 &] dip 2 >>'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1 == dup [3 &] dip 2 >>'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'14811 PE1.1'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'14811 PE1.1'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">14811</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span>
</pre></div>
</div>
<p>If we plug <code class="docutils literal notranslate"><span class="pre">14811</span></code> and <code class="docutils literal notranslate"><span class="pre">[PE1.1]</span></code> into our generator form…</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1] G'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1] G'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">14811</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
<p>…we get a generator that works for seven cycles before it reaches zero:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1] direco] 7 [x] times'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1] direco] 7 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
<h3>Reset at Zero<a class="headerlink" href="#reset-at-zero" title="Permalink to this headline">¶</a></h3>
<p>We need a function that checks if the int has reached zero and resets it
if so.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1.check == dup [pop 14811] [] branch'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1.check == dup [pop 14811] [] branch'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1.check PE1.1] G'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1.check PE1.1] G'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">14811</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mf">1.</span><span class="n">check</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mf">1.</span><span class="n">check</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
<p>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.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'7 66 * 4 +'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'7 66 * 4 +'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">466</span>
</pre></div>
</div>
<p>If we drive our generator 466 times and sum the stack we get 999.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">57</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mf">1.</span><span class="n">check</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">999</span>
</section>
<section id="project-euler-problem-one">
<h2>Project Euler Problem One<a class="headerlink" href="#project-euler-problem-one" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.2 == + dup [+] dip'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.2 == + dup [+] dip'</span><span class="p">)</span>
</pre></div>
</div>
<p>Now we can add <code class="docutils literal notranslate"><span class="pre">PE1.2</span></code> to the quoted program given to <code class="docutils literal notranslate"><span class="pre">G</span></code>.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">233168</span>
<span class="n">fib_gen</span> <span class="o">==</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">1</span> <span class="n">F</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib == + [popdd over] cons infra uncons'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib == + [popdd over] cons infra uncons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib_gen == [1 1 fib]'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib_gen == [1 1 fib]'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'fib_gen 10 [x] times'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'fib_gen 10 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">5</span> <span class="mi">8</span> <span class="mi">13</span> <span class="mi">21</span> <span class="mi">34</span> <span class="mi">55</span> <span class="mi">89</span> <span class="p">[</span><span class="mi">144</span> <span class="mi">89</span> <span class="n">fib</span><span class="p">]</span>
<p>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
<code class="docutils literal notranslate"><span class="pre">pop</span></code>s it otherwise.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.1 == dup 2 % [+] [pop] branch'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.1 == dup 2 % [+] [pop] branch'</span><span class="p">)</span>
</pre></div>
</div>
<p>And a predicate function that detects when the terms in the series
“exceed four million”.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'>4M == 4000000 >'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'>4M == 4000000 >'</span><span class="p">)</span>
</pre></div>
</div>
<p>Now it’s straightforward to define <code class="docutils literal notranslate"><span class="pre">PE2</span></code> as a recursive function that
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE2'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE2'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4613732</span>
</pre></div>
</div>
<p>Every third term is even.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x'</span><span class="p">)</span> <span class="c1"># To start the sequence with 1 1 2 3 instead of 1 2 3.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x'</span><span class="p">)</span> <span class="c1"># To start the sequence with 1 1 2 3 instead of 1 2 3.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">1</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="n">fib</span><span class="p">]</span>
</pre></div>
</div>
<p>Drive the generator three times and <code class="docutils literal notranslate"><span class="pre">popop</span></code> the two odd terms.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x [popop] dipd'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x [popop] dipd'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="n">fib</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.2 == x x x [popop] dipd'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.2 == x x x [popop] dipd'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] 10 [PE2.2] times'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] 10 [PE2.2] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="mi">8</span> <span class="mi">34</span> <span class="mi">144</span> <span class="mi">610</span> <span class="mi">2584</span> <span class="mi">10946</span> <span class="mi">46368</span> <span class="mi">196418</span> <span class="mi">832040</span> <span class="p">[</span><span class="mi">1346269</span> <span class="mi">832040</span> <span class="n">fib</span><span class="p">]</span>
</div>
<p>Replace <code class="docutils literal notranslate"><span class="pre">x</span></code> with our new driver function <code class="docutils literal notranslate"><span class="pre">PE2.2</span></code> and start our
<code class="docutils literal notranslate"><span class="pre">fib</span></code> generator at <code class="docutils literal notranslate"><span class="pre">1</span> <span class="pre">0</span></code>.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4613732</span>
</section>
<section id="an-interesting-variation">
<h2>An Interesting Variation<a class="headerlink" href="#an-interesting-variation" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'codireco == cons dip rest cons'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'codireco == cons dip rest cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 [dup ++] codireco] x'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 [dup ++] codireco] x'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="n">x</span>
<span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [codireco] cons cons'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [codireco] cons cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'230 [dup ++] G 5 [x] times pop'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'230 [dup ++] G 5 [x] times pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">230</span> <span class="mi">231</span> <span class="mi">232</span> <span class="mi">233</span> <span class="mi">234</span>
to write a function that can compute the square root of a number.</p>
<p>Cf. <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why Functional Programming Matters” by John
Hughes</a></p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<section id="a-generator-for-approximations">
<span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">make_generator</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
</div>
<p>Let’s drive the generator a few time (with the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator) and
square the approximation to see how well it works…</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra 6 [x popd] times first sqr'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra 6 [x popd] times first sqr'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">23.0000000001585</span>
<span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">a</span><span class="o">-</span><span class="n">b</span><span class="p">)</span><span class="o"><=</span><span class="n">ε</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_P [first - abs] dip <='</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_P [first - abs] dip <='</span><span class="p">)</span>
</pre></div>
</div>
</section>
<span class="n">b</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_B roll< popop first'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_B roll< popop first'</span><span class="p">)</span>
</pre></div>
</div>
</section>
<span class="n">b</span> <span class="p">[</span><span class="n">c</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">within</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_R [popd x] dip'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_R [popd x] dip'</span><span class="p">)</span>
</pre></div>
</div>
</section>
<span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="o">...</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'sqrt gsra within'</span><span class="p">)</span>
</pre></div>
</div>
<p>Try it out…</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'36 sqrt'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'36 sqrt'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">6.0</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span>
</pre></div>
</div>
<p>Check it.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">22.999999999999996</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">sqrt</span>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">sqrt</span>
<span class="n">sqrt</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
</pre></div>
implementation under the hood. (Where does the “type” come from? It has
a contingent existence predicated on the disciplined use of these
functions on otherwise undistinguished Joy datastructures.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
</pre></div>
</div>
<section id="adding-nodes-to-the-tree">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tree</span><span class="o">-</span><span class="n">new</span> <span class="o">==</span> <span class="n">swap</span> <span class="p">[[]</span> <span class="p">[]]</span> <span class="n">cons</span> <span class="n">cons</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-new == swap [[] []] cons cons'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-new == swap [[] []] cons cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'"v" "k" Tree-new'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'"v" "k" Tree-new'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'k'</span> <span class="s1">'v'</span> <span class="p">[]</span> <span class="p">[]]</span>
<span class="n">P</span> <span class="o">==</span> <span class="n">pop</span> <span class="n">roll</span><span class="o">></span> <span class="n">pop</span> <span class="n">first</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == pop roll> pop first'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == pop roll> pop first'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_key" 23 [] []] 17 "new_key" ["..."] P'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_key" 23 [] []] 17 "new_key" ["..."] P'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'new_key'</span> <span class="s1">'old_key'</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">T</span> <span class="o">==</span> <span class="n">cons</span> <span class="n">cons</span> <span class="p">[</span><span class="n">dipdd</span><span class="p">]</span> <span class="n">cons</span> <span class="n">infra</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'T == cons cons [dipdd] cons infra'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'T == cons cons [dipdd] cons infra'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'old_k'</span> <span class="s1">'old_value'</span> <span class="s1">'left'</span> <span class="s1">'Tree-add'</span> <span class="s1">'new_key'</span> <span class="s1">'new_value'</span> <span class="s1">'right'</span><span class="p">]</span>
<span class="p">[</span><span class="n">key_n</span> <span class="n">value_n</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">value</span> <span class="n">key</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span><span class="p">]</span> <span class="p">[</span><span class="n">P</span> <span class="o"><</span><span class="p">]</span> <span class="p">[</span><span class="n">Te</span><span class="p">]</span> <span class="p">[</span><span class="n">Ee</span><span class="p">]</span> <span class="n">ifte</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'E == [P <] [Te] [Ee] ifte'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'E == [P <] [Te] [Ee] ifte'</span><span class="p">)</span>
</pre></div>
</div>
<p>In this case <code class="docutils literal notranslate"><span class="pre">Te</span></code> works that same as <code class="docutils literal notranslate"><span class="pre">T</span></code> but on the left child tree
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Te</span> <span class="o">==</span> <span class="n">cons</span> <span class="n">cons</span> <span class="p">[</span><span class="n">dipd</span><span class="p">]</span> <span class="n">cons</span> <span class="n">infra</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Te == cons cons [dipd] cons infra'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Te == cons cons [dipd] cons infra'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'old_k'</span> <span class="s1">'old_value'</span> <span class="s1">'Tree-add'</span> <span class="s1">'new_key'</span> <span class="s1">'new_value'</span> <span class="s1">'left'</span> <span class="s1">'right'</span><span class="p">]</span>
<span class="p">[</span><span class="n">key</span> <span class="n">new_value</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Ee == pop swap roll< rest rest cons cons'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Ee == pop swap roll< rest rest cons cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'k'</span> <span class="s1">'new_value'</span> <span class="s1">'left'</span> <span class="s1">'right'</span><span class="p">]</span>
<span class="n">Tree</span><span class="o">-</span><span class="n">add</span> <span class="o">==</span> <span class="p">[</span><span class="n">popop</span> <span class="ow">not</span><span class="p">]</span> <span class="p">[[</span><span class="n">pop</span><span class="p">]</span> <span class="n">dipd</span> <span class="n">Tree</span><span class="o">-</span><span class="n">new</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">R</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec'</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="examples">
<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Initial</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Initial</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Greater than</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Greater than</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "a" Tree-add'</span><span class="p">)</span> <span class="c1"># Less than</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "a" Tree-add'</span><span class="p">)</span> <span class="c1"># Less than</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Equal to</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Equal to</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Series.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Series.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
<span class="n">L</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'G'</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'E'</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'L'</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">P</span> <span class="o">==</span> <span class="n">over</span> <span class="p">[</span><span class="n">popop</span> <span class="n">popop</span> <span class="n">first</span><span class="p">]</span> <span class="n">nullary</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == over [popop popop first] nullary'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == over [popop popop first] nullary'</span><span class="p">)</span>
</pre></div>
</div>
<p>Using <code class="docutils literal notranslate"><span class="pre">cmp</span></code> to simplify <cite>our code above at
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span> <span class="o">==</span> <span class="p">[</span><span class="n">popop</span> <span class="ow">not</span><span class="p">]</span> <span class="p">[[</span><span class="n">pop</span><span class="p">]</span> <span class="n">dipd</span> <span class="n">Tree</span><span class="o">-</span><span class="n">new</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">Ee</span><span class="p">]</span> <span class="p">[</span><span class="n">Te</span><span class="p">]</span> <span class="n">cmp</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tree</span><span class="o">-</span><span class="nb">iter</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="n">roll</span><span class="o"><</span> <span class="p">[</span><span class="n">dupdip</span> <span class="n">rest</span> <span class="n">rest</span><span class="p">]</span> <span class="n">cons</span> <span class="p">[</span><span class="n">step</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="id1">
<h3>Examples<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'b'</span> <span class="s1">'a'</span> <span class="s1">'c'</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span> <span class="mi">88</span> <span class="mi">44</span>
to it will only occur once within it, and we can query it in
<cite>:math:`O(log_2 N)</cite> <<a class="reference external" href="https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2">https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2</a>>`__
time.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
</div>
<p>And with that we can write a little program <code class="docutils literal notranslate"><span class="pre">unique</span></code> to remove
duplicate items from a list.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">7</span> <span class="mi">6</span> <span class="mi">8</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">9</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
</pre></div>
</div>
<p>Now we can sort sequences.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1">#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
<span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span>
<span class="n">Tree</span><span class="o">-</span><span class="n">get</span> <span class="o">==</span> <span class="p">[</span><span class="n">pop</span> <span class="ow">not</span><span class="p">]</span> <span class="n">swap</span> <span class="p">[]</span> <span class="p">[</span><span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">></span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o"><</span><span class="p">]</span> <span class="n">cmp</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
<span class="c1"># The original Joy system has "hide" which is a meta-command which allows you to use named</span>
<span class="c1"># definitions that are only in scope for a given definition. I don't want to implement</span>
<span class="c1"># that (yet) so...</span>
<span class="s1">'''</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'mike not in tree'</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> [] [[0 'a'] [1 'b'] [2 'c']] [i Tree-add] step</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> [] [[0 'a'] [1 'b'] [2 'c']] [i Tree-add] step</span>
</div>
<p>By the standards of the code I’ve written so far, this is a <em>huge</em> Joy
program.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1">first_two == uncons uncons pop</span>
<span class="s1">fourth == rest rest rest first</span>
<span class="s1">?fourth == [] [fourth] [] ifte</span>
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
<div class="body" role="main">
- <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+ <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<section id="quadratic-formula">
</div>
<p>The three arguments are to the left, so we can “chop off” everything to
the right and say it’s the definition of the <code class="docutils literal notranslate"><span class="pre">quadratic</span></code> function:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2'</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mf">0.3819660112501051</span> <span class="o">-</span><span class="mf">2.618033988749895</span>
lines are the <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">dipd</span></code> combinators building the main program
by incorporating the values on the stack. Then that program runs and you
get the results. This is pretty typical of Joy code.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'-5 1 4 quadratic'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'-5 1 4 quadratic'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="o">-</span><span class="mi">5</span> <span class="mi">1</span> <span class="mi">4</span> <span class="n">quadratic</span>
<div class="body" role="main">
- <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">DefinitionWrapper</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+ <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">DefinitionWrapper</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<section id="recursion-combinators">
</ul>
<p>It may be helpful to see this function implemented in imperative Python
code.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hylomorphism</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hylomorphism</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="sd">'''Return a hylomorphism function H.'''</span>
<span class="k">def</span> <span class="nf">H</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">hylomorphism</span> <span class="o">==</span> <span class="p">[</span><span class="n">unit</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="n">swoncat</span><span class="p">]</span> <span class="n">dipd</span> <span class="p">[</span><span class="n">dip</span><span class="p">]</span> <span class="n">swoncat</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec'</span><span class="p">)</span>
</pre></div>
</div>
<section id="example-finding-triangular-numbers">
<li><p><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></p></li>
</ul>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism'</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 triangular_number'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 triangular_number'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 1 2 3 4 5 6] [triangular_number] map'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 1 2 3 4 5 6] [triangular_number] map'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">6</span> <span class="mi">10</span> <span class="mi">15</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
-<section id="range-et-al">
-<h3><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al.<a class="headerlink" href="#range-et-al" title="Permalink to this headline">¶</a></h3>
-<p>An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</p>
+<section id="range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n">
+<h3><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al. An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.<a class="headerlink" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n" title="Permalink to this headline">¶</a></h3>
<p>Each of the above variations can be used to make four slightly different
<code class="docutils literal notranslate"><span class="pre">range</span></code> functions.</p>
<section id="range-with-h1">
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range == [0 <=] [] [-- dup] [swons] hylomorphism'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range == [0 <=] [] [-- dup] [swons] hylomorphism'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span><span class="p">]</span>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_reverse'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_reverse'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[[</span><span class="o">--</span><span class="p">]</span> <span class="n">dupdip</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">5</span> <span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">--</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger_reverse'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger_reverse'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="n">c</span> <span class="p">[</span><span class="n">uncons</span> <span class="n">swap</span><span class="p">]</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'swuncons == uncons swap'</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'swuncons == uncons swap'</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
</pre></div>
</div>
<p>An example of a catamorphism is the sum function.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">sum</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="mi">0</span> <span class="p">[</span><span class="n">swuncons</span><span class="p">]</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == [not] 0 [swuncons] [+] hylomorphism'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == [not] 0 [swuncons] [+] hylomorphism'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
<h3>The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator<a class="headerlink" href="#the-step-combinator" title="Permalink to this headline">¶</a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator will usually be better to use than
<code class="docutils literal notranslate"><span class="pre">catamorphism</span></code>.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[step] help'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[step] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Run</span> <span class="n">a</span> <span class="n">quoted</span> <span class="n">program</span> <span class="n">on</span> <span class="n">each</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">a</span> <span class="n">sequence</span><span class="o">.</span>
<span class="n">on</span> <span class="n">top</span> <span class="n">of</span> <span class="n">the</span> <span class="n">stack</span><span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == 0 swap [+] step'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == 0 swap [+] step'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
<span class="n">P</span> <span class="o">==</span> <span class="mi">1</span> <span class="o"><=</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 factorial'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 factorial'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">120</span>
<span class="n">P</span> <span class="o">==</span> <span class="ow">not</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'tails == [] swap [not] [pop] [rest dup [swons] dip] primrec'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'tails == [] swap [not] [pop] [rest dup [swons] dip] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] tails'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] tails'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[]</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span><span class="p">]]</span>
dictionary. However, there’s no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
</pre></div>
</div>
<section id="a-long-trace">
<h2>A long trace<a class="headerlink" href="#a-long-trace" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
<p>An efficient <code class="docutils literal notranslate"><span class="pre">sum</span></code> function is already in the library. But for
<code class="docutils literal notranslate"><span class="pre">size</span></code> we can use a “compiled” version hand-written in Python to speed
up evaluation and make the trace more readable.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="kn">import</span> <span class="n">iter_stack</span>
</div>
<p>Now we replace the old version in the dictionary with the new version,
and re-evaluate the expression.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'size'</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'size'</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span>
</pre></div>
</div>
</section>
<section id="a-shorter-trace">
<h2>A shorter trace<a class="headerlink" href="#a-shorter-trace" title="Permalink to this headline">¶</a></h2>
<p>You can see that <code class="docutils literal notranslate"><span class="pre">size</span></code> now executes in a single step.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
--- /dev/null
+
+<!DOCTYPE html>
+
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
+
+ <title>Square Spiral Example Joy Code — Thun 0.4.1 documentation</title>
+ <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
+ <link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
+ <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
+ <script src="../_static/jquery.js"></script>
+ <script src="../_static/underscore.js"></script>
+ <script src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="Traversing Datastructures with Zippers" href="Zipper.html" />
+ <link rel="prev" title="Newton’s method" href="Newton-Raphson.html" />
+
+ <link rel="stylesheet" href="../_static/custom.css" type="text/css" />
+
+
+ <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
+
+ </head><body>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+
+
+ <div class="body" role="main">
+
+ <div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+</pre></div>
+</div>
+<section id="square-spiral-example-joy-code">
+<h1>Square Spiral Example Joy Code<a class="headerlink" href="#square-spiral-example-joy-code" title="Permalink to this headline">¶</a></h1>
+<p>Here is the example of Joy code from the <code class="docutils literal notranslate"><span class="pre">README</span></code> file:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+</pre></div>
+</div>
+<p>It might seem unreadable but with a little familiarity it becomes just
+as legible as any other notation. Some layout helps:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+]
+[[ !-] [[++]] [[--]] ifte dip]
+[[pop !-] [--] [++] ifte ]
+ifte
+</pre></div>
+</div>
+<p>This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral).</p>
+<section id="original-form">
+<h2>Original Form<a class="headerlink" href="#original-form" title="Permalink to this headline">¶</a></h2>
+<p>It’s adapted from <a class="reference external" href="https://stackoverflow.com/questions/398299/looping-in-a-spiral/31864777#31864777">the original code on
+StackOverflow</a>:</p>
+<blockquote>
+<div><p>If all you’re trying to do is generate the first N points in the
+spiral (without the original problem’s constraint of masking to an N
+x M region), the code becomes very simple:</p>
+</div></blockquote>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>void spiral(const int N)
+{
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+}
+</pre></div>
+</div>
+</section>
+<section id="translation-to-joy">
+<h2>Translation to Joy<a class="headerlink" href="#translation-to-joy" title="Permalink to this headline">¶</a></h2>
+<p>I’m going to make a function that take two ints (<code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code>) and
+generates the next pair, we’ll turn it into a generator later using the
+<code class="docutils literal notranslate"><span class="pre">x</span></code> combinator.</p>
+<section id="first-boolean-predicate">
+<h3>First Boolean Predicate<a class="headerlink" href="#first-boolean-predicate" title="Permalink to this headline">¶</a></h3>
+<p>We need a function that computes <code class="docutils literal notranslate"><span class="pre">abs(x)</span> <span class="pre"><=</span> <span class="pre">abs(y)</span></code>, we can use <code class="docutils literal notranslate"><span class="pre">ii</span></code>
+to apply <code class="docutils literal notranslate"><span class="pre">abs</span></code> to both values and then compare them with <code class="docutils literal notranslate"><span class="pre"><=</span></code>:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="nb">abs</span><span class="p">]</span> <span class="n">ii</span> <span class="o"><=</span>
+</pre></div>
+</div>
+<p>I’ve defined two short-circuiting Boolean combinators <code class="docutils literal notranslate"><span class="pre">&&</span></code> and <code class="docutils literal notranslate"><span class="pre">||</span></code>
+that each accept two quoted predicate programs, run the first, and
+conditionally run the second only if required (to compute the final
+Boolean value). They run their predicate arguments <code class="docutils literal notranslate"><span class="pre">nullary</span></code>.</p>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'&& [nullary] cons [nullary [0]] dip branch'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'|| [nullary] cons [nullary] dip [1] branch'</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Given those, we can define <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">!=</span> <span class="pre">y</span> <span class="pre">||</span> <span class="pre">x</span> <span class="pre">>=</span> <span class="pre">0</span></code> as:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="o"><></span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="mi">0</span> <span class="o">>=</span><span class="p">]</span> <span class="o">||</span>
+</pre></div>
+</div>
+<p>And <code class="docutils literal notranslate"><span class="pre">(abs(x)</span> <span class="pre"><=</span> <span class="pre">abs(y)</span> <span class="pre">&&</span> <span class="pre">(x</span> <span class="pre">!=</span> <span class="pre">y</span> <span class="pre">||</span> <span class="pre">x</span> <span class="pre">>=</span> <span class="pre">0))</span></code> as:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="nb">abs</span><span class="p">]</span> <span class="n">ii</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[[</span><span class="o"><></span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="mi">0</span> <span class="o">>=</span><span class="p">]</span> <span class="o">||</span><span class="p">]</span> <span class="o">&&</span>
+</pre></div>
+</div>
+<p>It’s a little rough, but, as I say, with a little familiarity it becomes
+legible.</p>
+</section>
+<section id="the-increment-decrement-branches">
+<h3>The Increment / Decrement Branches<a class="headerlink" href="#the-increment-decrement-branches" title="Permalink to this headline">¶</a></h3>
+<p>Turning to the branches of the main <code class="docutils literal notranslate"><span class="pre">if</span></code> statement:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>x += ((y >= 0) ? 1 : -1);
+</pre></div>
+</div>
+<p>Rewrite as a hybrid (pseudo-code) <code class="docutils literal notranslate"><span class="pre">ifte</span></code> expression:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">y</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[</span><span class="n">x</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="n">X</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">]</span> <span class="n">ifte</span>
+</pre></div>
+</div>
+<p>Change each C phrase to Joy code:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="o">>=</span><span class="p">]</span> <span class="p">[[</span><span class="o">++</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[[</span><span class="o">--</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">ifte</span>
+</pre></div>
+</div>
+<p>Factor out the dip from each branch:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="o">>=</span><span class="p">]</span> <span class="p">[[</span><span class="o">++</span><span class="p">]]</span> <span class="p">[[</span><span class="o">--</span><span class="p">]]</span> <span class="n">ifte</span> <span class="n">dip</span>
+</pre></div>
+</div>
+<p>Similar logic applies to the other branch:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>y += ((x >= 0) ? -1 : 1);
+
+[x >= 0] [y -= 1] [y += 1] ifte
+
+[pop 0 >=] [--] [++] ifte
+</pre></div>
+</div>
+</section>
+<section id="not-negative">
+<h3>“Not Negative”<a class="headerlink" href="#not-negative" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'!- 0 >='</span><span class="p">)</span>
+</pre></div>
+</div>
+</section>
+</section>
+<section id="putting-the-pieces-together">
+<h2>Putting the Pieces Together<a class="headerlink" href="#putting-the-pieces-together" title="Permalink to this headline">¶</a></h2>
+<p>We can assemble the three functions we just defined in quotes and give
+them them to the <code class="docutils literal notranslate"><span class="pre">ifte</span></code> combinator. With some arrangement to show off
+the symmetry of the two branches, we have:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[[[abs] ii <=] [[<>] [pop !-] ||] &&]
+[[ !-] [[++]] [[--]] ifte dip]
+[[pop !-] [--] [++] ifte ]
+ifte
+</pre></div>
+</div>
+<p>As I was writing this up I realized that, since the <code class="docutils literal notranslate"><span class="pre">&&</span></code> combinator
+doesn’t consume the stack (below its quoted args), I can unquote the
+predicate, swap the branches, and use the <code class="docutils literal notranslate"><span class="pre">branch</span></code> combinator instead
+of <code class="docutils literal notranslate"><span class="pre">ifte</span></code>:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[[abs] ii <=] [[<>] [pop !-] ||] &&
+[[pop !-] [--] [++] ifte ]
+[[ !-] [[++]] [[--]] ifte dip]
+branch
+</pre></div>
+</div>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte'</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Let’s try it out:</p>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 spiral_next'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">0</span>
+</pre></div>
+</div>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 0 spiral_next'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="o">-</span><span class="mi">1</span>
+</pre></div>
+</div>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 -1 spiral_next'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span> <span class="o">-</span><span class="mi">1</span>
+</pre></div>
+</div>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 -1 spiral_next'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mi">1</span> <span class="o">-</span><span class="mi">1</span>
+</pre></div>
+</div>
+</section>
+<section id="turning-it-into-a-generator-with-x">
+<h2>Turning it into a Generator with <code class="docutils literal notranslate"><span class="pre">x</span></code><a class="headerlink" href="#turning-it-into-a-generator-with-x" title="Permalink to this headline">¶</a></h2>
+<p>It can be used with the x combinator to make a kind of generator for
+spiral square coordinates.</p>
+<p>We can use <code class="docutils literal notranslate"><span class="pre">codireco</span></code> to make a generator</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">codireco</span> <span class="p">:</span><span class="o">:=</span> <span class="n">cons</span> <span class="n">dip</span> <span class="n">rest</span> <span class="n">cons</span>
+</pre></div>
+</div>
+<p>It will look like this:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">value</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
+</pre></div>
+</div>
+<p>Here’s a trace of how it works:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="o">.</span> <span class="n">x</span>
+ <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="o">.</span> <span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span>
+ <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="mi">0</span> <span class="o">.</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span>
+<span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="o">.</span> <span class="n">codireco</span>
+<span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="o">.</span> <span class="n">cons</span> <span class="n">dip</span> <span class="n">rest</span> <span class="n">cons</span>
+<span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="p">[</span><span class="mi">0</span> <span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="o">.</span> <span class="n">dip</span> <span class="n">rest</span> <span class="n">cons</span>
+ <span class="o">.</span> <span class="mi">0</span> <span class="n">dup</span> <span class="o">++</span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="n">rest</span> <span class="n">cons</span>
+ <span class="mi">0</span> <span class="o">.</span> <span class="n">dup</span> <span class="o">++</span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="n">rest</span> <span class="n">cons</span>
+ <span class="mi">0</span> <span class="mi">0</span> <span class="o">.</span> <span class="o">++</span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="n">rest</span> <span class="n">cons</span>
+ <span class="mi">0</span> <span class="mi">1</span> <span class="o">.</span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="n">rest</span> <span class="n">cons</span>
+ <span class="mi">0</span> <span class="mi">1</span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="o">.</span> <span class="n">rest</span> <span class="n">cons</span>
+ <span class="mi">0</span> <span class="mi">1</span> <span class="p">[[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="o">.</span> <span class="n">cons</span>
+ <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="o">.</span>
+</pre></div>
+</div>
+<p>But first we have to change the <code class="docutils literal notranslate"><span class="pre">spiral_next</span></code> function to work on a
+quoted pair of integers, and leave a copy of the pair on the stack.
+From:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">y</span> <span class="n">x</span> <span class="n">spiral_next</span>
+<span class="o">---------------------</span>
+ <span class="n">y</span><span class="s1">' x'</span>
+</pre></div>
+</div>
+<p>to:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="n">x</span> <span class="n">y</span><span class="p">]</span> <span class="p">[</span><span class="n">spiral_next</span><span class="p">]</span> <span class="n">infra</span>
+<span class="o">-------------------------------</span>
+ <span class="p">[</span><span class="n">x</span><span class="s1">' y'</span><span class="p">]</span>
+</pre></div>
+</div>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 0] [spiral_next] infra'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">1</span><span class="p">]</span>
+</pre></div>
+</div>
+<p>So our generator is:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="n">x</span> <span class="n">y</span><span class="p">]</span> <span class="p">[</span><span class="n">dup</span> <span class="p">[</span><span class="n">spiral_next</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
+</pre></div>
+</div>
+<p>Or rather:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mi">0</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[</span><span class="n">dup</span> <span class="p">[</span><span class="n">spiral_next</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
+</pre></div>
+</div>
+<p>There is a function <code class="docutils literal notranslate"><span class="pre">make_generator</span></code> that will build the generator for
+us out of the value and stepper function:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="mi">0</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[</span><span class="n">dup</span> <span class="p">[</span><span class="n">spiral_next</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">make_generator</span>
+<span class="o">----------------------------------------------------</span>
+ <span class="p">[[</span><span class="mi">0</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[</span><span class="n">dup</span> <span class="p">[</span><span class="n">spiral_next</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
+</pre></div>
+</div>
+<p>Here it is in action:</p>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 0] [dup [spiral_next] infra] make_generator x x x x pop'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[</span><span class="mi">0</span> <span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="mi">1</span> <span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="mi">1</span> <span class="mi">0</span><span class="p">]</span>
+</pre></div>
+</div>
+<p>Four <code class="docutils literal notranslate"><span class="pre">x</span></code> combinators, four pairs of coordinates.</p>
+</section>
+<section id="conclusion">
+<h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
+<p>So that’s an example of Joy code. It’s a straightforward translation of
+the original. It’s a little long for a single definition, you might
+break it up like so:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+
+ _spn_T ::= [ !-] [[++]] [[--]] ifte dip
+ _spn_E ::= [pop !-] [--] [++] ifte
+
+spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+</pre></div>
+</div>
+<p>This way it’s easy to see that the function is a branch with two
+quasi-symmetrical paths.</p>
+<p>We then used this function to make a simple generator of coordinate
+pairs, where the next pair in the series can be generated at any time by
+using the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator on the generator (which is just a quoted
+expression containing a copy of the current pair and the “stepper
+function” to generate the next pair from that.)</p>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'_spn_T [!-] [[++]] [[--]] ifte dip'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'_spn_E [pop !-] [--] [++] ifte'</span><span class="p">)</span>
+<span class="n">define</span><span class="p">(</span><span class="s1">'spiral_next _spn_P [_spn_E] [_spn_T] branch'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'23 18 spiral_next'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> . 23 18 spiral_next
+ 23 . 18 spiral_next
+ 23 18 . spiral_next
+ 23 18 . _spn_P [_spn_E] [_spn_T] branch
+ 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
+ 23 18 . 0 [_spn_E] [_spn_T] branch
+ 23 18 0 . [_spn_E] [_spn_T] branch
+ 23 18 0 [_spn_E] . [_spn_T] branch
+ 23 18 0 [_spn_E] [_spn_T] . branch
+ 23 18 . _spn_E
+ 23 18 . [pop !-] [--] [++] ifte
+ 23 18 [pop !-] . [--] [++] ifte
+ 23 18 [pop !-] [--] . [++] ifte
+ 23 18 [pop !-] [--] [++] . ifte
+ 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
+ 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
+ 23 18 [pop !-] . nullary not [--] [++] branch
+ 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
+ 23 18 . stack [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
+ 23 18 . pop !- [18 23] swaack first not [--] [++] branch
+ 23 . !- [18 23] swaack first not [--] [++] branch
+ 23 . 0 >= [18 23] swaack first not [--] [++] branch
+ 23 0 . >= [18 23] swaack first not [--] [++] branch
+ True . [18 23] swaack first not [--] [++] branch
+ True [18 23] . swaack first not [--] [++] branch
+ 23 18 [True] . first not [--] [++] branch
+ 23 18 True . not [--] [++] branch
+ 23 18 False . [--] [++] branch
+ 23 18 False [--] . [++] branch
+ 23 18 False [--] [++] . branch
+ 23 18 . --
+ 23 17 .
+</pre></div>
+</div>
+</section>
+</section>
+
+
+ </div>
+
+ </div>
+ </div>
+ <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
+ <div class="sphinxsidebarwrapper">
+<h1 class="logo"><a href="../index.html">Thun</a></h1>
+
+
+
+
+
+
+
+
+<h3>Navigation</h3>
+<ul class="current">
+<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
+<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
+<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
+<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
+<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
+<li class="toctree-l2 current"><a class="current reference internal" href="#">Square Spiral Example Joy Code</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
+<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
+<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
+<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+</ul>
+</li>
+</ul>
+
+<div class="relations">
+<h3>Related Topics</h3>
+<ul>
+ <li><a href="../index.html">Documentation overview</a><ul>
+ <li><a href="index.html">Essays about Programming in Joy</a><ul>
+ <li>Previous: <a href="Newton-Raphson.html" title="previous chapter">Newton’s method</a></li>
+ <li>Next: <a href="Zipper.html" title="next chapter">Traversing Datastructures with Zippers</a></li>
+ </ul></li>
+ </ul></li>
+</ul>
+</div>
+<div id="searchbox" style="display: none" role="search">
+ <h3 id="searchlabel">Quick search</h3>
+ <div class="searchformwrapper">
+ <form class="search" action="../search.html" method="get">
+ <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
+ <input type="submit" value="Go" />
+ </form>
+ </div>
+</div>
+<script>$('#searchbox').show(0);</script>
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="footer" role="contentinfo">
+<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
+<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
+</a>
+<br />
+<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
+ </div>
+
+ </body>
+</html>
\ No newline at end of file
</section>
<section id="define-treestep">
<h2>Define <code class="docutils literal notranslate"><span class="pre">treestep</span></code><a class="headerlink" href="#define-treestep" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> _treestep_0 == [[not] swap] dip</span>
<span class="s1"> _treestep_1 == [dip] cons [uncons] swoncat</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sumtree</span> <span class="o">==</span> <span class="p">[</span><span class="n">pop</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="nb">sum</span> <span class="o">+</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sumtree == [pop 0] [] [sum +] treestep'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sumtree == [pop 0] [] [sum +] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<p>Running this function on an empty tree value gives zero:</p>
<span class="mi">0</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] sumtree'</span><span class="p">)</span> <span class="c1"># Empty tree.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] sumtree'</span><span class="p">)</span> <span class="c1"># Empty tree.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span>
<span class="n">n</span><span class="o">+</span><span class="n">m</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23] sumtree'</span><span class="p">)</span> <span class="c1"># No child trees.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23] sumtree'</span><span class="p">)</span> <span class="c1"># No child trees.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 []] sumtree'</span><span class="p">)</span> <span class="c1"># Child tree, empty.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 []] sumtree'</span><span class="p">)</span> <span class="c1"># Child tree, empty.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [4]] [3]] sumtree'</span><span class="p">)</span> <span class="c1"># Non-empty child trees.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [4]] [3]] sumtree'</span><span class="p">)</span> <span class="c1"># Non-empty child trees.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">32</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] sumtree'</span><span class="p">)</span> <span class="c1"># Etc...</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] sumtree'</span><span class="p">)</span> <span class="c1"># Etc...</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep'</span><span class="p">)</span> <span class="c1"># Alternate "spelling".</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep'</span><span class="p">)</span> <span class="c1"># Alternate "spelling".</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep'</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep'</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
</pre></div>
</div>
<p>This doesn’t quite work:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="s1">'B'</span> <span class="s1">'B'</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="p">[</span><span class="n">flatten</span> <span class="n">cons</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">9</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">8</span> <span class="mi">6</span> <span class="mi">7</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">i</span> <span class="n">roll</span><span class="o"><</span> <span class="n">swons</span> <span class="n">concat</span><span class="p">]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">N</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="n">C</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'key'</span> <span class="s1">'value'</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[[</span><span class="s1">'left'</span><span class="p">]</span> <span class="p">[</span><span class="s1">'right'</span><span class="p">]]</span> <span class="p">[[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="s1">'B'</span><span class="p">]</span> <span class="p">[</span><span class="n">uncons</span> <span class="p">[</span><span class="s1">'N'</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="s1">'C'</span><span class="p">]</span> <span class="n">genrec</span><span class="p">]</span> <span class="s1">'C'</span>
<section id="treegrind-with-step">
<h2><code class="docutils literal notranslate"><span class="pre">treegrind</span></code> with <code class="docutils literal notranslate"><span class="pre">step</span></code><a class="headerlink" href="#treegrind-with-step" title="Permalink to this headline">¶</a></h2>
<p>Iteration through the nodes</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span>
</pre></div>
</div>
<p>Sum the nodes’ keys.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">44</span>
</pre></div>
</div>
<p>Rebuild the tree using <code class="docutils literal notranslate"><span class="pre">map</span></code> (imitating <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mi">103</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">102</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">109</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">105</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">104</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">108</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">106</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">107</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
</pre></div>
</div>
<p>To me, that seems simpler than the <code class="docutils literal notranslate"><span class="pre">genrec</span></code> version.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> T> == pop [first] dip i</span>
<span class="s1"> T< == pop [second] dip i</span>
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
<section id="type-checking">
<h1>Type Checking<a class="headerlink" href="#type-checking" title="Permalink to this headline">¶</a></h1>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">sys</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">sys</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span>
<span class="nb">format</span><span class="o">=</span><span class="s1">'</span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.utils.types</span> <span class="kn">import</span> <span class="p">(</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.utils.types</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">doc_from_stack_effect</span><span class="p">,</span>
<span class="n">infer</span><span class="p">,</span>
<span class="n">reify</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">D</span> <span class="o">=</span> <span class="n">FUNCTIONS</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">D</span> <span class="o">=</span> <span class="n">FUNCTIONS</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">del</span> <span class="n">D</span><span class="p">[</span><span class="s1">'product'</span><span class="p">]</span>
<span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
<section id="an-example">
<h2>An Example<a class="headerlink" href="#an-example" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ pop swap rolldown rrest ccons
40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a4</span> <span class="n">a5</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a3</span> <span class="o">...</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="kn">import</span> <span class="n">stack_to_string</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'0 1 2 [3 4]'</span><span class="p">)</span> <span class="c1"># reverse order</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'0 1 2 [3 4]'</span><span class="p">)</span> <span class="c1"># reverse order</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">u</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">a5</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="unification-works-in-reverse">
<h2>Unification Works “in Reverse”<a class="headerlink" href="#unification-works-in-reverse" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[2 3]'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[2 3]'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
<span class="n">u</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a2</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="failing-a-check">
<h2>Failing a Check<a class="headerlink" href="#failing-a-check" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ dup mul
31 (i1 -- i2) ∘
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'"two"'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'"two"'</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'two'</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)</span>
<span class="k">except</span> <span class="n">JoyTypeError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">err</span>
<section id="compiling-popswaproll">
<h3>Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span></code><a class="headerlink" href="#compiling-popswaproll" title="Permalink to this headline">¶</a></h3>
<p>The simplest way to “compile” this function would be something like:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
<span class="k">return</span> <span class="n">rolldown</span><span class="p">(</span><span class="o">*</span><span class="n">swap</span><span class="p">(</span><span class="o">*</span><span class="n">pop</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">)))</span>
</pre></div>
</div>
</pre></div>
</div>
<p>We should be able to directly write out a Python function like:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
</pre></div>
</div>
<p>From this stack effect comment it should be possible to construct the
following Python code:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
</pre></div>
<h3>Representing Stack Effect Comments in Python<a class="headerlink" href="#representing-stack-effect-comments-in-python" title="Permalink to this headline">¶</a></h3>
<p>I’m going to use pairs of tuples of type descriptors, which will be
integers or tuples of type descriptors:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">roll_dn</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">roll_dn</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
</section>
<section id="compose">
<h3><code class="docutils literal notranslate"><span class="pre">compose()</span></code><a class="headerlink" href="#compose" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
</section>
<section id="unify">
<h3><code class="docutils literal notranslate"><span class="pre">unify()</span></code><a class="headerlink" href="#unify" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
</section>
<section id="update">
<h3><code class="docutils literal notranslate"><span class="pre">update()</span></code><a class="headerlink" href="#update" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">term</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">term</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">term</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">inner</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
</section>
<section id="relabel">
<h3><code class="docutils literal notranslate"><span class="pre">relabel()</span></code><a class="headerlink" href="#relabel" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">relabel</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">relabel</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
<span class="k">return</span> <span class="n">left</span><span class="p">,</span> <span class="n">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">):</span>
</section>
<section id="delabel">
<h3><code class="docutils literal notranslate"><span class="pre">delabel()</span></code><a class="headerlink" href="#delabel" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{</span><span class="n">u</span><span class="p">:</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">u</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">)))}</span>
<span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<p>At last we put it all together in a function <code class="docutils literal notranslate"><span class="pre">C()</span></code> that accepts two
stack effect comments and returns their composition (or raises and
exception if they can’t be composed due to type conflicts.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
<span class="n">fg</span> <span class="o">=</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
<span class="k">return</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">),</span> <span class="n">roll_dn</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">),</span> <span class="n">roll_dn</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">poswrd</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">poswrd</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
<span class="n">poswrd</span>
</pre></div>
</div>
<p>Here’s that trick to represent functions like <code class="docutils literal notranslate"><span class="pre">rest</span></code> and <code class="docutils literal notranslate"><span class="pre">cons</span></code> that
manipulate stacks. We use a cons-list of tuples and give the tails their
own numbers. Then everything above already works.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
<span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">poswrd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">poswrd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span>
<span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
<span class="n">F</span>
</pre></div>
<h3>Dealing with <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code><a class="headerlink" href="#dealing-with-cons-and-uncons" title="Permalink to this headline">¶</a></h3>
<p>However, if we try to compose e.g. <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code> it won’t
work:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">e</span>
<p>The problem is that the <code class="docutils literal notranslate"><span class="pre">unify()</span></code> function as written doesn’t handle
the case when both terms are tuples. We just have to add a clause to
deal with this recursively:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<section id="part-iii-compiling-yin-functions">
<h2>Part III: Compiling Yin Functions<a class="headerlink" href="#part-iii-compiling-yin-functions" title="Permalink to this headline">¶</a></h2>
<p>Now consider the Python function we would like to derive:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
</pre></div>
</div>
<p>And compare it to the input stack effect comment tuple we just computed:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</div>
<p>Eh?</p>
<p>And the return tuple</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),)</span>
<h3>Python Identifiers<a class="headerlink" href="#python-identifiers" title="Permalink to this headline">¶</a></h3>
<p>We want to substitute Python identifiers for the integers. I’m going to
repurpose <code class="docutils literal notranslate"><span class="pre">joy.parser.Symbol</span></code> class for this:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">Symbol</span>
effect comment tuples to reasonable text format. There are some details
in how this code works that related to stuff later in the notebook, so
you should skip it for now and read it later if you’re interested.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">'(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span>
<span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="n">inputs</span> <span class="o">+</span> <span class="p">(</span><span class="s1">''</span><span class="p">,))),</span>
<span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="p">(</span><span class="s1">''</span><span class="p">,)</span> <span class="o">+</span> <span class="n">outputs</span><span class="p">))</span>
<p>Now we can write a compiler function to emit Python source code. (The
underscore suffix distiguishes it from the built-in <code class="docutils literal notranslate"><span class="pre">compile()</span></code>
function.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
<span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">identifiers</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<p>Here it is in action:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">source</span> <span class="o">=</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">source</span> <span class="o">=</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">source</span>
</pre></div>
</pre></div>
</div>
<p>Compare:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
</pre></div>
</div>
<p>Next steps:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
<span class="nb">eval</span><span class="p">(</span><span class="nb">compile</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="s1">'__main__'</span><span class="p">,</span> <span class="s1">'single'</span><span class="p">),</span> <span class="p">{},</span> <span class="n">L</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
<span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'F'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SimpleFunctionWrapper</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="s1">'F'</span><span class="p">])</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'F'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SimpleFunctionWrapper</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="s1">'F'</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 5 ...] 2 3 1 F'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 5 ...] 2 3 1 F'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">]</span>
<h3>Compiling Library Functions<a class="headerlink" href="#compiling-library-functions" title="Permalink to this headline">¶</a></h3>
<p>We can use <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> to generate many primitives in the library
from their stack effect comments:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
<span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="nb">print</span>
<span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span><span class="p">)</span>
<span class="nb">print</span>
Python class hierarchy of Joy types and use the <code class="docutils literal notranslate"><span class="pre">issubclass()</span></code> method
to establish domain ordering, as well as other handy behaviour that will
make it fairly easy to reuse most of the code above.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">AnyJoyType</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">AnyJoyType</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="s1">'a'</span>
</pre></div>
</div>
<p>Mess with it a little:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">permutations</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">permutations</span>
</pre></div>
</div>
<p>“Any” types can be specialized to numbers and stacks, but not vice
versa:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="mi">2</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="mi">2</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">a</span> <span class="o">>=</span> <span class="n">b</span>
</pre></div>
</div>
<p>Our crude <a class="reference external" href="https://en.wikipedia.org/wiki/Numerical_tower">Numerical
Tower</a> of <em>numbers</em> >
<em>floats</em> > <em>integers</em> works as well (but we’re not going to use it yet):</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">FloatJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">IntJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span> <span class="mi">2</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">FloatJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">IntJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span> <span class="mi">2</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">a</span> <span class="o">>=</span> <span class="n">b</span>
</pre></div>
</div>
</section>
<section id="typing-sqr">
<h3>Typing <code class="docutils literal notranslate"><span class="pre">sqr</span></code><a class="headerlink" href="#typing-sqr" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,))</span>
<section id="modifying-the-inferencer">
<h3>Modifying the Inferencer<a class="headerlink" href="#modifying-the-inferencer" title="Permalink to this headline">¶</a></h3>
<p>Re-labeling still works fine:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
<span class="n">foo</span>
</pre></div>
<h4><code class="docutils literal notranslate"><span class="pre">delabel()</span></code> version 2<a class="headerlink" href="#delabel-version-2" title="Permalink to this headline">¶</a></h4>
<p>The <code class="docutils literal notranslate"><span class="pre">delabel()</span></code> function needs an overhaul. It now has to keep track
of how many labels of each domain it has “seen”.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
<span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">delabel</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">delabel</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">delabel</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">)),</span> <span class="p">((</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,)))</span>
</section>
<section id="unify-version-3">
<h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 3<a class="headerlink" href="#unify-version-3" title="Permalink to this headline">¶</a></h4>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
</pre></div>
</div>
<p>Rewrite the stack effect comments:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
<span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">DEFS</span> <span class="o">=</span> <span class="n">defs</span><span class="p">()</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DEFS</span> <span class="o">=</span> <span class="n">defs</span><span class="p">()</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
</pre></div>
</div>
<span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">DEFS</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">DEFS</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="compose-dup-and-mul">
<h4>Compose <code class="docutils literal notranslate"><span class="pre">dup</span></code> and <code class="docutils literal notranslate"><span class="pre">mul</span></code><a class="headerlink" href="#compose-dup-and-mul" title="Permalink to this headline">¶</a></h4>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n1</span><span class="p">,),</span> <span class="p">(</span><span class="n">n2</span><span class="p">,))</span>
</pre></div>
</div>
<p>Revisit the <code class="docutils literal notranslate"><span class="pre">F</span></code> function, works fine.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
<span class="n">F</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a3</span><span class="p">,</span> <span class="n">a4</span><span class="p">,</span> <span class="n">a5</span><span class="p">),</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a4</span> <span class="n">a5</span> <span class="o">--</span> <span class="p">[</span><span class="n">a4</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</div>
<p>Some otherwise inefficient functions are no longer to be feared. We can
also get the effect of combinators in some limited cases.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">neato</span><span class="p">(</span><span class="o">*</span><span class="n">funcs</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">neato</span><span class="p">(</span><span class="o">*</span><span class="n">funcs</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">funcs</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
<span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a3</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
<span class="n">neato</span><span class="p">(</span><span class="n">popdd</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">pop</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a4</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a4</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
<span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
</pre></div>
</div>
<h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 2<a class="headerlink" href="#compile-version-2" title="Permalink to this headline">¶</a></h4>
<p>Because the type labels represent themselves as valid Python identifiers
the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function doesn’t need to generate them anymore:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">f</span>
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">)</span>
<span class="s1"> return </span><span class="si">%s</span><span class="s1">'''</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
</div>
<p>But it cannot magically create new functions that involve e.g. math and
such. Note that this is <em>not</em> a <code class="docutils literal notranslate"><span class="pre">sqr</span></code> function implementation:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'sqr'</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'sqr'</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sqr</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<p>The functions that <em>can</em> be compiled are the ones that have only
<code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> and <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> labels in their stack effect
comments. We can write a function to check that:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">imap</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">imap</span>
<span class="k">def</span> <span class="nf">compilable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">all</span><span class="p">(</span><span class="n">imap</span><span class="p">(</span><span class="n">compilable</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span> <span class="ow">or</span> <span class="n">stacky</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="k">if</span> <span class="n">compilable</span><span class="p">(</span><span class="n">stack_effect_comment</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
</pre></div>
the “truthiness” of <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> to false to let e.g.
<code class="docutils literal notranslate"><span class="pre">joy.utils.stack.concat</span></code> work with our stack effect comment cons-list
tuples.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
<span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span> <span class="c1"># s can also be the empty dict, which is ok.</span>
</div>
<p>I don’t want to rewrite all the defs myself, so I’ll write a little
conversion function instead. This is programmer’s laziness.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sequence_to_stack</span><span class="p">(</span><span class="n">seq</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="n">StackJoyType</span><span class="p">(</span><span class="mi">23</span><span class="p">)):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sequence_to_stack</span><span class="p">(</span><span class="n">seq</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="n">StackJoyType</span><span class="p">(</span><span class="mi">23</span><span class="p">)):</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">seq</span><span class="p">:</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">stack</span>
<span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))))</span>
<section id="doc-from-stack-effect-version-2">
<h3><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code> version 2<a class="headerlink" href="#doc-from-stack-effect-version-2" title="Permalink to this headline">¶</a></h3>
<p>Clunky junk, but it will suffice for now.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
<span class="n">switch</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="c1"># Do we need to display the '...' for the rest of the main stack?</span>
<span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">_f</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">),</span> <span class="n">_f</span><span class="p">(</span><span class="n">outputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span>
<span class="k">if</span> <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
<span class="k">return</span> <span class="s1">'[</span><span class="si">%s</span><span class="s1">]'</span> <span class="o">%</span> <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
</pre></div>
</div>
<span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)))</span>
<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
<span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="p">[</span><span class="n">a1</span> <span class="o">...</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">[[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">...</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
<span class="n">Q</span>
</pre></div>
<h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 3<a class="headerlink" href="#compile-version-3" title="Permalink to this headline">¶</a></h4>
<p>This makes the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function pretty simple as the stack effect
comments are now already in the form needed for the Python code:</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">f</span>
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
<span class="s1"> return </span><span class="si">%s</span><span class="s1">'''</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'Q'</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'Q'</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">Q</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">),</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">unstack</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">unstack</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="n">enstacken</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">unstack</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">unstack</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">enstacken</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">enstacken</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">enstacken</span><span class="p">))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">enstacken</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
<section id="part-vi-multiple-stack-effects">
<h2>Part VI: Multiple Stack Effects<a class="headerlink" href="#part-vi-multiple-stack-effects" title="Permalink to this headline">¶</a></h2>
<p>…</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'i'</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'i'</span>
<span class="n">F</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
<span class="n">I</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">IntJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
<span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
<span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
<span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">product</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">product</span>
<span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">)))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">,</span> <span class="n">d</span><span class="p">:</span> <span class="n">e</span><span class="p">,</span> <span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">KleeneStar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">KleeneStar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
<section id="unify-version-4">
<h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 4<a class="headerlink" href="#unify-version-4" title="Permalink to this headline">¶</a></h4>
<p>Can now return multiple results…</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
<span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">a</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="n">b</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a10001</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)}</span> <span class="o">-></span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="p">(</span><span class="n">a10001</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="p">[</span><span class="n">a1</span><span class="o">*</span><span class="p">]</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span><span class="o">*</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">((</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">((</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">)</span>
</pre></div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]))),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]))),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">)</span>
</pre></div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="n">n1</span> <span class="n">n2</span> <span class="n">n3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">sum_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">sum_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">sum_</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<section id="compose-version-3">
<h4><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 3<a class="headerlink" href="#compose-version-3" title="Permalink to this headline">¶</a></h4>
<p>This function has to be modified to yield multiple results.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">n1</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">(((</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">(((</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">cons</span><span class="p">),</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">),</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="n">n1</span> <span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span> <span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
<span class="n">a</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
<span class="n">b</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span>
</pre></div>
</div>
<span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a2</span><span class="p">:</span> <span class="n">a10003</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span>
</pre></div>
</div>
<p>We need a type variable for Joy functions that can go in our expressions
and be used by the hybrid inferencer/interpreter. They have to store a
name and a list of stack effects.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FunctionJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FunctionJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<h4>Specialized for Simple Functions and Combinators<a class="headerlink" href="#specialized-for-simple-functions-and-combinators" title="Permalink to this headline">¶</a></h4>
<p>For non-combinator functions the stack effects list contains stack
effect comments (represented by pairs of cons-lists as described above.)</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="s1">'F'</span>
</pre></div>
</div>
<p>For combinators the list contains Python functions.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="s1">'C'</span>
</div>
<p>For simple combinators that have only one effect (like <code class="docutils literal notranslate"><span class="pre">dip</span></code>) you only
need one function and it can be the combinator itself.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
<span class="n">dip</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">'dip'</span><span class="p">,</span> <span class="p">[</span><span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">dip</span><span class="p">],</span> <span class="mi">23</span><span class="p">)</span>
</pre></div>
<p>For combinators that can have more than one effect (like <code class="docutils literal notranslate"><span class="pre">branch</span></code>) you
have to write functions that each implement the action of one of the
effects.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">branch_true</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">branch_true</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
<span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
updated along with the stack effects after doing unification or we risk
losing useful information. This was a straightforward, if awkward,
modification to the call structure of <code class="docutils literal notranslate"><span class="pre">meta_compose()</span></code> et. al.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">ID</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Identity function.</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">ID</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Identity function.</span>
<span class="k">def</span> <span class="nf">infer</span><span class="p">(</span><span class="o">*</span><span class="n">expression</span><span class="p">):</span>
cruft to convert the definitions in <code class="docutils literal notranslate"><span class="pre">DEFS</span></code> to the new
<code class="docutils literal notranslate"><span class="pre">SymbolJoyType</span></code> objects, and some combinators. Here is an example of
output from the current code :</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span> <span class="c1"># (Don't try to run this cell! It's not going to work. This is "read only" code heh..)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span> <span class="c1"># (Don't try to run this cell! It's not going to work. This is "read only" code heh..)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="nb">format</span><span class="o">=</span><span class="s1">'</span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">,</span> <span class="n">stream</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
as it were. There’s a working demo of this at the end of the <code class="docutils literal notranslate"><span class="pre">types</span></code>
module. But if you’re interested in all that you should just use Prolog!</p>
<p>Anyhow, type <em>checking</em> is a few easy steps away.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
<span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'accept'</span><span class="p">)</span>
<span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">accept</span><span class="p">))</span>
Huet</a></p>
<p>Given a datastructure on the stack we can navigate through it, modify
it, and rebuild it using the “zipper” technique.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<section id="trees">
(aka lists, aka quoted literals, aka aggregates, etc…), but we can build
<a class="reference external" href="https://en.wikipedia.org/wiki/Tree_%28data_structure%29">trees</a> out
of sequences.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8]'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8]'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
show the trace so you can see how it works. If we were going to use
these a lot it would make sense to write Python versions for efficiency,
but see below.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'z-down == [] swap uncons swap'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'z-down == [] swap uncons swap'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'z-up == swons swap shunt'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'z-right == [swons] cons dip uncons swap'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'z-left == swons [uncons swap] dip swap'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] z-down'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] z-down'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="n">z</span><span class="o">-</span><span class="n">down</span>
<span class="p">[]</span> <span class="p">[[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[] [[2 [3 4 25 6] 7] 8] 1 z-right'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[] [[2 [3 4 25 6] 7] 8] 1 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="n">z</span><span class="o">-</span><span class="n">right</span>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 25 6] 7] z-down'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 25 6] 7] z-down'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [] [[3 4 25 6] 7] 2 z-right'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [] [[3 4 25 6] 7] 2 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 25 6] z-down'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 25 6] z-down'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [] [4 25 6] 3 z-right'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [] [4 25 6] 3 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">4</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3] [25 6] 4 z-right'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3] [25 6] 4 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">25</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 25 sqr'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 25 sqr'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 625 z-up'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 625 z-up'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span> <span class="n">z</span><span class="o">-</span><span class="n">up</span>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 625 6] z-up'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 625 6] z-up'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 625 6] 7] z-up'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 625 6] 7] z-up'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
<h2><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code><a class="headerlink" href="#dip-and-infra" title="Permalink to this headline">¶</a></h2>
<p>In Joy we have the <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code> combinators which can “target”
or “address” any particular item in a Joy tree structure.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="p">[[[[[[</span><span class="n">sqr</span><span class="p">]</span> <span class="n">dipd</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">Z</span></code> function isn’t hard to make.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Z == [[] cons cons] step i'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Z == [[] cons cons] step i'</span><span class="p">)</span>
</pre></div>
</div>
<p>Here it is in action in a simplified scenario.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2 3 4] Z'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2 3 4] Z'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="n">Z</span>
</pre></div>
</div>
<p>And here it is doing the main thing.</p>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z'</span><span class="p">)</span>
+<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html#finding-consecutive-approximations-within-a-tolerance">Finding Consecutive Approximations within a Tolerance</a></li>
</ul>
</li>
+<li class="toctree-l1"><a class="reference internal" href="Square_Spiral.html">Square Spiral Example Joy Code</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html#original-form">Original Form</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html#translation-to-joy">Translation to Joy</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html#putting-the-pieces-together">Putting the Pieces Together</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html#turning-it-into-a-generator-with-x">Turning it into a Generator with <code class="docutils literal notranslate"><span class="pre">x</span></code></a></li>
+<li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html#conclusion">Conclusion</a></li>
+</ul>
+</li>
<li class="toctree-l1"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#trees">Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#zipper-in-joy">Zipper in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html">Square Spiral Example Joy Code</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Derivatives_of_Regular_Expressions","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/The_Four_Operations","notebooks/Treestep","notebooks/TypeChecking","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack","types"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Derivatives_of_Regular_Expressions.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/The_Four_Operations.rst","notebooks/Treestep.rst","notebooks/TypeChecking.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst","types.rst"],objects:{"joy.joy":[[1,1,1,"","UnknownSymbolError"],[1,2,1,"","interp"],[1,2,1,"","joy"],[1,2,1,"","repl"],[1,2,1,"","run"]],"joy.library":[[3,2,1,"","BinaryBuiltinWrapper"],[3,3,1,"","Def"],[3,2,1,"","FunctionWrapper"],[3,2,1,"","SimpleFunctionWrapper"],[3,2,1,"","UnaryBuiltinWrapper"],[3,2,1,"","add_aliases"],[3,2,1,"","app1"],[3,2,1,"","app2"],[3,2,1,"","app3"],[3,2,1,"","b"],[3,2,1,"","branch"],[3,2,1,"","choice"],[3,2,1,"","clear"],[3,2,1,"","cmp_"],[3,2,1,"","concat_"],[3,2,1,"","cond"],[3,2,1,"","dip"],[3,2,1,"","dipd"],[3,2,1,"","dipdd"],[3,2,1,"","disenstacken"],[3,2,1,"","divmod_"],[3,2,1,"","drop"],[3,2,1,"","dupdip"],[3,2,1,"","floor"],[3,2,1,"","gcd2"],[3,2,1,"","genrec"],[3,2,1,"","getitem"],[3,2,1,"","help_"],[3,2,1,"","i"],[3,2,1,"","id_"],[3,2,1,"","infra"],[3,2,1,"","initialize"],[3,2,1,"","inscribe"],[3,2,1,"","inscribe_"],[3,2,1,"","loop"],[3,2,1,"","map_"],[3,2,1,"","max_"],[3,2,1,"","min_"],[3,2,1,"","parse"],[3,2,1,"","pm"],[3,2,1,"","pred"],[3,2,1,"","primrec"],[3,2,1,"","remove"],[3,2,1,"","reverse"],[3,2,1,"","select"],[3,2,1,"","sharing"],[3,2,1,"","shunt"],[3,2,1,"","sort_"],[3,2,1,"","sqrt"],[3,2,1,"","step"],[3,2,1,"","succ"],[3,2,1,"","sum_"],[3,2,1,"","take"],[3,2,1,"","times"],[3,2,1,"","unique"],[3,2,1,"","void"],[3,2,1,"","warranty"],[3,2,1,"","words"],[3,2,1,"","x"],[3,2,1,"","zip_"]],"joy.parser":[[21,1,1,"","ParseError"],[21,3,1,"","Symbol"],[21,2,1,"","text_to_expression"]],"joy.utils":[[3,0,0,"-","generated_library"],[22,0,0,"-","pretty_print"],[23,0,0,"-","stack"]],"joy.utils.generated_library":[[3,2,1,"","ccons"],[3,2,1,"","cons"],[3,2,1,"","dup"],[3,2,1,"","dupd"],[3,2,1,"","dupdd"],[3,2,1,"","first"],[3,2,1,"","first_two"],[3,2,1,"","fourth"],[3,2,1,"","over"],[3,2,1,"","pop"],[3,2,1,"","popd"],[3,2,1,"","popdd"],[3,2,1,"","popop"],[3,2,1,"","popopd"],[3,2,1,"","popopdd"],[3,2,1,"","rest"],[3,2,1,"","rolldown"],[3,2,1,"","rollup"],[3,2,1,"","rrest"],[3,2,1,"","second"],[3,2,1,"","stack"],[3,2,1,"","stuncons"],[3,2,1,"","stununcons"],[3,2,1,"","swaack"],[3,2,1,"","swap"],[3,2,1,"","swons"],[3,2,1,"","third"],[3,2,1,"","tuck"],[3,2,1,"","uncons"],[3,2,1,"","unit"],[3,2,1,"","unswons"]],"joy.utils.pretty_print":[[22,3,1,"","TracePrinter"],[22,2,1,"","trace"]],"joy.utils.pretty_print.TracePrinter":[[22,4,1,"","go"],[22,4,1,"","viewer"]],"joy.utils.stack":[[23,2,1,"","concat"],[23,2,1,"","dnd"],[23,2,1,"","expression_to_string"],[23,2,1,"","iter_stack"],[23,2,1,"","list_to_stack"],[23,2,1,"","pick"],[23,2,1,"","stack_to_string"]],joy:[[1,0,0,"-","joy"],[3,0,0,"-","library"],[21,0,0,"-","parser"]]},objnames:{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},terms:{"0":[2,3,5,6,7,8,9,10,11,12,13,14,16,17,18,24],"0000000001585":9,"000000001":9,"01":[6,7],"03":18,"05":5,"0a":18,"0b":[6,7],"0b11100111011011":6,"1":[2,3,5,6,7,8,9,10,11,12,13,14,16,17,18,19,23,24],"10":[2,5,6,7,13,18,24],"100":[5,16,18],"1000":[5,6,7,18],"10000":[5,18],"10001":5,"1001":[5,18],"10010":5,"10011":5,"1002":18,"101":5,"1010":5,"10100":5,"10101":5,"1011":5,"10110":5,"10111":5,"102":16,"1024":2,"103":16,"104":16,"105":16,"106":16,"107":16,"108":16,"109":16,"10946":7,"11":[2,6,7,18,24],"110":[5,6],"1100":5,"11000":5,"11001":5,"1101":5,"11010":5,"11011":5,"1110":5,"11100":5,"11101":5,"1111":5,"11110":5,"11111":5,"12":[2,6,16],"120":13,"122":5,"123":8,"128":7,"13":[2,7,16,24],"1346269":7,"14":[2,6,16],"144":7,"14811":[6,7],"15":[2,6,13,16,18,24],"16":[2,7,12,16,24],"160":2,"17":[11,16],"18":[6,8,14,16,22],"19":[16,18,24],"196418":7,"1a":18,"1b":18,"2":[2,3,5,6,8,9,10,11,13,14,16,17,19,23,24],"20":[2,6,14,18,24],"2006":18,"2017":[8,18],"2020":24,"207":2,"21":[6,7],"22":[9,18,24],"23":[2,6,7,8,9,11,14,16,18,22],"230":7,"231":[6,7],"232":7,"233":7,"233168":[6,7],"234":7,"23rd":18,"24":[2,6,7],"25":[6,7,12,16,17,19,24],"256":7,"2584":7,"26":[2,5,7,18,24],"27":[6,7],"273":10,"28":[7,17,24],"29":[18,24],"2a":18,"2b":18,"3":[2,3,7,8,10,11,12,13,16,17,19,20,23,24],"30":[2,6,18,24],"31":17,"32":[2,7,16],"33":6,"34":[7,17,18,24],"36":9,"37":[17,18,24],"3702":[6,7],"38":[18,24],"3819660112501051":12,"3b":18,"3i":18,"4":[2,6,7,8,9,11,13,16,17,19,23,24],"40":[2,17,18],"4000000":7,"41":[14,18,24],"414":22,"44":[11,16,18,24],"45":[2,6],"46":18,"4613732":7,"46368":7,"466":6,"47":[18,24],"48":[18,24],"49":[16,18,24],"4ac":12,"4m":7,"5":[2,3,5,7,8,11,12,13,14,16,18,20,24],"50":2,"513":22,"529":[2,8],"53":[18,24],"547":8,"55":[6,7],"552":2,"5555555555555554":2,"56":[18,24],"57":[6,7],"5bkei":11,"5d":11,"6":[2,6,9,11,13,16,18,19],"60":6,"610":7,"618033988749895":12,"625":19,"64":7,"66":[6,7],"6945":6,"7":[2,6,7,11,16,18,19,24],"75":2,"795831523312719":[2,9],"8":[2,5,6,7,11,12,16,18,19,24],"80":6,"832040":7,"88":11,"8888":8,"89":7,"9":[2,6,11,12,16,18,24],"90":2,"92":5,"925":6,"978":6,"980":6,"981":6,"984":6,"985":6,"987":6,"99":22,"990":6,"991":6,"992":6,"993":6,"995":6,"996":6,"999":[6,7],"999999999999996":9,"9a9d60354c35":18,"\u03b4":5,"\u03b5":9,"abstract":[8,11],"boolean":[2,3,8,11,15],"break":[5,8,18],"byte":[5,6],"case":[2,3,13,15,16,18,23],"char":5,"class":[3,5,8,18,21,22,23],"default":[3,7,11,23],"do":[2,3,4,5,6,7,8,11,13,14,15,18,19,20],"export":[3,21],"final":[2,11,13],"float":[8,18,19,21],"function":[0,1,4,6,7,10,12,17,19,20,21,22,23,24],"g\u00e9rard":19,"goto":5,"import":[2,5,6,7,9,11,12,13,14,16,17,18,19],"int":[5,7,8,13,18,19,21,23],"long":[11,18,20],"new":[2,3,5,7,8,10,13,14,18],"p\u00f6ial":20,"p\u00f6ial06typingtool":18,"public":10,"return":[1,3,5,6,8,11,13,14,15,16,18,21,22,23],"static":[2,10],"super":18,"switch":[2,18],"throw":[11,24],"true":[2,3,5,6,13,15,18],"try":[7,9,12,13,16,17,18,20],"void":[0,3],"while":[3,5,8,11,18,21,23],A:[1,3,4,8,13,15,18,20,21,22,23],AND:[5,18],And:[5,6,7,9,11,13,15,18,19,23],As:[4,6,11,18],At:[6,13,18],Be:2,But:[0,4,6,7,8,11,14,18],By:[7,11,18],For:[2,3,11,13,14,18,20,23],If:[2,3,5,6,7,8,9,10,12,13,16,18,19],In:[2,3,4,6,7,8,13,15,18,19,20,23],It:[0,2,3,4,5,6,7,8,10,11,13,18,19,23,24],Its:3,NO:8,NOT:5,No:[0,16,20],Not:18,OR:[5,18],Of:6,On:[3,22],One:[2,8,15,18,20],Or:[5,10,11,16,18],TOS:[2,3],That:[6,11],The:[0,1,2,3,4,5,7,9,10,12,19,20,21,22,23,24],Then:[2,3,11,12,13,18],There:[5,12,13,15,16,18,23],These:[15,18,20,23],To:[0,5,6,7,9,11,13,16,18],With:[9,13,18,20,24],_0:5,_1000:18,_1:5,_:[8,14,18],__:11,__add__:18,__call__:5,__class__:18,__eq__:18,__ge__:18,__hash__:18,__init__:[5,18],__main__:18,__radd__:18,__repr__:18,__str__:22,_and:5,_compaction_rul:5,_con:5,_dictionari:18,_f:18,_ge:18,_infer:18,_interpret:18,_log:18,_log_it:18,_names_for:18,_or:5,_r:18,_templat:5,_to_str:18,_tree_add_:11,_tree_add_e:[3,11,24],_tree_add_p:11,_tree_add_r:11,_tree_add_t:11,_tree_delete_:11,_tree_delete_clear_stuff:[3,11,24],_tree_delete_del:11,_tree_delete_r0:[3,11,24],_tree_delete_r1:11,_tree_delete_rightmost:11,_tree_delete_w:11,_tree_get_:[3,11,24],_tree_get_p:11,_tree_get_r:11,_tree_get_t:11,_tree_iter_order_curr:11,_tree_iter_order_left:11,_tree_iter_order_r:11,_tree_iter_order_right:11,_tree_t:11,_treestep_0:16,_treestep_1:16,_uniqu:18,_within_b:9,_within_p:9,_within_r:9,a0:18,a10001:18,a10002:18,a10003:18,a10004:18,a1:[3,17,18,24],a2:[3,17,18,24],a3:[3,17,18,24],a4:[3,17,18,24],a5:[17,18,24],a_:9,a_i:9,aa:13,ab:[3,5,9],abbrevi:16,abl:[5,15,18,24],about:[0,8,11,15,18,19,23],abov:[0,5,6,9,11,13,15,18],absolut:8,ac:5,accept:[1,2,3,5,6,7,8,11,12,14,15,16,18,19],accord:5,accordingli:[11,15],accumul:6,act:[5,24],action:[0,8,14,18,19,20],actual:[2,6,8,11,15,18],ad:[4,5,8,10,14,18,20],adapt:20,add:[3,5,6,7,8,14,18,22,24],add_alias:3,add_def:[],add_definit:[11,16],addit:[0,2,3,6,8,13,14,16],address:20,adjust:11,advantag:18,affect:[3,15],after:[5,6,7,8,13,15,18,23,24],afterward:8,again:[2,3,6,8,11,13,18],against:18,aggreg:19,ahead:18,aka:[5,8,19,24],al:[15,18],albrecht:0,algorithm:[5,8,18],alia:3,alias:[3,8],align:[8,22],all:[3,5,6,7,8,11,13,14,15,16,18,22,23],alloc:18,allow:[10,11,15],almost:11,along:[5,8,13,18],alphabet:[3,20],alreadi:[5,9,14,18,19],also:[0,5,6,8,11,15,18,22,23],alter:[5,18],altern:[4,18],although:[4,11],altogeth:7,alwai:[6,10,13,15],am:[15,20],amend:15,among:18,amort:11,an:[0,1,2,3,4,5,9,13,14,16,20,23,24],analysi:[4,20],anamorph:[8,20],and_:3,ani:[4,5,6,8,10,11,15,18,19,21],annual:8,anonym:11,anoth:[5,11,15,18,23,24],anyhow:[15,18],anyjoytyp:18,anymor:18,anystarjoytyp:18,anyth:[2,3,5,8,18,24],apart:18,api:10,app1:3,app2:[3,8,12,13,14,15],app3:[3,15],app:8,appear:[2,4,5,6,11],append:18,appendix:20,appli:[2,3,6,7,11,13,18],applic:7,approach:6,appropri:5,approxim:20,ar:[1,2,3,5,6,7,8,10,12,13,15,16,18,19,20,21,23,24],archiv:0,aren:19,arg:[2,3],argument:[2,3,8,9,12,13,20,22,23],arithmet:2,ariti:[2,15],around:[6,18,21,23],arrang:16,arriv:[7,16],arrow:5,articl:[0,4,7,13],ascii:5,ascii_lowercas:5,ask:[4,7,18],aspect:0,assembl:5,assert:[5,18],assign:[15,23],associ:11,assum:9,asterisk:16,asterix:[18,24],asyncron:15,attack:8,attempt:[0,1,18],attribut:3,attributeerror:18,author:18,auto:[0,18,24],automat:[4,15,18],auxiliari:[5,16],avail:[0,18,24],averag:[8,14],avoid:11,awai:[11,18],awar:2,awkward:[11,13,18],azur:20,b0:3,b1:[3,18,24],b2:24,b3:24,b:[3,5,7,8,9,11,13,15,16,18],back:[3,11,18],backtrack:24,backward:[10,11,12,16],bad:18,bag:8,banana:13,bar:15,barb:13,base:[0,2,3,10,13,16,18],basic:[2,3,8,11],basicconfig:[17,18],bc:5,bd:5,becaas:5,becaus:[2,3,5,8,11,15,16,18,19,23],becom:[11,16,23],becuas:18,been:[5,9,10,11,18,19],befor:[5,7,8,11],begin:[11,16],behavior:[10,16,24],behaviour:[0,1,18],behind:15,being:[0,15],below:[2,3,5,6,7,11,18,19],bespok:8,best:0,better:[6,11,13,18],between:[0,6],beyond:7,biannual:8,bin:5,binari:[0,7,8,20],binary_search_tre:11,binarybuiltinwrapp:3,bind:8,bingo:19,bit:[5,6,7,11,18],blank:21,bliss:[0,20],block:6,bodi:[2,3,5,8,11,15],body_text:[],booktitl:18,bool:[3,13,18,24],borrow:[8,18],both:[2,6,8,12,13,14,15,18,23],bottom:7,bounce_to:5,bracket:[8,18,21],branch:[3,5,6,7,13,18,20,24],branch_fals:18,branch_tru:18,breakpoint:8,bring:[6,8,18],bruijn:18,brutal:15,brzozowski:[18,20],brzozowskian:5,btree:[11,16],buck:11,bug:[0,8],build:[7,8,12,13,19,23],built:[12,18],bullet:22,bundl:[2,3,13],burgeon:8,c:[0,1,2,3,5,7,9,11,13,15,16],calculu:4,call:[1,2,5,8,10,11,13,15,18,22,23],caller:[11,18],can:[0,2,3,4,5,6,7,8,9,10,12,13,14,15,16,18,19,20,21,23,24],cancel:15,cannot:[17,18,21],captur:8,card:8,care:[6,23],carefulli:19,carri:[7,11],cartesian:4,catamorph:20,categor:[0,20],categori:[4,15],ccc:4,ccon:[3,11,17,18,24],cell:[13,18],certain:[8,23],certainli:11,cf:[7,9,12,13],chain:[3,15],chang:[2,10,11,18,19],charact:[5,19],chat:8,chatter:[0,18],check:[0,7,9,18,20],child:16,choic:[3,13],choos:10,chop:12,chose:5,cinf:11,circl:5,circuit:4,cite_not:11,classmethod:[],claus:[3,18],clean:18,clear:[3,6,8],clear_stuff:11,cleav:[8,12,14],client:23,close:[0,1,4],clunki:[6,18],clv:15,cmp:[3,16,20],cmp_:3,code:[0,1,4,5,12,13,15,18,20,24],codireco:[7,9],collaps:13,collect:[4,5,7,8,18],combin:[0,3,6,7,8,9,12,15,16,19,20,22,24],combinatorjoytyp:18,come:[8,11,18],command:[8,11,18],comment:15,common:[2,6,15],compar:[3,4,5,18],comparison:[0,11],compat:15,compel:4,compil:[2,3,4,5,8,11,14,15,20,24],complement:5,complet:4,complex:[3,15,18,19,24],complic:18,compos:[5,24],composit:18,compostit:18,compound:11,comput:[2,4,5,6,8,12,15,18,24],con:[3,5,6,7,8,9,11,12,13,15,16,19,23,24],conal:[4,15],concat:[3,7,8,15,16,18,23],concat_:3,concaten:[0,5],concatin:[0,3,5,23],concern:15,conclus:20,concurr:2,cond:[3,11],condit:[3,8],confer:18,conflict:[11,18],consecut:20,consid:[5,6,7,11,13,16,18,19],consist:[2,7,8,15,16],constant:11,constitu:13,construct:[15,18],consum:[15,18],contain:[0,2,3,5,7,8,13,18,21],content:18,context:2,conting:11,continu:[0,5,13,18,19],control:8,conveni:[4,15,18],convent:15,convers:18,convert:[13,14,16,18,21,23],cool:11,copi:[2,3,6,11,13,15,16,17,20],copyright:8,correspond:[4,15],could:[2,4,5,6,8,10,11,15,18,19],couldn:15,count:[3,18],counter:[6,18],coupl:16,cours:[6,11,18],cover:18,cp:8,cpu:15,crack:11,crash:11,creat:[0,2,3,6,9,11,15,18],creativ:18,crude:[11,18,21],cruft:18,curent:24,current:[2,3,8,13,15,16,18,19,22,24],curri:5,custom:10,cycl:[6,7],cython:8,d010101:5,d0101:5,d01:5,d0:5,d10:5,d1:5,d:[2,3,5,11,13,14,15,16,17,18,19],d_compact:5,dai:8,data:[2,3,5,13],datastructur:[0,2,13,18,20,21,23],datatyp:23,ddididi:19,de:[18,19],deal:[0,5,11,15],dealt:18,debugg:18,decid:11,declar:18,decor:3,decoupl:13,decrement:3,deduc:[6,18],deeper:0,deepli:4,def:[3,5,8,13,14,18,23],defaultdict:[5,18],defi:[],defin:[2,4,5,6,7,8,9,10,12,13,14,15,18,19,20],definit:[0,2,3,6,7,8,10,11,13,16,18,20,24],definitionwrapp:[11,13,16],defint:15,del:17,deleg:8,delet:20,deliber:18,demo:18,demonstr:4,depend:[3,11,13,15],deposit:16,depth:[18,24],dequot:13,der:11,deriv:[2,3,6,8,9,11,18,20],derv:5,describ:[4,5,11,13,15,16,18,21],descript:[6,8],descriptor:18,design:[2,3,11,15,20],desir:[8,16],destin:5,destruct:11,detail:[8,11,18],detect:[5,7,11,13,18],determin:20,develop:[0,7,8,18,20],diagram:6,dialect:1,dict:[1,3,5,18,22],dictionari:[0,1,3,8,18,20,22],did:18,differ:[0,4,6,9,11,12,13,15,23],differenti:4,difficult:18,difficulti:15,dig:[11,19],digit:6,digraph:5,dinfrirst:[8,18,24],dip:[3,6,7,8,9,11,12,13,14,15,16,18,20,24],dipd:[3,7,8,11,12,13,15,18,19,24],dipdd:[3,11],direco:20,direct:8,directli:[6,15,16,18,23],disappear:[2,5,18],discard:[3,7,9,11,13],disciplin:11,disenstacken:[3,8],disk:8,displac:2,displai:18,distiguish:18,distribut:15,ditch:11,div:[3,8,18,24],dive:16,divis:[11,18],divmod:[3,24],divmod_:[3,18],dnd:23,doc:[2,3,8,18],doc_from_stack_effect:17,docstr:18,document:[18,20,21,23],doe:[0,1,3,4,5,7,8,14,15,18,20,22,24],doesn:[6,10,11,15,16,18,23],domain:[4,18],don:[5,6,8,11,18],done:[2,6,8,10,18],dooooc:18,door:8,dot:[5,22],doubl:[5,6,8,18],doublecircl:5,down:[2,5,9,13,19,24],down_to_zero:8,dozen:8,dr:5,draft:[4,10],drag:23,dream:8,drive:[7,9],driven:6,driver:[5,7],drop:[3,11,23],ds:5,dudipd:8,due:18,dup:[3,6,7,8,9,11,12,13,15,17,19,23,24],dupd:[3,18,24],dupdd:[3,24],dupdip:[3,6,11,12,13],duplic:[3,11,13],durat:2,dure:[2,13],e:[2,3,5,7,8,10,11,14,15,17,18,19,22,23],each:[2,3,4,5,6,8,13,14,15,16,18,22,24],easi:[0,11,16,18,19],easier:[3,11,15],easili:4,eat:5,edit:20,ee:[11,18],effect:[2,3,5,8,15,19,20,24],effici:[7,14,19],efg:18,eh:18,either:[1,2,3,5,11,13,18],el:23,elabor:18,eleg:[0,5,8,11,15,20],element:[2,3],elif:18,elimin:[5,18],elliott:[4,15],els:[2,3,5,13,15,18],else_:18,embed:[4,11,19],emit:18,empti:[3,5,8,16,18,23,24],en:11,encapsul:8,enclos:8,encod:7,encount:18,end:[5,6,11,13,16,18,23],endless:7,enforc:[2,8],engend:8,enough:[5,8,13,22,24],enstacken:[7,8,18],enter:8,enter_guard:18,entir:23,entri:[3,19,22],enumer:18,epsilon:9,eq:[2,3,24],equal:[3,6,16,23],equat:[8,9],equival:15,er:[0,8],ergo:[5,11],err:[11,17],error:[8,18,21],essai:0,establish:18,et:[15,18],etc:[3,16,18,19,21],euler:20,euro:18,eval:[0,18],evalu:[1,2,3,8,9,11,12,13,14,15,16,18,22],event:15,eventu:[15,18],ever:18,everi:[1,7,15],everybodi:15,everyth:[3,5,11,12,15,18],evolv:10,examin:13,exampl:[0,3,5,6,18,20,21,23,24],exce:7,except:[1,5,8,11,17,18,21],execut:[0,1,2,3,8,13,14,15,16,18,19,23,24],exend:18,exercis:[5,11],exist:[4,11,18],expand:11,expect:[2,3,15,16,18,23],experi:[8,16],explain:18,explan:8,explor:[8,18],express:[0,1,2,3,4,11,13,14,18,19,20,22,23],expression_to_str:[18,23],extend:18,extra:[1,6,7],extract:[11,12,20],extrem:8,extrememli:8,f0:18,f1:[17,18,24],f2:[17,18,24],f3:[18,24],f:[2,3,5,6,7,9,13,15,18],f_g:18,f_in:18,f_out:18,f_python:18,facet:0,facil:8,fact:21,factor:[2,6,8,11,18],factori:[3,20],fail:[2,3,11,20,21],fail_fail:[],fairli:18,fake:5,fall:18,fals:[2,3,5,6,13,15,18],falsei:18,far:[9,11,13,18,24],fascin:0,favorit:15,fear:[11,18],few:[6,8,9,12,15,18],fewer:[3,8],fg:18,fg_in:18,fg_out:18,fi:[17,18],fib:7,fib_gen:7,fibonacci:20,figur:[2,3,11,13,18],filter:11,fin:6,find:[2,3,5,6,7,15,16,18,20,24],finder:9,fine:[0,5,6,11,18,24],finite_state_machin:5,first:[3,5,7,8,9,11,12,13,14,16,19,20,23,24],first_two:[3,11,24],fit:[6,8],five:[6,8,20],fix:[2,3,5,13,18],fixm:[5,18],flag:[15,18],flatten:[8,16,18],flesh:5,flexibl:20,floatjoytyp:18,floatstarjoytyp:18,floor:3,floordiv:[3,6,24],flow:8,fn:18,fo:[17,18],follow:[0,2,3,5,8,10,13,15,16,18,19],foo:[8,10,11,15,18],foo_ii:10,fork:15,form:[2,3,4,5,6,7,13,16,18,23],forman:8,format:[17,18,20,22],formula:[0,6,20],forth:[8,18],forum:0,forward:18,found:8,four:[0,2,3,6,7,8,11,20],fourteen:6,fourth:[2,3,11,13,24],fr:5,frac:[9,12],fractal:8,fraction0:8,fraction:[2,8],frame:13,framework:8,free:[4,8,11],freeli:2,from:[0,1,2,3,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,23],from_:5,from_index:23,front:[2,3,13],frozenset:5,fulin:15,full:6,fun:[5,20],func:18,functionjoytyp:18,functionwrapp:3,functool:5,fundament:[0,20],funtion:11,further:[9,18,20],futur:15,g:[2,3,5,7,8,9,10,11,13,14,15,17,18,19,22,23],g_in:18,g_out:18,garbag:8,gari:11,gcd2:3,gcd:[3,8],ge:[2,3,24],gener:[0,2,4,13,15,18,20,23,24],generated_librari:3,genrec:[3,8,11,13,15,16,18],geometr:6,get:[2,4,5,6,7,8,12,13,18,20],getch:5,getitem:3,getrecursionlimit:23,getsourc:8,ghc:4,gi:18,give:[4,6,11,13,16,18,23],given:[2,3,6,7,9,11,13,15,18,19,20,23],global:[17,18],glue:8,go:[5,6,11,12,13,15,16,18,19,22],goe:24,good:[6,11,18],grab:18,grammar:21,grand:8,graph:[5,15],graphic:5,graphviz:5,great:[0,8,18,20],greater:23,grind:18,group:0,grow:5,gsra:9,gt:[2,3,24],guard:[11,18],h:[5,13,18],ha:[0,2,3,5,7,8,9,10,11,13,15,18,19,23],had:[5,6,19],haiku:8,half:[6,18,19],hallmark:15,hand:[5,8,14,18,20],handi:[9,18],handl:[11,18,23,24],happen:[8,18],happi:5,hard:[5,18,19],hardwar:4,hasattr:18,hash:18,haskel:4,have:[2,3,5,6,7,8,9,10,13,14,15,18,19,20,23,24],he:[4,9],head:23,heh:18,help:[3,8,11,13,18],help_:3,helper:5,herd:8,here:[5,6,7,11,16,18,19,24],hg:24,hide:11,hierarchi:18,higher:[5,8,11,18],highli:8,hij:5,histori:[18,22],hit:5,hmm:[5,11],hoist:3,hold:[6,18],hood:11,hope:[0,6,8,20],hopefulli:13,host:20,how:[0,4,5,9,11,13,18,19,20],howev:[13,14,15,18],html:[2,3,7,12,13,20],http:[11,24],huet:19,huge:11,hugh:[9,16],human:8,hybrid:24,hylomorph:20,hypothet:2,i0:18,i1:[17,18,24],i2:[17,18,24],i3:[18,24],i:[0,3,6,7,8,9,13,14,15,16,19,20,22,24],id:[3,18],id_:3,idea:[4,6,8,18],ident:[3,5,13,18,24],if_not_empti:11,ift:[3,11,13,16,18,24],ignor:[1,3,11,18],ii:[0,20],iii:20,illustr:[5,13],imagin:[5,15,19],imap:18,imit:[5,16],immedi:[5,13],immut:[5,8,11],imper:13,implement:[0,1,2,4,8,10,11,13,14,15,20,24],implementaion:15,implicit:8,improv:18,includ:[4,11,15,16,18,24],inclus:6,incom:23,incompat:10,incorpor:12,increas:6,increment:[3,4,6,10,15],index:[0,8,18,23],indexerror:23,indic:[15,16,18,23,24],ineffici:18,infer:[0,17],inferenc:24,info:[17,18],inform:[3,5,18,24],infra:[3,7,8,11,12,14,15,16,18,20,24],infrastructur:3,initi:[2,3,5,8,9,11,18],inlin:11,inner:18,inproceed:18,input:[1,9,15,17,18],input_:5,inscrib:3,inscribe_:3,insert:[18,23],insight:13,inspect:8,inspect_stack:18,instal:0,instanc:18,instanti:[4,22],instead:[5,6,7,11,13,18,19,23,24],instruct:5,integ:[2,3,8,13,16,18,21],integr:3,intend:[0,8],interact:[8,20],interest:[0,6,11,18,20],interfer:15,interlud:20,intermedi:13,intern:[0,18,22,23],interp:1,interpret:[0,4,10,14,21,22,24],interrupt:8,intersect:5,interspers:15,interv:[4,6],intjoytyp:18,introduc:10,introduct:0,intstarjoytyp:18,intuit:18,invari:3,invent:18,involv:18,ipf:8,ipython:18,isinst:[5,18],isn:[5,11,19],issubclass:18,item:[2,3,8,11,13,15,16,18,20,23],iter:[1,3,5,8,13,15,16,18,20,23],iter_stack:[14,23],iteritem:[5,18],itertool:[5,18],its:[0,1,2,3,4,6,8,11,13,15,16,18,23],itself:[0,2,8,11,15,18],iv:20,j05cmp:[2,3,13],j:[2,5,6,7,9,11,12,13,14,16,18,19],jaanu:18,jmp:5,job:[15,20],john:[9,16],joi:[2,4,10,11,12,14,15,17],join:[5,18],joypi:[19,24],joytypeerror:17,jp:[7,12],js:8,jump:5,jump_from:5,junk:18,jupyt:20,just:[0,2,3,5,7,8,10,11,13,15,16,18,19,22],juxtaposit:15,k:[6,11,16,18],keep:[5,11,12,15,18,19],kei:[5,16,20],kevin:0,key_n:11,keyerror:[5,11,18],kind:[2,4,8,11,13,16,18,24],kinda:18,kleen:[16,18],kleenestar:18,kleffner:18,know:[6,11,18],knowledg:18,known:[4,15],kstar:5,l:[3,5,11,18],l_kei:11,l_left:11,l_right:11,l_valu:11,la:0,label:[5,18],lambda:[4,5,18],languag:[3,4,5,8,10,11,14,18],larg:[5,18],larger:[20,23],largest:3,last:[6,11,13,18],lastli:7,later:[5,8,16,18],law:2,lazi:18,lazili:9,lcm:6,le:[2,3,24],lead:[5,8,18],leaf:11,lean:8,learn:0,least:[2,6,13,18,23],least_fract:8,leav:[3,6,15],left:[5,8,12,13,15,16,18,19,22,23],leftov:13,legend:5,len:[5,18],length:[3,6,23],lens:13,less:[6,7,8,13,18,23],let:[7,9,11,12,13,16,18,19,20],letter:18,level:[4,5,11,17,18],librari:[0,5,14],like:[2,3,5,6,8,15,16,18,20,21,22,24],limit:[18,24],line:[8,11,12,18,22,24],linear:23,link:[0,5,18],linux:0,list:[0,3,5,6,8,9,11,13,15,16,18,19,22],list_to_stack:[18,23],liter:[1,11,16,18,19,21],literatur:18,littl:[5,7,11,15,18,20],live:20,lk:16,lkei:16,ll:[5,6,7,8,13,16,18,19],load:[6,8],local:18,locat:2,locu:22,log:[17,18],log_2:11,logic:[0,6,20],longer:[11,18],look:[1,5,7,8,9,11,12,15,18],lookup:8,loop:[0,1,3,5,6,18,20,24],lose:18,lot:[5,8,11,18,19],love:6,low:[4,5],lower:6,lowercas:[5,18],lowest:11,lr:5,lshift:[3,24],lt:[2,3,24],m:[0,5,6,8,11,15,16,18],machin:[0,20],machineri:[11,18],macro:8,made:[0,8,15,18,19],magic:18,mai:[2,13,15,24],mail:0,main:[0,3,8,12,15,18,19],mainloop:10,maintain:19,major:10,make:[2,3,4,6,8,11,13,14,15,16,18,19,20],make_gener:9,make_graph:5,manfr:[0,2,3,4,13],mani:[0,5,8,18],manipul:18,manner:12,map:[1,3,5,6,8,10,13,16,18,22],map_:3,marker:8,mask:[6,7],match:[0,1,18,20],materi:0,math:[0,8,9,11,12,18],mathemat:8,matter:[6,9,11,16],max:3,max_:3,maximum:3,mayb:[11,18],mc:18,me:[8,16,18],mean:[4,6,8,9,11,13,16,18,23],meant:[8,11,13,16,23],mem:5,member:[2,3,13],memo:5,mental:8,mention:2,mercuri:[],mess:18,messag:[17,18],meta:[8,11,14],meta_compos:18,method:[0,8,18,20,22],midpoint:6,might:[4,5,7,11,18],mike:11,million:7,min:3,min_:3,mind:18,minimum:3,minor:11,minu:3,mirror:0,miscellan:0,mismatch:18,mix:[8,18],mod:3,mode:18,model:[4,8],modern:0,modif:[7,18],modifi:[8,11,19],modul:[0,1,3,8,18,21],modulo:18,modulu:[3,8,24],moment:18,month:8,more:[0,3,4,5,6,7,8,9,13,14,15,16,18,21,23,24],most:[5,18,24],mostli:0,move:[5,11],movement:2,ms:20,much:[5,6,7,11,13,18,23],muck:11,mul:[3,8,12,17,19,22,24],multi:[],multipl:[20,24],multipli:3,must:[2,3,6,10,13,15,16,18,21],my:[0,6,8,15],myself:18,n0:18,n10001:18,n10002:18,n10003:18,n1001:18,n1002:18,n1003:18,n1:[18,24],n2:[18,24],n3:[18,24],n4:[18,24],n:[2,3,5,6,8,9,11,13,14,16,18,19,23],name:[1,3,5,8,10,11,13,18,19,20,21,22,23,24],narr:18,natur:[5,6,7,11,18],navig:19,ne:[3,24],nearli:18,neat:11,neato:18,necessarili:18,need:[2,3,6,7,9,10,11,13,15,18],neg:[3,12,24],neither:[15,18],ness:5,nest:[3,8,11,19],net:24,network:8,never:[5,10,13],new_def:18,new_f:18,new_fo:18,new_kei:11,new_valu:11,newton:[0,20],next:[5,6,15,16,18,24],nice:[0,5,13,23],niether:2,nk:6,nm:5,node:[5,16,20],node_kei:11,node_valu:11,non:[5,16,18],none:[1,18],nope:16,nor:5,normal:15,not_:3,notat:[8,11],note:[2,5,6,9,11,13,15,18,23],notebook:[6,7,8,18,19,20],notebook_preambl:[2,6,7,9,11,12,13,14,16,18,19],noth:[2,11,15],notic:6,now:[3,5,6,7,8,13,14,16,18,20],ns:18,nth:[3,23],nullari:[8,11,15,18,24],number:[1,2,3,6,7,9,15,23,24],numberjoytyp:18,numberstarjoytyp:18,numer:18,o:[5,7,11,18],object:[5,18,21],observ:6,obviou:7,obvious:18,occur:11,odd:[6,7],off:[2,3,6,7,12,18,19],often:[5,15],oh:11,ok:18,old:[0,2,14],old_k:11,old_kei:11,old_valu:11,omg:[],omit:[13,18,21],onc:[3,5,10,11],one:[2,3,5,6,7,11,13,15,16,18,22,23,24],ones:[5,7,18],onli:[2,3,5,6,11,13,15,18,19,23],onto:[1,2,3,8,13,23],open:[8,18],oper:[0,3,5,8,11,13,20,23],oppos:18,optim:11,option:[1,8,11,18,23],or_:3,orchestr:15,order:[0,2,3,8,13,15,17,18,20,23],org:[0,11],origin:[0,1,2,3,11,19],osdn:24,other:[0,2,3,4,5,8,11,13,16,18,23],otherwis:[3,5,6,7,11,16,18],our:[5,6,7,8,9,13,16,18],out:[2,3,4,6,7,8,9,11,12,13,15,18,19,20],outcom:16,outlin:5,output:[1,5,9,13,15,17,18,24],outsid:4,over:[3,4,6,7,8,9,11,12,15,16,18,20,24],overhaul:18,overview:[3,18],own:[11,18],p:[2,3,6,11,13,15],pack:23,packag:[0,8],page:[0,11,18,23],pair:[2,3,6,7,11,18],palidrom:6,palindrom:6,pam:8,paper:[4,8,13,15,19],paradigm:20,parallel:[2,20],param:1,paramet:[1,2,3,13,14,21,22,23],parameter:20,paramorph:13,parenthes:[11,23],pariti:7,pars:[0,3,5,8],parse_definit:[],parseerror:21,parser:[0,17,18],part:[2,3,9,13,16,20],partial:[5,18],particular:19,pass:[0,5,11,18,22],patch:5,path:[5,18,20],pattern:[5,6,15,16,20],pe1:[6,7],pe2:7,pearl:19,pend:[3,8,13,18,19,22],peopl:20,per:[8,16],perfectli:15,perform:[5,15,18],perhap:7,period:8,permit:[15,18,23],permut:18,persist:11,phase:2,phi:5,pick:[3,6,7,15,23],pickl:8,pictur:11,piec:13,pip:0,place:[3,6,8,18],plai:0,plu:3,plug:[7,13,16],pm:[3,12,18,24],point:[4,5,8,11,13,15],pointless:2,pool:15,pop:[3,5,6,7,8,11,13,14,16,17,23,24],popd:[3,8,9,11,14,15,18,24],popdd:[3,7,12,18,24],popop:[3,6,7,8,9,11,16,18,24],popopd:[3,24],popopdd:[3,24],posit:[3,6,8,13],possibilit:11,possibl:[11,16,18,20],post:8,poswrd:18,potenti:15,pow:[3,24],power:[8,18],pprint:5,pragmat:6,preambl:9,preceed:15,precis:[0,1],pred:[3,18,24],predecessor:3,predic:[2,3,5,7,13,15],prefix:[18,22],preliminari:5,present:18,preserv:[4,16],pretti:[9,11,12,15,16,18,22,23],pretty_print:0,previou:[8,15],prime:9,primit:[2,3,18,20],primrec:[3,7,8,13],print:[0,1,2,3,5,17,18,22,23],probabl:[7,8,11,18],problem:[8,18,20],proc_curr:11,proc_left:11,proc_right:11,proce:[6,24],process:[5,8,16,18,22],produc:[3,6,11,13,16,18],product:[5,7,8,17,18],program:[0,2,3,7,8,9,11,13,15,18,19],programm:[15,18],progress:15,project:[20,24],prolog:18,promis:15,prompt:8,proper:[2,3,13,15,24],properti:0,provid:[0,4,8,15,18,24],pun:[0,8],punctuat:18,pure:[0,5],puriti:8,purpos:8,push:[2,3,8,13,19,23],put:[1,2,7,8,15,18,20,23],pypi:0,python3:8,python:[0,2,3,5,11,13,15,19,20,21,23,24],q:[2,3,11,13,15,18,19],quadrat:[0,20],queri:[11,16],query_kei:16,queu:13,quit:[0,16],quot:[0,3,7,8,11,12,13,15,16,18,19,22],quotat:[2,3,13],quotient:3,r0:[9,11,16],r1:[2,3,9,11,13,16],r2:[2,3,13],r:[2,3,5,11,13,18],r_kei:11,r_left:11,r_right:11,r_valu:11,rais:[5,11,18,21,23],rang:[5,8,18],range_revers:13,range_to_zero:8,ranger:13,ranger_revers:13,rankdir:5,raphson:9,rather:[6,8,13,16],ratio:8,re:[0,6,7,8,9,14,18,20,21],reach:[5,6,7,13],read:[0,1,6,7,11,18,19],readabl:14,reader:[5,11],readi:18,real:11,realiz:[4,11],rearrang:[2,11,18,23],reason:[6,8,15,18],rebuild:[16,19],rec1:[2,3,13],rec2:[2,3,13],recent:18,recogn:21,recombin:15,record:[8,22],recur:[3,13,18],recurs:[0,2,3,5,7,8,9,15,18,20,23],recus:8,redefin:20,redistribut:[3,8],redo:5,reduc:[2,18],redund:23,refactor:[8,10],refer:[0,2],referenti:15,reflect:15,regard:15,regist:2,regular:[18,20,21],reifi:17,reimplement:[15,20],rel:23,relat:[5,18],releas:10,rem:3,remain:[2,8,10,18],remaind:[3,9],rememb:5,remind:18,remot:23,remov:[3,11,18,23,24],render:20,repeat:6,repeatedli:6,repetit:5,repl:[0,1],replac:[0,2,3,7,12,13,15,16,18,19,20,23],repositori:0,repr:[5,18],repres:[2,8,11,15,21,22],represent:23,reprod:7,repurpos:18,requir:[15,18,23],research:18,resembl:8,resolut:15,resourc:15,respect:[5,6,15],rest:[3,6,7,8,11,13,19,20,23,24],rest_two:11,restart:[],restor:2,result:[1,2,3,5,6,11,12,13,15,16,18,19],resum:8,retir:2,retri:8,reus:[11,18,23],revers:[3,6,7,13,18,19,20,23],revisit:18,rewrit:[3,8,18],rewritten:8,rid:11,right:[7,8,12,16,18,20,22,23],rightest:11,rightmost:6,rigor:15,risk:18,rk:16,rkei:16,rob:18,roll:[3,9,11,16],roll_dn:18,rolldown:[3,17,18,24],rollup:[3,18,24],root:[3,9,12],round:[3,18],row:5,rrest:[3,17,18,24],rshift:[3,24],rtype:1,rule:[15,20],run:[0,1,3,6,8,9,11,12,13,15,16,18,19],runtim:15,runtimeerror:23,s0:18,s1:[17,18,24],s2:[17,18],s3:18,s4:18,s5:18,s:[0,1,2,3,4,7,8,10,12,13,14,15,16,17,19,20,22,23,24],sai:[5,7,11,12,16,18],same:[2,4,6,11,15,18,23],sandwich:[2,3,13],save:[2,5,6,8],scan:[],scanner:[8,21],scenario:19,scm:24,scope:[7,11],script:1,se:18,search:[0,11],sec:18,second:[3,8,11,13,16,23,24],section:13,see:[0,5,7,8,9,10,12,13,14,18,19,22],seem:[0,6,8,16,18,24],seen:[18,19],select:3,self:[5,15,18],semant:[2,3,8,10,11,15,18],semi:8,send:8,sens:[0,2,6,18,19],separ:[8,15,18,21],seq:18,sequenc:[0,1,2,3,6,8,11,13,14,19,20,21,24],sequence_to_stack:18,seri:[6,7,11,19],set:[2,3,5,13,18,20],seven:[6,7],sever:[0,4,8,13],shape:[5,15],share:[3,8],shelf:2,shew:5,shift:[6,7],shorter:20,shorthand:11,should:[2,3,5,6,11,13,15,18],shouldn:8,show:[4,15,18,19],shunt:[3,19],side:[5,11,17,18,24],sign:[],signatur:24,signifi:[8,11],similar:[11,16,18],simon:8,simpl:[1,5,8,13,23,24],simplefunctionwrapp:[3,14,18],simpler:16,simplest:[18,20],simpli:4,simplifi:[6,11,19],sinc:[2,6,11,18],singl:[3,7,8,14,15,18,21,24],singleton:5,situ:11,situat:11,six:[6,7,8],sixti:[6,7],size:[5,8,20],skeptic:8,skip:18,slight:9,slightli:[11,13,18],smallest:3,smart:11,sn:18,so:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19,24],softwar:8,solei:2,solut:[6,7],solvabl:8,some:[2,3,5,7,8,11,13,15,16,18,20,23,24],somehow:[11,18],someth:[2,10,11,18],sometim:11,somewher:[11,20],sort:[3,5,11,15,18],sort_:3,sourc:[0,1,3,18,20,21,22,23],space:[6,22],span:6,spawn:18,special:[7,11,20],specif:[0,4],specifi:[11,15],speed:14,spell:[5,16],sphinx:[20,23],spirit:[0,1,16],split:[5,18],sqr:[3,8,9,12,19],sqrt:[3,9,18,24],squar:[3,9,18,21],ss:18,stack:[0,1,3,6,7,9,11,12,13,14,15,16,17,19,20,21,22,24],stack_effect:18,stack_effect_com:18,stack_to_str:[17,23],stacki:18,stackjoytyp:18,stacklistbox:23,stackstarjoytyp:18,stage:16,stai:[0,1],stand:[4,5],standard:[8,11],star:[16,18],stare:11,start:[5,6,7,8,9,11,13,16,18,24],state:[8,20],state_nam:5,statement:[3,5],stdout:[17,18],step:[3,6,8,11,14,18,19,20],still:[5,11,18],stop:11,stopiter:5,storag:[6,11],store:[6,13,18],stori:13,str:[1,5,18,21,22,23],straightforward:[5,7,9,18,20],stream:[6,17,18],stretch:11,string:[1,2,3,8,18,19,20,21,22,23],stringi:5,structur:[8,15,16,18,19,20,23],stuck:5,studi:5,stuff:[11,18],stuncon:[3,24],stununcon:[3,24],style:[0,4,18],sub:[3,10,15,24],subclass:8,subject:[15,19],subsequ:15,subset:[18,24],substitut:[5,11,18],subtract:6,subtyp:20,succ:[3,18,24],succe:18,success:9,suck:18,suffic:18,suffici:11,suffix:18,suggest:[4,5,11],suitabl:[1,3,4,6],sum:[3,7,8,12,13,14,16],sum_:[3,18],summand:6,sumtre:16,suppli:[11,21],support:[8,18,22,23],sure:15,suspect:2,svg:[],swaack:[3,12,14,18,19,24],swap:[3,6,7,8,9,11,13,14,15,16,17,19,24],swon:[3,7,8,13,16,18,19,24],swoncat:[7,8,9,13,16],swuncon:13,sy:[17,18,23],sym:5,symbol:[1,2,3,5,15,18,19,20,21,22],symboljoytyp:18,symmetr:[6,11],symmetri:5,syntact:8,syntax:[8,23],system:[8,11,15],t0:3,t1:3,t:[2,3,5,6,8,10,11,13,15,18,19,23],tabl:[5,18],tag:[5,18,24],tail:[9,11,18,20,23],tailrec:[3,9],take:[3,5,6,8,9,11,13,15,18,23],talk:[8,11,18,23],target:19,tast:4,tbd:8,te:11,tear:13,technic:2,techniqu:[4,19],technolog:2,temporari:19,ten:6,term:[1,2,5,8,9,13,15,18,20,21,23,24],termin:[2,3,5,13],ternari:8,test:[2,3,13],text:[0,1,18],text_to_express:[8,17,21],textual:8,than:[0,3,5,6,7,8,9,13,15,16,18,23,24],thei:[2,5,6,7,8,11,13,15,18,19,21,23],them:[2,5,6,7,11,13,15,18,19,20,24],themselv:[15,18],theori:[2,3,13,15],therefor:7,thi:[0,1,2,3,4,5,6,7,8,9,12,13,15,16,18,19,20,21,22,23,24],thing:[2,7,11,13,15,18,19,21,23,24],think:[2,6,8,11,13,15,16,18],third:[3,7,8,11,24],thirti:6,those:[2,3,5,11,13,18,20,24],though:[6,15],thought:[8,15],thousand:6,thread:[2,15],three:[2,3,5,6,8,11,12,16,18,20],through:[1,6,8,16,18,19,23,24],thun:[2,3,4,10,13,15],thunder:8,thunk:15,time:[3,5,6,8,9,11,13,15,18,19],titl:18,to_check:5,to_index:23,to_set:11,todai:8,todo:[8,21],togeth:[7,8,15,18,20],token:21,toler:20,too:[5,13,18],tool:[8,18],tooo:18,top:[2,3,8,13,18,22,23],total:6,tower:18,trace:[0,8,12,13,19,20,23],traceback:18,traceprint:22,track:[12,18,19],tracker:0,transform:4,transit:5,translat:[4,12,18],trap:5,travers:[0,20],treasur:0,treat:[0,2,3,13,18,20],treatment:7,tree:[0,8,20],treegrind:20,treestep:[0,20],tri:6,triangl:15,triangular_numb:13,trick:[6,18],tricki:18,trobe:0,trove:0,truediv:24,truthi:[3,8,15,18],ts:16,tuck:[3,8,18,24],tupl:[3,5,8,18,23],turn:[2,3,5,18],twice:[11,13],two:[2,3,6,8,9,11,12,13,15,16,17,18,19,20,23,24],txt:[],type:[0,1,4,8,11,13,15,20,21,22,23],typeerror:18,typeless:18,typic:[2,3,12,13],u:[17,18],uh:18,ui:8,unari:8,unarybuiltinwrapp:3,unbalanc:[11,21],unbound:24,unchang:11,uncompil:18,uncon:[3,7,8,11,13,16,19,24],under:[2,3,8,11],underli:[5,15,18],underscor:18,understand:[0,11],undistinguish:11,undocu:8,unfinish:5,unfortun:23,unicod:18,unif:[18,20],unifi:17,union:5,uniqu:[3,5,11,18],unit:[3,8,13,15,24],univers:[0,8,15,18],unknownsymbolerror:1,unlik:15,unnecessari:20,unnecesssari:18,unpack:[2,3,11,23],unpair:6,unquot:[8,16,21],unrol:5,unstack:18,unswon:[3,24],untangl:13,until:[5,7,15],unus:6,unusu:11,unwrap:5,up:[1,2,3,6,7,8,11,13,14,15,18,19,23],updat:[0,17,20,24],uppercas:5,upward:15,us:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,19,20,21,23,24],usag:8,user:16,usual:[0,2,13],util:[0,3,14,17,18],uu:18,v0:24,v:[2,6,7,9,11,12,13,14,16,19,20],valid:18,valu:[0,1,2,3,6,8,9,12,13,14,15,16,18,20,21,23,24],value_n:11,valueerror:[5,18,23],variabl:[18,20],variant:11,variat:[13,15,20],varieti:[4,8],variou:0,ve:[11,18],vener:23,verbos:4,veri:[0,1,4,5,8,11,23],versa:[2,18],version:[0,1,2,5,7,10,16,19,20],vi:20,via:8,vice:[2,18],view:[11,20],viewer:[1,8,10,22],vii:20,visibl:18,von:[0,2,3,4,13],vs:18,vv:18,w:[3,11,13,16,18],wa:[2,6,8,11,15,18,23],waaaai:5,wai:[0,2,3,4,5,6,8,13,14,15,18],wait:15,want:[2,6,7,9,11,13,18],warranti:[3,8],wash:8,wast:8,we:[2,5,6,7,8,9,10,12,13,14,15,18,19,20,23],web:23,websit:[0,6],welcom:8,well:[0,4,8,9,11,18,21],went:18,were:[8,18,19],what:[2,3,4,5,8,11,13,15,16,18,22],whatev:[2,3,13,16,23],when:[6,7,8,11,13,15,18,19,21,23,24],where:[2,3,5,8,11,13,18,20,23],whether:[3,13],which:[0,1,3,5,6,8,9,11,13,15,16,18,19,21,23,24],whole:[2,3,6,13,16,18],whose:7,why:[9,15,16],wiki:11,wikipedia:[0,11,19],wildli:8,wind:8,wire:13,within:[8,11,14,20],without:[2,8,11,12,15,18],won:[11,18,23],word:[0,3,6,8,13,19],work:[0,3,5,6,7,8,9,11,12,13,15,16,19,20,23,24],worker:15,worri:15,worth:6,would:[2,6,7,8,9,11,13,15,18,19,23],wrap:[3,8],wrapper:18,write:[4,5,9,11,13,15,16,18,19,20,23],written:[0,1,9,11,14,18,23],wrong:2,wrote:18,x:[0,3,5,6,8,9,15,19,20],xor:3,xrang:18,y:[2,3,5,15],yang:18,yeah:15,year:[8,18],yet:[11,15,18,19],yield:[2,3,13,18,23],yin:20,you:[0,2,3,5,6,7,8,10,11,12,13,14,15,16,18,19,22,23,24],your:[2,3,8,13,18],yourself:[5,8,11],z:[3,5,15,18,20],zero:[3,5,11,13,15,16,18,21,23],zerodivisionerror:18,zip:[3,5,6,18],zip_:3,zipper:[0,20],zstr:19},titles:["Thun 0.4.1 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","\u2202RE","Developing a Program in Joy","Using <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursion Combinators","Replacing Functions in the Dictionary","The Four Fundamental Operations of Definite Action","Treating Trees II: <code class=\"docutils literal notranslate\"><span class=\"pre\">treestep</span></code>","Type Checking","The Blissful Elegance of Typing Joy","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026","Type Inference of Joy Expressions"],titleterms:{"0":0,"01":5,"1":0,"11":5,"111":5,"2":[7,12,18],"2a":12,"3":[6,18],"4":[0,12,18],"466":7,"5":6,"\u03bb":5,"\u03d5":5,"case":[9,11],"do":16,"function":[2,3,5,8,9,11,13,14,15,16,18],"long":14,"new":11,"p\u00f6ial":18,"try":5,"void":2,"while":[2,15],A:[5,6,7,9,11,14],If:11,In:[11,16],No:[5,10],One:[7,11],The:[6,8,11,13,15,16,18],There:8,With:[5,16],about:20,action:15,ad:11,add:[2,11],address:19,al:13,alphabet:5,altern:16,an:[6,7,8,11,17,18,19],ana:13,analysi:6,anamorph:[2,13],app1:2,app2:2,app3:2,appendix:[11,13,18],appli:15,approxim:9,ar:11,argument:18,auto:3,averag:2,b:[2,12],base:[9,11],binari:[2,11,16],bliss:18,both:11,branch:[2,11,15],brzozowski:5,c:[12,18],can:11,cata:13,catamorph:13,categor:4,chatter:2,check:17,child:11,choic:2,clear:2,cleav:[2,15],cmp:11,code:[8,11],combin:[2,11,13,18],comment:18,compact:5,compar:11,comparison:2,compil:[7,18],compile_:18,compos:18,comput:9,con:[2,18],concat:2,conclus:[13,18],consecut:9,continu:8,current:11,datastructur:[5,8,11,19],deal:18,defin:[11,16],definit:[12,15],delabel:18,delet:11,deriv:[5,12,13,16],design:13,determin:19,develop:6,diagram:5,dialect:0,dictionari:14,dip:[2,19],dipd:2,dipdd:2,direco:7,disenstacken:2,distinguish:18,div:2,doc_from_stack_effect:18,document:0,doe:11,down_to_zero:2,drive:5,drop:2,dup:[2,18],dupd:2,dupdip:2,e:16,effect:18,eleg:18,els:11,empti:11,enstacken:2,equal:11,er:2,essai:20,et:13,euler:[6,7],eval:8,even:7,exampl:[2,8,11,13,16,17],execut:22,explor:5,express:[5,8,21,24],extract:16,f:11,factori:13,fail:17,fibonacci:7,filter:6,find:[9,11,13],finish:15,finit:5,first:[2,6,15,18],five:7,flatten:2,flexibl:16,floordiv:2,formula:12,found:11,four:[13,15],from:[],fsm:5,fulmin:15,fun:13,fundament:15,further:6,gcd:2,gener:[3,5,6,7,9],genrec:2,get:[11,16],getitem:2,given:16,greater:11,group:2,h1:13,h2:13,h3:13,h4:13,handl:15,have:[11,16],help:2,highest:11,host:0,how:[6,7],hybrid:18,hylo:13,hylomorph:13,i:[2,5,11,18],identifi:18,ift:[2,15],ii:[16,18],iii:18,implement:[5,18],indic:0,infer:[18,24],inferenc:18,inform:0,infra:[2,19],integ:6,interest:7,interlud:11,intern:21,interpret:[1,8,18],item:19,iter:[6,11],iv:18,joi:[0,1,3,6,8,13,18,19,20,21,22,23,24],join:15,just:6,kei:11,kind:15,languag:0,larger:5,least_fract:2,left:11,less:11,let:[5,6],letter:5,librari:[3,8,18],like:11,list:[2,23],literari:8,littl:6,logic:[2,18],loop:[2,8,15],lower:11,lshift:2,machin:5,make:[7,9],mani:6,map:[2,15],match:5,math:2,memoiz:5,method:9,min:2,miscellan:2,mod:2,modifi:18,modulu:2,more:11,most:11,mul:[2,18],multipl:[6,7,18],must:11,n:[],name:12,ne:2,neg:2,newton:9,next:9,node:11,non:11,now:11,nullari:2,nulli:5,number:[13,18],one:8,onli:8,oper:15,order:[11,16],osdn:0,other:15,our:11,out:5,over:2,p:16,pack:6,pam:[2,15],para:13,paradigm:18,parallel:15,parameter:[11,16],pars:[2,21],parser:[8,21],part:18,pass:8,path:19,pattern:13,per:11,pop:[2,18],popd:2,popop:2,pow:2,power:7,pred:2,predic:[6,9,11,16],pretty_print:22,primit:13,primrec:2,print:8,problem:[6,7],process:11,product:2,program:[4,6,12,16,20],progress:18,project:[0,6,7],pure:8,put:[11,12,16],python:[8,14,18],quadrat:12,quick:0,quot:[2,23],rang:[2,6,13],range_to_zero:2,re:[5,11],read:8,recur:[9,11],recurs:[11,13,16],redefin:[11,16],refactor:[6,11],refer:3,regular:[5,8],reimplement:16,relabel:18,rem:2,remaind:2,remov:2,render:6,repl:8,replac:[11,14],repres:[5,18],represent:5,reset:7,rest:[2,18],revers:[2,5,17],right:[11,19],rightmost:11,roll:[2,18],rolldown:2,rollup:2,rshift:2,rule:[5,18],run:[2,7],s:[5,6,9,11,18],second:[2,18],select:2,sequenc:[7,15,18,23],set:[9,11],shorter:14,should:8,shunt:2,simpl:18,simplest:6,size:[2,14],sourc:11,special:[13,18],sqr:[2,18],sqrt:[2,12],stack:[2,8,18,23],start:0,state:5,step:[2,13,16],straightforward:12,stream:5,string:5,structur:11,style:8,sub:[2,11],subtyp:18,succ:2,sum:[2,6],swaack:2,swap:[2,18],swon:2,swoncat:2,symbol:[8,13],t:16,tabl:0,tail:13,take:2,term:[6,7,16],ternari:2,text:21,than:11,them:12,thi:11,third:[2,18],three:7,thun:[0,8],time:[2,7],togeth:[11,12,16],token:8,toler:9,trace:[14,22],traceprint:8,trampolin:5,travers:[11,16,19],treat:[11,16],tree:[11,16,19],treegrind:16,treestep:16,triangular:13,truediv:2,truthi:2,tuck:2,two:[5,7],type:[17,18,24],unari:2,unbound:18,uncon:[2,18],unif:17,unifi:18,unit:2,unnecessari:6,unquot:2,unstack:2,up:9,updat:[10,18],us:[7,18],util:[22,23,24],v:18,valu:[7,11],variabl:12,variat:7,version:[6,11,14,18],vi:18,view:8,vii:18,we:[11,16],which:[],within:9,word:2,work:[17,18],write:12,x:[2,7],xor:2,yin:18,z:19,zero:7,zip:2,zipper:19}})
\ No newline at end of file
+Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Derivatives_of_Regular_Expressions","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/Square_Spiral","notebooks/The_Four_Operations","notebooks/Treestep","notebooks/TypeChecking","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack","types"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Derivatives_of_Regular_Expressions.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/Square_Spiral.rst","notebooks/The_Four_Operations.rst","notebooks/Treestep.rst","notebooks/TypeChecking.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst","types.rst"],objects:{"joy.joy":[[1,1,1,"","UnknownSymbolError"],[1,2,1,"","interp"],[1,2,1,"","joy"],[1,2,1,"","repl"],[1,2,1,"","run"]],"joy.library":[[3,2,1,"","BinaryBuiltinWrapper"],[3,3,1,"","Def"],[3,2,1,"","FunctionWrapper"],[3,2,1,"","SimpleFunctionWrapper"],[3,2,1,"","UnaryBuiltinWrapper"],[3,2,1,"","add_aliases"],[3,2,1,"","app1"],[3,2,1,"","app2"],[3,2,1,"","app3"],[3,2,1,"","b"],[3,2,1,"","branch"],[3,2,1,"","choice"],[3,2,1,"","clear"],[3,2,1,"","cmp_"],[3,2,1,"","concat_"],[3,2,1,"","cond"],[3,2,1,"","dip"],[3,2,1,"","dipd"],[3,2,1,"","dipdd"],[3,2,1,"","disenstacken"],[3,2,1,"","divmod_"],[3,2,1,"","drop"],[3,2,1,"","dupdip"],[3,2,1,"","floor"],[3,2,1,"","gcd2"],[3,2,1,"","genrec"],[3,2,1,"","getitem"],[3,2,1,"","help_"],[3,2,1,"","i"],[3,2,1,"","id_"],[3,2,1,"","infra"],[3,2,1,"","initialize"],[3,2,1,"","inscribe"],[3,2,1,"","inscribe_"],[3,2,1,"","loop"],[3,2,1,"","map_"],[3,2,1,"","max_"],[3,2,1,"","min_"],[3,2,1,"","parse"],[3,2,1,"","pm"],[3,2,1,"","pred"],[3,2,1,"","primrec"],[3,2,1,"","remove"],[3,2,1,"","reverse"],[3,2,1,"","select"],[3,2,1,"","sharing"],[3,2,1,"","shunt"],[3,2,1,"","sort_"],[3,2,1,"","sqrt"],[3,2,1,"","step"],[3,2,1,"","succ"],[3,2,1,"","sum_"],[3,2,1,"","take"],[3,2,1,"","times"],[3,2,1,"","unique"],[3,2,1,"","void"],[3,2,1,"","warranty"],[3,2,1,"","words"],[3,2,1,"","x"],[3,2,1,"","zip_"]],"joy.parser":[[22,1,1,"","ParseError"],[22,3,1,"","Symbol"],[22,2,1,"","text_to_expression"]],"joy.utils":[[3,0,0,"-","generated_library"],[23,0,0,"-","pretty_print"],[24,0,0,"-","stack"]],"joy.utils.generated_library":[[3,2,1,"","ccons"],[3,2,1,"","cons"],[3,2,1,"","dup"],[3,2,1,"","dupd"],[3,2,1,"","dupdd"],[3,2,1,"","first"],[3,2,1,"","first_two"],[3,2,1,"","fourth"],[3,2,1,"","over"],[3,2,1,"","pop"],[3,2,1,"","popd"],[3,2,1,"","popdd"],[3,2,1,"","popop"],[3,2,1,"","popopd"],[3,2,1,"","popopdd"],[3,2,1,"","rest"],[3,2,1,"","rolldown"],[3,2,1,"","rollup"],[3,2,1,"","rrest"],[3,2,1,"","second"],[3,2,1,"","stack"],[3,2,1,"","stuncons"],[3,2,1,"","stununcons"],[3,2,1,"","swaack"],[3,2,1,"","swap"],[3,2,1,"","swons"],[3,2,1,"","third"],[3,2,1,"","tuck"],[3,2,1,"","uncons"],[3,2,1,"","unit"],[3,2,1,"","unswons"]],"joy.utils.pretty_print":[[23,3,1,"","TracePrinter"],[23,2,1,"","trace"]],"joy.utils.pretty_print.TracePrinter":[[23,4,1,"","go"],[23,4,1,"","viewer"]],"joy.utils.stack":[[24,2,1,"","concat"],[24,2,1,"","dnd"],[24,2,1,"","expression_to_string"],[24,2,1,"","iter_stack"],[24,2,1,"","list_to_stack"],[24,2,1,"","pick"],[24,2,1,"","stack_to_string"]],joy:[[1,0,0,"-","joy"],[3,0,0,"-","library"],[22,0,0,"-","parser"]]},objnames:{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},terms:{"0":[2,3,5,6,7,8,9,10,11,12,14,15,17,18,19,25],"0000000001585":9,"000000001":9,"01":[6,7],"03":19,"05":5,"0a":19,"0b":[6,7],"0b11100111011011":6,"1":[2,3,5,6,7,8,9,10,11,12,14,15,17,18,19,20,24,25],"10":[2,5,6,7,13,19,25],"100":[5,17,19],"1000":[5,6,7,19],"10000":[5,19],"10001":5,"1001":[5,19],"10010":5,"10011":5,"1002":19,"101":5,"1010":5,"10100":5,"10101":5,"1011":5,"10110":5,"10111":5,"102":17,"1024":2,"103":17,"104":17,"105":17,"106":17,"107":17,"108":17,"109":17,"10946":7,"11":[2,6,7,19,25],"110":[5,6],"1100":5,"11000":5,"11001":5,"1101":5,"11010":5,"11011":5,"1110":5,"11100":5,"11101":5,"1111":5,"11110":5,"11111":5,"12":[2,6,17],"120":13,"122":5,"123":8,"128":7,"13":[2,7,17,25],"1346269":7,"14":[2,6,17],"144":7,"14811":[6,7],"15":[2,6,13,17,19,25],"16":[2,7,12,17,25],"160":2,"17":[11,15,17],"18":[6,8,14,15,17,23],"19":[17,19,25],"196418":7,"1a":19,"1b":19,"2":[2,3,5,6,8,9,10,11,13,14,17,18,20,24,25],"20":[2,6,14,19,25],"2006":19,"2017":[8,19],"2020":25,"207":2,"21":[6,7],"22":[9,19,25],"23":[2,6,7,8,9,11,14,15,17,19,23],"230":7,"231":[6,7],"232":7,"233":7,"233168":[6,7],"234":7,"23rd":19,"24":[2,6,7],"25":[6,7,12,17,18,20,25],"256":7,"2584":7,"26":[2,5,7,19,25],"27":[6,7],"273":10,"28":[7,18,25],"29":[19,25],"2a":19,"2b":19,"3":[2,3,7,8,10,11,12,13,17,18,20,21,24,25],"30":[2,6,19,25],"31":18,"32":[2,7,17],"33":6,"34":[7,18,19,25],"36":9,"37":[18,19,25],"3702":[6,7],"38":[19,25],"3819660112501051":12,"3b":19,"3i":19,"4":[2,6,7,8,9,11,13,17,18,20,24,25],"40":[2,18,19],"4000000":7,"41":[14,19,25],"414":23,"44":[11,17,19,25],"45":[2,6],"46":19,"4613732":7,"46368":7,"466":6,"47":[19,25],"48":[19,25],"49":[17,19,25],"4ac":12,"4m":7,"5":[2,3,5,7,8,11,12,13,14,17,19,21,25],"50":2,"513":23,"529":[2,8],"53":[19,25],"547":8,"55":[6,7],"552":2,"5555555555555554":2,"56":[19,25],"57":[6,7],"5bkei":11,"5d":11,"6":[2,6,9,11,13,17,19,20],"60":6,"610":7,"618033988749895":12,"625":20,"64":7,"66":[6,7],"6945":6,"7":[2,6,7,11,17,19,20,25],"75":2,"795831523312719":[2,9],"8":[2,5,6,7,11,12,17,19,20,25],"80":6,"832040":7,"88":11,"8888":8,"89":7,"9":[2,6,11,12,17,19,25],"90":2,"92":5,"925":6,"978":6,"980":6,"981":6,"984":6,"985":6,"987":6,"99":23,"990":6,"991":6,"992":6,"993":6,"995":6,"996":6,"999":[6,7],"999999999999996":9,"9a9d60354c35":19,"\u03b4":5,"\u03b5":9,"abstract":[8,11],"boolean":[2,3,8,11,16],"break":[5,8,15,19],"byte":[5,6],"case":[2,3,13,16,17,19,24],"char":5,"class":[3,5,8,19,22,23,24],"const":15,"default":[3,7,11,24],"do":[2,3,4,5,6,7,8,11,13,14,15,16,19,20,21],"export":[3,22],"final":[2,11,13,15],"float":[8,19,20,22],"function":[0,1,4,6,7,10,12,15,18,20,21,22,23,24,25],"g\u00e9rard":20,"goto":5,"import":[2,5,6,7,9,11,12,13,14,15,17,18,19,20],"int":[5,7,8,13,15,19,20,22,24],"long":[11,15,19,21],"new":[0,2,3,5,7,8,10,13,14,15,19],"p\u00f6ial":21,"p\u00f6ial06typingtool":19,"public":10,"return":[1,3,5,6,8,11,13,14,16,17,19,22,23,24],"short":15,"static":[2,10],"super":19,"switch":[2,19],"throw":[11,25],"true":[2,3,5,6,13,15,16,19],"try":[7,9,12,13,15,17,18,19,21],"void":[0,3,15],"while":[3,5,8,11,19,22,24],A:[1,3,4,8,13,16,19,21,22,23,24],AND:[5,19],And:[5,6,7,9,11,13,15,16,19,20,24],As:[4,6,11,15,19],At:[6,13,19],Be:2,But:[0,4,6,7,8,11,14,15,19],By:[7,11,19],For:[0,2,3,11,13,14,19,21,24],If:[2,3,5,6,7,8,9,10,12,13,15,17,19,20],In:[2,3,4,6,7,8,13,16,19,20,21,24],It:[0,2,3,4,5,6,7,8,10,11,13,15,19,20,24,25],Its:3,NO:8,NOT:5,No:[0,17,21],Not:19,OR:[5,19],Of:6,On:[3,23],One:[2,8,16,19,21],Or:[5,10,11,15,17,19],TOS:[2,3],That:[6,11],The:[0,1,2,3,4,5,7,9,10,12,20,21,22,23,24,25],Then:[2,3,11,12,13,19],There:[5,12,13,15,16,17,19,24],These:[16,19,21,24],To:[0,5,6,7,9,11,13,17,19],With:[9,13,15,19,21,25],_0:5,_1000:19,_1:5,_:[8,14,19],__:11,__add__:19,__call__:5,__class__:19,__eq__:19,__ge__:19,__hash__:19,__init__:[5,19],__main__:19,__radd__:19,__repr__:19,__str__:23,_and:5,_compaction_rul:5,_con:5,_dictionari:19,_f:19,_ge:19,_infer:19,_interpret:19,_log:19,_log_it:19,_names_for:19,_or:5,_r:19,_spn_e:15,_spn_p:15,_spn_t:15,_templat:5,_to_str:19,_tree_add_:11,_tree_add_e:[3,11,25],_tree_add_p:11,_tree_add_r:11,_tree_add_t:11,_tree_delete_:11,_tree_delete_clear_stuff:[3,11,25],_tree_delete_del:11,_tree_delete_r0:[3,11,25],_tree_delete_r1:11,_tree_delete_rightmost:11,_tree_delete_w:11,_tree_get_:[3,11,25],_tree_get_p:11,_tree_get_r:11,_tree_get_t:11,_tree_iter_order_curr:11,_tree_iter_order_left:11,_tree_iter_order_r:11,_tree_iter_order_right:11,_tree_t:11,_treestep_0:17,_treestep_1:17,_uniqu:19,_within_b:9,_within_p:9,_within_r:9,a0:19,a10001:19,a10002:19,a10003:19,a10004:19,a1:[3,18,19,25],a2:[3,18,19,25],a3:[3,18,19,25],a4:[3,18,19,25],a5:[18,19,25],a_:9,a_i:9,aa:13,ab:[0,3,5,9,15],abbrevi:17,abl:[5,16,19,25],about:[0,8,11,16,19,20,24],abov:[0,5,6,9,11,13,16,19],absolut:8,ac:5,accept:[0,1,2,3,5,6,7,8,11,12,14,15,16,17,19,20],accord:5,accordingli:[11,16],accumul:6,act:[5,25],action:[0,8,14,15,19,20,21],actual:[2,6,8,11,16,19],ad:[4,5,8,10,14,19,21],adapt:[15,21],add:[3,5,6,7,8,14,19,23,25],add_alias:3,add_def:[],add_definit:[11,17],addit:[0,2,3,6,8,13,14,17],address:21,adjust:11,advantag:19,affect:[3,16],after:[5,6,7,8,13,16,19,24,25],afterward:8,again:[2,3,6,8,11,13,19],against:19,aggreg:20,ahead:19,aka:[5,8,20,25],al:[16,19],albrecht:0,algorithm:[5,8,19],alia:3,alias:[3,8],align:[8,23],all:[3,5,6,7,8,11,13,14,15,16,17,19,23,24],alloc:19,allow:[10,11,16],almost:11,along:[5,8,13,19],alphabet:[3,21],alreadi:[5,9,14,19,20],also:[0,5,6,8,11,16,19,23,24],alter:[5,19],altern:[4,19],although:[4,11],altogeth:7,alwai:[6,10,13,16],am:[16,21],amend:16,among:19,amort:11,an:[0,1,2,3,4,5,9,14,15,17,21,24,25],analysi:[4,21],anamorph:[8,21],and_:3,ani:[0,4,5,6,8,10,11,15,16,19,20,22],annual:8,anonym:11,anoth:[5,11,16,19,24,25],anyhow:[16,19],anyjoytyp:19,anymor:19,anystarjoytyp:19,anyth:[2,3,5,8,19,25],apart:19,api:10,app1:3,app2:[3,8,12,13,14,16],app3:[3,16],app:8,appear:[2,4,5,6,11],append:19,appendix:21,appli:[2,3,6,7,11,13,15,19],applic:7,approach:6,appropri:5,approxim:21,ar:[1,2,3,5,6,7,8,10,12,13,16,17,19,20,21,22,24,25],archiv:0,aren:20,arg:[2,3,15],argument:[2,3,8,9,12,13,15,21,23,24],arithmet:2,ariti:[2,16],around:[6,19,22,24],arrang:[15,17],arriv:[7,17],arrow:5,articl:[0,4,7,13],ascii:5,ascii_lowercas:5,ask:[4,7,19],aspect:0,assembl:[5,15],assert:[5,19],assign:[16,24],associ:11,assum:9,asterisk:17,asterix:[19,25],asyncron:16,attack:8,attempt:[0,1,19],attribut:3,attributeerror:19,author:19,auto:[0,19,25],automat:[4,16,19],auxiliari:[5,17],avail:[0,19,25],averag:[8,14],avoid:11,awai:[11,19],awar:2,awkward:[11,13,19],azur:21,b0:3,b1:[3,19,25],b2:25,b3:25,b:[3,5,7,8,9,11,13,16,17,19],back:[3,11,19],backtrack:25,backward:[10,11,12,17],bad:19,bag:8,banana:13,bar:16,barb:13,base:[0,2,3,10,13,17,19],basic:[2,3,8,11],basicconfig:[18,19],bc:5,bd:5,becaas:5,becaus:[2,3,5,8,11,16,17,19,20,24],becom:[0,11,15,17,24],becuas:19,been:[5,9,10,11,19,20],befor:[5,7,8,11],begin:[11,17],behavior:[10,17,25],behaviour:[0,1,19],behind:16,being:[0,16],below:[2,3,5,6,7,11,15,19,20],bespok:8,best:0,better:[6,11,13,19],between:[0,6],beyond:7,biannual:8,bin:5,binari:[0,7,8,21],binary_search_tre:11,binarybuiltinwrapp:3,bind:8,bingo:20,bit:[5,6,7,11,19],blank:22,bliss:[0,21],block:6,bodi:[2,3,5,8,11,16],body_text:[],booktitl:19,bool:[3,13,19,25],borrow:[8,19],both:[2,6,8,12,13,14,15,16,19,24],bottom:7,bounce_to:5,bracket:[8,19,22],branch:[3,5,6,7,13,19,21,25],branch_fals:19,branch_tru:19,breakpoint:8,bring:[6,8,19],bruijn:19,brutal:16,brzozowski:[19,21],brzozowskian:5,btree:[11,17],buck:11,bug:[0,8],build:[7,8,12,13,15,20,24],built:[12,19],bullet:23,bundl:[2,3,13],burgeon:8,c:[0,1,2,3,5,7,9,11,13,15,16,17],calculu:4,call:[1,2,5,8,10,11,13,16,19,23,24],caller:[11,19],can:[0,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,19,20,21,22,24,25],cancel:16,cannot:[18,19,22],captur:8,card:8,care:[6,24],carefulli:20,carri:[7,11],cartesian:4,catamorph:21,categor:[0,21],categori:[4,16],ccc:4,ccon:[3,11,18,19,25],cell:[13,19],certain:[8,24],certainli:11,cf:[7,9,12,13],chain:[3,16],chang:[2,10,11,15,19,20],charact:[5,20],chat:8,chatter:[0,19],check:[0,7,9,19,21],child:17,choic:[3,13],choos:10,chop:12,chose:5,cinf:11,circl:5,circuit:[4,15],cite_not:11,classmethod:[],claus:[3,19],clean:19,clear:[3,6,8],clear_stuff:11,cleav:[8,12,14],client:24,close:[0,1,4],clunki:[6,19],clv:16,cmp:[3,17,21],cmp_:3,code:[1,4,5,12,13,16,19,21,25],codireco:[7,9,15],collaps:13,collect:[4,5,7,8,19],combin:[0,3,6,7,8,9,12,15,16,17,20,21,23,25],combinatorjoytyp:19,come:[8,11,19],command:[8,11,19],comment:16,common:[2,6,16],compar:[3,4,5,15,19],comparison:[0,11],compat:16,compel:4,compil:[2,3,4,5,8,11,14,16,21,25],complement:5,complet:4,complex:[3,16,19,20,25],complic:19,compos:[5,25],composit:19,compostit:19,compound:11,comput:[2,4,5,6,8,12,15,16,19,25],con:[3,5,6,7,8,9,11,12,13,15,16,17,20,24,25],conal:[4,16],concat:[3,7,8,16,17,19,24],concat_:3,concaten:[0,5],concatin:[0,3,5,24],concern:16,conclus:21,concurr:2,cond:[3,11],condit:[3,8],condition:15,confer:19,conflict:[11,19],consecut:21,consid:[5,6,7,11,13,17,19,20],consist:[2,7,8,16,17],constant:11,constitu:13,constraint:15,construct:[0,15,16,19],consum:[15,16,19],contain:[0,2,3,5,7,8,13,15,19,22],content:19,context:2,conting:11,continu:[0,5,13,19,20],control:8,conveni:[4,16,19],convent:16,convers:19,convert:[13,14,17,19,22,24],cool:11,coordin:[0,15],copi:[2,3,6,11,13,15,16,17,18,21],copyright:8,correspond:[4,16],could:[2,4,5,6,8,10,11,16,19,20],couldn:16,count:[3,19],counter:[6,19],coupl:17,cours:[6,11,19],cout:15,cover:19,cp:8,cpu:16,crack:11,crash:11,creat:[0,2,3,6,9,11,16,19],creativ:19,crude:[11,19,22],cruft:19,curent:25,current:[2,3,8,13,15,16,17,19,20,23,25],curri:5,custom:10,cycl:[6,7],cython:8,d010101:5,d0101:5,d01:5,d0:5,d10:5,d1:5,d:[2,3,5,11,13,14,16,17,18,19,20],d_compact:5,dai:8,data:[2,3,5,13],datastructur:[0,2,13,19,21,22,24],datatyp:24,ddididi:20,de:[19,20],deal:[0,5,11,16],dealt:19,debugg:19,decid:11,declar:19,decor:3,decoupl:13,decrement:[0,3],deduc:[6,19],deeper:0,deepli:4,def:[3,5,8,13,14,19,24],defaultdict:[5,19],defi:[],defin:[2,4,5,6,7,8,9,10,12,13,14,15,16,19,20,21],definit:[0,2,3,6,7,8,10,11,13,15,17,19,21,25],definitionwrapp:[11,13,17],defint:16,del:18,deleg:8,delet:21,deliber:19,demo:19,demonstr:4,depend:[3,11,13,16],deposit:17,depth:[19,25],dequot:13,der:11,deriv:[2,3,6,8,9,11,19,21],derv:5,describ:[4,5,11,13,16,17,19,22],descript:[6,8],descriptor:19,design:[2,3,11,16,21],desir:[8,17],destin:5,destruct:11,detail:[8,11,19],detect:[5,7,11,13,19],determin:21,develop:[0,7,8,19,21],diagram:6,dialect:1,dict:[1,3,5,19,23],dictionari:[0,1,3,8,19,21,23],did:19,differ:[0,4,6,9,11,12,13,16,24],differenti:4,difficult:19,difficulti:16,dig:[11,20],digit:6,digraph:5,dinfrirst:[8,15,19,25],dip:[0,3,6,7,8,9,11,12,13,14,15,16,17,19,21,25],dipd:[3,7,8,11,12,13,15,16,19,20,25],dipdd:[3,11],direco:21,direct:8,directli:[6,16,17,19,24],disappear:[2,5,19],discard:[3,7,9,11,13],disciplin:11,disenstacken:[3,8],disk:8,displac:2,displai:19,distiguish:19,distribut:16,ditch:11,div:[3,8,19,25],dive:17,divis:[11,19],divmod:[3,25],divmod_:[3,19],dnd:24,doc:[2,3,8,19],doc_from_stack_effect:18,docstr:19,document:[19,21,22,24],doe:[0,1,3,4,5,7,8,14,16,19,21,23,25],doesn:[6,10,11,15,16,17,19,24],domain:[4,19],don:[5,6,8,11,19],done:[2,6,8,10,19],dooooc:19,door:8,dot:[5,23],doubl:[5,6,8,19],doublecircl:5,down:[2,5,9,13,20,25],down_to_zero:8,dozen:8,dr:5,draft:[4,10],drag:24,dream:8,drive:[7,9],driven:6,driver:[5,7],drop:[3,11,24],ds:5,dudipd:8,due:19,dup:[3,6,7,8,9,11,12,13,15,16,18,20,24,25],dupd:[3,19,25],dupdd:[3,25],dupdip:[3,6,11,12,13,15],duplic:[3,11,13],durat:2,dure:[2,13],e:[2,3,5,7,8,10,11,14,16,18,19,20,23,24],each:[2,3,4,5,6,8,13,14,15,16,17,19,23,25],easi:[0,11,15,17,19,20],easier:[3,11,16],easili:4,eat:5,edit:21,ee:[11,19],effect:[2,3,5,8,16,20,21,25],effici:[7,14,20],efg:19,eh:19,either:[1,2,3,5,11,13,19],el:24,elabor:19,eleg:[0,5,8,11,16,21],element:[2,3],elif:19,elimin:[5,19],elliott:[4,16],els:[2,3,5,13,15,16,19],else_:19,embed:[4,11,20],emit:19,empti:[3,5,8,17,19,24,25],en:11,encapsul:8,enclos:8,encod:7,encount:19,end:[5,6,11,13,17,19,24],endless:7,enforc:[2,8],engend:8,enough:[5,8,13,23,25],enstacken:[7,8,19],enter:8,enter_guard:19,entir:24,entri:[3,20,23],enumer:19,epsilon:9,eq:[2,3,25],equal:[3,6,17,24],equat:[8,9],equival:16,er:[0,8],ergo:[5,11],err:[11,18],error:[8,19,22],essai:0,establish:19,et:[16,19],etc:[3,17,19,20,22],euler:21,euro:19,eval:[0,19],evalu:[1,2,3,8,9,11,12,13,14,16,17,19,23],event:16,eventu:[16,19],ever:19,everi:[1,7,16],everybodi:16,everyth:[3,5,11,12,16,19],evolv:10,examin:13,exampl:[3,5,6,19,21,22,24,25],exce:7,except:[1,5,8,11,18,19,22],execut:[0,1,2,3,8,13,14,16,17,19,20,24,25],exend:19,exercis:[5,11],exist:[4,11,19],expand:11,expect:[2,3,16,17,19,24],experi:[8,17],explain:19,explan:8,explor:[8,19],express:[0,1,2,3,4,11,13,14,15,19,20,21,23,24],expression_to_str:[19,24],extend:19,extra:[1,6,7],extract:[11,12,21],extrem:8,extrememli:8,f0:19,f1:[18,19,25],f2:[18,19,25],f3:[19,25],f:[2,3,5,6,7,9,13,15,16,19],f_g:19,f_in:19,f_out:19,f_python:19,facet:0,facil:8,fact:22,factor:[2,6,8,11,15,19],factori:[3,21],fail:[2,3,11,21,22],fail_fail:[],fairli:19,fake:5,fall:19,fals:[2,3,5,6,13,15,16,19],falsei:19,familiar:[0,15],far:[9,11,13,19,25],fascin:0,favorit:16,fear:[11,19],few:[6,8,9,12,16,19],fewer:[3,8],fg:19,fg_in:19,fg_out:19,fi:[18,19],fib:7,fib_gen:7,fibonacci:21,figur:[2,3,11,13,19],file:15,filter:11,fin:6,find:[2,3,5,6,7,16,17,19,21,25],finder:9,fine:[0,5,6,11,19,25],finite_state_machin:5,first:[3,5,7,8,9,11,12,13,14,17,20,21,24,25],first_two:[3,11,25],fit:[6,8],five:[6,8,21],fix:[2,3,5,13,19],fixm:[5,19],flag:[16,19],flatten:[8,17,19],flesh:5,flexibl:21,floatjoytyp:19,floatstarjoytyp:19,floor:3,floordiv:[3,6,25],flow:8,fn:19,fo:[18,19],follow:[0,2,3,5,8,10,13,16,17,19,20],foo:[8,10,11,16,19],foo_ii:10,fork:16,form:[2,3,4,5,6,7,13,17,19,21,24],forman:8,format:[18,19,21,23],formula:[0,6,21],forth:[8,19],forum:0,forward:19,found:8,four:[0,2,3,6,7,8,11,15,21],fourteen:6,fourth:[2,3,11,13,25],fr:5,frac:[9,12],fractal:8,fraction0:8,fraction:[2,8],frame:13,framework:8,free:[4,8,11],freeli:2,from:[0,1,2,3,5,6,7,8,9,11,12,14,15,16,17,18,19,20,21,24],from_:5,from_index:24,front:[2,3,13],frozenset:5,fulin:16,full:6,fun:[5,21],func:19,functionjoytyp:19,functionwrapp:3,functool:5,fundament:[0,21],funtion:11,further:[9,19,21],futur:16,g:[2,3,5,7,8,9,10,11,13,14,16,18,19,20,23,24],g_in:19,g_out:19,garbag:8,gari:11,gcd2:3,gcd:[3,8],ge:[2,3,25],gener:[0,2,4,16,19,21,24,25],generated_librari:3,genrec:[3,8,11,13,16,17,19],geometr:6,get:[2,4,5,6,7,8,12,13,19,21],getch:5,getitem:3,getrecursionlimit:24,getsourc:8,ghc:4,gi:19,give:[4,6,11,13,15,17,19,24],given:[2,3,6,7,9,11,15,16,19,20,21,24],global:[18,19],glue:8,go:[5,6,11,12,13,15,16,17,19,20,23],goe:25,good:[6,11,19],grab:19,grammar:22,grand:8,graph:16,graphic:5,graphviz:5,great:[0,8,19,21],greater:24,grind:19,group:0,grow:5,gsra:9,gt:[2,3,25],guard:[11,19],h:[5,13,19],ha:[0,2,3,5,7,8,9,10,11,13,16,19,20,24],had:[5,6,20],haiku:8,half:[6,19,20],hallmark:16,hand:[5,8,14,19,21],handi:[9,19],handl:[11,19,24,25],happen:[8,19],happi:5,hard:[5,19,20],hardwar:4,hasattr:19,hash:19,haskel:4,have:[2,3,5,6,7,8,9,10,13,14,15,16,19,20,21,24,25],he:[4,9],head:24,heh:19,help:[0,3,8,11,13,15,19],help_:3,helper:5,herd:8,here:[0,5,6,7,11,15,17,19,20,25],hg:25,hide:11,hierarchi:19,higher:[5,8,11,19],highli:8,hij:5,histori:[19,23],hit:5,hmm:[5,11],hoist:3,hold:[6,19],hood:11,hope:[0,6,8,21],hopefulli:13,host:21,how:[0,4,5,9,11,13,15,19,20,21],howev:[13,14,16,19],html:[2,3,7,12,13,21],http:[11,25],huet:20,huge:11,hugh:[9,17],human:8,hybrid:[15,25],hylomorph:21,hypothet:2,i0:19,i1:[18,19,25],i2:[18,19,25],i3:[19,25],i:[0,3,6,7,8,9,13,14,15,16,17,20,21,23,25],id:[3,19],id_:3,idea:[4,6,8,19],ident:[3,5,13,19,25],if_not_empti:11,ift:[0,3,11,13,15,17,19,25],ignor:[1,3,11,19],ii:[0,15,21],iii:21,illustr:[5,13],imagin:[5,16,20],imap:19,imit:[5,17],immedi:[5,13],immut:[5,8,11],imper:13,implement:[0,1,2,4,8,10,11,13,14,16,21,25],implementaion:16,implicit:8,improv:19,includ:[4,11,16,17,19,25],inclus:6,incom:24,incompat:10,incorpor:12,increas:6,increment:[0,3,4,6,10,16],index:[0,8,19,24],indexerror:24,indic:[16,17,19,24,25],ineffici:19,infer:[0,18],inferenc:25,info:[18,19],inform:[3,5,19,25],infra:[3,7,8,11,12,14,15,16,17,19,21,25],infrastructur:3,initi:[2,3,5,8,9,11,19],inlin:11,inner:19,inproceed:19,input:[1,9,16,18,19],input_:5,inscrib:3,inscribe_:3,insert:[19,24],insight:13,inspect:8,inspect_stack:19,instal:0,instanc:19,instanti:[4,23],instead:[5,6,7,11,13,15,19,20,24,25],instruct:5,integ:[0,2,3,8,15,17,19,22],integr:3,intend:[0,8],interact:[8,21],interest:[0,6,11,19,21],interfer:16,interlud:21,intermedi:13,intern:[0,19,23,24],interp:1,interpret:[0,4,10,14,22,23,25],interrupt:8,intersect:5,interspers:16,interv:[4,6],intjoytyp:19,introduc:10,introduct:0,intstarjoytyp:19,intuit:19,invari:3,invent:19,involv:19,ipf:8,ipython:19,isinst:[5,19],isn:[5,11,20],issubclass:19,item:[2,3,8,11,13,16,17,19,21,24],iter:[1,3,5,8,13,16,17,19,21,24],iter_stack:[14,24],iteritem:[5,19],itertool:[5,19],its:[0,1,2,3,4,6,8,11,13,15,16,17,19,24],itself:[0,2,8,11,16,19],iv:21,j05cmp:[2,3,13],j:[2,5,6,7,9,11,12,13,14,15,17,19,20],jaanu:19,jmp:5,job:[16,21],john:[9,17],joi:[2,4,10,11,12,14,16,18],join:[5,19],joypi:[20,25],joytypeerror:18,jp:[7,12],js:8,jump:5,jump_from:5,junk:19,jupyt:21,just:[0,2,3,5,7,8,10,11,13,15,16,17,19,20,23],juxtaposit:16,k:[6,11,17,19],keep:[5,11,12,16,19,20],kei:[5,17,21],kevin:0,key_n:11,keyerror:[5,11,19],kind:[0,2,4,8,11,13,15,17,19,25],kinda:19,kleen:[17,19],kleenestar:19,kleffner:19,know:[6,11,19],knowledg:19,known:[4,16],kstar:5,l:[3,5,11,19],l_kei:11,l_left:11,l_right:11,l_valu:11,la:0,label:[5,19],lambda:[4,5,19],languag:[3,4,5,8,10,11,14,19],larg:[5,19],larger:[21,24],largest:3,last:[6,11,13,19],lastli:7,later:[5,8,15,17,19],law:2,layout:[0,15],lazi:19,lazili:9,lcm:6,le:[2,3,25],lead:[5,8,19],leaf:11,lean:8,learn:0,least:[2,6,13,19,24],least_fract:8,leav:[3,6,15,16],left:[5,8,12,13,16,17,19,20,23,24],leftov:13,legend:5,legibl:[0,15],len:[5,19],length:[3,6,24],lens:13,less:[6,7,8,13,19,24],let:[7,9,11,12,13,15,17,19,20,21],letter:19,level:[4,5,11,18,19],librari:[0,5,14],like:[0,2,3,5,6,8,15,16,17,19,21,22,23,25],limit:[19,25],line:[8,11,12,19,23,25],linear:24,link:[0,5,19],linux:0,list:[0,3,5,6,8,9,11,16,17,19,20,23],list_to_stack:[19,24],liter:[1,11,17,19,20,22],literatur:19,littl:[0,5,7,11,15,16,19,21],live:21,lk:17,lkei:17,ll:[5,6,7,8,13,15,17,19,20],load:[6,8],local:19,locat:2,locu:23,log:[18,19],log_2:11,logic:[0,6,15,21],longer:[11,19],look:[1,5,7,8,9,11,12,15,16,19],lookup:8,loop:[0,1,3,5,6,19,21,25],lose:19,lot:[5,8,11,19,20],love:6,low:[4,5],lower:6,lowercas:[5,19],lowest:11,lr:5,lshift:[3,25],lt:[2,3,25],m:[0,5,6,8,11,15,16,17,19],machin:[0,21],machineri:[11,19],macro:8,made:[0,8,16,19,20],magic:19,mai:[2,13,16,25],mail:0,main:[0,3,8,12,15,16,19,20],mainloop:10,maintain:20,major:10,make:[2,3,4,6,8,11,13,14,15,16,17,19,20,21],make_gener:[9,15],make_graph:5,manfr:[0,2,3,4,13],mani:[0,5,8,19],manipul:19,manner:12,map:[1,3,5,6,8,10,13,17,19,23],map_:3,marker:8,mask:[6,7,15],match:[0,1,19,21],materi:0,math:[0,8,9,11,12,19],mathemat:8,matter:[6,9,11,17],max:3,max_:3,maximum:3,mayb:[11,19],mc:19,me:[8,17,19],mean:[4,6,8,9,11,13,17,19,24],meant:[8,11,13,17,24],mem:5,member:[2,3,13],memo:5,mental:8,mention:2,mercuri:[],mess:19,messag:[18,19],meta:[8,11,14],meta_compos:19,method:[0,8,19,21,23],midpoint:6,might:[0,4,5,7,11,15,19],mike:11,million:7,min:3,min_:3,mind:19,minimum:3,minor:11,minu:3,mirror:0,miscellan:0,mismatch:19,mix:[8,19],mod:3,mode:19,model:[4,8],modern:0,modif:[7,19],modifi:[8,11,20],modul:[0,1,3,8,19,22],modulo:19,modulu:[3,8,25],moment:19,month:8,more:[0,3,4,5,6,7,8,9,13,14,16,17,19,22,24,25],most:[5,19,25],mostli:0,move:[5,11],movement:2,ms:21,much:[5,6,7,11,13,19,24],muck:11,mul:[3,8,12,18,20,23,25],multi:[],multipl:[21,25],multipli:3,must:[2,3,6,10,13,16,17,19,22],my:[0,6,8,16],myself:19,n0:19,n10001:19,n10002:19,n10003:19,n1001:19,n1002:19,n1003:19,n1:[19,25],n2:[19,25],n3:[19,25],n4:[19,25],n:[2,3,5,6,8,9,11,14,15,17,19,20,24],name:[1,3,5,8,10,11,13,19,20,21,22,23,24,25],narr:19,natur:[5,6,7,11,19],navig:20,ne:[3,25],nearli:19,neat:11,neato:19,necessarili:19,need:[2,3,6,7,9,10,11,13,15,16,19],neg:[3,12,25],neither:[16,19],ness:5,nest:[3,8,11,20],net:25,network:8,never:[5,10,13],new_def:19,new_f:19,new_fo:19,new_kei:11,new_valu:11,newton:[0,21],next:[0,5,6,15,16,17,19,25],nice:[0,5,13,24],niether:2,nk:6,nm:5,node:[5,17,21],node_kei:11,node_valu:11,non:[5,17,19],none:[1,19],nope:17,nor:5,normal:16,not_:3,notat:[0,8,11,15],note:[2,5,6,9,11,13,16,19,24],notebook:[6,7,8,19,20,21],notebook_preambl:[2,6,7,9,11,12,13,14,15,17,19,20],noth:[2,11,16],notic:6,now:[3,5,6,7,8,13,14,17,19,21],ns:19,nth:[3,24],nullari:[8,11,15,16,19,25],number:[0,1,2,3,6,7,9,15,16,24,25],numberjoytyp:19,numberstarjoytyp:19,numer:19,o:[5,7,11,19],object:[5,19,22],observ:6,obviou:7,obvious:19,occur:11,odd:[6,7],off:[2,3,6,7,12,15,19,20],often:[5,16],oh:11,ok:19,old:[0,2,14],old_k:11,old_kei:11,old_valu:11,omg:5,omit:[13,19,22],onc:[3,5,10,11],one:[0,2,3,5,6,7,11,13,15,16,17,19,23,24,25],ones:[5,7,19],onli:[2,3,5,6,11,13,15,16,19,20,24],onto:[1,2,3,8,13,24],open:[8,19],oper:[0,3,5,8,11,13,21,24],oppos:19,optim:11,option:[1,8,11,19,24],or_:3,orchestr:16,order:[0,2,3,8,13,16,18,19,21,24],org:[0,11],origin:[0,1,2,3,11,20,21],osdn:25,other:[0,2,3,4,5,8,11,13,15,17,19,24],otherwis:[3,5,6,7,11,17,19],our:[5,6,7,8,9,13,15,17,19],out:[2,3,4,6,7,8,9,11,12,13,15,16,19,20,21],outcom:17,outlin:5,output:[1,5,9,13,16,18,19,25],outsid:4,over:[3,4,6,7,8,9,11,12,16,17,19,21,25],overhaul:19,overview:[3,19],own:[11,19],p:[2,3,6,11,13,16],pack:24,packag:[0,8],page:[0,11,19,24],pair:[0,2,3,6,7,11,15,19],palidrom:6,palindrom:6,pam:8,paper:[4,8,13,16,20],paradigm:21,parallel:[2,21],param:1,paramet:[1,2,3,13,14,22,23,24],parameter:21,paramorph:13,parenthes:[11,24],pariti:7,pars:[0,3,5,8],parse_definit:[],parseerror:22,parser:[0,18,19],part:[2,3,9,13,17,21],partial:[5,19],particular:20,pass:[0,5,11,19,23],patch:5,path:[5,15,19,21],pattern:[5,6,16,17,21],pe1:[6,7],pe2:7,pearl:20,pend:[3,8,13,19,20,23],peopl:21,per:[8,17],perfectli:16,perform:[5,16,19],perhap:7,period:8,permit:[16,19,24],permut:19,persist:11,phase:2,phi:5,phrase:15,pick:[3,6,7,16,24],pickl:8,pictur:11,piec:[13,21],pip:0,place:[3,6,8,19],plai:0,plu:3,plug:[7,13,17],pm:[3,12,19,25],point:[4,5,8,11,13,15,16],pointless:2,pool:16,pop:[0,3,5,6,7,8,11,13,14,15,17,18,24,25],popd:[3,8,9,11,14,16,19,25],popdd:[3,7,12,19,25],popop:[3,6,7,8,9,11,17,19,25],popopd:[3,25],popopdd:[3,25],posit:[3,6,8,13],possibilit:11,possibl:[11,17,19,21],post:8,poswrd:19,potenti:16,pow:[3,25],power:[8,19],pprint:5,pragmat:6,preambl:9,preceed:16,precis:[0,1],pred:[3,19,25],predecessor:3,predic:[2,3,5,7,13,16],prefix:[19,23],preliminari:5,present:19,preserv:[4,17],pretti:[9,11,12,16,17,19,23,24],pretty_print:0,previou:[8,16],prime:9,primit:[2,3,19,21],primrec:[3,7,8,13],print:[0,1,2,3,5,18,19,23,24],probabl:[7,8,11,19],problem:[8,15,19,21],proc_curr:11,proc_left:11,proc_right:11,proce:[6,25],process:[5,8,17,19,23],produc:[3,6,11,13,17,19],product:[5,7,8,18,19],program:[0,2,3,7,8,9,11,13,15,16,19,20],programm:[16,19],progress:16,project:[21,25],prolog:19,promis:16,prompt:8,proper:[2,3,13,16,25],properti:0,provid:[0,4,8,16,19,25],pseudo:15,pun:[0,8],punctuat:19,pure:[0,5],puriti:8,purpos:8,push:[2,3,8,13,20,24],put:[1,2,7,8,16,19,21,24],pypi:0,python3:8,python:[0,2,3,5,11,13,16,20,21,22,24,25],q:[2,3,11,13,16,19,20],quadrat:[0,21],quasi:15,queri:[11,17],query_kei:17,queu:13,quit:[0,17],quot:[0,3,7,8,11,12,13,15,16,17,19,20,23],quotat:[2,3,13],quotient:3,r0:[9,11,17],r1:[2,3,9,11,13,17],r2:[2,3,13],r:[2,3,5,11,13,19],r_kei:11,r_left:11,r_right:11,r_valu:11,rais:[5,11,19,22,24],rang:[5,8,19],range_revers:13,range_to_zero:8,ranger:13,ranger_revers:13,rankdir:5,raphson:9,rather:[6,8,13,15,17],ratio:8,re:[0,6,7,8,9,14,15,19,21,22],reach:[5,6,7,13],read:[0,1,6,7,11,19,20],readabl:14,reader:[5,11],readi:19,readm:15,real:11,realiz:[4,11,15],rearrang:[2,11,19,24],reason:[6,8,16,19],rebuild:[17,20],rec1:[2,3,13],rec2:[2,3,13],recent:19,recogn:22,recombin:16,record:[8,23],recur:[3,13,19],recurs:[0,2,3,5,7,8,9,16,19,21,24],recus:8,redefin:21,redistribut:[3,8],redo:5,reduc:[2,19],redund:24,refactor:[8,10],refer:[0,2],referenti:16,reflect:16,regard:16,region:15,regist:2,regular:[19,21,22],reifi:18,reimplement:[16,21],rel:24,relat:[5,19],releas:10,rem:3,remain:[2,8,10,19],remaind:[3,9],rememb:5,remind:19,remot:24,remov:[3,11,19,24,25],render:21,repeat:6,repeatedli:6,repetit:5,repl:[0,1],replac:[0,2,3,7,12,13,16,17,19,20,21,24],repositori:0,repr:[5,19],repres:[2,8,11,16,22,23],represent:24,reprod:7,repurpos:19,requir:[15,16,19,24],research:19,resembl:8,resolut:16,resourc:16,respect:[5,6,16],rest:[3,6,7,8,11,13,15,20,21,24,25],rest_two:11,restart:[],restor:2,result:[1,2,3,5,6,11,12,13,16,17,19,20],resum:8,retir:2,retri:8,reus:[11,19,24],revers:[3,6,7,13,19,20,21,24],revisit:19,rewrit:[3,8,15,19],rewritten:8,rid:11,right:[7,8,12,17,19,21,23,24],rightest:11,rightmost:6,rigor:16,risk:19,rk:17,rkei:17,rob:19,roll:[3,9,11,17],roll_dn:19,rolldown:[3,18,19,25],rollup:[3,19,25],root:[3,9,12],rough:15,round:[3,19],row:5,rrest:[3,18,19,25],rshift:[3,25],rtype:1,rule:[16,21],run:[0,1,3,6,8,9,11,12,13,15,16,17,19,20],runtim:16,runtimeerror:24,s0:19,s1:[18,19,25],s2:[18,19],s3:19,s4:19,s5:19,s:[0,1,2,3,4,7,8,10,12,13,14,15,16,17,18,20,21,23,24,25],sai:[5,7,11,12,15,17,19],same:[2,4,6,11,16,19,24],sandwich:[2,3,13],save:[2,5,6,8],scan:[],scanner:[8,22],scenario:20,scm:25,scope:[7,11],script:1,se:19,search:[0,11],sec:19,second:[3,8,11,13,15,17,24,25],section:13,see:[0,5,7,8,9,10,12,13,14,15,19,20,23],seem:[0,6,8,15,17,19,25],seen:[19,20],select:3,self:[5,16,19],semant:[2,3,8,10,11,16,19],semi:8,send:8,sens:[0,2,6,19,20],separ:[8,16,19,22],seq:19,sequenc:[0,1,2,3,6,8,11,13,14,20,21,22,25],sequence_to_stack:19,seri:[6,7,11,15,20],set:[2,3,5,13,19,21],seven:[6,7],sever:[0,4,8,13],shape:[5,16],share:[3,8],shelf:2,shew:5,shift:[6,7],shorter:21,shorthand:11,should:[2,3,5,6,11,13,16,19],shouldn:8,show:[4,15,16,19,20],shunt:[3,20],side:[5,11,18,19,25],sign:[],signatur:25,signifi:[8,11],similar:[11,15,17,19],simon:8,simpl:[1,5,8,13,15,24,25],simplefunctionwrapp:[3,14,19],simpler:17,simplest:[19,21],simpli:4,simplifi:[6,11,20],sinc:[2,6,11,15,19],singl:[3,7,8,14,15,16,19,22,25],singleton:5,situ:11,situat:11,six:[6,7,8],sixti:[6,7],size:[5,8,21],skeptic:8,skip:19,slight:9,slightli:[11,13,19],smallest:3,smart:11,sn:19,so:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,25],softwar:8,solei:2,solut:[6,7],solvabl:8,some:[0,2,3,5,7,8,11,13,15,16,17,19,21,24,25],somehow:[11,19],someth:[2,10,11,19],sometim:11,somewher:[11,21],sort:[3,5,11,16,19],sort_:3,sourc:[0,1,3,19,21,22,23,24],space:[6,23],span:6,spawn:19,special:[7,11,21],specif:[0,4],specifi:[11,16],speed:14,spell:[5,17],sphinx:[21,24],spiral:[0,21],spiral_next:15,spirit:[0,1,17],split:[5,19],sqr:[3,8,9,12,20],sqrt:[3,9,19,25],squar:[0,3,9,19,21,22],square_spir:[],ss:19,stack:[0,1,3,6,7,9,11,12,13,14,15,16,17,18,20,21,22,23,25],stack_effect:19,stack_effect_com:19,stack_to_str:[18,24],stacki:19,stackjoytyp:19,stacklistbox:24,stackoverflow:15,stackstarjoytyp:19,stage:17,stai:[0,1],stand:[4,5],standard:[8,11],star:[17,19],stare:11,start:[5,6,7,8,9,11,13,17,19,25],state:[8,21],state_nam:5,statement:[3,5,15],stdout:[18,19],step:[3,6,8,11,14,19,20,21],stepper:15,still:[5,11,19],stop:11,stopiter:5,storag:[6,11],store:[6,13,19],stori:13,str:[1,5,19,22,23,24],straightforward:[5,7,9,15,19,21],stream:[6,18,19],stretch:11,string:[1,2,3,8,19,20,21,22,23,24],stringi:5,structur:[8,16,17,19,20,21,24],stuck:5,studi:5,stuff:[11,19],stuncon:[3,25],stununcon:[3,25],style:[0,4,19],sub:[3,10,16,25],subclass:8,subject:[16,20],subsequ:16,subset:[19,25],substitut:[5,11,19],subtract:6,subtyp:21,succ:[3,19,25],succe:19,success:9,suck:19,suffic:19,suffici:11,suffix:19,suggest:[4,5,11],suitabl:[1,3,4,6],sum:[3,7,8,12,13,14,17],sum_:[3,19],summand:6,sumtre:17,suppli:[11,22],support:[8,19,23,24],sure:16,suspect:2,svg:5,swaack:[3,12,14,15,19,20,25],swap:[3,6,7,8,9,11,13,14,15,16,17,18,20,25],swon:[3,7,8,13,17,19,20,25],swoncat:[7,8,9,13,17],swuncon:13,sy:[18,19,24],sym:5,symbol:[1,2,3,5,16,19,20,21,22,23],symboljoytyp:19,symmetr:[6,11,15],symmetri:[5,15],syntact:8,syntax:[8,24],system:[8,11,16],t0:3,t1:3,t:[2,3,5,6,8,10,11,13,15,16,19,20,24],tabl:[5,19],tag:[5,19,25],tail:[9,11,19,21,24],tailrec:[3,9],take:[3,5,6,8,9,11,13,15,16,19,24],talk:[8,11,19,24],target:20,tast:4,tbd:8,te:11,tear:13,technic:2,techniqu:[4,20],technolog:2,temporari:20,ten:6,term:[1,2,5,8,9,13,16,19,21,22,24,25],termin:[2,3,5,13],ternari:8,test:[2,3,13],text:[0,1,19],text_to_express:[8,18,22],textual:8,than:[0,3,5,6,7,8,9,13,16,17,19,24,25],thei:[2,5,6,7,8,11,13,15,16,19,20,22,24],them:[0,2,5,6,7,11,13,15,16,19,20,21,25],themselv:[16,19],theori:[2,3,13,16],therefor:7,thi:[0,1,2,3,4,5,6,7,8,9,12,13,15,16,17,19,20,21,22,23,24,25],thing:[2,7,11,13,16,19,20,22,24,25],think:[2,6,8,11,13,16,17,19],third:[3,7,8,11,25],thirti:6,those:[2,3,5,11,13,15,19,21,25],though:[6,16],thought:[8,16],thousand:6,thread:[2,16],three:[2,3,5,6,8,11,12,15,17,19,21],through:[1,6,8,17,19,20,24,25],thun:[2,3,4,10,13,16],thunder:8,thunk:16,time:[3,5,6,8,9,11,13,15,16,19,20],titl:19,to_check:5,to_index:24,to_set:11,todai:8,todo:[8,22],togeth:[7,8,16,19,21],token:22,toler:21,too:[5,13,19],tool:[8,19],tooo:19,top:[2,3,8,13,19,23,24],total:6,tower:19,trace:[0,8,12,13,15,20,21,24],traceback:19,traceprint:23,track:[12,19,20],tracker:0,transform:4,transit:5,translat:[4,12,19,21],trap:5,travers:[0,21],treasur:0,treat:[0,2,3,13,19,21],treatment:7,tree:[0,8,21],treegrind:21,treestep:[0,21],tri:6,triangl:16,triangular_numb:13,trick:[6,19],tricki:19,trobe:0,trove:0,truediv:25,truthi:[3,8,16,19],ts:17,tuck:[3,8,19,25],tupl:[3,5,8,19,24],turn:[2,3,5,19,21],twice:[11,13],two:[0,2,3,6,8,9,11,12,13,15,16,17,18,19,20,21,24,25],txt:[],type:[0,1,4,8,11,13,16,21,22,23,24],typeerror:19,typeless:19,typic:[2,3,12,13],u:[18,19],uh:19,ui:8,ulam:[0,15],unari:8,unarybuiltinwrapp:3,unbalanc:[11,22],unbound:25,unchang:11,uncompil:19,uncon:[3,7,8,11,13,17,20,25],under:[2,3,8,11],underli:[5,16,19],underscor:19,understand:[0,11],undistinguish:11,undocu:8,unfinish:5,unfortun:24,unicod:19,unif:[19,21],unifi:18,union:5,uniqu:[3,5,11,19],unit:[3,8,13,16,25],univers:[0,8,16,19],unknownsymbolerror:1,unlik:16,unnecessari:21,unnecesssari:19,unpack:[2,3,11,24],unpair:6,unquot:[8,15,17,22],unread:[0,15],unrol:5,unstack:19,unswon:[3,25],untangl:13,until:[5,7,16],unus:6,unusu:11,unwrap:5,up:[1,2,3,6,7,8,11,13,14,15,16,19,20,24],updat:[0,18,21,25],uppercas:5,upward:16,us:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,20,21,22,24,25],usag:8,user:17,usual:[0,2,13],util:[0,3,14,18,19],uu:19,v0:25,v:[2,6,7,9,11,12,13,14,15,17,20,21],valid:19,valu:[0,1,2,3,6,8,9,12,13,14,15,16,17,19,21,22,24,25],value_n:11,valueerror:[5,19,24],variabl:[19,21],variant:11,variat:[13,16,21],varieti:[4,8],variou:0,ve:[11,15,19],vener:24,verbos:4,veri:[0,1,4,5,8,11,15,24],versa:[2,19],version:[0,1,2,5,7,10,17,20,21],vi:21,via:8,vice:[2,19],view:[11,21],viewer:[1,8,10,23],vii:21,visibl:19,von:[0,2,3,4,13],vs:19,vv:19,w:[3,11,13,17,19],wa:[2,6,8,11,15,16,19,24],waaaai:5,wai:[0,2,3,4,5,6,8,13,14,15,16,19],wait:16,want:[2,6,7,9,11,13,19],warranti:[3,8],wash:8,wast:8,we:[2,5,6,7,8,9,10,12,13,14,15,16,19,20,21,24],web:24,websit:[0,6],welcom:8,well:[0,4,8,9,11,19,22],went:19,were:[8,19,20],what:[2,3,4,5,8,11,13,16,17,19,23],whatev:[2,3,13,17,24],when:[6,7,8,11,13,16,19,20,22,24,25],where:[2,3,5,8,11,13,15,19,21,24],whether:[3,13],which:[0,1,3,5,6,8,9,11,15,16,17,19,20,22,24,25],whole:[2,3,6,13,17,19],whose:7,why:[9,16,17],wiki:11,wikipedia:[0,11,20],wildli:8,wind:8,wire:13,within:[8,11,14,21],without:[2,8,11,12,15,16,19],won:[11,19,24],word:[0,3,6,8,13,20],work:[0,3,5,6,7,8,9,11,12,13,15,16,17,20,21,24,25],worker:16,worri:16,worth:6,would:[2,6,7,8,9,11,13,16,19,20,24],wrap:[3,8],wrapper:19,write:[4,5,9,11,13,15,16,17,19,20,21,24],written:[0,1,9,11,14,19,24],wrong:2,wrote:19,x:[0,3,5,6,8,9,16,20,21],xor:3,xrang:19,y:[2,3,5,15,16],yang:19,yeah:16,year:[8,19],yet:[11,16,19,20],yield:[2,3,13,19,24],yin:21,you:[0,2,3,5,6,7,8,10,11,12,13,14,15,16,17,19,20,23,24,25],your:[2,3,8,13,19],yourself:[5,8,11],z:[3,5,16,19,21],zero:[3,5,11,13,16,17,19,22,24],zerodivisionerror:19,zip:[3,5,6,19],zip_:3,zipper:[0,21],zstr:20},titles:["Thun 0.4.1 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","\u2202RE","Developing a Program in Joy","Using <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursion Combinators","Replacing Functions in the Dictionary","Square Spiral Example Joy Code","The Four Fundamental Operations of Definite Action","Treating Trees II: <code class=\"docutils literal notranslate\"><span class=\"pre\">treestep</span></code>","Type Checking","The Blissful Elegance of Typing Joy","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026","Type Inference of Joy Expressions"],titleterms:{"0":[0,13],"01":5,"1":[0,13],"11":5,"111":5,"2":[7,12,19],"2a":12,"3":[6,19],"4":[0,12,19],"466":7,"5":6,"\u03bb":5,"\u03d5":5,"boolean":15,"case":[9,11],"do":17,"function":[2,3,5,8,9,11,13,14,16,17,19],"long":14,"new":11,"p\u00f6ial":19,"try":5,"void":2,"while":[2,16],A:[5,6,7,9,11,14],If:11,In:[11,17],No:[5,10],Not:15,One:[7,11],The:[6,8,11,13,15,16,17,19],There:8,With:[5,17],about:21,action:16,ad:11,add:[2,11],address:20,al:13,alphabet:5,altern:17,an:[6,7,8,11,13,18,19,20],ana:13,analysi:6,anamorph:[2,13],app1:2,app2:2,app3:2,appendix:[11,13,19],appli:16,approxim:9,ar:11,argument:19,auto:3,averag:2,b:[2,12],base:[9,11],binari:[2,11,17],bliss:19,both:11,branch:[2,11,15,16],brzozowski:5,c:[12,19],can:11,cata:13,catamorph:13,categor:4,chatter:2,check:18,child:11,choic:2,clear:2,cleav:[2,16],cmp:11,code:[0,8,11,15],combin:[2,11,13,19],comment:19,compact:5,compar:11,comparison:2,compil:[7,19],compile_:19,compos:19,comput:9,con:[2,19],concat:2,conclus:[13,15,19],consecut:9,continu:8,current:11,datastructur:[5,8,11,20],deal:19,decrement:15,defin:[11,17],definit:[12,16],delabel:19,delet:11,deriv:[5,12,13,17],design:13,determin:20,develop:6,diagram:5,dialect:0,dictionari:14,dip:[2,20],dipd:2,dipdd:2,direco:7,disenstacken:2,distinguish:19,div:2,doc_from_stack_effect:19,document:0,doe:11,down_to_zero:2,drive:5,drop:2,dup:[2,19],dupd:2,dupdip:2,e:17,effect:19,eleg:19,els:11,empti:11,enstacken:2,equal:11,er:2,essai:21,et:13,euler:[6,7],eval:8,even:7,exampl:[0,2,8,11,13,15,17,18],execut:23,explor:5,express:[5,8,22,25],extract:17,f:11,factori:13,fail:18,fibonacci:7,filter:6,find:[9,11,13],finish:16,finit:5,first:[2,6,15,16,19],five:7,flatten:2,flexibl:17,floordiv:2,form:15,formula:12,found:11,four:[13,16],from:13,fsm:5,fulmin:16,fun:13,fundament:16,further:6,gcd:2,gener:[3,5,6,7,9,13,15],genrec:2,get:[11,17],getitem:2,given:[13,17],greater:11,group:2,h1:13,h2:13,h3:13,h4:13,handl:16,have:[11,17],help:2,highest:11,host:0,how:[6,7],hybrid:19,hylo:13,hylomorph:13,i:[2,5,11,19],identifi:19,ift:[2,16],ii:[17,19],iii:19,implement:[5,19],increment:15,indic:0,infer:[19,25],inferenc:19,inform:0,infra:[2,20],integ:[6,13],interest:7,interlud:11,intern:22,interpret:[1,8,19],item:20,iter:[6,11],iv:19,joi:[0,1,3,6,8,13,15,19,20,21,22,23,24,25],join:16,just:6,kei:11,kind:16,languag:0,larger:5,least_fract:2,left:11,less:11,let:[5,6],letter:5,librari:[3,8,19],like:11,list:[2,13,24],literari:8,littl:6,logic:[2,19],loop:[2,8,16],lower:11,lshift:2,machin:5,make:[7,9],mani:6,map:[2,16],match:5,math:2,memoiz:5,method:9,min:2,miscellan:2,mod:2,modifi:19,modulu:2,more:11,most:11,mul:[2,19],multipl:[6,7,19],must:11,n:13,name:12,ne:2,neg:[2,15],newton:9,next:9,node:11,non:11,now:11,nullari:2,nulli:5,number:[13,19],one:8,onli:8,oper:16,order:[11,17],origin:15,osdn:0,other:16,our:11,out:5,over:2,p:17,pack:6,pam:[2,16],para:13,paradigm:19,parallel:16,parameter:[11,17],pars:[2,22],parser:[8,22],part:19,pass:8,path:20,pattern:13,per:11,piec:15,pop:[2,19],popd:2,popop:2,pow:2,power:7,pred:2,predic:[6,9,11,15,17],pretty_print:23,primit:13,primrec:2,print:8,problem:[6,7],process:11,product:2,program:[4,6,12,17,21],progress:19,project:[0,6,7],pure:8,put:[11,12,15,17],python:[8,14,19],quadrat:12,quick:0,quot:[2,24],rang:[2,6,13],range_to_zero:2,re:[5,11],read:8,recur:[9,11],recurs:[11,13,17],redefin:[11,17],refactor:[6,11],refer:3,regular:[5,8],reimplement:17,relabel:19,rem:2,remaind:2,remov:2,render:6,repl:8,replac:[11,14],repres:[5,19],represent:5,reset:7,rest:[2,19],revers:[2,5,18],right:[11,20],rightmost:11,roll:[2,19],rolldown:2,rollup:2,rshift:2,rule:[5,19],run:[2,7],s:[5,6,9,11,19],second:[2,19],select:2,sequenc:[7,16,19,24],set:[9,11],shorter:14,should:8,shunt:2,simpl:19,simplest:6,size:[2,14],sourc:11,special:[13,19],spiral:15,sqr:[2,19],sqrt:[2,12],squar:15,stack:[2,8,19,24],start:0,state:5,step:[2,13,17],straightforward:12,stream:5,string:5,structur:11,style:8,sub:[2,11],subtyp:19,succ:2,sum:[2,6],swaack:2,swap:[2,19],swon:2,swoncat:2,symbol:[8,13],t:17,tabl:0,tail:13,take:2,term:[6,7,17],ternari:2,text:22,than:11,them:12,thi:11,third:[2,19],three:7,thun:[0,8],time:[2,7],togeth:[11,12,15,17],token:8,toler:9,trace:[14,23],traceprint:8,trampolin:5,translat:15,travers:[11,17,20],treat:[11,17],tree:[11,17,20],treegrind:17,treestep:17,triangular:13,truediv:2,truthi:2,tuck:2,turn:15,two:[5,7],type:[18,19,25],unari:2,unbound:19,uncon:[2,19],unif:18,unifi:19,unit:2,unnecessari:6,unquot:2,unstack:2,up:9,updat:[10,19],us:[7,19],util:[23,24,25],v:19,valu:[7,11],variabl:12,variat:7,version:[6,11,14,19],vi:19,view:8,vii:19,we:[11,17],which:13,within:9,word:2,work:[18,19],write:12,x:[2,7,15],xor:2,yin:19,z:20,zero:7,zip:2,zipper:20}})
\ No newline at end of file
.. _Concatinative: https://en.wikipedia.org/wiki/Concatenative_programming_language
+Example Code
+--------------------------------------------------
+
+Here is an example of Joy code::
+
+ [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+
+It might seem unreadable but with a little familiarity it becomes just as
+legible as any other notation. Some layout helps::
+
+ [ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+ ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral). For more information see :doc:`notebooks/Square_Spiral`
+
+
Quick Start
--------------------------------------------------
Implementation
--------------
-.. code:: python
+.. code:: ipython2
from functools import partial as curry
from itertools import product
The empty set and the set of just the empty string.
-.. code:: python
+.. code:: ipython2
phi = frozenset() # ϕ
y = frozenset({''}) # λ
I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
look like ``0`` and ``1`` (zero and one) respectively.
-.. code:: python
+.. code:: ipython2
syms = O, l = frozenset({'0'}), frozenset({'1'})
Where ``R`` and ``S`` stand for *regular expressions*.
-.. code:: python
+.. code:: ipython2
AND, CONS, KSTAR, NOT, OR = 'and cons * not or'.split() # Tags are just strings.
String Representation of RE Datastructures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def stringy(re):
'''
I = (0|1)*
-.. code:: python
+.. code:: ipython2
I = (KSTAR, (OR, O, l))
-.. code:: python
+.. code:: ipython2
print stringy(I)
Note that it contains one of everything.
-.. code:: python
+.. code:: ipython2
a = (CONS, I, (CONS, l, (CONS, l, (CONS, l, I))))
b = (CONS, I, (CONS, O, l))
c = (CONS, l, (KSTAR, l))
it = (AND, a, (NOT, (OR, b, c)))
-.. code:: python
+.. code:: ipython2
print stringy(it)
Let’s get that auxiliary predicate function ``δ`` out of the way.
-.. code:: python
+.. code:: ipython2
def nully(R):
'''
but does waaaay too much work because the expressions grow each
derivation.
-.. code:: python
+.. code:: ipython2
def D(symbol):
Compaction Rules
~~~~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def _compaction_rule(relation, one, zero, a, b):
return (
An elegant symmetry.
-.. code:: python
+.. code:: ipython2
# R ∧ I = I ∧ R = R
# R ∧ ϕ = ϕ ∧ R = ϕ
computed. RE datastructures are immutable and the ``derv()`` functions
are *pure* so this is fine.
-.. code:: python
+.. code:: ipython2
class Memo(object):
This version uses the rules above to perform compaction. It keeps the
expressions from growing too large.
-.. code:: python
+.. code:: ipython2
def D_compaction(symbol):
(FIXME: redo.)
-.. code:: python
+.. code:: ipython2
o, z = D_compaction('0'), D_compaction('1')
REs = set()
Says, “Three or more 1’s and not ending in 01 nor composed of all 1’s.”
-.. figure:: omg.svg
- :alt: State Machine Graph
+.. figure:: attachment:omg.svg
+ :alt: omg.svg
- State Machine Graph
+ omg.svg
Start at ``a`` and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with
in the way that the ``.111.`` on the left-hand side of the ``&``
disappears once it has been matched.
-.. code:: python
+.. code:: ipython2
from collections import defaultdict
from pprint import pprint
from string import ascii_lowercase
-.. code:: python
+.. code:: ipython2
d0, d1 = D_compaction('0'), D_compaction('1')
``explore()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def explore(re):
return table, accepting
-.. code:: python
+.. code:: ipython2
table, accepting = explore(it)
table
-.. code:: python
+.. code:: ipython2
accepting
Once we have the FSM table and the set of accepting states we can
generate the diagram above.
-.. code:: python
+.. code:: ipython2
_template = '''\
digraph finite_state_machine {
)
)
-.. code:: python
+.. code:: ipython2
print make_graph(table, accepting)
Python has no GOTO statement but we can fake it with a “trampoline”
function.
-.. code:: python
+.. code:: ipython2
def trampoline(input_, jump_from, accepting):
I = iter(input_)
Little helpers to process the iterator of our data (a “stream” of “1”
and “0” characters, not bits.)
-.. code:: python
+.. code:: ipython2
getch = lambda I: int(next(I))
branches in assembly and that the state names are branch destination
labels.)
-.. code:: python
+.. code:: ipython2
a = lambda I: c if getch(I) else b
b = lambda I: _0(I) or d
``h = g`` and we could eliminate one in the code but ``h`` is an
accepting state and ``g`` isn’t.
-.. code:: python
+.. code:: ipython2
def acceptable(input_):
return trampoline(input_, a, {h, i})
-.. code:: python
+.. code:: ipython2
for n in range(2**5):
s = bin(n)[2:]
Cf. jp-reprod.html
-.. code:: python
+.. code:: ipython2
from notebook_preamble import J, V, define
Let’s try it:
-.. code:: python
+.. code:: ipython2
V('[0 swap [dup ++] dip rest cons] x')
After one application of ``x`` the quoted program contains ``1`` and
``0`` is below it on the stack.
-.. code:: python
+.. code:: ipython2
J('[0 swap [dup ++] dip rest cons] x x x x x pop')
``direco``
----------
-.. code:: python
+.. code:: ipython2
define('direco == dip rest cons')
-.. code:: python
+.. code:: ipython2
V('[0 swap [dup ++] direco] x')
G == [direco] cons [swap] swap concat cons
G == [direco] cons [swap] swoncat cons
-.. code:: python
+.. code:: ipython2
define('G == [direco] cons [swap] swoncat cons')
Let’s try it out:
-.. code:: python
+.. code:: ipython2
J('0 [dup ++] G')
[0 swap [dup ++] direco]
-.. code:: python
+.. code:: ipython2
J('0 [dup ++] G x x x pop')
Powers of 2
~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
J('1 [dup 1 <<] G x x x x x x x x x pop')
If we have one of these quoted programs we can drive it using ``times``
with the ``x`` combinator.
-.. code:: python
+.. code:: ipython2
J('23 [dup ++] G 5 [x] times')
And pick them off by masking with 3 (binary 11) and then shifting the
int right two bits.
-.. code:: python
+.. code:: ipython2
define('PE1.1 == dup [3 &] dip 2 >>')
-.. code:: python
+.. code:: ipython2
V('14811 PE1.1')
If we plug ``14811`` and ``[PE1.1]`` into our generator form…
-.. code:: python
+.. code:: ipython2
J('14811 [PE1.1] G')
…we get a generator that works for seven cycles before it reaches zero:
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1] direco] 7 [x] times')
We need a function that checks if the int has reached zero and resets it
if so.
-.. code:: python
+.. code:: ipython2
define('PE1.1.check == dup [pop 14811] [] branch')
-.. code:: python
+.. code:: ipython2
J('14811 [PE1.1.check PE1.1] G')
[14811 swap [PE1.1.check PE1.1] direco]
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')
five less than 1000. It’s worked out that we need to use all seven
numbers sixty-six times and then four more.
-.. code:: python
+.. code:: ipython2
J('7 66 * 4 +')
If we drive our generator 466 times and sum the stack we get 999.
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times')
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] direco]
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum')
Project Euler Problem One
-------------------------
-.. code:: python
+.. code:: ipython2
define('PE1.2 == + dup [+] dip')
Now we can add ``PE1.2`` to the quoted program given to ``G``.
-.. code:: python
+.. code:: ipython2
J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
F == + [popdd over] cons infra uncons
fib_gen == [1 1 F]
-.. code:: python
+.. code:: ipython2
define('fib == + [popdd over] cons infra uncons')
-.. code:: python
+.. code:: ipython2
define('fib_gen == [1 1 fib]')
-.. code:: python
+.. code:: ipython2
J('fib_gen 10 [x] times')
function that adds a term in the sequence to a sum if it is even, and
``pop``\ s it otherwise.
-.. code:: python
+.. code:: ipython2
define('PE2.1 == dup 2 % [+] [pop] branch')
And a predicate function that detects when the terms in the series
“exceed four million”.
-.. code:: python
+.. code:: ipython2
define('>4M == 4000000 >')
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.
-.. code:: python
+.. code:: ipython2
define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')
-.. code:: python
+.. code:: ipython2
J('PE2')
Every third term is even.
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] x x x') # To start the sequence with 1 1 2 3 instead of 1 2 3.
Drive the generator three times and ``popop`` the two odd terms.
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] x x x [popop] dipd')
2 [3 2 fib]
-.. code:: python
+.. code:: ipython2
define('PE2.2 == x x x [popop] dipd')
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] 10 [PE2.2] times')
Replace ``x`` with our new driver function ``PE2.2`` and start our
``fib`` generator at ``1 0``.
-.. code:: python
+.. code:: ipython2
J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')
An Interesting Variation
------------------------
-.. code:: python
+.. code:: ipython2
define('codireco == cons dip rest cons')
-.. code:: python
+.. code:: ipython2
V('[0 [dup ++] codireco] x')
0 [1 [dup ++] codireco] .
-.. code:: python
+.. code:: ipython2
define('G == [codireco] cons cons')
-.. code:: python
+.. code:: ipython2
J('230 [dup ++] G 5 [x] times pop')
Cf. `"Why Functional Programming Matters" by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
-.. code:: python
+.. code:: ipython3
from notebook_preamble import J, V, define
1 [23 over / + 2 /] [dup] swoncat make_generator
1 [dup 23 over / + 2 /] make_generator
-.. code:: python
+.. code:: ipython3
define('gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator')
-.. code:: python
+.. code:: ipython3
J('23 gsra')
Let's drive the generator a few time (with the ``x`` combinator) and
square the approximation to see how well it works...
-.. code:: python
+.. code:: ipython3
J('23 gsra 6 [x popd] times first sqr')
abs(a-b) ε <=
(abs(a-b)<=ε)
-.. code:: python
+.. code:: ipython3
define('_within_P [first - abs] dip <=')
[b G] first
b
-.. code:: python
+.. code:: ipython3
define('_within_B roll< popop first')
b [c G] ε within
-.. code:: python
+.. code:: ipython3
define('_within_R [popd x] dip')
[a G] x ε ...
a [b G] ε ...
-.. code:: python
+.. code:: ipython3
define('within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec')
define('sqrt gsra within')
Try it out...
-.. code:: python
+.. code:: ipython3
J('36 sqrt')
6.0
-.. code:: python
+.. code:: ipython3
J('23 sqrt')
Check it.
-.. code:: python
+.. code:: ipython3
4.795831523312719**2
-.. code:: python
+.. code:: ipython3
from math import sqrt
a contingent existence predicated on the disciplined use of these
functions on otherwise undistinguished Joy datastructures.)
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V, define, DefinitionWrapper
Tree-new == swap [[] []] cons cons
-.. code:: python
+.. code:: ipython2
define('Tree-new == swap [[] []] cons cons')
-.. code:: python
+.. code:: ipython2
J('"v" "k" Tree-new')
P < == pop roll> pop first <
P == pop roll> pop first
-.. code:: python
+.. code:: ipython2
define('P == pop roll> pop first')
-.. code:: python
+.. code:: ipython2
J('["old_key" 23 [] []] 17 "new_key" ["..."] P')
T == cons cons [dipdd] cons infra
-.. code:: python
+.. code:: ipython2
define('T == cons cons [dipdd] cons infra')
-.. code:: python
+.. code:: ipython2
J('["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T')
[key_n value_n left right] value key [Tree-add] E
[key_n value_n left right] value key [Tree-add] [P <] [Te] [Ee] ifte
-.. code:: python
+.. code:: ipython2
define('E == [P <] [Te] [Ee] ifte')
Te == cons cons [dipd] cons infra
-.. code:: python
+.. code:: ipython2
define('Te == cons cons [dipd] cons infra')
-.. code:: python
+.. code:: ipython2
J('["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te')
key new_value [ left right] cons cons
[key new_value left right]
-.. code:: python
+.. code:: ipython2
define('Ee == pop swap roll< rest rest cons cons')
-.. code:: python
+.. code:: ipython2
J('["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee')
Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-.. code:: python
+.. code:: ipython2
define('Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec')
Examples
~~~~~~~~
-.. code:: python
+.. code:: ipython2
J('[] 23 "b" Tree-add') # Initial
['b' 23 [] []]
-.. code:: python
+.. code:: ipython2
J('["b" 23 [] []] 88 "c" Tree-add') # Greater than
['b' 23 [] ['c' 88 [] []]]
-.. code:: python
+.. code:: ipython2
J('["b" 23 [] []] 88 "a" Tree-add') # Less than
['b' 23 ['a' 88 [] []] []]
-.. code:: python
+.. code:: ipython2
J('["b" 23 [] []] 88 "b" Tree-add') # Equal to
['b' 88 [] []]
-.. code:: python
+.. code:: ipython2
J('[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add') # Series.
['b' 23 ['a' 88 [] []] ['c' 44 [] []]]
-.. code:: python
+.. code:: ipython2
J('[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step')
------------------------- a < b
L
-.. code:: python
+.. code:: ipython2
J("1 0 ['G'] ['E'] ['L'] cmp")
'G'
-.. code:: python
+.. code:: ipython2
J("1 1 ['G'] ['E'] ['L'] cmp")
'E'
-.. code:: python
+.. code:: ipython2
J("0 1 ['G'] ['E'] ['L'] cmp")
P == over [popop popop first] nullary
-.. code:: python
+.. code:: ipython2
define('P == over [popop popop first] nullary')
Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec
-.. code:: python
+.. code:: ipython2
define('Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec')
-.. code:: python
+.. code:: ipython2
J('[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add') # Still works.
Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
-.. code:: python
+.. code:: ipython2
define('Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec')
Examples
~~~~~~~~
-.. code:: python
+.. code:: ipython2
J('[] [foo] Tree-iter') # It doesn't matter what F is as it won't be used.
-.. code:: python
+.. code:: ipython2
J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter")
'b' 'a' 'c'
-.. code:: python
+.. code:: ipython2
J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter")
`:math:`O(\log_2 N)` <https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2>`__
time.
-.. code:: python
+.. code:: ipython2
J('[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step')
[3 0 [2 0 [] []] [9 0 [5 0 [4 0 [] []] [8 0 [6 0 [] [7 0 [] []]] []]] []]]
-.. code:: python
+.. code:: ipython2
define('to_set == [] swap [0 swap Tree-add] step')
-.. code:: python
+.. code:: ipython2
J('[3 9 5 2 8 6 7 8 4] to_set')
And with that we can write a little program ``unique`` to remove
duplicate items from a list.
-.. code:: python
+.. code:: ipython2
define('unique == [to_set [first] Tree-iter] cons run')
-.. code:: python
+.. code:: ipython2
J('[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique') # Filter duplicate items.
Now we can sort sequences.
-.. code:: python
+.. code:: ipython2
#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')
-.. code:: python
+.. code:: ipython2
J('[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order')
Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
-.. code:: python
+.. code:: ipython2
# I don't want to deal with name conflicts with the above so I'm inlining everything here.
# The original Joy system has "hide" which is a meta-command which allows you to use named
] genrec
''')
-.. code:: python
+.. code:: ipython2
J('["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get')
'mike not in tree'
-.. code:: python
+.. code:: ipython2
J('["gary" 23 [] []] "gary" [popop "err"] Tree-get')
23
-.. code:: python
+.. code:: ipython2
J('''
2
-.. code:: python
+.. code:: ipython2
J('''
By the standards of the code I’ve written so far, this is a *huge* Joy
program.
-.. code:: python
+.. code:: ipython2
DefinitionWrapper.add_definitions('''
first_two == uncons uncons pop
Tree-Delete == [pop not] [pop] [R0] [R1] genrec
''', D)
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete ")
['a' 23 [] ['b' 88 [] []]]
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete ")
['a' 23 [] ['c' 44 [] []]]
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete ")
['b' 88 [] ['c' 44 [] []]]
-.. code:: python
+.. code:: ipython2
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete ")
['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]
-.. code:: python
+.. code:: ipython2
J('[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step')
[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]]
-.. code:: python
+.. code:: ipython2
J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete ")
[4 0 [2 0 [1 0 [] []] []] [6 0 [5 0 [] []] [7 0 [] []]]]
-.. code:: python
+.. code:: ipython2
J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete ")
-.. code:: python
+.. code:: ipython2
from notebook_preamble import J, V, define
The three arguments are to the left, so we can “chop off” everything to
the right and say it’s the definition of the ``quadratic`` function:
-.. code:: python
+.. code:: ipython2
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
Let’s try it out:
-.. code:: python
+.. code:: ipython2
J('3 1 1 quadratic')
by incorporating the values on the stack. Then that program runs and you
get the results. This is pretty typical of Joy code.
-.. code:: python
+.. code:: ipython2
V('-5 1 4 quadratic')
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, DefinitionWrapper, J, V, define
It may be helpful to see this function implemented in imperative Python
code.
-.. code:: python
+.. code:: ipython2
def hylomorphism(c, F, P, G):
'''Return a hylomorphism function H.'''
hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
-.. code:: python
+.. code:: ipython2
define('hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec')
- ``[G]`` is ``[-- dup]``
- ``[F]`` is ``[+]``
-.. code:: python
+.. code:: ipython2
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
Let’s try it:
-.. code:: python
+.. code:: ipython2
J('5 triangular_number')
10
-.. code:: python
+.. code:: ipython2
J('[0 1 2 3 4 5 6] [triangular_number] map')
A == [P] [] [G] [swons] hylomorphism
-``range`` et. al.
-~~~~~~~~~~~~~~~~~
-
-An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
+``range`` et. al. An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each of the above variations can be used to make four slightly different
``range`` functions.
H1 == [P] [pop c] [G] [dip F] genrec
== [0 <=] [pop []] [-- dup] [dip swons] genrec
-.. code:: python
+.. code:: ipython2
define('range == [0 <=] [] [-- dup] [swons] hylomorphism')
-.. code:: python
+.. code:: ipython2
J('5 range')
H2 == c swap [P] [pop] [G [F] dip] primrec
== [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
-.. code:: python
+.. code:: ipython2
define('range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec')
-.. code:: python
+.. code:: ipython2
J('5 range_reverse')
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
== [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
-.. code:: python
+.. code:: ipython2
define('ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec')
-.. code:: python
+.. code:: ipython2
J('5 ranger')
H4 == c swap [P] [pop] [[F] dupdip G ] primrec
== [] swap [0 <=] [pop] [[swons] dupdip --] primrec
-.. code:: python
+.. code:: ipython2
define('ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec')
-.. code:: python
+.. code:: ipython2
J('5 ranger_reverse')
C == [not] c [uncons swap] [F] hylomorphism
-.. code:: python
+.. code:: ipython2
define('swuncons == uncons swap') # Awkward name.
sum == [not] 0 [swuncons] [+] hylomorphism
-.. code:: python
+.. code:: ipython2
define('sum == [not] 0 [swuncons] [+] hylomorphism')
-.. code:: python
+.. code:: ipython2
J('[5 4 3 2 1] sum')
The ``step`` combinator will usually be better to use than
``catamorphism``.
-.. code:: python
+.. code:: ipython2
J('[step] help')
-.. code:: python
+.. code:: ipython2
define('sum == 0 swap [+] step')
-.. code:: python
+.. code:: ipython2
J('[5 4 3 2 1] sum')
G == --
P == 1 <=
-.. code:: python
+.. code:: ipython2
define('factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec')
-.. code:: python
+.. code:: ipython2
J('5 factorial')
G == rest dup
P == not
-.. code:: python
+.. code:: ipython2
define('tails == [] swap [not] [pop] [rest dup [swons] dip] primrec')
-.. code:: python
+.. code:: ipython2
J('[1 2 3] tails')
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V
A long trace
------------
-.. code:: python
+.. code:: ipython2
V('[23 18] average')
``size`` we can use a “compiled” version hand-written in Python to speed
up evaluation and make the trace more readable.
-.. code:: python
+.. code:: ipython2
from joy.library import SimpleFunctionWrapper
from joy.utils.stack import iter_stack
Now we replace the old version in the dictionary with the new version,
and re-evaluate the expression.
-.. code:: python
+.. code:: ipython2
D['size'] = size
You can see that ``size`` now executes in a single step.
-.. code:: python
+.. code:: ipython2
V('[23 18] average')
--- /dev/null
+.. code:: ipython3
+
+ from notebook_preamble import J, V, define
+
+Square Spiral Example Joy Code
+==============================
+
+Here is the example of Joy code from the ``README`` file:
+
+::
+
+ [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+
+It might seem unreadable but with a little familiarity it becomes just
+as legible as any other notation. Some layout helps:
+
+::
+
+ [ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+ ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral).
+
+Original Form
+-------------
+
+It's adapted from `the original code on
+StackOverflow <https://stackoverflow.com/questions/398299/looping-in-a-spiral/31864777#31864777>`__:
+
+ If all you're trying to do is generate the first N points in the
+ spiral (without the original problem's constraint of masking to an N
+ x M region), the code becomes very simple:
+
+::
+
+ void spiral(const int N)
+ {
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+ }
+
+Translation to Joy
+------------------
+
+I'm going to make a function that take two ints (``x`` and ``y``) and
+generates the next pair, we'll turn it into a generator later using the
+``x`` combinator.
+
+First Boolean Predicate
+~~~~~~~~~~~~~~~~~~~~~~~
+
+We need a function that computes ``abs(x) <= abs(y)``, we can use ``ii``
+to apply ``abs`` to both values and then compare them with ``<=``:
+
+::
+
+ [abs] ii <=
+
+I've defined two short-circuiting Boolean combinators ``&&`` and ``||``
+that each accept two quoted predicate programs, run the first, and
+conditionally run the second only if required (to compute the final
+Boolean value). They run their predicate arguments ``nullary``.
+
+.. code:: ipython3
+
+ define('&& [nullary] cons [nullary [0]] dip branch')
+ define('|| [nullary] cons [nullary] dip [1] branch')
+
+Given those, we can define ``x != y || x >= 0`` as:
+
+::
+
+ [<>] [pop 0 >=] ||
+
+And ``(abs(x) <= abs(y) && (x != y || x >= 0))`` as:
+
+::
+
+ [[abs] ii <=] [[<>] [pop 0 >=] ||] &&
+
+It's a little rough, but, as I say, with a little familiarity it becomes
+legible.
+
+The Increment / Decrement Branches
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Turning to the branches of the main ``if`` statement:
+
+::
+
+ x += ((y >= 0) ? 1 : -1);
+
+Rewrite as a hybrid (pseudo-code) ``ifte`` expression:
+
+::
+
+ [y >= 0] [x += 1] [X -= 1] ifte
+
+Change each C phrase to Joy code:
+
+::
+
+ [0 >=] [[++] dip] [[--] dip] ifte
+
+Factor out the dip from each branch:
+
+::
+
+ [0 >=] [[++]] [[--]] ifte dip
+
+Similar logic applies to the other branch:
+
+::
+
+ y += ((x >= 0) ? -1 : 1);
+
+ [x >= 0] [y -= 1] [y += 1] ifte
+
+ [pop 0 >=] [--] [++] ifte
+
+"Not Negative"
+~~~~~~~~~~~~~~
+
+.. code:: ipython3
+
+ define('!- 0 >=')
+
+Putting the Pieces Together
+---------------------------
+
+We can assemble the three functions we just defined in quotes and give
+them them to the ``ifte`` combinator. With some arrangement to show off
+the symmetry of the two branches, we have:
+
+::
+
+ [[[abs] ii <=] [[<>] [pop !-] ||] &&]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+As I was writing this up I realized that, since the ``&&`` combinator
+doesn't consume the stack (below its quoted args), I can unquote the
+predicate, swap the branches, and use the ``branch`` combinator instead
+of ``ifte``:
+
+::
+
+ [[abs] ii <=] [[<>] [pop !-] ||] &&
+ [[pop !-] [--] [++] ifte ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ branch
+
+.. code:: ipython3
+
+ define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')
+
+Let's try it out:
+
+.. code:: ipython3
+
+ J('0 0 spiral_next')
+
+
+.. parsed-literal::
+
+ 1 0
+
+
+.. code:: ipython3
+
+ J('1 0 spiral_next')
+
+
+.. parsed-literal::
+
+ 1 -1
+
+
+.. code:: ipython3
+
+ J('1 -1 spiral_next')
+
+
+.. parsed-literal::
+
+ 0 -1
+
+
+.. code:: ipython3
+
+ J('0 -1 spiral_next')
+
+
+.. parsed-literal::
+
+ -1 -1
+
+
+Turning it into a Generator with ``x``
+--------------------------------------
+
+It can be used with the x combinator to make a kind of generator for
+spiral square coordinates.
+
+We can use ``codireco`` to make a generator
+
+::
+
+ codireco ::= cons dip rest cons
+
+It will look like this:
+
+::
+
+ [value [F] codireco]
+
+Here's a trace of how it works:
+
+::
+
+ [0 [dup ++] codireco] . x
+ [0 [dup ++] codireco] . 0 [dup ++] codireco
+ [0 [dup ++] codireco] 0 . [dup ++] codireco
+ [0 [dup ++] codireco] 0 [dup ++] . codireco
+ [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
+ [0 [dup ++] codireco] [0 dup ++] . dip rest cons
+ . 0 dup ++ [0 [dup ++] codireco] rest cons
+ 0 . dup ++ [0 [dup ++] codireco] rest cons
+ 0 0 . ++ [0 [dup ++] codireco] rest cons
+ 0 1 . [0 [dup ++] codireco] rest cons
+ 0 1 [0 [dup ++] codireco] . rest cons
+ 0 1 [[dup ++] codireco] . cons
+ 0 [1 [dup ++] codireco] .
+
+But first we have to change the ``spiral_next`` function to work on a
+quoted pair of integers, and leave a copy of the pair on the stack.
+From:
+
+::
+
+ y x spiral_next
+ ---------------------
+ y' x'
+
+to:
+
+::
+
+ [x y] [spiral_next] infra
+ -------------------------------
+ [x' y']
+
+.. code:: ipython3
+
+ J('[0 0] [spiral_next] infra')
+
+
+.. parsed-literal::
+
+ [0 1]
+
+
+So our generator is:
+
+::
+
+ [[x y] [dup [spiral_next] infra] codireco]
+
+Or rather:
+
+::
+
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+There is a function ``make_generator`` that will build the generator for
+us out of the value and stepper function:
+
+::
+
+ [0 0] [dup [spiral_next] infra] make_generator
+ ----------------------------------------------------
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+Here it is in action:
+
+.. code:: ipython3
+
+ J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')
+
+
+.. parsed-literal::
+
+ [0 0] [0 1] [-1 1] [-1 0]
+
+
+Four ``x`` combinators, four pairs of coordinates.
+
+Conclusion
+----------
+
+So that's an example of Joy code. It's a straightforward translation of
+the original. It's a little long for a single definition, you might
+break it up like so:
+
+::
+
+ _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+
+ _spn_T ::= [ !-] [[++]] [[--]] ifte dip
+ _spn_E ::= [pop !-] [--] [++] ifte
+
+ spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+
+This way it's easy to see that the function is a branch with two
+quasi-symmetrical paths.
+
+We then used this function to make a simple generator of coordinate
+pairs, where the next pair in the series can be generated at any time by
+using the ``x`` combinator on the generator (which is just a quoted
+expression containing a copy of the current pair and the "stepper
+function" to generate the next pair from that.)
+
+.. code:: ipython3
+
+ define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')
+ define('_spn_T [!-] [[++]] [[--]] ifte dip')
+ define('_spn_E [pop !-] [--] [++] ifte')
+ define('spiral_next _spn_P [_spn_E] [_spn_T] branch')
+
+.. code:: ipython3
+
+ V('23 18 spiral_next')
+
+
+.. parsed-literal::
+
+ . 23 18 spiral_next
+ 23 . 18 spiral_next
+ 23 18 . spiral_next
+ 23 18 . _spn_P [_spn_E] [_spn_T] branch
+ 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
+ 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
+ 23 18 . 0 [_spn_E] [_spn_T] branch
+ 23 18 0 . [_spn_E] [_spn_T] branch
+ 23 18 0 [_spn_E] . [_spn_T] branch
+ 23 18 0 [_spn_E] [_spn_T] . branch
+ 23 18 . _spn_E
+ 23 18 . [pop !-] [--] [++] ifte
+ 23 18 [pop !-] . [--] [++] ifte
+ 23 18 [pop !-] [--] . [++] ifte
+ 23 18 [pop !-] [--] [++] . ifte
+ 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
+ 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
+ 23 18 [pop !-] . nullary not [--] [++] branch
+ 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
+ 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
+ 23 18 . stack [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
+ 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
+ 23 18 . pop !- [18 23] swaack first not [--] [++] branch
+ 23 . !- [18 23] swaack first not [--] [++] branch
+ 23 . 0 >= [18 23] swaack first not [--] [++] branch
+ 23 0 . >= [18 23] swaack first not [--] [++] branch
+ True . [18 23] swaack first not [--] [++] branch
+ True [18 23] . swaack first not [--] [++] branch
+ 23 18 [True] . first not [--] [++] branch
+ 23 18 True . not [--] [++] branch
+ 23 18 False . [--] [++] branch
+ 23 18 False [--] . [++] branch
+ 23 18 False [--] [++] . branch
+ 23 18 . --
+ 23 17 .
+
Define ``treestep``
-------------------
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V, define, DefinitionWrapper
-.. code:: python
+.. code:: ipython2
DefinitionWrapper.add_definitions('''
sumtree == [pop 0] [] [sum +] treestep
-.. code:: python
+.. code:: ipython2
define('sumtree == [pop 0] [] [sum +] treestep')
------------------------------------
0
-.. code:: python
+.. code:: ipython2
J('[] sumtree') # Empty tree.
n m +
n+m
-.. code:: python
+.. code:: ipython2
J('[23] sumtree') # No child trees.
23
-.. code:: python
+.. code:: ipython2
J('[23 []] sumtree') # Child tree, empty.
23
-.. code:: python
+.. code:: ipython2
J('[23 [2 [4]] [3]] sumtree') # Non-empty child trees.
32
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] sumtree') # Etc...
49
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep') # Alternate "spelling".
49
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep') # Replace each node.
[23 [23 [23] [23]] [23] [23 []]]
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep')
[1 [1 [1] [1]] [1] [1 []]]
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree')
6
-.. code:: python
+.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep') # Combine replace and sum into one function.
6
-.. code:: python
+.. code:: ipython2
J('[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep') # Combine replace and sum into one function.
This doesn’t quite work:
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep')
[] [first] [flatten cons] treestep
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep')
[] [i roll< swons concat] [first] treestep
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep')
[key value] N [left right] [K] C
-.. code:: python
+.. code:: ipython2
J('[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind')
Iteration through the nodes
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind')
Sum the nodes’ keys.
-.. code:: python
+.. code:: ipython2
J('0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind')
Rebuild the tree using ``map`` (imitating ``treestep``.)
-.. code:: python
+.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind')
To me, that seems simpler than the ``genrec`` version.
-.. code:: python
+.. code:: ipython2
DefinitionWrapper.add_definitions('''
''', D)
-.. code:: python
+.. code:: ipython2
J('''\
15
-.. code:: python
+.. code:: ipython2
J('''\
Type Checking
=============
-.. code:: python
+.. code:: ipython2
import logging, sys
level=logging.INFO,
)
-.. code:: python
+.. code:: ipython2
from joy.utils.types import (
doc_from_stack_effect,
JoyTypeError,
)
-.. code:: python
+.. code:: ipython2
D = FUNCTIONS.copy()
del D['product']
An Example
----------
-.. code:: python
+.. code:: ipython2
fi, fo = infer(pop, swap, rolldown, rrest, ccons)[0]
40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(fi, fo)
([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1])
-.. code:: python
+.. code:: ipython2
from joy.parser import text_to_expression
from joy.utils.stack import stack_to_string
-.. code:: python
+.. code:: ipython2
e = text_to_expression('0 1 2 [3 4]') # reverse order
print stack_to_string(e)
[3 4] 2 1 0
-.. code:: python
+.. code:: ipython2
u = unify(e, fi)[0]
u
-.. code:: python
+.. code:: ipython2
g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
Unification Works “in Reverse”
------------------------------
-.. code:: python
+.. code:: ipython2
e = text_to_expression('[2 3]')
-.. code:: python
+.. code:: ipython2
u = unify(e, fo)[0] # output side, not input side
u
-.. code:: python
+.. code:: ipython2
g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
Failing a Check
---------------
-.. code:: python
+.. code:: ipython2
fi, fo = infer(dup, mul)[0]
31 (i1 -- i2) ∘
-.. code:: python
+.. code:: ipython2
e = text_to_expression('"two"')
print stack_to_string(e)
'two'
-.. code:: python
+.. code:: ipython2
try:
unify(e, fi)
The simplest way to “compile” this function would be something like:
-.. code:: python
+.. code:: ipython2
def poswrd(s, e, d):
return rolldown(*swap(*pop(s, e, d)))
We should be able to directly write out a Python function like:
-.. code:: python
+.. code:: ipython2
def poswrd(stack):
(_, (a, (b, (c, stack)))) = stack
From this stack effect comment it should be possible to construct the
following Python code:
-.. code:: python
+.. code:: ipython2
def F(stack):
(_, (d, (c, ((a, (b, S0)), stack)))) = stack
I’m going to use pairs of tuples of type descriptors, which will be
integers or tuples of type descriptors:
-.. code:: python
+.. code:: ipython2
roll_dn = (1, 2, 3), (2, 3, 1)
``compose()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def compose(f, g):
``unify()``
~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
``update()``
~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def update(s, term):
if not isinstance(term, tuple):
``relabel()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def relabel(left, right):
return left, _1000(right)
``delabel()``
~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
def delabel(f):
s = {u: i for i, u in enumerate(sorted(_unique(f)))}
stack effect comments and returns their composition (or raises and
exception if they can’t be composed due to type conflicts.)
-.. code:: python
+.. code:: ipython2
def C(f, g):
f, g = relabel(f, g)
Let’s try it out.
-.. code:: python
+.. code:: ipython2
C(pop, swap)
-.. code:: python
+.. code:: ipython2
C(C(pop, swap), roll_dn)
-.. code:: python
+.. code:: ipython2
C(swap, roll_dn)
-.. code:: python
+.. code:: ipython2
C(pop, C(swap, roll_dn))
-.. code:: python
+.. code:: ipython2
poswrd = reduce(C, (pop, swap, roll_dn))
poswrd
manipulate stacks. We use a cons-list of tuples and give the tails their
own numbers. Then everything above already works.
-.. code:: python
+.. code:: ipython2
rest = ((1, 2),), (2,)
cons = (1, 2), ((1, 2),)
-.. code:: python
+.. code:: ipython2
C(poswrd, rest)
0: 0,
}
-.. code:: python
+.. code:: ipython2
F = reduce(C, (pop, swap, roll_dn, rest, rest, cons, cons))
However, if we try to compose e.g. ``cons`` and ``uncons`` it won’t
work:
-.. code:: python
+.. code:: ipython2
uncons = ((1, 2),), (1, 2)
-.. code:: python
+.. code:: ipython2
try:
C(cons, uncons)
the case when both terms are tuples. We just have to add a clause to
deal with this recursively:
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
return s
-.. code:: python
+.. code:: ipython2
C(cons, uncons)
Now consider the Python function we would like to derive:
-.. code:: python
+.. code:: ipython2
def F_python(stack):
(_, (d, (c, ((a, (b, S0)), stack)))) = stack
And compare it to the input stack effect comment tuple we just computed:
-.. code:: python
+.. code:: ipython2
F[0]
And the return tuple
-.. code:: python
+.. code:: ipython2
F[1]
We want to substitute Python identifiers for the integers. I’m going to
repurpose ``joy.parser.Symbol`` class for this:
-.. code:: python
+.. code:: ipython2
from collections import defaultdict
from joy.parser import Symbol
in how this code works that related to stuff later in the notebook, so
you should skip it for now and read it later if you’re interested.
-.. code:: python
+.. code:: ipython2
def doc_from_stack_effect(inputs, outputs):
return '(%s--%s)' % (
underscore suffix distiguishes it from the built-in ``compile()``
function.)
-.. code:: python
+.. code:: ipython2
def compile_(name, f, doc=None):
if doc is None:
Here it is in action:
-.. code:: python
+.. code:: ipython2
source = compile_('F', F)
Compare:
-.. code:: python
+.. code:: ipython2
def F_python(stack):
(_, (d, (c, ((a, (b, S0)), stack)))) = stack
Next steps:
-.. code:: python
+.. code:: ipython2
L = {}
Let’s try it out:
-.. code:: python
+.. code:: ipython2
from notebook_preamble import D, J, V
from joy.library import SimpleFunctionWrapper
-.. code:: python
+.. code:: ipython2
D['F'] = SimpleFunctionWrapper(L['F'])
-.. code:: python
+.. code:: ipython2
J('[4 5 ...] 2 3 1 F')
We can use ``compile_()`` to generate many primitives in the library
from their stack effect comments:
-.. code:: python
+.. code:: ipython2
def defs():
return locals()
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(defs().items()):
print
to establish domain ordering, as well as other handy behaviour that will
make it fairly easy to reuse most of the code above.
-.. code:: python
+.. code:: ipython2
class AnyJoyType(object):
Mess with it a little:
-.. code:: python
+.. code:: ipython2
from itertools import permutations
“Any” types can be specialized to numbers and stacks, but not vice
versa:
-.. code:: python
+.. code:: ipython2
for a, b in permutations((A[0], N[0], S[0]), 2):
print a, '>=', b, '->', a >= b
Tower <https://en.wikipedia.org/wiki/Numerical_tower>`__ of *numbers* >
*floats* > *integers* works as well (but we’re not going to use it yet):
-.. code:: python
+.. code:: ipython2
for a, b in permutations((A[0], N[0], FloatJoyType(0), IntJoyType(0)), 2):
print a, '>=', b, '->', a >= b
Typing ``sqr``
~~~~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
dup = (A[1],), (A[1], A[1])
mul = (N[1], N[2]), (N[3],)
-.. code:: python
+.. code:: ipython2
dup
-.. code:: python
+.. code:: ipython2
mul
Re-labeling still works fine:
-.. code:: python
+.. code:: ipython2
foo = relabel(dup, mul)
The ``delabel()`` function needs an overhaul. It now has to keep track
of how many labels of each domain it has “seen”.
-.. code:: python
+.. code:: ipython2
from collections import Counter
return tuple(delabel(inner, seen, c) for inner in f)
-.. code:: python
+.. code:: ipython2
delabel(foo)
``unify()`` version 3
^^^^^^^^^^^^^^^^^^^^^
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
Rewrite the stack effect comments:
-.. code:: python
+.. code:: ipython2
def defs():
return locals()
-.. code:: python
+.. code:: ipython2
DEFS = defs()
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(DEFS.items()):
print name, '=', doc_from_stack_effect(*stack_effect_comment)
uncons = ([a1 .1.] -- a1 [.1.])
-.. code:: python
+.. code:: ipython2
globals().update(DEFS)
Compose ``dup`` and ``mul``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code:: python
+.. code:: ipython2
C(dup, mul)
Revisit the ``F`` function, works fine.
-.. code:: python
+.. code:: ipython2
F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
F
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*F)
Some otherwise inefficient functions are no longer to be feared. We can
also get the effect of combinators in some limited cases.
-.. code:: python
+.. code:: ipython2
def neato(*funcs):
print doc_from_stack_effect(*reduce(C, funcs))
-.. code:: python
+.. code:: ipython2
# e.g. [swap] dip
neato(rollup, swap, rolldown)
(a1 a2 a3 -- a2 a1 a3)
-.. code:: python
+.. code:: ipython2
# e.g. [popop] dipd
neato(popdd, rolldown, pop)
(a1 a2 a3 a4 -- a3 a4)
-.. code:: python
+.. code:: ipython2
# Reverse the order of the top three items.
neato(rollup, swap)
Because the type labels represent themselves as valid Python identifiers
the ``compile_()`` function doesn’t need to generate them anymore:
-.. code:: python
+.. code:: ipython2
def compile_(name, f, doc=None):
inputs, outputs = f
%s = stack
return %s''' % (name, doc, i, o)
-.. code:: python
+.. code:: ipython2
print compile_('F', F)
But it cannot magically create new functions that involve e.g. math and
such. Note that this is *not* a ``sqr`` function implementation:
-.. code:: python
+.. code:: ipython2
print compile_('sqr', C(dup, mul))
``AnyJoyType`` and ``StackJoyType`` labels in their stack effect
comments. We can write a function to check that:
-.. code:: python
+.. code:: ipython2
from itertools import imap
def compilable(f):
return isinstance(f, tuple) and all(imap(compilable, f)) or stacky(f)
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(defs().items()):
if compilable(stack_effect_comment):
``joy.utils.stack.concat`` work with our stack effect comment cons-list
tuples.)
-.. code:: python
+.. code:: ipython2
def compose(f, g):
(f_in, f_out), (g_in, g_out) = f, g
I don’t want to rewrite all the defs myself, so I’ll write a little
conversion function instead. This is programmer’s laziness.
-.. code:: python
+.. code:: ipython2
def sequence_to_stack(seq, stack=StackJoyType(23)):
for item in seq: stack = item, stack
NEW_DEFS['swaack'] = (S[1], S[0]), (S[0], S[1])
globals().update(NEW_DEFS)
-.. code:: python
+.. code:: ipython2
C(stack, uncons)
-.. code:: python
+.. code:: ipython2
reduce(C, (stack, uncons, uncons))
Clunky junk, but it will suffice for now.
-.. code:: python
+.. code:: ipython2
def doc_from_stack_effect(inputs, outputs):
switch = [False] # Do we need to display the '...' for the rest of the main stack?
a.append(end)
return '[%s]' % ' '.join(a)
-.. code:: python
+.. code:: ipython2
for name, stack_effect_comment in sorted(NEW_DEFS.items()):
print name, '=', doc_from_stack_effect(*stack_effect_comment)
uncons = ([a1 .1.] -- a1 [.1.])
-.. code:: python
+.. code:: ipython2
print ; print doc_from_stack_effect(*stack)
print ; print doc_from_stack_effect(*C(stack, uncons))
(... a1 -- ... a1 [a1 ...])
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*C(ccons, stack))
(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
-.. code:: python
+.. code:: ipython2
Q = C(ccons, stack)
This makes the ``compile_()`` function pretty simple as the stack effect
comments are now already in the form needed for the Python code:
-.. code:: python
+.. code:: ipython2
def compile_(name, f, doc=None):
i, o = f
%s = stack
return %s''' % (name, doc, i, o)
-.. code:: python
+.. code:: ipython2
print compile_('Q', Q)
-.. code:: python
+.. code:: ipython2
unstack = (S[1], S[0]), S[1]
enstacken = S[0], (S[0], S[1])
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*unstack)
([.1.] --)
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*enstacken)
(-- [.0.])
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*C(cons, unstack))
(a1 [.1.] -- a1)
-.. code:: python
+.. code:: ipython2
print doc_from_stack_effect(*C(cons, enstacken))
(a1 [.1.] -- [[a1 .1.] .2.])
-.. code:: python
+.. code:: ipython2
C(cons, unstack)
…
-.. code:: python
+.. code:: ipython2
class IntJoyType(NumberJoyType): prefix = 'i'
F = map(FloatJoyType, _R)
I = map(IntJoyType, _R)
-.. code:: python
+.. code:: ipython2
muls = [
((I[2], (I[1], S[0])), (I[3], S[0])),
((F[2], (F[1], S[0])), (F[3], S[0])),
]
-.. code:: python
+.. code:: ipython2
for f in muls:
print doc_from_stack_effect(*f)
(f1 f2 -- f3)
-.. code:: python
+.. code:: ipython2
for f in muls:
try:
(a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
-.. code:: python
+.. code:: ipython2
from itertools import product
def MC(F, G):
return sorted(set(meta_compose(F, G)))
-.. code:: python
+.. code:: ipython2
for f in MC([dup], [mul]):
print doc_from_stack_effect(*f)
(n1 -- n2)
-.. code:: python
+.. code:: ipython2
for f in MC([dup], muls):
print doc_from_stack_effect(*f)
{c: a, d: b, .1.: .0.}
{c: a, d: e, .1.: A* b .0.}
-.. code:: python
+.. code:: ipython2
class KleeneStar(object):
Can now return multiple results…
-.. code:: python
+.. code:: ipython2
def unify(u, v, s=None):
if s is None:
def stacky(thing):
return thing.__class__ in {AnyJoyType, StackJoyType}
-.. code:: python
+.. code:: ipython2
a = (As[1], S[1])
a
-.. code:: python
+.. code:: ipython2
b = (A[1], S[2])
b
-.. code:: python
+.. code:: ipython2
for result in unify(b, a):
print result, '->', update(result, a), update(result, b)
{a1: a10001, s2: (a1*, s1)} -> (a1*, s1) (a10001, (a1*, s1))
-.. code:: python
+.. code:: ipython2
for result in unify(a, b):
print result, '->', update(result, a), update(result, b)
(a1*, s1) [a1*] (a2, (a1*, s1)) [a2 a1*]
-.. code:: python
+.. code:: ipython2
sum_ = ((Ns[1], S[1]), S[0]), (N[0], S[0])
([n1* .1.] -- n0)
-.. code:: python
+.. code:: ipython2
f = (N[1], (N[2], (N[3], S[1]))), S[0]
(-- [n1 n2 n3 .1.])
-.. code:: python
+.. code:: ipython2
for result in unify(sum_[0], f):
print result, '->', update(result, sum_[1])
This function has to be modified to yield multiple results.
-.. code:: python
+.. code:: ipython2
def compose(f, g):
(f_in, f_out), (g_in, g_out) = f, g
-.. code:: python
+.. code:: ipython2
def meta_compose(F, G):
for f, g in product(F, G):
for fg in compose(f, g):
yield delabel(fg)
-.. code:: python
+.. code:: ipython2
for f in MC([dup], muls):
print doc_from_stack_effect(*f)
(i1 -- i2)
-.. code:: python
+.. code:: ipython2
([n1* .1.] -- [n1* .1.] n1)
-.. code:: python
+.. code:: ipython2
(n1 [n1* .1.] -- n2)
-.. code:: python
+.. code:: ipython2
sum_ = (((N[1], (Ns[1], S[1])), S[0]), (N[0], S[0]))
print doc_from_stack_effect(*cons),
(a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
-.. code:: python
+.. code:: ipython2
a = (A[4], (As[1], (A[3], S[1])))
a
-.. code:: python
+.. code:: ipython2
b = (A[1], (A[2], S[2]))
b
-.. code:: python
+.. code:: ipython2
for result in unify(b, a):
print result
{a1: a4, s2: (a1*, (a3, s1)), a2: a10003}
-.. code:: python
+.. code:: ipython2
for result in unify(a, b):
print result
and be used by the hybrid inferencer/interpreter. They have to store a
name and a list of stack effects.
-.. code:: python
+.. code:: ipython2
class FunctionJoyType(AnyJoyType):
For non-combinator functions the stack effects list contains stack
effect comments (represented by pairs of cons-lists as described above.)
-.. code:: python
+.. code:: ipython2
class SymbolJoyType(FunctionJoyType):
prefix = 'F'
For combinators the list contains Python functions.
-.. code:: python
+.. code:: ipython2
class CombinatorJoyType(FunctionJoyType):
For simple combinators that have only one effect (like ``dip``) you only
need one function and it can be the combinator itself.
-.. code:: python
+.. code:: ipython2
import joy.library
have to write functions that each implement the action of one of the
effects.
-.. code:: python
+.. code:: ipython2
def branch_true(stack, expression, dictionary):
(then, (else_, (flag, stack))) = stack
losing useful information. This was a straightforward, if awkward,
modification to the call structure of ``meta_compose()`` et. al.
-.. code:: python
+.. code:: ipython2
ID = S[0], S[0] # Identity function.
``SymbolJoyType`` objects, and some combinators. Here is an example of
output from the current code :
-.. code:: python
+.. code:: ipython2
1/0 # (Don't try to run this cell! It's not going to work. This is "read only" code heh..)
Anyhow, type *checking* is a few easy steps away.
-.. code:: python
+.. code:: ipython2
def _ge(self, other):
return (issubclass(other.__class__, self.__class__)
Given a datastructure on the stack we can navigate through it, modify
it, and rebuild it using the “zipper” technique.
-.. code:: python
+.. code:: ipython2
from notebook_preamble import J, V, define
`trees <https://en.wikipedia.org/wiki/Tree_%28data_structure%29>`__ out
of sequences.
-.. code:: python
+.. code:: ipython2
J('[1 [2 [3 4 25 6] 7] 8]')
these a lot it would make sense to write Python versions for efficiency,
but see below.
-.. code:: python
+.. code:: ipython2
define('z-down == [] swap uncons swap')
define('z-up == swons swap shunt')
define('z-right == [swons] cons dip uncons swap')
define('z-left == swons [uncons swap] dip swap')
-.. code:: python
+.. code:: ipython2
V('[1 [2 [3 4 25 6] 7] 8] z-down')
[] [[2 [3 4 25 6] 7] 8] 1 .
-.. code:: python
+.. code:: ipython2
V('[] [[2 [3 4 25 6] 7] 8] 1 z-right')
[1] [8] [2 [3 4 25 6] 7] .
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2 [3 4 25 6] 7] z-down')
[1] [8] [] [[3 4 25 6] 7] 2
-.. code:: python
+.. code:: ipython2
J('[1] [8] [] [[3 4 25 6] 7] 2 z-right')
[1] [8] [2] [7] [3 4 25 6]
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [3 4 25 6] z-down')
[1] [8] [2] [7] [] [4 25 6] 3
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [] [4 25 6] 3 z-right')
[1] [8] [2] [7] [3] [25 6] 4
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [3] [25 6] 4 z-right')
[1] [8] [2] [7] [4 3] [6] 25
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [4 3] [6] 25 sqr')
[1] [8] [2] [7] [4 3] [6] 625
-.. code:: python
+.. code:: ipython2
V('[1] [8] [2] [7] [4 3] [6] 625 z-up')
[1] [8] [2] [7] [3 4 625 6] .
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2] [7] [3 4 625 6] z-up')
[1] [8] [2 [3 4 625 6] 7]
-.. code:: python
+.. code:: ipython2
J('[1] [8] [2 [3 4 625 6] 7] z-up')
In Joy we have the ``dip`` and ``infra`` combinators which can “target”
or “address” any particular item in a Joy tree structure.
-.. code:: python
+.. code:: ipython2
V('[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra')
The ``Z`` function isn’t hard to make.
-.. code:: python
+.. code:: ipython2
define('Z == [[] cons cons] step i')
Here it is in action in a simplified scenario.
-.. code:: python
+.. code:: ipython2
V('1 [2 3 4] Z')
And here it is doing the main thing.
-.. code:: python
+.. code:: ipython2
J('[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z')
Treestep
Generator_Programs
Newton-Raphson
+ Square_Spiral
Zipper
Types
TypeChecking