<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css" ?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0"><updated>Mon, 26 Oct 2015 00:27:48 +0100</updated><category term="Programming"/><title type="text">Informatimago</title><link href="http://www.informatimago.com/blog" type="application/atom+xml" rel="self"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author><openSearch:totalResults>20</openSearch:totalResults><openSearch:itemsPerPage>20</openSearch:itemsPerPage><openSearch:startIndex>1</openSearch:startIndex><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/clext/pipe-article-en.html</id><published>2015-10-04T16:45:27+0100</published><updated>2015-10-26T00:27:48+0100</updated><title type="text">Stream Pipe</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/pipe.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/clext/pipe-article-en.html&quot;&gt;Stream Pipe&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A package implementing a unidirectional pipe using &quot;BORDEAUX-THREADS&quot; and &quot;TRIVIAL-GRAY-STREAM&quot;.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;common lisp,lisp,stream,pipe,gray streams,bordeaux-threads&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;stream-pipe&quot;&gt;
&lt;h1 class=&quot;title&quot;&gt;Stream Pipe&lt;/h1&gt;




&lt;p&gt;❡&lt;/p&gt;
&lt;div class=&quot;section&quot; id=&quot;id1&quot;&gt;
&lt;h1&gt;Stream Pipe&lt;/h1&gt;
&lt;p&gt;Here is a new package, &lt;tt class=&quot;docutils literal&quot;&gt;&amp;quot;COM.INFORMATIMAGO.CLEXT.PIPE&amp;quot;&lt;/tt&gt; that implements
a unidirectional pipe using &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;&amp;quot;BORDEAUX-THREADS&amp;quot;&lt;/span&gt;&lt;/tt&gt; and &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;&amp;quot;TRIVIAL-GRAY-STREAM&amp;quot;&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The data written to the &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;PIPE-OUTPUT-STREAM&lt;/span&gt;&lt;/tt&gt; is queued (if a maximum
queue-size is specified for the stream, then the writing
thread may block if the buffer is full).&lt;/p&gt;
&lt;p&gt;The data queued can be read from the &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;PIPE-INPUT-STREAM&lt;/span&gt;&lt;/tt&gt;.  If the
queue is empty, then the reading stream may block (unless it
used &lt;tt class=&quot;docutils literal&quot;&gt;LISTEN&lt;/tt&gt;, &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;READ-CHAR-NO-HANG&lt;/span&gt;&lt;/tt&gt;, etc).&lt;/p&gt;
&lt;p&gt;When the stream is closed, one can still read from it until
the end of file is reached.&lt;/p&gt;
&lt;p&gt;Multiple threads may read or write to the same pipe.&lt;/p&gt;
&lt;p&gt;To demonstrate the use of pipes, the &lt;tt class=&quot;docutils literal&quot;&gt;&amp;quot;COM.INFORMATIMAGO.CLEXT.FILTER&amp;quot;&lt;/tt&gt;
package exports a GREP function that processes &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;*STANDARD-INPUT*&lt;/span&gt;&lt;/tt&gt; and
writes to &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;*STANDARD-OUTPUT*&lt;/span&gt;&lt;/tt&gt;, and a FILTER macro that builds a pipe
chain of any number of forms, each running in its own thread (but the
last one which runs in the calling thread).&lt;/p&gt;
&lt;p&gt;It also provides a function IN that reads a text file and writes it to
&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;*STANDARD-OUTPUT*&lt;/span&gt;&lt;/tt&gt;, and a function OUT that reads &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;*STANDARD-INPUT*&lt;/span&gt;&lt;/tt&gt; and
writes it to a file. (They correspond to the unix redirections &lt;tt class=&quot;docutils literal&quot;&gt;&amp;lt;&lt;/tt&gt; &lt;tt class=&quot;docutils literal&quot;&gt;&amp;gt;&lt;/tt&gt;
and &lt;tt class=&quot;docutils literal&quot;&gt;&amp;gt;&amp;gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;COM.INFORMATIAMGO.COMMON-LISP.INTERACTIVE.BROWSER:MORE&lt;/span&gt;&lt;/tt&gt; and &lt;tt class=&quot;docutils literal&quot;&gt;CAT&lt;/tt&gt;
have been updated to read from &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;*STANDARD-INPUT*&lt;/span&gt;&lt;/tt&gt; when no file is
given, thus working as filters.&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
user1&amp;gt; (pprint (macroexpand-1 &#039;(filter (in #P&amp;quot;~/tmp/misc/wang&amp;quot;)
                                       (grep &amp;quot;LISP&amp;quot; :line-number t)
                                       (out &amp;quot;/tmp/wl.txt&amp;quot;))))

