3 <head><meta charset="utf-8" />
5 <title>Correcet_Programming</title>
7 <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
8 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
12 <style type="text/css">
19 * Bootstrap v3.3.7 (http://getbootstrap.com)
20 * Copyright 2011-2016 Twitter, Inc.
21 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
23 /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
25 font-family: sans-serif;
26 -ms-text-size-adjust: 100%;
27 -webkit-text-size-adjust: 100%;
51 display: inline-block;
52 vertical-align: baseline;
54 audio:not([controls]) {
63 background-color: transparent;
70 border-bottom: 1px dotted;
95 vertical-align: baseline;
113 box-sizing: content-box;
123 font-family: monospace, monospace;
140 text-transform: none;
143 html input[type="button"],
145 input[type="submit"] {
146 -webkit-appearance: button;
150 html input[disabled] {
153 button::-moz-focus-inner,
154 input::-moz-focus-inner {
161 input[type="checkbox"],
162 input[type="radio"] {
163 box-sizing: border-box;
166 input[type="number"]::-webkit-inner-spin-button,
167 input[type="number"]::-webkit-outer-spin-button {
170 input[type="search"] {
171 -webkit-appearance: textfield;
172 box-sizing: content-box;
174 input[type="search"]::-webkit-search-cancel-button,
175 input[type="search"]::-webkit-search-decoration {
176 -webkit-appearance: none;
179 border: 1px solid #c0c0c0;
181 padding: 0.35em 0.625em 0.75em;
194 border-collapse: collapse;
201 /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
206 background: transparent !important;
207 box-shadow: none !important;
208 text-shadow: none !important;
212 text-decoration: underline;
215 content: " (" attr(href) ")";
218 content: " (" attr(title) ")";
221 a[href^="javascript:"]:after {
226 border: 1px solid #999;
227 page-break-inside: avoid;
230 display: table-header-group;
234 page-break-inside: avoid;
237 max-width: 100% !important;
247 page-break-after: avoid;
253 .dropup > .btn > .caret {
254 border-top-color: #000 !important;
257 border: 1px solid #000;
260 border-collapse: collapse !important;
264 background-color: #fff !important;
268 border: 1px solid #ddd !important;
272 font-family: 'Glyphicons Halflings';
273 src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot');
274 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');
279 display: inline-block;
280 font-family: 'Glyphicons Halflings';
284 -webkit-font-smoothing: antialiased;
285 -moz-osx-font-smoothing: grayscale;
287 .glyphicon-asterisk:before {
290 .glyphicon-plus:before {
293 .glyphicon-euro:before,
294 .glyphicon-eur:before {
297 .glyphicon-minus:before {
300 .glyphicon-cloud:before {
303 .glyphicon-envelope:before {
306 .glyphicon-pencil:before {
309 .glyphicon-glass:before {
312 .glyphicon-music:before {
315 .glyphicon-search:before {
318 .glyphicon-heart:before {
321 .glyphicon-star:before {
324 .glyphicon-star-empty:before {
327 .glyphicon-user:before {
330 .glyphicon-film:before {
333 .glyphicon-th-large:before {
336 .glyphicon-th:before {
339 .glyphicon-th-list:before {
342 .glyphicon-ok:before {
345 .glyphicon-remove:before {
348 .glyphicon-zoom-in:before {
351 .glyphicon-zoom-out:before {
354 .glyphicon-off:before {
357 .glyphicon-signal:before {
360 .glyphicon-cog:before {
363 .glyphicon-trash:before {
366 .glyphicon-home:before {
369 .glyphicon-file:before {
372 .glyphicon-time:before {
375 .glyphicon-road:before {
378 .glyphicon-download-alt:before {
381 .glyphicon-download:before {
384 .glyphicon-upload:before {
387 .glyphicon-inbox:before {
390 .glyphicon-play-circle:before {
393 .glyphicon-repeat:before {
396 .glyphicon-refresh:before {
399 .glyphicon-list-alt:before {
402 .glyphicon-lock:before {
405 .glyphicon-flag:before {
408 .glyphicon-headphones:before {
411 .glyphicon-volume-off:before {
414 .glyphicon-volume-down:before {
417 .glyphicon-volume-up:before {
420 .glyphicon-qrcode:before {
423 .glyphicon-barcode:before {
426 .glyphicon-tag:before {
429 .glyphicon-tags:before {
432 .glyphicon-book:before {
435 .glyphicon-bookmark:before {
438 .glyphicon-print:before {
441 .glyphicon-camera:before {
444 .glyphicon-font:before {
447 .glyphicon-bold:before {
450 .glyphicon-italic:before {
453 .glyphicon-text-height:before {
456 .glyphicon-text-width:before {
459 .glyphicon-align-left:before {
462 .glyphicon-align-center:before {
465 .glyphicon-align-right:before {
468 .glyphicon-align-justify:before {
471 .glyphicon-list:before {
474 .glyphicon-indent-left:before {
477 .glyphicon-indent-right:before {
480 .glyphicon-facetime-video:before {
483 .glyphicon-picture:before {
486 .glyphicon-map-marker:before {
489 .glyphicon-adjust:before {
492 .glyphicon-tint:before {
495 .glyphicon-edit:before {
498 .glyphicon-share:before {
501 .glyphicon-check:before {
504 .glyphicon-move:before {
507 .glyphicon-step-backward:before {
510 .glyphicon-fast-backward:before {
513 .glyphicon-backward:before {
516 .glyphicon-play:before {
519 .glyphicon-pause:before {
522 .glyphicon-stop:before {
525 .glyphicon-forward:before {
528 .glyphicon-fast-forward:before {
531 .glyphicon-step-forward:before {
534 .glyphicon-eject:before {
537 .glyphicon-chevron-left:before {
540 .glyphicon-chevron-right:before {
543 .glyphicon-plus-sign:before {
546 .glyphicon-minus-sign:before {
549 .glyphicon-remove-sign:before {
552 .glyphicon-ok-sign:before {
555 .glyphicon-question-sign:before {
558 .glyphicon-info-sign:before {
561 .glyphicon-screenshot:before {
564 .glyphicon-remove-circle:before {
567 .glyphicon-ok-circle:before {
570 .glyphicon-ban-circle:before {
573 .glyphicon-arrow-left:before {
576 .glyphicon-arrow-right:before {
579 .glyphicon-arrow-up:before {
582 .glyphicon-arrow-down:before {
585 .glyphicon-share-alt:before {
588 .glyphicon-resize-full:before {
591 .glyphicon-resize-small:before {
594 .glyphicon-exclamation-sign:before {
597 .glyphicon-gift:before {
600 .glyphicon-leaf:before {
603 .glyphicon-fire:before {
606 .glyphicon-eye-open:before {
609 .glyphicon-eye-close:before {
612 .glyphicon-warning-sign:before {
615 .glyphicon-plane:before {
618 .glyphicon-calendar:before {
621 .glyphicon-random:before {
624 .glyphicon-comment:before {
627 .glyphicon-magnet:before {
630 .glyphicon-chevron-up:before {
633 .glyphicon-chevron-down:before {
636 .glyphicon-retweet:before {
639 .glyphicon-shopping-cart:before {
642 .glyphicon-folder-close:before {
645 .glyphicon-folder-open:before {
648 .glyphicon-resize-vertical:before {
651 .glyphicon-resize-horizontal:before {
654 .glyphicon-hdd:before {
657 .glyphicon-bullhorn:before {
660 .glyphicon-bell:before {
663 .glyphicon-certificate:before {
666 .glyphicon-thumbs-up:before {
669 .glyphicon-thumbs-down:before {
672 .glyphicon-hand-right:before {
675 .glyphicon-hand-left:before {
678 .glyphicon-hand-up:before {
681 .glyphicon-hand-down:before {
684 .glyphicon-circle-arrow-right:before {
687 .glyphicon-circle-arrow-left:before {
690 .glyphicon-circle-arrow-up:before {
693 .glyphicon-circle-arrow-down:before {
696 .glyphicon-globe:before {
699 .glyphicon-wrench:before {
702 .glyphicon-tasks:before {
705 .glyphicon-filter:before {
708 .glyphicon-briefcase:before {
711 .glyphicon-fullscreen:before {
714 .glyphicon-dashboard:before {
717 .glyphicon-paperclip:before {
720 .glyphicon-heart-empty:before {
723 .glyphicon-link:before {
726 .glyphicon-phone:before {
729 .glyphicon-pushpin:before {
732 .glyphicon-usd:before {
735 .glyphicon-gbp:before {
738 .glyphicon-sort:before {
741 .glyphicon-sort-by-alphabet:before {
744 .glyphicon-sort-by-alphabet-alt:before {
747 .glyphicon-sort-by-order:before {
750 .glyphicon-sort-by-order-alt:before {
753 .glyphicon-sort-by-attributes:before {
756 .glyphicon-sort-by-attributes-alt:before {
759 .glyphicon-unchecked:before {
762 .glyphicon-expand:before {
765 .glyphicon-collapse-down:before {
768 .glyphicon-collapse-up:before {
771 .glyphicon-log-in:before {
774 .glyphicon-flash:before {
777 .glyphicon-log-out:before {
780 .glyphicon-new-window:before {
783 .glyphicon-record:before {
786 .glyphicon-save:before {
789 .glyphicon-open:before {
792 .glyphicon-saved:before {
795 .glyphicon-import:before {
798 .glyphicon-export:before {
801 .glyphicon-send:before {
804 .glyphicon-floppy-disk:before {
807 .glyphicon-floppy-saved:before {
810 .glyphicon-floppy-remove:before {
813 .glyphicon-floppy-save:before {
816 .glyphicon-floppy-open:before {
819 .glyphicon-credit-card:before {
822 .glyphicon-transfer:before {
825 .glyphicon-cutlery:before {
828 .glyphicon-header:before {
831 .glyphicon-compressed:before {
834 .glyphicon-earphone:before {
837 .glyphicon-phone-alt:before {
840 .glyphicon-tower:before {
843 .glyphicon-stats:before {
846 .glyphicon-sd-video:before {
849 .glyphicon-hd-video:before {
852 .glyphicon-subtitles:before {
855 .glyphicon-sound-stereo:before {
858 .glyphicon-sound-dolby:before {
861 .glyphicon-sound-5-1:before {
864 .glyphicon-sound-6-1:before {
867 .glyphicon-sound-7-1:before {
870 .glyphicon-copyright-mark:before {
873 .glyphicon-registration-mark:before {
876 .glyphicon-cloud-download:before {
879 .glyphicon-cloud-upload:before {
882 .glyphicon-tree-conifer:before {
885 .glyphicon-tree-deciduous:before {
888 .glyphicon-cd:before {
891 .glyphicon-save-file:before {
894 .glyphicon-open-file:before {
897 .glyphicon-level-up:before {
900 .glyphicon-copy:before {
903 .glyphicon-paste:before {
906 .glyphicon-alert:before {
909 .glyphicon-equalizer:before {
912 .glyphicon-king:before {
915 .glyphicon-queen:before {
918 .glyphicon-pawn:before {
921 .glyphicon-bishop:before {
924 .glyphicon-knight:before {
927 .glyphicon-baby-formula:before {
930 .glyphicon-tent:before {
933 .glyphicon-blackboard:before {
936 .glyphicon-bed:before {
939 .glyphicon-apple:before {
942 .glyphicon-erase:before {
945 .glyphicon-hourglass:before {
948 .glyphicon-lamp:before {
951 .glyphicon-duplicate:before {
954 .glyphicon-piggy-bank:before {
957 .glyphicon-scissors:before {
960 .glyphicon-bitcoin:before {
963 .glyphicon-btc:before {
966 .glyphicon-xbt:before {
969 .glyphicon-yen:before {
972 .glyphicon-jpy:before {
975 .glyphicon-ruble:before {
978 .glyphicon-rub:before {
981 .glyphicon-scale:before {
984 .glyphicon-ice-lolly:before {
987 .glyphicon-ice-lolly-tasted:before {
990 .glyphicon-education:before {
993 .glyphicon-option-horizontal:before {
996 .glyphicon-option-vertical:before {
999 .glyphicon-menu-hamburger:before {
1002 .glyphicon-modal-window:before {
1005 .glyphicon-oil:before {
1008 .glyphicon-grain:before {
1011 .glyphicon-sunglasses:before {
1014 .glyphicon-text-size:before {
1017 .glyphicon-text-color:before {
1020 .glyphicon-text-background:before {
1023 .glyphicon-object-align-top:before {
1026 .glyphicon-object-align-bottom:before {
1029 .glyphicon-object-align-horizontal:before {
1032 .glyphicon-object-align-left:before {
1035 .glyphicon-object-align-vertical:before {
1038 .glyphicon-object-align-right:before {
1041 .glyphicon-triangle-right:before {
1044 .glyphicon-triangle-left:before {
1047 .glyphicon-triangle-bottom:before {
1050 .glyphicon-triangle-top:before {
1053 .glyphicon-console:before {
1056 .glyphicon-superscript:before {
1059 .glyphicon-subscript:before {
1062 .glyphicon-menu-left:before {
1065 .glyphicon-menu-right:before {
1068 .glyphicon-menu-down:before {
1071 .glyphicon-menu-up:before {
1075 -webkit-box-sizing: border-box;
1076 -moz-box-sizing: border-box;
1077 box-sizing: border-box;
1081 -webkit-box-sizing: border-box;
1082 -moz-box-sizing: border-box;
1083 box-sizing: border-box;
1087 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
1090 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1092 line-height: 1.42857143;
1094 background-color: #fff;
1100 font-family: inherit;
1102 line-height: inherit;
1106 text-decoration: none;
1111 text-decoration: underline;
1114 outline: 5px auto -webkit-focus-ring-color;
1115 outline-offset: -2px;
1121 vertical-align: middle;
1126 .carousel-inner > .item > img,
1127 .carousel-inner > .item > a > img {
1137 line-height: 1.42857143;
1138 background-color: #fff;
1139 border: 1px solid #ddd;
1141 -webkit-transition: all 0.2s ease-in-out;
1142 -o-transition: all 0.2s ease-in-out;
1143 transition: all 0.2s ease-in-out;
1144 display: inline-block;
1153 margin-bottom: 18px;
1155 border-top: 1px solid #eeeeee;
1164 clip: rect(0, 0, 0, 0);
1167 .sr-only-focusable:active,
1168 .sr-only-focusable:focus {
1191 font-family: inherit;
1220 font-weight: normal;
1298 margin-bottom: 18px;
1303 @media (min-width: 768px) {
1314 background-color: #fcf8e3;
1327 text-align: justify;
1330 white-space: nowrap;
1333 text-transform: lowercase;
1336 text-transform: uppercase;
1339 text-transform: capitalize;
1347 a.text-primary:hover,
1348 a.text-primary:focus {
1354 a.text-success:hover,
1355 a.text-success:focus {
1368 a.text-warning:hover,
1369 a.text-warning:focus {
1375 a.text-danger:hover,
1376 a.text-danger:focus {
1381 background-color: #337ab7;
1384 a.bg-primary:focus {
1385 background-color: #286090;
1388 background-color: #dff0d8;
1391 a.bg-success:focus {
1392 background-color: #c1e2b3;
1395 background-color: #d9edf7;
1399 background-color: #afd9ee;
1402 background-color: #fcf8e3;
1405 a.bg-warning:focus {
1406 background-color: #f7ecb5;
1409 background-color: #f2dede;
1413 background-color: #e4b9b9;
1416 padding-bottom: 8px;
1417 margin: 36px 0 18px;
1418 border-bottom: 1px solid #eeeeee;
1441 display: inline-block;
1447 margin-bottom: 18px;
1451 line-height: 1.42857143;
1459 @media (min-width: 541px) {
1466 text-overflow: ellipsis;
1467 white-space: nowrap;
1474 abbr[data-original-title] {
1476 border-bottom: 1px dotted #777777;
1480 text-transform: uppercase;
1486 border-left: 5px solid #eeeeee;
1488 blockquote p:last-child,
1489 blockquote ul:last-child,
1490 blockquote ol:last-child {
1498 line-height: 1.42857143;
1501 blockquote footer:before,
1502 blockquote small:before,
1503 blockquote .small:before {
1504 content: '\2014 \00A0';
1506 .blockquote-reverse,
1507 blockquote.pull-right {
1508 padding-right: 15px;
1510 border-right: 5px solid #eeeeee;
1514 .blockquote-reverse footer:before,
1515 blockquote.pull-right footer:before,
1516 .blockquote-reverse small:before,
1517 blockquote.pull-right small:before,
1518 .blockquote-reverse .small:before,
1519 blockquote.pull-right .small:before {
1522 .blockquote-reverse footer:after,
1523 blockquote.pull-right footer:after,
1524 .blockquote-reverse small:after,
1525 blockquote.pull-right small:after,
1526 .blockquote-reverse .small:after,
1527 blockquote.pull-right .small:after {
1528 content: '\00A0 \2014';
1531 margin-bottom: 18px;
1533 line-height: 1.42857143;
1539 font-family: monospace;
1545 background-color: #f9f2f4;
1552 background-color: transparent;
1554 box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
1567 line-height: 1.42857143;
1568 word-break: break-all;
1569 word-wrap: break-word;
1571 background-color: #f5f5f5;
1572 border: 1px solid #ccc;
1579 white-space: pre-wrap;
1580 background-color: transparent;
1593 @media (min-width: 768px) {
1598 @media (min-width: 992px) {
1603 @media (min-width: 1200px) {
1618 .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 {
1624 .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 {
1631 width: 91.66666667%;
1634 width: 83.33333333%;
1640 width: 66.66666667%;
1643 width: 58.33333333%;
1649 width: 41.66666667%;
1652 width: 33.33333333%;
1658 width: 16.66666667%;
1667 right: 91.66666667%;
1670 right: 83.33333333%;
1676 right: 66.66666667%;
1679 right: 58.33333333%;
1685 right: 41.66666667%;
1688 right: 33.33333333%;
1694 right: 16.66666667%;
1745 margin-left: 91.66666667%;
1748 margin-left: 83.33333333%;
1754 margin-left: 66.66666667%;
1757 margin-left: 58.33333333%;
1763 margin-left: 41.66666667%;
1766 margin-left: 33.33333333%;
1772 margin-left: 16.66666667%;
1775 margin-left: 8.33333333%;
1780 @media (min-width: 768px) {
1781 .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 {
1788 width: 91.66666667%;
1791 width: 83.33333333%;
1797 width: 66.66666667%;
1800 width: 58.33333333%;
1806 width: 41.66666667%;
1809 width: 33.33333333%;
1815 width: 16.66666667%;
1824 right: 91.66666667%;
1827 right: 83.33333333%;
1833 right: 66.66666667%;
1836 right: 58.33333333%;
1842 right: 41.66666667%;
1845 right: 33.33333333%;
1851 right: 16.66666667%;
1902 margin-left: 91.66666667%;
1905 margin-left: 83.33333333%;
1911 margin-left: 66.66666667%;
1914 margin-left: 58.33333333%;
1920 margin-left: 41.66666667%;
1923 margin-left: 33.33333333%;
1929 margin-left: 16.66666667%;
1932 margin-left: 8.33333333%;
1938 @media (min-width: 992px) {
1939 .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 {
1946 width: 91.66666667%;
1949 width: 83.33333333%;
1955 width: 66.66666667%;
1958 width: 58.33333333%;
1964 width: 41.66666667%;
1967 width: 33.33333333%;
1973 width: 16.66666667%;
1982 right: 91.66666667%;
1985 right: 83.33333333%;
1991 right: 66.66666667%;
1994 right: 58.33333333%;
2000 right: 41.66666667%;
2003 right: 33.33333333%;
2009 right: 16.66666667%;
2060 margin-left: 91.66666667%;
2063 margin-left: 83.33333333%;
2069 margin-left: 66.66666667%;
2072 margin-left: 58.33333333%;
2078 margin-left: 41.66666667%;
2081 margin-left: 33.33333333%;
2087 margin-left: 16.66666667%;
2090 margin-left: 8.33333333%;
2096 @media (min-width: 1200px) {
2097 .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 {
2104 width: 91.66666667%;
2107 width: 83.33333333%;
2113 width: 66.66666667%;
2116 width: 58.33333333%;
2122 width: 41.66666667%;
2125 width: 33.33333333%;
2131 width: 16.66666667%;
2140 right: 91.66666667%;
2143 right: 83.33333333%;
2149 right: 66.66666667%;
2152 right: 58.33333333%;
2158 right: 41.66666667%;
2161 right: 33.33333333%;
2167 right: 16.66666667%;
2218 margin-left: 91.66666667%;
2221 margin-left: 83.33333333%;
2227 margin-left: 66.66666667%;
2230 margin-left: 58.33333333%;
2236 margin-left: 41.66666667%;
2239 margin-left: 33.33333333%;
2245 margin-left: 16.66666667%;
2248 margin-left: 8.33333333%;
2255 background-color: transparent;
2259 padding-bottom: 8px;
2269 margin-bottom: 18px;
2271 .table > thead > tr > th,
2272 .table > tbody > tr > th,
2273 .table > tfoot > tr > th,
2274 .table > thead > tr > td,
2275 .table > tbody > tr > td,
2276 .table > tfoot > tr > td {
2278 line-height: 1.42857143;
2279 vertical-align: top;
2280 border-top: 1px solid #ddd;
2282 .table > thead > tr > th {
2283 vertical-align: bottom;
2284 border-bottom: 2px solid #ddd;
2286 .table > caption + thead > tr:first-child > th,
2287 .table > colgroup + thead > tr:first-child > th,
2288 .table > thead:first-child > tr:first-child > th,
2289 .table > caption + thead > tr:first-child > td,
2290 .table > colgroup + thead > tr:first-child > td,
2291 .table > thead:first-child > tr:first-child > td {
2294 .table > tbody + tbody {
2295 border-top: 2px solid #ddd;
2298 background-color: #fff;
2300 .table-condensed > thead > tr > th,
2301 .table-condensed > tbody > tr > th,
2302 .table-condensed > tfoot > tr > th,
2303 .table-condensed > thead > tr > td,
2304 .table-condensed > tbody > tr > td,
2305 .table-condensed > tfoot > tr > td {
2309 border: 1px solid #ddd;
2311 .table-bordered > thead > tr > th,
2312 .table-bordered > tbody > tr > th,
2313 .table-bordered > tfoot > tr > th,
2314 .table-bordered > thead > tr > td,
2315 .table-bordered > tbody > tr > td,
2316 .table-bordered > tfoot > tr > td {
2317 border: 1px solid #ddd;
2319 .table-bordered > thead > tr > th,
2320 .table-bordered > thead > tr > td {
2321 border-bottom-width: 2px;
2323 .table-striped > tbody > tr:nth-of-type(odd) {
2324 background-color: #f9f9f9;
2326 .table-hover > tbody > tr:hover {
2327 background-color: #f5f5f5;
2329 table col[class*="col-"] {
2332 display: table-column;
2334 table td[class*="col-"],
2335 table th[class*="col-"] {
2338 display: table-cell;
2340 .table > thead > tr > td.active,
2341 .table > tbody > tr > td.active,
2342 .table > tfoot > tr > td.active,
2343 .table > thead > tr > th.active,
2344 .table > tbody > tr > th.active,
2345 .table > tfoot > tr > th.active,
2346 .table > thead > tr.active > td,
2347 .table > tbody > tr.active > td,
2348 .table > tfoot > tr.active > td,
2349 .table > thead > tr.active > th,
2350 .table > tbody > tr.active > th,
2351 .table > tfoot > tr.active > th {
2352 background-color: #f5f5f5;
2354 .table-hover > tbody > tr > td.active:hover,
2355 .table-hover > tbody > tr > th.active:hover,
2356 .table-hover > tbody > tr.active:hover > td,
2357 .table-hover > tbody > tr:hover > .active,
2358 .table-hover > tbody > tr.active:hover > th {
2359 background-color: #e8e8e8;
2361 .table > thead > tr > td.success,
2362 .table > tbody > tr > td.success,
2363 .table > tfoot > tr > td.success,
2364 .table > thead > tr > th.success,
2365 .table > tbody > tr > th.success,
2366 .table > tfoot > tr > th.success,
2367 .table > thead > tr.success > td,
2368 .table > tbody > tr.success > td,
2369 .table > tfoot > tr.success > td,
2370 .table > thead > tr.success > th,
2371 .table > tbody > tr.success > th,
2372 .table > tfoot > tr.success > th {
2373 background-color: #dff0d8;
2375 .table-hover > tbody > tr > td.success:hover,
2376 .table-hover > tbody > tr > th.success:hover,
2377 .table-hover > tbody > tr.success:hover > td,
2378 .table-hover > tbody > tr:hover > .success,
2379 .table-hover > tbody > tr.success:hover > th {
2380 background-color: #d0e9c6;
2382 .table > thead > tr > td.info,
2383 .table > tbody > tr > td.info,
2384 .table > tfoot > tr > td.info,
2385 .table > thead > tr > th.info,
2386 .table > tbody > tr > th.info,
2387 .table > tfoot > tr > th.info,
2388 .table > thead > tr.info > td,
2389 .table > tbody > tr.info > td,
2390 .table > tfoot > tr.info > td,
2391 .table > thead > tr.info > th,
2392 .table > tbody > tr.info > th,
2393 .table > tfoot > tr.info > th {
2394 background-color: #d9edf7;
2396 .table-hover > tbody > tr > td.info:hover,
2397 .table-hover > tbody > tr > th.info:hover,
2398 .table-hover > tbody > tr.info:hover > td,
2399 .table-hover > tbody > tr:hover > .info,
2400 .table-hover > tbody > tr.info:hover > th {
2401 background-color: #c4e3f3;
2403 .table > thead > tr > td.warning,
2404 .table > tbody > tr > td.warning,
2405 .table > tfoot > tr > td.warning,
2406 .table > thead > tr > th.warning,
2407 .table > tbody > tr > th.warning,
2408 .table > tfoot > tr > th.warning,
2409 .table > thead > tr.warning > td,
2410 .table > tbody > tr.warning > td,
2411 .table > tfoot > tr.warning > td,
2412 .table > thead > tr.warning > th,
2413 .table > tbody > tr.warning > th,
2414 .table > tfoot > tr.warning > th {
2415 background-color: #fcf8e3;
2417 .table-hover > tbody > tr > td.warning:hover,
2418 .table-hover > tbody > tr > th.warning:hover,
2419 .table-hover > tbody > tr.warning:hover > td,
2420 .table-hover > tbody > tr:hover > .warning,
2421 .table-hover > tbody > tr.warning:hover > th {
2422 background-color: #faf2cc;
2424 .table > thead > tr > td.danger,
2425 .table > tbody > tr > td.danger,
2426 .table > tfoot > tr > td.danger,
2427 .table > thead > tr > th.danger,
2428 .table > tbody > tr > th.danger,
2429 .table > tfoot > tr > th.danger,
2430 .table > thead > tr.danger > td,
2431 .table > tbody > tr.danger > td,
2432 .table > tfoot > tr.danger > td,
2433 .table > thead > tr.danger > th,
2434 .table > tbody > tr.danger > th,
2435 .table > tfoot > tr.danger > th {
2436 background-color: #f2dede;
2438 .table-hover > tbody > tr > td.danger:hover,
2439 .table-hover > tbody > tr > th.danger:hover,
2440 .table-hover > tbody > tr.danger:hover > td,
2441 .table-hover > tbody > tr:hover > .danger,
2442 .table-hover > tbody > tr.danger:hover > th {
2443 background-color: #ebcccc;
2449 @media screen and (max-width: 767px) {
2452 margin-bottom: 13.5px;
2454 -ms-overflow-style: -ms-autohiding-scrollbar;
2455 border: 1px solid #ddd;
2457 .table-responsive > .table {
2460 .table-responsive > .table > thead > tr > th,
2461 .table-responsive > .table > tbody > tr > th,
2462 .table-responsive > .table > tfoot > tr > th,
2463 .table-responsive > .table > thead > tr > td,
2464 .table-responsive > .table > tbody > tr > td,
2465 .table-responsive > .table > tfoot > tr > td {
2466 white-space: nowrap;
2468 .table-responsive > .table-bordered {
2471 .table-responsive > .table-bordered > thead > tr > th:first-child,
2472 .table-responsive > .table-bordered > tbody > tr > th:first-child,
2473 .table-responsive > .table-bordered > tfoot > tr > th:first-child,
2474 .table-responsive > .table-bordered > thead > tr > td:first-child,
2475 .table-responsive > .table-bordered > tbody > tr > td:first-child,
2476 .table-responsive > .table-bordered > tfoot > tr > td:first-child {
2479 .table-responsive > .table-bordered > thead > tr > th:last-child,
2480 .table-responsive > .table-bordered > tbody > tr > th:last-child,
2481 .table-responsive > .table-bordered > tfoot > tr > th:last-child,
2482 .table-responsive > .table-bordered > thead > tr > td:last-child,
2483 .table-responsive > .table-bordered > tbody > tr > td:last-child,
2484 .table-responsive > .table-bordered > tfoot > tr > td:last-child {
2487 .table-responsive > .table-bordered > tbody > tr:last-child > th,
2488 .table-responsive > .table-bordered > tfoot > tr:last-child > th,
2489 .table-responsive > .table-bordered > tbody > tr:last-child > td,
2490 .table-responsive > .table-bordered > tfoot > tr:last-child > td {
2504 margin-bottom: 18px;
2506 line-height: inherit;
2509 border-bottom: 1px solid #e5e5e5;
2512 display: inline-block;
2517 input[type="search"] {
2518 -webkit-box-sizing: border-box;
2519 -moz-box-sizing: border-box;
2520 box-sizing: border-box;
2522 input[type="radio"],
2523 input[type="checkbox"] {
2526 line-height: normal;
2528 input[type="file"] {
2531 input[type="range"] {
2539 input[type="file"]:focus,
2540 input[type="radio"]:focus,
2541 input[type="checkbox"]:focus {
2542 outline: 5px auto -webkit-focus-ring-color;
2543 outline-offset: -2px;
2549 line-height: 1.42857143;
2558 line-height: 1.42857143;
2560 background-color: #fff;
2561 background-image: none;
2562 border: 1px solid #ccc;
2564 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2565 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2566 -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2567 -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2568 transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2570 .form-control:focus {
2571 border-color: #66afe9;
2573 -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
2574 box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
2576 .form-control::-moz-placeholder {
2580 .form-control:-ms-input-placeholder {
2583 .form-control::-webkit-input-placeholder {
2586 .form-control::-ms-expand {
2588 background-color: transparent;
2590 .form-control[disabled],
2591 .form-control[readonly],
2592 fieldset[disabled] .form-control {
2593 background-color: #eeeeee;
2596 .form-control[disabled],
2597 fieldset[disabled] .form-control {
2598 cursor: not-allowed;
2600 textarea.form-control {
2603 input[type="search"] {
2604 -webkit-appearance: none;
2606 @media screen and (-webkit-min-device-pixel-ratio: 0) {
2607 input[type="date"].form-control,
2608 input[type="time"].form-control,
2609 input[type="datetime-local"].form-control,
2610 input[type="month"].form-control {
2613 input[type="date"].input-sm,
2614 input[type="time"].input-sm,
2615 input[type="datetime-local"].input-sm,
2616 input[type="month"].input-sm,
2617 .input-group-sm input[type="date"],
2618 .input-group-sm input[type="time"],
2619 .input-group-sm input[type="datetime-local"],
2620 .input-group-sm input[type="month"] {
2623 input[type="date"].input-lg,
2624 input[type="time"].input-lg,
2625 input[type="datetime-local"].input-lg,
2626 input[type="month"].input-lg,
2627 .input-group-lg input[type="date"],
2628 .input-group-lg input[type="time"],
2629 .input-group-lg input[type="datetime-local"],
2630 .input-group-lg input[type="month"] {
2635 margin-bottom: 15px;
2642 margin-bottom: 10px;
2649 font-weight: normal;
2652 .radio input[type="radio"],
2653 .radio-inline input[type="radio"],
2654 .checkbox input[type="checkbox"],
2655 .checkbox-inline input[type="checkbox"] {
2661 .checkbox + .checkbox {
2667 display: inline-block;
2670 vertical-align: middle;
2671 font-weight: normal;
2674 .radio-inline + .radio-inline,
2675 .checkbox-inline + .checkbox-inline {
2679 input[type="radio"][disabled],
2680 input[type="checkbox"][disabled],
2681 input[type="radio"].disabled,
2682 input[type="checkbox"].disabled,
2683 fieldset[disabled] input[type="radio"],
2684 fieldset[disabled] input[type="checkbox"] {
2685 cursor: not-allowed;
2687 .radio-inline.disabled,
2688 .checkbox-inline.disabled,
2689 fieldset[disabled] .radio-inline,
2690 fieldset[disabled] .checkbox-inline {
2691 cursor: not-allowed;
2693 .radio.disabled label,
2694 .checkbox.disabled label,
2695 fieldset[disabled] .radio label,
2696 fieldset[disabled] .checkbox label {
2697 cursor: not-allowed;
2699 .form-control-static {
2701 padding-bottom: 7px;
2705 .form-control-static.input-lg,
2706 .form-control-static.input-sm {
2722 select[multiple].input-sm {
2725 .form-group-sm .form-control {
2732 .form-group-sm select.form-control {
2736 .form-group-sm textarea.form-control,
2737 .form-group-sm select[multiple].form-control {
2740 .form-group-sm .form-control-static {
2751 line-height: 1.3333333;
2759 select[multiple].input-lg {
2762 .form-group-lg .form-control {
2766 line-height: 1.3333333;
2769 .form-group-lg select.form-control {
2773 .form-group-lg textarea.form-control,
2774 .form-group-lg select[multiple].form-control {
2777 .form-group-lg .form-control-static {
2782 line-height: 1.3333333;
2787 .has-feedback .form-control {
2788 padding-right: 40px;
2790 .form-control-feedback {
2800 pointer-events: none;
2802 .input-lg + .form-control-feedback,
2803 .input-group-lg + .form-control-feedback,
2804 .form-group-lg .form-control + .form-control-feedback {
2809 .input-sm + .form-control-feedback,
2810 .input-group-sm + .form-control-feedback,
2811 .form-group-sm .form-control + .form-control-feedback {
2816 .has-success .help-block,
2817 .has-success .control-label,
2818 .has-success .radio,
2819 .has-success .checkbox,
2820 .has-success .radio-inline,
2821 .has-success .checkbox-inline,
2822 .has-success.radio label,
2823 .has-success.checkbox label,
2824 .has-success.radio-inline label,
2825 .has-success.checkbox-inline label {
2828 .has-success .form-control {
2829 border-color: #3c763d;
2830 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2831 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2833 .has-success .form-control:focus {
2834 border-color: #2b542c;
2835 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
2836 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
2838 .has-success .input-group-addon {
2840 border-color: #3c763d;
2841 background-color: #dff0d8;
2843 .has-success .form-control-feedback {
2846 .has-warning .help-block,
2847 .has-warning .control-label,
2848 .has-warning .radio,
2849 .has-warning .checkbox,
2850 .has-warning .radio-inline,
2851 .has-warning .checkbox-inline,
2852 .has-warning.radio label,
2853 .has-warning.checkbox label,
2854 .has-warning.radio-inline label,
2855 .has-warning.checkbox-inline label {
2858 .has-warning .form-control {
2859 border-color: #8a6d3b;
2860 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2861 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2863 .has-warning .form-control:focus {
2864 border-color: #66512c;
2865 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
2866 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
2868 .has-warning .input-group-addon {
2870 border-color: #8a6d3b;
2871 background-color: #fcf8e3;
2873 .has-warning .form-control-feedback {
2876 .has-error .help-block,
2877 .has-error .control-label,
2879 .has-error .checkbox,
2880 .has-error .radio-inline,
2881 .has-error .checkbox-inline,
2882 .has-error.radio label,
2883 .has-error.checkbox label,
2884 .has-error.radio-inline label,
2885 .has-error.checkbox-inline label {
2888 .has-error .form-control {
2889 border-color: #a94442;
2890 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2891 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2893 .has-error .form-control:focus {
2894 border-color: #843534;
2895 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
2896 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
2898 .has-error .input-group-addon {
2900 border-color: #a94442;
2901 background-color: #f2dede;
2903 .has-error .form-control-feedback {
2906 .has-feedback label ~ .form-control-feedback {
2909 .has-feedback label.sr-only ~ .form-control-feedback {
2915 margin-bottom: 10px;
2918 @media (min-width: 768px) {
2919 .form-inline .form-group {
2920 display: inline-block;
2922 vertical-align: middle;
2924 .form-inline .form-control {
2925 display: inline-block;
2927 vertical-align: middle;
2929 .form-inline .form-control-static {
2930 display: inline-block;
2932 .form-inline .input-group {
2933 display: inline-table;
2934 vertical-align: middle;
2936 .form-inline .input-group .input-group-addon,
2937 .form-inline .input-group .input-group-btn,
2938 .form-inline .input-group .form-control {
2941 .form-inline .input-group > .form-control {
2944 .form-inline .control-label {
2946 vertical-align: middle;
2948 .form-inline .radio,
2949 .form-inline .checkbox {
2950 display: inline-block;
2953 vertical-align: middle;
2955 .form-inline .radio label,
2956 .form-inline .checkbox label {
2959 .form-inline .radio input[type="radio"],
2960 .form-inline .checkbox input[type="checkbox"] {
2964 .form-inline .has-feedback .form-control-feedback {
2968 .form-horizontal .radio,
2969 .form-horizontal .checkbox,
2970 .form-horizontal .radio-inline,
2971 .form-horizontal .checkbox-inline {
2976 .form-horizontal .radio,
2977 .form-horizontal .checkbox {
2980 .form-horizontal .form-group {
2984 @media (min-width: 768px) {
2985 .form-horizontal .control-label {
2991 .form-horizontal .has-feedback .form-control-feedback {
2994 @media (min-width: 768px) {
2995 .form-horizontal .form-group-lg .control-label {
3000 @media (min-width: 768px) {
3001 .form-horizontal .form-group-sm .control-label {
3007 display: inline-block;
3009 font-weight: normal;
3011 vertical-align: middle;
3012 touch-action: manipulation;
3014 background-image: none;
3015 border: 1px solid transparent;
3016 white-space: nowrap;
3019 line-height: 1.42857143;
3021 -webkit-user-select: none;
3022 -moz-user-select: none;
3023 -ms-user-select: none;
3032 outline: 5px auto -webkit-focus-ring-color;
3033 outline-offset: -2px;
3039 text-decoration: none;
3044 background-image: none;
3045 -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3046 box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3050 fieldset[disabled] .btn {
3051 cursor: not-allowed;
3053 filter: alpha(opacity=65);
3054 -webkit-box-shadow: none;
3058 fieldset[disabled] a.btn {
3059 pointer-events: none;
3063 background-color: #fff;
3067 .btn-default.focus {
3069 background-color: #e6e6e6;
3070 border-color: #8c8c8c;
3072 .btn-default:hover {
3074 background-color: #e6e6e6;
3075 border-color: #adadad;
3077 .btn-default:active,
3078 .btn-default.active,
3079 .open > .dropdown-toggle.btn-default {
3081 background-color: #e6e6e6;
3082 border-color: #adadad;
3084 .btn-default:active:hover,
3085 .btn-default.active:hover,
3086 .open > .dropdown-toggle.btn-default:hover,
3087 .btn-default:active:focus,
3088 .btn-default.active:focus,
3089 .open > .dropdown-toggle.btn-default:focus,
3090 .btn-default:active.focus,
3091 .btn-default.active.focus,
3092 .open > .dropdown-toggle.btn-default.focus {
3094 background-color: #d4d4d4;
3095 border-color: #8c8c8c;
3097 .btn-default:active,
3098 .btn-default.active,
3099 .open > .dropdown-toggle.btn-default {
3100 background-image: none;
3102 .btn-default.disabled:hover,
3103 .btn-default[disabled]:hover,
3104 fieldset[disabled] .btn-default:hover,
3105 .btn-default.disabled:focus,
3106 .btn-default[disabled]:focus,
3107 fieldset[disabled] .btn-default:focus,
3108 .btn-default.disabled.focus,
3109 .btn-default[disabled].focus,
3110 fieldset[disabled] .btn-default.focus {
3111 background-color: #fff;
3114 .btn-default .badge {
3116 background-color: #333;
3120 background-color: #337ab7;
3121 border-color: #2e6da4;
3124 .btn-primary.focus {
3126 background-color: #286090;
3127 border-color: #122b40;
3129 .btn-primary:hover {
3131 background-color: #286090;
3132 border-color: #204d74;
3134 .btn-primary:active,
3135 .btn-primary.active,
3136 .open > .dropdown-toggle.btn-primary {
3138 background-color: #286090;
3139 border-color: #204d74;
3141 .btn-primary:active:hover,
3142 .btn-primary.active:hover,
3143 .open > .dropdown-toggle.btn-primary:hover,
3144 .btn-primary:active:focus,
3145 .btn-primary.active:focus,
3146 .open > .dropdown-toggle.btn-primary:focus,
3147 .btn-primary:active.focus,
3148 .btn-primary.active.focus,
3149 .open > .dropdown-toggle.btn-primary.focus {
3151 background-color: #204d74;
3152 border-color: #122b40;
3154 .btn-primary:active,
3155 .btn-primary.active,
3156 .open > .dropdown-toggle.btn-primary {
3157 background-image: none;
3159 .btn-primary.disabled:hover,
3160 .btn-primary[disabled]:hover,
3161 fieldset[disabled] .btn-primary:hover,
3162 .btn-primary.disabled:focus,
3163 .btn-primary[disabled]:focus,
3164 fieldset[disabled] .btn-primary:focus,
3165 .btn-primary.disabled.focus,
3166 .btn-primary[disabled].focus,
3167 fieldset[disabled] .btn-primary.focus {
3168 background-color: #337ab7;
3169 border-color: #2e6da4;
3171 .btn-primary .badge {
3173 background-color: #fff;
3177 background-color: #5cb85c;
3178 border-color: #4cae4c;
3181 .btn-success.focus {
3183 background-color: #449d44;
3184 border-color: #255625;
3186 .btn-success:hover {
3188 background-color: #449d44;
3189 border-color: #398439;
3191 .btn-success:active,
3192 .btn-success.active,
3193 .open > .dropdown-toggle.btn-success {
3195 background-color: #449d44;
3196 border-color: #398439;
3198 .btn-success:active:hover,
3199 .btn-success.active:hover,
3200 .open > .dropdown-toggle.btn-success:hover,
3201 .btn-success:active:focus,
3202 .btn-success.active:focus,
3203 .open > .dropdown-toggle.btn-success:focus,
3204 .btn-success:active.focus,
3205 .btn-success.active.focus,
3206 .open > .dropdown-toggle.btn-success.focus {
3208 background-color: #398439;
3209 border-color: #255625;
3211 .btn-success:active,
3212 .btn-success.active,
3213 .open > .dropdown-toggle.btn-success {
3214 background-image: none;
3216 .btn-success.disabled:hover,
3217 .btn-success[disabled]:hover,
3218 fieldset[disabled] .btn-success:hover,
3219 .btn-success.disabled:focus,
3220 .btn-success[disabled]:focus,
3221 fieldset[disabled] .btn-success:focus,
3222 .btn-success.disabled.focus,
3223 .btn-success[disabled].focus,
3224 fieldset[disabled] .btn-success.focus {
3225 background-color: #5cb85c;
3226 border-color: #4cae4c;
3228 .btn-success .badge {
3230 background-color: #fff;
3234 background-color: #5bc0de;
3235 border-color: #46b8da;
3240 background-color: #31b0d5;
3241 border-color: #1b6d85;
3245 background-color: #31b0d5;
3246 border-color: #269abc;
3250 .open > .dropdown-toggle.btn-info {
3252 background-color: #31b0d5;
3253 border-color: #269abc;
3255 .btn-info:active:hover,
3256 .btn-info.active:hover,
3257 .open > .dropdown-toggle.btn-info:hover,
3258 .btn-info:active:focus,
3259 .btn-info.active:focus,
3260 .open > .dropdown-toggle.btn-info:focus,
3261 .btn-info:active.focus,
3262 .btn-info.active.focus,
3263 .open > .dropdown-toggle.btn-info.focus {
3265 background-color: #269abc;
3266 border-color: #1b6d85;
3270 .open > .dropdown-toggle.btn-info {
3271 background-image: none;
3273 .btn-info.disabled:hover,
3274 .btn-info[disabled]:hover,
3275 fieldset[disabled] .btn-info:hover,
3276 .btn-info.disabled:focus,
3277 .btn-info[disabled]:focus,
3278 fieldset[disabled] .btn-info:focus,
3279 .btn-info.disabled.focus,
3280 .btn-info[disabled].focus,
3281 fieldset[disabled] .btn-info.focus {
3282 background-color: #5bc0de;
3283 border-color: #46b8da;
3287 background-color: #fff;
3291 background-color: #f0ad4e;
3292 border-color: #eea236;
3295 .btn-warning.focus {
3297 background-color: #ec971f;
3298 border-color: #985f0d;
3300 .btn-warning:hover {
3302 background-color: #ec971f;
3303 border-color: #d58512;
3305 .btn-warning:active,
3306 .btn-warning.active,
3307 .open > .dropdown-toggle.btn-warning {
3309 background-color: #ec971f;
3310 border-color: #d58512;
3312 .btn-warning:active:hover,
3313 .btn-warning.active:hover,
3314 .open > .dropdown-toggle.btn-warning:hover,
3315 .btn-warning:active:focus,
3316 .btn-warning.active:focus,
3317 .open > .dropdown-toggle.btn-warning:focus,
3318 .btn-warning:active.focus,
3319 .btn-warning.active.focus,
3320 .open > .dropdown-toggle.btn-warning.focus {
3322 background-color: #d58512;
3323 border-color: #985f0d;
3325 .btn-warning:active,
3326 .btn-warning.active,
3327 .open > .dropdown-toggle.btn-warning {
3328 background-image: none;
3330 .btn-warning.disabled:hover,
3331 .btn-warning[disabled]:hover,
3332 fieldset[disabled] .btn-warning:hover,
3333 .btn-warning.disabled:focus,
3334 .btn-warning[disabled]:focus,
3335 fieldset[disabled] .btn-warning:focus,
3336 .btn-warning.disabled.focus,
3337 .btn-warning[disabled].focus,
3338 fieldset[disabled] .btn-warning.focus {
3339 background-color: #f0ad4e;
3340 border-color: #eea236;
3342 .btn-warning .badge {
3344 background-color: #fff;
3348 background-color: #d9534f;
3349 border-color: #d43f3a;
3354 background-color: #c9302c;
3355 border-color: #761c19;
3359 background-color: #c9302c;
3360 border-color: #ac2925;
3364 .open > .dropdown-toggle.btn-danger {
3366 background-color: #c9302c;
3367 border-color: #ac2925;
3369 .btn-danger:active:hover,
3370 .btn-danger.active:hover,
3371 .open > .dropdown-toggle.btn-danger:hover,
3372 .btn-danger:active:focus,
3373 .btn-danger.active:focus,
3374 .open > .dropdown-toggle.btn-danger:focus,
3375 .btn-danger:active.focus,
3376 .btn-danger.active.focus,
3377 .open > .dropdown-toggle.btn-danger.focus {
3379 background-color: #ac2925;
3380 border-color: #761c19;
3384 .open > .dropdown-toggle.btn-danger {
3385 background-image: none;
3387 .btn-danger.disabled:hover,
3388 .btn-danger[disabled]:hover,
3389 fieldset[disabled] .btn-danger:hover,
3390 .btn-danger.disabled:focus,
3391 .btn-danger[disabled]:focus,
3392 fieldset[disabled] .btn-danger:focus,
3393 .btn-danger.disabled.focus,
3394 .btn-danger[disabled].focus,
3395 fieldset[disabled] .btn-danger.focus {
3396 background-color: #d9534f;
3397 border-color: #d43f3a;
3399 .btn-danger .badge {
3401 background-color: #fff;
3405 font-weight: normal;
3411 .btn-link[disabled],
3412 fieldset[disabled] .btn-link {
3413 background-color: transparent;
3414 -webkit-box-shadow: none;
3421 border-color: transparent;
3426 text-decoration: underline;
3427 background-color: transparent;
3429 .btn-link[disabled]:hover,
3430 fieldset[disabled] .btn-link:hover,
3431 .btn-link[disabled]:focus,
3432 fieldset[disabled] .btn-link:focus {
3434 text-decoration: none;
3437 .btn-group-lg > .btn {
3440 line-height: 1.3333333;
3444 .btn-group-sm > .btn {
3451 .btn-group-xs > .btn {
3461 .btn-block + .btn-block {
3464 input[type="submit"].btn-block,
3465 input[type="reset"].btn-block,
3466 input[type="button"].btn-block {
3471 -webkit-transition: opacity 0.15s linear;
3472 -o-transition: opacity 0.15s linear;
3473 transition: opacity 0.15s linear;
3488 display: table-row-group;
3494 -webkit-transition-property: height, visibility;
3495 transition-property: height, visibility;
3496 -webkit-transition-duration: 0.35s;
3497 transition-duration: 0.35s;
3498 -webkit-transition-timing-function: ease;
3499 transition-timing-function: ease;
3502 display: inline-block;
3506 vertical-align: middle;
3507 border-top: 4px dashed;
3508 border-top: 4px solid \9;
3509 border-right: 4px solid transparent;
3510 border-left: 4px solid transparent;
3516 .dropdown-toggle:focus {
3532 background-color: #fff;
3533 border: 1px solid #ccc;
3534 border: 1px solid rgba(0, 0, 0, 0.15);
3536 -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
3537 box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
3538 background-clip: padding-box;
3540 .dropdown-menu.pull-right {
3544 .dropdown-menu .divider {
3548 background-color: #e5e5e5;
3550 .dropdown-menu > li > a {
3554 font-weight: normal;
3555 line-height: 1.42857143;
3557 white-space: nowrap;
3559 .dropdown-menu > li > a:hover,
3560 .dropdown-menu > li > a:focus {
3561 text-decoration: none;
3563 background-color: #f5f5f5;
3565 .dropdown-menu > .active > a,
3566 .dropdown-menu > .active > a:hover,
3567 .dropdown-menu > .active > a:focus {
3569 text-decoration: none;
3571 background-color: #337ab7;
3573 .dropdown-menu > .disabled > a,
3574 .dropdown-menu > .disabled > a:hover,
3575 .dropdown-menu > .disabled > a:focus {
3578 .dropdown-menu > .disabled > a:hover,
3579 .dropdown-menu > .disabled > a:focus {
3580 text-decoration: none;
3581 background-color: transparent;
3582 background-image: none;
3583 filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
3584 cursor: not-allowed;
3586 .open > .dropdown-menu {
3592 .dropdown-menu-right {
3596 .dropdown-menu-left {
3604 line-height: 1.42857143;
3606 white-space: nowrap;
3608 .dropdown-backdrop {
3616 .pull-right > .dropdown-menu {
3621 .navbar-fixed-bottom .dropdown .caret {
3623 border-bottom: 4px dashed;
3624 border-bottom: 4px solid \9;
3627 .dropup .dropdown-menu,
3628 .navbar-fixed-bottom .dropdown .dropdown-menu {
3633 @media (min-width: 541px) {
3634 .navbar-right .dropdown-menu {
3638 .navbar-right .dropdown-menu-left {
3644 .btn-group-vertical {
3646 display: inline-block;
3647 vertical-align: middle;
3650 .btn-group-vertical > .btn {
3654 .btn-group > .btn:hover,
3655 .btn-group-vertical > .btn:hover,
3656 .btn-group > .btn:focus,
3657 .btn-group-vertical > .btn:focus,
3658 .btn-group > .btn:active,
3659 .btn-group-vertical > .btn:active,
3660 .btn-group > .btn.active,
3661 .btn-group-vertical > .btn.active {
3664 .btn-group .btn + .btn,
3665 .btn-group .btn + .btn-group,
3666 .btn-group .btn-group + .btn,
3667 .btn-group .btn-group + .btn-group {
3674 .btn-toolbar .btn-group,
3675 .btn-toolbar .input-group {
3678 .btn-toolbar > .btn,
3679 .btn-toolbar > .btn-group,
3680 .btn-toolbar > .input-group {
3683 .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
3686 .btn-group > .btn:first-child {
3689 .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
3690 border-bottom-right-radius: 0;
3691 border-top-right-radius: 0;
3693 .btn-group > .btn:last-child:not(:first-child),
3694 .btn-group > .dropdown-toggle:not(:first-child) {
3695 border-bottom-left-radius: 0;
3696 border-top-left-radius: 0;
3698 .btn-group > .btn-group {
3701 .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
3704 .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
3705 .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
3706 border-bottom-right-radius: 0;
3707 border-top-right-radius: 0;
3709 .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
3710 border-bottom-left-radius: 0;
3711 border-top-left-radius: 0;
3713 .btn-group .dropdown-toggle:active,
3714 .btn-group.open .dropdown-toggle {
3717 .btn-group > .btn + .dropdown-toggle {
3721 .btn-group > .btn-lg + .dropdown-toggle {
3723 padding-right: 12px;
3725 .btn-group.open .dropdown-toggle {
3726 -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3727 box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3729 .btn-group.open .dropdown-toggle.btn-link {
3730 -webkit-box-shadow: none;
3737 border-width: 5px 5px 0;
3738 border-bottom-width: 0;
3740 .dropup .btn-lg .caret {
3741 border-width: 0 5px 5px;
3743 .btn-group-vertical > .btn,
3744 .btn-group-vertical > .btn-group,
3745 .btn-group-vertical > .btn-group > .btn {
3751 .btn-group-vertical > .btn-group > .btn {
3754 .btn-group-vertical > .btn + .btn,
3755 .btn-group-vertical > .btn + .btn-group,
3756 .btn-group-vertical > .btn-group + .btn,
3757 .btn-group-vertical > .btn-group + .btn-group {
3761 .btn-group-vertical > .btn:not(:first-child):not(:last-child) {
3764 .btn-group-vertical > .btn:first-child:not(:last-child) {
3765 border-top-right-radius: 2px;
3766 border-top-left-radius: 2px;
3767 border-bottom-right-radius: 0;
3768 border-bottom-left-radius: 0;
3770 .btn-group-vertical > .btn:last-child:not(:first-child) {
3771 border-top-right-radius: 0;
3772 border-top-left-radius: 0;
3773 border-bottom-right-radius: 2px;
3774 border-bottom-left-radius: 2px;
3776 .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
3779 .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
3780 .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
3781 border-bottom-right-radius: 0;
3782 border-bottom-left-radius: 0;
3784 .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
3785 border-top-right-radius: 0;
3786 border-top-left-radius: 0;
3788 .btn-group-justified {
3791 table-layout: fixed;
3792 border-collapse: separate;
3794 .btn-group-justified > .btn,
3795 .btn-group-justified > .btn-group {
3797 display: table-cell;
3800 .btn-group-justified > .btn-group .btn {
3803 .btn-group-justified > .btn-group .dropdown-menu {
3806 [data-toggle="buttons"] > .btn input[type="radio"],
3807 [data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
3808 [data-toggle="buttons"] > .btn input[type="checkbox"],
3809 [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
3811 clip: rect(0, 0, 0, 0);
3812 pointer-events: none;
3817 border-collapse: separate;
3819 .input-group[class*="col-"] {
3824 .input-group .form-control {
3831 .input-group .form-control:focus {
3834 .input-group-lg > .form-control,
3835 .input-group-lg > .input-group-addon,
3836 .input-group-lg > .input-group-btn > .btn {
3840 line-height: 1.3333333;
3843 select.input-group-lg > .form-control,
3844 select.input-group-lg > .input-group-addon,
3845 select.input-group-lg > .input-group-btn > .btn {
3849 textarea.input-group-lg > .form-control,
3850 textarea.input-group-lg > .input-group-addon,
3851 textarea.input-group-lg > .input-group-btn > .btn,
3852 select[multiple].input-group-lg > .form-control,
3853 select[multiple].input-group-lg > .input-group-addon,
3854 select[multiple].input-group-lg > .input-group-btn > .btn {
3857 .input-group-sm > .form-control,
3858 .input-group-sm > .input-group-addon,
3859 .input-group-sm > .input-group-btn > .btn {
3866 select.input-group-sm > .form-control,
3867 select.input-group-sm > .input-group-addon,
3868 select.input-group-sm > .input-group-btn > .btn {
3872 textarea.input-group-sm > .form-control,
3873 textarea.input-group-sm > .input-group-addon,
3874 textarea.input-group-sm > .input-group-btn > .btn,
3875 select[multiple].input-group-sm > .form-control,
3876 select[multiple].input-group-sm > .input-group-addon,
3877 select[multiple].input-group-sm > .input-group-btn > .btn {
3882 .input-group .form-control {
3883 display: table-cell;
3885 .input-group-addon:not(:first-child):not(:last-child),
3886 .input-group-btn:not(:first-child):not(:last-child),
3887 .input-group .form-control:not(:first-child):not(:last-child) {
3893 white-space: nowrap;
3894 vertical-align: middle;
3896 .input-group-addon {
3899 font-weight: normal;
3903 background-color: #eeeeee;
3904 border: 1px solid #ccc;
3907 .input-group-addon.input-sm {
3912 .input-group-addon.input-lg {
3917 .input-group-addon input[type="radio"],
3918 .input-group-addon input[type="checkbox"] {
3921 .input-group .form-control:first-child,
3922 .input-group-addon:first-child,
3923 .input-group-btn:first-child > .btn,
3924 .input-group-btn:first-child > .btn-group > .btn,
3925 .input-group-btn:first-child > .dropdown-toggle,
3926 .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
3927 .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
3928 border-bottom-right-radius: 0;
3929 border-top-right-radius: 0;
3931 .input-group-addon:first-child {
3934 .input-group .form-control:last-child,
3935 .input-group-addon:last-child,
3936 .input-group-btn:last-child > .btn,
3937 .input-group-btn:last-child > .btn-group > .btn,
3938 .input-group-btn:last-child > .dropdown-toggle,
3939 .input-group-btn:first-child > .btn:not(:first-child),
3940 .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
3941 border-bottom-left-radius: 0;
3942 border-top-left-radius: 0;
3944 .input-group-addon:last-child {
3950 white-space: nowrap;
3952 .input-group-btn > .btn {
3955 .input-group-btn > .btn + .btn {
3958 .input-group-btn > .btn:hover,
3959 .input-group-btn > .btn:focus,
3960 .input-group-btn > .btn:active {
3963 .input-group-btn:first-child > .btn,
3964 .input-group-btn:first-child > .btn-group {
3967 .input-group-btn:last-child > .btn,
3968 .input-group-btn:last-child > .btn-group {
3986 .nav > li > a:hover,
3987 .nav > li > a:focus {
3988 text-decoration: none;
3989 background-color: #eeeeee;
3991 .nav > li.disabled > a {
3994 .nav > li.disabled > a:hover,
3995 .nav > li.disabled > a:focus {
3997 text-decoration: none;
3998 background-color: transparent;
3999 cursor: not-allowed;
4002 .nav .open > a:hover,
4003 .nav .open > a:focus {
4004 background-color: #eeeeee;
4005 border-color: #337ab7;
4011 background-color: #e5e5e5;
4013 .nav > li > a > img {
4017 border-bottom: 1px solid #ddd;
4021 margin-bottom: -1px;
4023 .nav-tabs > li > a {
4025 line-height: 1.42857143;
4026 border: 1px solid transparent;
4027 border-radius: 2px 2px 0 0;
4029 .nav-tabs > li > a:hover {
4030 border-color: #eeeeee #eeeeee #ddd;
4032 .nav-tabs > li.active > a,
4033 .nav-tabs > li.active > a:hover,
4034 .nav-tabs > li.active > a:focus {
4036 background-color: #fff;
4037 border: 1px solid #ddd;
4038 border-bottom-color: transparent;
4041 .nav-tabs.nav-justified {
4045 .nav-tabs.nav-justified > li {
4048 .nav-tabs.nav-justified > li > a {
4052 .nav-tabs.nav-justified > .dropdown .dropdown-menu {
4056 @media (min-width: 768px) {
4057 .nav-tabs.nav-justified > li {
4058 display: table-cell;
4061 .nav-tabs.nav-justified > li > a {
4065 .nav-tabs.nav-justified > li > a {
4069 .nav-tabs.nav-justified > .active > a,
4070 .nav-tabs.nav-justified > .active > a:hover,
4071 .nav-tabs.nav-justified > .active > a:focus {
4072 border: 1px solid #ddd;
4074 @media (min-width: 768px) {
4075 .nav-tabs.nav-justified > li > a {
4076 border-bottom: 1px solid #ddd;
4077 border-radius: 2px 2px 0 0;
4079 .nav-tabs.nav-justified > .active > a,
4080 .nav-tabs.nav-justified > .active > a:hover,
4081 .nav-tabs.nav-justified > .active > a:focus {
4082 border-bottom-color: #fff;
4088 .nav-pills > li > a {
4091 .nav-pills > li + li {
4094 .nav-pills > li.active > a,
4095 .nav-pills > li.active > a:hover,
4096 .nav-pills > li.active > a:focus {
4098 background-color: #337ab7;
4103 .nav-stacked > li + li {
4110 .nav-justified > li {
4113 .nav-justified > li > a {
4117 .nav-justified > .dropdown .dropdown-menu {
4121 @media (min-width: 768px) {
4122 .nav-justified > li {
4123 display: table-cell;
4126 .nav-justified > li > a {
4130 .nav-tabs-justified {
4133 .nav-tabs-justified > li > a {
4137 .nav-tabs-justified > .active > a,
4138 .nav-tabs-justified > .active > a:hover,
4139 .nav-tabs-justified > .active > a:focus {
4140 border: 1px solid #ddd;
4142 @media (min-width: 768px) {
4143 .nav-tabs-justified > li > a {
4144 border-bottom: 1px solid #ddd;
4145 border-radius: 2px 2px 0 0;
4147 .nav-tabs-justified > .active > a,
4148 .nav-tabs-justified > .active > a:hover,
4149 .nav-tabs-justified > .active > a:focus {
4150 border-bottom-color: #fff;
4153 .tab-content > .tab-pane {
4156 .tab-content > .active {
4159 .nav-tabs .dropdown-menu {
4161 border-top-right-radius: 0;
4162 border-top-left-radius: 0;
4167 margin-bottom: 18px;
4168 border: 1px solid transparent;
4170 @media (min-width: 541px) {
4175 @media (min-width: 541px) {
4181 overflow-x: visible;
4184 border-top: 1px solid transparent;
4185 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
4186 -webkit-overflow-scrolling: touch;
4188 .navbar-collapse.in {
4191 @media (min-width: 541px) {
4197 .navbar-collapse.collapse {
4198 display: block !important;
4199 height: auto !important;
4201 overflow: visible !important;
4203 .navbar-collapse.in {
4204 overflow-y: visible;
4206 .navbar-fixed-top .navbar-collapse,
4207 .navbar-static-top .navbar-collapse,
4208 .navbar-fixed-bottom .navbar-collapse {
4213 .navbar-fixed-top .navbar-collapse,
4214 .navbar-fixed-bottom .navbar-collapse {
4217 @media (max-device-width: 540px) and (orientation: landscape) {
4218 .navbar-fixed-top .navbar-collapse,
4219 .navbar-fixed-bottom .navbar-collapse {
4223 .container > .navbar-header,
4224 .container-fluid > .navbar-header,
4225 .container > .navbar-collapse,
4226 .container-fluid > .navbar-collapse {
4230 @media (min-width: 541px) {
4231 .container > .navbar-header,
4232 .container-fluid > .navbar-header,
4233 .container > .navbar-collapse,
4234 .container-fluid > .navbar-collapse {
4239 .navbar-static-top {
4241 border-width: 0 0 1px;
4243 @media (min-width: 541px) {
4244 .navbar-static-top {
4249 .navbar-fixed-bottom {
4255 @media (min-width: 541px) {
4257 .navbar-fixed-bottom {
4263 border-width: 0 0 1px;
4265 .navbar-fixed-bottom {
4268 border-width: 1px 0 0;
4277 .navbar-brand:hover,
4278 .navbar-brand:focus {
4279 text-decoration: none;
4281 .navbar-brand > img {
4284 @media (min-width: 541px) {
4285 .navbar > .container .navbar-brand,
4286 .navbar > .container-fluid .navbar-brand {
4296 margin-bottom: -2px;
4297 background-color: transparent;
4298 background-image: none;
4299 border: 1px solid transparent;
4302 .navbar-toggle:focus {
4305 .navbar-toggle .icon-bar {
4311 .navbar-toggle .icon-bar + .icon-bar {
4314 @media (min-width: 541px) {
4322 .navbar-nav > li > a {
4324 padding-bottom: 10px;
4327 @media (max-width: 540px) {
4328 .navbar-nav .open .dropdown-menu {
4333 background-color: transparent;
4337 .navbar-nav .open .dropdown-menu > li > a,
4338 .navbar-nav .open .dropdown-menu .dropdown-header {
4339 padding: 5px 15px 5px 25px;
4341 .navbar-nav .open .dropdown-menu > li > a {
4344 .navbar-nav .open .dropdown-menu > li > a:hover,
4345 .navbar-nav .open .dropdown-menu > li > a:focus {
4346 background-image: none;
4349 @media (min-width: 541px) {
4357 .navbar-nav > li > a {
4359 padding-bottom: 6px;
4366 border-top: 1px solid transparent;
4367 border-bottom: 1px solid transparent;
4368 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
4369 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
4371 margin-bottom: -1px;
4373 @media (min-width: 768px) {
4374 .navbar-form .form-group {
4375 display: inline-block;
4377 vertical-align: middle;
4379 .navbar-form .form-control {
4380 display: inline-block;
4382 vertical-align: middle;
4384 .navbar-form .form-control-static {
4385 display: inline-block;
4387 .navbar-form .input-group {
4388 display: inline-table;
4389 vertical-align: middle;
4391 .navbar-form .input-group .input-group-addon,
4392 .navbar-form .input-group .input-group-btn,
4393 .navbar-form .input-group .form-control {
4396 .navbar-form .input-group > .form-control {
4399 .navbar-form .control-label {
4401 vertical-align: middle;
4403 .navbar-form .radio,
4404 .navbar-form .checkbox {
4405 display: inline-block;
4408 vertical-align: middle;
4410 .navbar-form .radio label,
4411 .navbar-form .checkbox label {
4414 .navbar-form .radio input[type="radio"],
4415 .navbar-form .checkbox input[type="checkbox"] {
4419 .navbar-form .has-feedback .form-control-feedback {
4423 @media (max-width: 540px) {
4424 .navbar-form .form-group {
4427 .navbar-form .form-group:last-child {
4431 @media (min-width: 541px) {
4439 -webkit-box-shadow: none;
4443 .navbar-nav > li > .dropdown-menu {
4445 border-top-right-radius: 0;
4446 border-top-left-radius: 0;
4448 .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
4450 border-top-right-radius: 2px;
4451 border-top-left-radius: 2px;
4452 border-bottom-right-radius: 0;
4453 border-bottom-left-radius: 0;
4457 margin-bottom: -1px;
4459 .navbar-btn.btn-sm {
4463 .navbar-btn.btn-xs {
4471 @media (min-width: 541px) {
4478 @media (min-width: 541px) {
4480 float: left !important;
4484 float: right !important;
4488 .navbar-right ~ .navbar-right {
4493 background-color: #f8f8f8;
4494 border-color: #e7e7e7;
4496 .navbar-default .navbar-brand {
4499 .navbar-default .navbar-brand:hover,
4500 .navbar-default .navbar-brand:focus {
4502 background-color: transparent;
4504 .navbar-default .navbar-text {
4507 .navbar-default .navbar-nav > li > a {
4510 .navbar-default .navbar-nav > li > a:hover,
4511 .navbar-default .navbar-nav > li > a:focus {
4513 background-color: transparent;
4515 .navbar-default .navbar-nav > .active > a,
4516 .navbar-default .navbar-nav > .active > a:hover,
4517 .navbar-default .navbar-nav > .active > a:focus {
4519 background-color: #e7e7e7;
4521 .navbar-default .navbar-nav > .disabled > a,
4522 .navbar-default .navbar-nav > .disabled > a:hover,
4523 .navbar-default .navbar-nav > .disabled > a:focus {
4525 background-color: transparent;
4527 .navbar-default .navbar-toggle {
4530 .navbar-default .navbar-toggle:hover,
4531 .navbar-default .navbar-toggle:focus {
4532 background-color: #ddd;
4534 .navbar-default .navbar-toggle .icon-bar {
4535 background-color: #888;
4537 .navbar-default .navbar-collapse,
4538 .navbar-default .navbar-form {
4539 border-color: #e7e7e7;
4541 .navbar-default .navbar-nav > .open > a,
4542 .navbar-default .navbar-nav > .open > a:hover,
4543 .navbar-default .navbar-nav > .open > a:focus {
4544 background-color: #e7e7e7;
4547 @media (max-width: 540px) {
4548 .navbar-default .navbar-nav .open .dropdown-menu > li > a {
4551 .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
4552 .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
4554 background-color: transparent;
4556 .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
4557 .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
4558 .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
4560 background-color: #e7e7e7;
4562 .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
4563 .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
4564 .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
4566 background-color: transparent;
4569 .navbar-default .navbar-link {
4572 .navbar-default .navbar-link:hover {
4575 .navbar-default .btn-link {
4578 .navbar-default .btn-link:hover,
4579 .navbar-default .btn-link:focus {
4582 .navbar-default .btn-link[disabled]:hover,
4583 fieldset[disabled] .navbar-default .btn-link:hover,
4584 .navbar-default .btn-link[disabled]:focus,
4585 fieldset[disabled] .navbar-default .btn-link:focus {
4589 background-color: #222;
4590 border-color: #080808;
4592 .navbar-inverse .navbar-brand {
4595 .navbar-inverse .navbar-brand:hover,
4596 .navbar-inverse .navbar-brand:focus {
4598 background-color: transparent;
4600 .navbar-inverse .navbar-text {
4603 .navbar-inverse .navbar-nav > li > a {
4606 .navbar-inverse .navbar-nav > li > a:hover,
4607 .navbar-inverse .navbar-nav > li > a:focus {
4609 background-color: transparent;
4611 .navbar-inverse .navbar-nav > .active > a,
4612 .navbar-inverse .navbar-nav > .active > a:hover,
4613 .navbar-inverse .navbar-nav > .active > a:focus {
4615 background-color: #080808;
4617 .navbar-inverse .navbar-nav > .disabled > a,
4618 .navbar-inverse .navbar-nav > .disabled > a:hover,
4619 .navbar-inverse .navbar-nav > .disabled > a:focus {
4621 background-color: transparent;
4623 .navbar-inverse .navbar-toggle {
4626 .navbar-inverse .navbar-toggle:hover,
4627 .navbar-inverse .navbar-toggle:focus {
4628 background-color: #333;
4630 .navbar-inverse .navbar-toggle .icon-bar {
4631 background-color: #fff;
4633 .navbar-inverse .navbar-collapse,
4634 .navbar-inverse .navbar-form {
4635 border-color: #101010;
4637 .navbar-inverse .navbar-nav > .open > a,
4638 .navbar-inverse .navbar-nav > .open > a:hover,
4639 .navbar-inverse .navbar-nav > .open > a:focus {
4640 background-color: #080808;
4643 @media (max-width: 540px) {
4644 .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
4645 border-color: #080808;
4647 .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
4648 background-color: #080808;
4650 .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
4653 .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
4654 .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
4656 background-color: transparent;
4658 .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
4659 .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
4660 .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
4662 background-color: #080808;
4664 .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
4665 .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
4666 .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
4668 background-color: transparent;
4671 .navbar-inverse .navbar-link {
4674 .navbar-inverse .navbar-link:hover {
4677 .navbar-inverse .btn-link {
4680 .navbar-inverse .btn-link:hover,
4681 .navbar-inverse .btn-link:focus {
4684 .navbar-inverse .btn-link[disabled]:hover,
4685 fieldset[disabled] .navbar-inverse .btn-link:hover,
4686 .navbar-inverse .btn-link[disabled]:focus,
4687 fieldset[disabled] .navbar-inverse .btn-link:focus {
4692 margin-bottom: 18px;
4694 background-color: #f5f5f5;
4698 display: inline-block;
4700 .breadcrumb > li + li:before {
4705 .breadcrumb > .active {
4709 display: inline-block;
4717 .pagination > li > a,
4718 .pagination > li > span {
4722 line-height: 1.42857143;
4723 text-decoration: none;
4725 background-color: #fff;
4726 border: 1px solid #ddd;
4729 .pagination > li:first-child > a,
4730 .pagination > li:first-child > span {
4732 border-bottom-left-radius: 2px;
4733 border-top-left-radius: 2px;
4735 .pagination > li:last-child > a,
4736 .pagination > li:last-child > span {
4737 border-bottom-right-radius: 2px;
4738 border-top-right-radius: 2px;
4740 .pagination > li > a:hover,
4741 .pagination > li > span:hover,
4742 .pagination > li > a:focus,
4743 .pagination > li > span:focus {
4746 background-color: #eeeeee;
4749 .pagination > .active > a,
4750 .pagination > .active > span,
4751 .pagination > .active > a:hover,
4752 .pagination > .active > span:hover,
4753 .pagination > .active > a:focus,
4754 .pagination > .active > span:focus {
4757 background-color: #337ab7;
4758 border-color: #337ab7;
4761 .pagination > .disabled > span,
4762 .pagination > .disabled > span:hover,
4763 .pagination > .disabled > span:focus,
4764 .pagination > .disabled > a,
4765 .pagination > .disabled > a:hover,
4766 .pagination > .disabled > a:focus {
4768 background-color: #fff;
4770 cursor: not-allowed;
4772 .pagination-lg > li > a,
4773 .pagination-lg > li > span {
4776 line-height: 1.3333333;
4778 .pagination-lg > li:first-child > a,
4779 .pagination-lg > li:first-child > span {
4780 border-bottom-left-radius: 3px;
4781 border-top-left-radius: 3px;
4783 .pagination-lg > li:last-child > a,
4784 .pagination-lg > li:last-child > span {
4785 border-bottom-right-radius: 3px;
4786 border-top-right-radius: 3px;
4788 .pagination-sm > li > a,
4789 .pagination-sm > li > span {
4794 .pagination-sm > li:first-child > a,
4795 .pagination-sm > li:first-child > span {
4796 border-bottom-left-radius: 1px;
4797 border-top-left-radius: 1px;
4799 .pagination-sm > li:last-child > a,
4800 .pagination-sm > li:last-child > span {
4801 border-bottom-right-radius: 1px;
4802 border-top-right-radius: 1px;
4815 display: inline-block;
4817 background-color: #fff;
4818 border: 1px solid #ddd;
4819 border-radius: 15px;
4821 .pager li > a:hover,
4822 .pager li > a:focus {
4823 text-decoration: none;
4824 background-color: #eeeeee;
4827 .pager .next > span {
4830 .pager .previous > a,
4831 .pager .previous > span {
4834 .pager .disabled > a,
4835 .pager .disabled > a:hover,
4836 .pager .disabled > a:focus,
4837 .pager .disabled > span {
4839 background-color: #fff;
4840 cursor: not-allowed;
4844 padding: .2em .6em .3em;
4850 white-space: nowrap;
4851 vertical-align: baseline;
4852 border-radius: .25em;
4857 text-decoration: none;
4868 background-color: #777777;
4870 .label-default[href]:hover,
4871 .label-default[href]:focus {
4872 background-color: #5e5e5e;
4875 background-color: #337ab7;
4877 .label-primary[href]:hover,
4878 .label-primary[href]:focus {
4879 background-color: #286090;
4882 background-color: #5cb85c;
4884 .label-success[href]:hover,
4885 .label-success[href]:focus {
4886 background-color: #449d44;
4889 background-color: #5bc0de;
4891 .label-info[href]:hover,
4892 .label-info[href]:focus {
4893 background-color: #31b0d5;
4896 background-color: #f0ad4e;
4898 .label-warning[href]:hover,
4899 .label-warning[href]:focus {
4900 background-color: #ec971f;
4903 background-color: #d9534f;
4905 .label-danger[href]:hover,
4906 .label-danger[href]:focus {
4907 background-color: #c9302c;
4910 display: inline-block;
4917 vertical-align: middle;
4918 white-space: nowrap;
4920 background-color: #777777;
4921 border-radius: 10px;
4931 .btn-group-xs > .btn .badge {
4938 text-decoration: none;
4941 .list-group-item.active > .badge,
4942 .nav-pills > .active > a > .badge {
4944 background-color: #fff;
4946 .list-group-item > .badge {
4949 .list-group-item > .badge + .badge {
4952 .nav-pills > li > a > .badge {
4957 padding-bottom: 30px;
4958 margin-bottom: 30px;
4960 background-color: #eeeeee;
4967 margin-bottom: 15px;
4972 border-top-color: #d5d5d5;
4974 .container .jumbotron,
4975 .container-fluid .jumbotron {
4980 .jumbotron .container {
4983 @media screen and (min-width: 768px) {
4986 padding-bottom: 48px;
4988 .container .jumbotron,
4989 .container-fluid .jumbotron {
4991 padding-right: 60px;
5001 margin-bottom: 18px;
5002 line-height: 1.42857143;
5003 background-color: #fff;
5004 border: 1px solid #ddd;
5006 -webkit-transition: border 0.2s ease-in-out;
5007 -o-transition: border 0.2s ease-in-out;
5008 transition: border 0.2s ease-in-out;
5011 .thumbnail a > img {
5017 a.thumbnail.active {
5018 border-color: #337ab7;
5020 .thumbnail .caption {
5026 margin-bottom: 18px;
5027 border: 1px solid transparent;
5034 .alert .alert-link {
5045 .alert-dismissible {
5046 padding-right: 35px;
5048 .alert-dismissable .close,
5049 .alert-dismissible .close {
5056 background-color: #dff0d8;
5057 border-color: #d6e9c6;
5061 border-top-color: #c9e2b3;
5063 .alert-success .alert-link {
5067 background-color: #d9edf7;
5068 border-color: #bce8f1;
5072 border-top-color: #a6e1ec;
5074 .alert-info .alert-link {
5078 background-color: #fcf8e3;
5079 border-color: #faebcc;
5083 border-top-color: #f7e1b5;
5085 .alert-warning .alert-link {
5089 background-color: #f2dede;
5090 border-color: #ebccd1;
5094 border-top-color: #e4b9c0;
5096 .alert-danger .alert-link {
5099 @-webkit-keyframes progress-bar-stripes {
5101 background-position: 40px 0;
5104 background-position: 0 0;
5107 @keyframes progress-bar-stripes {
5109 background-position: 40px 0;
5112 background-position: 0 0;
5118 margin-bottom: 18px;
5119 background-color: #f5f5f5;
5121 -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
5122 box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
5132 background-color: #337ab7;
5133 -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
5134 box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
5135 -webkit-transition: width 0.6s ease;
5136 -o-transition: width 0.6s ease;
5137 transition: width 0.6s ease;
5139 .progress-striped .progress-bar,
5140 .progress-bar-striped {
5141 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);
5142 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);
5143 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);
5144 background-size: 40px 40px;
5146 .progress.active .progress-bar,
5147 .progress-bar.active {
5148 -webkit-animation: progress-bar-stripes 2s linear infinite;
5149 -o-animation: progress-bar-stripes 2s linear infinite;
5150 animation: progress-bar-stripes 2s linear infinite;
5152 .progress-bar-success {
5153 background-color: #5cb85c;
5155 .progress-striped .progress-bar-success {
5156 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);
5157 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);
5158 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);
5160 .progress-bar-info {
5161 background-color: #5bc0de;
5163 .progress-striped .progress-bar-info {
5164 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);
5165 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);
5166 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);
5168 .progress-bar-warning {
5169 background-color: #f0ad4e;
5171 .progress-striped .progress-bar-warning {
5172 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);
5173 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);
5174 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);
5176 .progress-bar-danger {
5177 background-color: #d9534f;
5179 .progress-striped .progress-bar-danger {
5180 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);
5181 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);
5182 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);
5187 .media:first-child {
5201 .media-object.img-thumbnail {
5205 .media > .pull-right {
5209 .media > .pull-left {
5210 padding-right: 10px;
5215 display: table-cell;
5216 vertical-align: top;
5219 vertical-align: middle;
5222 vertical-align: bottom;
5233 margin-bottom: 20px;
5240 margin-bottom: -1px;
5241 background-color: #fff;
5242 border: 1px solid #ddd;
5244 .list-group-item:first-child {
5245 border-top-right-radius: 2px;
5246 border-top-left-radius: 2px;
5248 .list-group-item:last-child {
5250 border-bottom-right-radius: 2px;
5251 border-bottom-left-radius: 2px;
5254 button.list-group-item {
5257 a.list-group-item .list-group-item-heading,
5258 button.list-group-item .list-group-item-heading {
5261 a.list-group-item:hover,
5262 button.list-group-item:hover,
5263 a.list-group-item:focus,
5264 button.list-group-item:focus {
5265 text-decoration: none;
5267 background-color: #f5f5f5;
5269 button.list-group-item {
5273 .list-group-item.disabled,
5274 .list-group-item.disabled:hover,
5275 .list-group-item.disabled:focus {
5276 background-color: #eeeeee;
5278 cursor: not-allowed;
5280 .list-group-item.disabled .list-group-item-heading,
5281 .list-group-item.disabled:hover .list-group-item-heading,
5282 .list-group-item.disabled:focus .list-group-item-heading {
5285 .list-group-item.disabled .list-group-item-text,
5286 .list-group-item.disabled:hover .list-group-item-text,
5287 .list-group-item.disabled:focus .list-group-item-text {
5290 .list-group-item.active,
5291 .list-group-item.active:hover,
5292 .list-group-item.active:focus {
5295 background-color: #337ab7;
5296 border-color: #337ab7;
5298 .list-group-item.active .list-group-item-heading,
5299 .list-group-item.active:hover .list-group-item-heading,
5300 .list-group-item.active:focus .list-group-item-heading,
5301 .list-group-item.active .list-group-item-heading > small,
5302 .list-group-item.active:hover .list-group-item-heading > small,
5303 .list-group-item.active:focus .list-group-item-heading > small,
5304 .list-group-item.active .list-group-item-heading > .small,
5305 .list-group-item.active:hover .list-group-item-heading > .small,
5306 .list-group-item.active:focus .list-group-item-heading > .small {
5309 .list-group-item.active .list-group-item-text,
5310 .list-group-item.active:hover .list-group-item-text,
5311 .list-group-item.active:focus .list-group-item-text {
5314 .list-group-item-success {
5316 background-color: #dff0d8;
5318 a.list-group-item-success,
5319 button.list-group-item-success {
5322 a.list-group-item-success .list-group-item-heading,
5323 button.list-group-item-success .list-group-item-heading {
5326 a.list-group-item-success:hover,
5327 button.list-group-item-success:hover,
5328 a.list-group-item-success:focus,
5329 button.list-group-item-success:focus {
5331 background-color: #d0e9c6;
5333 a.list-group-item-success.active,
5334 button.list-group-item-success.active,
5335 a.list-group-item-success.active:hover,
5336 button.list-group-item-success.active:hover,
5337 a.list-group-item-success.active:focus,
5338 button.list-group-item-success.active:focus {
5340 background-color: #3c763d;
5341 border-color: #3c763d;
5343 .list-group-item-info {
5345 background-color: #d9edf7;
5347 a.list-group-item-info,
5348 button.list-group-item-info {
5351 a.list-group-item-info .list-group-item-heading,
5352 button.list-group-item-info .list-group-item-heading {
5355 a.list-group-item-info:hover,
5356 button.list-group-item-info:hover,
5357 a.list-group-item-info:focus,
5358 button.list-group-item-info:focus {
5360 background-color: #c4e3f3;
5362 a.list-group-item-info.active,
5363 button.list-group-item-info.active,
5364 a.list-group-item-info.active:hover,
5365 button.list-group-item-info.active:hover,
5366 a.list-group-item-info.active:focus,
5367 button.list-group-item-info.active:focus {
5369 background-color: #31708f;
5370 border-color: #31708f;
5372 .list-group-item-warning {
5374 background-color: #fcf8e3;
5376 a.list-group-item-warning,
5377 button.list-group-item-warning {
5380 a.list-group-item-warning .list-group-item-heading,
5381 button.list-group-item-warning .list-group-item-heading {
5384 a.list-group-item-warning:hover,
5385 button.list-group-item-warning:hover,
5386 a.list-group-item-warning:focus,
5387 button.list-group-item-warning:focus {
5389 background-color: #faf2cc;
5391 a.list-group-item-warning.active,
5392 button.list-group-item-warning.active,
5393 a.list-group-item-warning.active:hover,
5394 button.list-group-item-warning.active:hover,
5395 a.list-group-item-warning.active:focus,
5396 button.list-group-item-warning.active:focus {
5398 background-color: #8a6d3b;
5399 border-color: #8a6d3b;
5401 .list-group-item-danger {
5403 background-color: #f2dede;
5405 a.list-group-item-danger,
5406 button.list-group-item-danger {
5409 a.list-group-item-danger .list-group-item-heading,
5410 button.list-group-item-danger .list-group-item-heading {
5413 a.list-group-item-danger:hover,
5414 button.list-group-item-danger:hover,
5415 a.list-group-item-danger:focus,
5416 button.list-group-item-danger:focus {
5418 background-color: #ebcccc;
5420 a.list-group-item-danger.active,
5421 button.list-group-item-danger.active,
5422 a.list-group-item-danger.active:hover,
5423 button.list-group-item-danger.active:hover,
5424 a.list-group-item-danger.active:focus,
5425 button.list-group-item-danger.active:focus {
5427 background-color: #a94442;
5428 border-color: #a94442;
5430 .list-group-item-heading {
5434 .list-group-item-text {
5439 margin-bottom: 18px;
5440 background-color: #fff;
5441 border: 1px solid transparent;
5443 -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
5444 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
5451 border-bottom: 1px solid transparent;
5452 border-top-right-radius: 1px;
5453 border-top-left-radius: 1px;
5455 .panel-heading > .dropdown .dropdown-toggle {
5465 .panel-title > small,
5466 .panel-title > .small,
5467 .panel-title > small > a,
5468 .panel-title > .small > a {
5473 background-color: #f5f5f5;
5474 border-top: 1px solid #ddd;
5475 border-bottom-right-radius: 1px;
5476 border-bottom-left-radius: 1px;
5478 .panel > .list-group,
5479 .panel > .panel-collapse > .list-group {
5482 .panel > .list-group .list-group-item,
5483 .panel > .panel-collapse > .list-group .list-group-item {
5484 border-width: 1px 0;
5487 .panel > .list-group:first-child .list-group-item:first-child,
5488 .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
5490 border-top-right-radius: 1px;
5491 border-top-left-radius: 1px;
5493 .panel > .list-group:last-child .list-group-item:last-child,
5494 .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
5496 border-bottom-right-radius: 1px;
5497 border-bottom-left-radius: 1px;
5499 .panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
5500 border-top-right-radius: 0;
5501 border-top-left-radius: 0;
5503 .panel-heading + .list-group .list-group-item:first-child {
5504 border-top-width: 0;
5506 .list-group + .panel-footer {
5507 border-top-width: 0;
5510 .panel > .table-responsive > .table,
5511 .panel > .panel-collapse > .table {
5514 .panel > .table caption,
5515 .panel > .table-responsive > .table caption,
5516 .panel > .panel-collapse > .table caption {
5518 padding-right: 15px;
5520 .panel > .table:first-child,
5521 .panel > .table-responsive:first-child > .table:first-child {
5522 border-top-right-radius: 1px;
5523 border-top-left-radius: 1px;
5525 .panel > .table:first-child > thead:first-child > tr:first-child,
5526 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
5527 .panel > .table:first-child > tbody:first-child > tr:first-child,
5528 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
5529 border-top-left-radius: 1px;
5530 border-top-right-radius: 1px;
5532 .panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
5533 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
5534 .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
5535 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
5536 .panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
5537 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
5538 .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
5539 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
5540 border-top-left-radius: 1px;
5542 .panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
5543 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
5544 .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
5545 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
5546 .panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
5547 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
5548 .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
5549 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
5550 border-top-right-radius: 1px;
5552 .panel > .table:last-child,
5553 .panel > .table-responsive:last-child > .table:last-child {
5554 border-bottom-right-radius: 1px;
5555 border-bottom-left-radius: 1px;
5557 .panel > .table:last-child > tbody:last-child > tr:last-child,
5558 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
5559 .panel > .table:last-child > tfoot:last-child > tr:last-child,
5560 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
5561 border-bottom-left-radius: 1px;
5562 border-bottom-right-radius: 1px;
5564 .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
5565 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
5566 .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
5567 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
5568 .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
5569 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
5570 .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
5571 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
5572 border-bottom-left-radius: 1px;
5574 .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
5575 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
5576 .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
5577 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
5578 .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
5579 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
5580 .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
5581 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
5582 border-bottom-right-radius: 1px;
5584 .panel > .panel-body + .table,
5585 .panel > .panel-body + .table-responsive,
5586 .panel > .table + .panel-body,
5587 .panel > .table-responsive + .panel-body {
5588 border-top: 1px solid #ddd;
5590 .panel > .table > tbody:first-child > tr:first-child th,
5591 .panel > .table > tbody:first-child > tr:first-child td {
5594 .panel > .table-bordered,
5595 .panel > .table-responsive > .table-bordered {
5598 .panel > .table-bordered > thead > tr > th:first-child,
5599 .panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
5600 .panel > .table-bordered > tbody > tr > th:first-child,
5601 .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
5602 .panel > .table-bordered > tfoot > tr > th:first-child,
5603 .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
5604 .panel > .table-bordered > thead > tr > td:first-child,
5605 .panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
5606 .panel > .table-bordered > tbody > tr > td:first-child,
5607 .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
5608 .panel > .table-bordered > tfoot > tr > td:first-child,
5609 .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
5612 .panel > .table-bordered > thead > tr > th:last-child,
5613 .panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
5614 .panel > .table-bordered > tbody > tr > th:last-child,
5615 .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
5616 .panel > .table-bordered > tfoot > tr > th:last-child,
5617 .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
5618 .panel > .table-bordered > thead > tr > td:last-child,
5619 .panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
5620 .panel > .table-bordered > tbody > tr > td:last-child,
5621 .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
5622 .panel > .table-bordered > tfoot > tr > td:last-child,
5623 .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
5626 .panel > .table-bordered > thead > tr:first-child > td,
5627 .panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
5628 .panel > .table-bordered > tbody > tr:first-child > td,
5629 .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
5630 .panel > .table-bordered > thead > tr:first-child > th,
5631 .panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
5632 .panel > .table-bordered > tbody > tr:first-child > th,
5633 .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
5636 .panel > .table-bordered > tbody > tr:last-child > td,
5637 .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
5638 .panel > .table-bordered > tfoot > tr:last-child > td,
5639 .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
5640 .panel > .table-bordered > tbody > tr:last-child > th,
5641 .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
5642 .panel > .table-bordered > tfoot > tr:last-child > th,
5643 .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
5646 .panel > .table-responsive {
5651 margin-bottom: 18px;
5653 .panel-group .panel {
5657 .panel-group .panel + .panel {
5660 .panel-group .panel-heading {
5663 .panel-group .panel-heading + .panel-collapse > .panel-body,
5664 .panel-group .panel-heading + .panel-collapse > .list-group {
5665 border-top: 1px solid #ddd;
5667 .panel-group .panel-footer {
5670 .panel-group .panel-footer + .panel-collapse .panel-body {
5671 border-bottom: 1px solid #ddd;
5676 .panel-default > .panel-heading {
5678 background-color: #f5f5f5;
5681 .panel-default > .panel-heading + .panel-collapse > .panel-body {
5682 border-top-color: #ddd;
5684 .panel-default > .panel-heading .badge {
5686 background-color: #333333;
5688 .panel-default > .panel-footer + .panel-collapse > .panel-body {
5689 border-bottom-color: #ddd;
5692 border-color: #337ab7;
5694 .panel-primary > .panel-heading {
5696 background-color: #337ab7;
5697 border-color: #337ab7;
5699 .panel-primary > .panel-heading + .panel-collapse > .panel-body {
5700 border-top-color: #337ab7;
5702 .panel-primary > .panel-heading .badge {
5704 background-color: #fff;
5706 .panel-primary > .panel-footer + .panel-collapse > .panel-body {
5707 border-bottom-color: #337ab7;
5710 border-color: #d6e9c6;
5712 .panel-success > .panel-heading {
5714 background-color: #dff0d8;
5715 border-color: #d6e9c6;
5717 .panel-success > .panel-heading + .panel-collapse > .panel-body {
5718 border-top-color: #d6e9c6;
5720 .panel-success > .panel-heading .badge {
5722 background-color: #3c763d;
5724 .panel-success > .panel-footer + .panel-collapse > .panel-body {
5725 border-bottom-color: #d6e9c6;
5728 border-color: #bce8f1;
5730 .panel-info > .panel-heading {
5732 background-color: #d9edf7;
5733 border-color: #bce8f1;
5735 .panel-info > .panel-heading + .panel-collapse > .panel-body {
5736 border-top-color: #bce8f1;
5738 .panel-info > .panel-heading .badge {
5740 background-color: #31708f;
5742 .panel-info > .panel-footer + .panel-collapse > .panel-body {
5743 border-bottom-color: #bce8f1;
5746 border-color: #faebcc;
5748 .panel-warning > .panel-heading {
5750 background-color: #fcf8e3;
5751 border-color: #faebcc;
5753 .panel-warning > .panel-heading + .panel-collapse > .panel-body {
5754 border-top-color: #faebcc;
5756 .panel-warning > .panel-heading .badge {
5758 background-color: #8a6d3b;
5760 .panel-warning > .panel-footer + .panel-collapse > .panel-body {
5761 border-bottom-color: #faebcc;
5764 border-color: #ebccd1;
5766 .panel-danger > .panel-heading {
5768 background-color: #f2dede;
5769 border-color: #ebccd1;
5771 .panel-danger > .panel-heading + .panel-collapse > .panel-body {
5772 border-top-color: #ebccd1;
5774 .panel-danger > .panel-heading .badge {
5776 background-color: #a94442;
5778 .panel-danger > .panel-footer + .panel-collapse > .panel-body {
5779 border-bottom-color: #ebccd1;
5788 .embed-responsive .embed-responsive-item,
5789 .embed-responsive iframe,
5790 .embed-responsive embed,
5791 .embed-responsive object,
5792 .embed-responsive video {
5801 .embed-responsive-16by9 {
5802 padding-bottom: 56.25%;
5804 .embed-responsive-4by3 {
5805 padding-bottom: 75%;
5810 margin-bottom: 20px;
5811 background-color: #f5f5f5;
5812 border: 1px solid #e3e3e3;
5814 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
5815 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
5819 border-color: rgba(0, 0, 0, 0.15);
5835 text-shadow: 0 1px 0 #fff;
5837 filter: alpha(opacity=20);
5842 text-decoration: none;
5845 filter: alpha(opacity=50);
5850 background: transparent;
5852 -webkit-appearance: none;
5866 -webkit-overflow-scrolling: touch;
5869 .modal.fade .modal-dialog {
5870 -webkit-transform: translate(0, -25%);
5871 -ms-transform: translate(0, -25%);
5872 -o-transform: translate(0, -25%);
5873 transform: translate(0, -25%);
5874 -webkit-transition: -webkit-transform 0.3s ease-out;
5875 -moz-transition: -moz-transform 0.3s ease-out;
5876 -o-transition: -o-transform 0.3s ease-out;
5877 transition: transform 0.3s ease-out;
5879 .modal.in .modal-dialog {
5880 -webkit-transform: translate(0, 0);
5881 -ms-transform: translate(0, 0);
5882 -o-transform: translate(0, 0);
5883 transform: translate(0, 0);
5885 .modal-open .modal {
5896 background-color: #fff;
5897 border: 1px solid #999;
5898 border: 1px solid rgba(0, 0, 0, 0.2);
5900 -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
5901 box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
5902 background-clip: padding-box;
5912 background-color: #000;
5914 .modal-backdrop.fade {
5916 filter: alpha(opacity=0);
5918 .modal-backdrop.in {
5920 filter: alpha(opacity=50);
5924 border-bottom: 1px solid #e5e5e5;
5926 .modal-header .close {
5931 line-height: 1.42857143;
5940 border-top: 1px solid #e5e5e5;
5942 .modal-footer .btn + .btn {
5946 .modal-footer .btn-group .btn + .btn {
5949 .modal-footer .btn-block + .btn-block {
5952 .modal-scrollbar-measure {
5959 @media (min-width: 768px) {
5965 -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
5966 box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
5972 @media (min-width: 992px) {
5981 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
5983 font-weight: normal;
5984 letter-spacing: normal;
5986 line-height: 1.42857143;
5989 text-decoration: none;
5991 text-transform: none;
5992 white-space: normal;
5994 word-spacing: normal;
5998 filter: alpha(opacity=0);
6002 filter: alpha(opacity=90);
6025 background-color: #000;
6032 border-color: transparent;
6033 border-style: solid;
6035 .tooltip.top .tooltip-arrow {
6039 border-width: 5px 5px 0;
6040 border-top-color: #000;
6042 .tooltip.top-left .tooltip-arrow {
6045 margin-bottom: -5px;
6046 border-width: 5px 5px 0;
6047 border-top-color: #000;
6049 .tooltip.top-right .tooltip-arrow {
6052 margin-bottom: -5px;
6053 border-width: 5px 5px 0;
6054 border-top-color: #000;
6056 .tooltip.right .tooltip-arrow {
6060 border-width: 5px 5px 5px 0;
6061 border-right-color: #000;
6063 .tooltip.left .tooltip-arrow {
6067 border-width: 5px 0 5px 5px;
6068 border-left-color: #000;
6070 .tooltip.bottom .tooltip-arrow {
6074 border-width: 0 5px 5px;
6075 border-bottom-color: #000;
6077 .tooltip.bottom-left .tooltip-arrow {
6081 border-width: 0 5px 5px;
6082 border-bottom-color: #000;
6084 .tooltip.bottom-right .tooltip-arrow {
6088 border-width: 0 5px 5px;
6089 border-bottom-color: #000;
6099 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
6101 font-weight: normal;
6102 letter-spacing: normal;
6104 line-height: 1.42857143;
6107 text-decoration: none;
6109 text-transform: none;
6110 white-space: normal;
6112 word-spacing: normal;
6115 background-color: #fff;
6116 background-clip: padding-box;
6117 border: 1px solid #ccc;
6118 border: 1px solid rgba(0, 0, 0, 0.2);
6120 -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
6121 box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
6139 background-color: #f7f7f7;
6140 border-bottom: 1px solid #ebebeb;
6141 border-radius: 2px 2px 0 0;
6147 .popover > .arrow:after {
6152 border-color: transparent;
6153 border-style: solid;
6158 .popover > .arrow:after {
6162 .popover.top > .arrow {
6165 border-bottom-width: 0;
6166 border-top-color: #999999;
6167 border-top-color: rgba(0, 0, 0, 0.25);
6170 .popover.top > .arrow:after {
6174 border-bottom-width: 0;
6175 border-top-color: #fff;
6177 .popover.right > .arrow {
6181 border-left-width: 0;
6182 border-right-color: #999999;
6183 border-right-color: rgba(0, 0, 0, 0.25);
6185 .popover.right > .arrow:after {
6189 border-left-width: 0;
6190 border-right-color: #fff;
6192 .popover.bottom > .arrow {
6195 border-top-width: 0;
6196 border-bottom-color: #999999;
6197 border-bottom-color: rgba(0, 0, 0, 0.25);
6200 .popover.bottom > .arrow:after {
6204 border-top-width: 0;
6205 border-bottom-color: #fff;
6207 .popover.left > .arrow {
6211 border-right-width: 0;
6212 border-left-color: #999999;
6213 border-left-color: rgba(0, 0, 0, 0.25);
6215 .popover.left > .arrow:after {
6218 border-right-width: 0;
6219 border-left-color: #fff;
6230 .carousel-inner > .item {
6233 -webkit-transition: 0.6s ease-in-out left;
6234 -o-transition: 0.6s ease-in-out left;
6235 transition: 0.6s ease-in-out left;
6237 .carousel-inner > .item > img,
6238 .carousel-inner > .item > a > img {
6241 @media all and (transform-3d), (-webkit-transform-3d) {
6242 .carousel-inner > .item {
6243 -webkit-transition: -webkit-transform 0.6s ease-in-out;
6244 -moz-transition: -moz-transform 0.6s ease-in-out;
6245 -o-transition: -o-transform 0.6s ease-in-out;
6246 transition: transform 0.6s ease-in-out;
6247 -webkit-backface-visibility: hidden;
6248 -moz-backface-visibility: hidden;
6249 backface-visibility: hidden;
6250 -webkit-perspective: 1000px;
6251 -moz-perspective: 1000px;
6252 perspective: 1000px;
6254 .carousel-inner > .item.next,
6255 .carousel-inner > .item.active.right {
6256 -webkit-transform: translate3d(100%, 0, 0);
6257 transform: translate3d(100%, 0, 0);
6260 .carousel-inner > .item.prev,
6261 .carousel-inner > .item.active.left {
6262 -webkit-transform: translate3d(-100%, 0, 0);
6263 transform: translate3d(-100%, 0, 0);
6266 .carousel-inner > .item.next.left,
6267 .carousel-inner > .item.prev.right,
6268 .carousel-inner > .item.active {
6269 -webkit-transform: translate3d(0, 0, 0);
6270 transform: translate3d(0, 0, 0);
6274 .carousel-inner > .active,
6275 .carousel-inner > .next,
6276 .carousel-inner > .prev {
6279 .carousel-inner > .active {
6282 .carousel-inner > .next,
6283 .carousel-inner > .prev {
6288 .carousel-inner > .next {
6291 .carousel-inner > .prev {
6294 .carousel-inner > .next.left,
6295 .carousel-inner > .prev.right {
6298 .carousel-inner > .active.left {
6301 .carousel-inner > .active.right {
6311 filter: alpha(opacity=50);
6315 text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
6316 background-color: rgba(0, 0, 0, 0);
6318 .carousel-control.left {
6319 background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6320 background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6321 background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6322 background-repeat: repeat-x;
6323 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
6325 .carousel-control.right {
6328 background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6329 background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6330 background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6331 background-repeat: repeat-x;
6332 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
6334 .carousel-control:hover,
6335 .carousel-control:focus {
6338 text-decoration: none;
6340 filter: alpha(opacity=90);
6342 .carousel-control .icon-prev,
6343 .carousel-control .icon-next,
6344 .carousel-control .glyphicon-chevron-left,
6345 .carousel-control .glyphicon-chevron-right {
6350 display: inline-block;
6352 .carousel-control .icon-prev,
6353 .carousel-control .glyphicon-chevron-left {
6357 .carousel-control .icon-next,
6358 .carousel-control .glyphicon-chevron-right {
6360 margin-right: -10px;
6362 .carousel-control .icon-prev,
6363 .carousel-control .icon-next {
6369 .carousel-control .icon-prev:before {
6372 .carousel-control .icon-next:before {
6375 .carousel-indicators {
6386 .carousel-indicators li {
6387 display: inline-block;
6391 text-indent: -999px;
6392 border: 1px solid #fff;
6393 border-radius: 10px;
6395 background-color: #000 \9;
6396 background-color: rgba(0, 0, 0, 0);
6398 .carousel-indicators .active {
6402 background-color: #fff;
6411 padding-bottom: 20px;
6414 text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
6416 .carousel-caption .btn {
6419 @media screen and (min-width: 768px) {
6420 .carousel-control .glyphicon-chevron-left,
6421 .carousel-control .glyphicon-chevron-right,
6422 .carousel-control .icon-prev,
6423 .carousel-control .icon-next {
6429 .carousel-control .glyphicon-chevron-left,
6430 .carousel-control .icon-prev {
6433 .carousel-control .glyphicon-chevron-right,
6434 .carousel-control .icon-next {
6435 margin-right: -10px;
6440 padding-bottom: 30px;
6442 .carousel-indicators {
6448 .dl-horizontal dd:before,
6449 .dl-horizontal dd:after,
6452 .container-fluid:before,
6453 .container-fluid:after,
6456 .form-horizontal .form-group:before,
6457 .form-horizontal .form-group:after,
6458 .btn-toolbar:before,
6460 .btn-group-vertical > .btn-group:before,
6461 .btn-group-vertical > .btn-group:after,
6466 .navbar-header:before,
6467 .navbar-header:after,
6468 .navbar-collapse:before,
6469 .navbar-collapse:after,
6474 .modal-header:before,
6475 .modal-header:after,
6476 .modal-footer:before,
6477 .modal-footer:after,
6478 .item_buttons:before,
6479 .item_buttons:after {
6484 .dl-horizontal dd:after,
6486 .container-fluid:after,
6488 .form-horizontal .form-group:after,
6490 .btn-group-vertical > .btn-group:after,
6493 .navbar-header:after,
6494 .navbar-collapse:after,
6497 .modal-header:after,
6498 .modal-footer:after,
6499 .item_buttons:after {
6508 float: right !important;
6511 float: left !important;
6514 display: none !important;
6517 display: block !important;
6526 background-color: transparent;
6530 display: none !important;
6536 width: device-width;
6542 display: none !important;
6546 .visible-xs-inline-block,
6549 .visible-sm-inline-block,
6552 .visible-md-inline-block,
6555 .visible-lg-inline-block {
6556 display: none !important;
6558 @media (max-width: 767px) {
6560 display: block !important;
6563 display: table !important;
6566 display: table-row !important;
6570 display: table-cell !important;
6573 @media (max-width: 767px) {
6575 display: block !important;
6578 @media (max-width: 767px) {
6579 .visible-xs-inline {
6580 display: inline !important;
6583 @media (max-width: 767px) {
6584 .visible-xs-inline-block {
6585 display: inline-block !important;
6588 @media (min-width: 768px) and (max-width: 991px) {
6590 display: block !important;
6593 display: table !important;
6596 display: table-row !important;
6600 display: table-cell !important;
6603 @media (min-width: 768px) and (max-width: 991px) {
6605 display: block !important;
6608 @media (min-width: 768px) and (max-width: 991px) {
6609 .visible-sm-inline {
6610 display: inline !important;
6613 @media (min-width: 768px) and (max-width: 991px) {
6614 .visible-sm-inline-block {
6615 display: inline-block !important;
6618 @media (min-width: 992px) and (max-width: 1199px) {
6620 display: block !important;
6623 display: table !important;
6626 display: table-row !important;
6630 display: table-cell !important;
6633 @media (min-width: 992px) and (max-width: 1199px) {
6635 display: block !important;
6638 @media (min-width: 992px) and (max-width: 1199px) {
6639 .visible-md-inline {
6640 display: inline !important;
6643 @media (min-width: 992px) and (max-width: 1199px) {
6644 .visible-md-inline-block {
6645 display: inline-block !important;
6648 @media (min-width: 1200px) {
6650 display: block !important;
6653 display: table !important;
6656 display: table-row !important;
6660 display: table-cell !important;
6663 @media (min-width: 1200px) {
6665 display: block !important;
6668 @media (min-width: 1200px) {
6669 .visible-lg-inline {
6670 display: inline !important;
6673 @media (min-width: 1200px) {
6674 .visible-lg-inline-block {
6675 display: inline-block !important;
6678 @media (max-width: 767px) {
6680 display: none !important;
6683 @media (min-width: 768px) and (max-width: 991px) {
6685 display: none !important;
6688 @media (min-width: 992px) and (max-width: 1199px) {
6690 display: none !important;
6693 @media (min-width: 1200px) {
6695 display: none !important;
6699 display: none !important;
6703 display: block !important;
6705 table.visible-print {
6706 display: table !important;
6709 display: table-row !important;
6713 display: table-cell !important;
6716 .visible-print-block {
6717 display: none !important;
6720 .visible-print-block {
6721 display: block !important;
6724 .visible-print-inline {
6725 display: none !important;
6728 .visible-print-inline {
6729 display: inline !important;
6732 .visible-print-inline-block {
6733 display: none !important;
6736 .visible-print-inline-block {
6737 display: inline-block !important;
6742 display: none !important;
6751 * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
6752 * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
6755 * -------------------------- */
6757 font-family: 'FontAwesome';
6758 src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?v=4.7.0');
6759 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');
6760 font-weight: normal;
6764 display: inline-block;
6765 font: normal normal normal 14px/1 FontAwesome;
6767 text-rendering: auto;
6768 -webkit-font-smoothing: antialiased;
6769 -moz-osx-font-smoothing: grayscale;
6771 /* makes the font 33% larger relative to the icon container */
6773 font-size: 1.33333333em;
6774 line-height: 0.75em;
6775 vertical-align: -15%;
6790 width: 1.28571429em;
6795 margin-left: 2.14285714em;
6796 list-style-type: none;
6803 left: -2.14285714em;
6804 width: 2.14285714em;
6809 left: -1.85714286em;
6812 padding: .2em .25em .15em;
6813 border: solid 0.08em #eee;
6814 border-radius: .1em;
6828 /* Deprecated as of 4.4.0 */
6842 -webkit-animation: fa-spin 2s infinite linear;
6843 animation: fa-spin 2s infinite linear;
6846 -webkit-animation: fa-spin 1s infinite steps(8);
6847 animation: fa-spin 1s infinite steps(8);
6849 @-webkit-keyframes fa-spin {
6851 -webkit-transform: rotate(0deg);
6852 transform: rotate(0deg);
6855 -webkit-transform: rotate(359deg);
6856 transform: rotate(359deg);
6859 @keyframes fa-spin {
6861 -webkit-transform: rotate(0deg);
6862 transform: rotate(0deg);
6865 -webkit-transform: rotate(359deg);
6866 transform: rotate(359deg);
6870 -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
6871 -webkit-transform: rotate(90deg);
6872 -ms-transform: rotate(90deg);
6873 transform: rotate(90deg);
6876 -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
6877 -webkit-transform: rotate(180deg);
6878 -ms-transform: rotate(180deg);
6879 transform: rotate(180deg);
6882 -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
6883 -webkit-transform: rotate(270deg);
6884 -ms-transform: rotate(270deg);
6885 transform: rotate(270deg);
6887 .fa-flip-horizontal {
6888 -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
6889 -webkit-transform: scale(-1, 1);
6890 -ms-transform: scale(-1, 1);
6891 transform: scale(-1, 1);
6894 -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
6895 -webkit-transform: scale(1, -1);
6896 -ms-transform: scale(1, -1);
6897 transform: scale(1, -1);
6899 :root .fa-rotate-90,
6900 :root .fa-rotate-180,
6901 :root .fa-rotate-270,
6902 :root .fa-flip-horizontal,
6903 :root .fa-flip-vertical {
6908 display: inline-block;
6912 vertical-align: middle;
6922 line-height: inherit;
6930 /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
6931 readers do not read off random characters that represent icons */
6941 .fa-envelope-o:before {
6959 .fa-th-large:before {
6965 .fa-th-list:before {
6976 .fa-search-plus:before {
6979 .fa-search-minus:before {
6982 .fa-power-off:before {
6992 .fa-trash-o:before {
7001 .fa-clock-o:before {
7007 .fa-download:before {
7010 .fa-arrow-circle-o-down:before {
7013 .fa-arrow-circle-o-up:before {
7019 .fa-play-circle-o:before {
7022 .fa-rotate-right:before,
7026 .fa-refresh:before {
7029 .fa-list-alt:before {
7038 .fa-headphones:before {
7041 .fa-volume-off:before {
7044 .fa-volume-down:before {
7047 .fa-volume-up:before {
7053 .fa-barcode:before {
7065 .fa-bookmark:before {
7083 .fa-text-height:before {
7086 .fa-text-width:before {
7089 .fa-align-left:before {
7092 .fa-align-center:before {
7095 .fa-align-right:before {
7098 .fa-align-justify:before {
7105 .fa-outdent:before {
7111 .fa-video-camera:before {
7116 .fa-picture-o:before {
7122 .fa-map-marker:before {
7132 .fa-pencil-square-o:before {
7135 .fa-share-square-o:before {
7138 .fa-check-square-o:before {
7144 .fa-step-backward:before {
7147 .fa-fast-backward:before {
7150 .fa-backward:before {
7162 .fa-forward:before {
7165 .fa-fast-forward:before {
7168 .fa-step-forward:before {
7174 .fa-chevron-left:before {
7177 .fa-chevron-right:before {
7180 .fa-plus-circle:before {
7183 .fa-minus-circle:before {
7186 .fa-times-circle:before {
7189 .fa-check-circle:before {
7192 .fa-question-circle:before {
7195 .fa-info-circle:before {
7198 .fa-crosshairs:before {
7201 .fa-times-circle-o:before {
7204 .fa-check-circle-o:before {
7210 .fa-arrow-left:before {
7213 .fa-arrow-right:before {
7216 .fa-arrow-up:before {
7219 .fa-arrow-down:before {
7222 .fa-mail-forward:before,
7229 .fa-compress:before {
7238 .fa-asterisk:before {
7241 .fa-exclamation-circle:before {
7256 .fa-eye-slash:before {
7260 .fa-exclamation-triangle:before {
7266 .fa-calendar:before {
7272 .fa-comment:before {
7278 .fa-chevron-up:before {
7281 .fa-chevron-down:before {
7284 .fa-retweet:before {
7287 .fa-shopping-cart:before {
7293 .fa-folder-open:before {
7296 .fa-arrows-v:before {
7299 .fa-arrows-h:before {
7302 .fa-bar-chart-o:before,
7303 .fa-bar-chart:before {
7306 .fa-twitter-square:before {
7309 .fa-facebook-square:before {
7312 .fa-camera-retro:before {
7322 .fa-comments:before {
7325 .fa-thumbs-o-up:before {
7328 .fa-thumbs-o-down:before {
7331 .fa-star-half:before {
7334 .fa-heart-o:before {
7337 .fa-sign-out:before {
7340 .fa-linkedin-square:before {
7343 .fa-thumb-tack:before {
7346 .fa-external-link:before {
7349 .fa-sign-in:before {
7355 .fa-github-square:before {
7361 .fa-lemon-o:before {
7367 .fa-square-o:before {
7370 .fa-bookmark-o:before {
7373 .fa-phone-square:before {
7376 .fa-twitter:before {
7379 .fa-facebook-f:before,
7380 .fa-facebook:before {
7389 .fa-credit-card:before {
7399 .fa-bullhorn:before {
7405 .fa-certificate:before {
7408 .fa-hand-o-right:before {
7411 .fa-hand-o-left:before {
7414 .fa-hand-o-up:before {
7417 .fa-hand-o-down:before {
7420 .fa-arrow-circle-left:before {
7423 .fa-arrow-circle-right:before {
7426 .fa-arrow-circle-up:before {
7429 .fa-arrow-circle-down:before {
7444 .fa-briefcase:before {
7447 .fa-arrows-alt:before {
7465 .fa-scissors:before {
7469 .fa-files-o:before {
7472 .fa-paperclip:before {
7476 .fa-floppy-o:before {
7487 .fa-list-ul:before {
7490 .fa-list-ol:before {
7493 .fa-strikethrough:before {
7496 .fa-underline:before {
7508 .fa-pinterest:before {
7511 .fa-pinterest-square:before {
7514 .fa-google-plus-square:before {
7517 .fa-google-plus:before {
7523 .fa-caret-down:before {
7526 .fa-caret-up:before {
7529 .fa-caret-left:before {
7532 .fa-caret-right:before {
7535 .fa-columns:before {
7538 .fa-unsorted:before,
7542 .fa-sort-down:before,
7543 .fa-sort-desc:before {
7547 .fa-sort-asc:before {
7550 .fa-envelope:before {
7553 .fa-linkedin:before {
7556 .fa-rotate-left:before,
7564 .fa-dashboard:before,
7565 .fa-tachometer:before {
7568 .fa-comment-o:before {
7571 .fa-comments-o:before {
7578 .fa-sitemap:before {
7581 .fa-umbrella:before {
7585 .fa-clipboard:before {
7588 .fa-lightbulb-o:before {
7591 .fa-exchange:before {
7594 .fa-cloud-download:before {
7597 .fa-cloud-upload:before {
7600 .fa-user-md:before {
7603 .fa-stethoscope:before {
7606 .fa-suitcase:before {
7615 .fa-cutlery:before {
7618 .fa-file-text-o:before {
7621 .fa-building-o:before {
7624 .fa-hospital-o:before {
7627 .fa-ambulance:before {
7633 .fa-fighter-jet:before {
7639 .fa-h-square:before {
7642 .fa-plus-square:before {
7645 .fa-angle-double-left:before {
7648 .fa-angle-double-right:before {
7651 .fa-angle-double-up:before {
7654 .fa-angle-double-down:before {
7657 .fa-angle-left:before {
7660 .fa-angle-right:before {
7663 .fa-angle-up:before {
7666 .fa-angle-down:before {
7669 .fa-desktop:before {
7678 .fa-mobile-phone:before,
7682 .fa-circle-o:before {
7685 .fa-quote-left:before {
7688 .fa-quote-right:before {
7691 .fa-spinner:before {
7697 .fa-mail-reply:before,
7701 .fa-github-alt:before {
7704 .fa-folder-o:before {
7707 .fa-folder-open-o:before {
7710 .fa-smile-o:before {
7713 .fa-frown-o:before {
7719 .fa-gamepad:before {
7722 .fa-keyboard-o:before {
7728 .fa-flag-checkered:before {
7731 .fa-terminal:before {
7737 .fa-mail-reply-all:before,
7738 .fa-reply-all:before {
7741 .fa-star-half-empty:before,
7742 .fa-star-half-full:before,
7743 .fa-star-half-o:before {
7746 .fa-location-arrow:before {
7752 .fa-code-fork:before {
7756 .fa-chain-broken:before {
7759 .fa-question:before {
7765 .fa-exclamation:before {
7768 .fa-superscript:before {
7771 .fa-subscript:before {
7777 .fa-puzzle-piece:before {
7780 .fa-microphone:before {
7783 .fa-microphone-slash:before {
7789 .fa-calendar-o:before {
7792 .fa-fire-extinguisher:before {
7801 .fa-chevron-circle-left:before {
7804 .fa-chevron-circle-right:before {
7807 .fa-chevron-circle-up:before {
7810 .fa-chevron-circle-down:before {
7822 .fa-unlock-alt:before {
7825 .fa-bullseye:before {
7828 .fa-ellipsis-h:before {
7831 .fa-ellipsis-v:before {
7834 .fa-rss-square:before {
7837 .fa-play-circle:before {
7843 .fa-minus-square:before {
7846 .fa-minus-square-o:before {
7849 .fa-level-up:before {
7852 .fa-level-down:before {
7855 .fa-check-square:before {
7858 .fa-pencil-square:before {
7861 .fa-external-link-square:before {
7864 .fa-share-square:before {
7867 .fa-compass:before {
7870 .fa-toggle-down:before,
7871 .fa-caret-square-o-down:before {
7874 .fa-toggle-up:before,
7875 .fa-caret-square-o-up:before {
7878 .fa-toggle-right:before,
7879 .fa-caret-square-o-right:before {
7919 .fa-file-text:before {
7922 .fa-sort-alpha-asc:before {
7925 .fa-sort-alpha-desc:before {
7928 .fa-sort-amount-asc:before {
7931 .fa-sort-amount-desc:before {
7934 .fa-sort-numeric-asc:before {
7937 .fa-sort-numeric-desc:before {
7940 .fa-thumbs-up:before {
7943 .fa-thumbs-down:before {
7946 .fa-youtube-square:before {
7949 .fa-youtube:before {
7955 .fa-xing-square:before {
7958 .fa-youtube-play:before {
7961 .fa-dropbox:before {
7964 .fa-stack-overflow:before {
7967 .fa-instagram:before {
7976 .fa-bitbucket:before {
7979 .fa-bitbucket-square:before {
7985 .fa-tumblr-square:before {
7988 .fa-long-arrow-down:before {
7991 .fa-long-arrow-up:before {
7994 .fa-long-arrow-left:before {
7997 .fa-long-arrow-right:before {
8003 .fa-windows:before {
8006 .fa-android:before {
8012 .fa-dribbble:before {
8018 .fa-foursquare:before {
8031 .fa-gratipay:before {
8040 .fa-archive:before {
8055 .fa-pagelines:before {
8058 .fa-stack-exchange:before {
8061 .fa-arrow-circle-o-right:before {
8064 .fa-arrow-circle-o-left:before {
8067 .fa-toggle-left:before,
8068 .fa-caret-square-o-left:before {
8071 .fa-dot-circle-o:before {
8074 .fa-wheelchair:before {
8077 .fa-vimeo-square:before {
8080 .fa-turkish-lira:before,
8084 .fa-plus-square-o:before {
8087 .fa-space-shuttle:before {
8093 .fa-envelope-square:before {
8096 .fa-wordpress:before {
8102 .fa-institution:before,
8104 .fa-university:before {
8107 .fa-mortar-board:before,
8108 .fa-graduation-cap:before {
8120 .fa-reddit-square:before {
8123 .fa-stumbleupon-circle:before {
8126 .fa-stumbleupon:before {
8129 .fa-delicious:before {
8135 .fa-pied-piper-pp:before {
8138 .fa-pied-piper-alt:before {
8147 .fa-language:before {
8153 .fa-building:before {
8171 .fa-behance:before {
8174 .fa-behance-square:before {
8180 .fa-steam-square:before {
8183 .fa-recycle:before {
8186 .fa-automobile:before,
8197 .fa-spotify:before {
8200 .fa-deviantart:before {
8203 .fa-soundcloud:before {
8206 .fa-database:before {
8209 .fa-file-pdf-o:before {
8212 .fa-file-word-o:before {
8215 .fa-file-excel-o:before {
8218 .fa-file-powerpoint-o:before {
8221 .fa-file-photo-o:before,
8222 .fa-file-picture-o:before,
8223 .fa-file-image-o:before {
8226 .fa-file-zip-o:before,
8227 .fa-file-archive-o:before {
8230 .fa-file-sound-o:before,
8231 .fa-file-audio-o:before {
8234 .fa-file-movie-o:before,
8235 .fa-file-video-o:before {
8238 .fa-file-code-o:before {
8244 .fa-codepen:before {
8247 .fa-jsfiddle:before {
8250 .fa-life-bouy:before,
8251 .fa-life-buoy:before,
8252 .fa-life-saver:before,
8254 .fa-life-ring:before {
8257 .fa-circle-o-notch:before {
8261 .fa-resistance:before,
8269 .fa-git-square:before {
8275 .fa-y-combinator-square:before,
8276 .fa-yc-square:before,
8277 .fa-hacker-news:before {
8280 .fa-tencent-weibo:before {
8291 .fa-paper-plane:before {
8295 .fa-paper-plane-o:before {
8298 .fa-history:before {
8301 .fa-circle-thin:before {
8307 .fa-paragraph:before {
8310 .fa-sliders:before {
8313 .fa-share-alt:before {
8316 .fa-share-alt-square:before {
8322 .fa-soccer-ball-o:before,
8323 .fa-futbol-o:before {
8329 .fa-binoculars:before {
8335 .fa-slideshare:before {
8344 .fa-newspaper-o:before {
8350 .fa-calculator:before {
8356 .fa-google-wallet:before {
8359 .fa-cc-visa:before {
8362 .fa-cc-mastercard:before {
8365 .fa-cc-discover:before {
8368 .fa-cc-amex:before {
8371 .fa-cc-paypal:before {
8374 .fa-cc-stripe:before {
8377 .fa-bell-slash:before {
8380 .fa-bell-slash-o:before {
8386 .fa-copyright:before {
8392 .fa-eyedropper:before {
8395 .fa-paint-brush:before {
8398 .fa-birthday-cake:before {
8401 .fa-area-chart:before {
8404 .fa-pie-chart:before {
8407 .fa-line-chart:before {
8413 .fa-lastfm-square:before {
8416 .fa-toggle-off:before {
8419 .fa-toggle-on:before {
8422 .fa-bicycle:before {
8428 .fa-ioxhost:before {
8431 .fa-angellist:before {
8442 .fa-meanpath:before {
8445 .fa-buysellads:before {
8448 .fa-connectdevelop:before {
8451 .fa-dashcube:before {
8454 .fa-forumbee:before {
8457 .fa-leanpub:before {
8463 .fa-shirtsinbulk:before {
8466 .fa-simplybuilt:before {
8469 .fa-skyatlas:before {
8472 .fa-cart-plus:before {
8475 .fa-cart-arrow-down:before {
8478 .fa-diamond:before {
8484 .fa-user-secret:before {
8487 .fa-motorcycle:before {
8490 .fa-street-view:before {
8493 .fa-heartbeat:before {
8502 .fa-mercury:before {
8505 .fa-intersex:before,
8506 .fa-transgender:before {
8509 .fa-transgender-alt:before {
8512 .fa-venus-double:before {
8515 .fa-mars-double:before {
8518 .fa-venus-mars:before {
8521 .fa-mars-stroke:before {
8524 .fa-mars-stroke-v:before {
8527 .fa-mars-stroke-h:before {
8533 .fa-genderless:before {
8536 .fa-facebook-official:before {
8539 .fa-pinterest-p:before {
8542 .fa-whatsapp:before {
8548 .fa-user-plus:before {
8551 .fa-user-times:before {
8558 .fa-viacoin:before {
8571 .fa-y-combinator:before {
8574 .fa-optin-monster:before {
8577 .fa-opencart:before {
8580 .fa-expeditedssl:before {
8583 .fa-battery-4:before,
8585 .fa-battery-full:before {
8588 .fa-battery-3:before,
8589 .fa-battery-three-quarters:before {
8592 .fa-battery-2:before,
8593 .fa-battery-half:before {
8596 .fa-battery-1:before,
8597 .fa-battery-quarter:before {
8600 .fa-battery-0:before,
8601 .fa-battery-empty:before {
8604 .fa-mouse-pointer:before {
8607 .fa-i-cursor:before {
8610 .fa-object-group:before {
8613 .fa-object-ungroup:before {
8616 .fa-sticky-note:before {
8619 .fa-sticky-note-o:before {
8625 .fa-cc-diners-club:before {
8631 .fa-balance-scale:before {
8634 .fa-hourglass-o:before {
8637 .fa-hourglass-1:before,
8638 .fa-hourglass-start:before {
8641 .fa-hourglass-2:before,
8642 .fa-hourglass-half:before {
8645 .fa-hourglass-3:before,
8646 .fa-hourglass-end:before {
8649 .fa-hourglass:before {
8652 .fa-hand-grab-o:before,
8653 .fa-hand-rock-o:before {
8656 .fa-hand-stop-o:before,
8657 .fa-hand-paper-o:before {
8660 .fa-hand-scissors-o:before {
8663 .fa-hand-lizard-o:before {
8666 .fa-hand-spock-o:before {
8669 .fa-hand-pointer-o:before {
8672 .fa-hand-peace-o:before {
8675 .fa-trademark:before {
8678 .fa-registered:before {
8681 .fa-creative-commons:before {
8687 .fa-gg-circle:before {
8690 .fa-tripadvisor:before {
8693 .fa-odnoklassniki:before {
8696 .fa-odnoklassniki-square:before {
8699 .fa-get-pocket:before {
8702 .fa-wikipedia-w:before {
8711 .fa-firefox:before {
8717 .fa-internet-explorer:before {
8721 .fa-television:before {
8733 .fa-calendar-plus-o:before {
8736 .fa-calendar-minus-o:before {
8739 .fa-calendar-times-o:before {
8742 .fa-calendar-check-o:before {
8745 .fa-industry:before {
8748 .fa-map-pin:before {
8751 .fa-map-signs:before {
8760 .fa-commenting:before {
8763 .fa-commenting-o:before {
8772 .fa-black-tie:before {
8775 .fa-fonticons:before {
8778 .fa-reddit-alien:before {
8784 .fa-credit-card-alt:before {
8787 .fa-codiepie:before {
8793 .fa-fort-awesome:before {
8799 .fa-product-hunt:before {
8802 .fa-mixcloud:before {
8808 .fa-pause-circle:before {
8811 .fa-pause-circle-o:before {
8814 .fa-stop-circle:before {
8817 .fa-stop-circle-o:before {
8820 .fa-shopping-bag:before {
8823 .fa-shopping-basket:before {
8826 .fa-hashtag:before {
8829 .fa-bluetooth:before {
8832 .fa-bluetooth-b:before {
8835 .fa-percent:before {
8841 .fa-wpbeginner:before {
8844 .fa-wpforms:before {
8850 .fa-universal-access:before {
8853 .fa-wheelchair-alt:before {
8856 .fa-question-circle-o:before {
8862 .fa-audio-description:before {
8865 .fa-volume-control-phone:before {
8868 .fa-braille:before {
8871 .fa-assistive-listening-systems:before {
8874 .fa-asl-interpreting:before,
8875 .fa-american-sign-language-interpreting:before {
8878 .fa-deafness:before,
8879 .fa-hard-of-hearing:before,
8886 .fa-glide-g:before {
8890 .fa-sign-language:before {
8893 .fa-low-vision:before {
8899 .fa-viadeo-square:before {
8902 .fa-snapchat:before {
8905 .fa-snapchat-ghost:before {
8908 .fa-snapchat-square:before {
8911 .fa-pied-piper:before {
8914 .fa-first-order:before {
8920 .fa-themeisle:before {
8923 .fa-google-plus-circle:before,
8924 .fa-google-plus-official:before {
8928 .fa-font-awesome:before {
8931 .fa-handshake-o:before {
8934 .fa-envelope-open:before {
8937 .fa-envelope-open-o:before {
8943 .fa-address-book:before {
8946 .fa-address-book-o:before {
8950 .fa-address-card:before {
8954 .fa-address-card-o:before {
8957 .fa-user-circle:before {
8960 .fa-user-circle-o:before {
8966 .fa-id-badge:before {
8969 .fa-drivers-license:before,
8970 .fa-id-card:before {
8973 .fa-drivers-license-o:before,
8974 .fa-id-card-o:before {
8980 .fa-free-code-camp:before {
8983 .fa-telegram:before {
8986 .fa-thermometer-4:before,
8987 .fa-thermometer:before,
8988 .fa-thermometer-full:before {
8991 .fa-thermometer-3:before,
8992 .fa-thermometer-three-quarters:before {
8995 .fa-thermometer-2:before,
8996 .fa-thermometer-half:before {
8999 .fa-thermometer-1:before,
9000 .fa-thermometer-quarter:before {
9003 .fa-thermometer-0:before,
9004 .fa-thermometer-empty:before {
9015 .fa-podcast:before {
9018 .fa-window-maximize:before {
9021 .fa-window-minimize:before {
9024 .fa-window-restore:before {
9027 .fa-times-rectangle:before,
9028 .fa-window-close:before {
9031 .fa-times-rectangle-o:before,
9032 .fa-window-close-o:before {
9035 .fa-bandcamp:before {
9047 .fa-ravelry:before {
9050 .fa-eercast:before {
9053 .fa-microchip:before {
9056 .fa-snowflake-o:before {
9059 .fa-superpowers:before {
9062 .fa-wpexplorer:before {
9075 clip: rect(0, 0, 0, 0);
9078 .sr-only-focusable:active,
9079 .sr-only-focusable:focus {
9087 .sr-only-focusable:active,
9088 .sr-only-focusable:focus {
9101 .modal.fade .modal-dialog {
9102 -webkit-transform: translate(0, 0);
9103 -ms-transform: translate(0, 0);
9104 -o-transform: translate(0, 0);
9105 transform: translate(0, 0);
9112 line-height: inherit;
9115 font-weight: normal;
9117 /* Make the page background atleast 100% the height of the view port */
9118 /* Make the page itself atleast 70% the height of the view port */
9119 .border-box-sizing {
9120 box-sizing: border-box;
9121 -moz-box-sizing: border-box;
9122 -webkit-box-sizing: border-box;
9130 /* Flexible box model classes */
9131 /* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
9132 /* This file is a compatability layer. It allows the usage of flexible box
9133 model layouts accross multiple browsers, including older browsers. The newest,
9134 universal implementation of the flexible box model is used when available (see
9135 `Modern browsers` comments below). Browsers that are known to implement this
9136 new spec completely include:
9140 Internet Explorer 11+
9143 Browsers not listed, including Safari, are supported via the styling under the
9144 `Old browsers` comments below.
9148 display: -webkit-box;
9149 -webkit-box-orient: horizontal;
9150 -webkit-box-align: stretch;
9152 -moz-box-orient: horizontal;
9153 -moz-box-align: stretch;
9155 box-orient: horizontal;
9157 /* Modern browsers */
9159 flex-direction: row;
9160 align-items: stretch;
9164 -webkit-box-flex: 0;
9167 /* Modern browsers */
9172 display: -webkit-box;
9173 -webkit-box-orient: vertical;
9174 -webkit-box-align: stretch;
9176 -moz-box-orient: vertical;
9177 -moz-box-align: stretch;
9179 box-orient: vertical;
9181 /* Modern browsers */
9183 flex-direction: column;
9184 align-items: stretch;
9188 -webkit-box-flex: 0;
9191 /* Modern browsers */
9198 -webkit-box-direction: reverse;
9199 -moz-box-direction: reverse;
9200 box-direction: reverse;
9201 /* Modern browsers */
9202 flex-direction: row-reverse;
9208 -webkit-box-flex: 0;
9211 /* Modern browsers */
9219 -webkit-box-flex: 1;
9222 /* Modern browsers */
9230 -webkit-box-flex: 1;
9233 /* Modern browsers */
9240 -webkit-box-flex: 2;
9243 /* Modern browsers */
9248 -webkit-box-flex-group: 1;
9249 -moz-box-flex-group: 1;
9254 -webkit-box-flex-group: 2;
9255 -moz-box-flex-group: 2;
9262 -webkit-box-pack: start;
9263 -moz-box-pack: start;
9265 /* Modern browsers */
9266 justify-content: flex-start;
9272 -webkit-box-pack: end;
9275 /* Modern browsers */
9276 justify-content: flex-end;
9282 -webkit-box-pack: center;
9283 -moz-box-pack: center;
9285 /* Modern browsers */
9286 justify-content: center;
9292 -webkit-box-pack: baseline;
9293 -moz-box-pack: baseline;
9295 /* Modern browsers */
9296 justify-content: baseline;
9302 -webkit-box-pack: stretch;
9303 -moz-box-pack: stretch;
9305 /* Modern browsers */
9306 justify-content: stretch;
9312 -webkit-box-align: start;
9313 -moz-box-align: start;
9315 /* Modern browsers */
9316 align-items: flex-start;
9322 -webkit-box-align: end;
9323 -moz-box-align: end;
9325 /* Modern browsers */
9326 align-items: flex-end;
9332 -webkit-box-align: center;
9333 -moz-box-align: center;
9335 /* Modern browsers */
9336 align-items: center;
9338 .hbox.align-baseline,
9339 .vbox.align-baseline,
9342 -webkit-box-align: baseline;
9343 -moz-box-align: baseline;
9344 box-align: baseline;
9345 /* Modern browsers */
9346 align-items: baseline;
9348 .hbox.align-stretch,
9349 .vbox.align-stretch,
9352 -webkit-box-align: stretch;
9353 -moz-box-align: stretch;
9355 /* Modern browsers */
9356 align-items: stretch;
9364 line-height: normal;
9368 line-height: normal;
9370 div.traceback-wrapper {
9375 div.traceback-wrapper pre.traceback {
9382 * Author: Jupyter Development Team
9385 background-color: #fff;
9386 /* This makes sure that the body covers the entire window and needs to
9387 be in a different element than the display: box in wrapper below */
9396 /* Initially hidden to prevent FLOUC */
9398 background-color: #fff;
9399 /* Display over codemirror */
9403 body > #header #header-container {
9405 flex-direction: row;
9406 justify-content: space-between;
9408 padding-bottom: 5px;
9410 box-sizing: border-box;
9411 -moz-box-sizing: border-box;
9412 -webkit-box-sizing: border-box;
9414 body > #header .header-bar {
9417 background: #e7e7e7;
9418 margin-bottom: -1px;
9422 display: none !important;
9437 padding-bottom: 1px;
9439 [dir="rtl"] #ipython_notebook {
9443 [dir="rtl"] #ipython_notebook.pull-left {
9444 float: right !important;
9453 padding-bottom: 16px;
9459 #ipython_notebook img {
9465 box-sizing: border-box;
9466 -moz-box-sizing: border-box;
9467 -webkit-box-sizing: border-box;
9472 height: auto !important;
9475 /* Smaller buttons */
9476 .ui-button .ui-button-text {
9477 padding: 0.2em 0.8em;
9481 padding: 0.3em 0.9em;
9483 span#kernel_logo_widget {
9489 [dir="rtl"] span#login_widget {
9492 span#login_widget > .button,
9495 background-color: #fff;
9498 span#login_widget > .button:focus,
9500 span#login_widget > .button.focus,
9503 background-color: #e6e6e6;
9504 border-color: #8c8c8c;
9506 span#login_widget > .button:hover,
9509 background-color: #e6e6e6;
9510 border-color: #adadad;
9512 span#login_widget > .button:active,
9514 span#login_widget > .button.active,
9516 .open > .dropdown-togglespan#login_widget > .button,
9517 .open > .dropdown-toggle#logout {
9519 background-color: #e6e6e6;
9520 border-color: #adadad;
9522 span#login_widget > .button:active:hover,
9523 #logout:active:hover,
9524 span#login_widget > .button.active:hover,
9525 #logout.active:hover,
9526 .open > .dropdown-togglespan#login_widget > .button:hover,
9527 .open > .dropdown-toggle#logout:hover,
9528 span#login_widget > .button:active:focus,
9529 #logout:active:focus,
9530 span#login_widget > .button.active:focus,
9531 #logout.active:focus,
9532 .open > .dropdown-togglespan#login_widget > .button:focus,
9533 .open > .dropdown-toggle#logout:focus,
9534 span#login_widget > .button:active.focus,
9535 #logout:active.focus,
9536 span#login_widget > .button.active.focus,
9537 #logout.active.focus,
9538 .open > .dropdown-togglespan#login_widget > .button.focus,
9539 .open > .dropdown-toggle#logout.focus {
9541 background-color: #d4d4d4;
9542 border-color: #8c8c8c;
9544 span#login_widget > .button:active,
9546 span#login_widget > .button.active,
9548 .open > .dropdown-togglespan#login_widget > .button,
9549 .open > .dropdown-toggle#logout {
9550 background-image: none;
9552 span#login_widget > .button.disabled:hover,
9553 #logout.disabled:hover,
9554 span#login_widget > .button[disabled]:hover,
9555 #logout[disabled]:hover,
9556 fieldset[disabled] span#login_widget > .button:hover,
9557 fieldset[disabled] #logout:hover,
9558 span#login_widget > .button.disabled:focus,
9559 #logout.disabled:focus,
9560 span#login_widget > .button[disabled]:focus,
9561 #logout[disabled]:focus,
9562 fieldset[disabled] span#login_widget > .button:focus,
9563 fieldset[disabled] #logout:focus,
9564 span#login_widget > .button.disabled.focus,
9565 #logout.disabled.focus,
9566 span#login_widget > .button[disabled].focus,
9567 #logout[disabled].focus,
9568 fieldset[disabled] span#login_widget > .button.focus,
9569 fieldset[disabled] #logout.focus {
9570 background-color: #fff;
9573 span#login_widget > .button .badge,
9576 background-color: #333;
9579 text-transform: none;
9584 .modal_stretch .modal-dialog {
9586 display: -webkit-box;
9587 -webkit-box-orient: vertical;
9588 -webkit-box-align: stretch;
9590 -moz-box-orient: vertical;
9591 -moz-box-align: stretch;
9593 box-orient: vertical;
9595 /* Modern browsers */
9597 flex-direction: column;
9598 align-items: stretch;
9601 .modal_stretch .modal-dialog .modal-body {
9602 max-height: calc(100vh - 200px);
9609 @media (min-width: 768px) {
9610 .modal .modal-dialog {
9614 @media (min-width: 768px) {
9615 select.form-control {
9626 display: inline-block;
9627 margin-bottom: -4px;
9629 [dir="rtl"] .center-nav form.pull-left {
9630 float: right !important;
9633 [dir="rtl"] .center-nav .navbar-text {
9636 [dir="rtl"] .navbar-inner {
9639 [dir="rtl"] div.text-left {
9647 /* We need an invisible input field on top of the sentense*/
9648 /* "Drag file onto the list ..." */
9650 background-color: none;
9653 .alternate_upload.form {
9657 .alternate_upload input.fileinput {
9667 .alternate_upload .btn-xs > input.fileinput {
9670 .alternate_upload .btn-upload {
9674 ::-webkit-file-upload-button {
9680 * Author: Jupyter Development Team
9687 padding-bottom: 4px;
9689 [dir="rtl"] ul#tabs.nav-tabs > li {
9692 [dir="rtl"] ul#tabs.nav.nav-tabs {
9695 ul.breadcrumb a:focus,
9696 ul.breadcrumb a:hover {
9697 text-decoration: none;
9699 ul.breadcrumb i.icon-home {
9703 ul.breadcrumb span {
9707 padding: 4px 0 4px 0;
9708 vertical-align: middle;
9710 .list_toolbar .tree-buttons {
9713 [dir="rtl"] .list_toolbar .tree-buttons .pull-right {
9714 float: left !important;
9717 [dir="rtl"] .list_toolbar .col-sm-4,
9718 [dir="rtl"] .list_toolbar .col-sm-8 {
9723 display: inline-block;
9725 .list_toolbar [class*="span"] {
9730 background-color: #EEE;
9735 padding-bottom: 4px;
9741 margin-bottom: 20px;
9742 border: 1px solid #ddd;
9745 .list_container > div {
9746 border-bottom: 1px solid #ddd;
9748 .list_container > div:hover .list-item {
9749 background-color: red;
9751 .list_container > div:last-child {
9754 .list_item:hover .list_item {
9755 background-color: #ddd;
9758 text-decoration: none;
9761 background-color: #fafafa;
9766 padding-bottom: 4px;
9771 .list_header > div input,
9772 .list_item > div input {
9775 vertical-align: text-bottom;
9780 .list_header > div .item_link,
9781 .list_item > div .item_link {
9783 vertical-align: baseline;
9786 [dir="rtl"] .list_item > div input {
9789 .new-file input[type=checkbox] {
9802 vertical-align: baseline;
9808 [dir="rtl"] .item_modified.pull-right {
9809 float: left !important;
9817 .item_buttons .btn-group,
9818 .item_buttons .input-group {
9821 .item_buttons > .btn,
9822 .item_buttons > .btn-group,
9823 .item_buttons > .input-group {
9826 .item_buttons .btn {
9829 .item_buttons .running-indicator {
9833 .item_buttons .kernel-name {
9839 [dir="rtl"] .item_buttons.pull-right {
9840 float: left !important;
9843 [dir="rtl"] .item_buttons .kernel-name {
9851 .list_item input:not([type=checkbox]) {
9853 padding-bottom: 3px;
9862 display: inline-block;
9866 #project_name > .breadcrumb {
9869 background-color: transparent;
9873 display: inline-block;
9876 [dir="rtl"] .sort_button.pull-right {
9877 float: left !important;
9883 #button-select-all {
9886 [dir="rtl"] #button-select-all.btn {
9895 [dir="rtl"] #select-all.pull-left {
9896 float: right !important;
9906 .folder_icon:before {
9907 display: inline-block;
9908 font: normal normal normal 14px/1 FontAwesome;
9910 text-rendering: auto;
9911 -webkit-font-smoothing: antialiased;
9912 -moz-osx-font-smoothing: grayscale;
9915 .folder_icon:before.fa-pull-left {
9918 .folder_icon:before.fa-pull-right {
9921 .folder_icon:before.pull-left {
9924 .folder_icon:before.pull-right {
9927 .notebook_icon:before {
9928 display: inline-block;
9929 font: normal normal normal 14px/1 FontAwesome;
9931 text-rendering: auto;
9932 -webkit-font-smoothing: antialiased;
9933 -moz-osx-font-smoothing: grayscale;
9938 .notebook_icon:before.fa-pull-left {
9941 .notebook_icon:before.fa-pull-right {
9944 .notebook_icon:before.pull-left {
9947 .notebook_icon:before.pull-right {
9950 .running_notebook_icon:before {
9951 display: inline-block;
9952 font: normal normal normal 14px/1 FontAwesome;
9954 text-rendering: auto;
9955 -webkit-font-smoothing: antialiased;
9956 -moz-osx-font-smoothing: grayscale;
9962 .running_notebook_icon:before.fa-pull-left {
9965 .running_notebook_icon:before.fa-pull-right {
9968 .running_notebook_icon:before.pull-left {
9971 .running_notebook_icon:before.pull-right {
9975 display: inline-block;
9976 font: normal normal normal 14px/1 FontAwesome;
9978 text-rendering: auto;
9979 -webkit-font-smoothing: antialiased;
9980 -moz-osx-font-smoothing: grayscale;
9985 .file_icon:before.fa-pull-left {
9988 .file_icon:before.fa-pull-right {
9991 .file_icon:before.pull-left {
9994 .file_icon:before.pull-right {
9997 #notebook_toolbar .pull-right {
10005 #new-menu .dropdown-header {
10007 border-bottom: 1px solid #e5e5e5;
10009 margin: -3px 20px 0;
10011 .kernel-menu-icon {
10012 padding-right: 12px;
10016 .kernel-menu-icon:before {
10019 .kernel-menu-icon-current:before {
10025 #running .panel-group .panel {
10027 margin-bottom: 1em;
10029 #running .panel-group .panel .panel-heading {
10030 background-color: #EEE;
10032 padding-bottom: 4px;
10034 padding-right: 7px;
10037 #running .panel-group .panel .panel-heading a:focus,
10038 #running .panel-group .panel .panel-heading a:hover {
10039 text-decoration: none;
10041 #running .panel-group .panel .panel-body {
10044 #running .panel-group .panel .panel-body .list_container {
10046 margin-bottom: 0px;
10048 border-radius: 0px;
10050 #running .panel-group .panel .panel-body .list_container .list_item {
10051 border-bottom: 1px solid #ddd;
10053 #running .panel-group .panel .panel-body .list_container .list_item:last-child {
10054 border-bottom: 0px;
10059 .duplicate-button {
10074 .dynamic-instructions {
10075 display: inline-block;
10080 * IPython text editor webapp
10083 .selected-keymap i.fa {
10086 .selected-keymap i.fa:before {
10093 .edit_app #header {
10094 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10095 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10097 .edit_app #menubar .navbar {
10098 /* Use a negative 1 bottom margin, so the border overlaps the border of the
10100 margin-bottom: -1px;
10103 display: inline-block;
10104 font: normal normal normal 14px/1 FontAwesome;
10105 font-size: inherit;
10106 text-rendering: auto;
10107 -webkit-font-smoothing: antialiased;
10108 -moz-osx-font-smoothing: grayscale;
10111 .dirty-indicator.fa-pull-left {
10112 margin-right: .3em;
10114 .dirty-indicator.fa-pull-right {
10117 .dirty-indicator.pull-left {
10118 margin-right: .3em;
10120 .dirty-indicator.pull-right {
10123 .dirty-indicator-dirty {
10124 display: inline-block;
10125 font: normal normal normal 14px/1 FontAwesome;
10126 font-size: inherit;
10127 text-rendering: auto;
10128 -webkit-font-smoothing: antialiased;
10129 -moz-osx-font-smoothing: grayscale;
10132 .dirty-indicator-dirty.fa-pull-left {
10133 margin-right: .3em;
10135 .dirty-indicator-dirty.fa-pull-right {
10138 .dirty-indicator-dirty.pull-left {
10139 margin-right: .3em;
10141 .dirty-indicator-dirty.pull-right {
10144 .dirty-indicator-clean {
10145 display: inline-block;
10146 font: normal normal normal 14px/1 FontAwesome;
10147 font-size: inherit;
10148 text-rendering: auto;
10149 -webkit-font-smoothing: antialiased;
10150 -moz-osx-font-smoothing: grayscale;
10153 .dirty-indicator-clean.fa-pull-left {
10154 margin-right: .3em;
10156 .dirty-indicator-clean.fa-pull-right {
10159 .dirty-indicator-clean.pull-left {
10160 margin-right: .3em;
10162 .dirty-indicator-clean.pull-right {
10165 .dirty-indicator-clean:before {
10166 display: inline-block;
10167 font: normal normal normal 14px/1 FontAwesome;
10168 font-size: inherit;
10169 text-rendering: auto;
10170 -webkit-font-smoothing: antialiased;
10171 -moz-osx-font-smoothing: grayscale;
10174 .dirty-indicator-clean:before.fa-pull-left {
10175 margin-right: .3em;
10177 .dirty-indicator-clean:before.fa-pull-right {
10180 .dirty-indicator-clean:before.pull-left {
10181 margin-right: .3em;
10183 .dirty-indicator-clean:before.pull-right {
10193 padding-right: 5px;
10195 #texteditor-backdrop {
10197 padding-bottom: 20px;
10200 #texteditor-backdrop {
10201 background-color: #EEE;
10205 #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
10206 #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
10207 background-color: #fff;
10211 #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
10212 #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
10213 background-color: #fff;
10217 #texteditor-backdrop #texteditor-container {
10219 background-color: #fff;
10220 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10221 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10224 .CodeMirror-dialog {
10225 background-color: #fff;
10232 /* CSS font colors for translated ANSI escape sequences */
10233 /* The color values are a mix of
10234 http://www.xcolors.net/dl/baskerville-ivorylight and
10235 http://www.xcolors.net/dl/euphrasia */
10240 background-color: #3E424D;
10242 .ansi-black-intense-fg {
10245 .ansi-black-intense-bg {
10246 background-color: #282C36;
10252 background-color: #E75C58;
10254 .ansi-red-intense-fg {
10257 .ansi-red-intense-bg {
10258 background-color: #B22B31;
10264 background-color: #00A250;
10266 .ansi-green-intense-fg {
10269 .ansi-green-intense-bg {
10270 background-color: #007427;
10276 background-color: #DDB62B;
10278 .ansi-yellow-intense-fg {
10281 .ansi-yellow-intense-bg {
10282 background-color: #B27D12;
10288 background-color: #208FFB;
10290 .ansi-blue-intense-fg {
10293 .ansi-blue-intense-bg {
10294 background-color: #0065CA;
10300 background-color: #D160C4;
10302 .ansi-magenta-intense-fg {
10305 .ansi-magenta-intense-bg {
10306 background-color: #A03196;
10312 background-color: #60C6C8;
10314 .ansi-cyan-intense-fg {
10317 .ansi-cyan-intense-bg {
10318 background-color: #258F8F;
10324 background-color: #C5C1B4;
10326 .ansi-white-intense-fg {
10329 .ansi-white-intense-bg {
10330 background-color: #A1A6B2;
10332 .ansi-default-inverse-fg {
10335 .ansi-default-inverse-bg {
10336 background-color: #000000;
10342 text-decoration: underline;
10344 /* The following styles are deprecated an will be removed in a future version */
10349 outline: 0.5px dotted;
10351 /* use dark versions for foreground, to improve visibility */
10376 /* and light for background, for the same reason */
10378 background-color: black;
10381 background-color: red;
10384 background-color: green;
10387 background-color: yellow;
10390 background-color: blue;
10393 background-color: magenta;
10396 background-color: cyan;
10399 background-color: gray;
10403 display: -webkit-box;
10404 -webkit-box-orient: vertical;
10405 -webkit-box-align: stretch;
10407 -moz-box-orient: vertical;
10408 -moz-box-align: stretch;
10410 box-orient: vertical;
10411 box-align: stretch;
10412 /* Modern browsers */
10414 flex-direction: column;
10415 align-items: stretch;
10416 border-radius: 2px;
10417 box-sizing: border-box;
10418 -moz-box-sizing: border-box;
10419 -webkit-box-sizing: border-box;
10421 border-style: solid;
10422 border-color: transparent;
10425 /* This acts as a spacer between cells, that is outside the border */
10428 position: relative;
10432 position: absolute;
10437 height: calc(100% + 2px);
10439 background: transparent;
10441 div.cell.jupyter-soft-selected {
10442 border-left-color: #E3F2FD;
10443 border-left-width: 1px;
10445 border-right-color: #E3F2FD;
10446 border-right-width: 1px;
10447 background: #E3F2FD;
10450 div.cell.jupyter-soft-selected {
10451 border-color: transparent;
10455 div.cell.selected.jupyter-soft-selected {
10456 border-color: #ababab;
10458 div.cell.selected:before,
10459 div.cell.selected.jupyter-soft-selected:before {
10460 position: absolute;
10465 height: calc(100% + 2px);
10467 background: #42A5F5;
10471 div.cell.selected.jupyter-soft-selected {
10472 border-color: transparent;
10475 .edit_mode div.cell.selected {
10476 border-color: #66BB6A;
10478 .edit_mode div.cell.selected:before {
10479 position: absolute;
10484 height: calc(100% + 2px);
10486 background: #66BB6A;
10489 .edit_mode div.cell.selected {
10490 border-color: transparent;
10494 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
10496 /* This padding is tuned to match the padding on the CodeMirror editor. */
10499 font-family: monospace;
10501 /* This has to match that of the the CodeMirror class line-height below */
10502 line-height: 1.21429em;
10503 /* Don't highlight prompt number selection */
10504 -webkit-touch-callout: none;
10505 -webkit-user-select: none;
10506 -khtml-user-select: none;
10507 -moz-user-select: none;
10508 -ms-user-select: none;
10510 /* Use default cursor */
10513 @media (max-width: 540px) {
10521 display: -webkit-box;
10522 -webkit-box-orient: vertical;
10523 -webkit-box-align: stretch;
10525 -moz-box-orient: vertical;
10526 -moz-box-align: stretch;
10528 box-orient: vertical;
10529 box-align: stretch;
10530 /* Modern browsers */
10532 flex-direction: column;
10533 align-items: stretch;
10535 -webkit-box-flex: 1;
10538 /* Modern browsers */
10541 /* input_area and input_prompt must match in top border and margin for alignment */
10543 border: 1px solid #cfcfcf;
10544 border-radius: 2px;
10545 background: #f7f7f7;
10546 line-height: 1.21429em;
10548 /* This is needed so that empty prompt areas can collapse to zero height when there
10549 is no content in the output_subarea and the prompt. The main purpose of this is
10550 to make sure that empty JavaScript output_subareas have no height. */
10555 div.unrecognized_cell {
10556 padding: 5px 5px 5px 0px;
10558 display: -webkit-box;
10559 -webkit-box-orient: horizontal;
10560 -webkit-box-align: stretch;
10562 -moz-box-orient: horizontal;
10563 -moz-box-align: stretch;
10565 box-orient: horizontal;
10566 box-align: stretch;
10567 /* Modern browsers */
10569 flex-direction: row;
10570 align-items: stretch;
10572 div.unrecognized_cell .inner_cell {
10573 border-radius: 2px;
10577 border: 1px solid #cfcfcf;
10578 background: #eaeaea;
10580 div.unrecognized_cell .inner_cell a {
10582 text-decoration: none;
10584 div.unrecognized_cell .inner_cell a:hover {
10586 text-decoration: none;
10588 @media (max-width: 540px) {
10589 div.unrecognized_cell > div.prompt {
10594 /* avoid page breaking on code cells when printing */
10598 page-break-inside: avoid;
10601 /* any special styling for code cells that are currently running goes here */
10603 page-break-inside: avoid;
10605 display: -webkit-box;
10606 -webkit-box-orient: horizontal;
10607 -webkit-box-align: stretch;
10609 -moz-box-orient: horizontal;
10610 -moz-box-align: stretch;
10612 box-orient: horizontal;
10613 box-align: stretch;
10614 /* Modern browsers */
10616 flex-direction: row;
10617 align-items: stretch;
10619 @media (max-width: 540px) {
10622 display: -webkit-box;
10623 -webkit-box-orient: vertical;
10624 -webkit-box-align: stretch;
10626 -moz-box-orient: vertical;
10627 -moz-box-align: stretch;
10629 box-orient: vertical;
10630 box-align: stretch;
10631 /* Modern browsers */
10633 flex-direction: column;
10634 align-items: stretch;
10637 /* input_area and input_prompt must match in top border and margin for alignment */
10640 border-top: 1px solid transparent;
10642 div.input_area > div.highlight {
10646 background-color: transparent;
10648 div.input_area > div.highlight > pre {
10652 background-color: transparent;
10654 /* The following gets added to the <head> if it is detected that the user has a
10655 * monospace font with inconsistent normal/bold/italic height. See
10656 * notebookmain.js. Such fonts will have keywords vertically offset with
10657 * respect to the rest of the text. The user should select a better font.
10658 * See: https://github.com/ipython/ipython/issues/1503
10660 * .CodeMirror span {
10661 * vertical-align: bottom;
10665 line-height: 1.21429em;
10666 /* Changed from 1em to our global default */
10669 /* Changed to auto to autogrow */
10671 /* Changed from white to allow our bg to show through */
10673 .CodeMirror-scroll {
10674 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
10675 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
10676 overflow-y: hidden;
10679 .CodeMirror-lines {
10680 /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
10681 /* we have set a different line-height and want this to scale with that. */
10682 /* Note that this should set vertical padding only, since CodeMirror assumes
10683 that horizontal padding will be set on CodeMirror pre */
10686 .CodeMirror-linenumber {
10687 padding: 0 8px 0 4px;
10689 .CodeMirror-gutters {
10690 border-bottom-left-radius: 2px;
10691 border-top-left-radius: 2px;
10694 /* In CM3 this went to 4px from 0 in CM2. This sets horizontal padding only,
10695 use .CodeMirror-lines for vertical */
10700 .CodeMirror-cursor {
10701 border-left: 1.4px solid black;
10703 @media screen and (min-width: 2138px) and (max-width: 4319px) {
10704 .CodeMirror-cursor {
10705 border-left: 2px solid black;
10708 @media screen and (min-width: 4320px) {
10709 .CodeMirror-cursor {
10710 border-left: 4px solid black;
10715 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
10716 Adapted from GitHub theme
10722 .highlight-variable {
10725 .highlight-variable-2 {
10728 .highlight-variable-3 {
10731 .highlight-string {
10734 .highlight-comment {
10736 font-style: italic;
10738 .highlight-number {
10744 .highlight-keyword {
10748 .highlight-builtin {
10754 .highlight-operator {
10761 /* previously not defined, copying from default codemirror */
10765 .highlight-string-2 {
10768 .highlight-qualifier {
10771 .highlight-bracket {
10777 .highlight-attribute {
10780 .highlight-header {
10789 /* apply the same style to codemirror */
10790 .cm-s-ipython span.cm-keyword {
10794 .cm-s-ipython span.cm-atom {
10797 .cm-s-ipython span.cm-number {
10800 .cm-s-ipython span.cm-def {
10803 .cm-s-ipython span.cm-variable {
10806 .cm-s-ipython span.cm-operator {
10810 .cm-s-ipython span.cm-variable-2 {
10813 .cm-s-ipython span.cm-variable-3 {
10816 .cm-s-ipython span.cm-comment {
10818 font-style: italic;
10820 .cm-s-ipython span.cm-string {
10823 .cm-s-ipython span.cm-string-2 {
10826 .cm-s-ipython span.cm-meta {
10829 .cm-s-ipython span.cm-qualifier {
10832 .cm-s-ipython span.cm-builtin {
10835 .cm-s-ipython span.cm-bracket {
10838 .cm-s-ipython span.cm-tag {
10841 .cm-s-ipython span.cm-attribute {
10844 .cm-s-ipython span.cm-header {
10847 .cm-s-ipython span.cm-quote {
10850 .cm-s-ipython span.cm-link {
10853 .cm-s-ipython span.cm-error {
10856 .cm-s-ipython span.cm-tab {
10857 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
10858 background-position: right;
10859 background-repeat: no-repeat;
10861 div.output_wrapper {
10862 /* this position must be relative to enable descendents to be absolute within it */
10863 position: relative;
10865 display: -webkit-box;
10866 -webkit-box-orient: vertical;
10867 -webkit-box-align: stretch;
10869 -moz-box-orient: vertical;
10870 -moz-box-align: stretch;
10872 box-orient: vertical;
10873 box-align: stretch;
10874 /* Modern browsers */
10876 flex-direction: column;
10877 align-items: stretch;
10880 /* class for the output area when it should be height-limited */
10881 div.output_scroll {
10882 /* ideally, this would be max-height, but FF barfs all over that */
10884 /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
10887 border-radius: 2px;
10888 -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
10889 box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
10892 /* output div while it is collapsed */
10893 div.output_collapsed {
10897 display: -webkit-box;
10898 -webkit-box-orient: vertical;
10899 -webkit-box-align: stretch;
10901 -moz-box-orient: vertical;
10902 -moz-box-align: stretch;
10904 box-orient: vertical;
10905 box-align: stretch;
10906 /* Modern browsers */
10908 flex-direction: column;
10909 align-items: stretch;
10911 div.out_prompt_overlay {
10913 padding: 0px 0.4em;
10914 position: absolute;
10915 border-radius: 2px;
10917 div.out_prompt_overlay:hover {
10918 /* use inner shadow to get border that is computed the same on WebKit/FF */
10919 -webkit-box-shadow: inset 0 0 1px #000;
10920 box-shadow: inset 0 0 1px #000;
10921 background: rgba(240, 240, 240, 0.5);
10923 div.output_prompt {
10926 /* This class is the outer container of all output sections. */
10929 page-break-inside: avoid;
10931 display: -webkit-box;
10932 -webkit-box-orient: horizontal;
10933 -webkit-box-align: stretch;
10935 -moz-box-orient: horizontal;
10936 -moz-box-align: stretch;
10938 box-orient: horizontal;
10939 box-align: stretch;
10940 /* Modern browsers */
10942 flex-direction: row;
10943 align-items: stretch;
10945 div.output_area .MathJax_Display {
10946 text-align: left !important;
10948 div.output_area .rendered_html table {
10952 div.output_area .rendered_html img {
10956 div.output_area img,
10957 div.output_area svg {
10961 div.output_area img.unconfined,
10962 div.output_area svg.unconfined {
10965 div.output_area .mglyph > img {
10968 /* This is needed to protect the pre formating from global settings such
10969 as that of bootstrap */
10972 display: -webkit-box;
10973 -webkit-box-orient: vertical;
10974 -webkit-box-align: stretch;
10976 -moz-box-orient: vertical;
10977 -moz-box-align: stretch;
10979 box-orient: vertical;
10980 box-align: stretch;
10981 /* Modern browsers */
10983 flex-direction: column;
10984 align-items: stretch;
10986 @media (max-width: 540px) {
10989 display: -webkit-box;
10990 -webkit-box-orient: vertical;
10991 -webkit-box-align: stretch;
10993 -moz-box-orient: vertical;
10994 -moz-box-align: stretch;
10996 box-orient: vertical;
10997 box-align: stretch;
10998 /* Modern browsers */
11000 flex-direction: column;
11001 align-items: stretch;
11004 div.output_area pre {
11006 padding: 1px 0 1px 0;
11008 vertical-align: baseline;
11010 background-color: transparent;
11013 /* This class is for the output subarea inside the output_area and after
11015 div.output_subarea {
11019 -webkit-box-flex: 1;
11022 /* Modern browsers */
11024 max-width: calc(100% - 14ex);
11026 div.output_scroll div.output_subarea {
11027 overflow-x: visible;
11029 /* The rest of the output_* classes are for special styling of the different
11031 /* all text output has this class: */
11035 /* This has to match that of the the CodeMirror class line-height below */
11036 line-height: 1.21429em;
11038 /* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
11039 div.output_stderr {
11041 /* very light red background for stderr */
11046 /* Empty output_javascript divs should have no height */
11047 div.output_javascript:empty {
11053 /* raw_input styles */
11054 div.raw_input_container {
11055 line-height: 1.21429em;
11058 pre.raw_input_prompt {
11059 /* nothing needed here. */
11062 font-family: monospace;
11063 font-size: inherit;
11066 /* make sure input baseline aligns with prompt */
11067 vertical-align: baseline;
11068 /* padding + margin = 0.5em between prompt and cursor */
11069 padding: 0em 0.25em;
11070 margin: 0em 0.25em;
11072 input.raw_input:focus {
11076 margin-bottom: 10px;
11078 div.output_unrecognized {
11083 div.output_unrecognized a {
11085 text-decoration: none;
11087 div.output_unrecognized a:hover {
11089 text-decoration: none;
11093 /* any extras will just be numbers: */
11095 .rendered_html em {
11096 font-style: italic;
11098 .rendered_html strong {
11102 text-decoration: underline;
11104 .rendered_html :link {
11105 text-decoration: underline;
11107 .rendered_html :visited {
11108 text-decoration: underline;
11110 .rendered_html h1 {
11112 margin: 1.08em 0 0 0;
11116 .rendered_html h2 {
11118 margin: 1.27em 0 0 0;
11122 .rendered_html h3 {
11124 margin: 1.55em 0 0 0;
11128 .rendered_html h4 {
11134 .rendered_html h5 {
11139 font-style: italic;
11141 .rendered_html h6 {
11146 font-style: italic;
11148 .rendered_html h1:first-child {
11149 margin-top: 0.538em;
11151 .rendered_html h2:first-child {
11152 margin-top: 0.636em;
11154 .rendered_html h3:first-child {
11155 margin-top: 0.777em;
11157 .rendered_html h4:first-child {
11160 .rendered_html h5:first-child {
11163 .rendered_html h6:first-child {
11166 .rendered_html ul:not(.list-inline),
11167 .rendered_html ol:not(.list-inline) {
11170 .rendered_html ul {
11173 .rendered_html ul ul {
11174 list-style: square;
11177 .rendered_html ul ul ul {
11178 list-style: circle;
11180 .rendered_html ol {
11181 list-style: decimal;
11183 .rendered_html ol ol {
11184 list-style: upper-alpha;
11187 .rendered_html ol ol ol {
11188 list-style: lower-alpha;
11190 .rendered_html ol ol ol ol {
11191 list-style: lower-roman;
11193 .rendered_html ol ol ol ol ol {
11194 list-style: decimal;
11196 .rendered_html * + ul {
11199 .rendered_html * + ol {
11202 .rendered_html hr {
11204 background-color: black;
11206 .rendered_html pre {
11209 background-color: #fff;
11211 .rendered_html code {
11212 background-color: #eff0f1;
11214 .rendered_html p code {
11217 .rendered_html pre code {
11218 background-color: #fff;
11220 .rendered_html pre,
11221 .rendered_html code {
11226 .rendered_html blockquote {
11229 .rendered_html table {
11231 margin-right: auto;
11233 border-collapse: collapse;
11237 table-layout: fixed;
11239 .rendered_html thead {
11240 border-bottom: 1px solid black;
11241 vertical-align: bottom;
11245 .rendered_html td {
11247 vertical-align: middle;
11248 padding: 0.5em 0.5em;
11249 line-height: normal;
11250 white-space: normal;
11254 .rendered_html th {
11257 .rendered_html tbody tr:nth-child(odd) {
11258 background: #f5f5f5;
11260 .rendered_html tbody tr:hover {
11261 background: rgba(66, 165, 245, 0.2);
11263 .rendered_html * + table {
11269 .rendered_html * + p {
11272 .rendered_html img {
11275 margin-right: auto;
11277 .rendered_html * + img {
11280 .rendered_html img,
11281 .rendered_html svg {
11285 .rendered_html img.unconfined,
11286 .rendered_html svg.unconfined {
11289 .rendered_html .alert {
11290 margin-bottom: initial;
11292 .rendered_html * + .alert {
11295 [dir="rtl"] .rendered_html p {
11300 display: -webkit-box;
11301 -webkit-box-orient: horizontal;
11302 -webkit-box-align: stretch;
11304 -moz-box-orient: horizontal;
11305 -moz-box-align: stretch;
11307 box-orient: horizontal;
11308 box-align: stretch;
11309 /* Modern browsers */
11311 flex-direction: row;
11312 align-items: stretch;
11314 @media (max-width: 540px) {
11315 div.text_cell > div.prompt {
11319 div.text_cell_render {
11320 /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
11324 border-style: none;
11325 padding: 0.5em 0.5em 0.5em 0.4em;
11327 box-sizing: border-box;
11328 -moz-box-sizing: border-box;
11329 -webkit-box-sizing: border-box;
11331 a.anchor-link:link {
11332 text-decoration: none;
11334 visibility: hidden;
11336 h1:hover .anchor-link,
11337 h2:hover .anchor-link,
11338 h3:hover .anchor-link,
11339 h4:hover .anchor-link,
11340 h5:hover .anchor-link,
11341 h6:hover .anchor-link {
11342 visibility: visible;
11344 .text_cell.rendered .input_area {
11347 .text_cell.rendered .rendered_html {
11349 overflow-y: hidden;
11351 .text_cell.rendered .rendered_html tr,
11352 .text_cell.rendered .rendered_html th,
11353 .text_cell.rendered .rendered_html td {
11356 .text_cell.unrendered .text_cell_render {
11359 .text_cell .dropzone .input_area {
11360 border: 2px dashed #bababa;
11370 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
11386 font-style: italic;
11390 font-style: italic;
11394 * IPython notebook webapp
11397 @media (max-width: 767px) {
11400 padding-right: 0px;
11403 #ipython-main-app {
11404 box-sizing: border-box;
11405 -moz-box-sizing: border-box;
11406 -webkit-box-sizing: border-box;
11409 div#notebook_panel {
11412 box-sizing: border-box;
11413 -moz-box-sizing: border-box;
11414 -webkit-box-sizing: border-box;
11420 overflow-y: hidden;
11423 /* This spaces the page away from the edge of the notebook area */
11427 box-sizing: border-box;
11428 -moz-box-sizing: border-box;
11429 -webkit-box-sizing: border-box;
11433 #notebook-container {
11435 background-color: #fff;
11437 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11438 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11442 #notebook-container {
11446 div.ui-widget-content {
11447 border: 1px solid #ababab;
11451 background-color: #f7f7f7;
11452 border: 1px solid #ddd;
11453 border-radius: 2px;
11460 /* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems
11461 to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do.
11467 white-space: pre-wrap;
11470 font-family: monospace;
11477 transition: height .2s ease;
11479 .notebook_app > #header {
11480 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11481 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11485 background-color: #EEE;
11489 border-style: solid;
11494 padding-right: 2px;
11496 padding-bottom: 1px;
11498 .jupyter-keybindings {
11501 border-bottom: 1px solid gray;
11503 .jupyter-keybindings input {
11508 .jupyter-keybindings i {
11512 background-color: #ffffff;
11513 border-color: #ababab;
11515 border-style: solid;
11518 padding-bottom: 1px;
11520 /* CSS for the cell toolbar */
11522 border: thin solid #CFCFCF;
11523 border-bottom: none;
11525 border-radius: 2px 2px 0px 0px;
11528 padding-right: 4px;
11530 display: -webkit-box;
11531 -webkit-box-orient: horizontal;
11532 -webkit-box-align: stretch;
11534 -moz-box-orient: horizontal;
11535 -moz-box-align: stretch;
11537 box-orient: horizontal;
11538 box-align: stretch;
11539 /* Modern browsers */
11541 flex-direction: row;
11542 align-items: stretch;
11544 -webkit-box-pack: end;
11545 -moz-box-pack: end;
11547 /* Modern browsers */
11548 justify-content: flex-end;
11549 display: -webkit-flex;
11558 vertical-align: bottom;
11560 /* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
11561 Cell toolbars are only shown when the ctb_global_show class is also set.
11563 .ctb_global_show .ctb_show.ctb_hideshow {
11566 .ctb_global_show .ctb_show + .input_area,
11567 .ctb_global_show .ctb_show + div.text_cell_input,
11568 .ctb_global_show .ctb_show ~ div.text_cell_render {
11569 border-top-right-radius: 0px;
11570 border-top-left-radius: 0px;
11572 .ctb_global_show .ctb_show ~ div.text_cell_render {
11573 border: 1px solid #cfcfcf;
11579 .celltoolbar select {
11585 line-height: 1.42857143;
11587 background-color: #fff;
11588 background-image: none;
11589 border: 1px solid #ccc;
11590 border-radius: 2px;
11591 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11592 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11593 -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11594 -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11595 transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11600 border-radius: 1px;
11602 font-size: inherit;
11605 display: inline-block;
11607 .celltoolbar select:focus {
11608 border-color: #66afe9;
11610 -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11611 box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11613 .celltoolbar select::-moz-placeholder {
11617 .celltoolbar select:-ms-input-placeholder {
11620 .celltoolbar select::-webkit-input-placeholder {
11623 .celltoolbar select::-ms-expand {
11625 background-color: transparent;
11627 .celltoolbar select[disabled],
11628 .celltoolbar select[readonly],
11629 fieldset[disabled] .celltoolbar select {
11630 background-color: #eeeeee;
11633 .celltoolbar select[disabled],
11634 fieldset[disabled] .celltoolbar select {
11635 cursor: not-allowed;
11637 textarea.celltoolbar select {
11640 select.celltoolbar select {
11644 textarea.celltoolbar select,
11645 select[multiple].celltoolbar select {
11648 .celltoolbar label {
11652 .tags_button_container {
11658 flex-direction: row;
11661 position: relative;
11663 .tag-container > * {
11672 .cell-tag:last-child:after {
11674 position: absolute;
11678 /* Fade to background color of cell toolbar */
11679 background: linear-gradient(to right, rgba(0, 0, 0, 0), #EEE);
11686 .tags-input button {
11692 line-height: 1.42857143;
11694 background-color: #fff;
11695 background-image: none;
11696 border: 1px solid #ccc;
11697 border-radius: 2px;
11698 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11699 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
11700 -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11701 -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11702 transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
11707 border-radius: 1px;
11710 font-size: inherit;
11714 display: inline-block;
11717 .tags-input input:focus,
11718 .tags-input button:focus {
11719 border-color: #66afe9;
11721 -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11722 box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
11724 .cell-tag::-moz-placeholder,
11725 .tags-input input::-moz-placeholder,
11726 .tags-input button::-moz-placeholder {
11730 .cell-tag:-ms-input-placeholder,
11731 .tags-input input:-ms-input-placeholder,
11732 .tags-input button:-ms-input-placeholder {
11735 .cell-tag::-webkit-input-placeholder,
11736 .tags-input input::-webkit-input-placeholder,
11737 .tags-input button::-webkit-input-placeholder {
11740 .cell-tag::-ms-expand,
11741 .tags-input input::-ms-expand,
11742 .tags-input button::-ms-expand {
11744 background-color: transparent;
11746 .cell-tag[disabled],
11747 .tags-input input[disabled],
11748 .tags-input button[disabled],
11749 .cell-tag[readonly],
11750 .tags-input input[readonly],
11751 .tags-input button[readonly],
11752 fieldset[disabled] .cell-tag,
11753 fieldset[disabled] .tags-input input,
11754 fieldset[disabled] .tags-input button {
11755 background-color: #eeeeee;
11758 .cell-tag[disabled],
11759 .tags-input input[disabled],
11760 .tags-input button[disabled],
11761 fieldset[disabled] .cell-tag,
11762 fieldset[disabled] .tags-input input,
11763 fieldset[disabled] .tags-input button {
11764 cursor: not-allowed;
11767 textarea.tags-input input,
11768 textarea.tags-input button {
11772 select.tags-input input,
11773 select.tags-input button {
11778 textarea.tags-input input,
11779 textarea.tags-input button,
11780 select[multiple].cell-tag,
11781 select[multiple].tags-input input,
11782 select[multiple].tags-input button {
11786 .tags-input button {
11790 background-color: #fff;
11791 white-space: nowrap;
11793 .tags-input input[type=text]:focus {
11796 border-color: #ccc;
11799 position: absolute;
11802 border: 1px solid #ababab;
11803 border-radius: 2px;
11804 -webkit-box-shadow: 0px 6px 10px -1px #adadad;
11805 box-shadow: 0px 6px 10px -1px #adadad;
11808 .completions select {
11815 font-family: monospace;
11820 .completions select option.context {
11823 #kernel_logo_widget .current_kernel_logo {
11826 margin-bottom: -1px;
11830 [dir="rtl"] #kernel_logo_widget {
11831 float: left !important;
11834 .modal .modal-body .move-path {
11836 flex-direction: row;
11837 justify-content: space;
11838 align-items: center;
11840 .modal .modal-body .move-path .server-root {
11841 padding-right: 20px;
11843 .modal .modal-body .move-path .path-input {
11847 box-sizing: border-box;
11848 -moz-box-sizing: border-box;
11849 -webkit-box-sizing: border-box;
11854 border-radius: 0px 0px 2px 2px;
11855 margin-bottom: 0px;
11857 #menubar .navbar-toggle {
11860 padding-bottom: 7px;
11863 #menubar .navbar-collapse {
11866 [dir="rtl"] #menubar .navbar-toggle {
11869 [dir="rtl"] #menubar .navbar-collapse {
11872 [dir="rtl"] #menubar .navbar-nav {
11875 [dir="rtl"] #menubar .nav {
11876 padding-right: 0px;
11878 [dir="rtl"] #menubar .navbar-nav > li {
11881 [dir="rtl"] #menubar .navbar-right {
11882 float: left !important;
11884 [dir="rtl"] ul.dropdown-menu {
11888 [dir="rtl"] ul#new-menu.dropdown-menu {
11893 border-bottom: 1px solid #e7e7e7;
11898 [dir="rtl"] i.menu-icon.pull-right {
11899 float: left !important;
11902 ul#help_menu li a {
11904 padding-right: 2.2em;
11906 ul#help_menu li a i {
11907 margin-right: -1.2em;
11909 [dir="rtl"] ul#help_menu li a {
11910 padding-left: 2.2em;
11912 [dir="rtl"] ul#help_menu li a i {
11914 margin-left: -1.2em;
11916 [dir="rtl"] ul#help_menu li a i.pull-right {
11917 float: left !important;
11920 .dropdown-submenu {
11921 position: relative;
11923 .dropdown-submenu > .dropdown-menu {
11929 [dir="rtl"] .dropdown-submenu > .dropdown-menu {
11931 margin-right: -1px;
11933 .dropdown-submenu:hover > .dropdown-menu {
11936 .dropdown-submenu > a:after {
11937 display: inline-block;
11938 font: normal normal normal 14px/1 FontAwesome;
11939 font-size: inherit;
11940 text-rendering: auto;
11941 -webkit-font-smoothing: antialiased;
11942 -moz-osx-font-smoothing: grayscale;
11948 margin-right: -10px;
11950 .dropdown-submenu > a:after.fa-pull-left {
11951 margin-right: .3em;
11953 .dropdown-submenu > a:after.fa-pull-right {
11956 .dropdown-submenu > a:after.pull-left {
11957 margin-right: .3em;
11959 .dropdown-submenu > a:after.pull-right {
11962 [dir="rtl"] .dropdown-submenu > a:after {
11966 margin-left: -10px;
11968 .dropdown-submenu:hover > a:after {
11971 .dropdown-submenu.pull-left {
11974 .dropdown-submenu.pull-left > .dropdown-menu {
11978 #notification_area {
11979 float: right !important;
11983 [dir="rtl"] #notification_area {
11984 float: left !important;
11988 float: right !important;
11995 text-align: center;
11998 [dir="rtl"] .indicator_area {
11999 float: left !important;
12002 #kernel_indicator {
12003 float: right !important;
12010 text-align: center;
12012 border-left: 1px solid;
12014 #kernel_indicator .kernel_indicator_name {
12016 padding-right: 5px;
12018 [dir="rtl"] #kernel_indicator {
12019 float: left !important;
12022 border-right: 1px solid;
12025 float: right !important;
12032 text-align: center;
12035 [dir="rtl"] #modal_indicator {
12036 float: left !important;
12039 #readonly-indicator {
12040 float: right !important;
12047 text-align: center;
12050 margin-bottom: 0px;
12055 .modal_indicator:before {
12056 width: 1.28571429em;
12057 text-align: center;
12059 .edit_mode .modal_indicator:before {
12060 display: inline-block;
12061 font: normal normal normal 14px/1 FontAwesome;
12062 font-size: inherit;
12063 text-rendering: auto;
12064 -webkit-font-smoothing: antialiased;
12065 -moz-osx-font-smoothing: grayscale;
12068 .edit_mode .modal_indicator:before.fa-pull-left {
12069 margin-right: .3em;
12071 .edit_mode .modal_indicator:before.fa-pull-right {
12074 .edit_mode .modal_indicator:before.pull-left {
12075 margin-right: .3em;
12077 .edit_mode .modal_indicator:before.pull-right {
12080 .command_mode .modal_indicator:before {
12081 display: inline-block;
12082 font: normal normal normal 14px/1 FontAwesome;
12083 font-size: inherit;
12084 text-rendering: auto;
12085 -webkit-font-smoothing: antialiased;
12086 -moz-osx-font-smoothing: grayscale;
12089 .command_mode .modal_indicator:before.fa-pull-left {
12090 margin-right: .3em;
12092 .command_mode .modal_indicator:before.fa-pull-right {
12095 .command_mode .modal_indicator:before.pull-left {
12096 margin-right: .3em;
12098 .command_mode .modal_indicator:before.pull-right {
12101 .kernel_idle_icon:before {
12102 display: inline-block;
12103 font: normal normal normal 14px/1 FontAwesome;
12104 font-size: inherit;
12105 text-rendering: auto;
12106 -webkit-font-smoothing: antialiased;
12107 -moz-osx-font-smoothing: grayscale;
12110 .kernel_idle_icon:before.fa-pull-left {
12111 margin-right: .3em;
12113 .kernel_idle_icon:before.fa-pull-right {
12116 .kernel_idle_icon:before.pull-left {
12117 margin-right: .3em;
12119 .kernel_idle_icon:before.pull-right {
12122 .kernel_busy_icon:before {
12123 display: inline-block;
12124 font: normal normal normal 14px/1 FontAwesome;
12125 font-size: inherit;
12126 text-rendering: auto;
12127 -webkit-font-smoothing: antialiased;
12128 -moz-osx-font-smoothing: grayscale;
12131 .kernel_busy_icon:before.fa-pull-left {
12132 margin-right: .3em;
12134 .kernel_busy_icon:before.fa-pull-right {
12137 .kernel_busy_icon:before.pull-left {
12138 margin-right: .3em;
12140 .kernel_busy_icon:before.pull-right {
12143 .kernel_dead_icon:before {
12144 display: inline-block;
12145 font: normal normal normal 14px/1 FontAwesome;
12146 font-size: inherit;
12147 text-rendering: auto;
12148 -webkit-font-smoothing: antialiased;
12149 -moz-osx-font-smoothing: grayscale;
12152 .kernel_dead_icon:before.fa-pull-left {
12153 margin-right: .3em;
12155 .kernel_dead_icon:before.fa-pull-right {
12158 .kernel_dead_icon:before.pull-left {
12159 margin-right: .3em;
12161 .kernel_dead_icon:before.pull-right {
12164 .kernel_disconnected_icon:before {
12165 display: inline-block;
12166 font: normal normal normal 14px/1 FontAwesome;
12167 font-size: inherit;
12168 text-rendering: auto;
12169 -webkit-font-smoothing: antialiased;
12170 -moz-osx-font-smoothing: grayscale;
12173 .kernel_disconnected_icon:before.fa-pull-left {
12174 margin-right: .3em;
12176 .kernel_disconnected_icon:before.fa-pull-right {
12179 .kernel_disconnected_icon:before.pull-left {
12180 margin-right: .3em;
12182 .kernel_disconnected_icon:before.pull-right {
12185 .notification_widget {
12188 background: rgba(240, 240, 240, 0.5);
12191 background-color: #fff;
12192 border-color: #ccc;
12194 .notification_widget:focus,
12195 .notification_widget.focus {
12197 background-color: #e6e6e6;
12198 border-color: #8c8c8c;
12200 .notification_widget:hover {
12202 background-color: #e6e6e6;
12203 border-color: #adadad;
12205 .notification_widget:active,
12206 .notification_widget.active,
12207 .open > .dropdown-toggle.notification_widget {
12209 background-color: #e6e6e6;
12210 border-color: #adadad;
12212 .notification_widget:active:hover,
12213 .notification_widget.active:hover,
12214 .open > .dropdown-toggle.notification_widget:hover,
12215 .notification_widget:active:focus,
12216 .notification_widget.active:focus,
12217 .open > .dropdown-toggle.notification_widget:focus,
12218 .notification_widget:active.focus,
12219 .notification_widget.active.focus,
12220 .open > .dropdown-toggle.notification_widget.focus {
12222 background-color: #d4d4d4;
12223 border-color: #8c8c8c;
12225 .notification_widget:active,
12226 .notification_widget.active,
12227 .open > .dropdown-toggle.notification_widget {
12228 background-image: none;
12230 .notification_widget.disabled:hover,
12231 .notification_widget[disabled]:hover,
12232 fieldset[disabled] .notification_widget:hover,
12233 .notification_widget.disabled:focus,
12234 .notification_widget[disabled]:focus,
12235 fieldset[disabled] .notification_widget:focus,
12236 .notification_widget.disabled.focus,
12237 .notification_widget[disabled].focus,
12238 fieldset[disabled] .notification_widget.focus {
12239 background-color: #fff;
12240 border-color: #ccc;
12242 .notification_widget .badge {
12244 background-color: #333;
12246 .notification_widget.warning {
12248 background-color: #f0ad4e;
12249 border-color: #eea236;
12251 .notification_widget.warning:focus,
12252 .notification_widget.warning.focus {
12254 background-color: #ec971f;
12255 border-color: #985f0d;
12257 .notification_widget.warning:hover {
12259 background-color: #ec971f;
12260 border-color: #d58512;
12262 .notification_widget.warning:active,
12263 .notification_widget.warning.active,
12264 .open > .dropdown-toggle.notification_widget.warning {
12266 background-color: #ec971f;
12267 border-color: #d58512;
12269 .notification_widget.warning:active:hover,
12270 .notification_widget.warning.active:hover,
12271 .open > .dropdown-toggle.notification_widget.warning:hover,
12272 .notification_widget.warning:active:focus,
12273 .notification_widget.warning.active:focus,
12274 .open > .dropdown-toggle.notification_widget.warning:focus,
12275 .notification_widget.warning:active.focus,
12276 .notification_widget.warning.active.focus,
12277 .open > .dropdown-toggle.notification_widget.warning.focus {
12279 background-color: #d58512;
12280 border-color: #985f0d;
12282 .notification_widget.warning:active,
12283 .notification_widget.warning.active,
12284 .open > .dropdown-toggle.notification_widget.warning {
12285 background-image: none;
12287 .notification_widget.warning.disabled:hover,
12288 .notification_widget.warning[disabled]:hover,
12289 fieldset[disabled] .notification_widget.warning:hover,
12290 .notification_widget.warning.disabled:focus,
12291 .notification_widget.warning[disabled]:focus,
12292 fieldset[disabled] .notification_widget.warning:focus,
12293 .notification_widget.warning.disabled.focus,
12294 .notification_widget.warning[disabled].focus,
12295 fieldset[disabled] .notification_widget.warning.focus {
12296 background-color: #f0ad4e;
12297 border-color: #eea236;
12299 .notification_widget.warning .badge {
12301 background-color: #fff;
12303 .notification_widget.success {
12305 background-color: #5cb85c;
12306 border-color: #4cae4c;
12308 .notification_widget.success:focus,
12309 .notification_widget.success.focus {
12311 background-color: #449d44;
12312 border-color: #255625;
12314 .notification_widget.success:hover {
12316 background-color: #449d44;
12317 border-color: #398439;
12319 .notification_widget.success:active,
12320 .notification_widget.success.active,
12321 .open > .dropdown-toggle.notification_widget.success {
12323 background-color: #449d44;
12324 border-color: #398439;
12326 .notification_widget.success:active:hover,
12327 .notification_widget.success.active:hover,
12328 .open > .dropdown-toggle.notification_widget.success:hover,
12329 .notification_widget.success:active:focus,
12330 .notification_widget.success.active:focus,
12331 .open > .dropdown-toggle.notification_widget.success:focus,
12332 .notification_widget.success:active.focus,
12333 .notification_widget.success.active.focus,
12334 .open > .dropdown-toggle.notification_widget.success.focus {
12336 background-color: #398439;
12337 border-color: #255625;
12339 .notification_widget.success:active,
12340 .notification_widget.success.active,
12341 .open > .dropdown-toggle.notification_widget.success {
12342 background-image: none;
12344 .notification_widget.success.disabled:hover,
12345 .notification_widget.success[disabled]:hover,
12346 fieldset[disabled] .notification_widget.success:hover,
12347 .notification_widget.success.disabled:focus,
12348 .notification_widget.success[disabled]:focus,
12349 fieldset[disabled] .notification_widget.success:focus,
12350 .notification_widget.success.disabled.focus,
12351 .notification_widget.success[disabled].focus,
12352 fieldset[disabled] .notification_widget.success.focus {
12353 background-color: #5cb85c;
12354 border-color: #4cae4c;
12356 .notification_widget.success .badge {
12358 background-color: #fff;
12360 .notification_widget.info {
12362 background-color: #5bc0de;
12363 border-color: #46b8da;
12365 .notification_widget.info:focus,
12366 .notification_widget.info.focus {
12368 background-color: #31b0d5;
12369 border-color: #1b6d85;
12371 .notification_widget.info:hover {
12373 background-color: #31b0d5;
12374 border-color: #269abc;
12376 .notification_widget.info:active,
12377 .notification_widget.info.active,
12378 .open > .dropdown-toggle.notification_widget.info {
12380 background-color: #31b0d5;
12381 border-color: #269abc;
12383 .notification_widget.info:active:hover,
12384 .notification_widget.info.active:hover,
12385 .open > .dropdown-toggle.notification_widget.info:hover,
12386 .notification_widget.info:active:focus,
12387 .notification_widget.info.active:focus,
12388 .open > .dropdown-toggle.notification_widget.info:focus,
12389 .notification_widget.info:active.focus,
12390 .notification_widget.info.active.focus,
12391 .open > .dropdown-toggle.notification_widget.info.focus {
12393 background-color: #269abc;
12394 border-color: #1b6d85;
12396 .notification_widget.info:active,
12397 .notification_widget.info.active,
12398 .open > .dropdown-toggle.notification_widget.info {
12399 background-image: none;
12401 .notification_widget.info.disabled:hover,
12402 .notification_widget.info[disabled]:hover,
12403 fieldset[disabled] .notification_widget.info:hover,
12404 .notification_widget.info.disabled:focus,
12405 .notification_widget.info[disabled]:focus,
12406 fieldset[disabled] .notification_widget.info:focus,
12407 .notification_widget.info.disabled.focus,
12408 .notification_widget.info[disabled].focus,
12409 fieldset[disabled] .notification_widget.info.focus {
12410 background-color: #5bc0de;
12411 border-color: #46b8da;
12413 .notification_widget.info .badge {
12415 background-color: #fff;
12417 .notification_widget.danger {
12419 background-color: #d9534f;
12420 border-color: #d43f3a;
12422 .notification_widget.danger:focus,
12423 .notification_widget.danger.focus {
12425 background-color: #c9302c;
12426 border-color: #761c19;
12428 .notification_widget.danger:hover {
12430 background-color: #c9302c;
12431 border-color: #ac2925;
12433 .notification_widget.danger:active,
12434 .notification_widget.danger.active,
12435 .open > .dropdown-toggle.notification_widget.danger {
12437 background-color: #c9302c;
12438 border-color: #ac2925;
12440 .notification_widget.danger:active:hover,
12441 .notification_widget.danger.active:hover,
12442 .open > .dropdown-toggle.notification_widget.danger:hover,
12443 .notification_widget.danger:active:focus,
12444 .notification_widget.danger.active:focus,
12445 .open > .dropdown-toggle.notification_widget.danger:focus,
12446 .notification_widget.danger:active.focus,
12447 .notification_widget.danger.active.focus,
12448 .open > .dropdown-toggle.notification_widget.danger.focus {
12450 background-color: #ac2925;
12451 border-color: #761c19;
12453 .notification_widget.danger:active,
12454 .notification_widget.danger.active,
12455 .open > .dropdown-toggle.notification_widget.danger {
12456 background-image: none;
12458 .notification_widget.danger.disabled:hover,
12459 .notification_widget.danger[disabled]:hover,
12460 fieldset[disabled] .notification_widget.danger:hover,
12461 .notification_widget.danger.disabled:focus,
12462 .notification_widget.danger[disabled]:focus,
12463 fieldset[disabled] .notification_widget.danger:focus,
12464 .notification_widget.danger.disabled.focus,
12465 .notification_widget.danger[disabled].focus,
12466 fieldset[disabled] .notification_widget.danger.focus {
12467 background-color: #d9534f;
12468 border-color: #d43f3a;
12470 .notification_widget.danger .badge {
12472 background-color: #fff;
12475 background-color: #fff;
12485 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12486 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12487 /* Display over codemirror */
12489 /* Hack which prevents jquery ui resizable from changing top. */
12490 top: auto !important;
12493 line-height: 1.21429em;
12495 background-color: #f7f7f7;
12498 div#pager #pager-button-area {
12499 position: absolute;
12503 div#pager #pager-contents {
12504 position: relative;
12509 div#pager #pager-contents #pager-container {
12510 position: relative;
12512 box-sizing: border-box;
12513 -moz-box-sizing: border-box;
12514 -webkit-box-sizing: border-box;
12516 div#pager .ui-resizable-handle {
12519 background: #f7f7f7;
12520 border-top: 1px solid #cfcfcf;
12521 border-bottom: 1px solid #cfcfcf;
12522 /* This injects handle bars (a short, wide = symbol) for
12523 the resize handle. */
12525 div#pager .ui-resizable-handle::after {
12531 margin-left: -15px;
12532 position: absolute;
12533 border-top: 1px solid #cfcfcf;
12537 display: -webkit-box;
12538 -webkit-box-orient: horizontal;
12539 -webkit-box-align: stretch;
12541 -moz-box-orient: horizontal;
12542 -moz-box-align: stretch;
12544 box-orient: horizontal;
12545 box-align: stretch;
12546 /* Modern browsers */
12548 flex-direction: row;
12549 align-items: stretch;
12550 line-height: 1.8em;
12553 display: inline-block;
12556 font-family: monospace;
12559 display: inline-block;
12561 -webkit-box-flex: 1;
12564 /* Modern browsers */
12571 justify-content: flex-start;
12572 align-items: baseline;
12576 span.save_widget span.filename {
12582 text-overflow: ellipsis;
12584 white-space: nowrap;
12585 border-radius: 2px;
12587 span.save_widget span.filename:hover {
12588 background-color: #e6e6e6;
12590 [dir="rtl"] span.save_widget.pull-left {
12591 float: right !important;
12594 [dir="rtl"] span.save_widget span.filename {
12596 margin-right: 16px;
12598 span.checkpoint_status,
12599 span.autosave_status {
12601 white-space: nowrap;
12604 @media (max-width: 767px) {
12607 padding: 0 0 0 5px;
12609 span.checkpoint_status,
12610 span.autosave_status {
12614 @media (min-width: 768px) and (max-width: 991px) {
12615 span.checkpoint_status {
12618 span.autosave_status {
12619 font-size: x-small;
12626 margin-bottom: 5px;
12627 box-sizing: border-box;
12628 -moz-box-sizing: border-box;
12629 -webkit-box-sizing: border-box;
12634 vertical-align: middle;
12636 margin-bottom: 0px;
12639 margin-left: 0.3em;
12640 margin-right: 0.3em;
12647 .toolbar .btn-group {
12651 .toolbar-btn-label {
12655 margin-bottom: -3px;
12661 padding-bottom: 3px;
12663 #maintoolbar .navbar-text {
12665 vertical-align: middle;
12674 [dir="rtl"] .btn-group > .btn,
12675 .btn-group-vertical > .btn {
12679 .dropdown-menu > li > a.pulse,
12680 li.pulse > a.dropdown-toggle,
12681 li.pulse.open > a.dropdown-toggle {
12682 background-color: #F37626;
12688 * Author: Jupyter Development Team
12690 /** WARNING IF YOU ARE EDITTING THIS FILE, if this is a .css file, It has a lot
12691 * of chance of beeing generated from the ../less/[samename].less file, you can
12692 * try to get back the less file by reverting somme commit in history
12695 * We'll try to get something pretty, so we
12696 * have some strange css to have the scroll bar on
12697 * the left with fix button on the top right of the tooltip
12699 @-moz-keyframes fadeOut {
12707 @-webkit-keyframes fadeOut {
12715 @-moz-keyframes fadeIn {
12723 @-webkit-keyframes fadeIn {
12731 /*properties of tooltip after "expand"*/
12735 -webkit-transition-property: height;
12736 -webkit-transition-duration: 500ms;
12737 -moz-transition-property: height;
12738 -moz-transition-duration: 500ms;
12739 transition-property: height;
12740 transition-duration: 500ms;
12742 /*properties of tooltip before "expand"*/
12744 -webkit-transition-property: height;
12745 -webkit-transition-duration: 500ms;
12746 -moz-transition-property: height;
12747 -moz-transition-duration: 500ms;
12748 transition-property: height;
12749 transition-duration: 500ms;
12750 text-overflow: ellipsis;
12755 position: absolute;
12756 padding-right: 15px;
12761 /*avoid the button to overlap on some docstring*/
12762 padding-right: 30px;
12766 /*fade-in animation when inserted*/
12767 -webkit-animation: fadeOut 400ms;
12768 -moz-animation: fadeOut 400ms;
12769 animation: fadeOut 400ms;
12770 -webkit-animation: fadeIn 400ms;
12771 -moz-animation: fadeIn 400ms;
12772 animation: fadeIn 400ms;
12773 vertical-align: middle;
12774 background-color: #f7f7f7;
12776 border: #ababab 1px solid;
12781 font-family: monospace;
12783 -moz-box-shadow: 0px 6px 10px -1px #adadad;
12784 -webkit-box-shadow: 0px 6px 10px -1px #adadad;
12785 box-shadow: 0px 6px 10px -1px #adadad;
12786 border-radius: 2px;
12787 position: absolute;
12790 .ipython_tooltip a {
12793 .ipython_tooltip .tooltiptext pre {
12797 background-color: #f7f7f7;
12806 position: absolute;
12808 .pretooltiparrow:before {
12809 background-color: #f7f7f7;
12810 border: 1px #ababab solid;
12813 position: absolute;
12818 -webkit-transform: rotate(45deg);
12819 -moz-transform: rotate(45deg);
12820 -ms-transform: rotate(45deg);
12821 -o-transform: rotate(45deg);
12823 ul.typeahead-list i {
12824 margin-left: -10px;
12827 [dir="rtl"] ul.typeahead-list i {
12829 margin-right: -10px;
12831 ul.typeahead-list {
12835 ul.typeahead-list > li > a {
12836 /** Firefox bug **/
12837 /* see https://github.com/jupyter/notebook/issues/559 */
12838 white-space: normal;
12840 ul.typeahead-list > li > a.pull-right {
12841 float: left !important;
12844 [dir="rtl"] .typeahead-list {
12847 .cmd-palette .modal-body {
12850 .cmd-palette form {
12853 .cmd-palette input {
12858 color: transparent;
12860 [dir="rtl"] .no-shortcut.pull-right {
12861 float: left !important;
12864 [dir="rtl"] .command-shortcut.pull-right {
12865 float: left !important;
12868 .command-shortcut:before {
12869 content: "(command mode)";
12870 padding-right: 3px;
12873 .edit-shortcut:before {
12875 padding-right: 3px;
12878 [dir="rtl"] .edit-shortcut.pull-right {
12879 float: left !important;
12882 #find-and-replace #replace-preview .match,
12883 #find-and-replace #replace-preview .insert {
12884 background-color: #BBDEFB;
12885 border-color: #90CAF9;
12886 border-style: solid;
12888 border-radius: 0px;
12890 [dir="ltr"] #find-and-replace .input-group-btn + .form-control {
12893 [dir="rtl"] #find-and-replace .input-group-btn + .form-control {
12894 border-right: none;
12896 #find-and-replace #replace-preview .replace .match {
12897 background-color: #FFCDD2;
12898 border-color: #EF9A9A;
12899 border-radius: 0px;
12901 #find-and-replace #replace-preview .replace .insert {
12902 background-color: #C8E6C9;
12903 border-color: #A5D6A7;
12904 border-radius: 0px;
12906 #find-and-replace #replace-preview {
12910 #find-and-replace #replace-preview pre {
12916 .terminal-app #header {
12918 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12919 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
12921 .terminal-app .terminal {
12924 font-family: monospace;
12928 border-radius: 2px;
12929 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
12930 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
12932 .terminal-app .terminal,
12933 .terminal-app .terminal dummy-screen {
12937 .terminal-app .terminal .xterm-rows {
12940 .terminal-app .terminal-cursor {
12944 .terminal-app #terminado-container {
12947 /*# sourceMappingURL=style.min.css.map */
12949 <style type="text/css">
12950 .highlight .hll { background-color: #ffffcc }
12951 .highlight { background: #f8f8f8; }
12952 .highlight .c { color: #408080; font-style: italic } /* Comment */
12953 .highlight .err { border: 1px solid #FF0000 } /* Error */
12954 .highlight .k { color: #008000; font-weight: bold } /* Keyword */
12955 .highlight .o { color: #666666 } /* Operator */
12956 .highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
12957 .highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
12958 .highlight .cp { color: #BC7A00 } /* Comment.Preproc */
12959 .highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
12960 .highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
12961 .highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
12962 .highlight .gd { color: #A00000 } /* Generic.Deleted */
12963 .highlight .ge { font-style: italic } /* Generic.Emph */
12964 .highlight .gr { color: #FF0000 } /* Generic.Error */
12965 .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
12966 .highlight .gi { color: #00A000 } /* Generic.Inserted */
12967 .highlight .go { color: #888888 } /* Generic.Output */
12968 .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
12969 .highlight .gs { font-weight: bold } /* Generic.Strong */
12970 .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
12971 .highlight .gt { color: #0044DD } /* Generic.Traceback */
12972 .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
12973 .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
12974 .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
12975 .highlight .kp { color: #008000 } /* Keyword.Pseudo */
12976 .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
12977 .highlight .kt { color: #B00040 } /* Keyword.Type */
12978 .highlight .m { color: #666666 } /* Literal.Number */
12979 .highlight .s { color: #BA2121 } /* Literal.String */
12980 .highlight .na { color: #7D9029 } /* Name.Attribute */
12981 .highlight .nb { color: #008000 } /* Name.Builtin */
12982 .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
12983 .highlight .no { color: #880000 } /* Name.Constant */
12984 .highlight .nd { color: #AA22FF } /* Name.Decorator */
12985 .highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
12986 .highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
12987 .highlight .nf { color: #0000FF } /* Name.Function */
12988 .highlight .nl { color: #A0A000 } /* Name.Label */
12989 .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
12990 .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
12991 .highlight .nv { color: #19177C } /* Name.Variable */
12992 .highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
12993 .highlight .w { color: #bbbbbb } /* Text.Whitespace */
12994 .highlight .mb { color: #666666 } /* Literal.Number.Bin */
12995 .highlight .mf { color: #666666 } /* Literal.Number.Float */
12996 .highlight .mh { color: #666666 } /* Literal.Number.Hex */
12997 .highlight .mi { color: #666666 } /* Literal.Number.Integer */
12998 .highlight .mo { color: #666666 } /* Literal.Number.Oct */
12999 .highlight .sa { color: #BA2121 } /* Literal.String.Affix */
13000 .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
13001 .highlight .sc { color: #BA2121 } /* Literal.String.Char */
13002 .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
13003 .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
13004 .highlight .s2 { color: #BA2121 } /* Literal.String.Double */
13005 .highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
13006 .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
13007 .highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
13008 .highlight .sx { color: #008000 } /* Literal.String.Other */
13009 .highlight .sr { color: #BB6688 } /* Literal.String.Regex */
13010 .highlight .s1 { color: #BA2121 } /* Literal.String.Single */
13011 .highlight .ss { color: #19177C } /* Literal.String.Symbol */
13012 .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
13013 .highlight .fm { color: #0000FF } /* Name.Function.Magic */
13014 .highlight .vc { color: #19177C } /* Name.Variable.Class */
13015 .highlight .vg { color: #19177C } /* Name.Variable.Global */
13016 .highlight .vi { color: #19177C } /* Name.Variable.Instance */
13017 .highlight .vm { color: #19177C } /* Name.Variable.Magic */
13018 .highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
13022 <style type="text/css">
13023 /* Overrides of notebook CSS for static HTML export */
13035 page-break-inside: avoid;
13037 div.output_wrapper {
13039 page-break-inside: avoid;
13043 page-break-inside: avoid;
13048 <!-- Custom stylesheet, it must be in the same directory as the html file -->
13049 <link rel="stylesheet" href="custom.css">
13051 <!-- Loading mathjax macro -->
13052 <!-- Load mathjax -->
13053 <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS_HTML"></script>
13054 <!-- MathJax configuration -->
13055 <script type="text/x-mathjax-config">
13056 MathJax.Hub.Config({
13058 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
13059 displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
13060 processEscapes: true,
13061 processEnvironments: true
13063 // Center justify equations in code and markdown cells. Elsewhere
13064 // we use CSS to left justify single line equations in code cells.
13065 displayAlign: 'center',
13067 styles: {'.MathJax_Display': {"margin": 0}},
13068 linebreaks: { automatic: true }
13072 <!-- End of mathjax configuration --></head>
13074 <div tabindex="-1" id="notebook" class="border-box-sizing">
13075 <div class="container" id="notebook-container">
13077 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13078 </div><div class="inner_cell">
13079 <div class="text_cell_render border-box-sizing rendered_html">
13080 <h1 id="Cerrect"><del>Cerrect</del><a class="anchor-link" href="#Cerrect">¶</a></h1><h1 id="Corroct"><del>Corroct</del><a class="anchor-link" href="#Corroct">¶</a></h1><h1 id="Correct-Programming">Correct Programming<a class="anchor-link" href="#Correct-Programming">¶</a></h1><p>Symbolic Logic in the Laws of Form â—‹ Python Expressions to Represent Forms â—‹ Reify Forms in an Environment â—‹ Building Circuits â—‹ Simplifying Expressions â—‹ SAT Solver â—‹ A Model of Computation</p>
13085 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13086 </div><div class="inner_cell">
13087 <div class="text_cell_render border-box-sizing rendered_html">
13088 <h1 id="Introduction">Introduction<a class="anchor-link" href="#Introduction">¶</a></h1><p>In 1969 George Spencer-Brown (GSB) published <a href="https://en.wikipedia.org/wiki/Laws_of_Form">"Laws of Form"</a> which presented a logical system based on a single action, a distinction, that is both an operation and a value. This notebook describes a Python implementation that mimics the Laws of Form notation and uses it to develop a model of computer circuits.</p>
13093 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13094 </div><div class="inner_cell">
13095 <div class="text_cell_render border-box-sizing rendered_html">
13096 <h2 id="The-Laws-of-Form">The Laws of Form<a class="anchor-link" href="#The-Laws-of-Form">¶</a></h2><p>See <a href="http://www.markability.net/">The Markable Mark</a>.</p>
13097 <h4 id="Arithmetic">Arithmetic<a class="anchor-link" href="#Arithmetic">¶</a></h4>
13102 <h4 id="Calculus">Calculus<a class="anchor-link" href="#Calculus">¶</a></h4>
13103 <pre><code>A((B)) = AB
13108 <p>I call these three laws the <strong>Bricken Basis</strong> after <a href="http://wbricken.com/">William Bricken</a> who figured out that the third law is complete with the other two. GSB had the first two laws and "Each Way" as the basis. (TODO: Find and include the references for all this.)</p>
13109 <p>(If anything here is unclear read <a href="http://www.markability.net/">The Markable Mark</a>. George Burnett-Stuart has done a fantastic job there explaining the <em>Laws of Form</em>.)</p>
13114 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13115 </div><div class="inner_cell">
13116 <div class="text_cell_render border-box-sizing rendered_html">
13117 <h2 id="Python-Sets-and-Strings-as-Laws-of-Form-Calculus-Expressions">Python Sets and Strings as Laws of Form Calculus Expressions<a class="anchor-link" href="#Python-Sets-and-Strings-as-Laws-of-Form-Calculus-Expressions">¶</a></h2><p>We can use data structures made solely out of Python <code>frozenset</code> and string objects to represent the forms of the Laws of Form notation. I'm going to use the terms "expression" and "form" interchangably in this document.</p>
13122 <div class="cell border-box-sizing code_cell rendered">
13123 <div class="input">
13124 <div class="prompt input_prompt">In [1]:</div>
13125 <div class="inner_cell">
13126 <div class="input_area">
13127 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">Form</span><span class="p">(</span><span class="nb">frozenset</span><span class="p">):</span>
13129 <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
13130 <span class="c1"># Because frozenset is immutable, and the contents are all string or frozenset,</span>
13131 <span class="c1"># we can cache the string repr of a form.</span>
13132 <span class="k">try</span><span class="p">:</span>
13133 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_str</span>
13134 <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
13135 <span class="bp">self</span><span class="o">.</span><span class="n">_str</span> <span class="o">=</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="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="bp">self</span><span class="p">)))</span>
13136 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_str</span>
13138 <span class="fm">__repr__</span> <span class="o">=</span> <span class="fm">__str__</span>
13141 <span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="o">*</span><span class="n">terms</span><span class="p">):</span>
13142 <span class="sd">'''Create a Form from terms.'''</span>
13143 <span class="k">return</span> <span class="n">Form</span><span class="p">([</span>
13144 <span class="n">term</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="p">(</span><span class="n">basestring</span><span class="p">,</span> <span class="n">Form</span><span class="p">))</span> <span class="k">else</span> <span class="n">F</span><span class="p">(</span><span class="o">*</span><span class="n">term</span><span class="p">)</span>
13145 <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">terms</span>
13146 <span class="p">])</span>
13154 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13155 </div><div class="inner_cell">
13156 <div class="text_cell_render border-box-sizing rendered_html">
13157 <p>Define a few variable names.</p>
13162 <div class="cell border-box-sizing code_cell rendered">
13163 <div class="input">
13164 <div class="prompt input_prompt">In [2]:</div>
13165 <div class="inner_cell">
13166 <div class="input_area">
13167 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
13175 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13176 </div><div class="inner_cell">
13177 <div class="text_cell_render border-box-sizing rendered_html">
13178 <p>Some examples of forms.</p>
13183 <div class="cell border-box-sizing code_cell rendered">
13184 <div class="input">
13185 <div class="prompt input_prompt">In [3]:</div>
13186 <div class="inner_cell">
13187 <div class="input_area">
13188 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">A</span> <span class="o">=</span> <span class="n">F</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="n">c</span><span class="p">)</span>
13189 <span class="n">A</span>
13196 <div class="output_wrapper">
13197 <div class="output">
13200 <div class="output_area">
13202 <div class="prompt output_prompt">Out[3]:</div>
13207 <div class="output_text output_subarea output_execute_result">
13217 <div class="cell border-box-sizing code_cell rendered">
13218 <div class="input">
13219 <div class="prompt input_prompt">In [4]:</div>
13220 <div class="inner_cell">
13221 <div class="input_area">
13222 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">B</span> <span class="o">=</span> <span class="n">F</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>
13223 <span class="n">B</span>
13230 <div class="output_wrapper">
13231 <div class="output">
13234 <div class="output_area">
13236 <div class="prompt output_prompt">Out[4]:</div>
13241 <div class="output_text output_subarea output_execute_result">
13242 <pre>(((c) b) a)</pre>
13251 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13252 </div><div class="inner_cell">
13253 <div class="text_cell_render border-box-sizing rendered_html">
13254 <p>Forms like <code>a b c</code> must be enclosed in a pair of nested containers like so <code>(( a b c ))</code>, this lets us treat them as a single (Python) object without inverting the logical value of the form.</p>
13259 <div class="cell border-box-sizing code_cell rendered">
13260 <div class="input">
13261 <div class="prompt input_prompt">In [5]:</div>
13262 <div class="inner_cell">
13263 <div class="input_area">
13264 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span> <span class="o">=</span> <span class="n">F</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="n">c</span><span class="p">))</span>
13265 <span class="n">C</span>
13272 <div class="output_wrapper">
13273 <div class="output">
13276 <div class="output_area">
13278 <div class="prompt output_prompt">Out[5]:</div>
13283 <div class="output_text output_subarea output_execute_result">
13284 <pre>((a b c))</pre>
13293 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13294 </div><div class="inner_cell">
13295 <div class="text_cell_render border-box-sizing rendered_html">
13296 <p>Duplicate terms in a form are automatically removed by <code>frozenset</code>.</p>
13301 <div class="cell border-box-sizing code_cell rendered">
13302 <div class="input">
13303 <div class="prompt input_prompt">In [6]:</div>
13304 <div class="inner_cell">
13305 <div class="input_area">
13306 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</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">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,))</span>
13313 <div class="output_wrapper">
13314 <div class="output">
13317 <div class="output_area">
13319 <div class="prompt output_prompt">Out[6]:</div>
13324 <div class="output_text output_subarea output_execute_result">
13334 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13335 </div><div class="inner_cell">
13336 <div class="text_cell_render border-box-sizing rendered_html">
13337 <p>Order is irrelevant, again due to <code>frozenset</code>.</p>
13342 <div class="cell border-box-sizing code_cell rendered">
13343 <div class="input">
13344 <div class="prompt input_prompt">In [7]:</div>
13345 <div class="inner_cell">
13346 <div class="input_area">
13347 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</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="n">c</span><span class="p">)</span> <span class="o">==</span> <span class="n">F</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="n">c</span><span class="p">)</span>
13354 <div class="output_wrapper">
13355 <div class="output">
13358 <div class="output_area">
13360 <div class="prompt output_prompt">Out[7]:</div>
13365 <div class="output_text output_subarea output_execute_result">
13375 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13376 </div><div class="inner_cell">
13377 <div class="text_cell_render border-box-sizing rendered_html">
13378 <p>It's prefectly okay to create forms out of other forms (not just strings.)</p>
13383 <div class="cell border-box-sizing code_cell rendered">
13384 <div class="input">
13385 <div class="prompt input_prompt">In [8]:</div>
13386 <div class="inner_cell">
13387 <div class="input_area">
13388 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</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">a</span><span class="p">)</span>
13395 <div class="output_wrapper">
13396 <div class="output">
13399 <div class="output_area">
13401 <div class="prompt output_prompt">Out[8]:</div>
13406 <div class="output_text output_subarea output_execute_result">
13407 <pre>(((((a b c))) (((c) b) a)) (a b c) a)</pre>
13416 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13417 </div><div class="inner_cell">
13418 <div class="text_cell_render border-box-sizing rendered_html">
13419 <h2 id="Mark-and-Void.">Mark and Void.<a class="anchor-link" href="#Mark-and-Void.">¶</a></h2>
13423 <div class="cell border-box-sizing code_cell rendered">
13424 <div class="input">
13425 <div class="prompt input_prompt">In [9]:</div>
13426 <div class="inner_cell">
13427 <div class="input_area">
13428 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Mark</span> <span class="o">=</span> <span class="n">F</span><span class="p">()</span>
13429 <span class="n">Mark</span>
13436 <div class="output_wrapper">
13437 <div class="output">
13440 <div class="output_area">
13442 <div class="prompt output_prompt">Out[9]:</div>
13447 <div class="output_text output_subarea output_execute_result">
13457 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13458 </div><div class="inner_cell">
13459 <div class="text_cell_render border-box-sizing rendered_html">
13460 <p>There is no way to represent Void directly in a programming language so we have to use the simplest Void-valued form instead.</p>
13465 <div class="cell border-box-sizing code_cell rendered">
13466 <div class="input">
13467 <div class="prompt input_prompt">In [10]:</div>
13468 <div class="inner_cell">
13469 <div class="input_area">
13470 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Void</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">Mark</span><span class="p">)</span>
13471 <span class="n">Void</span>
13478 <div class="output_wrapper">
13479 <div class="output">
13482 <div class="output_area">
13484 <div class="prompt output_prompt">Out[10]:</div>
13489 <div class="output_text output_subarea output_execute_result">
13499 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13500 </div><div class="inner_cell">
13501 <div class="text_cell_render border-box-sizing rendered_html">
13502 <h2 id="Environments">Environments<a class="anchor-link" href="#Environments">¶</a></h2><p>We can use a Python <code>dict</code> as a context or environment that supplies values (Mark or Void) for the names in a form.</p>
13507 <div class="cell border-box-sizing code_cell rendered">
13508 <div class="input">
13509 <div class="prompt input_prompt">In [11]:</div>
13510 <div class="inner_cell">
13511 <div class="input_area">
13512 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">env</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="n">Mark</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="n">Mark</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="n">Mark</span><span class="p">)</span>
13520 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13521 </div><div class="inner_cell">
13522 <div class="text_cell_render border-box-sizing rendered_html">
13523 <h2 id="The-reify(form,-environment)-Function">The <code>reify(form, environment)</code> Function<a class="anchor-link" href="#The-reify(form,-environment)-Function">¶</a></h2><p>Given forms with string variable names in them we want to be able to substitute values from an environment. If these values are Mark or Void the result will be a pure arithmentic form.</p>
13528 <div class="cell border-box-sizing code_cell rendered">
13529 <div class="input">
13530 <div class="prompt input_prompt">In [12]:</div>
13531 <div class="inner_cell">
13532 <div class="input_area">
13533 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">reify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">environment</span><span class="p">):</span>
13534 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
13535 <span class="k">return</span> <span class="n">environment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">form</span><span class="p">)</span>
13536 <span class="k">return</span> <span class="n">Form</span><span class="p">(</span><span class="n">reify</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">environment</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">form</span><span class="p">)</span>
13544 <div class="cell border-box-sizing code_cell rendered">
13545 <div class="input">
13546 <div class="prompt input_prompt">In [13]:</div>
13547 <div class="inner_cell">
13548 <div class="input_area">
13549 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">form</span> <span class="ow">in</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="n">C</span><span class="p">):</span>
13550 <span class="nb">print</span> <span class="n">form</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">reify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">env</span><span class="p">)</span>
13557 <div class="output_wrapper">
13558 <div class="output">
13561 <div class="output_area">
13563 <div class="prompt"></div>
13566 <div class="output_subarea output_stream output_stdout output_text">
13567 <pre>(a b c) ⟶ (())
13568 (((c) b) a) ⟶ (((()) ()) ())
13569 ((a b c)) ⟶ ((()))
13578 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13579 </div><div class="inner_cell">
13580 <div class="text_cell_render border-box-sizing rendered_html">
13581 <h2 id="The-void(form)-Function">The <code>void(form)</code> Function<a class="anchor-link" href="#The-void(form)-Function">¶</a></h2><p>Once the forms have been rendered to pure arithmetic we can use the <code>void()</code> function to find the value of each expression.</p>
13586 <div class="cell border-box-sizing code_cell rendered">
13587 <div class="input">
13588 <div class="prompt input_prompt">In [14]:</div>
13589 <div class="inner_cell">
13590 <div class="input_area">
13591 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">void</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
13592 <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="ow">not</span> <span class="n">void</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">form</span><span class="p">)</span>
13600 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13601 </div><div class="inner_cell">
13602 <div class="text_cell_render border-box-sizing rendered_html">
13603 <p>The <code>void()</code> function returns a Boolean value (Python <code>True</code> or <code>False</code>), for convenience let's write a function that returns the Mark or Void value of a form.</p>
13608 <div class="cell border-box-sizing code_cell rendered">
13609 <div class="input">
13610 <div class="prompt input_prompt">In [15]:</div>
13611 <div class="inner_cell">
13612 <div class="input_area">
13613 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">value_of</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">m</span><span class="o">=</span><span class="n">Mark</span><span class="p">,</span> <span class="n">v</span><span class="o">=</span><span class="n">Void</span><span class="p">):</span>
13614 <span class="k">return</span> <span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">v</span><span class="p">)[</span><span class="n">void</span><span class="p">(</span><span class="n">form</span><span class="p">)]</span>
13622 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13623 </div><div class="inner_cell">
13624 <div class="text_cell_render border-box-sizing rendered_html">
13625 <p>Now we can use the <code>void()</code> function (by way of <code>value_of()</code>) to calculate the base value of each expression structure.</p>
13630 <div class="cell border-box-sizing code_cell rendered">
13631 <div class="input">
13632 <div class="prompt input_prompt">In [16]:</div>
13633 <div class="inner_cell">
13634 <div class="input_area">
13635 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">form</span> <span class="ow">in</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="n">C</span><span class="p">):</span>
13636 <span class="n">arith</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">env</span><span class="p">)</span>
13637 <span class="nb">print</span> <span class="n">form</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">arith</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">value_of</span><span class="p">(</span><span class="n">arith</span><span class="p">)</span>
13644 <div class="output_wrapper">
13645 <div class="output">
13648 <div class="output_area">
13650 <div class="prompt"></div>
13653 <div class="output_subarea output_stream output_stdout output_text">
13654 <pre>(a b c) ⟶ (()) ⟶ (())
13655 (((c) b) a) ⟶ (((()) ()) ()) ⟶ (())
13656 ((a b c)) ⟶ ((())) ⟶ ()
13665 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13666 </div><div class="inner_cell">
13667 <div class="text_cell_render border-box-sizing rendered_html">
13668 <h2 id="All-Possible-Environments">All Possible Environments<a class="anchor-link" href="#All-Possible-Environments">¶</a></h2><p>For $n$ variables there are $2^n$ possible assignments of the two values of Mark and Void. If we generate environments that each contain one of the possible assignments of names to the base value we can evaluate an expression containing those names and compute its value.</p>
13673 <div class="cell border-box-sizing code_cell rendered">
13674 <div class="input">
13675 <div class="prompt input_prompt">In [17]:</div>
13676 <div class="inner_cell">
13677 <div class="input_area">
13678 <div class=" highlight hl-ipython2"><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="p">,</span> <span class="n">izip</span>
13681 <span class="n">BASE</span> <span class="o">=</span> <span class="n">Void</span><span class="p">,</span> <span class="n">Mark</span>
13684 <span class="k">def</span> <span class="nf">environments_of_variables</span><span class="p">(</span><span class="o">*</span><span class="n">variables</span><span class="p">):</span>
13685 <span class="n">universe</span> <span class="o">=</span> <span class="p">[</span><span class="n">BASE</span><span class="p">]</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">variables</span><span class="p">)</span>
13686 <span class="k">for</span> <span class="n">values</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="o">*</span><span class="n">universe</span><span class="p">):</span>
13687 <span class="k">yield</span> <span class="nb">dict</span><span class="p">(</span><span class="n">izip</span><span class="p">(</span><span class="n">variables</span><span class="p">,</span> <span class="n">values</span><span class="p">))</span>
13690 <span class="n">envs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">environments_of_variables</span><span class="p">(</span><span class="o">*</span><span class="s1">'abc'</span><span class="p">))</span>
13693 <span class="n">envs</span>
13700 <div class="output_wrapper">
13701 <div class="output">
13704 <div class="output_area">
13706 <div class="prompt output_prompt">Out[17]:</div>
13711 <div class="output_text output_subarea output_execute_result">
13712 <pre>[{'a': (()), 'b': (()), 'c': (())},
13713 {'a': (()), 'b': (()), 'c': ()},
13714 {'a': (()), 'b': (), 'c': (())},
13715 {'a': (()), 'b': (), 'c': ()},
13716 {'a': (), 'b': (()), 'c': (())},
13717 {'a': (), 'b': (()), 'c': ()},
13718 {'a': (), 'b': (), 'c': (())},
13719 {'a': (), 'b': (), 'c': ()}]</pre>
13728 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13729 </div><div class="inner_cell">
13730 <div class="text_cell_render border-box-sizing rendered_html">
13731 <p>This is a bit hard to read, so let's define a helper function to convert an environment to a string format.</p>
13736 <div class="cell border-box-sizing code_cell rendered">
13737 <div class="input">
13738 <div class="prompt input_prompt">In [18]:</div>
13739 <div class="inner_cell">
13740 <div class="input_area">
13741 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">format_env</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">m</span><span class="o">=</span><span class="s1">'()'</span><span class="p">,</span> <span class="n">v</span><span class="o">=</span><span class="s1">' '</span><span class="p">):</span>
13742 <span class="k">return</span> <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">v</span><span class="p">,</span> <span class="n">m</span><span class="p">)[</span><span class="ow">not</span> <span class="n">env</span><span class="p">[</span><span class="n">k</span><span class="p">]]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">env</span><span class="p">))</span>
13744 <span class="c1"># Note that Mark is an empty frozenset so in a Boolean context in Python it is False,</span>
13745 <span class="c1"># likewise Void is a set with one member, so Python considers it True in a Boolean context.</span>
13746 <span class="c1"># The `not` in the expression is just to force such a Boolean context, and we compensate</span>
13747 <span class="c1"># by putting `v` in the zero-is-False position in the indexed tuple.</span>
13755 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13756 </div><div class="inner_cell">
13757 <div class="text_cell_render border-box-sizing rendered_html">
13758 <p>Now we can print out the environments in a table. Notice that it looks just like a list of the eight three-bit binary numbers.</p>
13763 <div class="cell border-box-sizing code_cell rendered">
13764 <div class="input">
13765 <div class="prompt input_prompt">In [19]:</div>
13766 <div class="inner_cell">
13767 <div class="input_area">
13768 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="s1">'i a b c i in Binary'</span>
13769 <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">env</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">envs</span><span class="p">):</span>
13770 <span class="nb">print</span> <span class="n">i</span><span class="p">,</span> <span class="n">format_env</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">v</span><span class="o">=</span><span class="s1">'--'</span><span class="p">),</span> <span class="s1">'</span><span class="si">%3s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="nb">bin</span><span class="p">(</span><span class="n">i</span><span class="p">)[</span><span class="mi">2</span><span class="p">:],)</span>
13777 <div class="output_wrapper">
13778 <div class="output">
13781 <div class="output_area">
13783 <div class="prompt"></div>
13786 <div class="output_subarea output_stream output_stdout output_text">
13787 <pre>i a b c i in Binary
13804 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13805 </div><div class="inner_cell">
13806 <div class="text_cell_render border-box-sizing rendered_html">
13807 <h2 id="Reify-the-Forms-with-Each-Meaning">Reify the Forms with Each Meaning<a class="anchor-link" href="#Reify-the-Forms-with-Each-Meaning">¶</a></h2><p>Let's pick one of the expressions and iterate through the environments showing the result of reifying that expression in that environment.</p>
13812 <div class="cell border-box-sizing code_cell rendered">
13813 <div class="input">
13814 <div class="prompt input_prompt">In [20]:</div>
13815 <div class="inner_cell">
13816 <div class="input_area">
13817 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">B</span>
13818 <span class="nb">print</span> <span class="s1">'-----------'</span>
13819 <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">env</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">envs</span><span class="p">):</span>
13820 <span class="n">e</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">env</span><span class="p">)</span>
13821 <span class="nb">print</span> <span class="n">i</span><span class="p">,</span> <span class="n">format_env</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">v</span><span class="o">=</span><span class="s1">'--'</span><span class="p">),</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">value_of</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">m</span><span class="o">=</span><span class="s1">'()'</span><span class="p">,</span> <span class="n">v</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span>
13828 <div class="output_wrapper">
13829 <div class="output">
13832 <div class="output_area">
13834 <div class="prompt"></div>
13837 <div class="output_subarea output_stream output_stdout output_text">
13840 0 -- -- -- ⟶ ((((())) (())) (())) ⟶ ()
13841 1 -- -- () ⟶ (((())) (())) ⟶
13842 2 -- () -- ⟶ ((((())) ()) (())) ⟶ ()
13843 3 -- () () ⟶ (((()) ()) (())) ⟶ ()
13844 4 () -- -- ⟶ ((((())) (())) ()) ⟶
13845 5 () -- () ⟶ (((())) ()) ⟶
13846 6 () () -- ⟶ ((((())) ()) ()) ⟶
13847 7 () () () ⟶ (((()) ()) ()) ⟶
13856 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13857 </div><div class="inner_cell">
13858 <div class="text_cell_render border-box-sizing rendered_html">
13859 <h2 id="Truth-Table">Truth Table<a class="anchor-link" href="#Truth-Table">¶</a></h2><p>Let's render the above as a <a href="https://en.wikipedia.org/wiki/Truth_table">Truth Table</a>.</p>
13864 <div class="cell border-box-sizing code_cell rendered">
13865 <div class="input">
13866 <div class="prompt input_prompt">In [21]:</div>
13867 <div class="inner_cell">
13868 <div class="input_area">
13869 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">truth_table_3</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
13870 <span class="nb">print</span> <span class="n">expression</span>
13871 <span class="nb">print</span> <span class="s1">' a b c | Value'</span>
13872 <span class="nb">print</span> <span class="s1">'---------+------'</span>
13873 <span class="k">for</span> <span class="n">E</span> <span class="ow">in</span> <span class="n">envs</span><span class="p">:</span>
13874 <span class="n">e</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">E</span><span class="p">)</span>
13875 <span class="nb">print</span> <span class="n">format_env</span><span class="p">(</span><span class="n">E</span><span class="p">),</span> <span class="s1">'|'</span><span class="p">,</span> <span class="n">value_of</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">m</span><span class="o">=</span><span class="s1">'()'</span><span class="p">,</span> <span class="n">v</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span>
13883 <div class="cell border-box-sizing code_cell rendered">
13884 <div class="input">
13885 <div class="prompt input_prompt">In [22]:</div>
13886 <div class="inner_cell">
13887 <div class="input_area">
13888 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table_3</span><span class="p">(</span><span class="n">B</span><span class="p">)</span>
13895 <div class="output_wrapper">
13896 <div class="output">
13899 <div class="output_area">
13901 <div class="prompt"></div>
13904 <div class="output_subarea output_stream output_stdout output_text">
13924 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13925 </div><div class="inner_cell">
13926 <div class="text_cell_render border-box-sizing rendered_html">
13927 <p>This makes it clear that <em>each expression in Laws of Form calculus is describing a digital Boolean circuit</em>. The names are its inputs and its Void/Mark value is its output. Each boundary is a <a href="https://en.wikipedia.org/wiki/Logical_NOR">multi-input <strong>NOR</strong> gate</a>, known as the Peirce arrow or Quine dagger (See <a href="https://en.wikipedia.org/wiki/Sheffer_stroke">Sheffer stroke</a> and <a href="https://en.wikipedia.org/wiki/NOR_gate">NOR gate</a>.) Instead of two Boolean values there is only one value and non-existance.</p>
13932 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13933 </div><div class="inner_cell">
13934 <div class="text_cell_render border-box-sizing rendered_html">
13935 <h1 id="Let's-build-Circuits">Let's build Circuits<a class="anchor-link" href="#Let's-build-Circuits">¶</a></h1><p>In order to work with expressions as digital circuits, let's define some helper functions that will create logic circuits out of simpler forms. The names of the functions below reflect the choice of Mark as Boolean <code>True</code> but this is <a href="#Appendix:-Duals">just a convention</a>.</p>
13940 <div class="cell border-box-sizing code_cell rendered">
13941 <div class="input">
13942 <div class="prompt input_prompt">In [23]:</div>
13943 <div class="inner_cell">
13944 <div class="input_area">
13945 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">nor</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">bits</span><span class="p">:</span> <span class="n">F</span><span class="p">(</span><span class="o">*</span><span class="n">bits</span><span class="p">)</span>
13946 <span class="n">or_</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">bits</span><span class="p">:</span> <span class="n">F</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span>
13947 <span class="n">and_</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">bits</span><span class="p">:</span> <span class="n">Form</span><span class="p">(</span><span class="n">F</span><span class="p">(</span><span class="n">bit</span><span class="p">)</span> <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="n">bits</span><span class="p">)</span>
13948 <span class="n">nand</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">bits</span><span class="p">:</span> <span class="n">nor</span><span class="p">(</span><span class="n">and_</span><span class="p">(</span><span class="o">*</span><span class="n">bits</span><span class="p">))</span>
13949 <span class="n">nxor</span> <span class="o">=</span> <span class="n">eqiv</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">F</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">a</span><span class="p">,),</span> <span class="n">b</span><span class="p">))</span>
13950 <span class="n">xor</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">F</span><span class="p">(</span><span class="n">nxor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">))</span>
13952 <span class="c1"># To build logical expressions with Void as Boolean True use these functions.</span>
13953 <span class="n">anti_nor</span> <span class="o">=</span> <span class="n">nand</span>
13954 <span class="n">anti_or</span> <span class="o">=</span> <span class="n">and_</span>
13955 <span class="n">anti_and</span> <span class="o">=</span> <span class="n">or_</span>
13956 <span class="n">anti_nand</span> <span class="o">=</span> <span class="n">nor</span>
13957 <span class="n">anti_eqiv</span> <span class="o">=</span> <span class="n">xor</span>
13958 <span class="n">anti_xor</span> <span class="o">=</span> <span class="n">eqiv</span>
13966 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
13967 </div><div class="inner_cell">
13968 <div class="text_cell_render border-box-sizing rendered_html">
13969 <p>Some examples:</p>
13974 <div class="cell border-box-sizing code_cell rendered">
13975 <div class="input">
13976 <div class="prompt input_prompt">In [24]:</div>
13977 <div class="inner_cell">
13978 <div class="input_area">
13979 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
13982 <span class="n">some_expressions</span> <span class="o">=</span> <span class="p">(</span>
13983 <span class="n">nor</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="n">c</span><span class="p">),</span>
13984 <span class="n">or_</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="n">c</span><span class="p">),</span>
13985 <span class="n">and_</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="n">c</span><span class="p">),</span>
13986 <span class="n">nand</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="n">c</span><span class="p">),</span>
13987 <span class="n">xor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span>
13988 <span class="n">eqiv</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span>
13989 <span class="n">xor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">xor</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">)),</span>
13990 <span class="p">)</span>
13993 <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">some_expressions</span><span class="p">:</span>
13994 <span class="nb">print</span> <span class="n">expression</span>
14001 <div class="output_wrapper">
14002 <div class="output">
14005 <div class="output_area">
14007 <div class="prompt"></div>
14010 <div class="output_subarea output_stream output_stdout output_text">
14015 ((((a) b) ((b) a)))
14017 ((((((((b) c) ((c) b)))) a) (((((b) c) ((c) b))) (a))))
14026 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14027 </div><div class="inner_cell">
14028 <div class="text_cell_render border-box-sizing rendered_html">
14029 <p>And let's rewrite the <code>truth_table_3()</code> function to make it work for any number of variables.</p>
14034 <div class="cell border-box-sizing code_cell rendered">
14035 <div class="input">
14036 <div class="prompt input_prompt">In [25]:</div>
14037 <div class="inner_cell">
14038 <div class="input_area">
14039 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">yield_variables_of</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
14040 <span class="sd">'''Yield all string members of an expression.'''</span>
14041 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
14042 <span class="k">yield</span> <span class="n">expression</span>
14043 <span class="k">else</span><span class="p">:</span>
14044 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">expression</span><span class="p">:</span>
14045 <span class="k">for</span> <span class="n">leaf</span> <span class="ow">in</span> <span class="n">yield_variables_of</span><span class="p">(</span><span class="n">inner</span><span class="p">):</span>
14046 <span class="k">yield</span> <span class="n">leaf</span>
14049 <span class="k">def</span> <span class="nf">collect_names</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
14050 <span class="sd">'''Return a set of the variables mentioned in an expression.'''</span>
14051 <span class="k">return</span> <span class="nb">set</span><span class="p">(</span><span class="n">yield_variables_of</span><span class="p">(</span><span class="n">expression</span><span class="p">))</span>
14054 <span class="k">def</span> <span class="nf">truth_table</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
14055 <span class="sd">'''Print a truth table for an expression.'''</span>
14056 <span class="n">names</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">collect_names</span><span class="p">(</span><span class="n">expression</span><span class="p">))</span>
14057 <span class="n">header</span> <span class="o">=</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">names</span><span class="p">)</span>
14058 <span class="n">n</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">header</span><span class="p">)</span>
14059 <span class="n">header</span> <span class="o">+=</span> <span class="s1">' | Value'</span>
14060 <span class="nb">print</span> <span class="n">expression</span>
14061 <span class="nb">print</span> <span class="n">header</span>
14062 <span class="nb">print</span> <span class="s1">'-'</span> <span class="o">*</span> <span class="n">n</span> <span class="o">+</span> <span class="s1">'+------'</span>
14063 <span class="k">for</span> <span class="n">env</span> <span class="ow">in</span> <span class="n">environments_of_variables</span><span class="p">(</span><span class="o">*</span><span class="n">names</span><span class="p">):</span>
14064 <span class="n">e</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">env</span><span class="p">)</span>
14065 <span class="nb">print</span> <span class="n">format_env</span><span class="p">(</span><span class="n">env</span><span class="p">),</span> <span class="s1">'|'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'()'</span><span class="p">,</span> <span class="s1">''</span><span class="p">][</span><span class="n">void</span><span class="p">(</span><span class="n">e</span><span class="p">)]</span>
14073 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14074 </div><div class="inner_cell">
14075 <div class="text_cell_render border-box-sizing rendered_html">
14076 <p>We can use this <code>truth_table()</code> function to examine the expressions we created above.</p>
14081 <div class="cell border-box-sizing code_cell rendered">
14082 <div class="input">
14083 <div class="prompt input_prompt">In [26]:</div>
14084 <div class="inner_cell">
14085 <div class="input_area">
14086 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</span><span class="p">(</span><span class="n">nor</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="n">c</span><span class="p">))</span>
14093 <div class="output_wrapper">
14094 <div class="output">
14097 <div class="output_area">
14099 <div class="prompt"></div>
14102 <div class="output_subarea output_stream output_stdout output_text">
14122 <div class="cell border-box-sizing code_cell rendered">
14123 <div class="input">
14124 <div class="prompt input_prompt">In [27]:</div>
14125 <div class="inner_cell">
14126 <div class="input_area">
14127 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</span><span class="p">(</span><span class="n">or_</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="n">c</span><span class="p">))</span>
14134 <div class="output_wrapper">
14135 <div class="output">
14138 <div class="output_area">
14140 <div class="prompt"></div>
14143 <div class="output_subarea output_stream output_stdout output_text">
14163 <div class="cell border-box-sizing code_cell rendered">
14164 <div class="input">
14165 <div class="prompt input_prompt">In [28]:</div>
14166 <div class="inner_cell">
14167 <div class="input_area">
14168 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</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="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span>
14175 <div class="output_wrapper">
14176 <div class="output">
14179 <div class="output_area">
14181 <div class="prompt"></div>
14184 <div class="output_subarea output_stream output_stdout output_text">
14204 <div class="cell border-box-sizing code_cell rendered">
14205 <div class="input">
14206 <div class="prompt input_prompt">In [29]:</div>
14207 <div class="inner_cell">
14208 <div class="input_area">
14209 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</span><span class="p">(</span><span class="n">xor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">))</span>
14216 <div class="output_wrapper">
14217 <div class="output">
14220 <div class="output_area">
14222 <div class="prompt"></div>
14225 <div class="output_subarea output_stream output_stdout output_text">
14226 <pre>((((a) b) ((b) a)))
14241 <div class="cell border-box-sizing code_cell rendered">
14242 <div class="input">
14243 <div class="prompt input_prompt">In [30]:</div>
14244 <div class="inner_cell">
14245 <div class="input_area">
14246 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</span><span class="p">(</span><span class="n">eqiv</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">))</span>
14253 <div class="output_wrapper">
14254 <div class="output">
14257 <div class="output_area">
14259 <div class="prompt"></div>
14262 <div class="output_subarea output_stream output_stdout output_text">
14263 <pre>(((a) b) ((b) a))
14278 <div class="cell border-box-sizing code_cell rendered">
14279 <div class="input">
14280 <div class="prompt input_prompt">In [31]:</div>
14281 <div class="inner_cell">
14282 <div class="input_area">
14283 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</span><span class="p">(</span><span class="n">xor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">xor</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">)))</span>
14290 <div class="output_wrapper">
14291 <div class="output">
14294 <div class="output_area">
14296 <div class="prompt"></div>
14299 <div class="output_subarea output_stream output_stdout output_text">
14300 <pre>((((((((b) c) ((c) b)))) a) (((((b) c) ((c) b))) (a))))
14319 <div class="cell border-box-sizing code_cell rendered">
14320 <div class="input">
14321 <div class="prompt input_prompt">In [32]:</div>
14322 <div class="inner_cell">
14323 <div class="input_area">
14324 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">E1</span> <span class="o">=</span> <span class="n">and_</span><span class="p">(</span>
14325 <span class="n">or_</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="n">b</span><span class="p">),</span> <span class="n">and_</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">),</span> <span class="n">and_</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">a</span><span class="p">)),</span> <span class="c1"># Any two variables...</span>
14326 <span class="n">nand</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="n">c</span><span class="p">)</span> <span class="c1"># ...but not all three.</span>
14327 <span class="p">)</span>
14328 <span class="n">truth_table</span><span class="p">(</span><span class="n">E1</span><span class="p">)</span>
14335 <div class="output_wrapper">
14336 <div class="output">
14339 <div class="output_area">
14341 <div class="prompt"></div>
14344 <div class="output_subarea output_stream output_stdout output_text">
14345 <pre>((((((a) (b)) ((a) (c)) ((b) (c))))) ((((a) (b) (c)))))
14364 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14365 </div><div class="inner_cell">
14366 <div class="text_cell_render border-box-sizing rendered_html">
14367 <p>This is a <a href="https://en.wikipedia.org/wiki/Brute-force_search">brute-force</a> <a href="https://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT</a> <a href="https://en.wikipedia.org/wiki/Boolean_satisfiability_problem#Algorithms_for_solving_SAT">solver</a> that doesn't even bother to stop once it's found a solution.</p>
14372 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14373 </div><div class="inner_cell">
14374 <div class="text_cell_render border-box-sizing rendered_html">
14375 <h2 id="Expressions-from-Truth-Tables">Expressions from Truth Tables<a class="anchor-link" href="#Expressions-from-Truth-Tables">¶</a></h2><p>Sometimes we will have a function for which we know the behavior (truth table) but not an expression and we want the expression. For example, imagine that we didn't just create the expression for this table:</p>
14377 <pre><code> a b c | Value
14389 <h3 id="Each-Row-can-be-Represented-as-an-Expression">Each Row can be Represented as an Expression<a class="anchor-link" href="#Each-Row-can-be-Represented-as-an-Expression">¶</a></h3><p>To write an expression for this table, first we should understand that each row can be represented as an expression.</p>
14391 <pre><code> ⟶ ( a b c )
14394 () () ⟶ ( a (b) (c))
14396 () () ⟶ ((a) b (c))
14397 () () ⟶ ((a) (b) c )
14398 () () () ⟶ ((a) (b) (c))
14401 <p>Each of the above expressions will be true (Mark-valued) for only one possible combination of the three input variables. For example, let's look at the sixth expression above:</p>
14406 <div class="cell border-box-sizing code_cell rendered">
14407 <div class="input">
14408 <div class="prompt input_prompt">In [33]:</div>
14409 <div class="inner_cell">
14410 <div class="input_area">
14411 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">e6</span> <span class="o">=</span> <span class="n">F</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="p">(</span><span class="n">c</span><span class="p">,))</span>
14412 <span class="n">truth_table</span><span class="p">(</span><span class="n">e6</span><span class="p">)</span>
14419 <div class="output_wrapper">
14420 <div class="output">
14423 <div class="output_area">
14425 <div class="prompt"></div>
14428 <div class="output_subarea output_stream output_stdout output_text">
14448 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14449 </div><div class="inner_cell">
14450 <div class="text_cell_render border-box-sizing rendered_html">
14451 <p>To make an expression that is Mark-valued for just certain rows of the table, pick those rows' expressions,</p>
14453 <pre><code> () () | ( a (b) (c))
14454 () () | ((a) b (c))
14455 () () | ((a) (b) c )
14458 <p>And write them down as terms in an <strong>OR</strong> expression:</p>
14460 <pre><code>E = (a(b)(c)) ((a)b(c)) ((a)(b)c)
14463 <p>In conventional notation this is called <a href="https://en.wikipedia.org/wiki/Disjunctive_normal_form">Disjunctive normal form</a>:</p>
14465 <pre><code>E = (¬a ∧ b ∧ c) ∨ (a ∧ ¬b ∧ c) ∨ (a ∧ b ∧ ¬c)
14468 <p>Here it is in action:</p>
14473 <div class="cell border-box-sizing code_cell rendered">
14474 <div class="input">
14475 <div class="prompt input_prompt">In [34]:</div>
14476 <div class="inner_cell">
14477 <div class="input_area">
14478 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">e4</span> <span class="o">=</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>
14479 <span class="n">e6</span> <span class="o">=</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="p">(</span><span class="n">c</span><span class="p">,))</span>
14480 <span class="n">e7</span> <span class="o">=</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">c</span> <span class="p">)</span>
14482 <span class="n">E2</span> <span class="o">=</span> <span class="n">or_</span><span class="p">(</span><span class="n">e4</span><span class="p">,</span> <span class="n">e6</span><span class="p">,</span> <span class="n">e7</span><span class="p">)</span>
14484 <span class="n">truth_table</span><span class="p">(</span><span class="n">E2</span><span class="p">)</span>
14491 <div class="output_wrapper">
14492 <div class="output">
14495 <div class="output_area">
14497 <div class="prompt"></div>
14500 <div class="output_subarea output_stream output_stdout output_text">
14501 <pre>((((a) (b) c) ((a) (c) b) ((b) (c) a)))
14520 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14521 </div><div class="inner_cell">
14522 <div class="text_cell_render border-box-sizing rendered_html">
14523 <h3 id="Equivalence">Equivalence<a class="anchor-link" href="#Equivalence">¶</a></h3><p>Note that the expression E2 above is equivalent to the ealier expression E1 that has the same truth table, in other words:</p>
14525 <pre><code>((((((a) (b)) ((b) (c)) ((c) (a))))) ((((a) (b) (c)))))
14530 <pre><code>(((a (b) (c)) ((a) b (c)) ((a) (b) c)))
14533 <p>We can demonstrate this equivalence by evaluating the expression formed by <code>eqiv()</code> from these two.</p>
14534 <p>For every environment (from the set of possible values for the variables) if both expressions have the same value when evaluated then the <code>eqiv()</code> of those expressions will be Mark-valued (true in our chosen context.)</p>
14539 <div class="cell border-box-sizing code_cell rendered">
14540 <div class="input">
14541 <div class="prompt input_prompt">In [35]:</div>
14542 <div class="inner_cell">
14543 <div class="input_area">
14544 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</span><span class="p">(</span><span class="n">eqiv</span><span class="p">(</span><span class="n">E1</span><span class="p">,</span> <span class="n">E2</span><span class="p">))</span>
14551 <div class="output_wrapper">
14552 <div class="output">
14555 <div class="output_area">
14557 <div class="prompt"></div>
14560 <div class="output_subarea output_stream output_stdout output_text">
14561 <pre>(((((((((a) (b)) ((a) (c)) ((b) (c))))) ((((a) (b) (c)))))) ((((a) (b) c) ((a) (c) b) ((b) (c) a)))) (((((((a) (b)) ((a) (c)) ((b) (c))))) ((((a) (b) (c))))) (((((a) (b) c) ((a) (c) b) ((b) (c) a))))))
14580 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14581 </div><div class="inner_cell">
14582 <div class="text_cell_render border-box-sizing rendered_html">
14583 <p>The truth table above shows that the equivalence expression is true (Mark-valued by our current convention) for all possible assignments of Mark/Void to the three variables <code>a</code>, <code>b</code>, and <code>c</code>. This indicates that the expression is a <strong>tautology</strong>.</p>
14588 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14589 </div><div class="inner_cell">
14590 <div class="text_cell_render border-box-sizing rendered_html">
14591 <h2 id="Half-Bit-Adder"><a href="https://en.wikipedia.org/wiki/Adder_%28electronics%29#Half_adder">Half-Bit Adder</a><a class="anchor-link" href="#Half-Bit-Adder">¶</a></h2><p>If you have two binary digits ("bits") and you are interested in the (binary) sum of these digits you will need two circuits, one for the "ones place" and one for the "twos place" or "carry bit".</p>
14594 <pre><code>a b | c s
14602 <p>Treating each output column ('c' for carry, 's' for sum) as a single expression, it's easy to see that the carry bit is just <strong>AND</strong> and the sum bit is just <strong>XOR</strong> of the two input bits.</p>
14607 <div class="cell border-box-sizing code_cell rendered">
14608 <div class="input">
14609 <div class="prompt input_prompt">In [36]:</div>
14610 <div class="inner_cell">
14611 <div class="input_area">
14612 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="s1">'ab'</span>
14615 <span class="n">half_bit_adder</span> <span class="o">=</span> <span class="p">{</span>
14616 <span class="s1">'Sum'</span><span class="p">:</span> <span class="n">xor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span>
14617 <span class="s1">'Carry'</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="n">b</span><span class="p">),</span>
14618 <span class="p">}</span>
14621 <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">expr</span> <span class="ow">in</span> <span class="n">half_bit_adder</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
14622 <span class="nb">print</span> <span class="n">name</span>
14623 <span class="n">truth_table</span><span class="p">(</span><span class="n">expr</span><span class="p">)</span>
14624 <span class="nb">print</span>
14631 <div class="output_wrapper">
14632 <div class="output">
14635 <div class="output_area">
14637 <div class="prompt"></div>
14640 <div class="output_subarea output_stream output_stdout output_text">
14651 ((((a) b) ((b) a)))
14667 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14668 </div><div class="inner_cell">
14669 <div class="text_cell_render border-box-sizing rendered_html">
14670 <h2 id="Full-bit-Adder"><a href="https://en.wikipedia.org/wiki/Adder_%28electronics%29#Full_adder">Full-bit Adder</a><a class="anchor-link" href="#Full-bit-Adder">¶</a></h2><p>In order to add two multi-bit binary numbers we need adder circuits that are designed to work with <em>three</em> input bits: the two bits to add together and a carry bit from the previous addition:</p>
14672 <pre><code> a b Cin Sum Cout
14683 <p>Looking back at our table of three-variable expressions:</p>
14685 <pre><code> ⟶ ( a b c )
14688 () () ⟶ ( a (b) (c))
14690 () () ⟶ ((a) b (c))
14691 () () ⟶ ((a) (b) c )
14692 () () () ⟶ ((a) (b) (c))
14695 <p>We can easily determine expressions for sum and carry:</p>
14697 <pre><code>Sum = (a b (c)) (a (b) c) ((a) b c) ((a) (b) (c))
14699 Cout = (a (b) (c)) ((a) b (c)) ((a) (b) c) ((a) (b) (c))</code></pre>
14704 <div class="cell border-box-sizing code_cell rendered">
14705 <div class="input">
14706 <div class="prompt input_prompt">In [37]:</div>
14707 <div class="inner_cell">
14708 <div class="input_area">
14709 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Sum</span> <span class="o">=</span> <span class="n">F</span><span class="p">((</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="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">c</span><span class="p">),</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="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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),)</span>
14710 <span class="n">Carry</span> <span class="o">=</span> <span class="n">F</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="p">((</span><span class="n">a</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="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">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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),)</span>
14718 <div class="cell border-box-sizing code_cell rendered">
14719 <div class="input">
14720 <div class="prompt input_prompt">In [38]:</div>
14721 <div class="inner_cell">
14722 <div class="input_area">
14723 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="s1">'Sum'</span>
14724 <span class="n">truth_table</span><span class="p">(</span><span class="n">Sum</span><span class="p">)</span>
14725 <span class="nb">print</span>
14726 <span class="nb">print</span> <span class="s1">'Carry'</span>
14727 <span class="n">truth_table</span><span class="p">(</span><span class="n">Carry</span><span class="p">)</span>
14734 <div class="output_wrapper">
14735 <div class="output">
14738 <div class="output_area">
14740 <div class="prompt"></div>
14743 <div class="output_subarea output_stream output_stdout output_text">
14745 ((((a) (b) (c)) ((a) b c) ((b) a c) ((c) a b)))
14758 ((((a) (b) (c)) ((a) (b) c) ((a) (c) b) ((b) (c) a)))
14777 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14778 </div><div class="inner_cell">
14779 <div class="text_cell_render border-box-sizing rendered_html">
14780 <p>Let's make a <code>full_bit_adder()</code> function that can define new expressions in terms of variables (or expressions) passed into it.</p>
14785 <div class="cell border-box-sizing code_cell rendered">
14786 <div class="input">
14787 <div class="prompt input_prompt">In [39]:</div>
14788 <div class="inner_cell">
14789 <div class="input_area">
14790 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">full_bit_adder</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="n">c</span><span class="p">):</span>
14791 <span class="k">return</span> <span class="p">(</span>
14792 <span class="n">F</span><span class="p">((</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="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">c</span><span class="p">),</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="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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),),</span>
14793 <span class="n">F</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="p">((</span><span class="n">a</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="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">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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),),</span>
14794 <span class="p">)</span>
14802 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14803 </div><div class="inner_cell">
14804 <div class="text_cell_render border-box-sizing rendered_html">
14805 <p>Now we can chain it to make a set of circuits that define together an eight-bit adder circuit with carry.</p>
14810 <div class="cell border-box-sizing code_cell rendered">
14811 <div class="input">
14812 <div class="prompt input_prompt">In [40]:</div>
14813 <div class="inner_cell">
14814 <div class="input_area">
14815 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum0</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'b0'</span><span class="p">,</span> <span class="s1">'Cin'</span><span class="p">)</span>
14816 <span class="n">sum1</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14817 <span class="n">sum2</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14818 <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a3'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14819 <span class="n">sum4</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a4'</span><span class="p">,</span> <span class="s1">'b4'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14820 <span class="n">sum5</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a5'</span><span class="p">,</span> <span class="s1">'b5'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14821 <span class="n">sum6</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a6'</span><span class="p">,</span> <span class="s1">'b6'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14822 <span class="n">sum7</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a7'</span><span class="p">,</span> <span class="s1">'b7'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14830 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14831 </div><div class="inner_cell">
14832 <div class="text_cell_render border-box-sizing rendered_html">
14833 <p>Unfortunately, the sizes of the resulting expression explode:</p>
14838 <div class="cell border-box-sizing code_cell rendered">
14839 <div class="input">
14840 <div class="prompt input_prompt">In [41]:</div>
14841 <div class="inner_cell">
14842 <div class="input_area">
14843 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">map</span><span class="p">(</span><span class="nb">len</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="p">(</span><span class="n">sum0</span><span class="p">,</span> <span class="n">sum1</span><span class="p">,</span> <span class="n">sum2</span><span class="p">,</span> <span class="n">sum3</span><span class="p">,</span> <span class="n">sum4</span><span class="p">,</span> <span class="n">sum5</span><span class="p">,</span> <span class="n">sum6</span><span class="p">,</span> <span class="n">sum7</span><span class="p">,</span> <span class="n">cout</span><span class="p">)))</span>
14850 <div class="output_wrapper">
14851 <div class="output">
14854 <div class="output_area">
14856 <div class="prompt output_prompt">Out[41]:</div>
14861 <div class="output_text output_subarea output_execute_result">
14862 <pre>[63, 327, 1383, 5607, 22503, 90087, 360423, 1441767, 1441773]</pre>
14871 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14872 </div><div class="inner_cell">
14873 <div class="text_cell_render border-box-sizing rendered_html">
14874 <h3 id="Using-the-definitions-for-Sum-and-Carry">Using the definitions for Sum and Carry<a class="anchor-link" href="#Using-the-definitions-for-Sum-and-Carry">¶</a></h3><p>We could also use the definitions from the <a href="https://en.wikipedia.org/wiki/Adder_%28electronics%29#Full_adder">Wikipedia article</a>:</p>
14876 <pre><code>S = A ⊕ B ⊕ C
14877 Cout = (A ⋅ B) + (Cin ⋅ (A ⊕ B))</code></pre>
14882 <div class="cell border-box-sizing code_cell rendered">
14883 <div class="input">
14884 <div class="prompt input_prompt">In [42]:</div>
14885 <div class="inner_cell">
14886 <div class="input_area">
14887 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">full_bit_adder</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="n">c</span><span class="p">):</span>
14888 <span class="k">return</span> <span class="p">(</span>
14889 <span class="n">xor</span><span class="p">(</span><span class="n">xor</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="n">c</span><span class="p">),</span>
14890 <span class="n">or_</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="n">b</span><span class="p">),</span> <span class="n">and_</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">xor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">))),</span>
14891 <span class="p">)</span>
14899 <div class="cell border-box-sizing code_cell rendered">
14900 <div class="input">
14901 <div class="prompt input_prompt">In [43]:</div>
14902 <div class="inner_cell">
14903 <div class="input_area">
14904 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum0</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'b0'</span><span class="p">,</span> <span class="s1">'Cin'</span><span class="p">)</span>
14912 <div class="cell border-box-sizing code_cell rendered">
14913 <div class="input">
14914 <div class="prompt input_prompt">In [44]:</div>
14915 <div class="inner_cell">
14916 <div class="input_area">
14917 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="s1">'Sum'</span>
14918 <span class="n">truth_table</span><span class="p">(</span><span class="n">sum0</span><span class="p">)</span>
14919 <span class="nb">print</span>
14920 <span class="nb">print</span> <span class="s1">'Carry'</span>
14921 <span class="n">truth_table</span><span class="p">(</span><span class="n">cout</span><span class="p">)</span>
14928 <div class="output_wrapper">
14929 <div class="output">
14932 <div class="output_area">
14934 <div class="prompt"></div>
14937 <div class="output_subarea output_stream output_stdout output_text">
14939 ((((((((a0) b0) ((b0) a0)))) Cin) (((((a0) b0) ((b0) a0))) (Cin))))
14941 -------------+------
14952 ((((((((a0) b0) ((b0) a0)))) (Cin)) ((a0) (b0))))
14954 -------------+------
14971 <div class="cell border-box-sizing code_cell rendered">
14972 <div class="input">
14973 <div class="prompt input_prompt">In [45]:</div>
14974 <div class="inner_cell">
14975 <div class="input_area">
14976 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum1</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14977 <span class="n">sum2</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14978 <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a3'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14979 <span class="n">sum4</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a4'</span><span class="p">,</span> <span class="s1">'b4'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14980 <span class="n">sum5</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a5'</span><span class="p">,</span> <span class="s1">'b5'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14981 <span class="n">sum6</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a6'</span><span class="p">,</span> <span class="s1">'b6'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14982 <span class="n">sum7</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a7'</span><span class="p">,</span> <span class="s1">'b7'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
14990 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
14991 </div><div class="inner_cell">
14992 <div class="text_cell_render border-box-sizing rendered_html">
14993 <p>The sizes of these expression are much more tractable:</p>
14998 <div class="cell border-box-sizing code_cell rendered">
14999 <div class="input">
15000 <div class="prompt input_prompt">In [46]:</div>
15001 <div class="inner_cell">
15002 <div class="input_area">
15003 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">map</span><span class="p">(</span><span class="nb">len</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="p">(</span><span class="n">sum0</span><span class="p">,</span> <span class="n">sum1</span><span class="p">,</span> <span class="n">sum2</span><span class="p">,</span> <span class="n">sum3</span><span class="p">,</span> <span class="n">sum4</span><span class="p">,</span> <span class="n">sum5</span><span class="p">,</span> <span class="n">sum6</span><span class="p">,</span> <span class="n">sum7</span><span class="p">,</span> <span class="n">cout</span><span class="p">)))</span>
15010 <div class="output_wrapper">
15011 <div class="output">
15014 <div class="output_area">
15016 <div class="prompt output_prompt">Out[46]:</div>
15021 <div class="output_text output_subarea output_execute_result">
15022 <pre>[67, 159, 251, 343, 435, 527, 619, 711, 371]</pre>
15031 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15032 </div><div class="inner_cell">
15033 <div class="text_cell_render border-box-sizing rendered_html">
15034 <h1 id="Simplifying-Expressions">Simplifying Expressions<a class="anchor-link" href="#Simplifying-Expressions">¶</a></h1><p>The <code>Form</code> Python datastructure is based on <code>frozenset</code> so duplicate terms are automatically removed and order of terms is irrelevant just as we would prefer. But we want to be able to automatically simplify forms beyond just that. Ideally, we would like a function that applies the rules of the calculus automatically:</p>
15036 <pre><code>A((B)) = AB
15041 <p>I'm going to specify the behaviour of the desired function in a unittest.</p>
15046 <div class="cell border-box-sizing code_cell rendered">
15047 <div class="input">
15048 <div class="prompt input_prompt">In [47]:</div>
15049 <div class="inner_cell">
15050 <div class="input_area">
15051 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">import</span> <span class="nn">unittest</span>
15059 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15060 </div><div class="inner_cell">
15061 <div class="text_cell_render border-box-sizing rendered_html">
15062 <h3 id="Three-Easy-Cases">Three Easy Cases<a class="anchor-link" href="#Three-Easy-Cases">¶</a></h3><p>Let's deal with three easy cases first: string, the Mark, and the Void. The <code>simplify()</code> function should just return them unchanged.</p>
15067 <div class="cell border-box-sizing code_cell rendered">
15068 <div class="input">
15069 <div class="prompt input_prompt">In [48]:</div>
15070 <div class="inner_cell">
15071 <div class="input_area">
15072 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">UnwrapTest0</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15074 <span class="k">def</span> <span class="nf">testMark</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15075 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">Mark</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">Mark</span><span class="p">))</span>
15077 <span class="k">def</span> <span class="nf">testVoid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15078 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">Void</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">Void</span><span class="p">))</span>
15080 <span class="k">def</span> <span class="nf">testLeaf</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15081 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="s1">'a'</span><span class="p">))</span>
15084 <span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
15085 <span class="c1"># Three easy cases, for strings, Mark, or Void, just return it.</span>
15086 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span> <span class="ow">or</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
15087 <span class="k">return</span> <span class="n">form</span>
15090 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15091 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'UnwrapTest0'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15098 <div class="output_wrapper">
15099 <div class="output">
15102 <div class="output_area">
15104 <div class="prompt"></div>
15107 <div class="output_subarea output_stream output_stderr output_text">
15109 ----------------------------------------------------------------------
15110 Ran 3 tests in 0.004s
15121 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15122 </div><div class="inner_cell">
15123 <div class="text_cell_render border-box-sizing rendered_html">
15124 <h3 id="(a)"><code>(a)</code><a class="anchor-link" href="#(a)">¶</a></h3><p>A single string in a form <code>(a)</code> should also be returned unchanged:</p>
15129 <div class="cell border-box-sizing code_cell rendered">
15130 <div class="input">
15131 <div class="prompt input_prompt">In [49]:</div>
15132 <div class="inner_cell">
15133 <div class="input_area">
15134 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">UnwrapTest1</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15136 <span class="k">def</span> <span class="nf">testNegatedLeaf</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15137 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="s1">'a'</span><span class="p">)</span>
15138 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15141 <span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
15143 <span class="c1"># Three easy cases, for strings, Mark, or Void, just return it.</span>
15144 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span> <span class="ow">or</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
15145 <span class="k">return</span> <span class="n">form</span>
15147 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15148 <span class="c1"># returned above.)</span>
15150 <span class="c1"># Let's just recurse.</span>
15151 <span class="k">return</span> <span class="n">Form</span><span class="p">(</span><span class="n">simplify</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">form</span><span class="p">)</span>
15154 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15155 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'UnwrapTest1'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15162 <div class="output_wrapper">
15163 <div class="output">
15166 <div class="output_area">
15168 <div class="prompt"></div>
15171 <div class="output_subarea output_stream output_stderr output_text">
15173 ----------------------------------------------------------------------
15174 Ran 1 test in 0.001s
15185 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15186 </div><div class="inner_cell">
15187 <div class="text_cell_render border-box-sizing rendered_html">
15188 <h3 id="Doubly-Wrapped-Forms">Doubly-Wrapped Forms<a class="anchor-link" href="#Doubly-Wrapped-Forms">¶</a></h3><p>So far, so good. But what about <code>((a))</code>? This should be returned as just <code>a</code>. And <code>((a b))</code> should remain <code>((a b))</code> because we can't represent just <code>a b</code> as a single Python object, so we have to retain the outer pair of containers to hold them without inverting the Mark/Void value (if we just used one container.)</p>
15193 <div class="cell border-box-sizing code_cell rendered">
15194 <div class="input">
15195 <div class="prompt input_prompt">In [50]:</div>
15196 <div class="inner_cell">
15197 <div class="input_area">
15198 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">UnwrapTest2</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15200 <span class="k">def</span> <span class="nf">testUnwrapLeaf</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15201 <span class="sd">'''((a)) = a'''</span>
15202 <span class="n">a</span> <span class="o">=</span> <span class="n">or_</span><span class="p">(</span><span class="s1">'a'</span><span class="p">)</span>
15203 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15205 <span class="k">def</span> <span class="nf">testDoNotUnwrapTwoLeaves</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15206 <span class="sd">'''((a b)) = ((a b))'''</span>
15207 <span class="n">a</span> <span class="o">=</span> <span class="n">or_</span><span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">)</span>
15208 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15211 <span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
15213 <span class="c1"># Three easy cases, for strings, Mark, or Void, just return it.</span>
15214 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span> <span class="ow">or</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
15215 <span class="k">return</span> <span class="n">form</span>
15217 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15218 <span class="c1"># returned above.)</span>
15220 <span class="c1"># Let's just recurse.</span>
15221 <span class="n">result</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(</span><span class="n">simplify</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">form</span><span class="p">)</span>
15223 <span class="c1"># Check for ((a)) and return just a.</span>
15224 <span class="c1"># If there is more than one item in the inner container ((a b..))</span>
15225 <span class="c1"># then we must keep the outer containers.</span>
15226 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15227 <span class="n">inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">result</span> <span class="c1"># inner = (a)</span>
15228 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15229 <span class="n">a</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
15230 <span class="k">return</span> <span class="n">a</span>
15232 <span class="k">return</span> <span class="n">result</span>
15235 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15236 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'UnwrapTest2'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15243 <div class="output_wrapper">
15244 <div class="output">
15247 <div class="output_area">
15249 <div class="prompt"></div>
15252 <div class="output_subarea output_stream output_stderr output_text">
15254 ----------------------------------------------------------------------
15255 Ran 2 tests in 0.002s
15266 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15267 </div><div class="inner_cell">
15268 <div class="text_cell_render border-box-sizing rendered_html">
15269 <p>Does it work for <code>(((a))) = (a)</code> and <code>((((a)))) = a</code> and so on?</p>
15274 <div class="cell border-box-sizing code_cell rendered">
15275 <div class="input">
15276 <div class="prompt input_prompt">In [51]:</div>
15277 <div class="inner_cell">
15278 <div class="input_area">
15279 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">UnwrapTest3</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15281 <span class="k">def</span> <span class="nf">testMultiUnwrapLeaf</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15282 <span class="n">A</span> <span class="o">=</span> <span class="s1">'a'</span>
15283 <span class="n">B</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">A</span><span class="p">)</span>
15284 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">B</span><span class="p">)</span>
15285 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15286 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15287 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15288 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15289 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15290 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15291 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15292 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15293 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15294 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15295 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15297 <span class="k">def</span> <span class="nf">testMultiDoNotUnwrapTwoLeaves</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15298 <span class="n">e</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">)</span>
15299 <span class="n">f</span> <span class="o">=</span> <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
15300 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15301 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15302 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15303 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15304 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15305 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15306 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15307 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15308 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15309 <span class="n">a</span> <span class="o">=</span> <span class="n">nor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15310 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
15312 <span class="c1"># Technically, several of the tests above are redundant,</span>
15313 <span class="c1"># I'm not willing to figure out the right point ot stop</span>
15314 <span class="c1"># right now, so I just do extra tests.</span>
15316 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15317 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'UnwrapTest3'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15324 <div class="output_wrapper">
15325 <div class="output">
15328 <div class="output_area">
15330 <div class="prompt"></div>
15333 <div class="output_subarea output_stream output_stderr output_text">
15335 ----------------------------------------------------------------------
15336 Ran 2 tests in 0.003s
15347 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15348 </div><div class="inner_cell">
15349 <div class="text_cell_render border-box-sizing rendered_html">
15350 <h3 id="Unwrapping-Inner-Forms">Unwrapping Inner Forms<a class="anchor-link" href="#Unwrapping-Inner-Forms">¶</a></h3><p>But now let's trick our function, it can't handle <code>(a ((b c))) = (a b c)</code> yet. This is going to require an auxiliary helper function that is similar to <code>simplify()</code> but that yields terms into an outer context.</p>
15355 <div class="cell border-box-sizing code_cell rendered">
15356 <div class="input">
15357 <div class="prompt input_prompt">In [52]:</div>
15358 <div class="inner_cell">
15359 <div class="input_area">
15360 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">UnwrapTest4</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15362 <span class="k">def</span> <span class="nf">testMultiUnwrapLeaf</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15363 <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
15364 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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="n">c</span><span class="p">),))</span>
15365 <span class="n">e</span> <span class="o">=</span> <span class="n">F</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="n">c</span><span class="p">)</span>
15366 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15368 <span class="k">def</span> <span class="nf">testMulti_blah_Leaf</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15369 <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
15370 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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="n">c</span><span class="p">),),),)</span>
15371 <span class="n">e</span> <span class="o">=</span> <span class="n">F</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">c</span><span class="p">))</span>
15372 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15374 <span class="k">def</span> <span class="nf">testMulti_blah_blah_Leaf</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15375 <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="s1">'abcd'</span>
15376 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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="n">c</span><span class="p">),),</span> <span class="n">d</span><span class="p">),))</span>
15377 <span class="n">e</span> <span class="o">=</span> <span class="n">F</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="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span>
15378 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15381 <span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
15383 <span class="c1"># Three easy cases, for strings, Mark, or Void, just return it.</span>
15384 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span> <span class="ow">or</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
15385 <span class="k">return</span> <span class="n">form</span>
15387 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15388 <span class="c1"># returned above.)</span>
15390 <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
15391 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">simplify_gen</span><span class="p">(</span><span class="n">form</span><span class="p">):</span> <span class="c1"># Use the generator instead of recursing into simplify().</span>
15392 <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span>
15393 <span class="n">result</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
15395 <span class="c1"># Check for ((a)) and return just a.</span>
15396 <span class="c1"># If there is more than one item in the inner container ((a b..))</span>
15397 <span class="c1"># then we must keep the outer containers.</span>
15398 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15399 <span class="n">inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">result</span> <span class="c1"># inner = (a)</span>
15400 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">):</span>
15401 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15402 <span class="n">a</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
15403 <span class="k">return</span> <span class="n">a</span>
15404 <span class="k">else</span><span class="p">:</span>
15405 <span class="c1"># len(inner) cannot be 0, because that means form is Void</span>
15406 <span class="c1"># and would already have been returned.</span>
15407 <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span>
15409 <span class="c1"># What to do here?</span>
15410 <span class="c1"># We cannot yield the items in inner into the containing context</span>
15411 <span class="c1"># because we don't have it (or even know if it exists.)</span>
15412 <span class="c1"># Therefore we need a different simplify() generator function that yields</span>
15413 <span class="c1"># the simplified contents of a form, and we have to call that instead</span>
15414 <span class="c1"># of recurring on simplify() above.</span>
15415 <span class="k">pass</span>
15418 <span class="k">return</span> <span class="n">result</span>
15421 <span class="k">def</span> <span class="nf">simplify_gen</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
15423 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">form</span><span class="p">:</span>
15425 <span class="n">inner</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span>
15426 <span class="c1"># Now inner is simplified, except for ((a b...)) which simplify() can't handle.</span>
15428 <span class="c1"># Three easy cases, strings, Mark, or Void.</span>
15429 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
15430 <span class="k">yield</span> <span class="n">inner</span>
15431 <span class="k">continue</span>
15433 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Mark</span><span class="p">:</span>
15434 <span class="k">yield</span> <span class="n">inner</span>
15435 <span class="k">assert</span> <span class="kc">False</span> <span class="c1"># The simplify() function will not keep iterating after this.</span>
15436 <span class="k">return</span> <span class="c1"># Partial implementation of ()A = ().</span>
15438 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Void</span><span class="p">:</span>
15439 <span class="k">continue</span> <span class="c1"># Omit Void. Implementation of (()) = .</span>
15441 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15442 <span class="c1"># yielded above.)</span>
15444 <span class="c1"># Check for ((...)) and return just ... .</span>
15445 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> <span class="c1"># (foo bar)</span>
15446 <span class="k">yield</span> <span class="n">inner</span>
15447 <span class="k">continue</span>
15449 <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="c1"># Just in case...</span>
15451 <span class="n">inner_inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
15452 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner_inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">):</span> <span class="c1"># inner_inner = (...)</span>
15453 <span class="k">for</span> <span class="n">inner_inner_inner</span> <span class="ow">in</span> <span class="n">inner_inner</span><span class="p">:</span>
15454 <span class="k">yield</span> <span class="n">inner_inner_inner</span>
15455 <span class="k">continue</span>
15457 <span class="c1">#else: # inner_inner = foo ; inner = (foo)</span>
15459 <span class="k">yield</span> <span class="n">inner</span>
15462 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15463 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'UnwrapTest4'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15470 <div class="output_wrapper">
15471 <div class="output">
15474 <div class="output_area">
15476 <div class="prompt"></div>
15479 <div class="output_subarea output_stream output_stderr output_text">
15481 ----------------------------------------------------------------------
15482 Ran 3 tests in 0.005s
15493 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15494 </div><div class="inner_cell">
15495 <div class="text_cell_render border-box-sizing rendered_html">
15496 <h3 id="Marks">Marks<a class="anchor-link" href="#Marks">¶</a></h3><p>If the Mark occurs in a sub-form it should <em>Occlude</em> all sibling sub-forms, rendering its container form Void.</p>
15501 <div class="cell border-box-sizing code_cell rendered">
15502 <div class="input">
15503 <div class="prompt input_prompt">In [53]:</div>
15504 <div class="inner_cell">
15505 <div class="input_area">
15506 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">MarkTest0</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15508 <span class="k">def</span> <span class="nf">testMarkOccludes0</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15509 <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
15510 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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">c</span><span class="p">)</span>
15511 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">Void</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15513 <span class="k">def</span> <span class="nf">testMarkOccludes1</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15514 <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
15515 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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">c</span><span class="p">,</span> <span class="p">()))</span>
15516 <span class="n">e</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15517 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15519 <span class="k">def</span> <span class="nf">testMarkOccludes2</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15520 <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
15521 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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>
15522 <span class="n">e</span> <span class="o">=</span> <span class="n">F</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>
15523 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15526 <span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
15528 <span class="c1"># Three easy cases, for strings, Mark, or Void, just return it.</span>
15529 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span> <span class="ow">or</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
15530 <span class="k">return</span> <span class="n">form</span>
15532 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15533 <span class="c1"># returned above.)</span>
15535 <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
15536 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">simplify_gen</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
15537 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Mark</span><span class="p">:</span>
15538 <span class="k">return</span> <span class="n">Void</span> <span class="c1"># Discard any other inner forms, form is Void.</span>
15539 <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span>
15540 <span class="n">result</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
15542 <span class="c1"># Check for ((a)) and return just a.</span>
15543 <span class="c1"># If there is more than one item in the inner container ((a b..))</span>
15544 <span class="c1"># then we must keep the outer containers.</span>
15545 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15546 <span class="n">inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">result</span> <span class="c1"># inner = (a)</span>
15547 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">):</span>
15548 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15549 <span class="n">a</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
15550 <span class="k">return</span> <span class="n">a</span>
15552 <span class="k">return</span> <span class="n">result</span>
15555 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15556 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'MarkTest0'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15563 <div class="output_wrapper">
15564 <div class="output">
15567 <div class="output_area">
15569 <div class="prompt"></div>
15572 <div class="output_subarea output_stream output_stderr output_text">
15574 ----------------------------------------------------------------------
15575 Ran 3 tests in 0.004s
15586 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15587 </div><div class="inner_cell">
15588 <div class="text_cell_render border-box-sizing rendered_html">
15589 <h3 id="Pervade">Pervade<a class="anchor-link" href="#Pervade">¶</a></h3><p>So we have <code>(()) = --</code> and <code>()A = ()</code> what about <code>A(AB) = A(B)</code>?</p>
15594 <div class="cell border-box-sizing code_cell rendered">
15595 <div class="input">
15596 <div class="prompt input_prompt">In [54]:</div>
15597 <div class="inner_cell">
15598 <div class="input_area">
15599 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">PervadeTest0</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15601 <span class="k">def</span> <span class="nf">testPervade0</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15602 <span class="n">a</span> <span class="o">=</span> <span class="s1">'a'</span>
15603 <span class="n">f</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,))</span>
15604 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">Void</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15606 <span class="k">def</span> <span class="nf">testPervade1</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15607 <span class="n">a</span> <span class="o">=</span> <span class="s1">'a'</span>
15608 <span class="n">f</span> <span class="o">=</span> <span class="n">F</span><span class="p">(((</span><span class="n">a</span><span class="p">,),),</span> <span class="p">(</span><span class="n">a</span><span class="p">,))</span>
15609 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">Void</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15611 <span class="k">def</span> <span class="nf">testPervade2</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15612 <span class="n">a</span> <span class="o">=</span> <span class="s1">'a'</span>
15613 <span class="n">b</span> <span class="o">=</span> <span class="s1">'b'</span>
15614 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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">a</span><span class="p">,)))</span>
15615 <span class="n">e</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15616 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
15619 <span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">exclude</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
15621 <span class="c1"># Three easy cases, for strings, Mark, or Void, just return it.</span>
15622 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span> <span class="ow">or</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
15623 <span class="k">return</span> <span class="n">form</span>
15625 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15626 <span class="c1"># returned above.)</span>
15628 <span class="k">if</span> <span class="n">exclude</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
15629 <span class="n">exclude</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
15631 <span class="n">new_stuff</span> <span class="o">=</span> <span class="n">form</span> <span class="o">-</span> <span class="n">exclude</span>
15632 <span class="n">exclude</span> <span class="o">=</span> <span class="n">exclude</span> <span class="o">|</span> <span class="n">new_stuff</span>
15634 <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
15635 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">simplify_gen</span><span class="p">(</span><span class="n">new_stuff</span><span class="p">,</span> <span class="n">exclude</span><span class="p">):</span>
15636 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Mark</span><span class="p">:</span>
15637 <span class="k">return</span> <span class="n">Void</span> <span class="c1"># Discard any other inner forms, form is Void.</span>
15638 <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span>
15639 <span class="n">result</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
15641 <span class="c1"># Check for ((a)) and return just a.</span>
15642 <span class="c1"># If there is more than one item in the inner container ((a b..))</span>
15643 <span class="c1"># then we must keep the outer containers.</span>
15644 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15645 <span class="n">inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">result</span> <span class="c1"># inner = (a)</span>
15646 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">):</span>
15647 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15648 <span class="n">a</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
15649 <span class="k">return</span> <span class="n">a</span>
15651 <span class="k">return</span> <span class="n">result</span>
15654 <span class="k">def</span> <span class="nf">simplify_gen</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">exclude</span><span class="p">):</span>
15656 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">form</span><span class="p">:</span>
15658 <span class="n">inner</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">exclude</span><span class="p">)</span>
15659 <span class="c1"># Now inner is simplified, except for ((a b...)) which simplify() can't handle.</span>
15661 <span class="c1"># Three easy cases, strings, Mark, or Void.</span>
15662 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
15663 <span class="k">yield</span> <span class="n">inner</span>
15664 <span class="k">continue</span>
15666 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Mark</span><span class="p">:</span>
15667 <span class="k">yield</span> <span class="n">inner</span>
15668 <span class="k">assert</span> <span class="kc">False</span> <span class="c1"># The simplify() function will not keep iterating after this.</span>
15669 <span class="k">return</span> <span class="c1"># Partial implementation of ()A = ().</span>
15671 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Void</span><span class="p">:</span>
15672 <span class="k">continue</span> <span class="c1"># Omit Void. Implementation of (()) = .</span>
15674 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15675 <span class="c1"># yielded above.)</span>
15677 <span class="c1"># Check for ((...)) and return just ... .</span>
15678 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> <span class="c1"># (foo bar)</span>
15679 <span class="k">yield</span> <span class="n">inner</span>
15680 <span class="k">continue</span>
15682 <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="c1"># Just in case...</span>
15684 <span class="n">inner_inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
15685 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner_inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">):</span> <span class="c1"># inner_inner = (...)</span>
15686 <span class="k">for</span> <span class="n">inner_inner_inner</span> <span class="ow">in</span> <span class="n">inner_inner</span><span class="p">:</span>
15687 <span class="k">yield</span> <span class="n">inner_inner_inner</span>
15688 <span class="k">continue</span>
15690 <span class="c1">#else: # inner_inner = foo ; inner = (foo)</span>
15692 <span class="k">yield</span> <span class="n">inner</span>
15695 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15696 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'PervadeTest0'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15703 <div class="output_wrapper">
15704 <div class="output">
15707 <div class="output_area">
15709 <div class="prompt"></div>
15712 <div class="output_subarea output_stream output_stderr output_text">
15714 ----------------------------------------------------------------------
15715 Ran 3 tests in 0.004s
15726 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15727 </div><div class="inner_cell">
15728 <div class="text_cell_render border-box-sizing rendered_html">
15729 <p>TODO set up <a href="http://hypothesis.works/">Hypothesis</a> to generate test cases...</p>
15734 <div class="cell border-box-sizing code_cell rendered">
15735 <div class="input">
15736 <div class="prompt input_prompt">In [55]:</div>
15737 <div class="inner_cell">
15738 <div class="input_area">
15739 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Run ALL the tests!</span>
15741 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
15742 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
15749 <div class="output_wrapper">
15750 <div class="output">
15753 <div class="output_area">
15755 <div class="prompt"></div>
15758 <div class="output_subarea output_stream output_stderr output_text">
15759 <pre>.................
15760 ----------------------------------------------------------------------
15761 Ran 17 tests in 0.022s
15772 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15773 </div><div class="inner_cell">
15774 <div class="text_cell_render border-box-sizing rendered_html">
15775 <h2 id="Using-"Each-Way"-to-Simplify-Forms"><a href="http://www.markability.net/case_analysis.htm">Using "Each-Way" to Simplify Forms</a><a class="anchor-link" href="#Using-"Each-Way"-to-Simplify-Forms">¶</a></h2><p>GSB called this "Each-Way":</p>
15777 <pre><code>a = ((a b) (a (b)))</code></pre>
15782 <div class="cell border-box-sizing code_cell rendered">
15783 <div class="input">
15784 <div class="prompt input_prompt">In [56]:</div>
15785 <div class="inner_cell">
15786 <div class="input_area">
15787 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">truth_table</span><span class="p">(</span><span class="n">F</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="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,))))</span>
15794 <div class="output_wrapper">
15795 <div class="output">
15798 <div class="output_area">
15800 <div class="prompt"></div>
15803 <div class="output_subarea output_stream output_stdout output_text">
15804 <pre>(((b) a) (a b))
15819 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15820 </div><div class="inner_cell">
15821 <div class="text_cell_render border-box-sizing rendered_html">
15822 <p>The form says, "if b then a else a". I'll come back to the interpretation of "Each-Way" as an <code>if-then-else</code> statement later.</p>
15823 <p>The thing to note here is that the value for <code>a</code> can be a whole expression which appears twice in the new form: once next to <code>b</code> and once next to <code>(b)</code>.</p>
15824 <p>In the first case we can remove any occurances of <code>b</code> from the <code>a</code> next to it</p>
15826 <pre><code>b (...(b c (d ...)))
15827 b (...( c (d ...)))
15830 <p>and in the second case we can change any occurances of <code>b</code> to the Mark.</p>
15832 <pre><code>(b)(...(b c (d ...)))
15833 (b)((b)(b c (d ...)))
15834 (b)(...(b (b) c (d ...)))
15835 (b)(...(b ( ) c (d ...)))
15840 <p>We can send <code>(b)</code> into the form until it reaches and <code>b</code>, at which point <code>b(b)</code> becomes <code>()</code> and sweeps out any siblings rendering its containing form Void.</p>
15841 <p>For the first case we can use <code>simplify()</code> and pass in <code>b</code> as a member of the <code>exclude</code> set.</p>
15846 <div class="cell border-box-sizing code_cell rendered">
15847 <div class="input">
15848 <div class="prompt input_prompt">In [57]:</div>
15849 <div class="inner_cell">
15850 <div class="input_area">
15851 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">A</span> <span class="o">=</span> <span class="n">F</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>
15852 <span class="n">A</span>
15859 <div class="output_wrapper">
15860 <div class="output">
15863 <div class="output_area">
15865 <div class="prompt output_prompt">Out[57]:</div>
15870 <div class="output_text output_subarea output_execute_result">
15871 <pre>(((c) b) a)</pre>
15880 <div class="cell border-box-sizing code_cell rendered">
15881 <div class="input">
15882 <div class="prompt input_prompt">In [58]:</div>
15883 <div class="inner_cell">
15884 <div class="input_area">
15885 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">simplify</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>
15892 <div class="output_wrapper">
15893 <div class="output">
15896 <div class="output_area">
15898 <div class="prompt output_prompt">Out[58]:</div>
15903 <div class="output_text output_subarea output_execute_result">
15913 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
15914 </div><div class="inner_cell">
15915 <div class="text_cell_render border-box-sizing rendered_html">
15916 <h3 id="with_mark"><code>with_mark</code><a class="anchor-link" href="#with_mark">¶</a></h3><p>In the second case <code>(b)...b... = (b)...()...</code> we can modify the <code>simplify()</code> function to accept a name that it should treat as Mark-valued.</p>
15921 <div class="cell border-box-sizing code_cell rendered">
15922 <div class="input">
15923 <div class="prompt input_prompt">In [59]:</div>
15924 <div class="inner_cell">
15925 <div class="input_area">
15926 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">MarkitTest0</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
15928 <span class="k">def</span> <span class="nf">testMarkit0</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
15929 <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s1">'abc'</span>
15930 <span class="n">f</span> <span class="o">=</span> <span class="n">F</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>
15931 <span class="n">e</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
15932 <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">b</span><span class="p">))</span>
15935 <span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">exclude</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
15937 <span class="c1"># Three easy cases, for strings, Mark, or Void, just return it.</span>
15938 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span> <span class="ow">or</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
15939 <span class="k">return</span> <span class="n">form</span>
15941 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15942 <span class="c1"># returned above.)</span>
15944 <span class="k">if</span> <span class="n">exclude</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
15945 <span class="n">exclude</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
15947 <span class="n">new_stuff</span> <span class="o">=</span> <span class="n">form</span> <span class="o">-</span> <span class="n">exclude</span>
15948 <span class="n">exclude</span> <span class="o">=</span> <span class="n">exclude</span> <span class="o">|</span> <span class="n">new_stuff</span>
15950 <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
15951 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">simplify_gen</span><span class="p">(</span><span class="n">new_stuff</span><span class="p">,</span> <span class="n">exclude</span><span class="p">,</span> <span class="n">with_mark</span><span class="p">):</span>
15952 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Mark</span> <span class="ow">or</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">with_mark</span><span class="p">:</span>
15953 <span class="k">return</span> <span class="n">Void</span> <span class="c1"># Discard any other inner forms, form is Void.</span>
15954 <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span>
15955 <span class="n">result</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
15957 <span class="c1"># Check for ((a)) and return just a.</span>
15958 <span class="c1"># If there is more than one item in the inner container ((a b..))</span>
15959 <span class="c1"># then we must keep the outer containers.</span>
15960 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15961 <span class="n">inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">result</span> <span class="c1"># inner = (a)</span>
15962 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">):</span>
15963 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
15964 <span class="n">a</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
15965 <span class="k">return</span> <span class="n">a</span>
15967 <span class="k">return</span> <span class="n">result</span>
15970 <span class="k">def</span> <span class="nf">simplify_gen</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">exclude</span><span class="p">,</span> <span class="n">with_mark</span><span class="p">):</span>
15972 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">form</span><span class="p">:</span>
15974 <span class="n">inner</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">exclude</span><span class="p">,</span> <span class="n">with_mark</span><span class="p">)</span>
15975 <span class="c1"># Now inner is simplified, except for ((a b...)) which simplify() can't handle.</span>
15977 <span class="c1"># Three easy cases, strings, Mark, or Void.</span>
15978 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
15979 <span class="k">yield</span> <span class="n">inner</span>
15980 <span class="k">continue</span>
15982 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Mark</span> <span class="ow">or</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">with_mark</span><span class="p">:</span>
15983 <span class="k">yield</span> <span class="n">Mark</span>
15984 <span class="k">assert</span> <span class="kc">False</span> <span class="c1"># The simplify() function will not keep iterating after this.</span>
15985 <span class="k">return</span> <span class="c1"># Partial implementation of ()A = ().</span>
15987 <span class="k">if</span> <span class="n">inner</span> <span class="o">==</span> <span class="n">Void</span><span class="p">:</span>
15988 <span class="k">continue</span> <span class="c1"># Omit Void. Implementation of (()) = .</span>
15990 <span class="c1"># We know it's a Form and it's not empty (else it would be the Mark and</span>
15991 <span class="c1"># yielded above.)</span>
15993 <span class="c1"># Check for ((...)) and return just ... .</span>
15994 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> <span class="c1"># (foo bar)</span>
15995 <span class="k">yield</span> <span class="n">inner</span>
15996 <span class="k">continue</span>
15998 <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">inner</span><span class="p">)</span> <span class="c1"># Just in case...</span>
16000 <span class="n">inner_inner</span><span class="p">,</span> <span class="o">=</span> <span class="n">inner</span>
16001 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner_inner</span><span class="p">,</span> <span class="n">Form</span><span class="p">):</span> <span class="c1"># inner_inner = (...)</span>
16002 <span class="k">for</span> <span class="n">inner_inner_inner</span> <span class="ow">in</span> <span class="n">inner_inner</span><span class="p">:</span>
16003 <span class="k">if</span> <span class="n">inner_inner_inner</span> <span class="o">==</span> <span class="n">with_mark</span><span class="p">:</span>
16004 <span class="k">yield</span> <span class="n">Mark</span>
16005 <span class="k">assert</span> <span class="kc">False</span> <span class="c1"># The simplify() function will not keep iterating after this.</span>
16006 <span class="k">return</span> <span class="c1"># Never reached, could delete this line.</span>
16007 <span class="k">yield</span> <span class="n">inner_inner_inner</span>
16008 <span class="k">continue</span>
16010 <span class="c1">#else: # inner_inner = foo ; inner = (foo)</span>
16012 <span class="k">yield</span> <span class="n">inner</span>
16015 <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
16016 <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">(</span><span class="n">argv</span><span class="o">=</span><span class="p">[</span><span class="s1">'ignored'</span><span class="p">,</span> <span class="s1">'MarkitTest0'</span><span class="p">],</span> <span class="n">exit</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
16023 <div class="output_wrapper">
16024 <div class="output">
16027 <div class="output_area">
16029 <div class="prompt"></div>
16032 <div class="output_subarea output_stream output_stderr output_text">
16034 ----------------------------------------------------------------------
16035 Ran 1 test in 0.001s
16046 <div class="cell border-box-sizing code_cell rendered">
16047 <div class="input">
16048 <div class="prompt input_prompt">In [60]:</div>
16049 <div class="inner_cell">
16050 <div class="input_area">
16051 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">simplify</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">b</span><span class="p">)</span>
16058 <div class="output_wrapper">
16059 <div class="output">
16062 <div class="output_area">
16064 <div class="prompt output_prompt">Out[60]:</div>
16069 <div class="output_text output_subarea output_execute_result">
16079 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16080 </div><div class="inner_cell">
16081 <div class="text_cell_render border-box-sizing rendered_html">
16082 <p>Now we can create a new form that is equivalent to <code>A</code>.</p>
16087 <div class="cell border-box-sizing code_cell rendered">
16088 <div class="input">
16089 <div class="prompt input_prompt">In [61]:</div>
16090 <div class="inner_cell">
16091 <div class="input_area">
16092 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">each_way</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
16093 <span class="k">return</span> <span class="n">simplify</span><span class="p">(</span><span class="n">F</span><span class="p">(</span>
16094 <span class="p">(</span> <span class="n">name</span> <span class="p">,</span> <span class="n">form</span><span class="p">),</span>
16095 <span class="p">((</span><span class="n">name</span><span class="p">,),</span> <span class="n">simplify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">name</span><span class="p">)),</span>
16096 <span class="p">))</span>
16098 <span class="n">Ab</span> <span class="o">=</span> <span class="n">each_way</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
16100 <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">Ab</span>
16107 <div class="output_wrapper">
16108 <div class="output">
16111 <div class="output_area">
16113 <div class="prompt"></div>
16116 <div class="output_subarea output_stream output_stdout output_text">
16117 <pre>(((c) b) a) = (((a c) b) ((a) (b)))
16126 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16127 </div><div class="inner_cell">
16128 <div class="text_cell_render border-box-sizing rendered_html">
16129 <p>In this particular case the original form <code>A</code> was so simple that the new version <code>Ab</code> is actually a bit larger. With a large expression to start with the form after simplification would (usually) be smaller.</p>
16134 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16135 </div><div class="inner_cell">
16136 <div class="text_cell_render border-box-sizing rendered_html">
16137 <h3 id="Simplifying-the-Full-Bit-Adder">Simplifying the Full-Bit Adder<a class="anchor-link" href="#Simplifying-the-Full-Bit-Adder">¶</a></h3><p>Recall our original expressions for the sum and carry bits of a full-bit adder circuit, derived from the truth tables:</p>
16142 <div class="cell border-box-sizing code_cell rendered">
16143 <div class="input">
16144 <div class="prompt input_prompt">In [62]:</div>
16145 <div class="inner_cell">
16146 <div class="input_area">
16147 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Sum</span> <span class="o">=</span> <span class="n">F</span><span class="p">((</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="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">c</span><span class="p">),</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="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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),)</span>
16148 <span class="n">Carry</span> <span class="o">=</span> <span class="n">F</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="p">((</span><span class="n">a</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="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">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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),)</span>
16156 <div class="cell border-box-sizing code_cell rendered">
16157 <div class="input">
16158 <div class="prompt input_prompt">In [63]:</div>
16159 <div class="inner_cell">
16160 <div class="input_area">
16161 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Sum</span>
16168 <div class="output_wrapper">
16169 <div class="output">
16172 <div class="output_area">
16174 <div class="prompt output_prompt">Out[63]:</div>
16179 <div class="output_text output_subarea output_execute_result">
16180 <pre>((((a) (b) (c)) ((a) b c) ((b) a c) ((c) a b)))</pre>
16189 <div class="cell border-box-sizing code_cell rendered">
16190 <div class="input">
16191 <div class="prompt input_prompt">In [64]:</div>
16192 <div class="inner_cell">
16193 <div class="input_area">
16194 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Carry</span>
16201 <div class="output_wrapper">
16202 <div class="output">
16205 <div class="output_area">
16207 <div class="prompt output_prompt">Out[64]:</div>
16212 <div class="output_text output_subarea output_execute_result">
16213 <pre>((((a) (b) (c)) ((a) (b) c) ((a) (c) b) ((b) (c) a)))</pre>
16222 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16223 </div><div class="inner_cell">
16224 <div class="text_cell_render border-box-sizing rendered_html">
16225 <p>And the expressions derived from the definitions on Wikipedia:</p>
16230 <div class="cell border-box-sizing code_cell rendered">
16231 <div class="input">
16232 <div class="prompt input_prompt">In [65]:</div>
16233 <div class="inner_cell">
16234 <div class="input_area">
16235 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Sum</span><span class="p">,</span> <span class="n">Carry</span> <span class="o">=</span> <span class="n">full_bit_adder</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="n">c</span><span class="p">)</span>
16243 <div class="cell border-box-sizing code_cell rendered">
16244 <div class="input">
16245 <div class="prompt input_prompt">In [66]:</div>
16246 <div class="inner_cell">
16247 <div class="input_area">
16248 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Sum</span>
16255 <div class="output_wrapper">
16256 <div class="output">
16259 <div class="output_area">
16261 <div class="prompt output_prompt">Out[66]:</div>
16266 <div class="output_text output_subarea output_execute_result">
16267 <pre>((((((((a) b) ((b) a)))) c) (((((a) b) ((b) a))) (c))))</pre>
16276 <div class="cell border-box-sizing code_cell rendered">
16277 <div class="input">
16278 <div class="prompt input_prompt">In [67]:</div>
16279 <div class="inner_cell">
16280 <div class="input_area">
16281 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Carry</span>
16288 <div class="output_wrapper">
16289 <div class="output">
16292 <div class="output_area">
16294 <div class="prompt output_prompt">Out[67]:</div>
16299 <div class="output_text output_subarea output_execute_result">
16300 <pre>((((((((a) b) ((b) a)))) (c)) ((a) (b))))</pre>
16309 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16310 </div><div class="inner_cell">
16311 <div class="text_cell_render border-box-sizing rendered_html">
16312 <p>We can use the <code>each_way()</code> function to look for simpler equivalent forms by, for example, iterating though the names and trying it with each. Try the following cells with both versions of the <code>Sum</code> and <code>Carry</code> above.</p>
16317 <div class="cell border-box-sizing code_cell rendered">
16318 <div class="input">
16319 <div class="prompt input_prompt">In [68]:</div>
16320 <div class="inner_cell">
16321 <div class="input_area">
16322 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">Sum</span>
16323 <span class="k">for</span> <span class="n">name</span> <span class="ow">in</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="n">c</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="n">c</span><span class="p">):</span>
16324 <span class="n">Sum</span> <span class="o">=</span> <span class="n">each_way</span><span class="p">(</span><span class="n">Sum</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
16325 <span class="nb">print</span> <span class="n">Sum</span>
16332 <div class="output_wrapper">
16333 <div class="output">
16336 <div class="output_area">
16338 <div class="prompt"></div>
16341 <div class="output_subarea output_stream output_stdout output_text">
16342 <pre>((((((((a) b) ((b) a)))) c) (((((a) b) ((b) a))) (c))))
16343 ((((b) (c)) (a) (b c)) (((b) c) ((c) b) a))
16344 (((((a) (c)) (a c)) b) ((((a) c) ((c) a)) (b)))
16345 (((((a) (b)) (a b)) c) ((((a) b) ((b) a)) (c)))
16346 (((((b) (c)) (b c)) a) ((((b) c) ((c) b)) (a)))
16347 (((((a) (c)) (a c)) b) ((((a) c) ((c) a)) (b)))
16348 (((((a) (b)) (a b)) c) ((((a) b) ((b) a)) (c)))
16357 <div class="cell border-box-sizing code_cell rendered">
16358 <div class="input">
16359 <div class="prompt input_prompt">In [69]:</div>
16360 <div class="inner_cell">
16361 <div class="input_area">
16362 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">Carry</span>
16363 <span class="k">for</span> <span class="n">name</span> <span class="ow">in</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="n">c</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="n">c</span><span class="p">):</span>
16364 <span class="n">Carry</span> <span class="o">=</span> <span class="n">each_way</span><span class="p">(</span><span class="n">Carry</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
16365 <span class="nb">print</span> <span class="n">Carry</span>
16372 <div class="output_wrapper">
16373 <div class="output">
16376 <div class="output_area">
16378 <div class="prompt"></div>
16381 <div class="output_subarea output_stream output_stdout output_text">
16382 <pre>((((((((a) b) ((b) a)))) (c)) ((a) (b))))
16383 ((((b) (c)) a) ((a) b c))
16384 (((((a) c) (a)) b) ((b) a c))
16385 (((((b) a) (b)) c) ((c) a b))
16386 (((((c) b) (c)) a) ((a) b c))
16387 (((((a) c) (a)) b) ((b) a c))
16388 (((((b) a) (b)) c) ((c) a b))
16397 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16398 </div><div class="inner_cell">
16399 <div class="text_cell_render border-box-sizing rendered_html">
16400 <p>Let's redefine the <code>full_bit_adder()</code> function with the smallest version of each above.</p>
16405 <div class="cell border-box-sizing code_cell rendered">
16406 <div class="input">
16407 <div class="prompt input_prompt">In [70]:</div>
16408 <div class="inner_cell">
16409 <div class="input_area">
16410 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">full_bit_adder</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="n">c</span><span class="p">):</span>
16411 <span class="sd">'''From the truth table.'''</span>
16412 <span class="k">return</span> <span class="p">(</span>
16413 <span class="n">F</span><span class="p">((</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="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">c</span><span class="p">),</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="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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),),</span>
16414 <span class="n">F</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="p">((</span><span class="n">a</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="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">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="p">(</span><span class="n">c</span><span class="p">,))</span> <span class="p">),),</span>
16415 <span class="p">)</span>
16416 <span class="c1"># Sizes: [63, 327, 1383, 5607, 22503, 90087, 360423, 1441767, 1441773]</span>
16424 <div class="cell border-box-sizing code_cell rendered">
16425 <div class="input">
16426 <div class="prompt input_prompt">In [71]:</div>
16427 <div class="inner_cell">
16428 <div class="input_area">
16429 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">full_bit_adder</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="n">c</span><span class="p">):</span>
16430 <span class="sd">'''Simplest forms from above.'''</span>
16431 <span class="k">return</span> <span class="p">(</span>
16432 <span class="n">F</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="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">c</span><span class="p">)),</span> <span class="p">(((</span><span class="n">b</span><span class="p">,),</span> <span class="n">c</span><span class="p">),</span> <span class="p">((</span><span class="n">c</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="p">),</span>
16433 <span class="n">F</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">c</span><span class="p">,)),</span> <span class="n">b</span><span class="p">),</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="n">c</span><span class="p">)</span> <span class="p">),</span>
16434 <span class="p">)</span>
16435 <span class="c1"># Sizes: [57, 177, 417, 897, 1857, 3777, 7617, 15297, 7653]</span>
16443 <div class="cell border-box-sizing code_cell rendered">
16444 <div class="input">
16445 <div class="prompt input_prompt">In [72]:</div>
16446 <div class="inner_cell">
16447 <div class="input_area">
16448 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">full_bit_adder</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="n">c</span><span class="p">):</span>
16449 <span class="sd">'''Based on the definitions from Wikipedia.'''</span>
16450 <span class="k">return</span> <span class="p">(</span>
16451 <span class="n">xor</span><span class="p">(</span><span class="n">xor</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="n">c</span><span class="p">),</span> <span class="c1"># ((((((((a) b) ((b) a)))) c) (((((a) b) ((b) a))) (c))))</span>
16452 <span class="n">or_</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="n">b</span><span class="p">),</span> <span class="n">and_</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">xor</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="c1"># ((((((((a) b) ((b) a)))) (c)) ((a) (b))))</span>
16453 <span class="p">)</span>
16454 <span class="c1"># Sizes: [67, 159, 251, 343, 435, 527, 619, 711, 371]</span>
16462 <div class="cell border-box-sizing code_cell rendered">
16463 <div class="input">
16464 <div class="prompt input_prompt">In [73]:</div>
16465 <div class="inner_cell">
16466 <div class="input_area">
16467 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">full_bit_adder</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="n">c</span><span class="p">):</span>
16468 <span class="sd">'''Based on the definitions from Wikipedia.'''</span>
16469 <span class="k">return</span> <span class="p">(</span>
16470 <span class="n">simplify</span><span class="p">(</span><span class="n">xor</span><span class="p">(</span><span class="n">xor</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="n">c</span><span class="p">)),</span>
16471 <span class="n">simplify</span><span class="p">(</span><span class="n">or_</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="n">b</span><span class="p">),</span> <span class="n">and_</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">xor</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)))),</span>
16472 <span class="p">)</span>
16473 <span class="c1"># Sizes: [59, 135, 211, 287, 363, 439, 515, 591, 311]</span>
16481 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16482 </div><div class="inner_cell">
16483 <div class="text_cell_render border-box-sizing rendered_html">
16484 <p>In this case, the version from the definitions does much better than the other two.</p>
16489 <div class="cell border-box-sizing code_cell rendered">
16490 <div class="input">
16491 <div class="prompt input_prompt">In [74]:</div>
16492 <div class="inner_cell">
16493 <div class="input_area">
16494 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Sum</span><span class="p">,</span> <span class="n">Carry</span> <span class="o">=</span> <span class="n">full_bit_adder</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="n">c</span><span class="p">)</span>
16496 <span class="n">truth_table</span><span class="p">(</span><span class="n">Sum</span><span class="p">)</span>
16497 <span class="nb">print</span>
16498 <span class="n">truth_table</span><span class="p">(</span><span class="n">Carry</span><span class="p">)</span>
16499 <span class="nb">print</span>
16501 <span class="n">sum0</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'b0'</span><span class="p">,</span> <span class="s1">'Cin'</span><span class="p">)</span>
16502 <span class="n">sum1</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
16503 <span class="n">sum2</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
16504 <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a3'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
16505 <span class="n">sum4</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a4'</span><span class="p">,</span> <span class="s1">'b4'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
16506 <span class="n">sum5</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a5'</span><span class="p">,</span> <span class="s1">'b5'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
16507 <span class="n">sum6</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a6'</span><span class="p">,</span> <span class="s1">'b6'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
16508 <span class="n">sum7</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a7'</span><span class="p">,</span> <span class="s1">'b7'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
16510 <span class="nb">print</span> <span class="nb">map</span><span class="p">(</span><span class="nb">len</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="p">(</span><span class="n">sum0</span><span class="p">,</span> <span class="n">sum1</span><span class="p">,</span> <span class="n">sum2</span><span class="p">,</span> <span class="n">sum3</span><span class="p">,</span> <span class="n">sum4</span><span class="p">,</span> <span class="n">sum5</span><span class="p">,</span> <span class="n">sum6</span><span class="p">,</span> <span class="n">sum7</span><span class="p">,</span> <span class="n">cout</span><span class="p">)))</span>
16517 <div class="output_wrapper">
16518 <div class="output">
16521 <div class="output_area">
16523 <div class="prompt"></div>
16526 <div class="output_subarea output_stream output_stdout output_text">
16527 <pre>((((((a) b) ((b) a)) c) (((a) b) ((b) a) (c))))
16539 ((((((a) b) ((b) a)) (c)) ((a) (b))))
16551 [59, 135, 211, 287, 363, 439, 515, 591, 311]
16560 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16561 </div><div class="inner_cell">
16562 <div class="text_cell_render border-box-sizing rendered_html">
16563 <h1 id="Davis–Putnam–Logemann–Loveland-(DPLL)-algorithm-SAT-Solver"><a href="https://en.wikipedia.org/wiki/Davis%E2%80%93Putnam%E2%80%93Logemann%E2%80%93Loveland_algorithm">Davis–Putnam–Logemann–Loveland (DPLL) algorithm</a> SAT Solver<a class="anchor-link" href="#Davis–Putnam–Logemann–Loveland-(DPLL)-algorithm-SAT-Solver">¶</a></h1><p>This is something of an Interlude, we aren't going to use it below, but it's too cool to omit mention.</p>
16564 <p>We can use the <code>simplify()</code> function to create a more efficient SAT solver along the lines of the DPLL algorithm.</p>
16565 <p>It works by selecting a name from the form, and simplifying the form with that name first as <code>Void</code> then as <code>Mark</code>, then recursing with the new form and the next name. If the resulting simplified form becomes the <code>Mark</code> then our choices (of assigning <code>Void</code> or <code>Mark</code> to the names selected so far) constitute a "solution" to the original form. That is, if we <code>reify()</code> the form with the <em>environment</em> returned by the <code>dpll()</code> function the result will be Mark-valued.</p>
16570 <div class="cell border-box-sizing code_cell rendered">
16571 <div class="input">
16572 <div class="prompt input_prompt">In [75]:</div>
16573 <div class="inner_cell">
16574 <div class="input_area">
16575 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">dpll</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">partial</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
16576 <span class="k">if</span> <span class="n">partial</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
16577 <span class="n">partial</span> <span class="o">=</span> <span class="p">{}</span>
16578 <span class="k">else</span><span class="p">:</span>
16579 <span class="n">partial</span> <span class="o">=</span> <span class="n">partial</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="c1"># so we can backtrack later..</span>
16581 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
16582 <span class="n">partial</span><span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="o">=</span> <span class="n">Mark</span>
16583 <span class="k">return</span> <span class="n">partial</span>
16585 <span class="k">if</span> <span class="n">unit</span><span class="p">:</span>
16586 <span class="n">E</span> <span class="o">=</span> <span class="n">assign_unit_clauses</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">partial</span><span class="p">)</span>
16588 <span class="k">if</span> <span class="ow">not</span> <span class="n">E</span><span class="p">:</span>
16589 <span class="k">return</span> <span class="n">partial</span>
16591 <span class="k">if</span> <span class="n">Mark</span> <span class="ow">in</span> <span class="n">E</span><span class="p">:</span>
16592 <span class="k">return</span>
16594 <span class="n">v</span> <span class="o">=</span> <span class="n">next_symbol_of</span><span class="p">(</span><span class="n">E</span><span class="p">)</span>
16596 <span class="n">partial</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">Void</span>
16598 <span class="n">res</span> <span class="o">=</span> <span class="n">dpll</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="p">{</span><span class="n">v</span><span class="p">}),</span> <span class="n">partial</span><span class="p">,</span> <span class="n">unit</span><span class="p">)</span>
16599 <span class="k">if</span> <span class="n">res</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
16600 <span class="k">return</span> <span class="n">res</span>
16602 <span class="n">partial</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">Mark</span>
16604 <span class="k">return</span> <span class="n">dpll</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">v</span><span class="p">),</span> <span class="n">partial</span><span class="p">,</span> <span class="n">unit</span><span class="p">)</span>
16607 <span class="k">def</span> <span class="nf">assign_unit_clauses</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">partial</span><span class="p">):</span>
16608 <span class="sd">'''</span>
16609 <span class="sd"> Find and assign values to an "unit clauses" in the form, simplifying as you go.</span>
16610 <span class="sd"> A unit clause is a bare name or a negated name: a or (a), for these clauses we</span>
16611 <span class="sd"> can set them to Void or Mark, respectively, to contibute to making their containing</span>
16612 <span class="sd"> Form the Mark.</span>
16613 <span class="sd"> '''</span>
16614 <span class="n">on</span><span class="p">,</span> <span class="n">off</span><span class="p">,</span> <span class="n">E</span> <span class="o">=</span> <span class="n">find_units</span><span class="p">(</span><span class="n">E</span><span class="p">)</span>
16615 <span class="k">while</span> <span class="n">on</span> <span class="ow">or</span> <span class="n">off</span><span class="p">:</span>
16616 <span class="k">while</span> <span class="n">on</span><span class="p">:</span>
16617 <span class="k">if</span> <span class="n">on</span> <span class="o">&</span> <span class="n">off</span><span class="p">:</span> <span class="k">return</span> <span class="n">Void</span>
16618 <span class="n">term</span> <span class="o">=</span> <span class="n">first_of</span><span class="p">(</span><span class="n">on</span><span class="p">)</span>
16619 <span class="n">partial</span><span class="p">[</span><span class="n">term</span><span class="p">]</span> <span class="o">=</span> <span class="n">Mark</span>
16620 <span class="n">ON</span><span class="p">,</span> <span class="n">OFF</span><span class="p">,</span> <span class="n">E</span> <span class="o">=</span> <span class="n">find_units</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">term</span><span class="p">))</span>
16621 <span class="n">on</span> <span class="o">|=</span> <span class="n">ON</span>
16622 <span class="n">on</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
16623 <span class="n">off</span> <span class="o">|=</span> <span class="n">OFF</span>
16624 <span class="k">while</span> <span class="n">off</span><span class="p">:</span>
16625 <span class="k">if</span> <span class="n">on</span> <span class="o">&</span> <span class="n">off</span><span class="p">:</span> <span class="k">return</span> <span class="n">Void</span>
16626 <span class="n">term</span> <span class="o">=</span> <span class="n">first_of</span><span class="p">(</span><span class="n">off</span><span class="p">)</span>
16627 <span class="n">partial</span><span class="p">[</span><span class="n">term</span><span class="p">]</span> <span class="o">=</span> <span class="n">Void</span>
16628 <span class="n">ON</span><span class="p">,</span> <span class="n">OFF</span><span class="p">,</span> <span class="n">E</span> <span class="o">=</span> <span class="n">find_units</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="p">{</span><span class="n">term</span><span class="p">}))</span>
16629 <span class="n">off</span> <span class="o">|=</span> <span class="n">OFF</span>
16630 <span class="n">off</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
16631 <span class="n">on</span> <span class="o">|=</span> <span class="n">ON</span>
16632 <span class="k">return</span> <span class="n">E</span>
16635 <span class="k">def</span> <span class="nf">next_symbol_of</span><span class="p">(</span><span class="n">E</span><span class="p">):</span>
16636 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
16637 <span class="k">return</span> <span class="n">E</span>
16638 <span class="k">for</span> <span class="n">it</span> <span class="ow">in</span> <span class="n">E</span><span class="p">:</span>
16639 <span class="k">return</span> <span class="n">next_symbol_of</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
16640 <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"no more symbols"</span><span class="p">)</span>
16643 <span class="k">def</span> <span class="nf">find_units</span><span class="p">(</span><span class="n">E</span><span class="p">):</span>
16644 <span class="sd">'''</span>
16645 <span class="sd"> Return two sets and a possibly-reduced E. The literals in the first</span>
16646 <span class="sd"> set must be Void and those in the second must be set Mark to have the</span>
16647 <span class="sd"> entire expression become Void.</span>
16648 <span class="sd"> '''</span>
16649 <span class="n">on</span><span class="p">,</span> <span class="n">off</span><span class="p">,</span> <span class="n">poly</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(),</span> <span class="nb">set</span><span class="p">(),</span> <span class="nb">set</span><span class="p">()</span>
16650 <span class="k">for</span> <span class="n">clause</span> <span class="ow">in</span> <span class="n">E</span><span class="p">:</span>
16651 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">clause</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
16652 <span class="n">off</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">clause</span><span class="p">)</span>
16653 <span class="k">continue</span>
16654 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">clause</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
16655 <span class="n">poly</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">clause</span><span class="p">)</span>
16656 <span class="k">continue</span>
16657 <span class="p">(</span><span class="n">n</span><span class="p">,)</span> <span class="o">=</span> <span class="n">clause</span> <span class="c1"># Unwrap one layer of containment.</span>
16658 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
16659 <span class="n">on</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
16660 <span class="k">else</span><span class="p">:</span>
16661 <span class="n">poly</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">clause</span><span class="p">)</span>
16662 <span class="k">return</span> <span class="n">on</span><span class="p">,</span> <span class="n">off</span><span class="p">,</span> <span class="n">Form</span><span class="p">(</span><span class="n">poly</span><span class="p">)</span>
16665 <span class="c1"># Return any item from a form.</span>
16666 <span class="n">first_of</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">form</span><span class="p">:</span> <span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">form</span><span class="p">))</span>
16674 <div class="cell border-box-sizing code_cell rendered">
16675 <div class="input">
16676 <div class="prompt input_prompt">In [76]:</div>
16677 <div class="inner_cell">
16678 <div class="input_area">
16679 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">A</span> <span class="o">=</span> <span class="n">F</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>
16680 <span class="n">truth_table</span><span class="p">(</span><span class="n">A</span><span class="p">)</span>
16681 <span class="n">solution</span> <span class="o">=</span> <span class="n">dpll</span><span class="p">(</span><span class="n">A</span><span class="p">)</span>
16682 <span class="n">arith</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">solution</span><span class="p">)</span>
16683 <span class="nb">print</span>
16684 <span class="nb">print</span> <span class="s1">'A solution:'</span><span class="p">,</span> <span class="n">solution</span>
16685 <span class="nb">print</span>
16686 <span class="nb">print</span> <span class="s1">'Reifies to'</span><span class="p">,</span> <span class="n">arith</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">value_of</span><span class="p">(</span><span class="n">arith</span><span class="p">)</span>
16693 <div class="output_wrapper">
16694 <div class="output">
16697 <div class="output_area">
16699 <div class="prompt"></div>
16702 <div class="output_subarea output_stream output_stdout output_text">
16715 A solution: {'a': (()), 'c': (()), 'b': (())}
16717 Reifies to ((((())) (())) (())) ⟶ ()
16726 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16727 </div><div class="inner_cell">
16728 <div class="text_cell_render border-box-sizing rendered_html">
16729 <h3 id="dpll_iter()"><code>dpll_iter()</code><a class="anchor-link" href="#dpll_iter()">¶</a></h3><p>We can write a generator version of the function that keeps looking for solutions after the first.</p>
16734 <div class="cell border-box-sizing code_cell rendered">
16735 <div class="input">
16736 <div class="prompt input_prompt">In [77]:</div>
16737 <div class="inner_cell">
16738 <div class="input_area">
16739 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">dpll_iter</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">partial</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
16740 <span class="k">if</span> <span class="n">partial</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
16741 <span class="n">partial</span> <span class="o">=</span> <span class="p">{}</span>
16742 <span class="k">else</span><span class="p">:</span>
16743 <span class="n">partial</span> <span class="o">=</span> <span class="n">partial</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="c1"># so we can backtrack later..</span>
16745 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
16746 <span class="n">partial</span><span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="o">=</span> <span class="n">Mark</span>
16747 <span class="k">yield</span> <span class="n">partial</span>
16748 <span class="k">return</span>
16750 <span class="k">if</span> <span class="n">unit</span><span class="p">:</span>
16751 <span class="n">E</span> <span class="o">=</span> <span class="n">assign_unit_clauses</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">partial</span><span class="p">)</span>
16753 <span class="k">if</span> <span class="ow">not</span> <span class="n">E</span><span class="p">:</span>
16754 <span class="k">yield</span> <span class="n">partial</span>
16755 <span class="k">return</span>
16757 <span class="k">if</span> <span class="n">Mark</span> <span class="ow">in</span> <span class="n">E</span><span class="p">:</span>
16758 <span class="k">return</span>
16760 <span class="n">v</span> <span class="o">=</span> <span class="n">next_symbol_of</span><span class="p">(</span><span class="n">E</span><span class="p">)</span>
16762 <span class="n">partial</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">Void</span>
16764 <span class="k">for</span> <span class="n">res</span> <span class="ow">in</span> <span class="n">dpll_iter</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="p">{</span><span class="n">v</span><span class="p">}),</span> <span class="n">partial</span><span class="p">,</span> <span class="n">unit</span><span class="p">):</span>
16765 <span class="k">yield</span> <span class="n">res</span>
16767 <span class="n">partial</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">Mark</span>
16769 <span class="k">for</span> <span class="n">res</span> <span class="ow">in</span> <span class="n">dpll_iter</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">v</span><span class="p">),</span> <span class="n">partial</span><span class="p">,</span> <span class="n">unit</span><span class="p">):</span>
16770 <span class="k">yield</span> <span class="n">res</span>
16778 <div class="cell border-box-sizing code_cell rendered">
16779 <div class="input">
16780 <div class="prompt input_prompt">In [78]:</div>
16781 <div class="inner_cell">
16782 <div class="input_area">
16783 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">solution</span> <span class="ow">in</span> <span class="n">dpll_iter</span><span class="p">(</span><span class="n">A</span><span class="p">):</span>
16784 <span class="nb">print</span> <span class="p">(</span><span class="n">solution</span><span class="p">)</span>
16791 <div class="output_wrapper">
16792 <div class="output">
16795 <div class="output_area">
16797 <div class="prompt"></div>
16800 <div class="output_subarea output_stream output_stdout output_text">
16801 <pre>{'a': (()), 'c': (()), 'b': (())}
16802 {'a': (()), 'b': ()}
16811 <div class="cell border-box-sizing code_cell rendered">
16812 <div class="input">
16813 <div class="prompt input_prompt">In [79]:</div>
16814 <div class="inner_cell">
16815 <div class="input_area">
16816 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Sum</span><span class="p">,</span> <span class="n">Carry</span> <span class="o">=</span> <span class="n">full_bit_adder</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="n">c</span><span class="p">)</span>
16824 <div class="cell border-box-sizing code_cell rendered">
16825 <div class="input">
16826 <div class="prompt input_prompt">In [80]:</div>
16827 <div class="inner_cell">
16828 <div class="input_area">
16829 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">solution</span> <span class="ow">in</span> <span class="n">dpll_iter</span><span class="p">(</span><span class="n">Sum</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
16830 <span class="n">r</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">Sum</span><span class="p">,</span> <span class="n">solution</span><span class="p">)</span>
16831 <span class="nb">print</span> <span class="p">(</span><span class="n">solution</span><span class="p">),</span> <span class="n">r</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
16838 <div class="output_wrapper">
16839 <div class="output">
16842 <div class="output_area">
16844 <div class="prompt"></div>
16847 <div class="output_subarea output_stream output_stdout output_text">
16848 <pre>{'a': (()), 'c': (), 'b': (())} (((((((())) (()))) ()) ((((())) (())) (())))) = ()
16849 {'a': (()), 'c': (()), 'b': ()} (((((((())) ()) ((()))) (())) ((((())) ()) ((()))))) = ()
16850 {'a': (), 'c': (()), 'b': (())} (((((((())) ()) ((()))) (())) ((((())) ()) ((()))))) = ()
16851 {'a': (), 'c': (), 'b': ()} ((((((()) ())) ()) (((()) ()) (())))) = ()
16860 <div class="cell border-box-sizing code_cell rendered">
16861 <div class="input">
16862 <div class="prompt input_prompt">In [81]:</div>
16863 <div class="inner_cell">
16864 <div class="input_area">
16865 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">solution</span> <span class="ow">in</span> <span class="n">dpll_iter</span><span class="p">(</span><span class="n">Carry</span><span class="p">,</span> <span class="n">unit</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
16866 <span class="n">r</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">Carry</span><span class="p">,</span> <span class="n">solution</span><span class="p">)</span>
16867 <span class="nb">print</span> <span class="p">(</span><span class="n">solution</span><span class="p">),</span> <span class="n">r</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">simplify</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
16874 <div class="output_wrapper">
16875 <div class="output">
16878 <div class="output_area">
16880 <div class="prompt"></div>
16883 <div class="output_subarea output_stream output_stdout output_text">
16884 <pre>{'a': (()), 'c': (), 'b': ()} (((((((())) ()) ((()))) (())) (((())) (())))) = ()
16885 {'a': (), 'c': (), 'b': (())} (((((((())) ()) ((()))) (())) (((())) (())))) = ()
16886 {'a': (), 'b': ()} ((((((()) ())) (c)) ((())))) = ()
16895 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16896 </div><div class="inner_cell">
16897 <div class="text_cell_render border-box-sizing rendered_html">
16898 <p>Notice that the reified form still has <code>c</code> in it but that doesn't prevent the <code>simplify()</code> function from reducing the form to the Mark. This should be the case for all solutions generated by the <code>dpll_iter()</code> function.</p>
16903 <div class="cell border-box-sizing code_cell rendered">
16904 <div class="input">
16905 <div class="prompt input_prompt">In [82]:</div>
16906 <div class="inner_cell">
16907 <div class="input_area">
16908 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">solution</span> <span class="ow">in</span> <span class="n">dpll_iter</span><span class="p">(</span><span class="n">cout</span><span class="p">):</span>
16909 <span class="nb">print</span> <span class="n">simplify</span><span class="p">(</span><span class="n">reify</span><span class="p">(</span><span class="n">cout</span><span class="p">,</span> <span class="n">solution</span><span class="p">)),</span>
16916 <div class="output_wrapper">
16917 <div class="output">
16920 <div class="output_area">
16922 <div class="prompt"></div>
16925 <div class="output_subarea output_stream output_stdout output_text">
16926 <pre>() () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () (((a5) a5)) (((a5) a5)) () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () (((a5) a5)) (((a5) a5)) () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () (((a5) a5)) (((a5) a5)) () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () (((a5) a5)) (((a5) a5)) () ()
16935 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16936 </div><div class="inner_cell">
16937 <div class="text_cell_render border-box-sizing rendered_html">
16938 <p>Interesting! Some solutions do not <code>simplify()</code> completely in one go. The form <code>(((a5) a5))</code> is Mark-valued:</p>
16940 <pre><code>(((a5) a5))
16949 <div class="cell border-box-sizing code_cell rendered">
16950 <div class="input">
16951 <div class="prompt input_prompt">In [83]:</div>
16952 <div class="inner_cell">
16953 <div class="input_area">
16954 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">E</span> <span class="o">=</span> <span class="n">F</span><span class="p">(((</span><span class="n">a</span><span class="p">,),</span> <span class="n">a</span><span class="p">))</span>
16955 <span class="nb">print</span> <span class="n">E</span>
16956 <span class="nb">print</span> <span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">)</span>
16963 <div class="output_wrapper">
16964 <div class="output">
16967 <div class="output_area">
16969 <div class="prompt"></div>
16972 <div class="output_subarea output_stream output_stdout output_text">
16983 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16984 </div><div class="inner_cell">
16985 <div class="text_cell_render border-box-sizing rendered_html">
16986 <p>Something to keep in mind.</p>
16991 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
16992 </div><div class="inner_cell">
16993 <div class="text_cell_render border-box-sizing rendered_html">
16994 <h1 id="Now-back-to-Circuits">Now back to Circuits<a class="anchor-link" href="#Now-back-to-Circuits">¶</a></h1><h2 id="Using-the-Adder-Circuits-to-Add">Using the Adder Circuits to Add<a class="anchor-link" href="#Using-the-Adder-Circuits-to-Add">¶</a></h2><p>In order to keep things tractable I'm going to use just four bits rather than eight.</p>
16999 <div class="cell border-box-sizing code_cell rendered">
17000 <div class="input">
17001 <div class="prompt input_prompt">In [84]:</div>
17002 <div class="inner_cell">
17003 <div class="input_area">
17004 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum0</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'b0'</span><span class="p">,</span> <span class="s1">'Cin'</span><span class="p">)</span>
17005 <span class="n">sum1</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
17006 <span class="n">sum2</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
17007 <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a3'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
17015 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17016 </div><div class="inner_cell">
17017 <div class="text_cell_render border-box-sizing rendered_html">
17018 <p>Put the circuit expressions into a handy dictionary, and we are ready to add some numbers.</p>
17023 <div class="cell border-box-sizing code_cell rendered">
17024 <div class="input">
17025 <div class="prompt input_prompt">In [85]:</div>
17026 <div class="inner_cell">
17027 <div class="input_area">
17028 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">CIRCUITS</span> <span class="o">=</span> <span class="p">{</span>
17029 <span class="s1">'sum0'</span><span class="p">:</span> <span class="n">sum0</span><span class="p">,</span>
17030 <span class="s1">'sum1'</span><span class="p">:</span> <span class="n">sum1</span><span class="p">,</span>
17031 <span class="s1">'sum2'</span><span class="p">:</span> <span class="n">sum2</span><span class="p">,</span>
17032 <span class="s1">'sum3'</span><span class="p">:</span> <span class="n">sum3</span><span class="p">,</span>
17033 <span class="s1">'cout'</span><span class="p">:</span> <span class="n">cout</span><span class="p">,</span>
17034 <span class="p">}</span>
17042 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17043 </div><div class="inner_cell">
17044 <div class="text_cell_render border-box-sizing rendered_html">
17045 <p>A bunch of crufty junk to print out a nice truth table with the columns arranged to make it (relatively) easy to see the addition.</p>
17050 <div class="cell border-box-sizing code_cell rendered">
17051 <div class="input">
17052 <div class="prompt input_prompt">In [86]:</div>
17053 <div class="inner_cell">
17054 <div class="input_area">
17055 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">stringy_env</span><span class="p">(</span><span class="n">env</span><span class="p">):</span>
17056 <span class="k">return</span> <span class="p">{</span>
17057 <span class="n">k</span><span class="p">:</span> <span class="n">value_of</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">v</span><span class="o">=</span><span class="s1">'--'</span><span class="p">,</span> <span class="n">m</span><span class="o">=</span><span class="s1">'()'</span><span class="p">)</span>
17058 <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">env</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
17059 <span class="p">}</span>
17061 <span class="n">INPUTs</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'Cin'</span><span class="p">,</span> <span class="s1">'a3'</span><span class="p">,</span> <span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="s1">'b0'</span><span class="p">)</span>
17062 <span class="n">OUTPUTs</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'cout'</span><span class="p">,</span> <span class="s1">'sum3'</span><span class="p">,</span> <span class="s1">'sum2'</span><span class="p">,</span> <span class="s1">'sum1'</span><span class="p">,</span> <span class="s1">'sum0'</span><span class="p">)</span>
17064 <span class="n">format_string</span> <span class="o">=</span> <span class="s1">'%('</span> <span class="o">+</span> <span class="s1">')s %('</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">INPUTs</span><span class="p">)</span> <span class="o">+</span> <span class="s1">')s | %('</span> <span class="o">+</span> <span class="s1">')s %('</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">OUTPUTs</span><span class="p">)</span> <span class="o">+</span> <span class="s1">')s'</span>
17067 <span class="nb">print</span> <span class="s1">'Ci|a3 a2 a1 a0|b3 b2 b1 b0 | Co s3 s2 s1 s0'</span>
17068 <span class="n">results</span> <span class="o">=</span> <span class="p">{}</span>
17069 <span class="k">for</span> <span class="n">env</span> <span class="ow">in</span> <span class="n">environments_of_variables</span><span class="p">(</span><span class="o">*</span><span class="n">INPUTs</span><span class="p">):</span>
17071 <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">CIRCUITS</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
17072 <span class="n">results</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value_of</span><span class="p">(</span><span class="n">reify</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">env</span><span class="p">))</span>
17074 <span class="n">env</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
17075 <span class="nb">print</span> <span class="n">format_string</span> <span class="o">%</span> <span class="n">stringy_env</span><span class="p">(</span><span class="n">env</span><span class="p">)</span>
17082 <div class="output_wrapper">
17083 <div class="output">
17086 <div class="output_area">
17088 <div class="prompt"></div>
17091 <div class="output_subarea output_stream output_stdout output_text">
17092 <pre>Ci|a3 a2 a1 a0|b3 b2 b1 b0 | Co s3 s2 s1 s0
17093 -- -- -- -- -- -- -- -- -- | -- -- -- -- --
17094 -- -- -- -- -- -- -- -- () | -- -- -- -- ()
17095 -- -- -- -- -- -- -- () -- | -- -- -- () --
17096 -- -- -- -- -- -- -- () () | -- -- -- () ()
17097 -- -- -- -- -- -- () -- -- | -- -- () -- --
17098 -- -- -- -- -- -- () -- () | -- -- () -- ()
17099 -- -- -- -- -- -- () () -- | -- -- () () --
17100 -- -- -- -- -- -- () () () | -- -- () () ()
17101 -- -- -- -- -- () -- -- -- | -- () -- -- --
17102 -- -- -- -- -- () -- -- () | -- () -- -- ()
17103 -- -- -- -- -- () -- () -- | -- () -- () --
17104 -- -- -- -- -- () -- () () | -- () -- () ()
17105 -- -- -- -- -- () () -- -- | -- () () -- --
17106 -- -- -- -- -- () () -- () | -- () () -- ()
17107 -- -- -- -- -- () () () -- | -- () () () --
17108 -- -- -- -- -- () () () () | -- () () () ()
17109 -- -- -- -- () -- -- -- -- | -- -- -- -- ()
17110 -- -- -- -- () -- -- -- () | -- -- -- () --
17111 -- -- -- -- () -- -- () -- | -- -- -- () ()
17112 -- -- -- -- () -- -- () () | -- -- () -- --
17113 -- -- -- -- () -- () -- -- | -- -- () -- ()
17114 -- -- -- -- () -- () -- () | -- -- () () --
17115 -- -- -- -- () -- () () -- | -- -- () () ()
17116 -- -- -- -- () -- () () () | -- () -- -- --
17117 -- -- -- -- () () -- -- -- | -- () -- -- ()
17118 -- -- -- -- () () -- -- () | -- () -- () --
17119 -- -- -- -- () () -- () -- | -- () -- () ()
17120 -- -- -- -- () () -- () () | -- () () -- --
17121 -- -- -- -- () () () -- -- | -- () () -- ()
17122 -- -- -- -- () () () -- () | -- () () () --
17123 -- -- -- -- () () () () -- | -- () () () ()
17124 -- -- -- -- () () () () () | () -- -- -- --
17125 -- -- -- () -- -- -- -- -- | -- -- -- () --
17126 -- -- -- () -- -- -- -- () | -- -- -- () ()
17127 -- -- -- () -- -- -- () -- | -- -- () -- --
17128 -- -- -- () -- -- -- () () | -- -- () -- ()
17129 -- -- -- () -- -- () -- -- | -- -- () () --
17130 -- -- -- () -- -- () -- () | -- -- () () ()
17131 -- -- -- () -- -- () () -- | -- () -- -- --
17132 -- -- -- () -- -- () () () | -- () -- -- ()
17133 -- -- -- () -- () -- -- -- | -- () -- () --
17134 -- -- -- () -- () -- -- () | -- () -- () ()
17135 -- -- -- () -- () -- () -- | -- () () -- --
17136 -- -- -- () -- () -- () () | -- () () -- ()
17137 -- -- -- () -- () () -- -- | -- () () () --
17138 -- -- -- () -- () () -- () | -- () () () ()
17139 -- -- -- () -- () () () -- | () -- -- -- --
17140 -- -- -- () -- () () () () | () -- -- -- ()
17141 -- -- -- () () -- -- -- -- | -- -- -- () ()
17142 -- -- -- () () -- -- -- () | -- -- () -- --
17143 -- -- -- () () -- -- () -- | -- -- () -- ()
17144 -- -- -- () () -- -- () () | -- -- () () --
17145 -- -- -- () () -- () -- -- | -- -- () () ()
17146 -- -- -- () () -- () -- () | -- () -- -- --
17147 -- -- -- () () -- () () -- | -- () -- -- ()
17148 -- -- -- () () -- () () () | -- () -- () --
17149 -- -- -- () () () -- -- -- | -- () -- () ()
17150 -- -- -- () () () -- -- () | -- () () -- --
17151 -- -- -- () () () -- () -- | -- () () -- ()
17152 -- -- -- () () () -- () () | -- () () () --
17153 -- -- -- () () () () -- -- | -- () () () ()
17154 -- -- -- () () () () -- () | () -- -- -- --
17155 -- -- -- () () () () () -- | () -- -- -- ()
17156 -- -- -- () () () () () () | () -- -- () --
17157 -- -- () -- -- -- -- -- -- | -- -- () -- --
17158 -- -- () -- -- -- -- -- () | -- -- () -- ()
17159 -- -- () -- -- -- -- () -- | -- -- () () --
17160 -- -- () -- -- -- -- () () | -- -- () () ()
17161 -- -- () -- -- -- () -- -- | -- () -- -- --
17162 -- -- () -- -- -- () -- () | -- () -- -- ()
17163 -- -- () -- -- -- () () -- | -- () -- () --
17164 -- -- () -- -- -- () () () | -- () -- () ()
17165 -- -- () -- -- () -- -- -- | -- () () -- --
17166 -- -- () -- -- () -- -- () | -- () () -- ()
17167 -- -- () -- -- () -- () -- | -- () () () --
17168 -- -- () -- -- () -- () () | -- () () () ()
17169 -- -- () -- -- () () -- -- | () -- -- -- --
17170 -- -- () -- -- () () -- () | () -- -- -- ()
17171 -- -- () -- -- () () () -- | () -- -- () --
17172 -- -- () -- -- () () () () | () -- -- () ()
17173 -- -- () -- () -- -- -- -- | -- -- () -- ()
17174 -- -- () -- () -- -- -- () | -- -- () () --
17175 -- -- () -- () -- -- () -- | -- -- () () ()
17176 -- -- () -- () -- -- () () | -- () -- -- --
17177 -- -- () -- () -- () -- -- | -- () -- -- ()
17178 -- -- () -- () -- () -- () | -- () -- () --
17179 -- -- () -- () -- () () -- | -- () -- () ()
17180 -- -- () -- () -- () () () | -- () () -- --
17181 -- -- () -- () () -- -- -- | -- () () -- ()
17182 -- -- () -- () () -- -- () | -- () () () --
17183 -- -- () -- () () -- () -- | -- () () () ()
17184 -- -- () -- () () -- () () | () -- -- -- --
17185 -- -- () -- () () () -- -- | () -- -- -- ()
17186 -- -- () -- () () () -- () | () -- -- () --
17187 -- -- () -- () () () () -- | () -- -- () ()
17188 -- -- () -- () () () () () | () -- () -- --
17189 -- -- () () -- -- -- -- -- | -- -- () () --
17190 -- -- () () -- -- -- -- () | -- -- () () ()
17191 -- -- () () -- -- -- () -- | -- () -- -- --
17192 -- -- () () -- -- -- () () | -- () -- -- ()
17193 -- -- () () -- -- () -- -- | -- () -- () --
17194 -- -- () () -- -- () -- () | -- () -- () ()
17195 -- -- () () -- -- () () -- | -- () () -- --
17196 -- -- () () -- -- () () () | -- () () -- ()
17197 -- -- () () -- () -- -- -- | -- () () () --
17198 -- -- () () -- () -- -- () | -- () () () ()
17199 -- -- () () -- () -- () -- | () -- -- -- --
17200 -- -- () () -- () -- () () | () -- -- -- ()
17201 -- -- () () -- () () -- -- | () -- -- () --
17202 -- -- () () -- () () -- () | () -- -- () ()
17203 -- -- () () -- () () () -- | () -- () -- --
17204 -- -- () () -- () () () () | () -- () -- ()
17205 -- -- () () () -- -- -- -- | -- -- () () ()
17206 -- -- () () () -- -- -- () | -- () -- -- --
17207 -- -- () () () -- -- () -- | -- () -- -- ()
17208 -- -- () () () -- -- () () | -- () -- () --
17209 -- -- () () () -- () -- -- | -- () -- () ()
17210 -- -- () () () -- () -- () | -- () () -- --
17211 -- -- () () () -- () () -- | -- () () -- ()
17212 -- -- () () () -- () () () | -- () () () --
17213 -- -- () () () () -- -- -- | -- () () () ()
17214 -- -- () () () () -- -- () | () -- -- -- --
17215 -- -- () () () () -- () -- | () -- -- -- ()
17216 -- -- () () () () -- () () | () -- -- () --
17217 -- -- () () () () () -- -- | () -- -- () ()
17218 -- -- () () () () () -- () | () -- () -- --
17219 -- -- () () () () () () -- | () -- () -- ()
17220 -- -- () () () () () () () | () -- () () --
17221 -- () -- -- -- -- -- -- -- | -- () -- -- --
17222 -- () -- -- -- -- -- -- () | -- () -- -- ()
17223 -- () -- -- -- -- -- () -- | -- () -- () --
17224 -- () -- -- -- -- -- () () | -- () -- () ()
17225 -- () -- -- -- -- () -- -- | -- () () -- --
17226 -- () -- -- -- -- () -- () | -- () () -- ()
17227 -- () -- -- -- -- () () -- | -- () () () --
17228 -- () -- -- -- -- () () () | -- () () () ()
17229 -- () -- -- -- () -- -- -- | () -- -- -- --
17230 -- () -- -- -- () -- -- () | () -- -- -- ()
17231 -- () -- -- -- () -- () -- | () -- -- () --
17232 -- () -- -- -- () -- () () | () -- -- () ()
17233 -- () -- -- -- () () -- -- | () -- () -- --
17234 -- () -- -- -- () () -- () | () -- () -- ()
17235 -- () -- -- -- () () () -- | () -- () () --
17236 -- () -- -- -- () () () () | () -- () () ()
17237 -- () -- -- () -- -- -- -- | -- () -- -- ()
17238 -- () -- -- () -- -- -- () | -- () -- () --
17239 -- () -- -- () -- -- () -- | -- () -- () ()
17240 -- () -- -- () -- -- () () | -- () () -- --
17241 -- () -- -- () -- () -- -- | -- () () -- ()
17242 -- () -- -- () -- () -- () | -- () () () --
17243 -- () -- -- () -- () () -- | -- () () () ()
17244 -- () -- -- () -- () () () | () -- -- -- --
17245 -- () -- -- () () -- -- -- | () -- -- -- ()
17246 -- () -- -- () () -- -- () | () -- -- () --
17247 -- () -- -- () () -- () -- | () -- -- () ()
17248 -- () -- -- () () -- () () | () -- () -- --
17249 -- () -- -- () () () -- -- | () -- () -- ()
17250 -- () -- -- () () () -- () | () -- () () --
17251 -- () -- -- () () () () -- | () -- () () ()
17252 -- () -- -- () () () () () | () () -- -- --
17253 -- () -- () -- -- -- -- -- | -- () -- () --
17254 -- () -- () -- -- -- -- () | -- () -- () ()
17255 -- () -- () -- -- -- () -- | -- () () -- --
17256 -- () -- () -- -- -- () () | -- () () -- ()
17257 -- () -- () -- -- () -- -- | -- () () () --
17258 -- () -- () -- -- () -- () | -- () () () ()
17259 -- () -- () -- -- () () -- | () -- -- -- --
17260 -- () -- () -- -- () () () | () -- -- -- ()
17261 -- () -- () -- () -- -- -- | () -- -- () --
17262 -- () -- () -- () -- -- () | () -- -- () ()
17263 -- () -- () -- () -- () -- | () -- () -- --
17264 -- () -- () -- () -- () () | () -- () -- ()
17265 -- () -- () -- () () -- -- | () -- () () --
17266 -- () -- () -- () () -- () | () -- () () ()
17267 -- () -- () -- () () () -- | () () -- -- --
17268 -- () -- () -- () () () () | () () -- -- ()
17269 -- () -- () () -- -- -- -- | -- () -- () ()
17270 -- () -- () () -- -- -- () | -- () () -- --
17271 -- () -- () () -- -- () -- | -- () () -- ()
17272 -- () -- () () -- -- () () | -- () () () --
17273 -- () -- () () -- () -- -- | -- () () () ()
17274 -- () -- () () -- () -- () | () -- -- -- --
17275 -- () -- () () -- () () -- | () -- -- -- ()
17276 -- () -- () () -- () () () | () -- -- () --
17277 -- () -- () () () -- -- -- | () -- -- () ()
17278 -- () -- () () () -- -- () | () -- () -- --
17279 -- () -- () () () -- () -- | () -- () -- ()
17280 -- () -- () () () -- () () | () -- () () --
17281 -- () -- () () () () -- -- | () -- () () ()
17282 -- () -- () () () () -- () | () () -- -- --
17283 -- () -- () () () () () -- | () () -- -- ()
17284 -- () -- () () () () () () | () () -- () --
17285 -- () () -- -- -- -- -- -- | -- () () -- --
17286 -- () () -- -- -- -- -- () | -- () () -- ()
17287 -- () () -- -- -- -- () -- | -- () () () --
17288 -- () () -- -- -- -- () () | -- () () () ()
17289 -- () () -- -- -- () -- -- | () -- -- -- --
17290 -- () () -- -- -- () -- () | () -- -- -- ()
17291 -- () () -- -- -- () () -- | () -- -- () --
17292 -- () () -- -- -- () () () | () -- -- () ()
17293 -- () () -- -- () -- -- -- | () -- () -- --
17294 -- () () -- -- () -- -- () | () -- () -- ()
17295 -- () () -- -- () -- () -- | () -- () () --
17296 -- () () -- -- () -- () () | () -- () () ()
17297 -- () () -- -- () () -- -- | () () -- -- --
17298 -- () () -- -- () () -- () | () () -- -- ()
17299 -- () () -- -- () () () -- | () () -- () --
17300 -- () () -- -- () () () () | () () -- () ()
17301 -- () () -- () -- -- -- -- | -- () () -- ()
17302 -- () () -- () -- -- -- () | -- () () () --
17303 -- () () -- () -- -- () -- | -- () () () ()
17304 -- () () -- () -- -- () () | () -- -- -- --
17305 -- () () -- () -- () -- -- | () -- -- -- ()
17306 -- () () -- () -- () -- () | () -- -- () --
17307 -- () () -- () -- () () -- | () -- -- () ()
17308 -- () () -- () -- () () () | () -- () -- --
17309 -- () () -- () () -- -- -- | () -- () -- ()
17310 -- () () -- () () -- -- () | () -- () () --
17311 -- () () -- () () -- () -- | () -- () () ()
17312 -- () () -- () () -- () () | () () -- -- --
17313 -- () () -- () () () -- -- | () () -- -- ()
17314 -- () () -- () () () -- () | () () -- () --
17315 -- () () -- () () () () -- | () () -- () ()
17316 -- () () -- () () () () () | () () () -- --
17317 -- () () () -- -- -- -- -- | -- () () () --
17318 -- () () () -- -- -- -- () | -- () () () ()
17319 -- () () () -- -- -- () -- | () -- -- -- --
17320 -- () () () -- -- -- () () | () -- -- -- ()
17321 -- () () () -- -- () -- -- | () -- -- () --
17322 -- () () () -- -- () -- () | () -- -- () ()
17323 -- () () () -- -- () () -- | () -- () -- --
17324 -- () () () -- -- () () () | () -- () -- ()
17325 -- () () () -- () -- -- -- | () -- () () --
17326 -- () () () -- () -- -- () | () -- () () ()
17327 -- () () () -- () -- () -- | () () -- -- --
17328 -- () () () -- () -- () () | () () -- -- ()
17329 -- () () () -- () () -- -- | () () -- () --
17330 -- () () () -- () () -- () | () () -- () ()
17331 -- () () () -- () () () -- | () () () -- --
17332 -- () () () -- () () () () | () () () -- ()
17333 -- () () () () -- -- -- -- | -- () () () ()
17334 -- () () () () -- -- -- () | () -- -- -- --
17335 -- () () () () -- -- () -- | () -- -- -- ()
17336 -- () () () () -- -- () () | () -- -- () --
17337 -- () () () () -- () -- -- | () -- -- () ()
17338 -- () () () () -- () -- () | () -- () -- --
17339 -- () () () () -- () () -- | () -- () -- ()
17340 -- () () () () -- () () () | () -- () () --
17341 -- () () () () () -- -- -- | () -- () () ()
17342 -- () () () () () -- -- () | () () -- -- --
17343 -- () () () () () -- () -- | () () -- -- ()
17344 -- () () () () () -- () () | () () -- () --
17345 -- () () () () () () -- -- | () () -- () ()
17346 -- () () () () () () -- () | () () () -- --
17347 -- () () () () () () () -- | () () () -- ()
17348 -- () () () () () () () () | () () () () --
17349 () -- -- -- -- -- -- -- -- | -- -- -- -- ()
17350 () -- -- -- -- -- -- -- () | -- -- -- () --
17351 () -- -- -- -- -- -- () -- | -- -- -- () ()
17352 () -- -- -- -- -- -- () () | -- -- () -- --
17353 () -- -- -- -- -- () -- -- | -- -- () -- ()
17354 () -- -- -- -- -- () -- () | -- -- () () --
17355 () -- -- -- -- -- () () -- | -- -- () () ()
17356 () -- -- -- -- -- () () () | -- () -- -- --
17357 () -- -- -- -- () -- -- -- | -- () -- -- ()
17358 () -- -- -- -- () -- -- () | -- () -- () --
17359 () -- -- -- -- () -- () -- | -- () -- () ()
17360 () -- -- -- -- () -- () () | -- () () -- --
17361 () -- -- -- -- () () -- -- | -- () () -- ()
17362 () -- -- -- -- () () -- () | -- () () () --
17363 () -- -- -- -- () () () -- | -- () () () ()
17364 () -- -- -- -- () () () () | () -- -- -- --
17365 () -- -- -- () -- -- -- -- | -- -- -- () --
17366 () -- -- -- () -- -- -- () | -- -- -- () ()
17367 () -- -- -- () -- -- () -- | -- -- () -- --
17368 () -- -- -- () -- -- () () | -- -- () -- ()
17369 () -- -- -- () -- () -- -- | -- -- () () --
17370 () -- -- -- () -- () -- () | -- -- () () ()
17371 () -- -- -- () -- () () -- | -- () -- -- --
17372 () -- -- -- () -- () () () | -- () -- -- ()
17373 () -- -- -- () () -- -- -- | -- () -- () --
17374 () -- -- -- () () -- -- () | -- () -- () ()
17375 () -- -- -- () () -- () -- | -- () () -- --
17376 () -- -- -- () () -- () () | -- () () -- ()
17377 () -- -- -- () () () -- -- | -- () () () --
17378 () -- -- -- () () () -- () | -- () () () ()
17379 () -- -- -- () () () () -- | () -- -- -- --
17380 () -- -- -- () () () () () | () -- -- -- ()
17381 () -- -- () -- -- -- -- -- | -- -- -- () ()
17382 () -- -- () -- -- -- -- () | -- -- () -- --
17383 () -- -- () -- -- -- () -- | -- -- () -- ()
17384 () -- -- () -- -- -- () () | -- -- () () --
17385 () -- -- () -- -- () -- -- | -- -- () () ()
17386 () -- -- () -- -- () -- () | -- () -- -- --
17387 () -- -- () -- -- () () -- | -- () -- -- ()
17388 () -- -- () -- -- () () () | -- () -- () --
17389 () -- -- () -- () -- -- -- | -- () -- () ()
17390 () -- -- () -- () -- -- () | -- () () -- --
17391 () -- -- () -- () -- () -- | -- () () -- ()
17392 () -- -- () -- () -- () () | -- () () () --
17393 () -- -- () -- () () -- -- | -- () () () ()
17394 () -- -- () -- () () -- () | () -- -- -- --
17395 () -- -- () -- () () () -- | () -- -- -- ()
17396 () -- -- () -- () () () () | () -- -- () --
17397 () -- -- () () -- -- -- -- | -- -- () -- --
17398 () -- -- () () -- -- -- () | -- -- () -- ()
17399 () -- -- () () -- -- () -- | -- -- () () --
17400 () -- -- () () -- -- () () | -- -- () () ()
17401 () -- -- () () -- () -- -- | -- () -- -- --
17402 () -- -- () () -- () -- () | -- () -- -- ()
17403 () -- -- () () -- () () -- | -- () -- () --
17404 () -- -- () () -- () () () | -- () -- () ()
17405 () -- -- () () () -- -- -- | -- () () -- --
17406 () -- -- () () () -- -- () | -- () () -- ()
17407 () -- -- () () () -- () -- | -- () () () --
17408 () -- -- () () () -- () () | -- () () () ()
17409 () -- -- () () () () -- -- | () -- -- -- --
17410 () -- -- () () () () -- () | () -- -- -- ()
17411 () -- -- () () () () () -- | () -- -- () --
17412 () -- -- () () () () () () | () -- -- () ()
17413 () -- () -- -- -- -- -- -- | -- -- () -- ()
17414 () -- () -- -- -- -- -- () | -- -- () () --
17415 () -- () -- -- -- -- () -- | -- -- () () ()
17416 () -- () -- -- -- -- () () | -- () -- -- --
17417 () -- () -- -- -- () -- -- | -- () -- -- ()
17418 () -- () -- -- -- () -- () | -- () -- () --
17419 () -- () -- -- -- () () -- | -- () -- () ()
17420 () -- () -- -- -- () () () | -- () () -- --
17421 () -- () -- -- () -- -- -- | -- () () -- ()
17422 () -- () -- -- () -- -- () | -- () () () --
17423 () -- () -- -- () -- () -- | -- () () () ()
17424 () -- () -- -- () -- () () | () -- -- -- --
17425 () -- () -- -- () () -- -- | () -- -- -- ()
17426 () -- () -- -- () () -- () | () -- -- () --
17427 () -- () -- -- () () () -- | () -- -- () ()
17428 () -- () -- -- () () () () | () -- () -- --
17429 () -- () -- () -- -- -- -- | -- -- () () --
17430 () -- () -- () -- -- -- () | -- -- () () ()
17431 () -- () -- () -- -- () -- | -- () -- -- --
17432 () -- () -- () -- -- () () | -- () -- -- ()
17433 () -- () -- () -- () -- -- | -- () -- () --
17434 () -- () -- () -- () -- () | -- () -- () ()
17435 () -- () -- () -- () () -- | -- () () -- --
17436 () -- () -- () -- () () () | -- () () -- ()
17437 () -- () -- () () -- -- -- | -- () () () --
17438 () -- () -- () () -- -- () | -- () () () ()
17439 () -- () -- () () -- () -- | () -- -- -- --
17440 () -- () -- () () -- () () | () -- -- -- ()
17441 () -- () -- () () () -- -- | () -- -- () --
17442 () -- () -- () () () -- () | () -- -- () ()
17443 () -- () -- () () () () -- | () -- () -- --
17444 () -- () -- () () () () () | () -- () -- ()
17445 () -- () () -- -- -- -- -- | -- -- () () ()
17446 () -- () () -- -- -- -- () | -- () -- -- --
17447 () -- () () -- -- -- () -- | -- () -- -- ()
17448 () -- () () -- -- -- () () | -- () -- () --
17449 () -- () () -- -- () -- -- | -- () -- () ()
17450 () -- () () -- -- () -- () | -- () () -- --
17451 () -- () () -- -- () () -- | -- () () -- ()
17452 () -- () () -- -- () () () | -- () () () --
17453 () -- () () -- () -- -- -- | -- () () () ()
17454 () -- () () -- () -- -- () | () -- -- -- --
17455 () -- () () -- () -- () -- | () -- -- -- ()
17456 () -- () () -- () -- () () | () -- -- () --
17457 () -- () () -- () () -- -- | () -- -- () ()
17458 () -- () () -- () () -- () | () -- () -- --
17459 () -- () () -- () () () -- | () -- () -- ()
17460 () -- () () -- () () () () | () -- () () --
17461 () -- () () () -- -- -- -- | -- () -- -- --
17462 () -- () () () -- -- -- () | -- () -- -- ()
17463 () -- () () () -- -- () -- | -- () -- () --
17464 () -- () () () -- -- () () | -- () -- () ()
17465 () -- () () () -- () -- -- | -- () () -- --
17466 () -- () () () -- () -- () | -- () () -- ()
17467 () -- () () () -- () () -- | -- () () () --
17468 () -- () () () -- () () () | -- () () () ()
17469 () -- () () () () -- -- -- | () -- -- -- --
17470 () -- () () () () -- -- () | () -- -- -- ()
17471 () -- () () () () -- () -- | () -- -- () --
17472 () -- () () () () -- () () | () -- -- () ()
17473 () -- () () () () () -- -- | () -- () -- --
17474 () -- () () () () () -- () | () -- () -- ()
17475 () -- () () () () () () -- | () -- () () --
17476 () -- () () () () () () () | () -- () () ()
17477 () () -- -- -- -- -- -- -- | -- () -- -- ()
17478 () () -- -- -- -- -- -- () | -- () -- () --
17479 () () -- -- -- -- -- () -- | -- () -- () ()
17480 () () -- -- -- -- -- () () | -- () () -- --
17481 () () -- -- -- -- () -- -- | -- () () -- ()
17482 () () -- -- -- -- () -- () | -- () () () --
17483 () () -- -- -- -- () () -- | -- () () () ()
17484 () () -- -- -- -- () () () | () -- -- -- --
17485 () () -- -- -- () -- -- -- | () -- -- -- ()
17486 () () -- -- -- () -- -- () | () -- -- () --
17487 () () -- -- -- () -- () -- | () -- -- () ()
17488 () () -- -- -- () -- () () | () -- () -- --
17489 () () -- -- -- () () -- -- | () -- () -- ()
17490 () () -- -- -- () () -- () | () -- () () --
17491 () () -- -- -- () () () -- | () -- () () ()
17492 () () -- -- -- () () () () | () () -- -- --
17493 () () -- -- () -- -- -- -- | -- () -- () --
17494 () () -- -- () -- -- -- () | -- () -- () ()
17495 () () -- -- () -- -- () -- | -- () () -- --
17496 () () -- -- () -- -- () () | -- () () -- ()
17497 () () -- -- () -- () -- -- | -- () () () --
17498 () () -- -- () -- () -- () | -- () () () ()
17499 () () -- -- () -- () () -- | () -- -- -- --
17500 () () -- -- () -- () () () | () -- -- -- ()
17501 () () -- -- () () -- -- -- | () -- -- () --
17502 () () -- -- () () -- -- () | () -- -- () ()
17503 () () -- -- () () -- () -- | () -- () -- --
17504 () () -- -- () () -- () () | () -- () -- ()
17505 () () -- -- () () () -- -- | () -- () () --
17506 () () -- -- () () () -- () | () -- () () ()
17507 () () -- -- () () () () -- | () () -- -- --
17508 () () -- -- () () () () () | () () -- -- ()
17509 () () -- () -- -- -- -- -- | -- () -- () ()
17510 () () -- () -- -- -- -- () | -- () () -- --
17511 () () -- () -- -- -- () -- | -- () () -- ()
17512 () () -- () -- -- -- () () | -- () () () --
17513 () () -- () -- -- () -- -- | -- () () () ()
17514 () () -- () -- -- () -- () | () -- -- -- --
17515 () () -- () -- -- () () -- | () -- -- -- ()
17516 () () -- () -- -- () () () | () -- -- () --
17517 () () -- () -- () -- -- -- | () -- -- () ()
17518 () () -- () -- () -- -- () | () -- () -- --
17519 () () -- () -- () -- () -- | () -- () -- ()
17520 () () -- () -- () -- () () | () -- () () --
17521 () () -- () -- () () -- -- | () -- () () ()
17522 () () -- () -- () () -- () | () () -- -- --
17523 () () -- () -- () () () -- | () () -- -- ()
17524 () () -- () -- () () () () | () () -- () --
17525 () () -- () () -- -- -- -- | -- () () -- --
17526 () () -- () () -- -- -- () | -- () () -- ()
17527 () () -- () () -- -- () -- | -- () () () --
17528 () () -- () () -- -- () () | -- () () () ()
17529 () () -- () () -- () -- -- | () -- -- -- --
17530 () () -- () () -- () -- () | () -- -- -- ()
17531 () () -- () () -- () () -- | () -- -- () --
17532 () () -- () () -- () () () | () -- -- () ()
17533 () () -- () () () -- -- -- | () -- () -- --
17534 () () -- () () () -- -- () | () -- () -- ()
17535 () () -- () () () -- () -- | () -- () () --
17536 () () -- () () () -- () () | () -- () () ()
17537 () () -- () () () () -- -- | () () -- -- --
17538 () () -- () () () () -- () | () () -- -- ()
17539 () () -- () () () () () -- | () () -- () --
17540 () () -- () () () () () () | () () -- () ()
17541 () () () -- -- -- -- -- -- | -- () () -- ()
17542 () () () -- -- -- -- -- () | -- () () () --
17543 () () () -- -- -- -- () -- | -- () () () ()
17544 () () () -- -- -- -- () () | () -- -- -- --
17545 () () () -- -- -- () -- -- | () -- -- -- ()
17546 () () () -- -- -- () -- () | () -- -- () --
17547 () () () -- -- -- () () -- | () -- -- () ()
17548 () () () -- -- -- () () () | () -- () -- --
17549 () () () -- -- () -- -- -- | () -- () -- ()
17550 () () () -- -- () -- -- () | () -- () () --
17551 () () () -- -- () -- () -- | () -- () () ()
17552 () () () -- -- () -- () () | () () -- -- --
17553 () () () -- -- () () -- -- | () () -- -- ()
17554 () () () -- -- () () -- () | () () -- () --
17555 () () () -- -- () () () -- | () () -- () ()
17556 () () () -- -- () () () () | () () () -- --
17557 () () () -- () -- -- -- -- | -- () () () --
17558 () () () -- () -- -- -- () | -- () () () ()
17559 () () () -- () -- -- () -- | () -- -- -- --
17560 () () () -- () -- -- () () | () -- -- -- ()
17561 () () () -- () -- () -- -- | () -- -- () --
17562 () () () -- () -- () -- () | () -- -- () ()
17563 () () () -- () -- () () -- | () -- () -- --
17564 () () () -- () -- () () () | () -- () -- ()
17565 () () () -- () () -- -- -- | () -- () () --
17566 () () () -- () () -- -- () | () -- () () ()
17567 () () () -- () () -- () -- | () () -- -- --
17568 () () () -- () () -- () () | () () -- -- ()
17569 () () () -- () () () -- -- | () () -- () --
17570 () () () -- () () () -- () | () () -- () ()
17571 () () () -- () () () () -- | () () () -- --
17572 () () () -- () () () () () | () () () -- ()
17573 () () () () -- -- -- -- -- | -- () () () ()
17574 () () () () -- -- -- -- () | () -- -- -- --
17575 () () () () -- -- -- () -- | () -- -- -- ()
17576 () () () () -- -- -- () () | () -- -- () --
17577 () () () () -- -- () -- -- | () -- -- () ()
17578 () () () () -- -- () -- () | () -- () -- --
17579 () () () () -- -- () () -- | () -- () -- ()
17580 () () () () -- -- () () () | () -- () () --
17581 () () () () -- () -- -- -- | () -- () () ()
17582 () () () () -- () -- -- () | () () -- -- --
17583 () () () () -- () -- () -- | () () -- -- ()
17584 () () () () -- () -- () () | () () -- () --
17585 () () () () -- () () -- -- | () () -- () ()
17586 () () () () -- () () -- () | () () () -- --
17587 () () () () -- () () () -- | () () () -- ()
17588 () () () () -- () () () () | () () () () --
17589 () () () () () -- -- -- -- | () -- -- -- --
17590 () () () () () -- -- -- () | () -- -- -- ()
17591 () () () () () -- -- () -- | () -- -- () --
17592 () () () () () -- -- () () | () -- -- () ()
17593 () () () () () -- () -- -- | () -- () -- --
17594 () () () () () -- () -- () | () -- () -- ()
17595 () () () () () -- () () -- | () -- () () --
17596 () () () () () -- () () () | () -- () () ()
17597 () () () () () () -- -- -- | () () -- -- --
17598 () () () () () () -- -- () | () () -- -- ()
17599 () () () () () () -- () -- | () () -- () --
17600 () () () () () () -- () () | () () -- () ()
17601 () () () () () () () -- -- | () () () -- --
17602 () () () () () () () -- () | () () () -- ()
17603 () () () () () () () () -- | () () () () --
17604 () () () () () () () () () | () () () () ()
17613 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17614 </div><div class="inner_cell">
17615 <div class="text_cell_render border-box-sizing rendered_html">
17616 <h1 id="A-Model-of-Computation.">A Model of Computation.<a class="anchor-link" href="#A-Model-of-Computation.">¶</a></h1><p>That was a bit steep, let's formalize it and make it a little easier to work with.</p>
17617 <p>First let's have a <em>register</em> of named values:</p>
17622 <div class="cell border-box-sizing code_cell rendered">
17623 <div class="input">
17624 <div class="prompt input_prompt">In [87]:</div>
17625 <div class="inner_cell">
17626 <div class="input_area">
17627 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">R</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">Void</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="s1">'Cin a3 a2 a1 a0 b3 b2 b1 b0 Cout'</span><span class="o">.</span><span class="n">split</span><span class="p">()}</span>
17635 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17636 </div><div class="inner_cell">
17637 <div class="text_cell_render border-box-sizing rendered_html">
17638 <p>Let's have a <em>program</em> of named expressions that give new values when evaluated in terms of the current values in <strong>R</strong> (this is just the same <code>CIRCUITS</code>, but feeding back the results into the "b" bits):</p>
17643 <div class="cell border-box-sizing code_cell rendered">
17644 <div class="input">
17645 <div class="prompt input_prompt">In [88]:</div>
17646 <div class="inner_cell">
17647 <div class="input_area">
17648 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">P</span> <span class="o">=</span> <span class="p">{</span>
17649 <span class="s1">'b0'</span><span class="p">:</span> <span class="n">sum0</span><span class="p">,</span>
17650 <span class="s1">'b1'</span><span class="p">:</span> <span class="n">sum1</span><span class="p">,</span>
17651 <span class="s1">'b2'</span><span class="p">:</span> <span class="n">sum2</span><span class="p">,</span>
17652 <span class="s1">'b3'</span><span class="p">:</span> <span class="n">sum3</span><span class="p">,</span>
17653 <span class="s1">'Cout'</span><span class="p">:</span> <span class="n">cout</span><span class="p">,</span>
17654 <span class="p">}</span>
17662 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17663 </div><div class="inner_cell">
17664 <div class="text_cell_render border-box-sizing rendered_html">
17665 <p>One <em>cycle</em> of the machine means to evaluate each named expression in the program with the current values in the register.</p>
17670 <div class="cell border-box-sizing code_cell rendered">
17671 <div class="input">
17672 <div class="prompt input_prompt">In [89]:</div>
17673 <div class="inner_cell">
17674 <div class="input_area">
17675 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">make_reify_reducer</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">env</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">form</span><span class="p">:</span> <span class="n">value_of</span><span class="p">(</span><span class="n">reify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">env</span><span class="p">))</span>
17678 <span class="k">def</span> <span class="nf">cycle</span><span class="p">(</span><span class="n">program</span><span class="p">,</span> <span class="n">register</span><span class="p">):</span>
17679 <span class="n">rr</span> <span class="o">=</span> <span class="n">make_reify_reducer</span><span class="p">(</span><span class="n">register</span><span class="p">)</span>
17680 <span class="k">return</span> <span class="p">{</span><span class="n">bit</span><span class="p">:</span> <span class="n">rr</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> <span class="k">for</span> <span class="n">bit</span><span class="p">,</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">program</span><span class="o">.</span><span class="n">iteritems</span><span class="p">()}</span>
17688 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17689 </div><div class="inner_cell">
17690 <div class="text_cell_render border-box-sizing rendered_html">
17691 <p>With all the register values at "zero" (Void) nothing happens.</p>
17696 <div class="cell border-box-sizing code_cell rendered">
17697 <div class="input">
17698 <div class="prompt input_prompt">In [90]:</div>
17699 <div class="inner_cell">
17700 <div class="input_area">
17701 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">R</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">cycle</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">R</span><span class="p">))</span>
17702 <span class="n">R</span>
17709 <div class="output_wrapper">
17710 <div class="output">
17713 <div class="output_area">
17715 <div class="prompt output_prompt">Out[90]:</div>
17720 <div class="output_text output_subarea output_execute_result">
17721 <pre>{'Cin': (()),
17722 'Cout': (()),
17723 'a0': (()),
17724 'a1': (()),
17725 'a2': (()),
17726 'a3': (()),
17727 'b0': (()),
17728 'b1': (()),
17729 'b2': (()),
17730 'b3': (())}</pre>
17739 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17740 </div><div class="inner_cell">
17741 <div class="text_cell_render border-box-sizing rendered_html">
17742 <p>Let's make a nice display function to inspect our little adder computer.</p>
17747 <div class="cell border-box-sizing code_cell rendered">
17748 <div class="input">
17749 <div class="prompt input_prompt">In [91]:</div>
17750 <div class="inner_cell">
17751 <div class="input_area">
17752 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">show_as_int</span><span class="p">(</span><span class="o">*</span><span class="n">names</span><span class="p">):</span>
17753 <span class="sd">'''</span>
17754 <span class="sd"> Return a function that converts a sequence of</span>
17755 <span class="sd"> named bits (as Void/Mark values) into a integer.</span>
17756 <span class="sd"> '''</span>
17757 <span class="k">def</span> <span class="nf">inner</span><span class="p">(</span><span class="n">register</span><span class="p">):</span>
17758 <span class="n">i</span><span class="p">,</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
17759 <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
17760 <span class="k">if</span> <span class="ow">not</span> <span class="n">register</span><span class="p">[</span><span class="n">name</span><span class="p">]:</span>
17761 <span class="n">i</span> <span class="o">+=</span> <span class="n">n</span>
17762 <span class="n">n</span> <span class="o"><<=</span> <span class="mi">1</span>
17763 <span class="k">return</span> <span class="n">i</span>
17764 <span class="k">return</span> <span class="n">inner</span>
17772 <div class="cell border-box-sizing code_cell rendered">
17773 <div class="input">
17774 <div class="prompt input_prompt">In [92]:</div>
17775 <div class="inner_cell">
17776 <div class="input_area">
17777 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">a_register</span> <span class="o">=</span> <span class="n">show_as_int</span><span class="p">(</span><span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'a3'</span><span class="p">)</span>
17778 <span class="n">b_register</span> <span class="o">=</span> <span class="n">show_as_int</span><span class="p">(</span><span class="s1">'b0'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">)</span>
17781 <span class="k">def</span> <span class="nf">show_computer_state</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
17782 <span class="nb">print</span> <span class="s1">'a: </span><span class="si">%-3i</span><span class="s1"> b: </span><span class="si">%-3i</span><span class="s1"> Cin: </span><span class="si">%-3i</span><span class="s1"> Cout: </span><span class="si">%-3i</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
17783 <span class="n">a_register</span><span class="p">(</span><span class="n">R</span><span class="p">),</span>
17784 <span class="n">b_register</span><span class="p">(</span><span class="n">R</span><span class="p">),</span>
17785 <span class="nb">int</span><span class="p">(</span><span class="ow">not</span> <span class="n">R</span><span class="p">[</span><span class="s1">'Cin'</span><span class="p">]),</span>
17786 <span class="nb">int</span><span class="p">(</span><span class="ow">not</span> <span class="n">R</span><span class="p">[</span><span class="s1">'Cout'</span><span class="p">]),</span>
17787 <span class="p">)</span>
17795 <div class="cell border-box-sizing code_cell rendered">
17796 <div class="input">
17797 <div class="prompt input_prompt">In [93]:</div>
17798 <div class="inner_cell">
17799 <div class="input_area">
17800 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">show_computer_state</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
17807 <div class="output_wrapper">
17808 <div class="output">
17811 <div class="output_area">
17813 <div class="prompt"></div>
17816 <div class="output_subarea output_stream output_stdout output_text">
17817 <pre>a: 0 b: 0 Cin: 0 Cout: 0
17826 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17827 </div><div class="inner_cell">
17828 <div class="text_cell_render border-box-sizing rendered_html">
17829 <p>Let's set one bit to true (Mark-valued in the chosen convention. We could have Void be true but we would have to form the circuit expressions differently.)</p>
17834 <div class="cell border-box-sizing code_cell rendered">
17835 <div class="input">
17836 <div class="prompt input_prompt">In [94]:</div>
17837 <div class="inner_cell">
17838 <div class="input_area">
17839 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">R</span><span class="p">[</span><span class="s1">'a0'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Mark</span>
17847 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17848 </div><div class="inner_cell">
17849 <div class="text_cell_render border-box-sizing rendered_html">
17850 <p>Now let's count to twenty.</p>
17855 <div class="cell border-box-sizing code_cell rendered">
17856 <div class="input">
17857 <div class="prompt input_prompt">In [95]:</div>
17858 <div class="inner_cell">
17859 <div class="input_area">
17860 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
17861 <span class="n">show_computer_state</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
17862 <span class="n">R</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">cycle</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">R</span><span class="p">))</span>
17869 <div class="output_wrapper">
17870 <div class="output">
17873 <div class="output_area">
17875 <div class="prompt"></div>
17878 <div class="output_subarea output_stream output_stdout output_text">
17879 <pre>a: 1 b: 0 Cin: 0 Cout: 0
17880 a: 1 b: 1 Cin: 0 Cout: 0
17881 a: 1 b: 2 Cin: 0 Cout: 0
17882 a: 1 b: 3 Cin: 0 Cout: 0
17883 a: 1 b: 4 Cin: 0 Cout: 0
17884 a: 1 b: 5 Cin: 0 Cout: 0
17885 a: 1 b: 6 Cin: 0 Cout: 0
17886 a: 1 b: 7 Cin: 0 Cout: 0
17887 a: 1 b: 8 Cin: 0 Cout: 0
17888 a: 1 b: 9 Cin: 0 Cout: 0
17889 a: 1 b: 10 Cin: 0 Cout: 0
17890 a: 1 b: 11 Cin: 0 Cout: 0
17891 a: 1 b: 12 Cin: 0 Cout: 0
17892 a: 1 b: 13 Cin: 0 Cout: 0
17893 a: 1 b: 14 Cin: 0 Cout: 0
17894 a: 1 b: 15 Cin: 0 Cout: 0
17895 a: 1 b: 0 Cin: 0 Cout: 1
17896 a: 1 b: 1 Cin: 0 Cout: 0
17897 a: 1 b: 2 Cin: 0 Cout: 0
17898 a: 1 b: 3 Cin: 0 Cout: 0
17907 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17908 </div><div class="inner_cell">
17909 <div class="text_cell_render border-box-sizing rendered_html">
17910 <p>You can see that at the sixteenth step the "Cout" carry bit is true and the count cycles back to zero.</p>
17915 <div class="cell border-box-sizing code_cell rendered">
17916 <div class="input">
17917 <div class="prompt input_prompt">In [96]:</div>
17918 <div class="inner_cell">
17919 <div class="input_area">
17920 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Reset the register.</span>
17921 <span class="n">R</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">Void</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="s1">'Cin a3 a2 a1 a0 b3 b2 b1 b0 Cout'</span><span class="o">.</span><span class="n">split</span><span class="p">()}</span>
17923 <span class="c1"># Count by three.</span>
17924 <span class="n">R</span><span class="p">[</span><span class="s1">'a0'</span><span class="p">]</span> <span class="o">=</span> <span class="n">R</span><span class="p">[</span><span class="s1">'a1'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Mark</span>
17926 <span class="c1"># Print out twenty cycles.</span>
17927 <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
17928 <span class="n">show_computer_state</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
17929 <span class="n">R</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">cycle</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">R</span><span class="p">))</span>
17936 <div class="output_wrapper">
17937 <div class="output">
17940 <div class="output_area">
17942 <div class="prompt"></div>
17945 <div class="output_subarea output_stream output_stdout output_text">
17946 <pre>a: 3 b: 0 Cin: 0 Cout: 0
17947 a: 3 b: 3 Cin: 0 Cout: 0
17948 a: 3 b: 6 Cin: 0 Cout: 0
17949 a: 3 b: 9 Cin: 0 Cout: 0
17950 a: 3 b: 12 Cin: 0 Cout: 0
17951 a: 3 b: 15 Cin: 0 Cout: 0
17952 a: 3 b: 2 Cin: 0 Cout: 1
17953 a: 3 b: 5 Cin: 0 Cout: 0
17954 a: 3 b: 8 Cin: 0 Cout: 0
17955 a: 3 b: 11 Cin: 0 Cout: 0
17956 a: 3 b: 14 Cin: 0 Cout: 0
17957 a: 3 b: 1 Cin: 0 Cout: 1
17958 a: 3 b: 4 Cin: 0 Cout: 0
17959 a: 3 b: 7 Cin: 0 Cout: 0
17960 a: 3 b: 10 Cin: 0 Cout: 0
17961 a: 3 b: 13 Cin: 0 Cout: 0
17962 a: 3 b: 0 Cin: 0 Cout: 1
17963 a: 3 b: 3 Cin: 0 Cout: 0
17964 a: 3 b: 6 Cin: 0 Cout: 0
17965 a: 3 b: 9 Cin: 0 Cout: 0
17974 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17975 </div><div class="inner_cell">
17976 <div class="text_cell_render border-box-sizing rendered_html">
17977 <p>You can see that the "b" bits are indeed counting by threes: 0, 3, 6, 9, 12, 15 & carry, 2, 5, 8, 11, 14 & carry, 1, 4, 7, 10, 13 & carry, 0, 3, 6, 9, ...</p>
17978 <p>This is my basic model for computation: A register, a program, and a cycle function. Note that reducing the form on each cycle isn't necessary, we can run the cycles and just <code>reify()</code> without reducing and we get new circuits that define bits in terms of the register values N cycles in the past.</p>
17983 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
17984 </div><div class="inner_cell">
17985 <div class="text_cell_render border-box-sizing rendered_html">
17986 <h3 id="Simple-One-Dimensional-Cellular-Automaton">Simple One-Dimensional Cellular Automaton<a class="anchor-link" href="#Simple-One-Dimensional-Cellular-Automaton">¶</a></h3>
17990 <div class="cell border-box-sizing code_cell rendered">
17991 <div class="input">
17992 <div class="prompt input_prompt">In [97]:</div>
17993 <div class="inner_cell">
17994 <div class="input_area">
17995 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Universe</span>
17996 <span class="n">U</span> <span class="o">=</span> <span class="s1">'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'</span>
17999 <span class="c1"># Register.</span>
18000 <span class="n">R</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">Void</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">U</span><span class="p">}</span>
18003 <span class="c1"># A program to XOR each bit with its neighbor, wrapping at the edge.</span>
18004 <span class="n">P</span> <span class="o">=</span> <span class="p">{</span>
18005 <span class="n">name</span><span class="p">:</span> <span class="n">xor</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">U</span><span class="p">[(</span><span class="n">U</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">U</span><span class="p">)])</span>
18006 <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">U</span>
18007 <span class="p">}</span>
18010 <span class="k">def</span> <span class="nf">show</span><span class="p">(</span><span class="n">reg</span><span class="p">):</span>
18011 <span class="sd">'''Simple visualization of the register.'''</span>
18012 <span class="nb">print</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'.0'</span><span class="p">[</span><span class="ow">not</span> <span class="n">reg</span><span class="p">[</span><span class="n">name</span><span class="p">]]</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">U</span><span class="p">)</span>
18015 <span class="c1"># Set one "bit" in the register.</span>
18016 <span class="n">R</span><span class="p">[</span><span class="n">U</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]]</span> <span class="o">=</span> <span class="n">Mark</span>
18019 <span class="c1"># Run through some cycles.</span>
18020 <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
18021 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18022 <span class="n">R</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">cycle</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">R</span><span class="p">))</span>
18029 <div class="output_wrapper">
18030 <div class="output">
18033 <div class="output_area">
18035 <div class="prompt"></div>
18038 <div class="output_subarea output_stream output_stdout output_text">
18039 <pre>...................................................0
18040 ..................................................00
18041 .................................................0.0
18042 ................................................0000
18043 ...............................................0...0
18044 ..............................................00..00
18045 .............................................0.0.0.0
18046 ............................................00000000
18047 ...........................................0.......0
18048 ..........................................00......00
18049 .........................................0.0.....0.0
18050 ........................................0000....0000
18051 .......................................0...0...0...0
18052 ......................................00..00..00..00
18053 .....................................0.0.0.0.0.0.0.0
18054 ....................................0000000000000000
18055 ...................................0...............0
18056 ..................................00..............00
18057 .................................0.0.............0.0
18058 ................................0000............0000
18059 ...............................0...0...........0...0
18060 ..............................00..00..........00..00
18061 .............................0.0.0.0.........0.0.0.0
18062 ............................00000000........00000000
18063 ...........................0.......0.......0.......0
18064 ..........................00......00......00......00
18065 .........................0.0.....0.0.....0.0.....0.0
18066 ........................0000....0000....0000....0000
18067 .......................0...0...0...0...0...0...0...0
18068 ......................00..00..00..00..00..00..00..00
18069 .....................0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
18070 ....................00000000000000000000000000000000
18071 ...................0...............................0
18072 ..................00..............................00
18073 .................0.0.............................0.0
18074 ................0000............................0000
18075 ...............0...0...........................0...0
18076 ..............00..00..........................00..00
18077 .............0.0.0.0.........................0.0.0.0
18078 ............00000000........................00000000
18079 ...........0.......0.......................0.......0
18080 ..........00......00......................00......00
18081 .........0.0.....0.0.....................0.0.....0.0
18082 ........0000....0000....................0000....0000
18083 .......0...0...0...0...................0...0...0...0
18084 ......00..00..00..00..................00..00..00..00
18085 .....0.0.0.0.0.0.0.0.................0.0.0.0.0.0.0.0
18086 ....0000000000000000................0000000000000000
18087 ...0...............0...............0...............0
18088 ..00..............00..............00..............00
18089 .0.0.............0.0.............0.0.............0.0
18090 0000............0000............0000............0000
18091 ...0...........0...0...........0...0...........0....
18092 ..00..........00..00..........00..00..........00....
18093 .0.0.........0.0.0.0.........0.0.0.0.........0.0....
18094 0000........00000000........00000000........0000....
18095 ...0.......0.......0.......0.......0.......0...0...0
18096 ..00......00......00......00......00......00..00..00
18097 .0.0.....0.0.....0.0.....0.0.....0.0.....0.0.0.0.0.0
18098 0000....0000....0000....0000....0000....000000000000
18099 ...0...0...0...0...0...0...0...0...0...0............
18100 ..00..00..00..00..00..00..00..00..00..00............
18101 .0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0............
18102 0000000000000000000000000000000000000000............
18103 .......................................0...........0
18104 ......................................00..........00
18105 .....................................0.0.........0.0
18106 ....................................0000........0000
18107 ...................................0...0.......0...0
18108 ..................................00..00......00..00
18109 .................................0.0.0.0.....0.0.0.0
18110 ................................00000000....00000000
18111 ...............................0.......0...0.......0
18112 ..............................00......00..00......00
18113 .............................0.0.....0.0.0.0.....0.0
18114 ............................0000....00000000....0000
18115 ...........................0...0...0.......0...0...0
18116 ..........................00..00..00......00..00..00
18117 .........................0.0.0.0.0.0.....0.0.0.0.0.0
18118 ........................000000000000....000000000000
18119 .......................0...........0...0...........0
18120 ......................00..........00..00..........00
18121 .....................0.0.........0.0.0.0.........0.0
18122 ....................0000........00000000........0000
18123 ...................0...0.......0.......0.......0...0
18124 ..................00..00......00......00......00..00
18125 .................0.0.0.0.....0.0.....0.0.....0.0.0.0
18126 ................00000000....0000....0000....00000000
18127 ...............0.......0...0...0...0...0...0.......0
18128 ..............00......00..00..00..00..00..00......00
18129 .............0.0.....0.0.0.0.0.0.0.0.0.0.0.0.....0.0
18130 ............0000....000000000000000000000000....0000
18131 ...........0...0...0.......................0...0...0
18132 ..........00..00..00......................00..00..00
18133 .........0.0.0.0.0.0.....................0.0.0.0.0.0
18134 ........000000000000....................000000000000
18135 .......0...........0...................0...........0
18136 ......00..........00..................00..........00
18137 .....0.0.........0.0.................0.0.........0.0
18138 ....0000........0000................0000........0000
18147 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18148 </div><div class="inner_cell">
18149 <div class="text_cell_render border-box-sizing rendered_html">
18150 <h3 id="A-More-Efficient-Implementation">A More Efficient Implementation<a class="anchor-link" href="#A-More-Efficient-Implementation">¶</a></h3><p>Before building larger "computers" I want to switch to a more efficient implementation based on a register as a <code>set</code> of names that are currently Mark-valued, and a <code>set_solve()</code> function that evaluates a form in terms of such a <code>set</code>, and assuming all other names are Void-valued.</p>
18155 <div class="cell border-box-sizing code_cell rendered">
18156 <div class="input">
18157 <div class="prompt input_prompt">In [98]:</div>
18158 <div class="inner_cell">
18159 <div class="input_area">
18160 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">set_solve</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">marks</span><span class="p">):</span>
18161 <span class="sd">'''</span>
18162 <span class="sd"> Given a form and a set of names that are Marks assume all other names</span>
18163 <span class="sd"> in the form are Void and reduce to basic value (Mark or Void.)</span>
18164 <span class="sd"> '''</span>
18165 <span class="k">return</span> <span class="p">(</span>
18166 <span class="p">(</span><span class="n">Void</span><span class="p">,</span> <span class="n">Mark</span><span class="p">)[</span><span class="n">form</span> <span class="ow">in</span> <span class="n">marks</span><span class="p">]</span>
18167 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">basestring</span><span class="p">)</span>
18168 <span class="k">else</span> <span class="n">_set_solve</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">marks</span><span class="p">)</span>
18169 <span class="p">)</span>
18172 <span class="k">def</span> <span class="nf">_set_solve</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">marks</span><span class="p">):</span>
18173 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">form</span><span class="p">:</span>
18174 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
18175 <span class="k">if</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">marks</span><span class="p">:</span>
18176 <span class="k">return</span> <span class="n">Void</span>
18177 <span class="k">continue</span>
18178 <span class="k">if</span> <span class="ow">not</span> <span class="n">_set_solve</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">marks</span><span class="p">):</span> <span class="c1"># Mark</span>
18179 <span class="k">return</span> <span class="n">Void</span>
18180 <span class="k">return</span> <span class="n">Mark</span>
18188 <div class="cell border-box-sizing code_cell rendered">
18189 <div class="input">
18190 <div class="prompt input_prompt">In [99]:</div>
18191 <div class="inner_cell">
18192 <div class="input_area">
18193 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">A</span> <span class="o">=</span> <span class="n">F</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>
18194 <span class="nb">print</span> <span class="n">A</span>
18195 <span class="nb">print</span> <span class="n">set_solve</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="p">{</span><span class="n">a</span><span class="p">})</span>
18196 <span class="nb">print</span> <span class="n">set_solve</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>
18197 <span class="nb">print</span> <span class="n">set_solve</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="p">{</span><span class="n">c</span><span class="p">})</span>
18204 <div class="output_wrapper">
18205 <div class="output">
18208 <div class="output_area">
18210 <div class="prompt"></div>
18213 <div class="output_subarea output_stream output_stdout output_text">
18226 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18227 </div><div class="inner_cell">
18228 <div class="text_cell_render border-box-sizing rendered_html">
18229 <p>To calculate the new R first collect all the names in R that are not mentioned in P (and so cannot be
18230 set to Void by it) then add the names evaluated by solving P's expressions with the marks in R.</p>
18235 <div class="cell border-box-sizing code_cell rendered">
18236 <div class="input">
18237 <div class="prompt input_prompt">In [100]:</div>
18238 <div class="inner_cell">
18239 <div class="input_area">
18240 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">):</span>
18241 <span class="k">return</span> <span class="n">R</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">P</span><span class="p">)</span><span class="o">.</span><span class="n">union</span><span class="p">(</span>
18242 <span class="n">signal</span>
18243 <span class="k">for</span> <span class="n">signal</span><span class="p">,</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">P</span><span class="o">.</span><span class="n">iteritems</span><span class="p">()</span>
18244 <span class="k">if</span> <span class="ow">not</span> <span class="n">set_solve</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">R</span><span class="p">)</span>
18245 <span class="p">)</span>
18253 <div class="cell border-box-sizing code_cell rendered">
18254 <div class="input">
18255 <div class="prompt input_prompt">In [101]:</div>
18256 <div class="inner_cell">
18257 <div class="input_area">
18258 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Universe</span>
18259 <span class="n">U</span> <span class="o">=</span> <span class="s1">'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'</span>
18262 <span class="c1"># Register.</span>
18263 <span class="n">R</span> <span class="o">=</span> <span class="p">{</span><span class="n">U</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]}</span>
18266 <span class="c1"># A program to XOR each bit with its neighbor, wrapping at the edge.</span>
18267 <span class="n">P</span> <span class="o">=</span> <span class="p">{</span>
18268 <span class="n">name</span><span class="p">:</span> <span class="n">xor</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">U</span><span class="p">[(</span><span class="n">U</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">U</span><span class="p">)])</span>
18269 <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">U</span>
18270 <span class="p">}</span>
18273 <span class="k">def</span> <span class="nf">show</span><span class="p">(</span><span class="n">reg</span><span class="p">):</span>
18274 <span class="sd">'''Simple visualization of the register.'''</span>
18275 <span class="nb">print</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'.0'</span><span class="p">[</span><span class="n">name</span> <span class="ow">in</span> <span class="n">reg</span><span class="p">]</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">U</span><span class="p">)</span>
18278 <span class="c1"># Run through some cycles.</span>
18279 <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
18280 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18281 <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18288 <div class="output_wrapper">
18289 <div class="output">
18292 <div class="output_area">
18294 <div class="prompt"></div>
18297 <div class="output_subarea output_stream output_stdout output_text">
18298 <pre>...................................................0
18299 ..................................................00
18300 .................................................0.0
18301 ................................................0000
18302 ...............................................0...0
18303 ..............................................00..00
18304 .............................................0.0.0.0
18305 ............................................00000000
18306 ...........................................0.......0
18307 ..........................................00......00
18308 .........................................0.0.....0.0
18309 ........................................0000....0000
18310 .......................................0...0...0...0
18311 ......................................00..00..00..00
18312 .....................................0.0.0.0.0.0.0.0
18313 ....................................0000000000000000
18314 ...................................0...............0
18315 ..................................00..............00
18316 .................................0.0.............0.0
18317 ................................0000............0000
18318 ...............................0...0...........0...0
18319 ..............................00..00..........00..00
18320 .............................0.0.0.0.........0.0.0.0
18321 ............................00000000........00000000
18322 ...........................0.......0.......0.......0
18323 ..........................00......00......00......00
18324 .........................0.0.....0.0.....0.0.....0.0
18325 ........................0000....0000....0000....0000
18326 .......................0...0...0...0...0...0...0...0
18327 ......................00..00..00..00..00..00..00..00
18328 .....................0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
18329 ....................00000000000000000000000000000000
18330 ...................0...............................0
18331 ..................00..............................00
18332 .................0.0.............................0.0
18333 ................0000............................0000
18334 ...............0...0...........................0...0
18335 ..............00..00..........................00..00
18336 .............0.0.0.0.........................0.0.0.0
18337 ............00000000........................00000000
18338 ...........0.......0.......................0.......0
18339 ..........00......00......................00......00
18340 .........0.0.....0.0.....................0.0.....0.0
18341 ........0000....0000....................0000....0000
18342 .......0...0...0...0...................0...0...0...0
18343 ......00..00..00..00..................00..00..00..00
18344 .....0.0.0.0.0.0.0.0.................0.0.0.0.0.0.0.0
18345 ....0000000000000000................0000000000000000
18346 ...0...............0...............0...............0
18347 ..00..............00..............00..............00
18348 .0.0.............0.0.............0.0.............0.0
18349 0000............0000............0000............0000
18350 ...0...........0...0...........0...0...........0....
18351 ..00..........00..00..........00..00..........00....
18352 .0.0.........0.0.0.0.........0.0.0.0.........0.0....
18353 0000........00000000........00000000........0000....
18354 ...0.......0.......0.......0.......0.......0...0...0
18355 ..00......00......00......00......00......00..00..00
18356 .0.0.....0.0.....0.0.....0.0.....0.0.....0.0.0.0.0.0
18357 0000....0000....0000....0000....0000....000000000000
18358 ...0...0...0...0...0...0...0...0...0...0............
18359 ..00..00..00..00..00..00..00..00..00..00............
18360 .0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0............
18361 0000000000000000000000000000000000000000............
18362 .......................................0...........0
18363 ......................................00..........00
18364 .....................................0.0.........0.0
18365 ....................................0000........0000
18366 ...................................0...0.......0...0
18367 ..................................00..00......00..00
18368 .................................0.0.0.0.....0.0.0.0
18369 ................................00000000....00000000
18370 ...............................0.......0...0.......0
18371 ..............................00......00..00......00
18372 .............................0.0.....0.0.0.0.....0.0
18373 ............................0000....00000000....0000
18374 ...........................0...0...0.......0...0...0
18375 ..........................00..00..00......00..00..00
18376 .........................0.0.0.0.0.0.....0.0.0.0.0.0
18377 ........................000000000000....000000000000
18378 .......................0...........0...0...........0
18379 ......................00..........00..00..........00
18380 .....................0.0.........0.0.0.0.........0.0
18381 ....................0000........00000000........0000
18382 ...................0...0.......0.......0.......0...0
18383 ..................00..00......00......00......00..00
18384 .................0.0.0.0.....0.0.....0.0.....0.0.0.0
18385 ................00000000....0000....0000....00000000
18386 ...............0.......0...0...0...0...0...0.......0
18387 ..............00......00..00..00..00..00..00......00
18388 .............0.0.....0.0.0.0.0.0.0.0.0.0.0.0.....0.0
18389 ............0000....000000000000000000000000....0000
18390 ...........0...0...0.......................0...0...0
18391 ..........00..00..00......................00..00..00
18392 .........0.0.0.0.0.0.....................0.0.0.0.0.0
18393 ........000000000000....................000000000000
18394 .......0...........0...................0...........0
18395 ......00..........00..................00..........00
18396 .....0.0.........0.0.................0.0.........0.0
18397 ....0000........0000................0000........0000
18406 <div class="cell border-box-sizing code_cell rendered">
18407 <div class="input">
18408 <div class="prompt input_prompt">In [102]:</div>
18409 <div class="inner_cell">
18410 <div class="input_area">
18411 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">set_show_as_int</span><span class="p">(</span><span class="o">*</span><span class="n">names</span><span class="p">):</span>
18412 <span class="k">def</span> <span class="nf">inner</span><span class="p">(</span><span class="n">register</span><span class="p">):</span>
18413 <span class="n">i</span><span class="p">,</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
18414 <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
18415 <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">register</span><span class="p">:</span>
18416 <span class="n">i</span> <span class="o">+=</span> <span class="n">n</span>
18417 <span class="n">n</span> <span class="o"><<=</span> <span class="mi">1</span>
18418 <span class="k">return</span> <span class="n">i</span>
18419 <span class="k">return</span> <span class="n">inner</span>
18427 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18428 </div><div class="inner_cell">
18429 <div class="text_cell_render border-box-sizing rendered_html">
18430 <h3 id="Each-Way-as-If...-Then...">Each-Way as If... Then...<a class="anchor-link" href="#Each-Way-as-If...-Then...">¶</a></h3>
18434 <div class="cell border-box-sizing code_cell rendered">
18435 <div class="input">
18436 <div class="prompt input_prompt">In [103]:</div>
18437 <div class="inner_cell">
18438 <div class="input_area">
18439 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">ifte</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">true</span><span class="p">,</span> <span class="n">false</span><span class="p">):</span>
18440 <span class="k">return</span> <span class="n">F</span><span class="p">(</span>
18441 <span class="p">((</span><span class="n">predicate</span><span class="p">,),</span> <span class="n">true</span><span class="p">),</span>
18442 <span class="p">(</span> <span class="n">predicate</span> <span class="p">,</span> <span class="n">false</span><span class="p">),</span>
18443 <span class="p">)</span>
18446 <span class="n">E</span> <span class="o">=</span> <span class="n">ifte</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="n">c</span><span class="p">)</span>
18449 <span class="n">truth_table</span><span class="p">(</span><span class="n">E</span><span class="p">)</span>
18456 <div class="output_wrapper">
18457 <div class="output">
18460 <div class="output_area">
18462 <div class="prompt"></div>
18465 <div class="output_subarea output_stream output_stdout output_text">
18466 <pre>(((a) b) (a c))
18485 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18486 </div><div class="inner_cell">
18487 <div class="text_cell_render border-box-sizing rendered_html">
18488 <p>If <code>a</code> is Mark-valued the value of the whole form is that of <code>b</code>, but if <code>a</code> is Void-valued the value of the whole form is that of <code>c</code>.</p>
18490 <pre><code>w/ a = ()
18509 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18510 </div><div class="inner_cell">
18511 <div class="text_cell_render border-box-sizing rendered_html">
18512 <h2 id="Flip-Flops-for-Memory">Flip-Flops for Memory<a class="anchor-link" href="#Flip-Flops-for-Memory">¶</a></h2>
18516 <div class="cell border-box-sizing code_cell rendered">
18517 <div class="input">
18518 <div class="prompt input_prompt">In [104]:</div>
18519 <div class="inner_cell">
18520 <div class="input_area">
18521 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">flip_flop</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">reset</span><span class="p">,</span> <span class="n">set_</span><span class="p">):</span>
18522 <span class="k">return</span> <span class="n">F</span><span class="p">(</span><span class="n">reset</span><span class="p">,</span> <span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">set_</span><span class="p">))</span>
18524 <span class="n">q</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="s1">'qrs'</span>
18525 <span class="n">E</span> <span class="o">=</span> <span class="n">flip_flop</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
18526 <span class="n">truth_table</span><span class="p">(</span><span class="n">E</span><span class="p">)</span>
18533 <div class="output_wrapper">
18534 <div class="output">
18537 <div class="output_area">
18539 <div class="prompt"></div>
18542 <div class="output_subarea output_stream output_stdout output_text">
18562 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18563 </div><div class="inner_cell">
18564 <div class="text_cell_render border-box-sizing rendered_html">
18565 <p>This is a form that can be used in a circuit to "remember" a value.</p>
18567 <pre><code>w/ r = ()
18580 w/ s = ___, r = ___
18587 <p>If both are Void then the form is just <code>q</code>, if <code>r</code> is Mark then the form is Void, otherwise if <code>s</code> is Mark the form becomes Mark. This is called a "flip-flop" circuit, and it comprises a simple machine to remember one bit.</p>
18588 <p>Consider a simple computer:</p>
18593 <div class="cell border-box-sizing code_cell rendered">
18594 <div class="input">
18595 <div class="prompt input_prompt">In [105]:</div>
18596 <div class="inner_cell">
18597 <div class="input_area">
18598 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">U</span> <span class="o">=</span> <span class="n">q</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="s1">'qrs'</span>
18600 <span class="n">P</span> <span class="o">=</span> <span class="p">{</span>
18601 <span class="n">q</span><span class="p">:</span> <span class="n">flip_flop</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">),</span>
18602 <span class="n">r</span><span class="p">:</span> <span class="n">Void</span><span class="p">,</span>
18603 <span class="n">s</span><span class="p">:</span> <span class="n">Void</span><span class="p">,</span>
18604 <span class="p">}</span>
18606 <span class="n">R</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> <span class="c1"># Initially all signals are off, Void-valued.</span>
18614 <div class="cell border-box-sizing code_cell rendered">
18615 <div class="input">
18616 <div class="prompt input_prompt">In [106]:</div>
18617 <div class="inner_cell">
18618 <div class="input_area">
18619 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">bools_of</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">universe</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">register</span><span class="p">:</span> <span class="p">(</span><span class="n">name</span> <span class="ow">in</span> <span class="n">register</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">universe</span><span class="p">)</span>
18622 <span class="k">def</span> <span class="nf">simple_show</span><span class="p">(</span><span class="n">universe</span><span class="p">):</span>
18623 <span class="n">B</span> <span class="o">=</span> <span class="n">bools_of</span><span class="p">(</span><span class="n">universe</span><span class="p">)</span>
18624 <span class="k">def</span> <span class="nf">_shower</span><span class="p">(</span><span class="n">register</span><span class="p">):</span>
18625 <span class="nb">print</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'.0'</span><span class="p">[</span><span class="n">b</span><span class="p">]</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">B</span><span class="p">(</span><span class="n">register</span><span class="p">))</span>
18626 <span class="k">return</span> <span class="n">_shower</span>
18634 <div class="cell border-box-sizing code_cell rendered">
18635 <div class="input">
18636 <div class="prompt input_prompt">In [107]:</div>
18637 <div class="inner_cell">
18638 <div class="input_area">
18639 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">show</span> <span class="o">=</span> <span class="n">simple_show</span><span class="p">(</span><span class="n">U</span><span class="p">)</span>
18640 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18647 <div class="output_wrapper">
18648 <div class="output">
18651 <div class="output_area">
18653 <div class="prompt"></div>
18656 <div class="output_subarea output_stream output_stdout output_text">
18666 <div class="cell border-box-sizing code_cell rendered">
18667 <div class="input">
18668 <div class="prompt input_prompt">In [108]:</div>
18669 <div class="inner_cell">
18670 <div class="input_area">
18671 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">SET</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
18672 <span class="n">R</span> <span class="o">|=</span> <span class="p">{</span><span class="n">s</span><span class="p">}</span>
18673 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18674 <span class="k">return</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18677 <span class="k">def</span> <span class="nf">RESET</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
18678 <span class="n">R</span> <span class="o">|=</span> <span class="p">{</span><span class="n">r</span><span class="p">}</span>
18679 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18680 <span class="k">return</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18688 <div class="cell border-box-sizing code_cell rendered">
18689 <div class="input">
18690 <div class="prompt input_prompt">In [109]:</div>
18691 <div class="inner_cell">
18692 <div class="input_area">
18693 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">U</span>
18694 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18695 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18696 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18698 <span class="n">R</span> <span class="o">=</span> <span class="n">SET</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18700 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18701 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18703 <span class="n">R</span> <span class="o">=</span> <span class="n">SET</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18705 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18706 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18708 <span class="n">R</span> <span class="o">=</span> <span class="n">RESET</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18710 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18711 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18713 <span class="n">R</span> <span class="o">=</span> <span class="n">RESET</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
18715 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18716 <span class="n">show</span><span class="p">(</span><span class="n">R</span><span class="p">)</span> <span class="p">;</span> <span class="n">R</span> <span class="o">=</span> <span class="n">set_cycle</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="n">P</span><span class="p">)</span>
18723 <div class="output_wrapper">
18724 <div class="output">
18727 <div class="output_area">
18729 <div class="prompt"></div>
18732 <div class="output_subarea output_stream output_stdout output_text">
18757 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18758 </div><div class="inner_cell">
18759 <div class="text_cell_render border-box-sizing rendered_html">
18760 <p>You can see that <code>q</code> is stable unless <code>s</code> or <code>r</code> set or reset it.</p>
18765 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18766 </div><div class="inner_cell">
18767 <div class="text_cell_render border-box-sizing rendered_html">
18768 <h3 id="Using-Flip-Flops-and-If...Then...Else...-to-make-RAM">Using Flip-Flops and If...Then...Else... to make RAM<a class="anchor-link" href="#Using-Flip-Flops-and-If...Then...Else...-to-make-RAM">¶</a></h3><p>We can use the system we have developed so far to build addressable RAM.</p>
18773 <div class="cell border-box-sizing code_cell rendered">
18774 <div class="input">
18775 <div class="prompt input_prompt">In [110]:</div>
18776 <div class="inner_cell">
18777 <div class="input_area">
18778 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Width in bits of the DATA registers.</span>
18779 <span class="n">WIDTH</span> <span class="o">=</span> <span class="mi">2</span>
18781 <span class="c1"># Width in bits of the ADDR registers.</span>
18782 <span class="n">LENGTH</span> <span class="o">=</span> <span class="mi">3</span> <span class="c1"># Actual length 2**LENGTH</span>
18790 <div class="cell border-box-sizing code_cell rendered">
18791 <div class="input">
18792 <div class="prompt input_prompt">In [111]:</div>
18793 <div class="inner_cell">
18794 <div class="input_area">
18795 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">P</span> <span class="o">=</span> <span class="p">{}</span>
18803 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18804 </div><div class="inner_cell">
18805 <div class="text_cell_render border-box-sizing rendered_html">
18806 <p>We'll assume a single <code>WRITE</code> bit that sets a RAM location determined by the <code>ADDR</code> sub-register to the contents of the <code>DATA</code> sub-register.</p>
18811 <div class="cell border-box-sizing code_cell rendered">
18812 <div class="input">
18813 <div class="prompt input_prompt">In [112]:</div>
18814 <div class="inner_cell">
18815 <div class="input_area">
18816 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">WRITE</span> <span class="o">=</span> <span class="s1">'WRITE'</span>
18824 <div class="cell border-box-sizing code_cell rendered">
18825 <div class="input">
18826 <div class="prompt input_prompt">In [113]:</div>
18827 <div class="inner_cell">
18828 <div class="input_area">
18829 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Address register.</span>
18830 <span class="n">ADDR</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'addr_</span><span class="si">%i</span><span class="s1">'</span> <span class="o">%</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">LENGTH</span><span class="p">)]</span>
18831 <span class="n">ADDR</span>
18838 <div class="output_wrapper">
18839 <div class="output">
18842 <div class="output_area">
18844 <div class="prompt output_prompt">Out[113]:</div>
18849 <div class="output_text output_subarea output_execute_result">
18850 <pre>['addr_0', 'addr_1', 'addr_2']</pre>
18859 <div class="cell border-box-sizing code_cell rendered">
18860 <div class="input">
18861 <div class="prompt input_prompt">In [114]:</div>
18862 <div class="inner_cell">
18863 <div class="input_area">
18864 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Data register.</span>
18865 <span class="n">DATA</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'a</span><span class="si">%i</span><span class="s1">'</span> <span class="o">%</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">WIDTH</span><span class="p">)]</span>
18866 <span class="n">DATA</span>
18873 <div class="output_wrapper">
18874 <div class="output">
18877 <div class="output_area">
18879 <div class="prompt output_prompt">Out[114]:</div>
18884 <div class="output_text output_subarea output_execute_result">
18885 <pre>['a0', 'a1']</pre>
18894 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
18895 </div><div class="inner_cell">
18896 <div class="text_cell_render border-box-sizing rendered_html">
18897 <p>We can recognize which <code>RAM</code> location we want to address by using the <a href="#Each-Row-can-be-Represented-as-an-Expression">expressions for each row from above</a> to create a predicate for each location that depends on the <code>ADDR</code> bits.</p>
18902 <div class="cell border-box-sizing code_cell rendered">
18903 <div class="input">
18904 <div class="prompt input_prompt">In [115]:</div>
18905 <div class="inner_cell">
18906 <div class="input_area">
18907 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">make_ram</span><span class="p">(</span><span class="n">program</span><span class="p">,</span> <span class="n">addrs</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">write</span><span class="p">):</span>
18908 <span class="n">RAM</span> <span class="o">=</span> <span class="p">[]</span>
18909 <span class="k">for</span> <span class="n">addr</span><span class="p">,</span> <span class="n">env</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">environments_of_variables</span><span class="p">(</span><span class="o">*</span><span class="n">addrs</span><span class="p">)):</span>
18911 <span class="n">addr_predicate</span> <span class="o">=</span> <span class="n">F</span><span class="p">((</span><span class="n">name</span><span class="p">,)</span> <span class="k">if</span> <span class="n">env</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">else</span> <span class="n">name</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">env</span><span class="p">)</span>
18913 <span class="n">predicate</span> <span class="o">=</span> <span class="n">and_</span><span class="p">(</span><span class="n">write</span><span class="p">,</span> <span class="n">addr_predicate</span><span class="p">)</span>
18915 <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">width</span><span class="p">):</span>
18916 <span class="n">ram</span> <span class="o">=</span> <span class="s1">'RAM_</span><span class="si">%i</span><span class="s1">_</span><span class="si">%i</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">addr</span><span class="p">,</span> <span class="n">bit</span><span class="p">)</span>
18917 <span class="n">RAM</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">ram</span><span class="p">)</span>
18918 <span class="n">program</span><span class="p">[</span><span class="n">ram</span><span class="p">]</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">ifte</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="n">bit</span><span class="p">],</span> <span class="n">ram</span><span class="p">))</span>
18920 <span class="k">return</span> <span class="n">RAM</span>
18928 <div class="cell border-box-sizing code_cell rendered">
18929 <div class="input">
18930 <div class="prompt input_prompt">In [116]:</div>
18931 <div class="inner_cell">
18932 <div class="input_area">
18933 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">RAM</span> <span class="o">=</span> <span class="n">make_ram</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">ADDR</span><span class="p">,</span> <span class="n">DATA</span><span class="p">,</span> <span class="n">WIDTH</span><span class="p">,</span> <span class="n">WRITE</span><span class="p">)</span>
18934 <span class="n">RAM</span>
18941 <div class="output_wrapper">
18942 <div class="output">
18945 <div class="output_area">
18947 <div class="prompt output_prompt">Out[116]:</div>
18952 <div class="output_text output_subarea output_execute_result">
18953 <pre>['RAM_0_0',
18968 'RAM_7_1']</pre>
18977 <div class="cell border-box-sizing code_cell rendered">
18978 <div class="input">
18979 <div class="prompt input_prompt">In [117]:</div>
18980 <div class="inner_cell">
18981 <div class="input_area">
18982 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">P</span>
18989 <div class="output_wrapper">
18990 <div class="output">
18993 <div class="output_area">
18995 <div class="prompt output_prompt">Out[117]:</div>
19000 <div class="output_text output_subarea output_execute_result">
19001 <pre>{'RAM_0_0': (((((addr_0) (addr_1) (addr_2)) (WRITE)) RAM_0_0) (((addr_0) (addr_1) (addr_2)) (WRITE) a0)),
19002 'RAM_0_1': (((((addr_0) (addr_1) (addr_2)) (WRITE)) RAM_0_1) (((addr_0) (addr_1) (addr_2)) (WRITE) a1)),
19003 'RAM_1_0': (((((addr_0) (addr_1) addr_2) (WRITE)) RAM_1_0) (((addr_0) (addr_1) addr_2) (WRITE) a0)),
19004 'RAM_1_1': (((((addr_0) (addr_1) addr_2) (WRITE)) RAM_1_1) (((addr_0) (addr_1) addr_2) (WRITE) a1)),
19005 'RAM_2_0': (((((addr_0) (addr_2) addr_1) (WRITE)) RAM_2_0) (((addr_0) (addr_2) addr_1) (WRITE) a0)),
19006 'RAM_2_1': (((((addr_0) (addr_2) addr_1) (WRITE)) RAM_2_1) (((addr_0) (addr_2) addr_1) (WRITE) a1)),
19007 'RAM_3_0': (((((addr_0) addr_1 addr_2) (WRITE)) RAM_3_0) (((addr_0) addr_1 addr_2) (WRITE) a0)),
19008 'RAM_3_1': (((((addr_0) addr_1 addr_2) (WRITE)) RAM_3_1) (((addr_0) addr_1 addr_2) (WRITE) a1)),
19009 'RAM_4_0': (((((addr_1) (addr_2) addr_0) (WRITE)) RAM_4_0) (((addr_1) (addr_2) addr_0) (WRITE) a0)),
19010 'RAM_4_1': (((((addr_1) (addr_2) addr_0) (WRITE)) RAM_4_1) (((addr_1) (addr_2) addr_0) (WRITE) a1)),
19011 'RAM_5_0': (((((addr_1) addr_0 addr_2) (WRITE)) RAM_5_0) (((addr_1) addr_0 addr_2) (WRITE) a0)),
19012 'RAM_5_1': (((((addr_1) addr_0 addr_2) (WRITE)) RAM_5_1) (((addr_1) addr_0 addr_2) (WRITE) a1)),
19013 'RAM_6_0': (((((addr_2) addr_0 addr_1) (WRITE)) RAM_6_0) (((addr_2) addr_0 addr_1) (WRITE) a0)),
19014 'RAM_6_1': (((((addr_2) addr_0 addr_1) (WRITE)) RAM_6_1) (((addr_2) addr_0 addr_1) (WRITE) a1)),
19015 'RAM_7_0': ((((WRITE) (addr_0 addr_1 addr_2)) RAM_7_0) ((WRITE) (addr_0 addr_1 addr_2) a0)),
19016 'RAM_7_1': ((((WRITE) (addr_0 addr_1 addr_2)) RAM_7_1) ((WRITE) (addr_0 addr_1 addr_2) a1))}</pre>
19025 <div class="cell border-box-sizing code_cell rendered">
19026 <div class="input">
19027 <div class="prompt input_prompt">In [118]:</div>
19028 <div class="inner_cell">
19029 <div class="input_area">
19030 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">E</span> <span class="o">=</span> <span class="n">P</span><span class="p">[</span><span class="s1">'RAM_0_0'</span><span class="p">]</span>
19031 <span class="n">E</span>
19038 <div class="output_wrapper">
19039 <div class="output">
19042 <div class="output_area">
19044 <div class="prompt output_prompt">Out[118]:</div>
19049 <div class="output_text output_subarea output_execute_result">
19050 <pre>(((((addr_0) (addr_1) (addr_2)) (WRITE)) RAM_0_0) (((addr_0) (addr_1) (addr_2)) (WRITE) a0))</pre>
19059 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19060 </div><div class="inner_cell">
19061 <div class="text_cell_render border-box-sizing rendered_html">
19062 <p>Note that if the <code>WRITE</code> bit is unset then each <code>RAM</code> bit is just set to itself.</p>
19067 <div class="cell border-box-sizing code_cell rendered">
19068 <div class="input">
19069 <div class="prompt input_prompt">In [119]:</div>
19070 <div class="inner_cell">
19071 <div class="input_area">
19072 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">exclude</span><span class="o">=</span><span class="p">{</span><span class="s1">'WRITE'</span><span class="p">})</span>
19079 <div class="output_wrapper">
19080 <div class="output">
19083 <div class="output_area">
19085 <div class="prompt output_prompt">Out[119]:</div>
19090 <div class="output_text output_subarea output_execute_result">
19091 <pre>'RAM_0_0'</pre>
19100 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19101 </div><div class="inner_cell">
19102 <div class="text_cell_render border-box-sizing rendered_html">
19103 <p>But if the <code>WRITE</code> bit is set then each <code>RAM</code> location still depends on the -per-location-predicate.</p>
19108 <div class="cell border-box-sizing code_cell rendered">
19109 <div class="input">
19110 <div class="prompt input_prompt">In [120]:</div>
19111 <div class="inner_cell">
19112 <div class="input_area">
19113 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="s1">'WRITE'</span><span class="p">)</span>
19120 <div class="output_wrapper">
19121 <div class="output">
19124 <div class="output_area">
19126 <div class="prompt output_prompt">Out[120]:</div>
19131 <div class="output_text output_subarea output_execute_result">
19132 <pre>((((addr_0) (addr_1) (addr_2)) a0) ((addr_0) (addr_1) (addr_2) RAM_0_0))</pre>
19141 <div class="cell border-box-sizing code_cell rendered">
19142 <div class="input">
19143 <div class="prompt input_prompt">In [121]:</div>
19144 <div class="inner_cell">
19145 <div class="input_area">
19146 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">make_accumulator</span><span class="p">(</span><span class="n">program</span><span class="p">,</span> <span class="n">addrs</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">read</span><span class="p">,</span> <span class="n">alts</span><span class="p">):</span>
19148 <span class="n">addr_predicates</span> <span class="o">=</span> <span class="p">[</span>
19149 <span class="n">F</span><span class="p">((</span><span class="n">name</span><span class="p">,)</span> <span class="k">if</span> <span class="n">env</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">else</span> <span class="n">name</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">env</span><span class="p">)</span>
19150 <span class="k">for</span> <span class="n">env</span> <span class="ow">in</span> <span class="n">environments_of_variables</span><span class="p">(</span><span class="o">*</span><span class="n">addrs</span><span class="p">)</span>
19151 <span class="p">]</span>
19153 <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">width</span><span class="p">):</span>
19154 <span class="n">a</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">bit</span><span class="p">]</span>
19155 <span class="n">alt</span> <span class="o">=</span> <span class="n">alts</span><span class="p">[</span><span class="n">bit</span><span class="p">]</span>
19156 <span class="n">foo</span> <span class="o">=</span> <span class="n">Void</span>
19157 <span class="k">for</span> <span class="n">addr</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">addr_predicates</span><span class="p">):</span>
19158 <span class="n">ram</span> <span class="o">=</span> <span class="s1">'RAM_</span><span class="si">%i</span><span class="s1">_</span><span class="si">%i</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">addr</span><span class="p">,</span> <span class="n">bit</span><span class="p">)</span>
19159 <span class="n">foo</span> <span class="o">=</span> <span class="p">(</span><span class="n">ifte</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">ram</span><span class="p">,</span> <span class="n">foo</span><span class="p">))</span>
19160 <span class="n">program</span><span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">=</span> <span class="n">ifte</span><span class="p">(</span><span class="n">read</span><span class="p">,</span> <span class="n">foo</span><span class="p">,</span> <span class="n">alt</span><span class="p">)</span>
19168 <div class="cell border-box-sizing code_cell rendered">
19169 <div class="input">
19170 <div class="prompt input_prompt">In [122]:</div>
19171 <div class="inner_cell">
19172 <div class="input_area">
19173 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">p</span> <span class="o">=</span> <span class="p">{}</span>
19174 <span class="n">make_accumulator</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">ADDR</span><span class="p">,</span> <span class="n">DATA</span><span class="p">,</span> <span class="n">WIDTH</span><span class="p">,</span> <span class="s1">'READ'</span><span class="p">,</span> <span class="n">DATA</span><span class="p">)</span>
19175 <span class="n">p</span>
19182 <div class="output_wrapper">
19183 <div class="output">
19186 <div class="output_area">
19188 <div class="prompt output_prompt">Out[122]:</div>
19193 <div class="output_text output_subarea output_execute_result">
19194 <pre>{'a0': ((((((((((((((((((((((addr_0) (addr_1) (addr_2)))) RAM_0_0) ((((addr_0) (addr_1) (addr_2))) (()))) (((addr_0) (addr_1) addr_2))) (((((addr_0) (addr_1) addr_2))) RAM_1_0)) (((addr_0) (addr_2) addr_1))) (((((addr_0) (addr_2) addr_1))) RAM_2_0)) (((addr_0) addr_1 addr_2))) (((((addr_0) addr_1 addr_2))) RAM_3_0)) (((addr_1) (addr_2) addr_0))) (((((addr_1) (addr_2) addr_0))) RAM_4_0)) (((addr_1) addr_0 addr_2))) (((((addr_1) addr_0 addr_2))) RAM_5_0)) (((addr_2) addr_0 addr_1))) (((((addr_2) addr_0 addr_1))) RAM_6_0)) ((addr_0 addr_1 addr_2))) ((((addr_0 addr_1 addr_2))) RAM_7_0)) (READ)) (READ a0)),
19195 'a1': ((((((((((((((((((((((addr_0) (addr_1) (addr_2)))) RAM_0_1) ((((addr_0) (addr_1) (addr_2))) (()))) (((addr_0) (addr_1) addr_2))) (((((addr_0) (addr_1) addr_2))) RAM_1_1)) (((addr_0) (addr_2) addr_1))) (((((addr_0) (addr_2) addr_1))) RAM_2_1)) (((addr_0) addr_1 addr_2))) (((((addr_0) addr_1 addr_2))) RAM_3_1)) (((addr_1) (addr_2) addr_0))) (((((addr_1) (addr_2) addr_0))) RAM_4_1)) (((addr_1) addr_0 addr_2))) (((((addr_1) addr_0 addr_2))) RAM_5_1)) (((addr_2) addr_0 addr_1))) (((((addr_2) addr_0 addr_1))) RAM_6_1)) ((addr_0 addr_1 addr_2))) ((((addr_0 addr_1 addr_2))) RAM_7_1)) (READ)) (READ a1))}</pre>
19204 <div class="cell border-box-sizing code_cell rendered">
19205 <div class="input">
19206 <div class="prompt input_prompt">In [123]:</div>
19207 <div class="inner_cell">
19208 <div class="input_area">
19209 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">E</span> <span class="o">=</span> <span class="n">p</span><span class="p">[</span><span class="n">DATA</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
19210 <span class="n">E</span>
19217 <div class="output_wrapper">
19218 <div class="output">
19221 <div class="output_area">
19223 <div class="prompt output_prompt">Out[123]:</div>
19228 <div class="output_text output_subarea output_execute_result">
19229 <pre>((((((((((((((((((((((addr_0) (addr_1) (addr_2)))) RAM_0_0) ((((addr_0) (addr_1) (addr_2))) (()))) (((addr_0) (addr_1) addr_2))) (((((addr_0) (addr_1) addr_2))) RAM_1_0)) (((addr_0) (addr_2) addr_1))) (((((addr_0) (addr_2) addr_1))) RAM_2_0)) (((addr_0) addr_1 addr_2))) (((((addr_0) addr_1 addr_2))) RAM_3_0)) (((addr_1) (addr_2) addr_0))) (((((addr_1) (addr_2) addr_0))) RAM_4_0)) (((addr_1) addr_0 addr_2))) (((((addr_1) addr_0 addr_2))) RAM_5_0)) (((addr_2) addr_0 addr_1))) (((((addr_2) addr_0 addr_1))) RAM_6_0)) ((addr_0 addr_1 addr_2))) ((((addr_0 addr_1 addr_2))) RAM_7_0)) (READ)) (READ a0))</pre>
19238 <div class="cell border-box-sizing code_cell rendered">
19239 <div class="input">
19240 <div class="prompt input_prompt">In [124]:</div>
19241 <div class="inner_cell">
19242 <div class="input_area">
19243 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="s1">'READ'</span><span class="p">)</span>
19250 <div class="output_wrapper">
19251 <div class="output">
19254 <div class="output_area">
19256 <div class="prompt output_prompt">Out[124]:</div>
19261 <div class="output_text output_subarea output_execute_result">
19262 <pre>((((((((((((((((((addr_0) (addr_1) (addr_2)) RAM_0_0) ((addr_0) (addr_1) (addr_2))) (addr_0) (addr_1) addr_2) (((addr_0) (addr_1) addr_2) RAM_1_0)) (addr_0) (addr_2) addr_1) (((addr_0) (addr_2) addr_1) RAM_2_0)) (addr_0) addr_1 addr_2) (((addr_0) addr_1 addr_2) RAM_3_0)) (addr_1) (addr_2) addr_0) (((addr_1) (addr_2) addr_0) RAM_4_0)) (addr_1) addr_0 addr_2) (((addr_1) addr_0 addr_2) RAM_5_0)) (addr_2) addr_0 addr_1) (((addr_2) addr_0 addr_1) RAM_6_0)) addr_0 addr_1 addr_2) ((addr_0 addr_1 addr_2) RAM_7_0))</pre>
19271 <div class="cell border-box-sizing code_cell rendered">
19272 <div class="input">
19273 <div class="prompt input_prompt">In [125]:</div>
19274 <div class="inner_cell">
19275 <div class="input_area">
19276 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">simplify</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="p">{</span><span class="s1">'READ'</span><span class="p">})</span>
19283 <div class="output_wrapper">
19284 <div class="output">
19287 <div class="output_area">
19289 <div class="prompt output_prompt">Out[125]:</div>
19294 <div class="output_text output_subarea output_execute_result">
19295 <pre>'a0'</pre>
19304 <div class="cell border-box-sizing code_cell rendered">
19305 <div class="input">
19306 <div class="prompt input_prompt">In [126]:</div>
19307 <div class="inner_cell">
19308 <div class="input_area">
19309 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">each_way</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="s1">'a0'</span><span class="p">)</span>
19316 <div class="output_wrapper">
19317 <div class="output">
19320 <div class="output_area">
19322 <div class="prompt output_prompt">Out[126]:</div>
19327 <div class="output_text output_subarea output_execute_result">
19328 <pre>((((((((((((((((((((((addr_0) (addr_1) (addr_2)) RAM_0_0) ((addr_0) (addr_1) (addr_2))) (addr_0) (addr_1) addr_2) (((addr_0) (addr_1) addr_2) RAM_1_0)) (addr_0) (addr_2) addr_1) (((addr_0) (addr_2) addr_1) RAM_2_0)) (addr_0) addr_1 addr_2) (((addr_0) addr_1 addr_2) RAM_3_0)) (addr_1) (addr_2) addr_0) (((addr_1) (addr_2) addr_0) RAM_4_0)) (addr_1) addr_0 addr_2) (((addr_1) addr_0 addr_2) RAM_5_0)) (addr_2) addr_0 addr_1) (((addr_2) addr_0 addr_1) RAM_6_0)) addr_0 addr_1 addr_2) ((addr_0 addr_1 addr_2) RAM_7_0)) (READ)) (READ)) a0) ((((addr_0 addr_1 addr_2) RAM_7_0) (RAM_6_0 addr_0 addr_1 addr_2)) (READ) (a0)))</pre>
19337 <div class="cell border-box-sizing code_cell rendered">
19338 <div class="input">
19339 <div class="prompt input_prompt">In [ ]:</div>
19340 <div class="inner_cell">
19341 <div class="input_area">
19342 <div class=" highlight hl-ipython2"><pre><span></span>
19350 <div class="cell border-box-sizing code_cell rendered">
19351 <div class="input">
19352 <div class="prompt input_prompt">In [ ]:</div>
19353 <div class="inner_cell">
19354 <div class="input_area">
19355 <div class=" highlight hl-ipython2"><pre><span></span>
19363 <div class="cell border-box-sizing code_cell rendered">
19364 <div class="input">
19365 <div class="prompt input_prompt">In [ ]:</div>
19366 <div class="inner_cell">
19367 <div class="input_area">
19368 <div class=" highlight hl-ipython2"><pre><span></span>
19376 <div class="cell border-box-sizing code_cell rendered">
19377 <div class="input">
19378 <div class="prompt input_prompt">In [127]:</div>
19379 <div class="inner_cell">
19380 <div class="input_area">
19381 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">each_way</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="s1">'WRITE'</span><span class="p">)</span>
19388 <div class="output_wrapper">
19389 <div class="output">
19392 <div class="output_area">
19394 <div class="prompt output_prompt">Out[127]:</div>
19399 <div class="output_text output_subarea output_execute_result">
19400 <pre>((((((((((((((((((((((addr_0) (addr_1) (addr_2)) RAM_0_0) ((addr_0) (addr_1) (addr_2))) (addr_0) (addr_1) addr_2) (((addr_0) (addr_1) addr_2) RAM_1_0)) (addr_0) (addr_2) addr_1) (((addr_0) (addr_2) addr_1) RAM_2_0)) (addr_0) addr_1 addr_2) (((addr_0) addr_1 addr_2) RAM_3_0)) (addr_1) (addr_2) addr_0) (((addr_1) (addr_2) addr_0) RAM_4_0)) (addr_1) addr_0 addr_2) (((addr_1) addr_0 addr_2) RAM_5_0)) (addr_2) addr_0 addr_1) (((addr_2) addr_0 addr_1) RAM_6_0)) addr_0 addr_1 addr_2) ((addr_0 addr_1 addr_2) RAM_7_0)) (READ)) (READ a0)) WRITE) ((((((addr_0 addr_1 addr_2) RAM_7_0) (RAM_6_0 addr_0 addr_1 addr_2)) (READ)) (READ a0)) (WRITE)))</pre>
19409 <div class="cell border-box-sizing code_cell rendered">
19410 <div class="input">
19411 <div class="prompt input_prompt">In [128]:</div>
19412 <div class="inner_cell">
19413 <div class="input_area">
19414 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">each_way</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="s1">'addr_0'</span><span class="p">)</span>
19421 <div class="output_wrapper">
19422 <div class="output">
19425 <div class="output_area">
19427 <div class="prompt output_prompt">Out[128]:</div>
19432 <div class="output_text output_subarea output_execute_result">
19433 <pre>((((((((((((((addr_1) (addr_2)) RAM_4_0) ((addr_1) (addr_2) RAM_3_0)) (addr_1) addr_2) (((addr_1) addr_2) RAM_5_0)) (addr_2) addr_1) (((addr_2) addr_1) RAM_6_0)) addr_1 addr_2) ((addr_1 addr_2) RAM_7_0)) (READ)) (READ a0)) addr_0) ((((READ) RAM_7_0) (READ a0)) (addr_0)))</pre>
19442 <div class="cell border-box-sizing code_cell rendered">
19443 <div class="input">
19444 <div class="prompt input_prompt">In [129]:</div>
19445 <div class="inner_cell">
19446 <div class="input_area">
19447 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">each_way</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="s1">'a0'</span><span class="p">)</span>
19454 <div class="output_wrapper">
19455 <div class="output">
19458 <div class="output_area">
19460 <div class="prompt output_prompt">Out[129]:</div>
19465 <div class="output_text output_subarea output_execute_result">
19466 <pre>((((((((((((((((((((((addr_0) (addr_1) (addr_2)) RAM_0_0) ((addr_0) (addr_1) (addr_2))) (addr_0) (addr_1) addr_2) (((addr_0) (addr_1) addr_2) RAM_1_0)) (addr_0) (addr_2) addr_1) (((addr_0) (addr_2) addr_1) RAM_2_0)) (addr_0) addr_1 addr_2) (((addr_0) addr_1 addr_2) RAM_3_0)) (addr_1) (addr_2) addr_0) (((addr_1) (addr_2) addr_0) RAM_4_0)) (addr_1) addr_0 addr_2) (((addr_1) addr_0 addr_2) RAM_5_0)) (addr_2) addr_0 addr_1) (((addr_2) addr_0 addr_1) RAM_6_0)) addr_0 addr_1 addr_2) ((addr_0 addr_1 addr_2) RAM_7_0)) (READ)) (READ)) a0) ((((addr_0 addr_1 addr_2) RAM_7_0) (RAM_6_0 addr_0 addr_1 addr_2)) (READ) (a0)))</pre>
19475 <div class="cell border-box-sizing code_cell rendered">
19476 <div class="input">
19477 <div class="prompt input_prompt">In [130]:</div>
19478 <div class="inner_cell">
19479 <div class="input_area">
19480 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">simplify</span><span class="p">(</span><span class="n">each_way</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="s1">'WRITE'</span><span class="p">),</span> <span class="n">with_mark</span><span class="o">=</span><span class="s1">'WRITE'</span><span class="p">)</span>
19487 <div class="output_wrapper">
19488 <div class="output">
19491 <div class="output_area">
19493 <div class="prompt output_prompt">Out[130]:</div>
19498 <div class="output_text output_subarea output_execute_result">
19499 <pre>(((((addr_0 addr_1 addr_2) RAM_7_0) (RAM_6_0 addr_0 addr_1 addr_2)) (READ)) (READ a0))</pre>
19508 <div class="cell border-box-sizing code_cell rendered">
19509 <div class="input">
19510 <div class="prompt input_prompt">In [ ]:</div>
19511 <div class="inner_cell">
19512 <div class="input_area">
19513 <div class=" highlight hl-ipython2"><pre><span></span>
19521 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19522 </div><div class="inner_cell">
19523 <div class="text_cell_render border-box-sizing rendered_html">
19524 <p>, Sorting Networks for routing, more basic functions.</p>
19525 <p>Eventually: Orchestration with Joy.</p>
19530 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19531 </div><div class="inner_cell">
19532 <div class="text_cell_render border-box-sizing rendered_html">
19533 <h1 id="FIN-for-now.">FIN for now.<a class="anchor-link" href="#FIN-for-now.">¶</a></h1>
19537 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19538 </div><div class="inner_cell">
19539 <div class="text_cell_render border-box-sizing rendered_html">
19540 <h2 id="Appendix:-Demonstration-of-A(AB)-=-A(B)">Appendix: Demonstration of A(AB) = A(B)<a class="anchor-link" href="#Appendix:-Demonstration-of-A(AB)-=-A(B)">¶</a></h2><p>The rule <code>A(AB) = A(B)</code> is the powerhouse of LoF.</p>
19543 <pre><code> A(AB) = A(B)
19550 <pre><code> A(AB) = A(B)
19555 <p>Be aware of the recursive nature of this rule:</p>
19557 <pre><code>A(...(...(A B)))
19565 <p>There is this too:</p>
19567 <pre><code>(A)(...(...(... A B)))
19568 (A)((A)(...(... A B)))
19569 (A)((A)((A)(... A B)))
19570 (A)((A)((A)((A) A B)))
19571 (A)((A)((A)(( ) A B)))
19572 (A)((A)(...(( ) )))
19578 <pre><code>(A)(...(...(... A )))
19579 (A)(...(...(... () )))
19580 (A)(...(... ))</code></pre>
19585 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19586 </div><div class="inner_cell">
19587 <div class="text_cell_render border-box-sizing rendered_html">
19588 <h2 id="Appendix:-Reduce-String-Expressions-by-Substitution">Appendix: Reduce String Expressions by Substitution<a class="anchor-link" href="#Appendix:-Reduce-String-Expressions-by-Substitution">¶</a></h2><p>Given a string form of an arithmetic expression (in other words a string that consists of only balanced pairs of parentheses) we can reduce it to its Mark/Void value by substitution to a <a href="https://en.wikipedia.org/wiki/Fixed_point_%28mathematics%29">fixed-point</a>.</p>
19593 <div class="cell border-box-sizing code_cell rendered">
19594 <div class="input">
19595 <div class="prompt input_prompt">In [131]:</div>
19596 <div class="inner_cell">
19597 <div class="input_area">
19598 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># Translate the LoF Arithmetic rules to string substitution rules.</span>
19599 <span class="n">reduce_string</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="p">(</span>
19600 <span class="n">s</span>
19601 <span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'()()'</span><span class="p">,</span> <span class="s1">'()'</span><span class="p">)</span>
19602 <span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'(())'</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
19603 <span class="p">)</span>
19611 <div class="cell border-box-sizing code_cell rendered">
19612 <div class="input">
19613 <div class="prompt input_prompt">In [132]:</div>
19614 <div class="inner_cell">
19615 <div class="input_area">
19616 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">to_fixed_point</span><span class="p">(</span><span class="n">initial_value</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">10000</span><span class="p">):</span>
19617 <span class="sd">'''Do value = F(value) until value == F(value).'''</span>
19619 <span class="n">next_value</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">initial_value</span><span class="p">)</span>
19621 <span class="k">while</span> <span class="n">next_value</span> <span class="o">!=</span> <span class="n">initial_value</span><span class="p">:</span>
19623 <span class="k">if</span> <span class="ow">not</span> <span class="n">limit</span><span class="p">:</span> <span class="c1"># A safety mechanism. Bail out after N iterations.</span>
19624 <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">'Reached limit of allowed iterations without finding fixed point.'</span><span class="p">)</span>
19625 <span class="n">limit</span> <span class="o">-=</span> <span class="mi">1</span>
19627 <span class="n">initial_value</span> <span class="o">=</span> <span class="n">next_value</span>
19628 <span class="n">next_value</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">initial_value</span><span class="p">)</span>
19630 <span class="k">return</span> <span class="n">initial_value</span>
19638 <div class="cell border-box-sizing code_cell rendered">
19639 <div class="input">
19640 <div class="prompt input_prompt">In [133]:</div>
19641 <div class="inner_cell">
19642 <div class="input_area">
19643 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">operator</span> <span class="kn">import</span> <span class="n">add</span>
19646 <span class="k">def</span> <span class="nf">dyck_language</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="s1">''</span><span class="p">,</span> <span class="n">A</span><span class="o">=</span><span class="s1">'('</span><span class="p">,</span> <span class="n">B</span><span class="o">=</span><span class="s1">')'</span><span class="p">,</span> <span class="n">op</span><span class="o">=</span><span class="n">add</span><span class="p">):</span>
19647 <span class="sd">'''Yield balanced pairs of A and B.'''</span>
19648 <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">left</span> <span class="ow">or</span> <span class="n">right</span><span class="p">):</span>
19649 <span class="k">yield</span> <span class="n">t</span>
19650 <span class="k">return</span>
19652 <span class="k">if</span> <span class="n">left</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
19653 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">dyck_language</span><span class="p">(</span><span class="n">left</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">right</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">op</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">A</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="n">op</span><span class="p">):</span>
19654 <span class="k">yield</span> <span class="n">i</span>
19656 <span class="k">if</span> <span class="n">right</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
19657 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">dyck_language</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">op</span><span class="p">(</span><span class="n">t</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="n">B</span><span class="p">,</span> <span class="n">op</span><span class="p">):</span>
19658 <span class="k">yield</span> <span class="n">i</span>
19666 <div class="cell border-box-sizing code_cell rendered">
19667 <div class="input">
19668 <div class="prompt input_prompt">In [134]:</div>
19669 <div class="inner_cell">
19670 <div class="input_area">
19671 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">dyck_language</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
19672 <span class="nb">print</span> <span class="n">s</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">reduce_string</span><span class="p">)</span>
19679 <div class="output_wrapper">
19680 <div class="output">
19683 <div class="output_area">
19685 <div class="prompt"></div>
19688 <div class="output_subarea output_stream output_stdout output_text">
19689 <pre>((((())))) ⟶ ()
19739 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19740 </div><div class="inner_cell">
19741 <div class="text_cell_render border-box-sizing rendered_html">
19742 <h2 id="Appendix:-void()-and-mark()">Appendix: <code>void()</code> and <code>mark()</code><a class="anchor-link" href="#Appendix:-void()-and-mark()">¶</a></h2><p>The <code>void()</code> and <code>mark()</code> functions can be defined recursively in terms of each other. Note that <code>void()</code> uses <code>any()</code> while <code>mark()</code> uses <code>all()</code>. These functions implement a depth-first search. If we used versions of <code>any()</code> and <code>all()</code> that evaluated their arguments in parallel <code>void()</code> could return after the <code>True</code> result while <code>mark()</code> depends on all terms's results so its runtime will be bound by term with the greatest runtime.</p>
19747 <div class="cell border-box-sizing code_cell rendered">
19748 <div class="input">
19749 <div class="prompt input_prompt">In [135]:</div>
19750 <div class="inner_cell">
19751 <div class="input_area">
19752 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">void</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
19753 <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">mark</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">form</span><span class="p">)</span>
19755 <span class="k">def</span> <span class="nf">mark</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
19756 <span class="k">return</span> <span class="nb">all</span><span class="p">(</span><span class="n">void</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">form</span><span class="p">)</span>
19758 <span class="k">for</span> <span class="n">form</span> <span class="ow">in</span> <span class="n">BASE</span><span class="p">:</span>
19759 <span class="k">for</span> <span class="n">func</span> <span class="ow">in</span> <span class="p">(</span><span class="n">void</span><span class="p">,</span> <span class="n">mark</span><span class="p">):</span>
19760 <span class="nb">print</span> <span class="n">form</span><span class="p">,</span> <span class="s1">'is'</span><span class="p">,</span> <span class="n">func</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="s1">'?'</span><span class="p">,</span> <span class="n">func</span><span class="p">(</span><span class="n">form</span><span class="p">)</span>
19767 <div class="output_wrapper">
19768 <div class="output">
19771 <div class="output_area">
19773 <div class="prompt"></div>
19776 <div class="output_subarea output_stream output_stdout output_text">
19777 <pre>(()) is void ? True
19778 (()) is mark ? False
19789 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19790 </div><div class="inner_cell">
19791 <div class="text_cell_render border-box-sizing rendered_html">
19792 <h2 id="Appendix:-Duals">Appendix: Duals<a class="anchor-link" href="#Appendix:-Duals">¶</a></h2><p>The Void and the Mark are not Boolean true and false. Rather they correspond to non-existance and existance. When translating a traditional logical statement into Laws of Form the first thing we must do is choose which mapping we would like to use: true = Mark or true = Void. The notation works the same way once the translation is made, so the only real criteria for choosing is which gives the smaller form.</p>
19793 <p>If you examine the truth tables for the basic forms above in light of this, you can see that each defines two logical functions depending on whether you treat Void as true and Mark as false, or Void as false and Mark as true.</p>
19794 <p>For example, the juxtaposition of two terms next to each other <code>a b</code> corresponds to <strong>OR</strong> if Mark is true, and to <strong>AND</strong> if Void is true. Likewise, the form <code>((a)(b))</code> is <strong>AND</strong> if Mark is true and <strong>OR</strong> if Void is true.</p>
19797 <pre><code>(A ∧ ¬B) ∨ (C ∧ D)
19800 <p>(This reads "(A and not B) or (C and D)" in case you have a hard time remembering what the symbols mean like I do.)</p>
19801 <p>If we choose Mark to be true then the form is:</p>
19803 <pre><code>((A) B) ((C)(D))
19806 <p>If we choose Void to be true then the form is:</p>
19808 <pre><code>((A (B)) (C D))
19811 <p>As I said above, the notation works the same way either way, so once the translation is made you can forget about the Boolean true/false and just work with the Laws of Form rules. Logic is containers.</p>
19812 <h3 id="De-Morgan-Duals">De Morgan Duals<a class="anchor-link" href="#De-Morgan-Duals">¶</a></h3><p>Consider also the <a href="https://en.wikipedia.org/wiki/De_Morgan%27s_laws">De Morgan dual</a> of the original statement:</p>
19814 <pre><code>¬((¬A ∨ B) ∧ (¬C ∨ ¬D))
19817 <p>If we choose Mark to be true then the form is:</p>
19819 <pre><code>(( ((A) B) ((C)(D)) ))
19822 <p>The outer pair of containers can be deleted leaving the same form as above:</p>
19824 <pre><code>((A) B) ((C)(D))
19827 <p>Likewise, if we choose Void to be true then the form is:</p>
19829 <pre><code>((((A)) (B)) (((C)) ((D))))
19832 <p>Again, A((B)) => AB reduces this form to the same one above:</p>
19834 <pre><code>((A (B)) (C D))
19837 <p>In the Laws of Form there are no De Morgan Dual statements. If you translate a logic statement and its dual into Laws of Form notation they both reduce to the same form.</p>
19838 <p>To me this is a clear indication that the Laws of Form are superior to the traditional notation involving <code>¬ ∨ ∧</code>, etc. LoF replaces all the symbols with just names and boundaries. The Laws of Form are not dualistic, they work directly in terms of existance and non-existance. Duality only comes in when you interpret the forms as Boolean statements and have to pick a mapping.</p>
19843 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19844 </div><div class="inner_cell">
19845 <div class="text_cell_render border-box-sizing rendered_html">
19846 <h1 id="Misc.-Junk">Misc. Junk<a class="anchor-link" href="#Misc.-Junk">¶</a></h1>
19850 <div class="cell border-box-sizing code_cell rendered">
19851 <div class="input">
19852 <div class="prompt input_prompt">In [136]:</div>
19853 <div class="inner_cell">
19854 <div class="input_area">
19855 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
19857 <span class="n">histo</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">yield_variables_of</span><span class="p">(</span><span class="n">cout</span><span class="p">))</span>
19858 <span class="n">histo</span>
19865 <div class="output_wrapper">
19866 <div class="output">
19869 <div class="output_area">
19871 <div class="prompt output_prompt">Out[136]:</div>
19876 <div class="output_text output_subarea output_execute_result">
19877 <pre>Counter({'Cin': 1,
19885 'b3': 3})</pre>
19894 <div class="cell border-box-sizing code_cell rendered">
19895 <div class="input">
19896 <div class="prompt input_prompt">In [137]:</div>
19897 <div class="inner_cell">
19898 <div class="input_area">
19899 <div class=" highlight hl-ipython2"><pre><span></span><span class="c1">#import pprint as pp</span>
19902 <span class="c1">#E = cout</span>
19903 <span class="c1">#for var, count in histo.most_common():</span>
19904 <span class="c1"># print 'stan', var, count</span>
19905 <span class="c1"># E = to_fixed_point(simplify(standardize(E, var)), simplify)</span>
19906 <span class="c1"># print len(str(E))</span>
19907 <span class="c1"># pp.pprint(dict(Counter(yield_variables_of(E))))</span>
19908 <span class="c1"># print '------'</span>
19916 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
19917 </div><div class="inner_cell">
19918 <div class="text_cell_render border-box-sizing rendered_html">
19919 <p>Rather than manually calling <code>standard_form()</code> let's define a function that reduces a form to a (hopefully) smaller equivalent form by going through all the variables in the form and using <code>standard_form()</code> with each. Along with clean and unwrap we can drive an expression to a fixed point.</p>
19924 <div class="cell border-box-sizing code_cell rendered">
19925 <div class="input">
19926 <div class="prompt input_prompt">In [138]:</div>
19927 <div class="inner_cell">
19928 <div class="input_area">
19929 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">STAN</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
19930 <span class="k">for</span> <span class="n">var</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">Counter</span><span class="p">(</span><span class="n">yield_variables_of</span><span class="p">(</span><span class="n">form</span><span class="p">))</span><span class="o">.</span><span class="n">most_common</span><span class="p">():</span>
19931 <span class="n">form</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="n">standardize</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">var</span><span class="p">)),</span> <span class="n">simplify</span><span class="p">)</span>
19932 <span class="k">return</span> <span class="n">form</span>
19940 <div class="cell border-box-sizing code_cell rendered">
19941 <div class="input">
19942 <div class="prompt input_prompt">In [139]:</div>
19943 <div class="inner_cell">
19944 <div class="input_area">
19945 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum0</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'b0'</span><span class="p">,</span> <span class="s1">'Cin'</span><span class="p">)</span>
19946 <span class="n">sum1</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
19947 <span class="n">sum2</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
19948 <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a3'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
19950 <span class="nb">map</span><span class="p">(</span><span class="nb">len</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="p">(</span><span class="n">sum0</span><span class="p">,</span> <span class="n">sum1</span><span class="p">,</span> <span class="n">sum2</span><span class="p">,</span> <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span><span class="p">)))</span>
19957 <div class="output_wrapper">
19958 <div class="output">
19961 <div class="output_area">
19963 <div class="prompt output_prompt">Out[139]:</div>
19968 <div class="output_text output_subarea output_execute_result">
19969 <pre>[59, 135, 211, 287, 159]</pre>
19978 <div class="cell border-box-sizing code_cell rendered">
19979 <div class="input">
19980 <div class="prompt input_prompt">In [140]:</div>
19981 <div class="inner_cell">
19982 <div class="input_area">
19983 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum0</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a0'</span><span class="p">,</span> <span class="s1">'b0'</span><span class="p">,</span> <span class="s1">'Cin'</span><span class="p">)</span>
19984 <span class="n">sum0</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">sum0</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
19985 <span class="n">cout</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">cout</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
19987 <span class="n">sum1</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a1'</span><span class="p">,</span> <span class="s1">'b1'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
19988 <span class="n">sum1</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">sum1</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
19989 <span class="n">cout</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">cout</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
19991 <span class="n">sum2</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a2'</span><span class="p">,</span> <span class="s1">'b2'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
19992 <span class="n">sum2</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">sum2</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
19993 <span class="n">cout</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">cout</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
19995 <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span> <span class="o">=</span> <span class="n">full_bit_adder</span><span class="p">(</span><span class="s1">'a3'</span><span class="p">,</span> <span class="s1">'b3'</span><span class="p">,</span> <span class="n">cout</span><span class="p">)</span>
19996 <span class="n">sum3</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">sum3</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
19997 <span class="n">cout</span> <span class="o">=</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">cout</span><span class="p">,</span> <span class="n">STAN</span><span class="p">)</span>
20000 <span class="nb">map</span><span class="p">(</span><span class="nb">len</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="p">(</span><span class="n">sum0</span><span class="p">,</span> <span class="n">sum1</span><span class="p">,</span> <span class="n">sum2</span><span class="p">,</span> <span class="n">sum3</span><span class="p">,</span> <span class="n">cout</span><span class="p">)))</span>
20007 <div class="output_wrapper">
20008 <div class="output">
20011 <div class="output_area">
20013 <div class="prompt"></div>
20016 <div class="output_subarea output_text output_error">
20018 <span class="ansi-red-fg">---------------------------------------------------------------------------</span>
20019 <span class="ansi-red-fg">NameError</span> Traceback (most recent call last)
20020 <span class="ansi-green-fg"><ipython-input-140-34665b9e1d61></span> in <span class="ansi-cyan-fg"><module></span><span class="ansi-blue-fg">()</span>
20021 <span class="ansi-green-intense-fg ansi-bold"> 1</span> sum0<span class="ansi-blue-fg">,</span> cout <span class="ansi-blue-fg">=</span> full_bit_adder<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">'a0'</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">'b0'</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">'Cin'</span><span class="ansi-blue-fg">)</span>
20022 <span class="ansi-green-fg">----> 2</span><span class="ansi-red-fg"> </span>sum0 <span class="ansi-blue-fg">=</span> to_fixed_point<span class="ansi-blue-fg">(</span>sum0<span class="ansi-blue-fg">,</span> STAN<span class="ansi-blue-fg">)</span>
20023 <span class="ansi-green-intense-fg ansi-bold"> 3</span> cout <span class="ansi-blue-fg">=</span> to_fixed_point<span class="ansi-blue-fg">(</span>cout<span class="ansi-blue-fg">,</span> STAN<span class="ansi-blue-fg">)</span>
20024 <span class="ansi-green-intense-fg ansi-bold"> 4</span>
20025 <span class="ansi-green-intense-fg ansi-bold"> 5</span> sum1<span class="ansi-blue-fg">,</span> cout <span class="ansi-blue-fg">=</span> full_bit_adder<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">'a1'</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">'b1'</span><span class="ansi-blue-fg">,</span> cout<span class="ansi-blue-fg">)</span>
20027 <span class="ansi-green-fg"><ipython-input-132-bf263ba512a2></span> in <span class="ansi-cyan-fg">to_fixed_point</span><span class="ansi-blue-fg">(initial_value, F, limit)</span>
20028 <span class="ansi-green-intense-fg ansi-bold"> 2</span> <span class="ansi-blue-fg">'''Do value = F(value) until value == F(value).'''</span>
20029 <span class="ansi-green-intense-fg ansi-bold"> 3</span>
20030 <span class="ansi-green-fg">----> 4</span><span class="ansi-red-fg"> </span>next_value <span class="ansi-blue-fg">=</span> F<span class="ansi-blue-fg">(</span>initial_value<span class="ansi-blue-fg">)</span>
20031 <span class="ansi-green-intense-fg ansi-bold"> 5</span>
20032 <span class="ansi-green-intense-fg ansi-bold"> 6</span> <span class="ansi-green-fg">while</span> next_value <span class="ansi-blue-fg">!=</span> initial_value<span class="ansi-blue-fg">:</span>
20034 <span class="ansi-green-fg"><ipython-input-138-99179e550c4a></span> in <span class="ansi-cyan-fg">STAN</span><span class="ansi-blue-fg">(form)</span>
20035 <span class="ansi-green-intense-fg ansi-bold"> 1</span> <span class="ansi-green-fg">def</span> STAN<span class="ansi-blue-fg">(</span>form<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
20036 <span class="ansi-green-intense-fg ansi-bold"> 2</span> <span class="ansi-green-fg">for</span> var<span class="ansi-blue-fg">,</span> _ <span class="ansi-green-fg">in</span> Counter<span class="ansi-blue-fg">(</span>yield_variables_of<span class="ansi-blue-fg">(</span>form<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">.</span>most_common<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
20037 <span class="ansi-green-fg">----> 3</span><span class="ansi-red-fg"> </span>form <span class="ansi-blue-fg">=</span> to_fixed_point<span class="ansi-blue-fg">(</span>simplify<span class="ansi-blue-fg">(</span>standardize<span class="ansi-blue-fg">(</span>form<span class="ansi-blue-fg">,</span> var<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">,</span> simplify<span class="ansi-blue-fg">)</span>
20038 <span class="ansi-green-intense-fg ansi-bold"> 4</span> <span class="ansi-green-fg">return</span> form
20040 <span class="ansi-red-fg">NameError</span>: global name 'standardize' is not defined</pre>
20048 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
20049 </div><div class="inner_cell">
20050 <div class="text_cell_render border-box-sizing rendered_html">
20051 <p>It would be useful and fun to write a simple search algorithm that tried different ways to reduce a form to see if it could find particulaly compact versions.</p>
20052 <p>Let's generate the expressions for the next two output bits, and the carry bit.</p>
20057 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
20058 </div><div class="inner_cell">
20059 <div class="text_cell_render border-box-sizing rendered_html">
20060 <p>The <code>sum3</code> bit expression is pretty big.</p>
20065 <div class="cell border-box-sizing code_cell rendered">
20066 <div class="input">
20067 <div class="prompt input_prompt">In [ ]:</div>
20068 <div class="inner_cell">
20069 <div class="input_area">
20070 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">sum3</span>
20078 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
20079 </div><div class="inner_cell">
20080 <div class="text_cell_render border-box-sizing rendered_html">
20081 <p>But it's only about 1/9th of size of the previous version (which was 9261.)</p>
20086 <div class="cell border-box-sizing code_cell rendered">
20087 <div class="input">
20088 <div class="prompt input_prompt">In [ ]:</div>
20089 <div class="inner_cell">
20090 <div class="input_area">
20091 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">sum3</span><span class="p">))</span>
20099 <div class="cell border-box-sizing code_cell rendered">
20100 <div class="input">
20101 <div class="prompt input_prompt">In [ ]:</div>
20102 <div class="inner_cell">
20103 <div class="input_area">
20104 <div class=" highlight hl-ipython2"><pre><span></span>
20112 <div class="cell border-box-sizing code_cell rendered">
20113 <div class="input">
20114 <div class="prompt input_prompt">In [ ]:</div>
20115 <div class="inner_cell">
20116 <div class="input_area">
20117 <div class=" highlight hl-ipython2"><pre><span></span>
20125 <div class="cell border-box-sizing code_cell rendered">
20126 <div class="input">
20127 <div class="prompt input_prompt">In [ ]:</div>
20128 <div class="inner_cell">
20129 <div class="input_area">
20130 <div class=" highlight hl-ipython2"><pre><span></span>
20138 <div class="cell border-box-sizing code_cell rendered">
20139 <div class="input">
20140 <div class="prompt input_prompt">In [ ]:</div>
20141 <div class="inner_cell">
20142 <div class="input_area">
20143 <div class=" highlight hl-ipython2"><pre><span></span>
20151 <div class="cell border-box-sizing code_cell rendered">
20152 <div class="input">
20153 <div class="prompt input_prompt">In [ ]:</div>
20154 <div class="inner_cell">
20155 <div class="input_area">
20156 <div class=" highlight hl-ipython2"><pre><span></span>
20164 <div class="cell border-box-sizing code_cell rendered">
20165 <div class="input">
20166 <div class="prompt input_prompt">In [ ]:</div>
20167 <div class="inner_cell">
20168 <div class="input_area">
20169 <div class=" highlight hl-ipython2"><pre><span></span>
20177 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
20178 </div><div class="inner_cell">
20179 <div class="text_cell_render border-box-sizing rendered_html">
20180 <p>Let's simplify the first one manually just for fun:</p>
20182 <pre><code>(((((())) (())) ((()))))
20187 <p>Sure enough, it reduces to Mark after just a few applications of the rule <code>(()) = __</code> (the underscores indicates the absence of any value, aka Void.) We could also just delete variables that are Void in the original expression:</p>
20189 <pre><code>((((a)b)(c)))
20196 <div class="cell border-box-sizing code_cell rendered">
20197 <div class="input">
20198 <div class="prompt input_prompt">In [ ]:</div>
20199 <div class="inner_cell">
20200 <div class="input_area">
20201 <div class=" highlight hl-ipython2"><pre><span></span>
20209 <div class="cell border-box-sizing code_cell rendered">
20210 <div class="input">
20211 <div class="prompt input_prompt">In [ ]:</div>
20212 <div class="inner_cell">
20213 <div class="input_area">
20214 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span> <span class="o">=</span> <span class="n">F</span><span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">))</span>
20215 <span class="k">for</span> <span class="n">form</span> <span class="ow">in</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="n">C</span><span class="p">):</span>
20216 <span class="n">arth</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">env</span><span class="p">)</span>
20217 <span class="nb">print</span> <span class="n">form</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">arth</span><span class="p">,</span> <span class="sa">u</span><span class="s1">'⟶'</span><span class="p">,</span> <span class="n">value_of</span><span class="p">(</span><span class="n">arth</span><span class="p">)</span>
20225 <div class="cell border-box-sizing code_cell rendered">
20226 <div class="input">
20227 <div class="prompt input_prompt">In [ ]:</div>
20228 <div class="inner_cell">
20229 <div class="input_area">
20230 <div class=" highlight hl-ipython2"><pre><span></span>
20238 <div class="cell border-box-sizing code_cell rendered">
20239 <div class="input">
20240 <div class="prompt input_prompt">In [ ]:</div>
20241 <div class="inner_cell">
20242 <div class="input_area">
20243 <div class=" highlight hl-ipython2"><pre><span></span>
20251 <div class="cell border-box-sizing code_cell rendered">
20252 <div class="input">
20253 <div class="prompt input_prompt">In [ ]:</div>
20254 <div class="inner_cell">
20255 <div class="input_area">
20256 <div class=" highlight hl-ipython2"><pre><span></span>
20264 <div class="cell border-box-sizing code_cell rendered">
20265 <div class="input">
20266 <div class="prompt input_prompt">In [ ]:</div>
20267 <div class="inner_cell">
20268 <div class="input_area">
20269 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">A</span>
20270 <span class="n">Aa</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="p">{</span><span class="n">a</span><span class="p">})</span>
20271 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">Aa</span>
20272 <span class="n">Aab</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">Aa</span><span class="p">,</span> <span class="p">{</span><span class="n">b</span><span class="p">})</span>
20273 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">Aab</span>
20274 <span class="n">Aabc</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">Aab</span><span class="p">,</span> <span class="p">{</span><span class="n">c</span><span class="p">})</span>
20275 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">Aabc</span>
20283 <div class="cell border-box-sizing code_cell rendered">
20284 <div class="input">
20285 <div class="prompt input_prompt">In [ ]:</div>
20286 <div class="inner_cell">
20287 <div class="input_area">
20288 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">Aa</span>
20289 <span class="n">Aab</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">Aa</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">b</span><span class="p">)</span>
20290 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">F</span><span class="p">(</span><span class="n">b</span><span class="p">),</span> <span class="n">Aab</span>
20298 <div class="cell border-box-sizing code_cell rendered">
20299 <div class="input">
20300 <div class="prompt input_prompt">In [ ]:</div>
20301 <div class="inner_cell">
20302 <div class="input_area">
20303 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">Aa</span>
20304 <span class="n">Aac</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">Aa</span><span class="p">,</span> <span class="n">with_mark</span><span class="o">=</span><span class="n">c</span><span class="p">)</span>
20305 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">F</span><span class="p">(</span><span class="n">c</span><span class="p">),</span> <span class="n">Aac</span>
20313 <div class="cell border-box-sizing code_cell rendered">
20314 <div class="input">
20315 <div class="prompt input_prompt">In [ ]:</div>
20316 <div class="inner_cell">
20317 <div class="input_area">
20318 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">Aa</span>
20319 <span class="n">Aac</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">Aa</span><span class="p">,</span> <span class="p">{</span><span class="n">c</span><span class="p">})</span>
20320 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">Aac</span>
20328 <div class="cell border-box-sizing code_cell rendered">
20329 <div class="input">
20330 <div class="prompt input_prompt">In [ ]:</div>
20331 <div class="inner_cell">
20332 <div class="input_area">
20333 <div class=" highlight hl-ipython2"><pre><span></span>
20341 <div class="cell border-box-sizing code_cell rendered">
20342 <div class="input">
20343 <div class="prompt input_prompt">In [ ]:</div>
20344 <div class="inner_cell">
20345 <div class="input_area">
20346 <div class=" highlight hl-ipython2"><pre><span></span>
20354 <div class="cell border-box-sizing code_cell rendered">
20355 <div class="input">
20356 <div class="prompt input_prompt">In [ ]:</div>
20357 <div class="inner_cell">
20358 <div class="input_area">
20359 <div class=" highlight hl-ipython2"><pre><span></span>
20367 <div class="cell border-box-sizing code_cell rendered">
20368 <div class="input">
20369 <div class="prompt input_prompt">In [ ]:</div>
20370 <div class="inner_cell">
20371 <div class="input_area">
20372 <div class=" highlight hl-ipython2"><pre><span></span>
20380 <div class="cell border-box-sizing code_cell rendered">
20381 <div class="input">
20382 <div class="prompt input_prompt">In [ ]:</div>
20383 <div class="inner_cell">
20384 <div class="input_area">
20385 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
20387 <span class="n">histo</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">yield_variables_of</span><span class="p">(</span><span class="n">sum7</span><span class="p">))</span>
20388 <span class="n">histo</span>
20396 <div class="cell border-box-sizing code_cell rendered">
20397 <div class="input">
20398 <div class="prompt input_prompt">In [ ]:</div>
20399 <div class="inner_cell">
20400 <div class="input_area">
20401 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">sum7</span><span class="p">))</span>
20409 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
20410 </div><div class="inner_cell">
20411 <div class="text_cell_render border-box-sizing rendered_html">
20412 <p>Immediately we can just call <code>simplify()</code> until it stops shinking the expression.</p>
20417 <div class="cell border-box-sizing code_cell rendered">
20418 <div class="input">
20419 <div class="prompt input_prompt">In [ ]:</div>
20420 <div class="inner_cell">
20421 <div class="input_area">
20422 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">s7</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">sum7</span><span class="p">)</span>
20423 <span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">s7</span><span class="p">))</span>
20431 <div class="cell border-box-sizing code_cell rendered">
20432 <div class="input">
20433 <div class="prompt input_prompt">In [ ]:</div>
20434 <div class="inner_cell">
20435 <div class="input_area">
20436 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">s7</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">s7</span><span class="p">)</span>
20437 <span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">s7</span><span class="p">))</span>
20445 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
20446 </div><div class="inner_cell">
20447 <div class="text_cell_render border-box-sizing rendered_html">
20448 <p>Once was enough (we should consider adding a call to <code>simplify()</code> in the <code>full_bit_adder()</code> function.)</p>
20449 <p>Let's try using <code>each_way()</code> with the most common names in the form.</p>
20454 <div class="cell border-box-sizing code_cell rendered">
20455 <div class="input">
20456 <div class="prompt input_prompt">In [ ]:</div>
20457 <div class="inner_cell">
20458 <div class="input_area">
20459 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">s7</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">each_way</span><span class="p">(</span><span class="n">s7</span><span class="p">,</span> <span class="s1">'a0'</span><span class="p">))</span>
20460 <span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">s7</span><span class="p">))</span>
20468 <div class="cell border-box-sizing code_cell rendered">
20469 <div class="input">
20470 <div class="prompt input_prompt">In [ ]:</div>
20471 <div class="inner_cell">
20472 <div class="input_area">
20473 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">s7</span> <span class="o">=</span> <span class="n">simplify</span><span class="p">(</span><span class="n">s7</span><span class="p">)</span>
20474 <span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">s7</span><span class="p">))</span>
20482 <div class="cell border-box-sizing code_cell rendered">
20483 <div class="input">
20484 <div class="prompt input_prompt">In [ ]:</div>
20485 <div class="inner_cell">
20486 <div class="input_area">
20487 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">Counter</span><span class="p">(</span><span class="n">yield_variables_of</span><span class="p">(</span><span class="n">s7</span><span class="p">))</span>
20495 <div class="cell border-box-sizing code_cell rendered">
20496 <div class="input">
20497 <div class="prompt input_prompt">In [ ]:</div>
20498 <div class="inner_cell">
20499 <div class="input_area">
20500 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">s7</span> <span class="o">=</span> <span class="n">sum7</span>
20502 <span class="c1">#for name, count in histo.most_common():</span>
20503 <span class="c1"># s7 = simplify(each_way(s7, name))</span>
20504 <span class="c1"># print len(str(s7))</span>
20512 <div class="cell border-box-sizing code_cell rendered">
20513 <div class="input">
20514 <div class="prompt input_prompt">In [ ]:</div>
20515 <div class="inner_cell">
20516 <div class="input_area">
20517 <div class=" highlight hl-ipython2"><pre><span></span>
20525 <div class="cell border-box-sizing code_cell rendered">
20526 <div class="input">
20527 <div class="prompt input_prompt">In [ ]:</div>
20528 <div class="inner_cell">
20529 <div class="input_area">
20530 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">super_simple</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
20531 <span class="k">return</span> <span class="n">to_fixed_point</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">simplify</span><span class="p">)</span>
20539 <div class="cell border-box-sizing code_cell rendered">
20540 <div class="input">
20541 <div class="prompt input_prompt">In [ ]:</div>
20542 <div class="inner_cell">
20543 <div class="input_area">
20544 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">sum7</span><span class="p">))</span>
20545 <span class="n">s7</span> <span class="o">=</span> <span class="n">super_simple</span><span class="p">(</span><span class="n">sum7</span><span class="p">)</span>
20546 <span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">s7</span><span class="p">))</span>
20554 <div class="cell border-box-sizing code_cell rendered">
20555 <div class="input">
20556 <div class="prompt input_prompt">In [ ]:</div>
20557 <div class="inner_cell">
20558 <div class="input_area">
20559 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">s7</span> <span class="o">=</span> <span class="n">sum7</span>
20561 <span class="c1">#for name, count in histo.most_common():</span>
20562 <span class="c1"># s7 = super_simple(each_way(s7, name))</span>
20563 <span class="c1"># print len(str(s7))</span>
20571 <div class="cell border-box-sizing code_cell rendered">
20572 <div class="input">
20573 <div class="prompt input_prompt">In [ ]:</div>
20574 <div class="inner_cell">
20575 <div class="input_area">
20576 <div class=" highlight hl-ipython2"><pre><span></span>
20584 <div class="cell border-box-sizing code_cell rendered">
20585 <div class="input">
20586 <div class="prompt input_prompt">In [ ]:</div>
20587 <div class="inner_cell">
20588 <div class="input_area">
20589 <div class=" highlight hl-ipython2"><pre><span></span>
20597 <div class="cell border-box-sizing code_cell rendered">
20598 <div class="input">
20599 <div class="prompt input_prompt">In [ ]:</div>
20600 <div class="inner_cell">
20601 <div class="input_area">
20602 <div class=" highlight hl-ipython2"><pre><span></span>
20610 <div class="cell border-box-sizing code_cell rendered">
20611 <div class="input">
20612 <div class="prompt input_prompt">In [ ]:</div>
20613 <div class="inner_cell">
20614 <div class="input_area">
20615 <div class=" highlight hl-ipython2"><pre><span></span><span class="nb">print</span> <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">name</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">R</span><span class="p">))</span>
20616 <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
20617 <span class="nb">print</span> <span class="n">format_env</span><span class="p">(</span><span class="n">R</span><span class="p">),</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">b_register</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
20618 <span class="n">R</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">cycle</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">R</span><span class="p">))</span>
20626 <div class="cell border-box-sizing code_cell rendered">
20627 <div class="input">
20628 <div class="prompt input_prompt">In [ ]:</div>
20629 <div class="inner_cell">
20630 <div class="input_area">
20631 <div class=" highlight hl-ipython2"><pre><span></span>
20639 <div class="cell border-box-sizing code_cell rendered">
20640 <div class="input">
20641 <div class="prompt input_prompt">In [ ]:</div>
20642 <div class="inner_cell">
20643 <div class="input_area">
20644 <div class=" highlight hl-ipython2"><pre><span></span>
20652 <div class="cell border-box-sizing code_cell rendered">
20653 <div class="input">
20654 <div class="prompt input_prompt">In [ ]:</div>
20655 <div class="inner_cell">
20656 <div class="input_area">
20657 <div class=" highlight hl-ipython2"><pre><span></span>
20665 <div class="cell border-box-sizing code_cell rendered">
20666 <div class="input">
20667 <div class="prompt input_prompt">In [ ]:</div>
20668 <div class="inner_cell">
20669 <div class="input_area">
20670 <div class=" highlight hl-ipython2"><pre><span></span>