(let ((#1=#:|pipe77885| (com.informatimago.clext.pipe:make-pipe
                         :buffer-size com.informatimago.clext.filter::*buffer-size*)))
  (bordeaux-threads:make-thread
   (lambda nil
     (unwind-protect
          (filter (in #P&amp;quot;/Users/pjb/tmp/misc/wang&amp;quot;) (grep &amp;quot;LISP&amp;quot; :line-number t))
       (close *standard-output*)))
   :initial-bindings
   (list (cons &#039;*standard-output* (com.informatimago.clext.pipe:pipe-output-stream #1#))
         (cons &#039;*standard-input* *standard-input*)))
  (let ((*standard-input* (com.informatimago.clext.pipe:pipe-input-stream #1#)))
    (out &amp;quot;/tmp/wl.txt&amp;quot;)))

; No value
user1&amp;gt;
&lt;/pre&gt;
&lt;div class=&quot;section&quot; id=&quot;example&quot;&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
cl-user&amp;gt; (mkupack :use &#039;(&amp;quot;COMMON-LISP&amp;quot;
                         &amp;quot;COM.INFORMATIMAGO.COMMON-LISP.INTERACTIVE.BROWSER&amp;quot;
                         &amp;quot;COM.INFORMATIMAGO.CLEXT.FILTER&amp;quot;))
#&amp;lt;Package &amp;quot;USER1&amp;quot;&amp;gt;
user1&amp;gt; (filter (in #P&amp;quot;~/tmp/misc/wang&amp;quot;))
Hao Wang, logicien americain.

L&#039;algorithme en  question  a  ete  publie  en  1960  dans l&#039;IBM Journal,
article intitule &amp;quot;Toward  Mechanical Mathematics&amp;quot;, avec des variantes et
une  extension au calcul  des  predicats.  Il  s&#039;agit  ici  du  &amp;quot;premier
programme&amp;quot; de Wang, systeme &amp;quot;P&amp;quot;.

L&#039;article a ete ecrit en 1958, et les experiences effectuees sur IBM 704
- machine a lampes, 32 k  mots  de 36 bits, celle-la meme qui vit naitre
LISP a la meme epoque. Le programme  a  ete ecrit en assembleur (Fortran
existait, mais il ne s&#039;etait pas encore impose)  et  l&#039;auteur estime que
&amp;quot;there is very little in the program that is not straightforward&amp;quot;.

Il observe que les preuves engendrees sont &amp;quot;essentiellement des arbres&amp;quot;,
et  annonce  que  la  machine  a  demontre 220 theoremes du  calcul  des
propositions  (tautologies)  en  3  minutes. Il en tire argument pour la
superiorite  d&#039;une  approche  algorithmique  par  rapport a une approche
heuristique comme celle du &amp;quot;Logic Theorist&amp;quot; de Newell, Shaw et  Simon (a
partir de 1956 sur la machine JOHNNIAC de la Rand Corporation): un debat
qui dure encore...

Cet  algorithme  a  ete popularise par J. McCarthy, comme exemple-fanion
d&#039;application  de LISP. Il figure dans le manuel de la premiere  version
de  LISP  (LISP  1,  sur IBM 704 justement, le manuel est date  de  Mars
1960), et il a ete repris dans le celebre &amp;quot;LISP 1.5 Programmer&#039;s Manual&amp;quot;
publie en 1962 par MIT Press, un des maitres-livres de l&#039;Informatique.



nil
user1&amp;gt; (filter (in #P&amp;quot;~/tmp/misc/wang&amp;quot;) (grep &amp;quot;LISP&amp;quot;))
LISP a la meme epoque. Le programme  a  ete ecrit en assembleur (Fortran
d&#039;application  de LISP. Il figure dans le manuel de la premiere  version
de  LISP  (LISP  1,  sur IBM 704 justement, le manuel est date  de  Mars
1960), et il a ete repris dans le celebre &amp;quot;LISP 1.5 Programmer&#039;s Manual&amp;quot;
nil
user1&amp;gt; (filter (in #P&amp;quot;~/tmp/misc/wang&amp;quot;) (grep &amp;quot;program&amp;quot; :case-insensitive t))
programme&amp;quot; de Wang, systeme &amp;quot;P&amp;quot;.
LISP a la meme epoque. Le programme  a  ete ecrit en assembleur (Fortran
&amp;quot;there is very little in the program that is not straightforward&amp;quot;.
1960), et il a ete repris dans le celebre &amp;quot;LISP 1.5 Programmer&#039;s Manual&amp;quot;
nil
user1&amp;gt; (filter (in #P&amp;quot;~/tmp/misc/wang&amp;quot;)
               (grep &amp;quot; &amp;quot; :line-number t)
               (let ((*terminal-height* 7)) (more)))
1:Hao Wang, logicien americain.
2:
3:L&#039;algorithme en  question  a  ete  publie  en  1960  dans l&#039;IBM Journal,
4:article intitule &amp;quot;Toward  Mechanical Mathematics&amp;quot;, avec des variantes et
5:une  extension au calcul  des  predicats.  Il  s&#039;agit  ici  du  &amp;quot;premier
6:programme&amp;quot; de Wang, systeme &amp;quot;P&amp;quot;.
7:
8:L&#039;article a ete ecrit en 1958, et les experiences effectuees sur IBM 704
Type RETURN for next page:
9:- machine a lampes, 32 k  mots  de 36 bits, celle-la meme qui vit naitre
10:LISP a la meme epoque. Le programme  a  ete ecrit en assembleur (Fortran
11:existait, mais il ne s&#039;etait pas encore impose)  et  l&#039;auteur estime que
12:&amp;quot;there is very little in the program that is not straightforward&amp;quot;.
13:
14:Il observe que les preuves engendrees sont &amp;quot;essentiellement des arbres&amp;quot;,
15:et  annonce  que  la  machine  a  demontre 220 theoremes du  calcul  des
Type RETURN for next page:
16:propositions  (tautologies)  en  3  minutes. Il en tire argument pour la
17:superiorite  d&#039;une  approche  algorithmique  par  rapport a une approche
18:heuristique comme celle du &amp;quot;Logic Theorist&amp;quot; de Newell, Shaw et  Simon (a
19:partir de 1956 sur la machine JOHNNIAC de la Rand Corporation): un debat
20:qui dure encore...
21:
22:Cet  algorithme  a  ete popularise par J. McCarthy, comme exemple-fanion
Type RETURN for next page:
23:d&#039;application  de LISP. Il figure dans le manuel de la premiere  version
24:de  LISP  (LISP  1,  sur IBM 704 justement, le manuel est date  de  Mars
25:1960), et il a ete repris dans le celebre &amp;quot;LISP 1.5 Programmer&#039;s Manual&amp;quot;
26:publie en 1962 par MIT Press, un des maitres-livres de l&#039;Informatique.
27:
28:
29:
Type RETURN for next page:

; No value
user1&amp;gt; (filter (in #P&amp;quot;~/tmp/misc/wang&amp;quot;) (grep &amp;quot;LISP&amp;quot; :line-number t) (out &amp;quot;/tmp/wl.txt&amp;quot;))
nil
user1&amp;gt; (cat &amp;quot;/tmp/wl.txt&amp;quot;)
10:LISP a la meme epoque. Le programme  a  ete ecrit en assembleur (Fortran
23:d&#039;application  de LISP. Il figure dans le manuel de la premiere  version
24:de  LISP  (LISP  1,  sur IBM 704 justement, le manuel est date  de  Mars
25:1960), et il a ete repris dans le celebre &amp;quot;LISP 1.5 Programmer&#039;s Manual&amp;quot;
; No value
user1&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;section&quot; id=&quot;sources&quot;&gt;
&lt;h2&gt;Sources&lt;/h2&gt;
&lt;p&gt;These new packages are available on gitlab and github; and they&#039;ll be
distributed in &lt;cite&gt;quicklisp&lt;/cite&gt;.&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
git clone https://gitlab.com/com-informatimago/com-informatimago.git informatimago
&lt;/pre&gt;
&lt;p&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://www.informatimago.com/develop/lisp/index.html&quot;&gt;Informatimago Public Common Lisp Libraries&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/clext/pipe-article-en.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/botihn/botihn-fr.html</id><published>2015-04-27T12:00:00+0100</published><updated>2015-10-26T00:27:48+0100</updated><title type="text">Botihn: un simple robot IRC pour surveiller Hacker News (FR)</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/botihn.png&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/botihn/botihn-fr.html&quot;&gt;Botihn: un simple robot IRC pour surveiller Hacker News (FR)&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Écriture d&#039;un robot IRC simple.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;common lisp,lisp,irc,bot,hacker news,drakma,cl-json,cl-irc,cesarum&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;ecriture-d-un-robot-irc-simple&quot;&gt;
&lt;h1 class=&quot;title&quot;&gt;Écriture d&#039;un robot IRC simple&lt;/h1&gt;




&lt;p&gt;❡&lt;/p&gt;
&lt;div class=&quot;section&quot; id=&quot;id1&quot;&gt;
&lt;h1&gt;Écriture d&#039;un robot IRC simple&lt;/h1&gt;
&lt;p&gt;Pour soulager notre dépendence à &lt;em&gt;Hacker News&lt;/em&gt;
(&lt;a class=&quot;reference external&quot; href=&quot;http://news.ycombinator.com/newest&quot;&gt;http://news.ycombinator.com/newest&lt;/a&gt;), qui nous incite à cliquer sur
&lt;em&gt;Reload&lt;/em&gt; toutes les dix secondes, on va écrire un &lt;cite&gt;ircbot&lt;/cite&gt;, un petit
programme qui va aller chercher périodiquement les nouveaux articles
sur &lt;em&gt;Hacker News&lt;/em&gt;, et en transmettre le titre et l&#039;&lt;cite&gt;URL&lt;/cite&gt; sur un canal &lt;cite&gt;IRC&lt;/cite&gt;.&lt;/p&gt;
&lt;div class=&quot;section&quot; id=&quot;dependences-systeme-asdf&quot;&gt;
&lt;h2&gt;Dependences - Système &lt;cite&gt;ASDF&lt;/cite&gt;&lt;/h2&gt;
&lt;p&gt;Ce programme est écrit en &lt;cite&gt;Common Lisp&lt;/cite&gt; (cf. &lt;a class=&quot;reference external&quot; href=&quot;http://cliki.net/&quot;&gt;http://cliki.net/&lt;/a&gt;), en
utilisant quelques bibliothèques:&lt;/p&gt;
&lt;ul class=&quot;simple&quot;&gt;
&lt;li&gt;&lt;em&gt;drakma&lt;/em&gt;, client &lt;cite&gt;HTTP&lt;/cite&gt;, va nous permettre d&#039;obtenir les données voulues;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;cl-json&lt;/em&gt; va nous permettre de décoder ces données au format &lt;cite&gt;JSON&lt;/cite&gt;,
et d&#039;obtenir des structures Lisp;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;cl-irc&lt;/em&gt; va nous permettre de communiquer avec le serveur &lt;cite&gt;IRC&lt;/cite&gt;.&lt;/li&gt;
&lt;li&gt;je vais aussi utiliser une fonctions de ma bibliothèque
&lt;em&gt;com.informatimago.common-lisp.cesarum&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces bibliothèques sont obtenues, installées et compilées avec
&lt;em&gt;quicklisp&lt;/em&gt; et &lt;em&gt;asdf&lt;/em&gt;.  Nous allons donc commencer par écrire un
système ASDF indiquant les dépendences de notre programme &lt;cite&gt;botihn&lt;/cite&gt; sur
ces bibliothèques &lt;cite&gt;com.informatimago.small-cl-pgms.botihn.asd&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(asdf:defsystem &amp;quot;com.informatimago.small-cl-pgms.botihn&amp;quot;
    :description &amp;quot;An IRC bot monitoring Hacker News.&amp;quot;
    :author &amp;quot;Pascal J. Bourguignon&amp;quot;
    :version &amp;quot;1.0.0&amp;quot;
    :license &amp;quot;AGPL3&amp;quot;
    :depends-on (&amp;quot;com.informatimago.common-lisp.cesarum&amp;quot;
                 &amp;quot;cl-irc&amp;quot; &amp;quot;cl-json&amp;quot; &amp;quot;drakma&amp;quot;)
    :components ((:file &amp;quot;botihn&amp;quot;)))
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;section&quot; id=&quot;paquetage&quot;&gt;
&lt;h2&gt;Paquetage&lt;/h2&gt;
&lt;p&gt;Nous pouvons alors commencer à programmer notre robot.  Définissons
d&#039;abord le paquetage lisp.  Comme ce sera un petit programme, nous
mettrons tout le code dans un seul fichier, &lt;cite&gt;botihn.lisp&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defpackage &amp;quot;COM.INFORMATIMAGO.SMALL-CL-PGMS.BOTIHN&amp;quot;
  (:use &amp;quot;COMMON-LISP&amp;quot; &amp;quot;CL-IRC&amp;quot; &amp;quot;CL-JSON&amp;quot; &amp;quot;DRAKMA&amp;quot;
        &amp;quot;COM.INFORMATIMAGO.COMMON-LISP.CESARUM.LIST&amp;quot;)
  (:export &amp;quot;MAIN&amp;quot;))
(in-package &amp;quot;COM.INFORMATIMAGO.SMALL-CL-PGMS.BOTIHN&amp;quot;)
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;section&quot; id=&quot;obtenir-les-informations-d-hacker-news&quot;&gt;
&lt;h2&gt;Obtenir les informations d&#039;&lt;em&gt;Hacker News&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;La première chose à faire, est d&#039;obtenir les données.  Pour celà, nous
consultons l&#039;&lt;cite&gt;API&lt;/cite&gt; indiqué en bas de la page d&#039;Hacker News,
&lt;a class=&quot;reference external&quot; href=&quot;https://github.com/HackerNews/API&quot;&gt;https://github.com/HackerNews/API&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Nous allons utiliser l&#039;&lt;cite&gt;URL&lt;/cite&gt;:
&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;https://hacker-news.firebaseio.com/v0/newstories.json&lt;/span&gt;&lt;/tt&gt; pour obtenir
les &lt;cite&gt;ID&lt;/cite&gt; des dernières nouvelles, et
&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;https://hacker-news.firebaseio.com/v0/item/ID.json&lt;/span&gt;&lt;/tt&gt; pour obtenir les
informations sur une nouvelle identifiée par son ID.&lt;/p&gt;
&lt;p&gt;Afin que les données envoyées par le serveur soient considérées comme
du texte par drakma, nous devrons lui indiquer que c&#039;est le cas pour
un &lt;cite&gt;Content-Type&lt;/cite&gt; &lt;cite&gt;application/json&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(push &#039;(&amp;quot;application&amp;quot; . &amp;quot;json&amp;quot;) *text-content-types*)
&lt;/pre&gt;
&lt;p&gt;&lt;cite&gt;DRAKMA:HTTP-REQUEST&lt;/cite&gt; retourne plusieurs valeurs; la première est la
resource obtenue; la deuxième est le code status.  Nous ignorerons les
autres valeurs.&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(http-request &amp;quot;https://hacker-news.firebaseio.com/v0/newstories.json&amp;quot;)
--&amp;gt; &amp;quot;[9446519,9446509,9446505,…,9443212]&amp;quot;
    200
    ((:content-length . &amp;quot;4001&amp;quot;)
     (:strict-transport-security . &amp;quot;max-age=31556926; includeSubDomains; preload&amp;quot;)
     (:content-type . &amp;quot;application/json; charset=utf-8&amp;quot;)
     (:cache-control . &amp;quot;no-cache&amp;quot;))
    #&amp;lt;uri https://hacker-news.firebaseio.com/v0/newstories.json&amp;gt;
    #&amp;lt;flexi-streams:flexi-io-stream #x302006213FED&amp;gt;
    t
    &amp;quot;OK&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Utilisons &lt;cite&gt;CL-JSON:DECODE-JSON-FROM-STRING&lt;/cite&gt; pour décoder le vecteur
&lt;cite&gt;JSON&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun new-stories ()
  (multiple-value-bind (value status)
       (http-request &amp;quot;https://hacker-news.firebaseio.com/v0/newstories.json&amp;quot;)
    (when (= 200 status)
      (decode-json-from-string value))))

(subseq (new-stories) 0 8)
--&amp;gt; (9446577 9446573 9446563 9446561 9446559 9446558 9446541 9446519)
&lt;/pre&gt;
&lt;p&gt;De façon similaire, nous obtiendrons les informations sur une nouvelle
identifiée :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun story (id)
  (multiple-value-bind (value status)
      (http-request (format nil &amp;quot;https://hacker-news.firebaseio.com/v0/item/~A.json&amp;quot; id))
    (when (= 200 status)
      (decode-json-from-string value))))


(story 9446577)
--&amp;gt; ((:by . &amp;quot;antjanus&amp;quot;)
     (:descendants . 0)
     (:id . 9446577)
     (:score . 1)
     (:text . &amp;quot;&amp;quot;)
     (:time . 1430145589)
     (:title . &amp;quot;Ask HN: Where do you look for a job? Why do you pick those places to apply?&amp;quot;)
     (:type . &amp;quot;story&amp;quot;)
     (:url . &amp;quot;&amp;quot;))
&lt;/pre&gt;
&lt;p&gt;Nous allons quérir cette liste périodiquement, et nous ne devons
afficher que les nouvelles nouvelles.  Nous conserverons
l&#039;identification de la dernière nouvelle dans une variable globale
&lt;em&gt;*LAST-STORY*&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defvar *last-story* nil)
&lt;/pre&gt;
&lt;p&gt;Lorsque le programme démarre, &lt;em&gt;*LAST-STORY*&lt;/em&gt; sera &lt;cite&gt;NIL&lt;/cite&gt;, et alors
nous n&#039;afficherons que la toute dernière nouvelle (tant pis pour les
nouvelles manquées pendant que le programme était arrêté).  Sinon,
nous prenons toutes les nouvelles qui se trouvent dans la liste avant
cette dernière nouvelle affichée, et nous renversons la liste pour
l&#039;avoir dans l&#039;ordre chronologique.&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun get-new-stories ()
  (let ((news (new-stories)))
    (if *last-story*
        (reverse (subseq news 0 (or (position *last-story* news) 1)))
        (list (first news)))))
&lt;/pre&gt;
&lt;p&gt;Certaines de ces nouvelles n&#039;ont pas d&#039;&lt;cite&gt;URL&lt;/cite&gt;, mais contienent un texte
sur leur page web sur &lt;em&gt;Hacker News&lt;/em&gt;.  Nous construisons l&#039;&lt;cite&gt;URL&lt;/cite&gt; de
cette page avec la fonction suivante :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun hn-url (story)
  (format nil &amp;quot;https://news.ycombinator.com/item?id=~A&amp;quot; story))
&lt;/pre&gt;
&lt;p&gt;Et formattons le message pour une nouvelle ainsi :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun format-story (story)
  (let ((title  (aget story :title))
        (url    (aget story :url))
        (id     (aget story :id)))
    (when (and title url)
      (format nil &amp;quot;~A &amp;lt;~A&amp;gt;&amp;quot; title (if (zerop (length url))
                                      (hn-url id)
                                      url)))))
&lt;/pre&gt;
&lt;p&gt;Nous pouvons alors effectuer le traitement périodique, consistant à
obtenir les dernières nouvelles, à les formatter et à les envoyer :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun monitor-hacker-news (send)
  (dolist (story (get-new-stories))
    (let ((message (format-story (story story))))
      (when message
        (funcall send message))
      (setf *last-story* story))))
&lt;/pre&gt;
&lt;p&gt;Nous rassemblons l&#039;initialisations dans une fonction :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun monitor-initialize ()
  (unless (find &#039;(&amp;quot;application&amp;quot; . &amp;quot;json&amp;quot;) *text-content-types*
                :test (function equalp))
    (push &#039;(&amp;quot;application&amp;quot; . &amp;quot;json&amp;quot;) *text-content-types*))
  (setf *last-story* nil))
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;section&quot; id=&quot;ecriture-du-client-irc&quot;&gt;
&lt;h2&gt;Écriture du client &lt;cite&gt;IRC&lt;/cite&gt;&lt;/h2&gt;
&lt;p&gt;Se connecter au serveur &lt;cite&gt;IRC&lt;/cite&gt; avec &lt;cite&gt;cl-irc&lt;/cite&gt; et joindre un canal est
trés simple :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defvar *connection* nil)
(defvar *server*   &amp;quot;irc.freenode.org&amp;quot;)
(defvar *nickname* &amp;quot;botihn&amp;quot;)
(defvar *channel*  &amp;quot;#hn&amp;quot;)
(defvar *period* 10 #|seconds|#)

(setf *connection* (connect :nickname *nickname* :server *server*))
(join *connection* *channel*)
&lt;/pre&gt;
&lt;p&gt;Nous pouvons alors transmettre les nouvelles &lt;em&gt;Hacker news&lt;/em&gt;
periodiquement :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(monitor-initialize)
(loop
   (monitor-hacker-news (lambda (message) (privmsg *connection* *channel* message)))
   (sleep *period*))
&lt;/pre&gt;
&lt;p&gt;Cependant, ceci n&#039;est pas satisfaisant, car nous ne recevons ni ne
traitons aucun message provenant du serveur &lt;cite&gt;IRC&lt;/cite&gt;.  Pour celà, il faut
appeler la fonction &lt;cite&gt;(read-message *connection*)&lt;/cite&gt;.  Cette fonction
contient un temps mort de 10 secondes: si aucun message n&#039;est reçu au
bout de 10 secondes, elle retourne &lt;cite&gt;NIL&lt;/cite&gt; au lieu de &lt;cite&gt;T&lt;/cite&gt;.  Comme notre
période de travail n&#039;est pas inférieur à 10 secondes, nous pouvons
nous accomoder de ce temps mort.&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(monitor-initialize)
(loop
  :with next-time = (+ *period* (get-universal-time))
  :for time = (get-universal-time)
  :do (if (&amp;lt;= next-time time)
          (progn
            (monitor-hacker-news (lambda (message) (privmsg *connection* *channel* message)))
            (incf next-time *period*))
          (read-message *connection*) #|there&#039;s a 10 s timeout in here.|#))
&lt;/pre&gt;
&lt;p&gt;Nous pouvons maintenant ajouter une fonction de traitement des
messages privés, afin de fournir sur demande, une information à propos
du robot &lt;cite&gt;botihn&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(add-hook *connection* &#039;irc::irc-privmsg-message &#039;msg-hook)
&lt;/pre&gt;
&lt;p&gt;Avec :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defvar *sources-url* &amp;quot;https://gitlab.com/com-informatimago/com-informatimago/tree/master/small-cl-pgms/botihn/&amp;quot;)

(defun msg-hook (message)
  (when (string= *nickname* (first (arguments message)))
    (privmsg *connection* (source message)
             (format nil &amp;quot;I&#039;m an IRC bot forwarding HackerNews news to ~A; ~
                          under AGPL3 license, my sources are available at &amp;lt;~A&amp;gt;.&amp;quot;
                     *channel*
                     *sources-url*))))
&lt;/pre&gt;
&lt;p&gt;Avec &lt;cite&gt;IRC&lt;/cite&gt;, les messages sont envoyés à un canal ou à un utilisateur
donné en utilisant le même message de protocole, un &lt;cite&gt;PRIVMSG&lt;/cite&gt;.  Le
client peut distinguer à qui le message était envoyé en observant le
premier argument du message, qui sera le nom du canal ou le nom de
l&#039;utilisateur.  Notre robot ne réagit pas aux messages envoyés sur le
canal, mais répond seulement aux messages qui lui sont directement
adressés, avec &lt;cite&gt;/msg&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
/msg botihn heho!

&amp;lt;botihn&amp;gt; I&#039;m an IRC bot forwarding HackerNews news to #hn; under AGPL3 license, my sources
are available at
&amp;lt;https://gitlab.com/com-informatimago/com-informatimago/tree/master/small-cl-pgms/botihn/&amp;gt;.
&lt;/pre&gt;
&lt;p&gt;Jusqu&#039;à présent, nous ne nous sommes pas occupé des cas d&#039;erreur.
Principalement, si une erreur survient, c&#039;est pour cause de
déconnexion du serveur &lt;cite&gt;IRC&lt;/cite&gt;.  Si une erreur survient avec le serveur
de nouvelles, nous obtenons des listes de nouvelles vides, et nous
n&#039;envoyons simplement aucun message.&lt;/p&gt;
&lt;p&gt;Ainsi, si nous détectons une sortie non-locale (avec
&lt;cite&gt;UNWIND-PROTECT&lt;/cite&gt;), nous quittons simplement la connexion, et nous
essayons de nous reconnecter après un délai aléatoire.&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(defun call-with-retry (delay thunk)
  (loop
    (handler-case (funcall thunk)
      (error (err) (format *error-output* &amp;quot;~A~%&amp;quot; err)))
    (funcall delay)))

(defmacro with-retry (delay-expression &amp;amp;body body)
  `(call-with-retry (lambda () ,delay-expression)
                    (lambda () ,&amp;#64;body)))

(defun main ()
  (catch :gazongues
    (with-retry (sleep (+ 10 (random 30)))
      (unwind-protect
           (progn
             (setf *connection* (connect :nickname *nickname* :server *server*))
             (add-hook *connection* &#039;irc::irc-privmsg-message &#039;msg-hook)
             (join *connection* *channel*)
             (monitor-initialize)
             (loop
               :with next-time = (+ *period* (get-universal-time))
               :for time = (get-universal-time)
               :do (if (&amp;lt;= next-time time)
                       (progn
                         (monitor-hacker-news (lambda (message) (privmsg *connection* *channel* message)))
                         (incf next-time *period*))
                       (read-message *connection*) #|there&#039;s a 10 s timeout in here.|#)))
        (when *connection*
          (quit *connection*)
          (setf *connection* nil))))))
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;section&quot; id=&quot;generation-d-un-executable-independant&quot;&gt;
&lt;h2&gt;Génération d&#039;un exécutable indépendant&lt;/h2&gt;
&lt;p&gt;Afin de générer un exécutable indépendant, nous écrivons un petit
script &lt;cite&gt;generate-application.lisp&lt;/cite&gt; qui sera exécuté dans un
environnement vierge.  Ce script charge &lt;cite&gt;quicklisp&lt;/cite&gt;, charge botihn, et
enregistre une image exécutable, en indiquant la fonction &lt;cite&gt;main&lt;/cite&gt; comme
point d&#039;entrée du programme (&lt;cite&gt;toplevel-function&lt;/cite&gt;) :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
(in-package &amp;quot;COMMON-LISP-USER&amp;quot;)
(progn (format t &amp;quot;~%;;; Loading quicklisp.~%&amp;quot;) (finish-output) (values))
(load #P&amp;quot;~/quicklisp/setup.lisp&amp;quot;)

(progn (format t &amp;quot;~%;;; Loading botihn.~%&amp;quot;) (finish-output) (values))
(push (make-pathname :name nil :type nil :version nil
                     :defaults *load-truename*) asdf:*central-registry*)

(ql:quickload :com.informatimago.small-cl-pgms.botihn)

(progn (format t &amp;quot;~%;;; Saving hotihn.~%&amp;quot;) (finish-output) (values))
;; This doesn&#039;t return.
#+ccl (ccl::save-application
       &amp;quot;botihn&amp;quot;
       :mode #o755 :prepend-kernel t
       :toplevel-function (function com.informatimago.small-cl-pgms.botihn:main)
       :init-file nil
       :error-handler :quit)
&lt;/pre&gt;
&lt;p&gt;Un petit &lt;cite&gt;Makefile&lt;/cite&gt; permet d&#039;exécuter ce script facilement à partir du
shell &lt;cite&gt;unix&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
all:botihn
botihn: com.informatimago.small-cl-pgms.botihn.asd  botihn.lisp generate-application.lisp
    ccl -norc &amp;lt; generate-application.lisp
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;section&quot; id=&quot;conclusion&quot;&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Vous pouvez obtenir les sources complets de ce petit exemple à:
&lt;a class=&quot;reference external&quot; href=&quot;https://gitlab.com/com-informatimago/com-informatimago/tree/master/small-cl-pgms/botihn/&quot;&gt;https://gitlab.com/com-informatimago/com-informatimago/tree/master/small-cl-pgms/botihn/&lt;/a&gt; :&lt;/p&gt;
&lt;pre class=&quot;literal-block&quot;&gt;
git clone https://gitlab.com/com-informatimago/com-informatimago.git
cd com-informatimago/small-cl-pgms/botihn/
emacs # edit configuration
make
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/botihn/botihn-fr.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/articles/raspberrypi/ccl-sur-qemu.html</id><published>2013-12-20T22:54:26+0100</published><updated>2015-10-26T00:27:48+0100</updated><title type="text">Clozure CL sur Raspberry Pi (FR)</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/raspberry-pi.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/articles/raspberrypi/ccl-sur-qemu.html&quot;&gt;Clozure CL sur Raspberry Pi (FR)&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Installer Clozure CL sur Raspberry Pi.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;ccl-sur-qemu&quot;&gt;
&lt;h1&gt;Raspberry Pi&lt;/h1&gt;


&lt;p&gt;Je devrais recevoir un Raspberry Pi cette semaine.  Prenant un peu
d&#039;avance, j&#039;ai essayé &lt;a href=&quot;http://ccl.clozure.com/&quot;&gt;&lt;tt&gt;Clozure CL&lt;/tt&gt;&lt;/a&gt;
sur &lt;a href=&quot;http://www.raspbian.org/&quot;&gt;&lt;tt&gt;raspbian&lt;/tt&gt;&lt;/a&gt;  sur l&#039;émulateur
&lt;a href=&quot;https://launchpad.net/qemu-linaro&quot;&gt;&lt;tt&gt;qemu linaro&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;Instructions&lt;/h2&gt;


&lt;p&gt;Suivons les instructions de
&lt;a href=&quot;http://linux-news.org/index.php/2012/06/02/raspberry-pi-emulation/&quot;&gt;
Linux-News Raspberry PI Emulation&lt;/a&gt;.

&lt;pre&gt;
RPI=&quot;$HOME/raspberrypi&quot;
mkdir &quot;$RPI&quot;
cd &quot;$RPI&quot;
wget http://xecdesign.com/downloads/linux-qemu/kernel-qemu
wget http://downloads.raspberrypi.org/images/raspbian/2012-07-15-wheezy-raspbian/2012-07-15-wheezy-raspbian.zip
unzip -x 2012-07-15-wheezy-raspbian.zip
git clone git://git.linaro.org/qemu/qemu-linaro.git
cd qemu-linaro
./configure --prefix=&quot;$RPI&quot;/opt --target-list=arm-softmmu
make
make install
cd &quot;$RPI&quot;
./opt/bin/qemu-system-arm \
    -kernel kernel-qemu \
    -cpu arm1136-r2 \
    -M versatilepb \
    -no-reboot \
    -append &quot;root=/dev/sda2 panic=1&quot; \
    -hda 2012-07-15-wheezy-raspbian.img
&lt;/pre&gt;






&lt;p&gt;Ça démarre bien, mais on n&#039;a pas accès au réseau.  Avec un interface tun configuré sur la machine
hôte, et un serveur DHCP sur le réseau local, on peut configurer un interface réseau tap avec la
commande suivante:


&lt;pre&gt;
cd &quot;$RPI&quot;
./opt/bin/qemu-system-arm \
    -net nic,macaddr=52:54:0:0:0:77 -net tap \
    -kernel kernel-qemu \
    -cpu arm1136-r2 \
    -M versatilepb \
    -no-reboot \
    -append &quot;root=/dev/sda2 panic=1&quot; \
    -hda 2012-07-15-wheezy-raspbian.img
&lt;/pre&gt;


&lt;p&gt;On peut alors se connecter au compte &lt;tt&gt;pi&lt;/tt&gt; (mot de passe par défaut: &lt;tt&gt;raspberry&lt;/tt&gt;),
et utiliser la connection réseau pour installer &lt;a href=&quot;http://ccl.clozure.com/&quot;&gt;&lt;tt&gt;Clozure CL&lt;/tt&gt;&lt;/a&gt;:&lt;/p&gt;


&lt;pre&gt;
svn co http://svn.clozure.com/publicsvn/openmcl/trunk/linuxarm/ccl
ccl/armcl
&lt;/pre&gt;


&lt;p&gt;Et voilà le résultat:
&lt;img src=&quot;ccl-raspberry-pi-qemu.png&quot; alt=&quot;Booting Clozure CL on raspbian on qemu&quot;&gt;&lt;/img&gt;
&lt;/p&gt;


&lt;/p&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/articles/raspberrypi/ccl-sur-qemu.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sudoku-solver/index.html</id><published>2012-12-12T11:00:00+0100</published><updated>2015-10-26T00:27:48+0100</updated><title type="text">Sudoku Solver</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/sudoku.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sudoku-solver/index.html&quot;&gt;Sudoku Solver&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Sudoku Solver&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Brainfuck, Common Lisp, Lisp, virtual machine, compiler, emulator&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;sudoku-solver&quot;&gt;


&lt;h1&gt;Sudoku Solver&lt;/h1&gt;




&lt;p&gt;This file contains a sudoku solver.&lt;/p&gt;




&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;sudoku-solver.lisp&quot;&gt;sudoku-solver.lisp&lt;/a&gt;&lt;/li&gt;



&lt;/ul&gt;




&lt;p&gt;Example:&lt;/p&gt;




&lt;pre class=&quot;dribble&quot;&gt;&lt;span class=&quot;slime-repl-prompt&quot;&gt;sudoku-solver&amp;gt; &lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;(use-package :com.informatimago.sudoku-solver)&lt;/span&gt;&lt;span class=&quot;slime-repl-result&quot;&gt;&lt;span class=&quot;slime-repl-inputed-output&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-result&quot;&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-prompt&quot;&gt;sudoku-solver&amp;gt; &lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cl-special-operator&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;let*&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt; ((sudoku #2A((x x x 8 x 4 2 x x)
                                  (6 x 8 x 2 x x x 4)
                                  (2 1 x 6 5 3 x x 8)
                                  (x 7 x 2 x 6 x 9 x)
                                  (x x x x 3 x 1 x x)
                                  (4 2 3 x x 9 x 5 7)
                                  (x 6 x 4 1 5 7 x x)
                                  (x x 7 x x 8 3 x x)
                                  (x 5 9 x x x x 1 x))))
                 (&lt;/span&gt;&lt;span class=&quot;cl-macro&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;multiple-value-bind&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt; (solutions tries) (sudoku-solver sudoku)
                   (&lt;/span&gt;&lt;span class=&quot;cl-function&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;terpri&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;)
                   (sudoku-print sudoku)
                   (&lt;/span&gt;&lt;span class=&quot;cl-function&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;format&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cl-system-class&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt; &lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;&quot;  has ~D solution~:*~P,~%  found in ~D tries.~2%&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;
                           (&lt;/span&gt;&lt;span class=&quot;cl-function&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;length&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt; solutions) tries)
                   (&lt;/span&gt;&lt;span class=&quot;cl-function&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;map&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cl-type&quot;&gt;&lt;span class=&quot;slime-repl-input&quot;&gt;nil&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-input&quot;&gt; &#039;sudoku-print solutions)))
&lt;/span&gt;&lt;span class=&quot;slime-repl-output&quot;&gt;
+---+---+---+---+---+---+---+---+---+
| .   6   2 | .   .   4 | .   .   . |
|   +   +   |   +   +   |   +   +   |
| .   .   1 | 7   .   2 | 6   .   5 |
|   +   +   |   +   +   |   +   +   |
| .   8   . | .   .   3 | .   7   9 |
+---+---+---+---+---+---+---+---+---+
| 8   .   6 | 2   .   . | 4   .   . |
|   +   +   |   +   +   |   +   +   |
| .   2   5 | .   3   . | 1   .   . |
|   +   +   |   +   +   |   +   +   |
| 4   .   3 | 6   .   9 | 5   8   . |
+---+---+---+---+---+---+---+---+---+
| 2   .   . | .   1   . | 7   3   . |
|   +   +   |   +   +   |   +   +   |
| .   .   . | 9   .   5 | .   .   1 |
|   +   +   |   +   +   |   +   +   |
| .   4   8 | .   .   7 | .   .   . |
+---+---+---+---+---+---+---+---+---+

  has 1 solution,
  found in 44 tries.

+---+---+---+---+---+---+---+---+---+
| 7   6   2 | 5   9   4 | 3   1   8 |
|   +   +   |   +   +   |   +   +   |
| 3   9   1 | 7   8   2 | 6   4   5 |
|   +   +   |   +   +   |   +   +   |
| 5   8   4 | 1   6   3 | 2   7   9 |
+---+---+---+---+---+---+---+---+---+
| 8   7   6 | 2   5   1 | 4   9   3 |
|   +   +   |   +   +   |   +   +   |
| 9   2   5 | 4   3   8 | 1   6   7 |
|   +   +   |   +   +   |   +   +   |
| 4   1   3 | 6   7   9 | 5   8   2 |
+---+---+---+---+---+---+---+---+---+
| 2   5   9 | 8   1   6 | 7   3   4 |
|   +   +   |   +   +   |   +   +   |
| 6   3   7 | 9   4   5 | 8   2   1 |
|   +   +   |   +   +   |   +   +   |
| 1   4   8 | 3   2   7 | 9   5   6 |
+---+---+---+---+---+---+---+---+---+

&lt;/span&gt;&lt;span class=&quot;slime-repl-result&quot;&gt;&lt;span class=&quot;slime-repl-inputed-output&quot;&gt;nil&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-result&quot;&gt;&lt;/span&gt;&lt;span class=&quot;slime-repl-prompt&quot;&gt;sudoku-solver&amp;gt; &lt;/span&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sudoku-solver/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/wang.html</id><published>2012-10-04T14:52:16+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">Old LISP programs still run in Common Lisp</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/hao-wang.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/wang.html&quot;&gt;Old LISP programs still run in Common Lisp&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;How to run in Common Lisp, Hao Wang&#039;s algorithm published by John
    McCarthy as an application of LISP, in the manual of the first version
    of LISP on IBM 704, dated March 1960.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;LISP 1.5, Common Lisp, Lisp, Wang algorithm&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;wang&quot;&gt;


&lt;h1&gt;Old LISP programs still run in Common Lisp&lt;/h1&gt;




&lt;p&gt;Actually, any Common Lisp implementation can be applied with
     almost all Lisp material from any time, thanks to the concensual
     approach of the Common Lisp standard.&lt;/p&gt;




&lt;p&gt;For example, here is how you can run a lisp program written in
     1960 in a Common Lisp of 2014.  Rendez-vous in 28 years to see
     how you can run a 1996 perl program in perl 2042...&lt;/p&gt;




&lt;p&gt;This Wang&#039;s algorithm has been popularized by John McCarthy as an
     application of LISP, published in the manual of the first version
     of LISP, LISP 1 implémenté sur IBM 704, dated March 1960.
    &lt;a href=&quot;http://community.computerhistory.org/scc/projects/LISP/book/LISP%20I%20Programmers%20Manual.pdf&quot;&gt;LISP 1 Programmer&#039;s Manual, page 32&lt;/a&gt;
    (and also reproduced in
    &lt;a href=&quot;http://community.computerhistory.org/scc/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=52&quot;&gt;LISP
      1.5 Programmer&#039;s Manual, Chapter VIII, page 52: A Complete LISP
      Program - the Wang Algorithm for the Propositional
      Calculus.&lt;/a&gt;). &lt;/p&gt;





&lt;pre class=&quot;code&quot;&gt;
----(wang-cl.lisp)------------------------------------------------------
(shadow &#039;(trace untrace))
(defun trace   (functions) (eval `(cl:trace   ,@functions)))
(defun untrace (functions) (eval `(cl:untrace ,@functions)))

(defun define (definitions)
  (dolist (def definitions)
    (eval (if (and (consp (second def)) (eq &#039;lambda (car (second def))))
              `(progn (defun        ,(first def) ,@(cdr (second def)))
                      (defparameter ,(first def) ,(second def)))
              `(defparameter ,(first def) ,(second def))))))

(defun stop (arguments) (throw &#039;driver-end-of-deck nil))
(defun fin  (arguments) (throw &#039;driver-end-of-deck nil))
(defun test (arguments) (princ arguments) (terpri))

(defun driver (path)
  (with-open-file (cards path)
    (catch &#039;driver-end-of-deck
      (loop (let ((first-char (read-char cards)))
              (if (char= #\* first-char)
                  (read-line cards)     ; comment
                  (progn
                    (unread-char first-char cards)
                    (let* ((command   (read cards))
                           (arguments (if (member command &#039;(stop fin test))
                                          (list (read-line cards))
                                          (read cards))))
                      (print (apply command arguments))))))))))

(driver &quot;wang.job&quot;)
----(wang.job)----------------------------------------------------------
* M948-1207 LEVIN, LISP, TEST, 2,3,250,0
        TEST WANG ALGORITHM FOR THE PROPOSITIONAL CALCULUS

DEFINE ((
(THEOREM (LAMBDA (S) (TH1 NIL NIL (CADR S) (CADDR S))))

(TH1 (LAMBDA (A1 A2 A C) (COND ((NULL A)
        (TH2 A1 A2 NIL NIL C)) (T
        (OR (MEMBER (CAR A) C) (COND ((ATOM (CAR A))
        (TH1 (COND ((MEMBER (CAR A) A1) A1)
        (T (CONS (CAR A) A1))) A2 (CDR A) C))
        (T (TH1 A1 (COND ((MEMBER (CAR A) A2) A2)
        (T (CONS (CAR A) A2))) (CDR A) C))))))))

(TH2 (LAMBDA (A1 A2 C1 C2 C) (COND
        ((NULL C) (TH A1 A2 C1 C2))
        ((ATOM (CAR C)) (TH2 A1 A2 (COND
        ((MEMBER (CAR C) C1) C1) (T
        (CONS (CAR C) C1))) C2 (CDR C)))
        (T (TH2 A1 A2 C1 (COND ((MEMBER
        (CAR C) C2) C2) (T (CONS (CAR C) C2)))
        (CDR C))))))

(TH (LAMBDA (A1 A2 C1 C2) (COND ((NULL A2) (AND (NOT (NULL C2))
        (THR (CAR C2) A1 A2 C1 (CDR C2)))) (T (THL (CAR A2) A1 (CDR A2)
        C1 C2)))))

(THL (LAMBDA (U A1 A2 C1 C2) (COND
        ((EQ (CAR U) (QUOTE NOT)) (TH1R (CADR U) A1 A2 C1 C2))
        ((EQ (CAR U) (QUOTE AND)) (TH2L (CDR U) A1 A2 C1 C2))
        ((EQ (CAR U) (QUOTE OR)) (AND (TH1L (CADR U) A1 A2 C1 C2)
        (TH1L (CADDR U) A1 A2 C1 C2) ))
        ((EQ (CAR U) (QUOTE IMPLIES)) (AND (TH1L (CADDR U) A1 A2 C1
        C2) (TH1R (CADR U) A1 A2 C1 C2) ))
        ((EQ (CAR U) (QUOTE EQUIV)) (AND (TH2L (CDR U) A1 A2 C1 C2)
        (TH2R (CDR U) A1 A2 C1 C2) ))
        (T (ERROR (LIST (QUOTE THL) U A1 A2 C1 C2)))
        )))

(THR (LAMBDA (U A1 A2 C1 C2) (COND
        ((EQ (CAR U) (QUOTE NOT)) (TH1L (CADR U) A1 A2 C1 C2))
        ((EQ (CAR U) (QUOTE AND)) (AND (TH1R (CADR U) A1 A2 C1 C2)
        (TH1R (CADDR U) A1 A2 C1 C2) ))
        ((EQ (CAR U) (QUOTE OR)) (TH2R (CDR U) A1 A2 C1 C2))
        ((EQ (CAR U) (QUOTE IMPLIES)) (TH11 (CADR U) (CADDR U)
         A1 A2 C1 C2))
        ((EQ (CAR U) (QUOTE EQUIV)) (AND (TH11 (CADR U) (CADDR U)
        A1 A2 C1 C2) (TH11 (CADDR U) (CADR U) A1 A2 C1 C2) ))
        (T (ERROR (LIST (QUOTE THR) U A1 A2 C1 C2)))
        )))

(TH1L (LAMBDA (V A1 A2 C1 C2) (COND
        ((ATOM V) (OR (MEMBER V C1)
        (TH (CONS V A1) A2 C1 C2) ))
        (T (OR (MEMBER V C2) (TH A1 (CONS V A2) C1 C2) ))
        )))

(TH1R (LAMBDA (V A1 A2 C1 C2) (COND
        ((ATOM V) (OR (MEMBER V A1)
        (TH A1 A2 (CONS V C1) C2) ))
        (T (OR (MEMBER V A2) (TH A1 A2 C1 (CONS V C2))))
        )))

(TH2L (LAMBDA (V A1 A2 C1 C2) (COND
        ((ATOM (CAR V)) (OR (MEMBER (CAR V) C1)
        (TH1L (CADR V) (CONS (CAR V) A1) A2 C1 C2)))
        (T (OR (MEMBER (CAR V) C2) (TH1L (CADR V) A1 (CONS (CAR V)
        A2) C1 C2)))
        )))

(TH2R (LAMBDA (V A1 A2 C1 C2) (COND
        ((ATOM (CAR V)) (OR (MEMBER (CAR V) A1)
        (TH1R (CADR V) A1 A2 (CONS (CAR V) C1) C2)))
        (T (OR (MEMBER (CAR V) A2) (TH1R (CADR V) A1 A2 C1
        (CONS (CAR V) C2))))
        )))

(TH11 (LAMBDA (VI V2 A1 A2 C1 C2) (COND
        ((ATOM VI) (OR (MEMBER VI C1) (TH1R V2 (CONS VI A1) A2 C1
        C2)))
        (T (OR (MEMBER VI C2) (TH1R V2 A1 (CONS VI A2) C1 C2)))
        )))
))

TRACE ((THEOREM TH1 TH2 TH THL THR TH1L TH1R TH2L TH2R TH11))

THEOREM
((ARROW (P) ((OR P Q))))

UNTRACE ((THEOREM TH1 TH2 THR THL TH1L TH1R TH2L TH2R TH11))

THEOREM
((ARROW ((OR A (NOT B))) ((IMPLIES (AND P Q) (EQUIV P Q))) ))

STOP)))    )))     )))     )))
FIN     END OF LISP RUN        M948-1207 LEVIN
------------------------------------------------------------------------

[60]&gt; (load&quot;wang-cl.lisp&quot;)
;; Loading file wang-cl.lisp ...
WANG ALGORITHM FOR THE PROPOSITIONAL CALCULUS

NIL
WARNING: DEFUN/DEFMACRO: redefining TH; it was traced!
NIL
;; Tracing function THEOREM.
;; Tracing function TH1.
;; Tracing function TH2.
;; Tracing function TH.
;; Tracing function THL.
;; Tracing function THR.
;; Tracing function TH1L.
;; Tracing function TH1R.
;; Tracing function TH2L.
;; Tracing function TH2R.
;; Tracing function TH11.
(THEOREM TH1 TH2 TH THL THR TH1L TH1R TH2L TH2R TH11)
1. Trace: (THEOREM &#039;(ARROW (P) ((OR P Q))))
2. Trace: (TH1 &#039;NIL &#039;NIL &#039;(P) &#039;((OR P Q)))
3. Trace: (TH1 &#039;(P) &#039;NIL &#039;NIL &#039;((OR P Q)))
4. Trace: (TH2 &#039;(P) &#039;NIL &#039;NIL &#039;NIL &#039;((OR P Q)))
5. Trace: (TH2 &#039;(P) &#039;NIL &#039;NIL &#039;((OR P Q)) &#039;NIL)
6. Trace: (TH &#039;(P) &#039;NIL &#039;NIL &#039;((OR P Q)))
7. Trace: (THR &#039;(OR P Q) &#039;(P) &#039;NIL &#039;NIL &#039;NIL)
8. Trace: (TH2R &#039;(P Q) &#039;(P) &#039;NIL &#039;NIL &#039;NIL)
8. Trace: TH2R ==&gt; (P)
7. Trace: THR ==&gt; (P)
6. Trace: TH ==&gt; (P)
5. Trace: TH2 ==&gt; (P)
4. Trace: TH2 ==&gt; (P)
3. Trace: TH1 ==&gt; (P)
2. Trace: TH1 ==&gt; (P)
1. Trace: THEOREM ==&gt; (P)
(P)
(THEOREM TH1 TH2 THR THL TH1L TH1R TH2L TH2R TH11)
1. Trace: (TH &#039;NIL &#039;((OR A (NOT B))) &#039;NIL &#039;((IMPLIES (AND P Q) (EQUIV P Q))))
2. Trace: (TH &#039;(A) &#039;NIL &#039;NIL &#039;((IMPLIES (AND P Q) (EQUIV P Q))))
3. Trace: (TH &#039;(A) &#039;((AND P Q)) &#039;NIL &#039;((EQUIV P Q)))
4. Trace: (TH &#039;(Q P A) &#039;NIL &#039;NIL &#039;((EQUIV P Q)))
4. Trace: TH ==&gt; (P A)
3. Trace: TH ==&gt; (P A)
2. Trace: TH ==&gt; (P A)
2. Trace: (TH &#039;NIL &#039;((NOT B)) &#039;NIL &#039;((IMPLIES (AND P Q) (EQUIV P Q))))
3. Trace: (TH &#039;NIL &#039;NIL &#039;(B) &#039;((IMPLIES (AND P Q) (EQUIV P Q))))
4. Trace: (TH &#039;NIL &#039;((AND P Q)) &#039;(B) &#039;((EQUIV P Q)))
5. Trace: (TH &#039;(Q P) &#039;NIL &#039;(B) &#039;((EQUIV P Q)))
5. Trace: TH ==&gt; (P)
4. Trace: TH ==&gt; (P)
3. Trace: TH ==&gt; (P)
2. Trace: TH ==&gt; (P)
1. Trace: TH ==&gt; (P)
(P)
;; Loaded file wang-cl.lisp
T
[61]&gt;
  &lt;/pre&gt;




&lt;p&gt;Note, the output obviously differ in the form, but the semantics
     are the same, notably the result of the theorem function calls is
     &quot;true&quot; both in 2014 Common Lisp and in 1966 LISP 1.5. &lt;/p&gt;




&lt;p&gt;You may also download the sources here:&lt;/p&gt;



&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;wang-cl.lisp&quot;&gt;wang-cl.lisp&lt;/a&gt;

&lt;li&gt;&lt;a href=&quot;wang.job&quot;&gt;wang.job&lt;/a&gt;
  &lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/wang.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/intersection-r5rs-common-lisp-emacs-lisp/index.html</id><published>2011-05-27T12:00:00+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">Intersection Common Lisp, Emacs Lisp and R5RS Scheme</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/intersection.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/intersection-r5rs-common-lisp-emacs-lisp/index.html&quot;&gt;Intersection Common Lisp, Emacs Lisp and R5RS Scheme&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A program that can be interpreted by both Common Lisp, Emacs Lisp and R5RS Scheme.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Intersection, Common Lisp, Emacs Lisp, R5RS, Scheme, Lisp&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;intersection-r5rs-cl-el&quot;&gt;


&lt;h1&gt;Intersection Common Lisp, Emacs Lisp and R5RS Scheme&lt;/h1&gt;




&lt;p&gt;&lt;a href=&quot;intersection-cl-el-r5rs.lisp&quot;&gt;intersection-cl-el-r5rs.lisp&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;This lisp source file can be loaded and run on:

&lt;ul&gt;



&lt;li&gt; any Common Lisp conforming implementation, &lt;/li&gt;



&lt;li&gt; any R5RS implementation,&lt;/li&gt;



&lt;li&gt; GNU emacs (tested with emacs-23 and emacs-24).&lt;/li&gt;



&lt;/ul&gt;


  &lt;/p&gt;




&lt;p&gt;Example:

&lt;pre class=&quot;code&quot;&gt;
        &lt;span class=&quot;comint-highlight-prompt&quot;&gt;[pjb@kuiper :0 intersection-r5rs-common-lisp-emacs-lisp]$ &lt;/span&gt;&lt;span class=&quot;comint-highlight-input&quot;&gt;make test-intersection-cl-el-r5rs&lt;/span&gt;


;;======================================================================
;; Test intersection-cl-el-r5rs
;;

;; Common Lisp
clisp &lt;span class=&quot;comment&quot;&gt;-ansi&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-norc&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-q&lt;/span&gt; intersection-cl-el-r5rs.lisp

(booted a lisp over common-lisp)
((fact 10) = 3628800)

;; Emacs Lisp
emacs &lt;span class=&quot;comment&quot;&gt;-Q&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;--batch&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-l&lt;/span&gt; intersection-cl-el-r5rs.lisp &lt;span class=&quot;comment&quot;&gt;-q&lt;/span&gt;

(booted a lisp over emacs-lisp)
((fact 10) = 3628800)

;; Scheme
bigloo &lt;span class=&quot;comment&quot;&gt;-no-hello&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-q&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-w&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-load&lt;/span&gt;  intersection-cl-el-r5rs.lisp &lt;span class=&quot;comment&quot;&gt;-eval&lt;/span&gt; &#039;(quit)&#039;

(booted a lisp over scheme)
((fact 10) = 3628800)
&lt;span class=&quot;comint-highlight-prompt&quot;&gt;[pjb@kuiper :0 intersection-r5rs-common-lisp-emacs-lisp]$&lt;/span&gt;&lt;/pre&gt;



&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/intersection-r5rs-common-lisp-emacs-lisp/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/articles/flpl/index.html</id><published>2011-01-19T00:55:26+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">A Fortran-Compiled List-Processing Language</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/IBM704b.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/articles/flpl/index.html&quot;&gt;A Fortran-Compiled List-Processing Language&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A transcription of the April 1959 article &quot;A Fortran-Compiled List-Processing Language&quot; by: H. Gelernter, J. R. Hansen, C. L. Gerberich.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;flpl&quot;&gt;
&lt;h1&gt;A Fortran-Compiled List-Processing Language&lt;/h1&gt;



&lt;p&gt;Here is a transcription of the April 1959 article  &quot;A
Fortran-Compiled List-Processing Language&quot; by: H. Gelernter,
J. R. Hansen, C. L. Gerberich.

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;flpl.pdf&quot;&gt;PDF file&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;flpl.html&quot;&gt;HTML file&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;flpl.txt&quot;&gt;reStructured source&lt;/a&gt; with &lt;a href=&quot;figures.lisp&quot;&gt;lisp source&lt;/a&gt;&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/articles/flpl/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/articles/emacs-colors/index.html</id><published>2010-10-20T08:16:58+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">Playing with colors in emacs</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/colors.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/articles/emacs-colors/index.html&quot;&gt;Playing with colors in emacs&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Having fun with color text properties in GNU emacs.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;emacs-color&quot;&gt;
&lt;h1&gt;Playing with colors in emacs&lt;/h1&gt;


&lt;p&gt;The fundamental feature to set the color of characters in emacs are
the text properties, namely, the face text property.&lt;/p&gt;


&lt;p&gt;An important precondition is to disable font-locking, since this
feature will override any colorizing you may be doing, usually soon
enough that you won&#039;t even see the result of your settings.&lt;/p&gt;


&lt;pre&gt;
(add-text-properties start end
     `(face (:foreground ,(format &quot;#%02x%02x%02x&quot; red green blue)))
&lt;/pre&gt;



&lt;img src=&quot;rainbow.png&quot; alt=&quot;A picture of the code of the rainbow function, applied to itself.&quot;&gt;


&lt;pre&gt;

(require &#039;cl)

(defun gradient (start end start-color end-color)
  (destructuring-bind (red green blue) start-color
    (destructuring-bind (ered egreen eblue) end-color
      (let* ((count     (coerce (- end    start) &#039;float))
             (ired   (/ (- ered   red)   count))
             (igreen (/ (- egreen green) count))
             (iblue  (/ (- eblue  blue)  count)))
        (while (&amp;lt; 0 count)
          (add-text-properties start (incf start)
                               `(face (:foreground ,(format &quot;#%02x%02x%02x&quot;
                                                            red green blue))))
          (incf red   ired)
          (incf green igreen)
          (incf blue  iblue)
          (decf       count))))))


(defun rgb (name)
  (let ((entry (assoc name color-name-rgb-alist)))
    (if entry
        (mapcar (lambda (x) (/ x 256.0)) (rest entry))
        &#039;(0 0 0))))

(defun rainbow (start end)
  (interactive &quot;r&quot;)
  (let ((range (truncate (- end start) 5)))
    (loop
       for (from to) on (list (rgb &quot;red&quot;)
                              (rgb &quot;orange&quot;)
                              (rgb &quot;yellow&quot;)
                              (rgb &quot;green&quot;)
                              (rgb &quot;blue&quot;)
                              (rgb &quot;violet&quot;))
       while to
       for start from start           by range
       for next  from (+ start range) by range
       do (gradient start (if to next end) from to))))

(progn (font-lock-mode -1)
       (rainbow (point-min) (point-max)))

&lt;/pre&gt;


&lt;/img&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/articles/emacs-colors/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/articles/life-saver.html</id><published>2010-10-14T23:48:34+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">Life Saver</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/articles/lifesaver.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/articles/life-saver.html&quot;&gt;Life Saver&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Libraries and tools to help to the Lisp programmer having to write C++ code.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;emacs-color&quot;&gt;

&lt;img src=&quot;lifesaver.jpg&quot; class=&quot;floatRight&quot; alt=&quot;A picture of a life saver of the Titanic, the later representing about any C++ project...&quot;&gt;

&lt;h1&gt;Life Saver &amp;#8212; Help to the Lisp programmer having to write C++ code&lt;/h1&gt;



&lt;p&gt;If you have to write a program in C++, condolences.&lt;/p&gt;


&lt;p&gt;Now to relieve the pain somewhat, here are some libraries and tools that may be of use.&lt;/p&gt;



&lt;small&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#openc++&quot;&gt;Metaprogramming: OpenC++&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;#lpp&quot;&gt;Sexps and Dynamic Data Structures: Lpp&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;#sexp&quot;&gt;Writing Sexp-formated data: Rivest&#039;s SEXP&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;#intelib&quot;&gt;Writing Lisp code in C++: InteLib&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;#boehmgc&quot;&gt;Garbage Collection: BoehmGC&lt;/a&gt;&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/small&gt;

&lt;p&gt;&lt;small&gt;Colophon: The examples below are taken from the
documentations of each of these libraries, and are copyrighted by
their respective authors.  The diagram is linked directly from the
OpenC++ site.  The Titanic life saver picture has been ruthelessly
copied from the web.  The examples are formated with the &lt;a href=&quot;http://www.gnu.org/software/emacs&quot;&gt;GNU emacs&lt;/a&gt;&lt;code&gt;htmlize-region&lt;/code&gt; command.&lt;/small&gt;&lt;/p&gt;






&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;&lt;a name=&quot;openc++&quot;&gt;
&lt;h2&gt;Metaprogramming: OpenC++&lt;/h2&gt;


&lt;p&gt;&lt;a href=&quot;http://www.csg.is.titech.ac.jp/~chiba/openc++.html&quot;&gt;OpenC++&lt;/a&gt;
is a pre-processor to C++, which extends C++ with a Meta Object
Protocol (MOP), which allow you to do metaprogramming in a sane way
(nothing to do with templates and boost hell).&lt;/p&gt;



&lt;center&gt;
&lt;img src=&quot;http://www.csg.is.titech.ac.jp/~chiba/opencxx/html/occ.gif&quot; alt=&quot;[metal-level program .cc] --&gt; &lt;OpenC++ compiler&gt; --&gt; &lt;C++ compiler&gt; --&gt; [C++ module .so],[base-level program .cc] --&gt; [OpenC++ compiler] --&gt; [C++ compiler] --&gt; [object .o]&quot;&gt;&lt;/img&gt;
&lt;/center&gt;



&lt;blockquote&gt;
&lt;em&gt;Notice that gcc 4.4.3 on Linux x86_64 can&#039;t compile occ programs:&lt;/em&gt;
&lt;pre&gt;
/usr/include/wchar.h:220: parse error before `&quot;wcschr&quot;&#039;
/usr/include/stdlib.h:525: parse error before `&quot;at_quick_exit&quot;&#039;
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3
&lt;/pre&gt;
&lt;em&gt;We&#039;d probably need to use an older gcc.&lt;/em&gt;
&lt;/blockquote&gt;




&lt;p&gt;Meta programs have the same form and syntax as normal C++ program,
the only syntactic extensions being a &lt;em&gt;metaclass&lt;/em&gt; keyword.
&lt;p&gt;


&lt;p&gt;&lt;code&gt;VerboseClass.cc&lt;/code&gt;:

&lt;pre&gt;

&lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;VerboseClass.mc
&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;mop.h&quot;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;VerboseClass&lt;/span&gt; : &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Class&lt;/span&gt; {
&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;:
    &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;* &lt;span class=&quot;function-name&quot;&gt;TranslateMemberCall&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;Environment&lt;/span&gt;*, &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;*, &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;*,
                               &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;*, &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;*);
};
&lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;* &lt;span class=&quot;constant&quot;&gt;VerboseClass&lt;/span&gt;::&lt;span class=&quot;function-name&quot;&gt;TranslateMemberCall&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;Environment&lt;/span&gt;* &lt;span class=&quot;variable-name&quot;&gt;env&lt;/span&gt;,
                                         &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;* &lt;span class=&quot;variable-name&quot;&gt;object&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;* &lt;span class=&quot;variable-name&quot;&gt;op&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;* &lt;span class=&quot;variable-name&quot;&gt;member&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Ptree&lt;/span&gt;* &lt;span class=&quot;variable-name&quot;&gt;arglist&lt;/span&gt;)
{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Ptree&lt;/span&gt;::Make(&lt;span class=&quot;string&quot;&gt;&quot;(puts(\&quot;%p()\&quot;), %p)&quot;&lt;/span&gt;,
                       member,
                       &lt;span class=&quot;constant&quot;&gt;Class&lt;/span&gt;::TranslateMemberCall(env, object,
                                                  op,
                                                  member, arglist));
}

&lt;/pre&gt;


&lt;code&gt;person.cc&lt;/code&gt;:
&lt;pre&gt;

&lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;person.cc
&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
metaclass &lt;span class=&quot;type&quot;&gt;VerboseClass&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;Person&lt;/span&gt;; &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;metaclass declaration
&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Person&lt;/span&gt; {
&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;:
    &lt;span class=&quot;function-name&quot;&gt;Person&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;age&lt;/span&gt;);
    &lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;Age&lt;/span&gt;() { &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; age; }
    &lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;BirthdayComes&lt;/span&gt;() { &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; ++age; }
    2
    &lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;:
    &lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; age;
};
&lt;span class=&quot;function-name&quot;&gt;main&lt;/span&gt;()
{
    &lt;span class=&quot;type&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;billy&lt;/span&gt;(24);
    printf(&lt;span class=&quot;string&quot;&gt;&quot;age %d\n&quot;&lt;/span&gt;, billy.Age());
    printf(&lt;span class=&quot;string&quot;&gt;&quot;age %d\n&quot;&lt;/span&gt;, billy.BirthdayComes());
}

&lt;/pre&gt;


When compiled with:

&lt;pre&gt;

% occ -m -- -g VerboseClass.mc
% occ -- -g -o person person.cc

&lt;/pre&gt;


produces:

&lt;pre&gt;

% person
Age()
age 24
BirthdayComes()
age 25

&lt;/pre&gt;


&lt;p&gt;It also allow to easily define new control structures (patterned after
the existing ones) such as:

&lt;pre&gt;

{
    &lt;span class=&quot;type&quot;&gt;Matrix&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;m&lt;/span&gt;;
    m.forall(e){ e = 0.0; }
}

&lt;/pre&gt;




&lt;p&gt;Notice that the OpenC++ preprocessor is able to output the syntax
tree of a C++ source in a processable form!&lt;/p&gt;



&lt;pre&gt;

% myocc -s person.cc
[&lt;span class=&quot;keyword&quot;&gt;typedef&lt;/span&gt; [&lt;span class=&quot;type&quot;&gt;char&lt;/span&gt;] [* __gnuc_va_list] ;]
    :
    :
[metaclass VerboseClass Person nil ;]
[[[class Person nil [{ [
                        [public :]
                        [nil [Person ( [[[&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt;] [i]]] )] [{ [
                                                            [[age = i] ;]
                                                            ] }]]
                        [[&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt;] [Age ( nil )] [{ [
                                                 [&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; age ;]
                                                 ] }]]
                        [[&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt;] [BirthdayComes ( nil )] [{ [
                                                           [&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; [++ age] ;]
                                                           ] }]]
                        [private :]
                        [[&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt;] [age] ;]
                        ] }]]] ;]
[nil nil [main ( nil )] [{ [
                            [[Person] [billy ( [24] )] ;]
                            [[printf [( [&lt;span class=&quot;string&quot;&gt;&quot;age %d\n&quot;&lt;/span&gt; , [billy . Age [( nil )]]] )]] ;]
                            [[printf [( [&lt;span class=&quot;string&quot;&gt;&quot;age %d\n&quot;&lt;/span&gt; , [billy . BirthdayComes ...
                                                       ] }]]
%

&lt;/pre&gt;







&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;&lt;a name=&quot;lpp&quot;&gt;
&lt;h2&gt;Sexps and Dynamic Data Structures: Lpp&lt;/h2&gt;


&lt;p&gt;&lt;a href=&quot;http://www.interhack.net/projects/lpp/&quot;&gt;Lpp&lt;/a&gt; is a C++
library of Lisp-like functions and macros, providing the various data
types commonly found in Lisp, such as symbols, lists, hash-tables,
etc.

&lt;blockquote&gt;
&lt;em&gt;Unfortunately, the latest versions of &lt;b&gt;Lpp&lt;/b&gt; (1.21.2 and
previous) don&#039;t compile with gcc-4.4.3; there are a lot of missing
extern declarations...&lt;/em&gt;
&lt;/blockquote&gt;




&lt;pre&gt;

     &lt;span class=&quot;comment-delimiter&quot;&gt;/////////////////////////////////////////////////////////////////&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&lt;/span&gt;     &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;main.cc = Introduction Simple Data Base example.
&lt;/span&gt;
&lt;span class=&quot;preprocessor&quot;&gt;     #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;Lpp.hh&amp;gt;&lt;/span&gt;

     &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Data Base class.
&lt;/span&gt;     &lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;DataBase&lt;/span&gt; {
       &lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;size&lt;/span&gt;;
       &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;contents&lt;/span&gt;;
     &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;:
       &lt;span class=&quot;function-name&quot;&gt;DataBase&lt;/span&gt;();
       &lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;getSize&lt;/span&gt;() {&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; size;}
       &lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;addEntity&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;let&lt;/span&gt;);
       &lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;setValue&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;let&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt;);
       &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;getValue&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;let&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt;);};

     &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Data Base constructor.
&lt;/span&gt;     &lt;span class=&quot;constant&quot;&gt;DataBase&lt;/span&gt;::&lt;span class=&quot;function-name&quot;&gt;DataBase&lt;/span&gt;() {size = 0; contents = makeHashTable();}

     &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Add an entity to the Data Base.
&lt;/span&gt;     &lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;DataBase&lt;/span&gt;::&lt;span class=&quot;function-name&quot;&gt;addEntity&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;entity&lt;/span&gt;) {
       &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;negation-char&quot;&gt;!&lt;/span&gt;gethash(entity, contents)) {
         puthash(entity, contents, 0);
         size++;}}

     &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Set the value of an attribute for given entity.
&lt;/span&gt;     &lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;DataBase&lt;/span&gt;::&lt;span class=&quot;function-name&quot;&gt;setValue&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;entity&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;attribute&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;value&lt;/span&gt;) {
       &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;attributes&lt;/span&gt; = gethash(entity, contents);
       &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;old&lt;/span&gt; = assoc(attribute, attributes);
       &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (old) rplacd(old, value);
       &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
         push(cons(attribute, value), attributes);
         puthash(entity, contents, attributes);}}

     &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;Return the value of an attribute for given entity.
&lt;/span&gt;     &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;DataBase&lt;/span&gt;::&lt;span class=&quot;function-name&quot;&gt;getValue&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;entity&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;attribute&lt;/span&gt;) {
       &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; cdr(assoc(attribute, gethash(entity, contents)));}

&lt;/pre&gt;






&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;&lt;a name=&quot;sexp&quot;&gt;
&lt;h2&gt;Writing Sexp-formated data in C: Rivest&#039;s SEXP&lt;/h2&gt;


&lt;p&gt;Ronald L. Rivest&#039;s &lt;a href=&quot;http://people.csail.mit.edu/rivest/sexp.html&quot;&gt;SEXP&lt;/a&gt;
format writes and reads data in a sexp-like format, with some provision for binary data.

&lt;p&gt;It may be a nice alternative to JSON or XML.   Of course, one can
always read or parse Common Lisp sexps too.&lt;/p&gt;


&lt;p&gt;A short example:
&lt;pre&gt;

    (6:issuer3:bob)

    (4:icon[12:image/bitmap]9:xxxxxxxxx)

    (7:subject(3:ref5:alice6:mother))

&lt;/pre&gt;



&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;&lt;a name=&quot;intelib&quot;&gt;
&lt;h2&gt;Writing Lisp code in C++: InteLib&lt;/h2&gt;


&lt;p&gt;&lt;a href=&quot;http://www.intelib.org/&quot;&gt;InteLib&lt;/a&gt; is a C++ library
allowing us to write dynamic code, using a subset of C++ syntax similar
to Lisp syntax, without any preprocessing.
&lt;p&gt;

&lt;p&gt;&lt;code&gt;isomorph.cpp&lt;/code&gt;:


&lt;pre&gt;

 &lt;span class=&quot;comment-delimiter&quot;&gt;//       &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;File isomorph.cpp
&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;intelib/lisp/lisp.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;intelib/lisp/lsymbol.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;intelib/lfun_std.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;intelib/lfun_sel.hpp&amp;gt;&lt;/span&gt;


 &lt;span class=&quot;type&quot;&gt;LSymbol&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;ISOMORPHIC&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;ISOMORPHIC&quot;&lt;/span&gt;);

 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LFunctionalSymbol&lt;/span&gt;&amp;lt;LFunctionDefun&amp;gt; &lt;span class=&quot;function-name&quot;&gt;DEFUN&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;DEFUN&quot;&lt;/span&gt;);
 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LFunctionalSymbol&lt;/span&gt;&amp;lt;LFunctionCond&amp;gt; &lt;span class=&quot;function-name&quot;&gt;COND&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;COND&quot;&lt;/span&gt;);
 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LFunctionalSymbol&lt;/span&gt;&amp;lt;LFunctionAtom&amp;gt; &lt;span class=&quot;function-name&quot;&gt;ATOM&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;ATOM&quot;&lt;/span&gt;);
 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LFunctionalSymbol&lt;/span&gt;&amp;lt;LFunctionAnd&amp;gt; &lt;span class=&quot;function-name&quot;&gt;AND&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;AND&quot;&lt;/span&gt;);
 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LFunctionalSymbol&lt;/span&gt;&amp;lt;LFunctionCar&amp;gt; &lt;span class=&quot;function-name&quot;&gt;CAR&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;CAR&quot;&lt;/span&gt;);
 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LFunctionalSymbol&lt;/span&gt;&amp;lt;LFunctionCdr&amp;gt; &lt;span class=&quot;function-name&quot;&gt;CDR&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;CDR&quot;&lt;/span&gt;);

 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LListConstructor&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;L&lt;/span&gt;;

 &lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; LispInit_isomorphic() {
   &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LSymbol&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;TREE1&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;TREE1&quot;&lt;/span&gt;);
   &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LSymbol&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;TREE2&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;TREE2&quot;&lt;/span&gt;);
   &lt;span class=&quot;comment-delimiter&quot;&gt;////////////////////////////////////////////////&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&lt;/span&gt;   &lt;span class=&quot;comment-delimiter&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&lt;/span&gt;   (L|DEFUN, ISOMORPHIC, (L|TREE1, TREE2),
     (L|COND,
       (L|(L|ATOM, TREE1), (L|ATOM, TREE2)),
       (L|(L|ATOM, TREE2), NIL),
       (L|T, (L|AND,
         (L|ISOMORPHIC, (L|CAR, TREE1),
                        (L|CAR, TREE2)),
         (L|ISOMORPHIC, (L|CDR, TREE1),
                        (L|CDR, TREE2))
   )))).Evaluate();
   &lt;span class=&quot;comment-delimiter&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&lt;/span&gt;   &lt;span class=&quot;comment-delimiter&quot;&gt;////////////////////////////////////////////////&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&lt;/span&gt; }
 &lt;span class=&quot;comment-delimiter&quot;&gt;//      &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;end of file
&lt;/span&gt;&lt;/pre&gt;


&lt;code&gt;main.cpp&lt;/code&gt;:

&lt;pre&gt;

 &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;file main.cpp
&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;intelib/sexpress/sexpress.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;intelib/sexpress/sstring.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt; #include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;intelib/lisp/lsymbol.hpp&amp;gt;&lt;/span&gt;

 &lt;span class=&quot;keyword&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LSymbol&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;ISOMORPHIC&lt;/span&gt;;
 &lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;LispInit_isomorphic&lt;/span&gt;();

 &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;LListConstructor&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;L&lt;/span&gt;;

 &lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;call_isomorph&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SReference&lt;/span&gt; &amp;amp;&lt;span class=&quot;variable-name&quot;&gt;l1&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;SReference&lt;/span&gt; &amp;amp;&lt;span class=&quot;variable-name&quot;&gt;l2&lt;/span&gt;)
 {
     &lt;span class=&quot;type&quot;&gt;SReference&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;res&lt;/span&gt; = (L|ISOMORPHIC, ~l1, ~l2).Evaluate();
     printf(&lt;span class=&quot;string&quot;&gt;&quot;%s ~~ %s : %s\n&quot;&lt;/span&gt;,
            l1-&amp;gt;TextRepresentation().c_str(),
            l2-&amp;gt;TextRepresentation().c_str(),
            res-&amp;gt;TextRepresentation().c_str());
 }

 &lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;main&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;argc&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;char&lt;/span&gt; *&lt;span class=&quot;variable-name&quot;&gt;argv&lt;/span&gt;[])
 {
     LispInit_isomorphic();
     &lt;span class=&quot;type&quot;&gt;SReference&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;ls1&lt;/span&gt; = (L|(L|1, 2), 3, 4);         &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;((1 2) 3 4)
&lt;/span&gt;     &lt;span class=&quot;type&quot;&gt;SReference&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;ls2&lt;/span&gt; = (L|(L|&lt;span class=&quot;string&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;b&quot;&lt;/span&gt;), &lt;span class=&quot;string&quot;&gt;&quot;c&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;d&quot;&lt;/span&gt;); &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;((&quot;a&quot; &quot;b&quot;) &quot;c&quot; &quot;d&quot;)
&lt;/span&gt;     &lt;span class=&quot;type&quot;&gt;SReference&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;ls3&lt;/span&gt; = (L|(L|1, 2), (L|3, 4));     &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;((1 2) (3 4))
&lt;/span&gt;     call_isomorph(ls1, ls2);
     call_isomorph(ls1, ls3);
     &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; 0;
 }
 &lt;span class=&quot;comment-delimiter&quot;&gt;// &lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;end of file
&lt;/span&gt;&lt;/pre&gt;


Compiled with:

&lt;pre&gt;

 g++ -Wall -g isomorph.cpp main.cpp -lintelib -o isomorph &amp;&amp; ./isomorph

&lt;/pre&gt;


will produce:

&lt;pre&gt;

 ((1 2) 3 4) ~~ ((&lt;span class=&quot;string&quot;&gt;&quot;a&quot;&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;b&quot;&lt;/span&gt;) &lt;span class=&quot;string&quot;&gt;&quot;c&quot;&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;d&quot;&lt;/span&gt;) : T
 ((1 2) 3 4) ~~ ((1 2) (3 4)) : NIL

&lt;/pre&gt;







&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;&lt;a name=&quot;boehmgc&quot;&gt;
&lt;h2&gt;Garbage Collection: BoehmGC&lt;/h2&gt;


&lt;p&gt;&lt;a href=&quot;http://www.hpl.hp.com/personal/Hans_Boehm/gc/&quot;&gt;BoehmGC&lt;/a&gt;
is probably the most under-used piece of software worldwide.  It
should be included in any application written in C or C++.

&lt;/p&gt;
&lt;/a&gt;&lt;/br&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/a&gt;&lt;/br&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/a&gt;&lt;/br&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/a&gt;&lt;/br&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/a&gt;&lt;/br&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/articles/life-saver.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/articles/cl-types/index.html</id><published>2010-10-10T10:10:10+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">Graphs of Common Lisp Types</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/graph.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/articles/cl-types/index.html&quot;&gt;Graphs of Common Lisp Types&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Generate the graph of the Common Lisp type hierarchy in the implementation.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;cl-types&quot;&gt;

&lt;h1&gt;Graphs of Common Lisp Types&lt;/h1&gt;


&lt;p&gt;A newbie asked about the types defined in Common Lisp. There was a
nice graph of Common Lisp types published some times, but despite my
google-foo, I couldn&#039;t find it again.  It&#039;s not the first time.  So I
decided to write a little quick &amp;amp; dirty program to build those
graphs by introspecting the Common Lisp implementation.&lt;/p&gt;


&lt;p&gt;Notice that the graph of type hierarchy depends on the
implementation, because some type relationships are left to the
implementations to be defined (eg. the subtypes of FLOAT may all be
the same, or all distinct, or some combination as long as some order
on the significant bits they have).&lt;/p&gt;


&lt;p&gt;So here is the code of
&lt;a href=&quot;cl-types-graph.lisp&quot;&gt;cl-types-graph.lisp&lt;/a&gt; which gets all the
symbols exported from the COMMON-LISP package, and check their subtype
relationships.&lt;/p&gt;


&lt;p&gt;In the case of some implementations such as Clozure or SBCL, any
symbol denotes a type, so is integrated to the graph, between the NIL
and T types.  This is not meaningful, so we remove them.&lt;/p&gt;


&lt;p&gt;Equivalent type names are drawn in a single box labelled by a list
containing all the equivalent type names.&lt;/p&gt;


&lt;p&gt;Finally, notice that we only consider here the types denoted by a
single symbol.   The
&lt;a href=&quot;http://www.lispworks.com/documentation/HyperSpec/Front/index.htm&quot;&gt;
Common Lisp standard&lt;/a&gt; actually defines families of types denoted by sexps,
such as &lt;code&gt;(vector 42 single-float)&lt;/code&gt;.

&lt;p&gt;The graph thus obtained is written as a &lt;a href=&quot;http://www.graphviz.org/&quot;&gt;Graphviz&lt;/a&gt; &lt;code&gt;dot&lt;/code&gt; file and
graphviz &lt;code&gt;tred&lt;/code&gt; and &lt;code&gt;dot&lt;/code&gt; are used to generate
the graph image. For example: &lt;/p&gt;


&lt;pre&gt;
    clall &#039;(load &quot;cl-types-graph.lisp&quot;)&#039;
    for f in cl-types-in-*.dot ; do
       tred &amp;lt; $f |dot -Tps /dev/stdin &amp;gt; ${f/.dot/.ps}
    done
    for f in  cl-types-in-*.ps ; do
       gsview $f &amp;amp;
    done
&lt;/pre&gt;


&lt;p&gt;&lt;code&gt;clall&lt;/code&gt; can be get from &lt;a href=&quot;http://tinyurl.com/2urswh9&quot;&gt;here&lt;/a&gt; in &lt;a href=&quot;http://git.informatimago.com/viewgit/index.php?a=summary&amp;p=public/bin&quot;&gt;http://git.informatimago.com/viewgit/index.php?a=summary&amp;amp;p=public/bin&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;Finally, you can get the generated graphs to compare the type
hierarchy of these various implementations:&lt;/p&gt;


&lt;table&gt;


&lt;tr&gt;
&lt;th&gt;clisp 2.48&lt;/th&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-clisp.dot&quot;&gt;cl-types-in-clisp.dot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-clisp.ps&quot;&gt;cl-types-in-clisp.ps&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
&lt;th&gt;Clozure Common Lisp 1.5&lt;/th&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-clozure-common-lisp.dot&quot;&gt;cl-types-in-clozure-common-lisp.dot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-clozure-common-lisp.ps&quot;&gt;cl-types-in-clozure-common-lisp.ps&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
&lt;th&gt;ecl 9.12.3&lt;/th&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-ecl.dot&quot;&gt;cl-types-in-ecl.dot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-ecl.ps&quot;&gt;cl-types-in-ecl.ps&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
&lt;th&gt;SBCL 1.0.19-gentoo&lt;/th&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-sbcl.dot&quot;&gt;cl-types-in-sbcl.dot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;cl-types-in-sbcl.ps&quot;&gt;cl-types-in-sbcl.ps&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;


&lt;/table&gt;


&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/articles/cl-types/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sedit/index.html</id><published>2010-09-08T12:00:00+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">A Simple Sexp Structure Editor</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/sedit.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sedit/index.html&quot;&gt;A Simple Sexp Structure Editor&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A simple sexp structure editor to demonstrate how we can edit lisp sources directly.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Common Lisp, Lisp, Sexp, Editor, Structure Editor&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;sedit&quot;&gt;


&lt;h1&gt;A Simple Sexp Structure Editor&lt;/h1&gt;




&lt;p&gt;This is a simple sexp structure editor to demonstrate how we can
     edit lisp sources directly instead of going thru the
     deserialization and serialization (converting the sexps into a
     textual representation and using a text editor such as emacs).
&lt;p&gt;


&lt;p&gt;This editor manipulates directly the sexp data structure.&lt;/p&gt;




&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;sedit.lisp&quot;&gt;sedit.lisp&lt;/a&gt;&lt;/li&gt;



&lt;/ul&gt;





&lt;p&gt;It is invoked as (sedit sexp), and returns the modified sexp.
     (The sexp is modified destructively).&lt;/p&gt;



&lt;pre class=&quot;command&quot;&gt;
 (sedit (copy-tree &#039;(an example)))
  &lt;/pre&gt;



&lt;p&gt;At each interaction loop, it prints the whole sexp, showing the selected
    sub-sexp, and query a command. The list of commands are:&lt;/p&gt;



&lt;ul&gt;



&lt;li&gt;&lt;tt&gt; q quit               &lt;/tt&gt; to return the modified sexp from sedit.

&lt;li&gt;&lt;tt&gt; i in                 &lt;/tt&gt; to enter inside the selected list.

&lt;li&gt;&lt;tt&gt; o out                &lt;/tt&gt; to select the list containing the selection.

&lt;li&gt;&lt;tt&gt; f forward n next     &lt;/tt&gt; to select the sexp following the selection (or out).

&lt;li&gt;&lt;tt&gt; b backward p previous&lt;/tt&gt; to select the sexp preceding the selection (or out).

&lt;li&gt;&lt;tt&gt; s insert             &lt;/tt&gt; to insert a new sexp before the selection.

&lt;li&gt;&lt;tt&gt; r replace            &lt;/tt&gt; to replace the selection with a new sexp.

&lt;li&gt;&lt;tt&gt; a add                &lt;/tt&gt; to add a new sexp after the selection.

&lt;li&gt;&lt;tt&gt; x cut                &lt;/tt&gt; to cut the selection into a *clipboard*.

&lt;li&gt;&lt;tt&gt; c copy               &lt;/tt&gt; to copy the selection into a *clipboard*.

&lt;li&gt;&lt;tt&gt; y paste              &lt;/tt&gt; to paste the *clipboard* replacing the selection.
  &lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;



  Example:

&lt;pre class=&quot;dribble&quot;&gt;

C/IBCL-USER[4]&amp;gt; (sedit &#039;())

Sexp Editor:
【NIL】
&amp;gt; r
replacement sexp: (let ((*package #.*package*)) (print &#039;hello))
【(LET ((*PACKAGE #&amp;lt;PACKAGE IMAGE-BASED-COMMON-LISP-USER&amp;gt;)) (PRINT (QUOTE HELLO)))】
&amp;gt; i
(【LET】 ((*PACKAGE #&amp;lt;PACKAGE IMAGE-BASED-COMMON-LISP-USER&amp;gt;)) (PRINT (QUOTE HELLO)))
&amp;gt; n
(LET 【((*PACKAGE #&amp;lt;PACKAGE IMAGE-BASED-COMMON-LISP-USER&amp;gt;))】 (PRINT (QUOTE HELLO)))
&amp;gt; i
(LET (【(*PACKAGE #&amp;lt;PACKAGE IMAGE-BASED-COMMON-LISP-USER&amp;gt;)】) (PRINT (QUOTE HELLO)))
&amp;gt; i
(LET ((【*PACKAGE】 #&amp;lt;PACKAGE IMAGE-BASED-COMMON-LISP-USER&amp;gt;)) (PRINT (QUOTE HELLO)))
&amp;gt; r
replacement sexp: *package*
(LET ((【*PACKAGE*】 #&amp;lt;PACKAGE IMAGE-BASED-COMMON-LISP-USER&amp;gt;)) (PRINT (QUOTE HELLO)))
&amp;gt; q
(LET ((*PACKAGE* #&amp;lt;PACKAGE IMAGE-BASED-COMMON-LISP-USER&amp;gt;)) (PRINT &#039;HELLO))
C/IBCL-USER[5]&amp;gt; (eval *)

HELLO
HELLO
C/IBCL-USER[6]&amp;gt;

  &lt;/pre&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/sedit/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/rpsls/index.html</id><published>2010-07-17T12:00:00+0100</published><updated>2015-10-26T00:27:49+0100</updated><title type="text">Rock, Paper, Scissors, Gun, Dynamite, Nuke, Lightning, Devil, Dragon, Alien, Water, Bowl, Air, Moon, Sponge, Wolf, Cockroach, Tree, Man, Woman, Monkey, Snake, Axe, Fire, Sun</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/rps.png&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/rpsls/index.html&quot;&gt;Rock, Paper, Scissors, Gun, Dynamite, Nuke, Lightning, Devil, Dragon, Alien, Water, Bowl, Air, Moon, Sponge, Wolf, Cockroach, Tree, Man, Woman, Monkey, Snake, Axe, Fire, Sun&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A little program implementing Rock, Paper, Scissor style games.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Common Lisp, Lisp, game, Rock, Paper, Scissors, Gun, Dynamite, Nuke, Lightning, Devil, Dragon, Alien, Water, Bowl, Air, Moon, Sponge, Wolf, Cockroach, Tree, Man, Woman, Monkey, Snake, Axe, Fire, Sun, Lisard, Lizard, Spock&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;rpsls&quot;&gt;


&lt;h1&gt;Rock, Paper, Scissors, Gun, Dynamite, Nuke, Lightning, Devil, Dragon, Alien, Water, Bowl, Air, Moon, Sponge, Wolf, Cockroach, Tree, Man, Woman, Monkey, Snake, Axe, Fire, Sun&lt;/h1&gt;




&lt;p&gt;This little program implements Rock, Paper, Scissor style games.&lt;/p&gt;



&lt;p&gt;Graphs are defined for:&lt;/p&gt;



&lt;ul&gt;



&lt;li&gt;Rock, Paper, Scissor;&lt;/li&gt;



&lt;li&gt;Rock, Paper, Scissor, Lizard, Spock; and&lt;/li&gt;



&lt;li&gt;Rock, Paper, Scissors, Gun, Dynamite, Nuke, Lightning, Devil, Dragon, Alien, Water, Bowl, Air, Moon, Sponge, Wolf, Cockroach, Tree, Man, Woman, Monkey, Snake, Axe, Fire, Sun. (see the &lt;a href=&quot;rpsls-25.jpg&quot;&gt;table&lt;/a&gt;)&lt;/li&gt;



&lt;/ul&gt;




&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;rpsls.lisp&quot;&gt;rpsls.lisp&lt;/a&gt;&lt;/li&gt;



&lt;/ul&gt;




&lt;p&gt;Example:&lt;/p&gt;



&lt;pre class=&quot;dribble&quot;&gt;
CL-USER&amp;gt; (RPSLS:main RPSLS::*rock-paper-scissors-gun-dynamite-nuke-lightning-devil-dragon-alien-water-bowl-air-moon-sponge-wolf-cockroach-tree-man-woman-monkey-snake-axe-fire-sun*)
Please choose an item amongst:
  quit air alien axe bowl cockroach devil dragon dynamite fire gun lightning man monkey moon nuke paper rock scissors snake sponge sun tree water wolf woman
&amp;gt; air
You chose AIR.
Computer chose MAN.
Man breathes air.
Therefore you lose.

Please choose an item amongst:
  quit air alien axe bowl cockroach devil dragon dynamite fire gun lightning man monkey moon nuke paper rock scissors snake sponge sun tree water wolf woman
&amp;gt; man
You chose MAN.
Computer chose MOON.
Man travels to moon.
Therefore you win.

Please choose an item amongst:
  quit air alien axe bowl cockroach devil dragon dynamite fire gun lightning man monkey moon nuke paper rock scissors snake sponge sun tree water wolf woman
&amp;gt; moon
You chose MOON.
Computer chose WATER.
Moon has no water.
Therefore you win.

Please choose an item amongst:
  quit air alien axe bowl cockroach devil dragon dynamite fire gun lightning man monkey moon nuke paper rock scissors snake sponge sun tree water wolf woman
&amp;gt; water
You chose WATER.
Computer chose WOLF.
Wolf drinks water.
Therefore you lose.

Please choose an item amongst:
  quit air alien axe bowl cockroach devil dragon dynamite fire gun lightning man monkey moon nuke paper rock scissors snake sponge sun tree water wolf woman
&amp;gt; wolf
You chose WOLF.
Computer chose FIRE.
Fire burns wolf.
Therefore you lose.

Please choose an item amongst:
  quit air alien axe bowl cockroach devil dragon dynamite fire gun lightning man monkey moon nuke paper rock scissors snake sponge sun tree water wolf woman
&amp;gt; quit
You      won 2 of 6 games.
Computer won 3 of 6 games.
2
3
1
6
CL-USER&amp;gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/rpsls/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/playtomo-stonedge/index.html</id><published>2010-07-09T12:00:00+0100</published><updated>2015-10-26T00:27:50+0100</updated><title type="text">Playtomo Stonedge Game</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/stoneedge.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/playtomo-stonedge/index.html&quot;&gt;Playtomo Stonedge Game&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;An implementation of the Playtomo Stonedge Game, and its solver.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Common Lisp, Lisp, game, playtomo, stonedge, solver&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;playtomo-stonedge&quot;&gt;


&lt;h1&gt;An implementation of the Playtomo Stonedge game, with its solver&lt;/h1&gt;




&lt;p&gt;This is an implementation of the Playtomo Stonedge Game, and its
     solver.
     See &lt;a href=&quot;http://www.playtomo.com/&quot;&gt;http://www.playtomo.com/&lt;/a&gt;
     (not much here when I went); Download the playtomo games on
     BlackBerry.



&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;playtomo-stonedge.lisp&quot;&gt;playtomo-stonedge.lisp&lt;/a&gt;&lt;/li&gt;



&lt;/ul&gt;


  &lt;/p&gt;




&lt;p&gt;Playtomo&#039;s implementation is nicer (graphical), but here, we
     provide a solver that will find all the solutions to a given
     level. &lt;strong&gt;Even nicer!&lt;/strong&gt;&lt;/p&gt;




&lt;pre class=&quot;text&quot;&gt;
                  +---+
block             |BBB|
                  +---+
empty cell        |   |
                  +---+
solid cell        |SSS|
                  +---+
red button cell   |[R]|
                  +---+
blue button cell  |[B]|
                  +---+
ice cell          |,,,|
                  +---+
target cell       |TTT|
                  +---+
closed door       | / |
                  +---+
open door         |---|
                  +---+
&lt;/pre&gt;





&lt;p&gt;To move the block, use:&lt;/p&gt;



&lt;pre class=&quot;text&quot;&gt;
      8           i
    4   6   or  j   l
      2           k
  &lt;/pre&gt;





&lt;p&gt;Example:&lt;/p&gt;



&lt;pre class=&quot;dribble&quot;&gt;
CL-USER&amp;gt; (stonedge *level-39*)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |CCC|[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   | / |SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 8
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |CCC|[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   | / |SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+BBB+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 8
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |CCC|[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|   |   |   |   |   | / |SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 8
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |CCC|[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|BBB|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+BBB+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   | / |SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 8
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|BBB|---|[R]| / |CCC|[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   | / |SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]|BBBBBBB|---|CCC|[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   | / |SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]|---|[R]|BBB|CCC|[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   | / |SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]|---|[R]|---|BBBBBBB|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]|---|[R]|BBB|   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]|BBBBBBB| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|BBB| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |BBBBBBB|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |BBBBBBB|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|BBB|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+BBB+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+BBB+---+---+---+---+---+---+---+---+---+
|   |   |   |   |BBB|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|BBB|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+BBB+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|BBB|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |BBB|CCC|SSS|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|BBBBBBB|CCC|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|   |SSS|BBB|SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |CCC|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|   |SSS|   |BBBBBBB|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 8
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |BBBBBBB|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|   |SSS|   |SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 8
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |BBBBBBB|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|   |SSS|   |SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|BBB|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|   |SSS|   |SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 8
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |---|BBB|   |   |
+---+---+---+---+---+---+---+---+---+---+---+BBB+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|BBB|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|   |SSS|   |SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|[B]| / |[R]| / |   |[R]|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |,,,|,,,|SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |BBB|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+BBB+---+---+---+
|   |   |   |   |SSS|   |   |   |   |   |BBB|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |,,,|SSS|   |   |   |SSS|TTT|SSS|   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |SSS|SSS|   |   |   |   |SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |SSS|   |SSS|   |SSS|SSS|   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Your move: 2

You win!

; No value
CL-USER&amp;gt; (solve-problem *level-39*)

(NUMBER OF STATES = 990)
((:WIN 10 5 10 5 :CLOSED :CLOSED :CLOSED :CLOSED :CLOSED :CLOSED :OPEN)
 (:FRONT :FRONT :FRONT :FRONT :RIGHT :RIGHT :RIGHT :LEFT :LEFT :LEFT :LEFT
  :BACK :RIGHT :BACK :BACK :BACK :RIGHT :BACK :RIGHT :RIGHT :RIGHT :FRONT
  :FRONT :RIGHT :FRONT :LEFT :BACK))
((:WIN 10 5 10 5 :OPEN :CLOSED :CLOSED :CLOSED :CLOSED :CLOSED :OPEN)
 (:FRONT :FRONT :FRONT :FRONT :RIGHT :RIGHT :RIGHT :LEFT :LEFT :LEFT :LEFT
  :RIGHT :LEFT :BACK :RIGHT :BACK :BACK :BACK :RIGHT :BACK :RIGHT :RIGHT :RIGHT
  :FRONT :FRONT :RIGHT :FRONT :LEFT :BACK))
((:WIN 10 5 10 5 :CLOSED :CLOSED :OPEN :CLOSED :CLOSED :CLOSED :OPEN)
 (:FRONT :FRONT :FRONT :FRONT :RIGHT :RIGHT :RIGHT :LEFT :LEFT :LEFT :LEFT
  :RIGHT :RIGHT :LEFT :LEFT :BACK :RIGHT :BACK :BACK :BACK :RIGHT :BACK :RIGHT
  :RIGHT :RIGHT :FRONT :FRONT :RIGHT :FRONT :LEFT :BACK))
((:WIN 10 5 10 5 :OPEN :CLOSED :OPEN :CLOSED :CLOSED :CLOSED :OPEN)
 (:FRONT :FRONT :FRONT :FRONT :RIGHT :RIGHT :RIGHT :LEFT :LEFT :LEFT :LEFT
  :RIGHT :RIGHT :LEFT :LEFT :RIGHT :LEFT :BACK :RIGHT :BACK :BACK :BACK :RIGHT
  :BACK :RIGHT :RIGHT :RIGHT :FRONT :FRONT :RIGHT :FRONT :LEFT :BACK))
Real time: 0.288899 sec.
Run time: 0.288956 sec.
Space: 6520144 Bytes
GC: 1, GC time: 0.009999 sec.
NIL
CL-USER&amp;gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/playtomo-stonedge/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/articles/ffn=-n/index.html</id><published>2008-03-09T11:00:00+0100</published><updated>2015-10-26T00:27:50+0100</updated><title type="text">f(f(n)) = -n</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/ffn=-n.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/articles/ffn=-n/index.html&quot;&gt;f(f(n)) = -n&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A function f on 32-bit integers that, when applied twice, negates the integer. f(f(n)) = -n.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;ffn=-n&quot;&gt;
&lt;h1&gt;f(f(n)) = -n&lt;/h1&gt;


&lt;p&gt;In a comment to Steve Yegge&#039;s blog &lt;a href=&quot;http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.html&quot;&gt;
   http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.html&lt;/a&gt;,&lt;/p&gt;


&lt;blockquote&gt;



&lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://www.blogger.com/profile/13466586996802181998&quot;&gt;Vlad Patryshev&lt;/a&gt; said...&lt;/b&gt;&lt;/p&gt;



&lt;p&gt;Tactically, you are very right. Strategically... I don&#039;t know. You
       mix two things together, strict typing in general, abuse of UML and
       class hierarchy, and overuse of strict typing where it is not
       necessary (I mean JavaScript).&lt;/p&gt;



&lt;p&gt;Regarding class structures - it&#039;s probably hard to force people
       that love bureaucracy not to fill their code with Managers,
       Handlers, Helpers, and the like (none of these does any work, but
       they pass it around, like in real life). But I&#039;m afraid this
       anti-bureaucratic rant has nothing to do with the issue of modeling
       in general.&lt;/p&gt;



&lt;p&gt;I&#039;ll give you one example, an interview problem. Write a function f
       on 32-bit integers that, applied twice, it negates the
       integer. f(f(n)) = -n.&lt;/p&gt;



&lt;p&gt;Try to solve it without any kind of model, by just applying
       randomly ad-hoc xors and shifts.&lt;/p&gt;



&lt;p&gt;9:00 PM, February 11, 2008&lt;/p&gt;


&lt;/blockquote&gt;



&lt;p&gt;Assuming Vlad means integers represented in two-complement, which
   is the case with 99% of the processors nowadays, such a function
   just doesn&#039;t exist. Here&#039;s the mathematical proof.&lt;/p&gt;


&lt;p&gt;First, in ℤ, such functions indeed exist. For example:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
    (defun integer/f (n)
      &quot;
    Assuming n is an INTEGER, (= (- n) (f (f n)))
         0 --&gt;  0
        +1 --&gt; -2 --&gt; -1 --&gt; +2 --&gt; +1
        +3 --&gt; -4 --&gt; -3 --&gt; +4 --&gt; +3
        ...
        +(2k+1) --&gt; -(2k+2) --&gt; -(2k+1) --&gt; +(2k+2) --&gt; +(2k+1)
    &quot;
      (declare (type integer n))
      (if (zerop n)
          0
          (if (plusp n)
              (if (oddp n)
                  (1- (- n))
                  (1- n))
              (if(oddp n)
                  (1+ (- n))
                  (1+ n)))))
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The same function works in one-complement representation, too
   (assuming &lt;code&gt;zerop&lt;/code&gt; indicates both +0 and -0).&lt;/p&gt;




&lt;p&gt;But things are different in ℤ/&lt;sub&gt;m&lt;/sub&gt;, because of the special
   properties of the negation in these sets.&lt;/p&gt;


&lt;p&gt;When m=2&lt;sup&gt;p&lt;/sup&gt; with p&gt;2:&lt;/p&gt;
&lt;p&gt;Let i be the identity function:  ∀ a ∈ ℤ/&lt;sub&gt;m&lt;/sub&gt;, i(a)=a
&lt;p&gt;Let n be the negation function in two-complement on
   ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;. n is defined as: n(x) = 1+(¬x), with ¬x
   being the bitwise not operation.&lt;/p&gt;
&lt;p&gt;Here are some properties of n:
&lt;ol&gt;
&lt;li&gt;n(0)=0
&lt;li&gt;let M = -2&lt;sup&gt;p-1&lt;/sup&gt;.  In two-complement arithmetic, n(M)=M.
&lt;li&gt;∀ a ∈ ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;∖{0, M}, n(a)≠a
&lt;li&gt;∀ a ∈ ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;, n(n(a))=a ; n&lt;sup&gt;2&lt;/sup&gt; = i
&lt;li&gt;∀ (a,b) ∈ ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt;,
    n(a)=n(b) ⇒ a=b (trivially deduced from 4.)
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;


&lt;p&gt;Properties 3 and 4 allow partitionning
ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;∖{0, M} in two symetrical subsets, one
representing the positive integers, and the other their opposite
negative integers.&lt;/p&gt;


&lt;br&gt;
&lt;br&gt;
&lt;p&gt;Now, assume there is a function f such as ∃ x ∈ ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;,  f(f(x))=n(x).&lt;/p&gt;
&lt;p&gt;Let&#039;s denote the composition of functions by mere juxtaposition: fg = f○g.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;f&lt;sup&gt;0&lt;/sup&gt; = i
&lt;li&gt;f&lt;sup&gt;2&lt;/sup&gt; = n
&lt;li&gt;f&lt;sup&gt;3&lt;/sup&gt; = nf&lt;sup&gt;1&lt;/sup&gt; = f&lt;sup&gt;1&lt;/sup&gt;n
&lt;li&gt;f&lt;sup&gt;1&lt;/sup&gt; = nf&lt;sup&gt;3&lt;/sup&gt; = f&lt;sup&gt;3&lt;/sup&gt;n = f
&lt;li&gt;f&lt;sup&gt;4&lt;/sup&gt; = n&lt;sup&gt;2&lt;/sup&gt; = i
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;

and so on, ∀ k ∈ ℕ, f&lt;sup&gt;4k&lt;/sup&gt;=i, f&lt;sup&gt;4k+1&lt;/sup&gt;=f, f&lt;sup&gt;4k+2&lt;/sup&gt;=n, f&lt;sup&gt;4k+3&lt;/sup&gt;=nf.

&lt;p&gt;Let C be the function from ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt; to
2&lt;sup&gt;ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;&lt;/sup&gt; such as:
C(x) = { f&lt;sup&gt;0&lt;/sup&gt;(x), f&lt;sup&gt;1&lt;/sup&gt;(x),
         f&lt;sup&gt;2&lt;/sup&gt;(x), f&lt;sup&gt;3&lt;/sup&gt;(x) }&lt;/p&gt;


&lt;p&gt;Now, let (a,b) ∈ ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt;, such as
   a ∉ {0, M}, f&lt;sup&gt;2&lt;/sup&gt;(a)=n(a) and b ∉ C(a) [H]&lt;/p&gt;


&lt;p&gt;Since a ∉ {0, M} and f&lt;sup&gt;2&lt;/sup&gt;(a)=n(a), | C(a) | = 4.&lt;/p&gt;
&lt;p&gt;And:
&lt;ul&gt;
&lt;li&gt;b = f&lt;sup&gt;0&lt;/sup&gt;(b) ≠ a, by hypothesis [H].
&lt;li&gt;f&lt;sup&gt;1&lt;/sup&gt;(b) ≠ a, since by hypothesis [H], b ≠ f&lt;sup&gt;3&lt;/sup&gt;(a).
&lt;li&gt;f&lt;sup&gt;2&lt;/sup&gt;(b) ≠ a, since by hypothesis [H], b ≠ f&lt;sup&gt;2&lt;/sup&gt;(a).
&lt;li&gt;f&lt;sup&gt;3&lt;/sup&gt;(b) ≠ a, since by hypothesis [H], b ≠ f&lt;sup&gt;1&lt;/sup&gt;(a).
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;in consequence, all the subsets C(x) are disjoint and form a partition of ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;.
&lt;/br&gt;
&lt;/p&gt;


&lt;p&gt;However, since C(0) = { 0, f&lt;sup&gt;1&lt;/sup&gt;(0) }, and C(M) = { M,
f&lt;sup&gt;1&lt;/sup&gt;(M) }, and ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt; is divisible by 4
when p&gt;2, there is at least two other elements of
ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;, let&#039;s call them N and O, such as C(O) = {
O, f&lt;sup&gt;1&lt;/sup&gt;(O) } and C(N) = { N, f&lt;sup&gt;1&lt;/sup&gt;(N) }. &lt;/p&gt;


&lt;p&gt;We have f&lt;sup&gt;2&lt;/sup&gt;(O) = O and f&lt;sup&gt;2&lt;/sup&gt;(N) = N, which shows
that ∃ x ∈ ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt;, f(f(x)) ≠ -x.

&lt;p&gt;&lt;em&gt;Conclusion&lt;/em&gt;: When p&gt;2, there is no function on
ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt; such as f&lt;sup&gt;2&lt;/sup&gt; = n.&lt;/p&gt;
  At most, we
can find functions such as f(f(x)) = -x for all elements x of
ℤ/&lt;sub&gt;2&lt;sup&gt;p&lt;/sup&gt;&lt;/sub&gt; but for two of our choosing.  Note that we
can choose to break the formula for 0 and M, since -0 is not very
interesting and -M in two-complement is pathologic anyways.&lt;/p&gt;


&lt;p&gt;(For other sets, ℤ/&lt;sub&gt;q&lt;/sub&gt; if q ≡ 1 [4] or  q ≡ 2 [4],
then there are functions such as f&lt;sup&gt;2&lt;/sup&gt;=n).&lt;/p&gt;



&lt;p&gt;Finally, we can implement a function that does almost what was
asked, only with a bug: we get to choose which two values for which
f(f(x)) ≠ -x.

&lt;p&gt;But of course, not using only XOR and SHIFT operations!  Using only
NAND and SHIFT, it would be possible (since NAND is all is needed to
build all the boolean operators, but XOR is not powerful enough to do
so, see Wikipedia articles on
&lt;a href=&quot;http://en.wikipedia.org/wiki/Logical_connective&quot;&gt;Logical connective&lt;/a&gt;
or on &lt;a href=&quot;http://en.wikipedia.org/wiki/Functional_completeness&quot;&gt;Functional completeness&lt;/a&gt;).
&lt;/p&gt;
&lt;blockquote&gt;
&lt;small&gt;

&lt;p&gt;Technically, we don&#039;t need full functional completeness for XOR
   (⊻), we&#039;d only need to be able to implement logical not and
   increment.  For logical not, there&#039;s no problem, a ⊻ 1 = ¬a, but
   for increment, we need to implement a semi-adder, where s = a ⊻ b
   and c = a ∧ b.  But there is no way to get AND from XOR, because
   XOR is closed over {0, 1, a, b, ¬a, ¬b, a⊻b, ¬(a⊻b)} (any
   application of XOR on two elements of this set gives an element of
   this set).&lt;/p&gt;


&lt;/small&gt;
&lt;/blockquote&gt;


&lt;p&gt;Since two-complement negation on binary words of length w is
defined as &lt;code&gt;(mod (1+ (lognot n)) (expt 2 w))&lt;/code&gt;, we need more
than just XOR and SHIFT...  Two impossibilities for one &lt;em&gt;interview
question&lt;/em&gt;.  Vicious!  And asking to do that &quot;without any kind of
model&quot;, tskss, tskss, I wouldn&#039;t like to work at such a company,
unless the question was designed exactly for that, to weed out people
doing what they&#039;re told without thinking...&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;
(declaim (ftype (function (integer) (unsigned-byte 32))
                32-bit
                32-bit/2-complement-neg))

(defun 32-bit (x)
  &quot;Mask off 32-bits of X&quot;
  (logand #xffffffff x))

(defun 32-bit/plusp (n)
  &quot;Whether N represents a positive integer.&quot;
  (declare (type (unsigned-byte 32) n))
  (zerop (ldb (byte 1 31) n)))

(defun 32-bit/2-complement-neg (n)
  &quot;Return the negation of N in 2-complement.&quot;
  (declare (type (unsigned-byte 32) n))
  (32-bit (1+ (lognot n))))

(defun 32-bit/f (n)
  &quot;
Assuming n is a 32-bit 2-complement signed integer different
from 0 and -2³¹,  (= (- n) (f (f n)))
&quot;
  (declare (type (unsigned-byte 32) n))
  (32-bit
   (case n                              ; (f (f n))
     ((#x00000000) #x80000001)          ; --&gt; 0x80000000
     ((#x80000000) #x7FFFFFFF)          ; --&gt; 0x00000000
     ((#x7FFFFFFF) #x00000000)          ; --&gt; 0x80000001
     ((#x80000001) #x80000000)          ; --&gt; 0x7fffffff
     ;;  For the above exceptions, any permutation is valid;
     ;;  we choose here to break it for 0 and M, with
     ;;  f(f(0))=M and f(f(M))=0,
     ;;  to keep f(f(2³¹-1))= -(2³¹-1) and f(f(-(2³¹-1)))= 2³¹-1
     (otherwise
      (if (32-bit/plusp n)
          (if (oddp n)
              (lognot n)
              (1- n))
          (if (oddp n)
              (+ (lognot n) 2)
              (1+ n)))))))

&lt;/code&gt;&lt;/pre&gt;


&lt;hr&gt;

&lt;pre&gt;&lt;code&gt;

C/USER[83]&gt; (load&quot;&lt;a href=&quot;ffn=-n.lisp&quot;&gt;ffn=-n.lisp&lt;/a&gt;&quot;)
;; Loading file ffn=-n.lisp ...
;; Loaded file ffn=-n.lisp
T
C/USER[84]&gt; (test-f)


           i           -i    (f (f i))        (f i) (- (f (f i)))
    00000000     00000000 /=  80000000    80000001     80000000
    00000001     FFFFFFFF     FFFFFFFF    FFFFFFFE     00000001
    00000002     FFFFFFFE     FFFFFFFE    00000001     00000002
    00000003     FFFFFFFD     FFFFFFFD    FFFFFFFC     00000003
    00000004     FFFFFFFC     FFFFFFFC    00000003     00000004
    00000005     FFFFFFFB     FFFFFFFB    FFFFFFFA     00000005
    00000006     FFFFFFFA     FFFFFFFA    00000005     00000006
    00000007     FFFFFFF9     FFFFFFF9    FFFFFFF8     00000007
    00000008     FFFFFFF8     FFFFFFF8    00000007     00000008
    00000009     FFFFFFF7     FFFFFFF7    FFFFFFF6     00000009
    0000000A     FFFFFFF6     FFFFFFF6    00000009     0000000A
    0000000B     FFFFFFF5     FFFFFFF5    FFFFFFF4     0000000B
    0000000C     FFFFFFF4     FFFFFFF4    0000000B     0000000C
    0000000D     FFFFFFF3     FFFFFFF3    FFFFFFF2     0000000D
    0000000E     FFFFFFF2     FFFFFFF2    0000000D     0000000E
    0000000F     FFFFFFF1     FFFFFFF1    FFFFFFF0     0000000F
    00000010     FFFFFFF0     FFFFFFF0    0000000F     00000010
    00000011     FFFFFFEF     FFFFFFEF    FFFFFFEE     00000011
    00000012     FFFFFFEE     FFFFFFEE    00000011     00000012
    00000013     FFFFFFED     FFFFFFED    FFFFFFEC     00000013
    FFFFFFFF     00000001     00000001    00000002     FFFFFFFF
    FFFFFFFE     00000002     00000002    FFFFFFFF     FFFFFFFE
    FFFFFFFD     00000003     00000003    00000004     FFFFFFFD
    FFFFFFFC     00000004     00000004    FFFFFFFD     FFFFFFFC
    FFFFFFFB     00000005     00000005    00000006     FFFFFFFB
    FFFFFFFA     00000006     00000006    FFFFFFFB     FFFFFFFA
    FFFFFFF9     00000007     00000007    00000008     FFFFFFF9
    FFFFFFF8     00000008     00000008    FFFFFFF9     FFFFFFF8
    FFFFFFF7     00000009     00000009    0000000A     FFFFFFF7
    FFFFFFF6     0000000A     0000000A    FFFFFFF7     FFFFFFF6
    FFFFFFF5     0000000B     0000000B    0000000C     FFFFFFF5
    FFFFFFF4     0000000C     0000000C    FFFFFFF5     FFFFFFF4
    FFFFFFF3     0000000D     0000000D    0000000E     FFFFFFF3
    FFFFFFF2     0000000E     0000000E    FFFFFFF3     FFFFFFF2
    FFFFFFF1     0000000F     0000000F    00000010     FFFFFFF1
    FFFFFFF0     00000010     00000010    FFFFFFF1     FFFFFFF0
    FFFFFFEF     00000011     00000011    00000012     FFFFFFEF
    FFFFFFEE     00000012     00000012    FFFFFFEF     FFFFFFEE
    FFFFFFED     00000013     00000013    00000014     FFFFFFED
    FFFFFFEC     00000014     00000014    FFFFFFED     FFFFFFEC
    7FFFFFEC     80000014     80000014    7FFFFFEB     7FFFFFEC
    7FFFFFED     80000013     80000013    80000012     7FFFFFED
    7FFFFFEE     80000012     80000012    7FFFFFED     7FFFFFEE
    7FFFFFEF     80000011     80000011    80000010     7FFFFFEF
    7FFFFFF0     80000010     80000010    7FFFFFEF     7FFFFFF0
    7FFFFFF1     8000000F     8000000F    8000000E     7FFFFFF1
    7FFFFFF2     8000000E     8000000E    7FFFFFF1     7FFFFFF2
    7FFFFFF3     8000000D     8000000D    8000000C     7FFFFFF3
    7FFFFFF4     8000000C     8000000C    7FFFFFF3     7FFFFFF4
    7FFFFFF5     8000000B     8000000B    8000000A     7FFFFFF5
    7FFFFFF6     8000000A     8000000A    7FFFFFF5     7FFFFFF6
    7FFFFFF7     80000009     80000009    80000008     7FFFFFF7
    7FFFFFF8     80000008     80000008    7FFFFFF7     7FFFFFF8
    7FFFFFF9     80000007     80000007    80000006     7FFFFFF9
    7FFFFFFA     80000006     80000006    7FFFFFF9     7FFFFFFA
    7FFFFFFB     80000005     80000005    80000004     7FFFFFFB
    7FFFFFFC     80000004     80000004    7FFFFFFB     7FFFFFFC
    7FFFFFFD     80000003     80000003    80000002     7FFFFFFD
    7FFFFFFE     80000002     80000002    7FFFFFFD     7FFFFFFE
    7FFFFFFF     80000001     80000001    00000000     7FFFFFFF
    80000013     7FFFFFED     7FFFFFED    7FFFFFEE     80000013
    80000012     7FFFFFEE     7FFFFFEE    80000013     80000012
    80000011     7FFFFFEF     7FFFFFEF    7FFFFFF0     80000011
    80000010     7FFFFFF0     7FFFFFF0    80000011     80000010
    8000000F     7FFFFFF1     7FFFFFF1    7FFFFFF2     8000000F
    8000000E     7FFFFFF2     7FFFFFF2    8000000F     8000000E
    8000000D     7FFFFFF3     7FFFFFF3    7FFFFFF4     8000000D
    8000000C     7FFFFFF4     7FFFFFF4    8000000D     8000000C
    8000000B     7FFFFFF5     7FFFFFF5    7FFFFFF6     8000000B
    8000000A     7FFFFFF6     7FFFFFF6    8000000B     8000000A
    80000009     7FFFFFF7     7FFFFFF7    7FFFFFF8     80000009
    80000008     7FFFFFF8     7FFFFFF8    80000009     80000008
    80000007     7FFFFFF9     7FFFFFF9    7FFFFFFA     80000007
    80000006     7FFFFFFA     7FFFFFFA    80000007     80000006
    80000005     7FFFFFFB     7FFFFFFB    7FFFFFFC     80000005
    80000004     7FFFFFFC     7FFFFFFC    80000005     80000004
    80000003     7FFFFFFD     7FFFFFFD    7FFFFFFE     80000003
    80000002     7FFFFFFE     7FFFFFFE    80000003     80000002
    80000001     7FFFFFFF     7FFFFFFF    80000000     80000001
    80000000     80000000 /=  00000000    7FFFFFFF     00000000
NIL
C/USER[85]&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/hr&gt;
&lt;/p&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/articles/ffn=-n/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/m-expression/index.html</id><published>2006-09-28T12:00:00+0100</published><updated>2015-10-26T00:27:50+0100</updated><title type="text">A Parser for M-Expressions</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/m-expr-mccarthy.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/m-expression/index.html&quot;&gt;A Parser for M-Expressions&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Here is a parser for Lisp M-Expressions as documented
    in the Memo 8, AIM-8.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;LISP, Common Lisp, M-Expressions&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;m-expression&quot;&gt;


&lt;h1&gt;A Parser for M-Expressions&lt;/h1&gt;



&lt;p&gt;Here is a parser for Lisp M-Expressions as documented in the
    &lt;a href=&quot;../aim-8/index.html&quot;&gt;Memo 8, AIM-8&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;
    A lot of lisp newbies ask for more conventionnal syntax for lisp.
    Since day one, lisp was intended to have such a syntax: M-expressions.
  &lt;/p&gt;



&lt;p&gt;
    Let&#039;s newbies play with them, and realize how impractical they are.
    Note for example, that we cannot use macros anymore because
    their syntax would need to be known by the M-expression parser,
    like it&#039;s the case for &lt;tt&gt;lambda[[...];...]&lt;/tt&gt;.
    Macros were added later in lisp history.
  &lt;/p&gt;



&lt;p&gt;
    Note that S-expressions can still be entered, as literal objects,
    but using comma instead of space to separate the items in lists.
  &lt;/p&gt;



&lt;p&gt;The file &lt;a href=&quot;m-expression.lisp&quot;&gt;m-expression.lisp&lt;/a&gt;
    contains the M-expression parser and a REPL, in Common-Lisp.&lt;/p&gt;




&lt;h2&gt;Exemple&lt;/h2&gt;




&lt;pre class=&quot;dribble&quot;&gt;
% &lt;b&gt;/usr/local/bin/clisp -q -norc -ansi &lt;/b&gt;

[1]&amp;gt; &lt;b&gt;(load&quot;m-expression.lisp&quot; :external-format #+clisp charset:utf-8 #+sbcl :utf-8)&lt;/b&gt;
;; Loading file m-expression.lisp ...
;; Loaded file m-expression.lisp
T
[2]&amp;gt; &lt;b&gt;(m-repl)&lt;/b&gt;

;; We are going to define a function that is exported by COMMON-LISP,
;; so let&#039;s shadow it first:

COMMON-LISP-USER[1]M-REPL&amp;gt; &lt;b&gt;shadow[SUBST];&lt;/b&gt;
 --&amp;gt; T

COMMON-LISP-USER[2]M-REPL&amp;gt; &lt;b&gt;label[subst;λ[[x;y;s];[null[s]-&amp;gt;nil;atom[s]⟶
           [y=s-&amp;gt;x;1-&amp;gt;s];1-&amp;gt;combine[subst[x;y;first[s]];
                subst[x;y;rest[s]]]]]];&lt;/b&gt;
 --&amp;gt; SUBST

;; S-expressions embedded in M-expressions must use comma as separator:
COMMON-LISP-USER[3]M-REPL&amp;gt; &lt;b&gt;subst[WATER;WINE;(MIX WATER AND WINE
                                  INTO (MIXED WATER AND WINE))];&lt;/b&gt;
SIMPLE-ERROR:
Unexpected S-CLOSE, not (:S-SYMBOL WATER)
 at &quot; AND WINE&quot;

COMMON-LISP-USER[4]M-REPL&amp;gt; SIMPLE-ERROR:
Please terminate your m-expressions with a semi-colon, not (:S-OPEN)

COMMON-LISP-USER[5]M-REPL&amp;gt;
SIMPLE-ERROR:
Please terminate your m-expressions with a semi-colon, not (:S-SYMBOL WATER)

COMMON-LISP-USER[6]M-REPL&amp;gt;
SIMPLE-ERROR:
Please terminate your m-expressions with a semi-colon, not (:S-SYMBOL WINE)

COMMON-LISP-USER[7]M-REPL&amp;gt;
SIMPLE-ERROR:
Unexpected token in m-term: (:S-CLOSE)
 at &amp;quot;)];&amp;quot;

COMMON-LISP-USER[8]M-REPL&amp;gt; &lt;b&gt;subst[WATER;WINE;(MIX,WATER,AND,WINE,
                                 INTO,(MIXED,WATER,AND,WINE))];&lt;/b&gt;
 --&amp;gt; (MIX WATER AND WATER INTO (MIXED WATER AND WATER))

COMMON-LISP-USER[9]M-REPL&amp;gt; &lt;b&gt;subst[WINE;WATER;(MIX,WATER,AND,WINE,
                                 INTO,(MIXED,WATER,AND,WINE))];&lt;/b&gt;
 --&amp;gt; (MIX WINE AND WINE INTO (MIXED WINE AND WINE))

COMMON-LISP-USER[10]M-REPL&amp;gt; &lt;b&gt;first[((A,B),C,D)]=(A,B);&lt;/b&gt;

 --&amp;gt; NIL

COMMON-LISP-USER[11]M-REPL&amp;gt; &lt;b&gt;combine[A;⋀];&lt;/b&gt;
 --&amp;gt; (A)

COMMON-LISP-USER[12]M-REPL&amp;gt; &lt;b&gt;quit[];&lt;/b&gt;
NIL
[3]&amp;gt;

  &lt;/pre&gt;



&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/m-expression/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/articles/interleave/index.html</id><published>2006-08-26T12:00:00+0100</published><updated>2015-10-26T00:27:50+0100</updated><title type="text">Interleave</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/interleave.png&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/articles/interleave/index.html&quot;&gt;Interleave&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Implementation in Common Lisp of an algorithm to compute &quot;interleave&quot; and &quot;deinterleave&quot; permutations.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;interleave&quot;&gt;
&lt;h1&gt;Interleave&lt;/h1&gt;



&lt;p&gt;On &lt;a href=&quot;news:comp.programming&quot;&gt;comp.programming&lt;/a&gt; &lt;em&gt;mike3&lt;/em&gt;&lt;a href=&quot;http://groups.google.com/group/comp.programming/browse_frm/thread/b335648ee7e3d065/21a1283c430f6ad5?#21a1283c430f6ad5&quot;&gt;
asked for an algorithm to compute &quot;interleave&quot; and &quot;deinterleave&quot;
permutations&lt;/a&gt;.

Here is &lt;a href=&quot;interleave.lisp&quot;&gt;an implementation&lt;/a&gt; in &lt;a href=&quot;http://en.wikipedia.org/wiki/Common_Lisp&quot;&gt;Common Lisp&lt;/a&gt; of such an algorithm.

&lt;p&gt;The following diagrams are generated by &lt;a href=&quot;http://www.graphviz.org/&quot;&gt;
Graphviz&lt;/a&gt; from .dot files generated by &lt;a href=&quot;interleave.lisp&quot;&gt;interleave.lisp&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;permutations.html&quot;&gt;Permutations up to 98&lt;/a&gt;...&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;
&lt;br&gt;2 cycles, of lengths: 1, 1.
&lt;br&gt;((1) (0))
&lt;br&gt;
2 = 2
&lt;br&gt;
0 =
&lt;br&gt;
&lt;img src=&quot;graph-02.png&quot;&gt;&amp;nbsp;
&lt;img src=&quot;interleave-02.png&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;circle-02.png&quot; width=&quot;194&quot;&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt;
&lt;br&gt;3 cycles, of lengths: 1, 2, 1.
&lt;br&gt;((3) (2 1) (0))
&lt;br&gt;
4 = 2&lt;sup&gt;2&lt;/sup&gt;
&lt;br&gt;
2 = 2
&lt;br&gt;
&lt;img src=&quot;graph-04.png&quot;&gt;&amp;nbsp;
&lt;img src=&quot;interleave-04.png&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;circle-04.png&quot; width=&quot;207&quot;&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;6&lt;/strong&gt;
&lt;br&gt;3 cycles, of lengths: 1, 4, 1.
&lt;br&gt;((5) (2 4 3 1) (0))
&lt;br&gt;
6 = 3 * 2
&lt;br&gt;
4 = 2&lt;sup&gt;2&lt;/sup&gt;
&lt;br&gt;
&lt;img src=&quot;graph-06.png&quot;&gt;&amp;nbsp;
&lt;img src=&quot;interleave-06.png&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;circle-06.png&quot; width=&quot;288&quot;&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;8&lt;/strong&gt;
&lt;br&gt;4 cycles, of lengths: 1, 3, 3, 1.
&lt;br&gt;((7) (6 5 3) (2 4 1) (0))
&lt;br&gt;
8 = 2&lt;sup&gt;3&lt;/sup&gt;
&lt;br&gt;
6 = 3 * 2
&lt;br&gt;
&lt;img src=&quot;graph-08.png&quot;&gt;&amp;nbsp;
&lt;img src=&quot;interleave-08.png&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;circle-08.png&quot; width=&quot;370&quot;&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt;
&lt;br&gt;4 cycles, of lengths: 1, 2, 6, 1.
&lt;br&gt;((9) (6 3) (2 4 8 7 5 1) (0))
&lt;br&gt;
10 = 5 * 2
&lt;br&gt;
8 = 2&lt;sup&gt;3&lt;/sup&gt;
&lt;br&gt;
&lt;img src=&quot;graph-10.png&quot;&gt;&amp;nbsp;
&lt;img src=&quot;interleave-10.png&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;circle-10.png&quot; width=&quot;452&quot;&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt;
&lt;br&gt;3 cycles, of lengths: 1, 10, 1.
&lt;br&gt;((11) (2 4 8 5 10 9 7 3 6 1) (0))
&lt;br&gt;
12 = 3 * 2&lt;sup&gt;2&lt;/sup&gt;
&lt;br&gt;
10 = 5 * 2
&lt;br&gt;
&lt;img src=&quot;graph-12.png&quot;&gt;&amp;nbsp;
&lt;img src=&quot;interleave-12.png&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;circle-12.png&quot; width=&quot;564&quot;&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;14&lt;/strong&gt;
&lt;br&gt;3 cycles, of lengths: 1, 12, 1.
&lt;br&gt;((13) (2 4 8 3 6 12 11 9 5 10 7 1) (0))
&lt;br&gt;
14 = 7 * 2
&lt;br&gt;
12 = 3 * 2&lt;sup&gt;2&lt;/sup&gt;
&lt;br&gt;
&lt;img src=&quot;graph-14.png&quot;&gt;&amp;nbsp;
&lt;img src=&quot;interleave-14.png&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;circle-14.png&quot; width=&quot;651&quot;&gt;
&lt;br&gt;
&lt;hr&gt;



&lt;p&gt;&lt;a href=&quot;permutations.html&quot;&gt;Permutations up to 98&lt;/a&gt;...&lt;/p&gt;


&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/hr&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/img&gt;
&lt;/img&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/br&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/articles/interleave/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/ibcl/index.html</id><published>2006-05-04T12:00:00+0100</published><updated>2015-10-26T00:27:50+0100</updated><title type="text">Image Based Development</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/interlisp-xerox.gif&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/ibcl/index.html&quot;&gt;Image Based Development&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;An utility to ease development in a Common Lisp image.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Common Lisp, Lisp, Lisp Image, Image Based Common Lisp, IBCL&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;ibcl&quot;&gt;


&lt;h1&gt;Image Based Development&lt;/h1&gt;




&lt;p&gt;The package &lt;tt&gt;IBCL&lt;/tt&gt; exports the same symbols as &lt;tt&gt;COMMON-LISP&lt;/tt&gt;, but for
    some of the functions of macros modified to track of the source
    of the definitions and to be able to edit them from the image,
    and to save them in files.&lt;/p&gt;




&lt;p&gt;The package &lt;tt&gt;IBCL-USER&lt;/tt&gt; is a virgin package using &lt;tt&gt;IBCL&lt;/tt&gt; instead of &lt;tt&gt;CL&lt;/tt&gt;.&lt;/p&gt;




&lt;p&gt;One can work at the REPL, define variables with
    &lt;tt&gt;DEFCONSTANT&lt;/tt&gt;, &lt;tt&gt;DEFVAR&lt;/tt&gt;, &lt;tt&gt;DEFPARAMETER&lt;/tt&gt;, macros with &lt;tt&gt;DEFMACRO&lt;/tt&gt;,
    and functions with &lt;tt&gt;DEFUN&lt;/tt&gt;, edit macro and function definitions
    with &lt;tt&gt;ED&lt;/tt&gt;, and save the image with &lt;tt&gt;SAVE-IMAGE&lt;/tt&gt;.&lt;/p&gt;




&lt;p&gt;The function &lt;tt&gt;LIST-PACKAGES-WITH-SOURCES&lt;/tt&gt; returns a list of packages
    where some of these variables or functions are defined.
    The function &lt;tt&gt;SOURCE&lt;/tt&gt; returns the source form of the given
    variable or function.
    The function &lt;tt&gt;SAVE-SOURCES&lt;/tt&gt; saves the definitions in a package,
    or all the definitions to a file or stream.&lt;/p&gt;




&lt;p&gt;A recent complete implementation of IBCL can be found in the
    &lt;a href=&quot;https://gitorious.org/com-informatimago/com-informatimago&quot;&gt;
      Informatimago  Common Lisp Library at gitorious&lt;/a&gt;, specifically:
    &lt;a href=&quot;https://gitorious.org/com-informatimago/com-informatimago/trees/master/common-lisp/lisp&quot;&gt;
      com.informatimago.common-lisp.lisp&lt;/a&gt;.


&lt;p&gt;You can load it in a Common Lisp implementation with
    &lt;a href=&quot;http://www.quicklisp.org/&quot;&gt;quicklisp&lt;/a&gt;:&lt;/p&gt;




&lt;pre class=&quot;dribble&quot;&gt;
cl-user&amp;gt; (ql:quickload :com.informatimago.common-lisp.lisp.ibcl)
To load &quot;com.informatimago.common-lisp.lisp.ibcl&quot;:
  Load 1 ASDF system:
    com.informatimago.common-lisp.lisp.ibcl
; Loading &quot;com.informatimago.common-lisp.lisp.ibcl&quot;
[package com.informatimago.common-lisp.lisp.image-based-common-lisp]
[package com.informatimago.common-lisp.lisp.image-based-common-lisp-user]
(:com.informatimago.common-lisp.lisp.ibcl)
cl-user&amp;gt; (in-package :ibcl-user)
#&amp;lt;Package &quot;COM.INFORMATIMAGO.COMMON-LISP.LISP.IMAGE-BASED-COMMON-LISP-USER&quot;&amp;gt;
image-based-common-lisp-user&amp;gt; (defun f (x)
                                (if (zerop x)
                                  1
                                  (* x (f (1- x)))))

f
image-based-common-lisp-user&amp;gt; (source &#039;f :function)
(defun f (x) (if (zerop x) 1 (* x (f (1- x)))))
#&amp;lt;Package &quot;COM.INFORMATIMAGO.COMMON-LISP.LISP.IMAGE-BASED-COMMON-LISP-USER&quot;&amp;gt;
image-based-common-lisp-user&amp;gt; (defvar f 42)
f
image-based-common-lisp-user&amp;gt; (source &#039;f :variable)
(defvar f 42)
#&amp;lt;Package &quot;COM.INFORMATIMAGO.COMMON-LISP.LISP.IMAGE-BASED-COMMON-LISP-USER&quot;&amp;gt;
image-based-common-lisp-user&amp;gt; (defun (setf f) (newval) (setf f newval))
(setf f)
image-based-common-lisp-user&amp;gt; (source &#039;(setf f) :function)
(defun (setf f) (newval) (setf f newval))
#&amp;lt;Package &quot;COM.INFORMATIMAGO.COMMON-LISP.LISP.IMAGE-BASED-COMMON-LISP-USER&quot;&amp;gt;
image-based-common-lisp-user&amp;gt; (in-package :cl-user)
#&amp;lt;Package &quot;COM.INFORMATIMAGO.COMMON-LISP.LISP.IMAGE-BASED-COMMON-LISP-USER&quot;&amp;gt;
image-based-common-lisp-user&amp;gt; (cl:in-package :cl-user)
#&amp;lt;Package &quot;COMMON-LISP-USER&quot;&amp;gt;
cl-user&amp;gt;
  &lt;/pre&gt;




&lt;p&gt;Old proof-of-concept source:

&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;ibcl.lisp&quot;&gt;ibcl.lisp&lt;/a&gt;&lt;/li&gt;



&lt;li&gt;&lt;a href=&quot;ibcl-bootstrap.lisp&quot;&gt;ibcl-bootstrap.lisp&lt;/a&gt;
        A script to generate an executable image using
        IMAGE-BASED-COMMON-LISP instead of COMMON-LISP.
        For &lt;a href=&quot;http://clisp.cons.org/&quot;&gt;clisp&lt;/a&gt;
        or  &lt;a href=&quot;http://sbcl.sourceforge.net/&quot;&gt;sbcl&lt;/a&gt;.&lt;/li&gt;



&lt;/ul&gt;


  &lt;/p&gt;



&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/ibcl/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/brainfuck/index.html</id><published>2005-09-11T12:00:00+0100</published><updated>2015-10-26T00:27:50+0100</updated><title type="text">Brainfuck</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/brainfuck.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/brainfuck/index.html&quot;&gt;Brainfuck&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A Brainfuck implementation.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Brainfuck, Common Lisp, Lisp, virtual machine, compiler, emulator&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;brainfuck&quot;&gt;


&lt;h1&gt;Brainfuck in Lisp&lt;/h1&gt;




&lt;p&gt;This file contains:

&lt;ul&gt;




&lt;li&gt;a brainfuck virtual machine in Lisp&lt;/li&gt;




&lt;li&gt;a brainfuck optimizing compiler, translates to lisp and compiles
        lisp to native code&lt;/li&gt;




&lt;li&gt;a sketch for an implementation of a lisp on brainfuck. Nothing
        much actually, some macros to generate brainfuck code from lisp,
        some lisp &quot;vm&quot; primitives.  I kind of abandonned this, given the
        time complexity of any non-trivial brainfuck program and space
        limitations of the brainfuck virtual machine (however, this
        brainfuck to lisp compiler reduces the time complexities by using
        some random access to the memory, so it might be practical. Not
        that there is no limitation on the size of the
        programs...).
&lt;br&gt;Instead of implementing a lisp system over the
        brainfuck virtual machine, it might be more practical to implement
        a lisp compiler generating optimized brainfuck code.&lt;/br&gt;
&lt;/li&gt;




&lt;/ul&gt;


  &lt;/p&gt;





&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;bf.lisp&quot;&gt;bf.lisp&lt;/a&gt;&lt;/li&gt;



&lt;li&gt;&lt;a href=&quot;99botles.bf&quot;&gt;99botles.bf -- the &quot;99 Bottles&quot; program in brainfuck&lt;/a&gt;&lt;/li&gt;



&lt;/ul&gt;



&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/brainfuck/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/aim-8/index.html</id><published>2004-10-24T12:00:00+0100</published><updated>2015-10-26T00:27:51+0100</updated><title type="text">The original LISP</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/aim-8-mccarthy.gif&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/aim-8/index.html&quot;&gt;The original LISP&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;An implementation of the Original LISP in the AIM-8,
    including a transcription of said memo.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;LISP, Common Lisp, AIM-8, John McCarthy&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;original-lisp&quot;&gt;


&lt;h1&gt;The original LISP&lt;/h1&gt;



&lt;p&gt;Here is an implementation of the Original LISP as documented in
  &lt;quote&gt;
&lt;pre class=&quot;text&quot;&gt;
                                  March 4, 1959

    Artificial Intelligence Project--RLE and MIT Computation Center

                           Memo 8

    RECURSIVE FUNCTIONS OF SYMBOLIC EXPRESSIONS AND THEIR COMPUTATION

                         BY MACHINE

                       by J. McCarthy
   &lt;/pre&gt;
&lt;/quote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;aim-8.html&quot;&gt;A transcription into machine readable form
                        (HTML and text)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-008.pdf&quot;&gt;
      AI Memo 8, AIM-008.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ai.mit.edu/research/publications/browse/0000browse.shtml&quot;&gt;
      CSAIL Digital Archive - Artificial Intelligence Laboratory Series,
      Publications 0 through 99&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www-formal.stanford.edu/jmc/history/lisp/lisp.html&quot;&gt;
    History of Lisp&lt;/a&gt; by John McCarthy&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;




&lt;p&gt;The only symbols predefined are: DEFINE, LAMBDA, LABEL, COND, COMBINE,
FIRST, REST, NULL, ATOM, EQ, NIL, T, and QUOTE. &lt;/p&gt;




&lt;p&gt;The file &lt;a href=&quot;aim-8.lisp&quot;&gt;aim-8.lisp&lt;/a&gt;
     contains an implementation in Common-Lisp.&lt;/p&gt;



&lt;p&gt;The file &lt;a href=&quot;aim-8.aim-8&quot;&gt;aim-8.aim-8&lt;/a&gt;
     contains an implementation in AIM-8 LISP.&lt;/p&gt;



&lt;p&gt;The file &lt;a href=&quot;examples.aim-8&quot;&gt;examples.aim-8&lt;/a&gt;
     contains the other examples given in AIM-8: differential
     and turing machine.&lt;/p&gt;




&lt;p&gt;(It should be  noted that &quot;compiler&quot; occurs 4  times in this Memo,
      while &quot;interpreter&quot; doesn&#039;t appears.)&lt;/p&gt;





&lt;p&gt;For more information about Lisp history, see the
     &lt;a href=&quot;http://community.computerhistory.org/scc/projects/LISP/&quot;&gt;
         Computer History Museum, History of Lisp&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;Exemple&lt;/h2&gt;



&lt;pre class=&quot;dribble&quot;&gt;
% &lt;b&gt;/usr/local/bin/clisp -norc -ansi &lt;/b&gt;
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+&#039; /  I      8         8           8     8        8    8
   \  `-+-&#039;  /       8         8           8      ooooo   8oooo
    `-__|__-&#039;        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2006

[1]&amp;gt; &lt;b&gt;(load (compile-file &quot;aim-8.lisp&quot;))&lt;/b&gt;
;; Compiling file /local/users/pjb/src/public/small-cl-pgms/aim-8/aim-8.lisp ...
;; Wrote file /local/users/pjb/src/public/small-cl-pgms/aim-8/aim-8.fas
0 errors, 0 warnings
;; Loading file /local/users/pjb/src/public/small-cl-pgms/aim-8/aim-8.fas ...
;; Loaded file /local/users/pjb/src/public/small-cl-pgms/aim-8/aim-8.fas
T
[2]&amp;gt; &lt;b&gt;(aim-8:repl)&lt;/b&gt;
You&#039;ve got:
    LAMBDA LABEL
    COND AND OR NOT  COMBINE FIRST REST
    NULL ATOM EQ NIL T QUOTE
Extensions:
    DEFINE RELOAD DUMP-ENVIRONMENT LOAD
    QUIT
AIM-8&amp;gt; &lt;b&gt;(define maplist
           (lambda (x f)
             (cond ((null x) nil)
                   (t        (combine (f x) (maplist (rest x) f))))))&lt;/b&gt;
MAPLIST
AIM-8&amp;gt; &lt;b&gt;(define diff
           (lambda (y x)
             (cond
               ((atom y)
                (cond ((eq y x) (quote one))
                      (t (quote zero))))
               ((eq (first y) (quote plus))
                (combine (quote plus)
                         (maplist (rest y) (lambda (a) (diff (first a) x)))))
               ((eq (first y) (quote times))
                (combine (quote plus)
                         (maplist
                          (rest y)
                          (lambda (a) (combine
                                  (quote times)
                                  (maplist
                                   (rest y)
                                   (lambda (w) (cond
                                            ((not (eq a w)) (first w))
                                            (t (diff (first w) x))
                                            )))))))))))&lt;/b&gt;
DIFF
AIM-8&amp;gt; &lt;b&gt;(diff (quote (plus (times a x) b)) (quote x))&lt;/b&gt;
(PLUS (PLUS (TIMES ZERO X) (TIMES A ONE)) ZERO)
AIM-8&amp;gt; &lt;b&gt;(diff (quote (plus (times a x x) (times b x) c)) (quote x))&lt;/b&gt;
(PLUS (PLUS (TIMES ZERO X X) (TIMES A ONE X) (TIMES A X ONE))
 (PLUS (TIMES ZERO X) (TIMES B ONE)) ZERO)

;; Beware, AIM-8 is defined with substitution evaluation.
;; Therefore, for each occurence of a variable, the whole expression
;; bound to this variable is evaluated again.  This gives surprizing
;; results for procedures with side-effects like PRINT and READ.
;; Moreover, this has the effect of giving exponential complexities very easily.

AIM-8&amp;gt; &lt;b&gt;((lambda (x) (combine x (combine x nil))) (print (quote a)))&lt;/b&gt;

A
A (A A)
AIM-8&amp;gt; &lt;b&gt;(quit)&lt;/b&gt;
GOOD BYE
NIL
[3]&amp;gt; &lt;b&gt;(quit)&lt;/b&gt;
Bye.
%

  &lt;/pre&gt;



&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/aim-8/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry><entry><id>http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/basic/index.html</id><published>2003-05-19T12:00:00+0100</published><updated>2015-10-26T00:27:51+0100</updated><title type="text">BASIC</title><content type="html">&lt;div class=&quot;blog&quot;&gt;
&lt;div class=&quot;header&quot;&gt;
&lt;img src=&quot;http://www.informatimago.com/blog/dartmouth-basic.jpg&quot; height=&quot;100px&quot; class=&quot;floatRight&quot;&gt;&lt;/img&gt;
&lt;h1&gt;&lt;a href=&quot;http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/basic/index.html&quot;&gt;BASIC&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A Quick, Dirty and Ugly Basic interpreter&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;mailto:pjb+blog@informatimago.com&quot;&gt;Pascal J. Bourguignon&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;BASIC, Common Lisp, Lisp&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;document&quot; id=&quot;basic&quot;&gt;


&lt;h1&gt;BASIC&lt;/h1&gt;



&lt;h2&gt;A Quick, Dirty and Ugly Basic interpreter&lt;/h2&gt;




&lt;p&gt;This is a silly BASIC interpreter, implemented in Common Lisp.&lt;/p&gt;




&lt;p&gt;The lines are tokenized and stored as-is in an array indexed by
    the line number.  When interpreting the program, the instructions
    are parsed directly from there ; the expressions are parsed into
    trees which are then evaluated.&lt;/p&gt;




&lt;p&gt;The variables are stored into a hash table indexed by their
    identifier (symbol). Undefined variables are taken as 0 or &quot;&quot;.&lt;/p&gt;




&lt;p&gt;We distinguish number and string variables depending on the presence
    of a &#039;$&#039; character in the last position of the variable identifier.&lt;/p&gt;




&lt;p&gt;Variables are reset by the command RUN. (A program can be
    restarted without losing the variable using the GOTO or GOSUB
    statements).  Commands are not distinguished from statements and
    may occur in a program. In particular, LOAD could be used to
    load a subprogram overlay, and takes a line number where to jump
    to. &lt;/p&gt;




&lt;p&gt;Programs are loaded and saved in source form.&lt;/p&gt;




&lt;ul&gt;



&lt;li&gt;&lt;a href=&quot;basic.lisp&quot;&gt;basic.lisp&lt;/a&gt;&lt;/li&gt;



&lt;li&gt;&lt;a href=&quot;test1.basic&quot;&gt;test1.basic&lt;/a&gt;&lt;/li&gt;



&lt;li&gt;&lt;a href=&quot;test2.basic&quot;&gt;test2.basic&lt;/a&gt;&lt;/li&gt;



&lt;/ul&gt;



&lt;/div&gt;
&lt;/div&gt;
</content><link rel="self" type="application/atom+xml" href="http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/basic/index.html"/><author><name>Pascal J. Bourguignon</name><email>pjb+blog@informatimago.com</email></author></entry></feed>
ViewGit