<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkYESXo5fSp7ImA9WxNUE04.&quot;"><id>tag:blogger.com,1999:blog-5829875</id><updated>2009-11-04T12:21:48.425+02:00</updated><title>Theory and Practice</title><subtitle type="html">RGrig's thoughts</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://rgrig.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>202</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/3.0/" /><link rel="self" href="http://feeds.feedburner.com/RgrigsBlog" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;A0UAQ3Y9eSp7ImA9WxNVF0w.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-5419174340109738063</id><published>2009-10-28T10:40:00.000+02:00</published><updated>2009-10-28T10:40:42.861+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-28T10:40:42.861+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><title>Irrational</title><content type="html">&lt;p&gt;&lt;i&gt;A cute math puzzle that I saw twice in the past week.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;There are three parts. The first two are supposed to be very easy.&lt;p&gt;

&lt;ol&gt;
&lt;li&gt;Are there two irrational numbers &lt;i&gt;a&lt;/i&gt; and &lt;i&gt;b&lt;/i&gt; such that &lt;i&gt;a&lt;/i&gt;+&lt;i&gt;b&lt;/i&gt; is rational?&lt;/li&gt;
&lt;li&gt;Are there two irrational numbers &lt;i&gt;a&lt;/i&gt; and &lt;i&gt;b&lt;/i&gt; such that &lt;i&gt;ab&lt;/i&gt; is rational?&lt;/li&gt;
&lt;li&gt;Are there two irrational numbers &lt;i&gt;a&lt;/i&gt; and &lt;i&gt;b&lt;/i&gt; such that &lt;i&gt;a&lt;sup&gt;b&lt;/sup&gt;&lt;/i&gt; is rational?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sources: The Princeton Companion and Richard Lipton's blog, quoting a talk by Manny Blum.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-5419174340109738063?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/4_6WOqvXKSc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/5419174340109738063/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/10/irrational.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5419174340109738063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5419174340109738063?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/4_6WOqvXKSc/irrational.html" title="Irrational" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/10/irrational.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIMQ3g4eip7ImA9WxNVEk0.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-8026178733992561162</id><published>2009-10-22T12:25:00.001+03:00</published><updated>2009-10-22T12:26:22.632+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-22T12:26:22.632+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="random" /><title>Overflow</title><content type="html">&lt;p&gt;&lt;i&gt;How do you use &lt;a href="http://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt; and &lt;a href="http://mathoverflow.net/"&gt;MathOverflow&lt;/a&gt;?&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;I sometimes find answers on StackOverflow while googling for technical problems. For example, yesterday I wanted to know what is a good way to center code typeset with the LaTeX package &lt;tt&gt;listings&lt;/tt&gt;. I didn't find out, so I'm stuck with nesting four environments: &lt;tt&gt;figure&lt;/tt&gt;, &lt;tt&gt;center&lt;/tt&gt;, &lt;tt&gt;tabular&lt;/tt&gt;, &lt;tt&gt;lstlisting&lt;/tt&gt;. Instead, I found someone asking on StackOverflow how to top-align two listings that go on the same row of a &lt;tt&gt;tabular&lt;/tt&gt; environment. There were a few overly complicated answers, so I added mine (&lt;tt&gt;\lstset{boxpos=t}&lt;/tt&gt;). Notice that it's more of a coincidence that StackOverflow got involved—I never planned to answer a question there. In fact, whenever I feel like helping random people and I go to StackOverflow or MathOverflow and click on "Unanswered" I end up sad because I &lt;i&gt;never&lt;/i&gt; know how to answer &lt;i&gt;any&lt;/i&gt; question.&lt;/p&gt;

&lt;p&gt;
So, do you use these websites? If yes, then how do you interact with them?&lt;/p&gt;

&lt;p&gt;PS: In other news, expect this blog to be quiet until next year. I'm suppose to write a dissertation. Wish me luck.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-8026178733992561162?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/MuXxYfzVFXw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/8026178733992561162/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/10/overflow.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/8026178733992561162?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/8026178733992561162?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/MuXxYfzVFXw/overflow.html" title="Overflow" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/10/overflow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04HQn46fSp7ImA9WxNWF00.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-4676498439562574888</id><published>2009-10-16T17:57:00.007+03:00</published><updated>2009-10-16T18:12:13.015+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-16T18:12:13.015+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="graphs" /><category scheme="http://www.blogger.com/atom/ns#" term="research" /><category scheme="http://www.blogger.com/atom/ns#" term="learning" /><title>Reducible Flowgraphs 0</title><content type="html">&lt;style&gt;
DT{float:left;clear:left}
&lt;/style&gt;

&lt;br /&gt;
&lt;i&gt;A summary of some basic results on reducible
flowgraphs. Feedback is welcome. In particular, the ‘easy’ and
‘obvious’ parts are notorious for hiding mistakes. So let me know
if something doesn’t look as ‘easy’ as I claim. This post is also
available in &lt;a href="http://radu.ucd.ie/temp/blog/reducible0.pdf"&gt;PDF form&lt;/a&gt;.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Preliminaries.&lt;/b&gt;&amp;nbsp;&amp;nbsp; A &lt;i&gt;flowgraph&lt;/i&gt; is a 
&lt;a href="http://www.google.com/#q=directed+graph"&gt;digraph&lt;/a&gt; with an &lt;i&gt;initial node&lt;/i&gt;&amp;nbsp;0 from
which all other nodes are reachable. Typically nodes represent
statements in some low-level language (like Java bytecode)
and edges represent possible successors in an execution.
There are various restricted classes of flowgraphs that have
been studied and are important in practice. For example, if
a flowgraph is a &lt;a href="http://www.google.com/#q=directed+acyclic+graph"&gt;dag&lt;/a&gt;
(has no cycles) then the program terminates for all inputs;
if a flowgraph is a &lt;a href="http://www.google.com/#q=series+parallel+graph"&gt;two-terminal series–parallel graph&lt;/a&gt; then it corresponds to
programs written using only two simple composition operations:
sequence (&lt;tt&gt;;&lt;/tt&gt;) and choice (&lt;tt&gt;[]&lt;/tt&gt;). The subject
of this post, reducible flowgraphs, is a class of flowgraphs
that correspond to programs that can be written without using
&lt;b&gt;goto &lt;/b&gt;— loops like &lt;b&gt;while&lt;/b&gt; and &lt;b&gt;for&lt;/b&gt;
suffice.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="theorem"&gt;
&lt;b&gt;Definition&amp;nbsp;1&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
A flowgraph is &lt;/i&gt;reducible&lt;i&gt; when it does &lt;/i&gt;&lt;i&gt;&lt;b&gt;not&lt;/b&gt;&lt;/i&gt;&lt;i&gt; have a
strongly connected &lt;/i&gt;&lt;a href="http://www.google.com/#q=subgraph"&gt;&lt;i&gt;subgraph&lt;/i&gt;&lt;/a&gt;&lt;i&gt; with two (or more) entries.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
A graph is &lt;i&gt;strongly connected&lt;/i&gt; when there is a
&lt;a href="http://www.google.com/#q=graph+path"&gt;path&lt;/a&gt;&amp;nbsp;&lt;i&gt;x&lt;/i&gt; ↝ &lt;i&gt;y&lt;/i&gt; for all nodes&amp;nbsp;&lt;i&gt;x&lt;/i&gt;
and&amp;nbsp;&lt;i&gt;y&lt;/i&gt;. Node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; is an &lt;i&gt;entry&lt;/i&gt; for a subgraph&amp;nbsp;&lt;i&gt;H&lt;/i&gt; when
there is a path&amp;nbsp;0 ↝&lt;sup&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;p&lt;/i&gt;&lt;/span&gt;&lt;/sup&gt; &lt;i&gt;x&lt;/i&gt; such that &lt;i&gt;p&lt;/i&gt; ∩
&lt;i&gt;H&lt;/i&gt; = {&lt;i&gt;x&lt;/i&gt;}. (By notation abuse, &lt;i&gt;p&lt;/i&gt; and &lt;i&gt;H&lt;/i&gt; stand for sets of
nodes, including the endpoints for the path.)&lt;br /&gt;
&lt;br /&gt;
There are at least three other equivalent definitions, as
Theorem&amp;nbsp;1 shows. Those definitions use a few
more graph-theoretic concepts. A node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; &lt;i&gt;dominates&lt;/i&gt;
node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; when all paths&amp;nbsp;0 ↝ &lt;i&gt;y&lt;/i&gt; contain node&amp;nbsp;&lt;i&gt;x&lt;/i&gt;. An
edge&amp;nbsp;&lt;i&gt;x&lt;/i&gt; → &lt;i&gt;x&lt;/i&gt; (for some node&amp;nbsp;&lt;i&gt;x&lt;/i&gt;) is a &lt;i&gt;cycle-edge&lt;/i&gt;.
A &lt;a href="http://www.google.com/#q=depth+first+search"&gt;depth first search&lt;/a&gt; (DFS) of a
flowgraph partitions its edges into &lt;i&gt;tree edges&lt;/i&gt; (making
up a spanning tree known as a &lt;i&gt;DFS tree&lt;/i&gt;), &lt;i&gt;forward
edges&lt;/i&gt; (pointing to a successor in the spanning tree), &lt;i&gt;back
edges&lt;/i&gt; (pointing to a predecessor in the spanning tree, plus
cycle-edges), and &lt;i&gt;cross edges&lt;/i&gt; (the others). Tree edges,
forward edges, and cross edges form a dag known as a &lt;i&gt;DFS
dag&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="theorem"&gt;
&lt;b&gt;Theorem&amp;nbsp;1&lt;/b&gt;&amp;nbsp;&lt;b&gt;(&lt;/b&gt;&lt;b&gt;[&lt;/b&gt;&lt;b&gt;1&lt;/b&gt;&lt;b&gt;, &lt;/b&gt;&lt;b&gt;2&lt;/b&gt;&lt;b&gt;]&lt;/b&gt;&lt;b&gt;)&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
The following statements about a flowgraph are equivalent:
&lt;/i&gt;&lt;br /&gt;
&lt;ol class="enumerate" type="1"&gt;
&lt;li class="li-enumerate"&gt;&lt;i&gt;
&lt;/i&gt;&lt;i&gt;It is reducible.
&lt;/i&gt;&lt;/li&gt;
&lt;li class="li-enumerate"&gt;&lt;i&gt;Every back edge has its source dominated by its target,
for all DFS trees.
&lt;/i&gt;&lt;/li&gt;
&lt;li class="li-enumerate"&gt;&lt;i&gt;It has a unique DFS dag.
&lt;/i&gt;&lt;/li&gt;
&lt;li class="li-enumerate"&gt;&lt;i&gt;It can be transformed into a single node by
repeated application of the transformations &lt;/i&gt;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;&lt;i&gt; and&amp;nbsp;&lt;/i&gt;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;&lt;i&gt;:
&lt;/i&gt;&lt;br /&gt;



&lt;br /&gt;
&lt;br /&gt;
&lt;ul class="itemize"&gt;
&lt;li class="li-itemize"&gt;&lt;i&gt;
&lt;/i&gt;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;&lt;i&gt;: Remove a cycle-edge.
&lt;/i&gt;&lt;/li&gt;
&lt;li class="li-itemize"&gt;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;&lt;i&gt;: Pick a non-initial node&amp;nbsp;&lt;/i&gt;&lt;i&gt;y&lt;/i&gt;&lt;i&gt; that has only one
incoming edge&amp;nbsp;&lt;/i&gt;&lt;i&gt;x&lt;/i&gt; → &lt;i&gt;y&lt;/i&gt;&lt;i&gt; and glue nodes&amp;nbsp;&lt;/i&gt;&lt;i&gt;x&lt;/i&gt;&lt;i&gt; and&amp;nbsp;&lt;/i&gt;&lt;i&gt;y&lt;/i&gt;&lt;i&gt;.
&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;i&gt;
&lt;/i&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="th:red-def"&gt;&lt;/a&gt;&lt;i&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;i&gt;Proof.&lt;/i&gt; It is not hard to show (by taking the contrapositive) that (1)
⇒ (2) and (2) ⇒ (3) and (3) ⇒ (1) and (4) ⇒
(1). It remains to show that (4) is implied by one of the
others, which I’ll do, again, by looking at the contrapositive.&lt;br /&gt;
&lt;br /&gt;
(1) ⇒ (4): If &lt;i&gt;T&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt; and&amp;nbsp;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt; cannot reduce a graph to
a single node then the graph must have a strongly connected
subgraph with two entries. This task can be split in two:
First, show that if &lt;i&gt;T&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt; and&amp;nbsp;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt; cannot be applied at all then
there is a strongly connected subgraph with two entries; second,
show that applications of &lt;i&gt;T&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;−1&lt;/sup&gt; and&amp;nbsp;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;&lt;sup&gt;−1&lt;/sup&gt; maintain the
existence of a strongly connected subgraph with two entries.&lt;br /&gt;
&lt;br /&gt;
First part: If &lt;i&gt;T&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt; and&amp;nbsp;&lt;i&gt;T&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt; cannot be applied then each
non-initial node has ≥ 2 (distinct) predecessors. The initial
node must have ≥ 2 (distinct) successors, let’s call them
1,…,&lt;i&gt;k&lt;/i&gt;. Let’s look at nodes&amp;nbsp;&lt;i&gt;x&lt;/i&gt; and&amp;nbsp;&lt;i&gt;y&lt;/i&gt; ranging over this
set. Because node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; must have a second incoming edge there
has to be a path&amp;nbsp;&lt;i&gt;x&lt;/i&gt; ↝ &lt;i&gt;y&lt;/i&gt; for some&amp;nbsp;&lt;i&gt;x&lt;/i&gt;. If we can find
&lt;i&gt;x&lt;/i&gt; ≠ &lt;i&gt;y&lt;/i&gt; for all&amp;nbsp;&lt;i&gt;y&lt;/i&gt; then we are done, since at least two of
1,…,&lt;i&gt;k&lt;/i&gt; must be in strongly connected subgraph. Otherwise,
let’s examine some node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; whose second incoming edge comes
from a cycle&amp;nbsp;&lt;i&gt;y&lt;/i&gt; ↝ &lt;i&gt;y&lt;/i&gt;. The other nodes in this cycle must
themselves have some second incoming edge which might come from
some node &lt;i&gt;x&lt;/i&gt; ≠ &lt;i&gt;y&lt;/i&gt;, and we are done as before. Otherwise, we
apply recursively the same reasoning on the subflowgraph induced
by the nodes of the cycle&amp;nbsp;&lt;i&gt;y&lt;/i&gt; ↝ &lt;i&gt;y&lt;/i&gt; (with node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; as the
initial node).&lt;br /&gt;
&lt;br /&gt;
Second part: Easy. (Some would say ‘exercise’.)  ☐&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The loop forest.&lt;/b&gt;&amp;nbsp;&amp;nbsp;
Typically a programmer writes in a language with &lt;b&gt;while&lt;/b&gt;,
which gets desugared, and then various tools (like optimizers or
program verifiers) must reconstruct the loop structure of the
original program. You may wonder why not keep the &lt;b&gt;while&lt;/b&gt;
constructs around in the low-level language:&lt;br /&gt;
&lt;ul class="itemize"&gt;
&lt;li class="li-itemize"&gt;
Fewer language constructs means &lt;i&gt;other&lt;/i&gt; algorithms 
are easier.
&lt;/li&gt;
&lt;li class="li-itemize"&gt;If the programmer is abusing &lt;b&gt;goto&lt;/b&gt; we still want to
know what he meant.
&lt;/li&gt;
&lt;/ul&gt;
An important property of reducible flowgraphs is that there is a
natural definition for loops. Intuitively, we want loops to be
strongly connected subgraphs and, in reducible flowgraphs, such
subgraphs can be associated with their entry.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="theorem"&gt;
&lt;b&gt;Definition&amp;nbsp;2&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
In a reducible flowgraph, the &lt;/i&gt;loop&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt;&lt;i&gt; associated with
the node&amp;nbsp;&lt;/i&gt;&lt;i&gt;x&lt;/i&gt;&lt;i&gt; is the unique maximal strongly connected subgraph
for which node&amp;nbsp;&lt;/i&gt;&lt;i&gt;x&lt;/i&gt;&lt;i&gt; is an entry.
&lt;/i&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="def:loop-red"&gt;&lt;/a&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
Such a graph always exists because a strongly connected
subgraph of a reducible flowgraph is dominated by its unique
entry. In other words, Definition&amp;nbsp;2 says that
the loop&amp;nbsp;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt; is the set of nodes&amp;nbsp;&lt;i&gt;y&lt;/i&gt; that are dominated by
node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; and also have a path&amp;nbsp;&lt;i&gt;y&lt;/i&gt; ↝ &lt;i&gt;x&lt;/i&gt; back to the entry.
(The path&amp;nbsp;0 ↝ &lt;i&gt;x&lt;/i&gt; that witnesses node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; being an entry
cannot contain any dominated node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; ≠ &lt;i&gt;x&lt;/i&gt;.)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="theorem"&gt;
&lt;b&gt;Proposition&amp;nbsp;1&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
Loops are strongly connected.
&lt;/i&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="prop:conn"&gt;&lt;/a&gt;&lt;i&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div class="theorem"&gt;
&lt;b&gt;Proposition&amp;nbsp;2&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
Two loops are either disjunct or one is included in the other.
&lt;/i&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="prop:loop-tree"&gt;&lt;/a&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;i&gt;Proof.&lt;/i&gt; If node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; dominates node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; and there exists a node&amp;nbsp;&lt;i&gt;z&lt;/i&gt; ∈ &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt;
∩ &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sub&gt; then &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt; ∩ &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sub&gt; = &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sub&gt;. If there is no domination
between node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; and node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; then there is no node dominated by
both so &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt; ∩ &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sub&gt; = ∅.  ☐&lt;br /&gt;
&lt;br /&gt;
When we extend the definition of loops to non-reducible
graphs we’ll make sure that Propositions&amp;nbsp;1
and&amp;nbsp;2 still hold. Thus, it always makes sense
to talk about a &lt;i&gt;loop forest&lt;/i&gt; (in which there is a path&amp;nbsp;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt;
↝ &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sub&gt; when &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt; ⊇ &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sub&gt;).&lt;br /&gt;
&lt;br /&gt;
The structure of loops in reducible flowgraphs can be analyzed
by looking at what back edges they contain. A &lt;i&gt;cycle&lt;/i&gt; is a
graph of the form 1 → 2 → ⋯ → &lt;i&gt;k&lt;/i&gt; → 1. Every cycle
(which is a subgraph) of a flowgraph must contain one back edge.
In reducible flowgraphs a stronger statement holds.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="theorem"&gt;
&lt;b&gt;Lemma&amp;nbsp;1&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
Every cycle in a reducible flowgraph contains exactly
one back edge.
&lt;/i&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="lemma:one-back"&gt;&lt;/a&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;i&gt;Proof.&lt;/i&gt; Suppose there is a cycle &lt;i&gt;x&lt;/i&gt;′ → &lt;i&gt;x&lt;/i&gt; ↝&lt;sup&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;p&lt;/i&gt;&lt;/span&gt;&lt;/sup&gt; &lt;i&gt;y&lt;/i&gt;′
→ &lt;i&gt;y&lt;/i&gt; ↝&lt;sup&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;q&lt;/i&gt;&lt;/span&gt;&lt;/sup&gt; &lt;i&gt;x&lt;/i&gt;′, which contains back edges &lt;i&gt;x&lt;/i&gt;′
→ &lt;i&gt;x&lt;/i&gt; and &lt;i&gt;y&lt;/i&gt;′ → &lt;i&gt;y&lt;/i&gt;. By definition, the nodes of a cycle are
distinct, but we allow paths&amp;nbsp;&lt;i&gt;p&lt;/i&gt; and&amp;nbsp;&lt;i&gt;q&lt;/i&gt; to be (not necessarily
both) of length&amp;nbsp;0 so it is possible that &lt;i&gt;x&lt;/i&gt; = &lt;i&gt;y&lt;/i&gt;′ and it is
possible that&amp;nbsp;&lt;i&gt;y&lt;/i&gt; = &lt;i&gt;x&lt;/i&gt;′. Every path&amp;nbsp;0 ↝ &lt;i&gt;x&lt;/i&gt;′ must contain
node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; according to statement (2) in Theorem&amp;nbsp;1.
Since there are paths&amp;nbsp;0 ↝ &lt;i&gt;y&lt;/i&gt; ↝&lt;sup&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;q&lt;/i&gt;&lt;/span&gt;&lt;/sup&gt; &lt;i&gt;x&lt;/i&gt;′,
this implies that all paths&amp;nbsp;0 ↝ &lt;i&gt;y&lt;/i&gt; must contain node&amp;nbsp;&lt;i&gt;x&lt;/i&gt;
(because path&amp;nbsp;&lt;i&gt;q&lt;/i&gt; does not contain node&amp;nbsp;&lt;i&gt;x&lt;/i&gt;, since they are
part of a cycle). In other words, node&amp;nbsp;&lt;i&gt;x&lt;/i&gt; dominates node&amp;nbsp;&lt;i&gt;y&lt;/i&gt;.
Symmetrically, node&amp;nbsp;&lt;i&gt;y&lt;/i&gt; dominates node&amp;nbsp;&lt;i&gt;x&lt;/i&gt;. This is only possible
if &lt;i&gt;x&lt;/i&gt;=&lt;i&gt;y&lt;/i&gt;, which is a contradiction.  ☐
&lt;br /&gt;
&lt;blockquote class="figure"&gt;
&lt;div class="center"&gt;
&lt;div class="center"&gt;
&lt;hr size="2" width="80%" /&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_byUC16gzOKM/StiJBiU3FkI/AAAAAAAABsw/gm03Kql9nGM/s1600-h/reducible000.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_byUC16gzOKM/StiJBiU3FkI/AAAAAAAABsw/gm03Kql9nGM/s320/reducible000.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_byUC16gzOKM/StiJG2MKp3I/AAAAAAAABs4/WPCaaJxGwQ4/s1600-h/reducible001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_byUC16gzOKM/StiJG2MKp3I/AAAAAAAABs4/WPCaaJxGwQ4/s320/reducible001.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="fig:loops-1"&gt;&lt;/a&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;


&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="fig:loops-2"&gt;&lt;/a&gt;

&lt;br /&gt;
&lt;div class="caption"&gt;
&lt;table cellpadding="0" cellspacing="6" height="30" style="width: 557px;"&gt;&lt;tbody&gt;
&lt;tr align="center"&gt;&lt;td valign="top"&gt;Figure 1: flowgraph examples&lt;br /&gt;
&lt;/td&gt;&lt;td valign="top"&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td valign="top"&gt;&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="center"&gt;
&lt;hr size="2" width="80%" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
Because of Lemma&amp;nbsp;1, Hecht and
Ullman&amp;nbsp;[2] originally defined loops in reducible
graphs by associating them to back edges: The loop&amp;nbsp;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt; → &lt;i&gt;x&lt;/i&gt;&lt;/sub&gt;
is the union of paths&amp;nbsp;&lt;i&gt;x&lt;/i&gt; ↝ &lt;i&gt;y&lt;/i&gt; that do not use node&amp;nbsp;&lt;i&gt;x&lt;/i&gt;
as an intermediate node, plus the back edge itself. This shows
that there isn’t really only one natural way of defining loops in
reducible flowgraphs. For the graph in Figure 1(left)
the old definition gives loop&amp;nbsp;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;1 → 0&lt;/sub&gt;={0,1} nested in
loop&amp;nbsp;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;2 → 0&lt;/sub&gt;={0,1,2}, while our definition only finds the
loop&amp;nbsp;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;0&lt;/sub&gt;=&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;2 → 0&lt;/sub&gt; (plus the uninteresting &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;={1} and
&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;={2}). The problem with the old definition, however, is
that it does not imply Proposition&amp;nbsp;2 as can be
seen in Figure 1(right).&lt;br /&gt;
&lt;br /&gt;
Definition&amp;nbsp;2 is always more coarse grained
than that of Hecht and Ullman&amp;nbsp;[2].&lt;br /&gt;
&lt;br /&gt;
&lt;div class="theorem"&gt;
&lt;b&gt;Lemma&amp;nbsp;2&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
In a reducible flowgraph, we have &lt;/i&gt;&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt; = ∪&lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt; → &lt;i&gt;x&lt;/i&gt;&lt;/sub&gt;&lt;i&gt;,
where the union ranges over back edges&amp;nbsp;&lt;/i&gt;&lt;i&gt;y&lt;/i&gt; → &lt;i&gt;x&lt;/i&gt;&lt;i&gt;.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;blockquote class="figure"&gt;
&lt;div class="center"&gt;
&lt;div class="center"&gt;
&lt;hr size="2" width="80%" /&gt;
&lt;/div&gt;
&lt;pre class="prettyprint"&gt;
def dfs_forward(x):
  assert status[x] == unseen
  status[x] = seen
  for y in succ[x]:
    if status[y] == unseen:
      dfs_forward(y)
    elif status[y] == seen:
      backpred[y] += [x]
  for y in backpred[x]:
    dfs_backward(y, x)
  status[x] = done
&lt;/pre&gt;
&lt;pre class="prettyprint"&gt;def dfs_backward(y, z):
  y = find(y)
  if inner[y] != -1 or y == z:
    return
  if status[y] != done:
    print ’NOT reducible!’
    exit(1)
  inner[y] = z
  union(y, z)
  for x in pred[y]:
    dfs_backward(x, z)
&lt;/pre&gt;
&lt;div class="caption"&gt;
&lt;table cellpadding="0" cellspacing="6"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td align="left" valign="top"&gt;Figure 2: finding loops in reducible flowgraphs&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;a href="http://www.blogger.com/post-edit.g?blogID=5829875&amp;amp;postID=4676498439562574888" name="fig:red-algo"&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;div class="center"&gt;
&lt;hr size="2" width="80%" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
Tarjan&amp;nbsp;[4] described an
algorithm for recognizing reducible flowgraphs.
Ramalingam&amp;nbsp;[3] presents a
modified version that identifies the loop forest.
(Tarjan&amp;nbsp;[4] says that Ullman discovered
independently the same algorithm, although he didn’t publish it.
Ramalingam&amp;nbsp;[3] doesn’t say that he presents
a modified algorithm. Perhaps the modification is folklore?) The
core of &lt;a href="http://radu.ucd.ie/temp/blog/reducible-loops0.py"&gt;a Python implementation&lt;/a&gt; appears in Figure&amp;nbsp;2.
After executing &lt;code&gt;&lt;i&gt;dfs_forward&lt;/i&gt;&lt;/code&gt;&lt;code&gt;(0)&lt;/code&gt; we
have&amp;nbsp;&lt;code&gt;&lt;i&gt;x&lt;/i&gt;&lt;/code&gt;&lt;code&gt;==&lt;/code&gt;&lt;code&gt;&lt;i&gt;inner&lt;/i&gt;&lt;/code&gt;&lt;code&gt;[&lt;/code&gt;&lt;code&gt;&lt;i&gt;y&lt;/i&gt;&lt;/code&gt;&lt;code&gt;]&lt;/code&gt; when &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt; ⊃ &lt;i&gt;L&lt;/i&gt;&lt;sub&gt;&lt;i&gt;y&lt;/i&gt;&lt;/sub&gt; and
there’s no other loop in between. In other words, the
array&amp;nbsp;&lt;code&gt;&lt;i&gt;inner&lt;/i&gt;&lt;/code&gt; contains the parent pointers of
the loop forest. The array&amp;nbsp;&lt;code&gt;&lt;i&gt;succ&lt;/i&gt;&lt;/code&gt; represents the
flowgraph through adjacency lists; the array&amp;nbsp;&lt;code&gt;&lt;i&gt;pred&lt;/i&gt;&lt;/code&gt;
represents the reversed graph through adjacency lists. The
functions &lt;code&gt;&lt;i&gt;union&lt;/i&gt;&lt;/code&gt; and &lt;code&gt;&lt;i&gt;find&lt;/i&gt;&lt;/code&gt; are the
standard &lt;span style="font-variant: small-caps;"&gt;union-find&lt;/span&gt; with the added trick that
&lt;code&gt;&lt;i&gt;find&lt;/i&gt;&lt;/code&gt;&lt;code&gt;(&lt;/code&gt;&lt;code&gt;&lt;i&gt;x&lt;/i&gt;&lt;/code&gt;&lt;code&gt;)&lt;/code&gt; is guaranteed to return the&amp;nbsp;&lt;code&gt;&lt;i&gt;z&lt;/i&gt;&lt;/code&gt;
in the last call &lt;code&gt;&lt;i&gt;union&lt;/i&gt;&lt;/code&gt;&lt;code&gt;(&lt;/code&gt;&lt;code&gt;&lt;i&gt;y&lt;/i&gt;&lt;/code&gt;&lt;code&gt;,&amp;nbsp;&lt;/code&gt;&lt;code&gt;&lt;i&gt;z&lt;/i&gt;&lt;/code&gt;&lt;code&gt;)&lt;/code&gt; that involved the set
to which &lt;code&gt;&lt;i&gt;x&lt;/i&gt;&lt;/code&gt; now belongs. (Figuring out a nice way to
implement this trick is not hard, but fun.)&lt;br /&gt;
&lt;div class="theorem"&gt;
&lt;br /&gt;
&lt;b&gt;Remark&amp;nbsp;1&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;
The recursive implementation looks nice but it tends to crash
the stack, especially in Python, which has a rather low default
recursion limit (1000 on my computer).
&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
It is hopefully not too hard to see why this algorithm works
after all those lemmas and theorems.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;More to come.&lt;/b&gt;&amp;nbsp;&amp;nbsp; I plan three more posts: (1) finding
loops in graphs that are not reducible, (2) making graphs
reducible, and (3) summary of advanced results.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt; &lt;br /&gt;
&lt;h2 class="section"&gt;




&lt;/h2&gt;
&lt;dl class="thebibliography"&gt;
&lt;dt class="dt-thebibliography"&gt;
&lt;span style="color: purple;"&gt;[1]&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="dd-thebibliography"&gt;Mattew&amp;nbsp;S. Hecht and Jeffrey&amp;nbsp;D. Ullman.
Flow graph reducibility.
1972.&lt;br /&gt;
&lt;/dd&gt;
&lt;dt class="dt-thebibliography"&gt;&lt;span style="color: purple;"&gt;[2]&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="dd-thebibliography"&gt;Mattew&amp;nbsp;S. Hecht and Jeffrey&amp;nbsp;D. Ullman.
Characterizations of reducible flow graphs.
1974.&lt;br /&gt;
&lt;/dd&gt;
&lt;dt class="dt-thebibliography"&gt;&lt;span style="color: purple;"&gt;[3]&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="dd-thebibliography"&gt;Ganesan Ramalingam.
Identifying loops in almost linear time.
1999.&lt;br /&gt;
&lt;/dd&gt;
&lt;dt class="dt-thebibliography"&gt;&lt;span style="color: purple;"&gt;[4]&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="dd-thebibliography"&gt;Robert Tarjan.
Testing flow graph reducibility.
1974.&lt;br /&gt;
&lt;/dd&gt;&lt;/dl&gt;
&lt;br /&gt;
&lt;b&gt;Thanks&lt;/b&gt;&amp;nbsp;&amp;nbsp; to Claudia Grigore for feedback.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-4676498439562574888?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/P8LmA_hCwdw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/4676498439562574888/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/10/dtfloatleftclearleft-summary-of-some.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4676498439562574888?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4676498439562574888?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/P8LmA_hCwdw/dtfloatleftclearleft-summary-of-some.html" title="Reducible Flowgraphs 0" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_byUC16gzOKM/StiJBiU3FkI/AAAAAAAABsw/gm03Kql9nGM/s72-c/reducible000.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/10/dtfloatleftclearleft-summary-of-some.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMNQXo8fSp7ImA9WxNWFkw.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-7804213333074351486</id><published>2009-10-15T15:10:00.005+03:00</published><updated>2009-10-15T17:54:50.475+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-15T17:54:50.475+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><title>Time, learning, teaching, markup</title><content type="html">&lt;!--CUT DEF section 1 --&gt;&lt;P&gt;
&lt;I&gt;A rant about blog-writing technology.&lt;/I&gt;&lt;/P&gt;&lt;P&gt;This term I am not teaching so that I can focus my energies on
writing a thesis. Instead, I found other creative ways of wasting
time. I have recently succumbed to peer-pressure and started
using Facebook and Twitter. I am also writing blog posts.&lt;/P&gt;&lt;P&gt;I realized recently that my knowledge about reducible flowgraphs
is shallow. Normally I&amp;#X2019;d go and read about them from a textbook
or some old articles and perhaps even do a few exercises. This
time I decided to apply an advice I heard often: &amp;#X201C;The best
way to learn a subject is to teach it.&amp;#X201D; Since I don&amp;#X2019;t teach,
the next best thing is to write a blog post about it. (That&amp;#X2019;s
not entirely true: Even if I would teach a blog post would be
a better option, because I&amp;#X2019;m usually either demonstrating and
have little say on the content, or I&amp;#X2019;m in charge of a course on
a subject like &lt;I&gt;Unix programming&lt;/I&gt; &amp;#X2014; good luck with fitting
graph theory in there.)&lt;/P&gt;&lt;P&gt;The obvious question is: Why is this post not about reducible
flowgraphs and instead it rants about an inexistent post about
reducible flowgraph? OK, perhaps phrased like that it isn&amp;#X2019;t
quite &amp;#X2018;obvious&amp;#X2019;. Maybe this works better: Get to the point!&lt;/P&gt;&lt;P&gt;Well, I&amp;#X2019;m technology frustrated. The mechanics of writing and
publishing should take an insignificant amount of time compared
to the time it takes to produce the content. Alas, that&amp;#X2019;s not
the case when you want to convey information using:
&lt;/P&gt;&lt;OL CLASS="enumerate" type=1&gt;&lt;LI CLASS="li-enumerate"&gt;
text
&lt;/LI&gt;&lt;LI CLASS="li-enumerate"&gt;drawings
&lt;/LI&gt;&lt;LI CLASS="li-enumerate"&gt;code (in a programming language)
&lt;/LI&gt;&lt;LI CLASS="li-enumerate"&gt;(math) formulas
&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Let&amp;#X2019;s see what&amp;#X2019;s available. (La)TeX is very good for text and
formulas. You just go and write your text. A new paragraph
is achieved by 2&amp;#XA0;enter keys, marking up a block of text with
italics takes 5&amp;#XA0;extra characters, inserting a link takes 9&amp;#XA0;extra
characters. For formulas, it is superb: I can typeset &lt;I&gt;a&lt;/I&gt;&lt;SUB&gt;&lt;I&gt;b&lt;/I&gt;&lt;/SUB&gt; with
5&amp;#XA0;keys, including the 2&amp;#XA0;delimiters. (If you think I&amp;#X2019;m crazy to
count keys, wait until I tell you how many you need in the xML
family of languages.) For drawings (La)TeX is again very good
if you use the TiKZ package. Describing pictures in that language
is so cool that I often fantasize about using it to introduce
kids to programming. For code, the LaTeX(-only) package &lt;B&gt;listings&lt;/B&gt; does a decent job: You have to bracket the piece
of code with the right environment (34&amp;#XA0;keys), but sometimes
you need to configure it to get nice results.&lt;/P&gt;&lt;P&gt;However, there is a big problem with LaTeX: browsers don&amp;#X2019;t know
how to render it. Browsers know how to render xML: HTML, XML with
style-sheets, MathML, SVG, and so on. Unfortunately, writing in
these languages is a nightmare because they were designed to
be easily consumed and produced by programs, not by people. Of
course, you may use an editor that hides the details, but there
are two problems with that approach. First, I know of no good
editor that handles all those four types of content. Second,
switching between keyboard and mouse takes time and disrupts
focus so wysiwyg editors are out of the question for me. The
corollary to that is that what I want is a &lt;I&gt;language&lt;/I&gt; that
lets me type easily the content. After that is available, fancy
editors can bring minor improvements.&lt;/P&gt;&lt;P&gt;But let me be more explicit about why using xML is horrible.
For text it is fairly OK. A new paragraph is achieved by a
minimum of 3&amp;#XA0;keys (or 7&amp;#XA0;keys if you want proper bracketing
of tags) but you usually type the 2&amp;#XA0;extra enters anyway to
have the paragraphs nicely layed out while editing. Marking up
a block of text with italics takes 7&amp;#XA0;extra characters.
Inserting a link takes 14&amp;#XA0;characters (5&amp;#XA0;more than for LaTeX,
which is ironic considering that when people think HTML they
think links). But it gets worse. The xML way to typeset
&lt;I&gt;a&lt;/I&gt;&lt;SUB&gt;&lt;I&gt;b&lt;/I&gt;&lt;/SUB&gt; is to use MathML and it takes&amp;#X2026; 89&amp;#XA0;characters!
(Plus, locally the file &lt;I&gt;must&lt;/I&gt; have the extension &lt;TT&gt;xml&lt;/TT&gt;
so I&amp;#X2019;m not sure it will work on Blogger.) Call me crazy,
but I&amp;#X2019;m not willing to trade 5&amp;#XA0;characters for 89&amp;#XA0;characters
no matter how better structured and more explicit the
latter is. For drawings there&amp;#X2019;s something called SVG,
which is similarly verbose, although perhaps not quite
as bad when compared to TiKZ (or metapost). For typesetting
code the xML solution is actually quite good: You
just put the code in the proper environment (31&amp;#XA0;keys)
and then you let a &lt;A HREF="http://google-code-prettify.googlecode.com/svn/trunk/README.html"&gt;script&lt;/A&gt;
do its job. I never saw it fail (although the implementation
is quite hackish).&lt;/P&gt;&lt;P&gt;There is of course the option of writing LaTeX and converting
that to xML. There are a few tools around to do just that. The
best, in my opinion, is &lt;A HREF="http://hevea.inria.fr"&gt;HeVeA&lt;/A&gt;.
It handles text perfectly. For TiKZ drawings you can add an
environment (again, around 30&amp;#XA0;keys) and it will make PNGs out of
those. Cool. For formulas it uses plain HTML (no MathML) so the
result works on older browsers but looks uglier than it could on
newer ones. (MathML support is experimental, and it doesn&amp;#X2019;t work
on my files.) You also have the option of transforming selected
formulas to images (just like you do with TiKZ pictures). This
makes sense if the formulas are complicated, in which case the
HTML-only rendering is likely to suck. For code, HeVeA has some
built-in special handling of the &lt;B&gt;listings&lt;/B&gt; package, which
produces results that I find quite ugly. HeVeA is almost ideal,
except it is hard to customize, even though it&amp;#X2019;s supposed to be
easy. For example, I want to translate the &lt;TT&gt;lstlisting&lt;/TT&gt; LaTeX
environment into a &lt;TT&gt;pre&lt;/TT&gt; block with a certain class and let
the script I mentioned do the syntax highlight. Why? It looks
better and it is backed by Google, meaning that it&amp;#X2019;s likely to be
more up-to-date than the internals of HeVeA. (HeVea has one &lt;I&gt;great&lt;/I&gt; developer, but he is still &lt;B&gt;one&lt;/B&gt;.) This customization
seems to require changing the OCaml code of HeVeA and that is
&lt;I&gt;not&lt;/I&gt; easy. I also want to change some uses of &lt;TT&gt;df&lt;/TT&gt; and
&lt;TT&gt;dd&lt;/TT&gt; tags and some purple (yuck!) things it generates but,
again, I need to spend some time to figure out how to do it: It&amp;#X2019;s
not easy. Of course, one solution for code is to turn it into
images: That would look OK (though no colors) but it precludes
readers to do copy and paste.&lt;/P&gt;&lt;P&gt;Another LaTeX to HTML converter is 
&lt;A HREF="http://lucatrevisan.wordpress.com/latex-to-wordpress/"&gt;latex2wp&lt;/A&gt;.
It handles text OK. It handles formulas by exploiting Wordpress
support, which makes it unusable on Blogger or other sites
(unless you are willing to piss off Wordpress for using their
resources to drive traffic to a competitor). This brings up
another point about HeVeA: If you are a Wordpress user it
makes sense to exploit their support for LaTeX. But, good luck
with convincing HeVeA to translate &lt;TT&gt;$a_b$&lt;/TT&gt; into 
&lt;TT&gt;$latex a_b$&lt;/TT&gt;. Finally, if I remember correctly,
latex2wp has no support for drawings or code.&lt;/P&gt;&lt;P&gt;HeVeA is a successor written by &lt;A HREF="http://moscova.inria.fr/~maranget/"&gt;Luc Maranget&lt;/A&gt; of a convertor written by the &lt;A HREF="http://pauillac.inria.fr/~xleroy/"&gt;Xavier Leroy&lt;/A&gt;. (And, if you don&amp;#X2019;t know who the latter is,
then you are not a computer scientist.) Xavier remarked that
an ideal solution for writing technical documentation would be
to design a new language that is easily convertible to both
LaTeX (to produce printable PDFs) and xML (for easy viewing in
browsers), but practically most people writing technical stuff
would prefer to use LaTeX and will be reluctant to learn a 
new language. That was before Wikipedia: Its markup language 
&lt;I&gt;is&lt;/I&gt; convertible to both HTML and PDF (through LaTeX?).
Alas, I think their tools are not publicly available. (If
they are and are easy to use on Linux I want to know!) Supposing
that the tools are available, there is a bigger problem:
While text, code, and math are supported, drawings have to
be written in the verbose SVG.&lt;/P&gt;&lt;P&gt;That was the motivation. Now comes the challenge.&lt;/P&gt;&lt;P&gt;&lt;I&gt;Design a concise language for describing documents with
text, drawings, code, and formulas. Make it feel familiar
by having syntax similar to existing languages. Implement
translations to LaTeX and xML. Make sure the implementation
is &lt;/I&gt;&lt;I&gt;&lt;B&gt;very&lt;/B&gt;&lt;/I&gt;&lt;I&gt; easy to customize. (Keep in mind the failings
of HeVeA in this area.) The usage of the tool should be
as easy as &lt;/I&gt;&lt;I&gt;&lt;TT&gt;tool -tex docname&lt;/TT&gt;&lt;/I&gt;&lt;I&gt;.&lt;/I&gt;&lt;/P&gt;&lt;P&gt;Now, why didn&amp;#X2019;t I think of using that as a project when
I was teaching?&lt;/P&gt;&lt;P&gt;PS: In case you wonder, I wrote this in LaTeX and used HeVeA.&lt;/P&gt;&lt;!--CUT END --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-7804213333074351486?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/r5D4M4JvG4E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/7804213333074351486/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/10/time-learning-teaching-markup.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7804213333074351486?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7804213333074351486?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/r5D4M4JvG4E/time-learning-teaching-markup.html" title="Time, learning, teaching, markup" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/10/time-learning-teaching-markup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUGQX86eCp7ImA9WxNXEUo.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-4651967213641577227</id><published>2009-09-29T01:31:00.001+03:00</published><updated>2009-09-29T01:33:40.110+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-29T01:33:40.110+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><title>Ambiguity in CLOPS</title><content type="html">&lt;p&gt;&lt;i&gt;A problem we hit while working on CLOPS. We know
a good solution but it makes a nice puzzle.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Problem.&lt;/b&gt; A digraph has letters on edges, so there is a word
corresponding to each &lt;a href="http://en.wikipedia.org/wiki/Glossary_of_graph_theory"&gt;walk&lt;/a&gt;. Given two nodes&amp;nbsp;&lt;i&gt;m&lt;/i&gt; and &lt;i&gt;n&lt;/i&gt;, are there two distinct walks
&lt;i&gt;m&lt;/i&gt; ↝ &lt;i&gt;n&lt;/i&gt; that have the same corresponding word?&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Examples.&lt;/b&gt; We are looking at walks from &lt;span style="color: blue;"&gt;blue&lt;/span&gt;
to &lt;span style="color: red;"&gt;red&lt;/span&gt;.&lt;br /&gt;
In the graph&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/_byUC16gzOKM/SsE4RzntN0I/AAAAAAAABsI/7QCurhI3NU8/s1600-h/ambig001.png" imageanchor="1"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_byUC16gzOKM/SsE4RzntN0I/AAAAAAAABsI/7QCurhI3NU8/s320/ambig001.png" /&gt;&lt;/a&gt;&lt;br /&gt;
there are no two distinct walks with the same word.&lt;br /&gt;
&lt;br /&gt;
If the graph&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/_byUC16gzOKM/SsE4t1rLiDI/AAAAAAAABsQ/aS2THepXX-o/s1600-h/ambig002.png" imageanchor="1"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_byUC16gzOKM/SsE4t1rLiDI/AAAAAAAABsQ/aS2THepXX-o/s320/ambig002.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
has the letter &lt;i&gt;x&lt;/i&gt; on all edges then there are two distinct walks
corresponding to the word &lt;i&gt;xxxxxxxxxxxxxxxxx&lt;/i&gt; (length 17).
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Comment.&lt;/b&gt; This problem amounts to finding whether a
CLOPS input file, which is a regular grammar for what can go
on the command line of a program, is ambiguous.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-4651967213641577227?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/MyVJUuhUrx8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/4651967213641577227/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/ambiguity-in-clops.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4651967213641577227?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4651967213641577227?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/MyVJUuhUrx8/ambiguity-in-clops.html" title="Ambiguity in CLOPS" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_byUC16gzOKM/SsE4RzntN0I/AAAAAAAABsI/7QCurhI3NU8/s72-c/ambig001.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/ambiguity-in-clops.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcAQ3w7cCp7ImA9WxNXEEg.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-1040130761613083282</id><published>2009-09-27T16:23:00.002+03:00</published><updated>2009-09-27T16:27:22.208+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-27T16:27:22.208+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="random" /><title>My most beautiful result</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_byUC16gzOKM/Sr9oBvVCytI/AAAAAAAABsA/wIoLUbsgwPo/s1600-h/vlad_alexandru-2383.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://2.bp.blogspot.com/_byUC16gzOKM/Sr9oBvVCytI/AAAAAAAABsA/wIoLUbsgwPo/s400/vlad_alexandru-2383.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5386138058452290258" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-1040130761613083282?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/dHBKaLWBamk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/1040130761613083282/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/my-most-beautiful-result.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/1040130761613083282?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/1040130761613083282?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/dHBKaLWBamk/my-most-beautiful-result.html" title="My most beautiful result" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_byUC16gzOKM/Sr9oBvVCytI/AAAAAAAABsA/wIoLUbsgwPo/s72-c/vlad_alexandru-2383.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/my-most-beautiful-result.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBRXY-fip7ImA9WxNXEEg.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-381164596099940426</id><published>2009-09-27T14:15:00.001+03:00</published><updated>2009-09-27T14:15:54.856+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-27T14:15:54.856+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><title>Celebrity gossip and physics mix well</title><content type="html">&lt;p&gt;&lt;i&gt;A short review of Gina.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;I have recently finished reading 
&lt;a href="http://gilkalai.wordpress.com/2009/06/23/my-book-gina-says-adventures-in-the-blogsphere-string-war/"&gt;
&lt;i&gt;Gina says&lt;/i&gt;&lt;/a&gt; a (free) book by Gil Kalai. My opinion: not
light bedtime reading! Indeed, I started reading at 11pm and
finished around 3am... because I &lt;i&gt;couldn't&lt;/i&gt; stop. But
I was joking: It &lt;i&gt;is&lt;/i&gt; fairly light reading. It is
also quite depressing and should be hidden from high-school
students trying to choose a career path. (Yes, I'm joking
again: I don't really think hiding data is a good way of
attracting kids to science.) On the other hand, I think
it has great potential in popularizing some nice mathematical
results.&lt;/p&gt;

&lt;p&gt;If you like gossip about celebrities you will certainly love this book!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-381164596099940426?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/zCAruhlaDOQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/381164596099940426/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/celebrity-gossip-and-physics-mix-well.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/381164596099940426?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/381164596099940426?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/zCAruhlaDOQ/celebrity-gossip-and-physics-mix-well.html" title="Celebrity gossip and physics mix well" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/celebrity-gossip-and-physics-mix-well.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QCRXs5cCp7ImA9WxNXEU4.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-4891375753720030899</id><published>2009-09-27T13:13:00.001+03:00</published><updated>2009-09-28T13:56:04.528+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-28T13:56:04.528+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><category scheme="http://www.blogger.com/atom/ns#" term="teaching" /><title>There is no segfault: sort of an answer</title><content type="html">&lt;p&gt;[&lt;b&gt;edit:&lt;/b&gt; updated link to dead cat]&lt;/p&gt;

&lt;I&gt;My attempt at answering my own puzzle.&lt;/I&gt;&lt;/P&gt;&lt;P&gt;But first I should acknowledge that the title comes from the
song &lt;A HREF="http://lovevoid.free.fr/hdw/disco2.html"&gt;&lt;I&gt;There is no dead cat&lt;/I&gt;&lt;/A&gt;. Second, I should note that my
presentation of what induction means is unnecessarily redundant:
The base case is included in the induction step given that there
is a smallest element. (And, yes, that&amp;#X2019;s my strange sense of humor.)&lt;/P&gt;&lt;P&gt;OK, now the challenge: Under which conditions can we conclude
&lt;I&gt;P&lt;/I&gt;(&lt;I&gt;n&lt;/I&gt;) for all &lt;I&gt;n&lt;/I&gt;&amp;#X2208; &lt;I&gt;S&lt;/I&gt; given that &amp;#X2227;&lt;SUB&gt;&lt;I&gt;k&lt;/I&gt;&amp;#X2260; &lt;I&gt;n&lt;/I&gt;&lt;/SUB&gt; &lt;I&gt;P&lt;/I&gt;(&lt;I&gt;k&lt;/I&gt;)
implies &lt;I&gt;P&lt;/I&gt;(&lt;I&gt;n&lt;/I&gt;) for all &lt;I&gt;n&lt;/I&gt;&amp;#X2208; &lt;I&gt;S&lt;/I&gt;? &lt;/P&gt;&lt;P&gt;Read literally the question is not interesting: &amp;#X201C;Under which conditions
&lt;I&gt;p&lt;/I&gt; implies &lt;I&gt;q&lt;/I&gt;?&amp;#X201D; has the obvious and useless answer &amp;#X201C;&lt;I&gt;q&lt;/I&gt;, since 
&lt;I&gt;p&lt;/I&gt; &amp;#X2227; &lt;I&gt;q&lt;/I&gt; implies &lt;I&gt;q&lt;/I&gt;.&amp;#X201D;
So, why is this an interesting question?
Because we reduce the former to the later whenever &lt;I&gt;P&lt;/I&gt;(&lt;I&gt;n&lt;/I&gt;) has the form
&amp;#X201C;the piece of code&amp;#XA0;&lt;I&gt;n&lt;/I&gt; is OK,&amp;#X201D; for some value of OK, one example
being &amp;#X201C;does not dereference a null pointer.&amp;#X201D; Another reason that
makes the question interesting to me is that I &lt;I&gt;feel&lt;/I&gt; we
are justified in looking at code one function at a time to
assess whether it &amp;#X201C;goes wrong&amp;#X201D; but I don&amp;#X2019;t &lt;I&gt;know&lt;/I&gt; it,
because I never read or gave a coherent explanation: The matter
is always treated as &amp;#X201C;obvious&amp;#X201D; as far as I can tell. Also,
I formulated the problem in more general terms so that the
answer has a chance of being useful in a different setting than
program verification. Finally, I vaguely remembered reading
that modular reasoning about a system is a form of coinduction:
After reading a little about coinduction I&amp;#X2019;m not so sure anymore.
(I looked at &lt;A HREF="http://www.cs.chalmers.se/Cs/Research/Logic/TypesSS05/Extra/bertot_sl2.pdf"&gt;slides introducing coinduction in Coq&lt;/A&gt; by Yves Bertot
and at blogs like &lt;A HREF="http://golem.ph.utexas.edu/category/2009/09/proof_by_coinduction.html"&gt;n-category&lt;/A&gt; and &lt;A HREF="http://blog.sigfpe.com/2006/04/mongruences.html"&gt;a neighborhood of infinity&lt;/A&gt;. Reading through &lt;A HREF="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.1418"&gt;this tutorial&lt;/A&gt; is slow.)&lt;/P&gt;&lt;P&gt;The intuitive reason why we can analyze program pieces one at
a time is that any counterexample is an execution that has
&lt;I&gt;one&lt;/I&gt; place where null is dereferenced. A bit more precise:
An &lt;I&gt;execution&lt;/I&gt; is a sequence of states. A &lt;I&gt;state&lt;/I&gt;
is a pointer to the next program statement to be executed plus
the content of the memory (that is, a map from variables to values).
The &lt;I&gt;wrong state&lt;/I&gt; is special. The assumption 
&amp;#X2227;&lt;SUB&gt;&lt;I&gt;k&lt;/I&gt; &amp;#X2260; &lt;I&gt;n&lt;/I&gt;&lt;/SUB&gt; &lt;I&gt;P&lt;/I&gt;(&lt;I&gt;k&lt;/I&gt;) amounts to &amp;#X201C;ignore executions that
go to the wrong state after executing a statement of a
module&amp;#XA0;&lt;I&gt;k&lt;/I&gt; &amp;#X2260; &lt;I&gt;n&lt;/I&gt;.&amp;#X201D;&lt;/P&gt;&lt;P&gt;&lt;I&gt;Problem.&lt;/I&gt; Can we use modular reasoning to put upper bounds
(other than zero) on the number of errors that can occur in an
execution? For example, is it possible even in principle to conclude
that &amp;#X201C;this program may break its contract at most three times
during its execution&amp;#X201D; without doing a global analysis? I suspect
not.&lt;/P&gt;&lt;P&gt;Is there a useful way to generalize the answer with &amp;#X201C;executions&amp;#X201D;?
Since &lt;A HREF="http://rgrig.blogspot.com/2009/09/good-companion.html"&gt;I&amp;#X2019;ve been reading&lt;/A&gt; about &lt;A HREF="http://en.wikipedia.org/wiki/Model_theory"&gt;model theory&lt;/A&gt; I&amp;#X2019;m inclined to view the program as a theory
whose models are its executions. In this language the trick
is that we can systematically explore &lt;I&gt;parts of a model&lt;/I&gt; where
a formula may not hold, assuming that in all other parts it does
hold.&lt;/P&gt;&lt;P&gt;For the record, I&amp;#X2019;m not satisfied with my answer.&lt;/P&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-4891375753720030899?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/P_-DTq57Los" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/4891375753720030899/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/there-is-no-segfault-sort-of-answer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4891375753720030899?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4891375753720030899?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/P_-DTq57Los/there-is-no-segfault-sort-of-answer.html" title="There is no segfault: sort of an answer" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/there-is-no-segfault-sort-of-answer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUCQnoyeCp7ImA9WxNQFEQ.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-623418241905007343</id><published>2009-09-21T03:50:00.000+03:00</published><updated>2009-09-21T03:51:03.490+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-21T03:51:03.490+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><category scheme="http://www.blogger.com/atom/ns#" term="teaching" /><title>There is no segfault</title><content type="html">&lt;p&gt;&lt;i&gt;A short puzzle related to induction.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;To prove that all elements of a set &lt;i&gt;S&lt;/i&gt; have a property
&lt;i&gt;P&lt;/i&gt; we can use induction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[&lt;i&gt;induction step&lt;/i&gt;] we show that the elements of &lt;i&gt;size&lt;/i&gt; &lt;i&gt;s&lt;/i&gt; have the
property &lt;i&gt;P&lt;/i&gt;, assuming that all elements of size &amp;lt;&lt;i&gt;s&lt;/i&gt;
have it, and&lt;/li&gt;
&lt;li&gt;[&lt;i&gt;base case&lt;/i&gt;] we show that the &lt;i&gt;smallest&lt;/i&gt; elements have the property &lt;i&gt;P&lt;/i&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if &lt;i&gt;S&lt;/i&gt; is the set of natural numbers and the size
of a natural number is itself, then we can prove that 
  2&amp;Sigma;&lt;sub&gt;&lt;i&gt;k&lt;/i&gt;&amp;le;&lt;i&gt;n&lt;/i&gt;&lt;/sub&gt;k=&lt;i&gt;n&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;+1)
by showing that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[&lt;i&gt;base case&lt;/i&gt;]
  2&amp;Sigma;&lt;sub&gt;&lt;i&gt;k&lt;/i&gt;&amp;le;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt;k=0, and&lt;/li&gt;
&lt;li&gt;[&lt;i&gt;induction step&lt;/i&gt;]
  2&amp;Sigma;&lt;sub&gt;&lt;i&gt;k&lt;/i&gt;&amp;lt;&lt;i&gt;n&lt;/i&gt;&lt;/sub&gt;k=&lt;i&gt;n&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;-1) &amp;rArr;
  2&amp;Sigma;&lt;sub&gt;&lt;i&gt;k&lt;/i&gt;&amp;le;&lt;i&gt;n&lt;/i&gt;&lt;/sub&gt;k=&lt;i&gt;n&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;+1)
&lt;/ul&gt;

&lt;p&gt;As another example, if &lt;i&gt;S&lt;/i&gt; is the set of (non-empty) binary trees in which
each node either is a leaf or has exactly two children then we can show
that the number of leafs is one more than the number of non-leafs by induction.
In this case the size is the number of nodes in the tree.
If we denote by &lt;i&gt;l&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;) the number of leafs in the tree &lt;i&gt;t&lt;/i&gt;
and by &lt;i&gt;k&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;) the number of non-leafs, then the statement
we want to prove is &lt;i&gt;l&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;)-&lt;i&gt;k&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;)=1 for all
trees &lt;i&gt;t&lt;/i&gt;. Induction says that it suffices to show:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[&lt;i&gt;base case&lt;/i&gt;] &lt;i&gt;l&lt;/i&gt;(&amp;bull;)-&lt;i&gt;k&lt;/i&gt;(&amp;bull;)=1, and&lt;/li&gt;
&lt;li&gt;[&lt;i&gt;induction step&lt;/i&gt;] 
  (&lt;i&gt;l&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;)-&lt;i&gt;k&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;)=1 &amp;and;
   &lt;i&gt;l&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;)-&lt;i&gt;k&lt;/i&gt;(&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;)=1) &amp;rArr;
  &lt;i&gt;l&lt;/i&gt;((&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;,&amp;bull;,&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;))-&lt;i&gt;k&lt;/i&gt;((&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;,&amp;bull;,&lt;i&gt;t&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;))=1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may want to take a moment to convince yourself (if you haven't
already) that the base case and the induction step 
are fairly easy to check for both examples above.&lt;/p&gt;

&lt;p&gt;But there is another type of induction! Suppose you have a program
&lt;i&gt;Q&lt;/i&gt; that is a set &lt;i&gt;S&lt;/i&gt; of functions and you want to prove the
following theorem: &lt;i&gt;Program Q will not dereference a null pointer&lt;/i&gt;.
One way to approach this task is to prove for each function that it will
not dereference a null pointer (&amp;quot;throw &lt;tt&gt;NullPointerException&lt;/tt&gt;&amp;quot;
in Java, segfault in C, etc.) assuming that &lt;i&gt;all the other&lt;/i&gt; functions
in the program do not dereference a null pointer.&lt;/p&gt;

&lt;p&gt;However, there is something troublesome about this. Until now
we had an order: We think about the first proof by induction as
first showing that an identity holds for &lt;i&gt;n&lt;/i&gt;=0 then for
&lt;i&gt;n&lt;/i&gt;=1 then for &lt;i&gt;n&lt;/i&gt;=2,... and whenever we get to proving
for some value we rely on what was proven &amp;quot;before&amp;quot;.
But the last proof enjoys no such property: We can happily have
a program made out of &lt;i&gt;n&lt;/i&gt; functions, each calling all the
&lt;i&gt;n&lt;/i&gt; functions. Let's put it differently. Say we have four
functions: &lt;i&gt;a&lt;/i&gt;, &lt;i&gt;b&lt;/i&gt;, &lt;i&gt;c&lt;/i&gt;, and &lt;i&gt;d&lt;/i&gt;. Is it
possible for &lt;i&gt;a&lt;/i&gt;, &lt;i&gt;b&lt;/i&gt;, and &lt;i&gt;c&lt;/i&gt; to be OK but &lt;i&gt;d&lt;/i&gt;
not? No, it isn't, because one of the proof obligations was to
show that &lt;i&gt;d&lt;/i&gt; is OK given that the others are. But... what's
stopping &lt;i&gt;c&lt;/i&gt; and &lt;i&gt;d&lt;/i&gt; to be &lt;i&gt;both&lt;/i&gt; &lt;b&gt;not&lt;/b&gt; OK?&lt;/p&gt;

&lt;p&gt;Still, I claim the proof is fine. Can you see why it works?
What are the general conditions under which such proofs work?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-623418241905007343?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/7KVOhotT8Vc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/623418241905007343/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/there-is-no-segfault.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/623418241905007343?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/623418241905007343?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/7KVOhotT8Vc/there-is-no-segfault.html" title="There is no segfault" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/there-is-no-segfault.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUENRnkzeip7ImA9WxNRGU4.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-2725546232941892759</id><published>2009-09-14T16:08:00.001+03:00</published><updated>2009-09-14T16:08:17.782+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-14T16:08:17.782+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="random" /><title>A Good Companion</title><content type="html">&lt;p&gt;&lt;i&gt;A short &amp;quot;review&amp;quot; for the
The Princeton Companion to Mathematics.&lt;/i&gt;&lt;/p&gt;

&lt;!--Begin Gowers Widget--&gt;&lt;table border=2 cellpadding=5&gt;&lt;tr&gt;&lt;td align=center&gt;&lt;table&gt;&lt;tr&gt;&lt;td align=center style="font: 10px arial;"&gt;&lt;a href=http://press.princeton.edu/titles/8350.html?utm_source=Network&amp;utm_medium=Widget&amp;utm_campaign=Title&gt;The Princeton Companion&lt;br&gt;to Mathematics&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=center&gt;&lt;img src=http://press.princeton.edu/widgets/w8350.png&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font: 10px arial;"&gt;&lt;a href=http://press.princeton.edu/chapters/gowers/gowers_V_10.pdf?utm_source=Network&amp;utm_medium=Widget&amp;utm_campaign=Chapter onClick="javascript: pageTracker._trackPageview('/chapters/gowers/gowers_V_10.pdf');"&gt;Sample Entry: Fermat's&lt;br&gt;Last Theorem&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font: 10px arial;"&gt;&lt;a href=http://press.princeton.edu/video/gowers.mp3?utm_source=Network&amp;utm_medium=Widget&amp;utm_campaign=Podcast onClick="javascript: pageTracker._trackPageview('/video/gowers.mp3'); "&gt;Podcast interview with&lt;br&gt;editor Timothy Gowers&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;!--End Gowers Widget--&gt;

&lt;p&gt;Saturday I found
&lt;a href="http://maps.google.com/maps?hl=en&amp;safe=off&amp;um=1&amp;ie=UTF-8&amp;q=hodges+figgis+dublin&amp;fb=1&amp;split=1&amp;gl=ie&amp;view=text&amp;latlng=1485283981616044960"&gt;
a bookshop that I like&lt;/a&gt;. It has four floors: basement (bargains), 
ground (fiction), first (humanistic subjects), second (scientific
subjects). This is contrast to the usual fiction and fiction bargains,
plus some nude pictures counting as &amp;quot;art&amp;quot;.&lt;/p&gt;

&lt;p&gt;I stayed on the second floor for five minutes before deciding
to buy &lt;i&gt;The Companion&lt;/i&gt;. It is remarkable that it is expensive:
80 euro. It is also remarkable that within those five minutes
two other people decided to buy it.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Compressed preface.&lt;/b&gt; The book leans towards examples
rather than formalism. The core is a set of chapters on
branches of mathematics that are being developed actively by
today's researchers, such as, arithmetic geometry, numerical
analysis, and theoretical computer science. Other parts
worth mentioning are the concept index (useful for when you are 
too ashamed to admit you are completely lost in someone's
argument) and the set of biographies of mathematicians.
I'll let the other goodies surprise you.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;My opinion after one hour.&lt;/b&gt; Contributors were chosen
by expertise and expository skill so I was surprised to not
see Knuth. I guess he's getting old and needs to finish &lt;i&gt;his&lt;/i&gt;
book. The typesetting uses Palatino fonts and is really well done.
(Even the annoyingly small parentheses that Terence Tao uses
have been fixed and now have the proper size. :p) OK, now
let's get to less trivial things! The book is awesome!
It's something I would have absolutely &lt;i&gt;loved&lt;/i&gt; to
have when I was in high-school and it's something that
I will use as a bed-time reading for a while. It is very
different in flavour from Knuth's books, though. It covers
a lot of breadth and intuition but does not go into depth.
That is intended, since in-depth study is fairly easy to
carry on now that most scientific articles are available online.
The big picture, however, can be acquired only by attending
conferences, and few are lucky enough to be able to do it.&lt;/p&gt;

&lt;p&gt;PS: It's a &amp;quot;review&amp;quot; and not a review because a
proper review is done &lt;i&gt;after&lt;/i&gt; you read the whole book.
That won't happen any time soon.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-2725546232941892759?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/V-5Uba3ClUQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/2725546232941892759/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/good-companion.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/2725546232941892759?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/2725546232941892759?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/V-5Uba3ClUQ/good-companion.html" title="A Good Companion" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/good-companion.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UBQH88fip7ImA9WxNRGU4.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-816342091259531499</id><published>2009-09-14T15:21:00.002+03:00</published><updated>2009-09-14T15:27:31.176+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-14T15:27:31.176+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="random" /><title>Facebook Politics</title><content type="html">&lt;p&gt;It's interesting how otherwise smart people get worked up
by irrational arguments, usually involving politics or religion.
A colleague of mine was flooding my Facebook recently with
basically this argument:&lt;/p&gt;

&lt;blockquote&gt;
Treaty T is bad because:
&lt;ul&gt;
&lt;li&gt;It is written by crooks in city F (F stands for &amp;quot;&lt;b&gt;f&lt;/b&gt;ar away&amp;quot;)&lt;/li&gt;
&lt;li&gt;It gives more power to people in city F and takes it away from
  people in city C (C stands for &amp;quot;&lt;b&gt;c&lt;/b&gt;lose by&amp;quot; or
  &amp;quot;&lt;b&gt;c&lt;/b&gt;apital&amp;quot;, your choice). Voters know more about
  the people in city C.
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, if you didn't spot yet why this is insanely illogic, let me help.&lt;/p&gt;

&lt;p&gt;First, let us make clear the assumptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;People in city F are crooks.&lt;/li&gt;
&lt;li&gt;We (voters) don't know people in city F well enough for an informed vote but we do know people in city C well enough for an informed vote.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This begs the question:&lt;/p&gt;

&lt;blockquote&gt;
How do you know some people are &amp;quot;crooks&amp;quot; if you don't know
enough about them?
&lt;/blockquote&gt;

&lt;p&gt;The assumptions are inconsistent. That should be enough to make
any logician puke. But let's assume only one of them is false.&lt;/p&gt;

&lt;p&gt;So, first we assume that people in city F are crooks. So what?
It doesn't follow in any way that treaty T is bad. A treaty is good
or bad depending on what it contains, not depending on who wrote it.&lt;/p&gt;

&lt;p&gt;Now let's assume they may be crooks but we don't know for sure
because we don't know enough about them. How is that an argument
against the treaty T?? Since people get their information through
television, radio, and Internet the &lt;b&gt;distance&lt;/b&gt; is completely
irrelevant. Of course, it may be that media (who &lt;i&gt;pushes&lt;/i&gt;
information onto the sheepish voters) makes a bad choice in selecting
what is important. That may very well be, but that's an argument
against the media, not against the treaty. If the media would suddenly
decide to only talk about the private life of Paris Hilton, does that
mean that we can't vote for anyone else because we don't know enough
about them? No, it means that the media is fucked up.&lt;/p&gt;

&lt;p&gt;To make it clear, I am &lt;i&gt;not&lt;/i&gt; arguing &lt;i&gt;for&lt;/i&gt; the treaty
for the simple reason that I did not read it. Before I read it I do
not feel competent enough to preach to others how they should vote.
However, I would prefer to see a little less fanaticism and a little
more reason in my &amp;quot;inbox&amp;quot;.&lt;/p&gt;

&lt;p&gt;PS: Since I spent enough time on this spamming issue, be advised
I will not read any comment on this post. Feel free to comment 
if you need to vent.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-816342091259531499?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/OPCOR6En4uc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/816342091259531499/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/facebook-politics.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/816342091259531499?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/816342091259531499?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/OPCOR6En4uc/facebook-politics.html" title="Facebook Politics" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/facebook-politics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYHSX45eCp7ImA9WxNRFEQ.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-1322209391471120921</id><published>2009-09-09T12:54:00.001+03:00</published><updated>2009-09-09T12:55:38.020+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-09T12:55:38.020+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="random" /><title>carnival 56</title><content type="html">It seems the Carnival of Mathematics is trying to get back to life. Here's my modest help: &lt;a href="http://stochastix.wordpress.com/2009/08/27/carnival-of-mathematics-56/"&gt;a link&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-1322209391471120921?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/HyhC62oa1ME" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/1322209391471120921/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/09/carnival-56.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/1322209391471120921?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/1322209391471120921?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/HyhC62oa1ME/carnival-56.html" title="carnival 56" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/09/carnival-56.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIFQH09eCp7ImA9WxNTFkU.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-4147546172794795385</id><published>2009-08-19T16:24:00.002+03:00</published><updated>2009-08-19T16:28:31.360+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-19T16:28:31.360+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Java is fast, they say on ##java</title><content type="html">&lt;p&gt;&lt;i&gt;Which class from the Java runtime environment you
should use when you need a stack.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;The package &lt;code class="prettyprint"&gt;java.util&lt;/code&gt;
contains a few classes suitable for pushing, poping, and
peeking in stack style.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;push&lt;/th&gt;&lt;th&gt;pop&lt;/th&gt;&lt;th&gt;peek&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Stack&lt;/th&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.push(e)&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.pop()&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.peek()&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;ArrayList&lt;/th&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.add(e)&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.remove(s.size()-1)&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.get(s.size()-1)&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;LinkedList&lt;/th&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.addFirst(e)&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.removeFirst()&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.peekFirst()&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;ArrayDeque&lt;/th&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.addFirst(e)&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.removeFirst()&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&lt;code class="prettyprint"&gt;s.peekFirst()&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;All but &lt;code class="prettyprint"&gt;ArrayDeque&lt;/code&gt; implement
the widely used and known interface &lt;code class="prettyprint"&gt;List&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's see how efficient are the implementations in JRE6,
in relative units.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;time&lt;/th&gt;&lt;th&gt;space&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Stack&lt;/th&gt;&lt;td&gt;x2.09&lt;/td&gt;&lt;td&gt;x1.6&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;ArrayList&lt;/th&gt;&lt;td&gt;x1.15&lt;/td&gt;&lt;td&gt;x1.3&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;LinkedList&lt;/th&gt;&lt;td&gt;x1.27&lt;/td&gt;&lt;td&gt;x3.02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;ArrayDeque&lt;/th&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Yep, &lt;code class="prettyprint"&gt;ArrayDeque&lt;/code&gt; is best
both in terms of time and speed. If you need a subtype of
&lt;code class="prettyprint"&gt;List&lt;/code&gt; then go with
&lt;code class="prettyprint"&gt;ArrayList&lt;/code&gt;. If you want
to eat memory like crazy for no good reason then try
&lt;code class="prettyprint"&gt;LinkedList&lt;/code&gt;. And if you
have a thing for names like &lt;code class="prettyprint"&gt;Vector&lt;/code&gt;
(which &lt;code class="prettyprint"&gt;Stack&lt;/code&gt; extends) then,
well, go for it. Just don't say I told you to use it.
Finally, if you are a speed junkie and you know in advance the
maximum possible size of the stack, then you can implement
your own for a x1.2 speed-up (compared to &lt;code class="prettyprint"&gt;ArrayDeque&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Just for the record, a basic stack operation for &lt;code
class="prettyprint"&gt;ArrayDeque&lt;/code&gt; takes about 15ns on my 
old laptop.
&lt;/p&gt;

&lt;p&gt;Good bye, and stay tuned for the next useless microbenchmark
results.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-4147546172794795385?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/yT-2tP2DZ-8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/4147546172794795385/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/08/java-is-fast-they-say-on-java.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4147546172794795385?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/4147546172794795385?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/yT-2tP2DZ-8/java-is-fast-they-say-on-java.html" title="Java is fast, they say on ##java" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/08/java-is-fast-they-say-on-java.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcAQXw7eSp7ImA9WxJVFk8.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-5703382948845577081</id><published>2009-07-03T15:00:00.003+03:00</published><updated>2009-07-03T15:27:20.201+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-03T15:27:20.201+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Type Inference in C++</title><content type="html">&lt;p&gt;&lt;i&gt;A short note to let you know about a long-missed C++ feature you can now use.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Since gcc 4.4 (21 April 2009) you can now skip giving the types of variables that you initialize. Do you remember the old macro&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
#define foreach(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
&lt;/pre&gt;

&lt;p&gt;? Well, you can now write&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
#define foreach(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
&lt;/pre&gt;

&lt;p&gt;In fact, since the definition is shorter now, you might even consider ditching the macro altogether. After all, macros cause bugs that take much time to track down.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Edit:&lt;/b&gt; Oh, yeah. I forgot to mention that &lt;code class="prettyprint"&gt;auto&lt;/code&gt; will be a standard C++ feature, while &lt;code class="prettyprint"&gt;typeof&lt;/code&gt; is a GNU extension.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-5703382948845577081?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/o668qTIkGRk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/5703382948845577081/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/07/type-inference-in-c.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5703382948845577081?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5703382948845577081?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/o668qTIkGRk/type-inference-in-c.html" title="Type Inference in C++" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/07/type-inference-in-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEMRngzcCp7ImA9WxJVFEg.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-6040608304401478461</id><published>2009-07-01T17:28:00.001+03:00</published><updated>2009-07-01T17:31:27.688+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-01T17:31:27.688+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Type Inference in Java, for Generics</title><content type="html">&lt;p&gt;&lt;i&gt;An unexpected failure of the Java compiler. Or is it a failure
of the Java type system?&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Java programmers write repetitive code like&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
HashMap&amp;lt;String, Integer&amp;gt; foo = new HashMap&amp;lt;String, Integer&amp;gt;();
&lt;/pre&gt;

&lt;p&gt;all the time. Those who seek beauty in their code may choose
to use the Google collections library and write instead&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
HashMap&amp;lt;String, Integer&amp;gt; foo = Maps.newHashMap();
&lt;/pre&gt;

&lt;p&gt;Constructors and static methods interact in very different ways
with generics. If you say &lt;code class="prettyprint"&gt;new Foo()&lt;/code&gt;
you instantiate a raw type, which is quite different from a what
you get by saying &lt;code class="prettyprint"&gt;new Foo&amp;lt;Bar&amp;gt;()&lt;/code&gt;.
On the other hand, static methods are the beneficiaries of a little
bit of type inference, as specified by sections
&lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.2.7"&gt;15.12.2.7&lt;/a&gt; and
&lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.2.8"&gt;15.12.2.8&lt;/a&gt;
of the Java Language Specification (Third Edition). The actual
rules are complicated (and I haven't read them yet) but the idea
seems to be to use two sources of information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the types of the actual arguments&lt;/li&gt;
&lt;li&gt;if the result is &amp;quot;assignment convertible&amp;quot; to some type
  &lt;i&gt;T&lt;/i&gt; then this type &lt;i&gt;T&lt;/i&gt; is used too.
&lt;/ul&gt;

&lt;p&gt;The reason why the Google collections library works is the
second bullet: The compiler uses the type of &lt;code class="prettyprint"&gt;foo&lt;/code&gt;
to figure out how to instantiate the type arguments of
&lt;code class="prettyprint"&gt;Maps.newHashMap&lt;/code&gt;.

&lt;p&gt;OK, that was the background. Now let's see some examples.&lt;/p&gt;

&lt;p&gt;Would you expect the following code to compile?&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
interface A {
  static enum Foo { BAR; }
  static enum Bar { FOO; }
}

class B&amp;lt;T extends Enum&amp;lt;T&amp;gt;&amp;gt; {
  private B() {}
  public static &amp;lt;T extends Enum&amp;lt;T&amp;gt;&amp;gt; B&amp;lt;T&amp;gt; get() {
    return new B&amp;lt;T&amp;gt;();
  }
}

public class C {
  public static void main(String[] args) {
    B&amp;lt;A.Foo&amp;gt; b = B.get();
  }
}
&lt;/pre&gt;

&lt;p&gt;Yes, it works. The Sun Java compiler 1.6.0_13 has no problem in handling
the sort-of recursive bound put on the type.&lt;/p&gt;

&lt;p&gt;Now, would you expect the following to work?&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
interface A {
  static enum Foo { BAR; }
  static enum Bar { FOO; }
}

class B&amp;lt;T, S&amp;gt; {
  private B() {}
  public static &amp;lt;T, S&amp;gt; B&amp;lt;T, S&amp;gt; get() {
    return new B&amp;lt;T, S&amp;gt;();
  }
}

public class C {
  public static void main(String[] args) {
    B&amp;lt;A.Foo, A.Bar&amp;gt; b = B.get();
  }
}
&lt;/pre&gt;

&lt;p&gt;Again, it works flawlessly. After all, why would multiple
type arguments confuse the compiler?&lt;/p&gt;

&lt;p&gt;So, you'd expect the following to work too, won't you?&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
interface A {
  static enum Foo { BAR; }
  static enum Bar { FOO; }
}

class B&amp;lt;T extends Enum&amp;lt;T&amp;gt;, S extends Enum&amp;lt;S&amp;gt;&amp;gt; {
  private B() {}
  public static &amp;lt;T extends Enum&amp;lt;T&amp;gt;, S extends Enum&amp;lt;S&amp;gt;&amp;gt; B&amp;lt;T, S&amp;gt; get() {
    return new B&amp;lt;T, S&amp;gt;();
  }
}

public class C {
  public static void main(String[] args) {
    B&amp;lt;A.Foo, A.Bar&amp;gt; b = B.get();
  }
}
&lt;/pre&gt;

&lt;p&gt;Tough luck, though: It doesn't work. Apparently
&amp;quot;no instance(s) of type variable(s) T,S exist so
that B&amp;lt;T,S&amp;gt; conforms to B&amp;lt;A.Foo,A.Bar&amp;gt;&amp;quot;.
I would have thought that &lt;code class="prettyprint"&gt;T=A.Foo&lt;/code&gt;
and &lt;code class="prettyprint"&gt;S=A.Bar&lt;/code&gt; would do the job.
&lt;/p&gt;

&lt;p&gt;As I said, I haven't read yet the relevant sections in the Java
specification to see if this a problem with the language or a problem 
with the compiler. The thing is that the two sections take 10 and a
half screens on my monitor, which signals that I should put aside
maybe one whole day for it, and I don't have one whole day to spend.
My hope is that it is a bug in the compiler, because otherwise I'd
loose some confidence in the language itself. After all, there's
something fishy about a 10-pages algorithm that doesn't end up
trying the obvious solution.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-6040608304401478461?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/GSydyRRPGRU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/6040608304401478461/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/07/type-inference-in-java-for-generics.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/6040608304401478461?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/6040608304401478461?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/GSydyRRPGRU/type-inference-in-java-for-generics.html" title="Type Inference in Java, for Generics" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/07/type-inference-in-java-for-generics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkADQHkyeyp7ImA9WxJQF0w.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-7927073657815984317</id><published>2009-05-30T17:17:00.001+03:00</published><updated>2009-05-30T22:12:51.793+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-30T22:12:51.793+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><title>BDD sucks, BDD rocks</title><content type="html">&lt;p&gt;&lt;i&gt;Whining mode.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;BDD (Behavioral Driven Development) is the most idiotic thing
I've ever heard of. It is a buzzword that stands for something
I completely don't understand. So, how can I say in such strong 
terms that it is idiotic if I don't even know what it is about?
Simple: It breaks Google. Whenever I search for information about
&lt;a href="http://en.wikipedia.org/wiki/Binary_decision_diagram"&gt;BDDs
(Binary Decision Diagrams)&lt;/a&gt;
I find complete garbage. OK, it's not that bad: Scholar gives
&lt;a href="http://scholar.google.com/scholar?as_q=bdd&amp;num=30&amp;as_subj=eng"&gt;
sensible results&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-7927073657815984317?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/EYRaDZf7u2A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/7927073657815984317/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/05/bdd-sucks-bdd-rocks.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7927073657815984317?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7927073657815984317?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/EYRaDZf7u2A/bdd-sucks-bdd-rocks.html" title="BDD sucks, BDD rocks" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/05/bdd-sucks-bdd-rocks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IMQXk5eip7ImA9WxJQFEk.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-3370958956153167600</id><published>2009-05-27T20:22:00.003+03:00</published><updated>2009-05-27T20:33:00.722+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-27T20:33:00.722+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="research" /><title>Related to Transitive Closures</title><content type="html">&lt;p&gt;&lt;i&gt;A problem that Mikolas bumped into.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Alice has a graph &lt;i&gt;G&lt;/i&gt; that is closed under transitivity.
Bob wants to reconstruct the graph &lt;i&gt;G&lt;/i&gt; but Alice would only
answer with YES or NO to questions of the form &amp;quot;is there an
edge from node &lt;i&gt;m&lt;/i&gt; to node &lt;i&gt;n&lt;/i&gt;?&amp;quot;. Help Bob achieve
his task with as few questions as possible.&lt;/p&gt;

&lt;p&gt;There are two possible cases. One is that Bob must aim for
a minimum number of questions for the worst possible graph 
&lt;i&gt;G&lt;/i&gt;. (Equivalently, Alice is evil and she keeps changing the
portions of the graph &lt;i&gt;G&lt;/i&gt; she didn't &amp;quot;commit&amp;quot; to
yet, just so that Bob needs to ask more questions.) The other is
that Bob aims for an &lt;i&gt;expected&lt;/i&gt; minimum, thinking that Alice
drew the graph randomly from some bag of graphs. (In the simplest
case the bag is a set of all possible graphs.)&lt;/p&gt;

&lt;p&gt;The number of nodes &lt;i&gt;N&lt;/i&gt; is known in advance to Bob.&lt;/p&gt;

&lt;p&gt;Any pointers?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-3370958956153167600?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/jXZVUU9BWYs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/3370958956153167600/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/05/related-to-transitive-closures.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/3370958956153167600?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/3370958956153167600?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/jXZVUU9BWYs/related-to-transitive-closures.html" title="Related to Transitive Closures" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/05/related-to-transitive-closures.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYGR3k4cCp7ImA9WxJQEkg.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-5024924308466579400</id><published>2009-05-25T14:14:00.000+03:00</published><updated>2009-05-25T14:15:26.738+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-25T14:15:26.738+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Puzzle Answer: Postfix Expressions</title><content type="html">&lt;p&gt;&lt;i&gt;A solution to a two-month old puzzle.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;A while back I posted a puzzle asking for a
&lt;a href="http://rgrig.blogspot.com/2009/03/postfix-expressions.html"&gt;
recursive and stackless postfix expression evaluator&lt;/a&gt;. A bit over a week
ago I received a solution from
&lt;a href="http://ashutoshmehra.net/blog/"&gt;Ashutosh Mehra&lt;/a&gt;.
(Go on, have a look at his blog. It's quite nice.)&lt;/p&gt;

&lt;p&gt;At first sight this seems like a lowly coding exercise. And it is,
but with a catch: It is designed to illustrate two fundamental
ideas that &lt;i&gt;should&lt;/i&gt; be part of every programmer's ethos.
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;i&gt;Recursion&lt;/i&gt; is equivalent to &lt;i&gt;loops&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Recursion is implemented with &lt;i&gt;stacks&lt;/i&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If one of these two fairly obvious statements is not built into
you, then you'll have trouble finding a solution. The first statement
implies that any program can be written without using loops. How?
First, write all the loops using only &lt;code class="prettyprint"&gt;while&lt;/code&gt;.
Second, replace each loop &lt;code class="prettyprint"&gt;while (C) B;&lt;/code&gt;
with a call to a new function &lt;code class="prettyprint"&gt;loop&lt;/code&gt;
defined as follows:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
void loop(ARGS) {
  if (!C) return;
  B; loop();
}
&lt;/pre&gt;

&lt;p&gt;The condition C and the body B will probably refer to some local
variables. In order to have them accessible for reading and for writing
from &lt;code class="prettyprint"&gt;loop&lt;/code&gt; we send as arguments ARGS
pointers to them, and modify C and B accordingly.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Exercise:&lt;/i&gt; What to do if B contains &lt;code class="prettyprint"&gt;
break&lt;/code&gt;? (Note: The solution to this is supposed to be easy if the
previous two paragraphs were understood.)&lt;/p&gt;

&lt;p&gt;What about the stack? We also want to get rid of the stack.&lt;/p&gt;

&lt;p&gt;The solution is again easy if you remember that local variables
(and function arguments)
come from a &amp;quot;stack&amp;quot;. So the key idea is to &lt;i&gt;use the call
stack as the operand stack&lt;/i&gt;. This said, enjoy the solution.&lt;/p&gt;


&lt;pre class="prettyprint"&gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;ctype.h&amp;gt;

int add(int x, int y) { return x + y; }
int sub(int x, int y) { return x - y; }
int mul(int x, int y) { return x * y; }
typedef int (*op_t)(int, int);
op_t op[256];

int c; /* last read character */

void read_digits(int* y) {
  if (!isdigit(c = getchar())) return;
  *y = eval(*y, c - '0');
  read_digits(y);
}

int eval(int x, int y) {
  read_digits(&amp;amp;y);
  return op[c](x, y);
}

int main() {
  op['+'] = add, op['-'] = sub, op['*'] = mul, op['|'] = add;
  printf("%d\n", eval(0, getchar() - '0'));
}
&lt;/pre&gt;

&lt;p&gt;When the function &lt;code class="prettyprint"&gt;eval(x, y)&lt;/code&gt;
is called, the top value in the operand stack is 
&lt;code class="prettyprint"&gt;y&lt;/code&gt; and the value just before
is &lt;code class="prettyprint"&gt;x&lt;/code&gt;. While the next token
is a digit it calls itself recursively &lt;code class="prettyprint"&gt;
eval(y, new_digit)&lt;/code&gt;. The &amp;quot;while&amp;quot; part is implemented
by the recursive function &lt;code class="prettyprint"&gt;read_digits&lt;/code&gt;.
When the token that says what operation should be performed between
&lt;code class="prettyprint"&gt;x&lt;/code&gt; and &lt;code class="prettyprint"&gt;y&lt;/code&gt;
is read, the operation is performed and the result returned.&lt;/p&gt;

&lt;p&gt;This variant is somewhat wasteful of memory.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-5024924308466579400?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/vnyNlUKEXaQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/5024924308466579400/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/05/puzzle-answer-postfix-expressions.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5024924308466579400?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5024924308466579400?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/vnyNlUKEXaQ/puzzle-answer-postfix-expressions.html" title="Puzzle Answer: Postfix Expressions" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/05/puzzle-answer-postfix-expressions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8EQnc8eyp7ImA9WxVaEU4.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-7269689423687058893</id><published>2009-04-08T00:11:00.001+03:00</published><updated>2009-04-08T00:13:23.973+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T00:13:23.973+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="random" /><title>Startups and the Crisis</title><content type="html">&lt;p&gt;&lt;i&gt;Short reviews of a few websites.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;For the past few months I've been told there's an economic
crisis. I've also been told about a few startups. I would have
thought that in hard times people are less inclined to risk.
Can anyone explain me why the opposite seems to hold?
While you think about that, I'll list the sites:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a href="http://www.taskwriter.com/"&gt;TaskWriter&lt;/a&gt;&lt;/b&gt; is
a site for keeping track of what you need to do. Once you go to
the website you see a &amp;quot;please wait while I'm loading&amp;quot;
sign and while waiting you can read that you should use this
site because it's the fastest. Now, that may sound ironic, and
it is. Still, once the login box appears it gets much quicker.
Registering is hassle-free. Once you get in you see that the main
functionality of the website is to keep track of TODO lists where
items are one line long. The obvious concern is: &amp;quot;Do I want
my TODO list on some random website?&amp;quot; I guess the answer
depends on whether you have something to hide. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a href="http://www.easytrack.ro/"&gt;EasyTrack&lt;/a&gt;&lt;/b&gt; is
a site for Romanian companies that have many cars and want to
track them. Why Romanian? Probably because maps are rented and
it's expensive to rent good maps for everywhere. Why track the
cars? To optimize costs. I hear that giving your employees cars
as a perk may be costlier than it sounds. It's probably easier
to abuse than a free lunch, anyway.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;a href="http://balaur.ro/"&gt;Balaurul&lt;/a&gt; (The
dragon)&lt;/b&gt; is a search engine for jobs&amp;hellip; in Romania.
Now I finally see some correlation with the economic crisis:
More people must be looking for jobs. I wonder if similar search
engines are already successful in other countries. The business
model is a little too Google for my taste: simple web design,
attract ads. Usually cool stuff is &lt;i&gt;different&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Disclaimer:&lt;/b&gt; TaskWriter and EasyTrack are the startups
of two of my friends from college. I also met two of the three
people that started Balaurul.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Others:&lt;/b&gt; My brother-in-law is starting a software
development company, after being 
&lt;a href="http://en.wikipedia.org/wiki/Chief_technical_officer"&gt;CTO&lt;/a&gt;
for a long time in a company that provides software solutions for
restaurants and hotels. Finally, three of my students will
work for themselves for a while.&lt;/p&gt;

&lt;p&gt;I hope many of these will be successful. I really do. All the
people involved are high quality. Which makes me wonder what
would happen if they would all work together. This must be a key
ingredient in making a successful business: Getting many good
people to work together. I wonder how you do that.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-7269689423687058893?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/ho6bZLQ9ZHQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/7269689423687058893/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/04/startups-and-crisis.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7269689423687058893?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7269689423687058893?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/ho6bZLQ9ZHQ/startups-and-crisis.html" title="Startups and the Crisis" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/04/startups-and-crisis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8NQ3c7eCp7ImA9WxVbF0w.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-5209722060362895410</id><published>2009-04-03T03:34:00.001+03:00</published><updated>2009-04-03T03:34:52.900+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-03T03:34:52.900+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>WHY Java</title><content type="html">&lt;p&gt;&lt;i&gt;Y in Java.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;Y&lt;/tt&gt; is a cute concept from &lt;a
href="http://en.wikipedia.org/wiki/Lambda_calculus"&gt;lambda
calculus&lt;/a&gt;. It's easy to define in Haskell. &lt;/p&gt;

&lt;pre class="prettyprint"&gt;
y f = f (y f)
fact r 0 = 1
fact r n = n * r (n-1)
f = y fact
&lt;/pre&gt;

&lt;p&gt;An execution of &lt;tt&gt;f 3&lt;/tt&gt; computes 3!:&lt;/p&gt;

&lt;pre&gt;
f 3
  = y fact 3
  = fact (y fact) 3
  = 3 * y fact 2
  = 3 * fact (y fact) 2
  = 3 * 2 * y fact 1
  = 3 * 2 * fact (y fact) 1
  = 3 * 2 * 1 * y fact 0
  = 3 * 2 * 1 * 1
&lt;/pre&gt;

&lt;p&gt;While showing this to Claudia I realized that I never coded Y
in Java. It's interesting to see how &lt;i&gt;long&lt;/i&gt; it is.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
interface Fun { int go(int n); }
interface UntiedFun { int go(Fun f, int n); }

public class Rec {
  public static void main(String[] args) {
    System.out.println(f(10));
  }

  public static int fact(Fun f, int n) {
    if (n == 0) return 1;
    return n * f.go(n-1);
  }

  public static int Y(final UntiedFun f, int n) {
    return f.go(new Fun() {
      public int go(int n) { return Y(f, n); }
    }, n);
  }

  public static int f(int n) {
    return y(new UntiedFun() {
      public int go(Fun f, int n) {return fact(f, n);}
    }, n);
  }
}
&lt;/pre&gt;

&lt;p&gt;Great stuff you can do with recursion. Which reminds me: Did
you figure out the last puzzle?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-5209722060362895410?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/IGGstH3iyKA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/5209722060362895410/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/04/why-java.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5209722060362895410?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5209722060362895410?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/IGGstH3iyKA/why-java.html" title="WHY Java" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/04/why-java.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIMR345eyp7ImA9WxVbFEk.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-7163900269572501467</id><published>2009-03-31T00:28:00.002+03:00</published><updated>2009-03-31T00:29:46.023+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-31T00:29:46.023+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="puzzle" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Postfix Expressions</title><content type="html">&lt;p&gt;&lt;i&gt;Puzzle: recursive postfix evaluation.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;On Saturday the Computer Science&amp;amp;Informatics School of
the University College Dublin has a 
&lt;a href="http://www.csi.ucd.ie/progcomp2009/"&gt;
local programming competition&lt;/a&gt;. That, and
&lt;a href="http://infoweekly.blogspot.com/2009/03/classic-problem.html"&gt;
a problem from Mihai&lt;/a&gt;, reminded me that I didn't
post puzzles here in a long time. This one is an implementation
puzzle.&lt;/p&gt;

&lt;p&gt;A typical way to evaluate a postfix expression is to use a stack.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
#include &amp;lt;stdio.h&amp;gt;

int stack[1&amp;lt;&amp;lt;20]; /* operand stack */
int sz; /* stack[0..sz) is used */

int main() {
  int c; /* last read character */
  while ((c = getchar()) != '|') {
    switch (c) {
    case '+': --sz; stack[sz-1] += stack[sz]; break;
    case '-': --sz; stack[sz-1] -= stack[sz]; break;
    case '*': --sz; stack[sz-1] *= stack[sz]; break;
    default:
      if ('0' &amp;lt;= c &amp;amp;&amp;amp; c &amp;lt;= '9') stack[sz++] = c - '0';
    }
  }
  printf("%d\n", *stack);
}
&lt;/pre&gt;

&lt;p&gt;The code above assumes that operands are digits, that the only
allowed operators are &lt;tt&gt;+-*&lt;/tt&gt;, that the input is terminated by
&lt;tt&gt;|&lt;/tt&gt;, and that there are no other characters.&lt;/p&gt;

&lt;p&gt;The problem is: Can you implement this &lt;i&gt;without:&lt;/i&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an explicit stack&lt;/li&gt;
&lt;li&gt;loops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both should be replaced by &lt;i&gt;recursion&lt;/i&gt;. As usual, you can email
me solutions to &lt;i&gt;radugrigore&lt;/i&gt; at &lt;i&gt;gmail.com&lt;/i&gt; and I'll
post the best solution plus a list of those who solved the
puzzle. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-7163900269572501467?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/1b-iEG1kNsw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/7163900269572501467/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/03/postfix-expressions.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7163900269572501467?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7163900269572501467?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/1b-iEG1kNsw/postfix-expressions.html" title="Postfix Expressions" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/03/postfix-expressions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4HSH8_eyp7ImA9WxVbE08.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-5765969587609385541</id><published>2009-03-29T00:52:00.003+02:00</published><updated>2009-03-29T14:08:59.143+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-29T14:08:59.143+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="research" /><title>Blogs by Researchers</title><content type="html">&lt;p&gt;&lt;i&gt;Which researchers are more inclined to blog?&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Methodology:&lt;/b&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;pick a conference/workshop&lt;/li&gt;
&lt;li&gt;go thru the program committee (PC) and search for the 
  word &amp;quot;blog&amp;quot; on each homepage&lt;/li&gt;
&lt;li&gt;eliminate blogs that don't contain any Computer Science post
  in the last 5&amp;nbsp;posts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I do &lt;i&gt;not&lt;/i&gt; include the blogs I know about that can't be
found using the methodology above. Why? (1)&amp;nbsp;If the same
rules are applied to different communities then the results say something about the 
difference between communities. (2)&amp;nbsp;I want to simulate what
an outsider would be able to find with &lt;i&gt;little&lt;/i&gt; effort.&lt;/p&gt;&lt;p&gt;
&lt;b&gt;Results:&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ecoop09.disi.unige.it/committees.html"&gt;
ECOOP&lt;/a&gt;: 
Analysis, design methods and design patterns;
Concurrent, real-time or parallel systems;
Databases, persistence and transactions;
Distributed and mobile systems;
Frameworks, product lines and software architectures;
Language design and implementation;
Testing and metrics;
Programming environments and tools;
Theoretical foundations, type systems, formal methods;
Versioning, compatibility, software evolution;
Aspects, Components, Modularity, Reflection;
Collaboration, Workflow.
PC with 29&amp;nbsp;people. Blogs:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://wcook.blogspot.com/"&gt;William Cook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.spinellis.gr/blog/index.html"&gt;Diomidis D. Spinellis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tratt.net/laurie/tech_articles/"&gt;Laurence Tratt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://www.embedded.rwth-aachen.de/tacas2009/"&gt;TACAS&lt;/a&gt;:
Specification and verification techniques for finite and infinite-state systems;
Software and hardware verification;
Theorem-proving and model-checking;
System construction and transformation techniques;
Static and run-time analysis;
Abstraction techniques for modeling and validation;
Compositional and refinement-based methodologies;
Testing and test-case generation;
Analytical techniques for secure, real-time, hybrid, critical, biological or dependable systems;
Integration of formal methods and static analysis in high-level hardware design or software environments;
Tool environments and tool architectures;
SAT solvers;
Applications and case studies .
PC with 29&amp;nbsp;people. No blog.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://people.cis.ksu.edu/~ab/FTfJP09/ftfjp09.html"&gt;FTfJP&lt;/a&gt;:
specification techniques and interface specification languages;
specification of software components and library packages;
automated checking and verification of program properties;
verification logics;
language semantics;
program analysis;
type systems;
security. 
PC with 15&amp;nbsp;people. No blog.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.umiacs.umd.edu/conferences/stoc2009/"&gt;STOC&lt;/a&gt;:
algorithms and data structures;
computational complexity; 
cryptography;
privacy;
computational geometry;
algorithmic graph theory and combinatorics;
randomness in computing;
parallel and distributed computation;
machine learning;
applications of logic;
algorithmic algebra and coding theory;
computational biology;
computational game theory;
quantum computing and other alternative models of computation;
theoretical aspects of areas such as databases, information retrieval, and networks.
PC with 24&amp;nbsp;people. Blogs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mybiasedcoin.blogspot.com/"&gt;Michael Mitzenmacher&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you apply this to some other conferences I'd be interested
in the results. Blogs are a good way for researchers to spread
the important ideas in their specialized areas. The rate of
researchers with blogs is very low.&lt;/p&gt;

&lt;p&gt;[&lt;b&gt;Edit&lt;/b&gt;] You may say &lt;tt&gt;&lt;a href="http://radugrigore.googlepages.com/blogs.py"&gt;blogs.py&lt;/a&gt; page&lt;/tt&gt;, where &lt;tt&gt;page&lt;/tt&gt; is the URL of a conference page that contains the program committee, to get a list of probable blogs. This cuts down the manual work a lot (but also misses some blogs, if the authors do not include &amp;quot;blog&amp;quot; in the &lt;i&gt;link&lt;/i&gt; text).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-5765969587609385541?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/Abm9BuZMtGc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/5765969587609385541/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/03/blogs-by-researchers.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5765969587609385541?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/5765969587609385541?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/Abm9BuZMtGc/blogs-by-researchers.html" title="Blogs by Researchers" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/03/blogs-by-researchers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQBQX44fCp7ImA9WxVbEks.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-1804904298127592656</id><published>2009-03-28T21:08:00.000+02:00</published><updated>2009-03-28T21:09:10.034+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-28T21:09:10.034+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Command Line Options</title><content type="html">&lt;p&gt;&lt;i&gt;A short introduction to CLOPS, a Java library for parsing the
command line.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Did you ever write
&lt;code class="prettyprint"&gt;public static void main(String[] args)&lt;/code&gt;?
If so, did you ever use &lt;code class="prettyprint"&gt;args&lt;/code&gt; later?
If &lt;i&gt;yes&lt;/i&gt; and &lt;i&gt;yes&lt;/i&gt; then you need 
&lt;a href="http://clops.sf.net/"&gt;CLOPS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I can hear you saying that &amp;quot;handling
&lt;code class="prettyprint"&gt;args&lt;/code&gt; is very easy and doesn't
justify learning a new technology.&amp;quot; You are right that the
benefits of a technology have to be weighted against its costs,
and one of the most important costs that a technology incurs is
the time spent learning it. Obviously, this poses a problem: How
can you balance benefits and costs &lt;i&gt;before&lt;/i&gt; learning? To solve
this dilemma, it seems to me, most people rely on the assessment
of others. So hear my word: &lt;i&gt;Learning CLOPS is much easier
than you think!&lt;/i&gt; Alas, I'm biased because I contributed to
the design. I understand if you don't believe me: I started
to contribute late precisely because in the beginning I was a
skeptic myself. I had to see something working before changing
my mind.&lt;/p&gt;

&lt;p&gt;Most technologies have a complexity threshold: Products more
complex than the threshold benefit from using the technology;
products less complex than the threshold are hurt. HTML is a
technology. Is it worth learning HTML for writing a blog? Not
really. But is it worth learning if you want to develop a serious
web-site? Probably. ViM is another technology. Is it worth
learning for writing email? Definitely not. Is it worth learning
for writing C programs? Maybe.&lt;/p&gt;

&lt;p&gt;So what's the complexity threshold of CLOPS? A simple way to
assess the complexity threshold of a technology is to pick a task
and complete it with and without the technology. Let's write a
program that prints &amp;quot;Hello world!&amp;quot; when run with no
arguments, prints &amp;quot;Goodbye cruel world!&amp;quot; when run with
the argument &lt;tt&gt;-bye&lt;/tt&gt;, and prints a usage message in all other
cases.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
public class Main {
  public static void main(String[] args) {
    if (args.length &amp;gt; 1 || (args.length == 1 &amp;&amp; !args[0].equals("-bye"))) {
      System.out.println("Usage: hello [-bye]");
      return;
    }
    if (args.length == 1)
      System.out.println("Goodbye cruel world!");
    else
      System.out.println("Hello world!");
  }
}
&lt;/pre&gt;

&lt;p&gt;The CLOPS version is almost the same length:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
public class Main {
  public static void main(String[] args) {
    HelloParser parser = new HelloParser();
    if (!parser.parse(args)) {
      System.out.println("Usage: hello [-bye]");
      return;
    }
    if (parser.getOptionStore().isByeSet())
      System.out.println("Goodbye cruel world!");
    else
      System.out.println("Hello world!");
  }
}
&lt;/pre&gt;

&lt;p&gt;That's not too bad. But we &lt;i&gt;do&lt;/i&gt; have to write one more
file, let's call it &lt;tt&gt;hello.clo&lt;/tt&gt;, that describes the command
line.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
NAME:: Hello
ARGS:: Bye: {"-bye"}
FORMAT:: Bye?;
&lt;/pre&gt;

&lt;p&gt;To compile we must say&lt;/p&gt;

&lt;pre&gt;
clops hello.clo
javac -cp clops-runtime.jar:. *.java
&lt;/pre&gt;

&lt;p&gt;and to run we say&lt;/p&gt;

&lt;pre&gt;
java -cp clops-runtime.jar:. Main
&lt;/pre&gt;

&lt;p&gt;This &lt;i&gt;is&lt;/i&gt; definitely more complicated than not using
CLOPS. It indicates that for such a simple example it is
&lt;i&gt;not&lt;/i&gt; worth using CLOPS. But, by the same argument, for this
example it is not worth using the build system ANT. Why write a
&lt;tt&gt;build.xml&lt;/tt&gt; file when you can get away without? Yet, for
some strange reason some people keep using ANT even for such
small projects. (Not me.) I believe the reason they are using it
is that they get into a routine: copy the &lt;tt&gt;build.xml&lt;/tt&gt; file
of an old project, modify a little inside, and then operate in
a familiar environment. It makes sense. Even if later the build
process becomes more complicated than just invoking the Java
compiler, it still is the case that a build can be achieved by
&lt;i&gt;one&lt;/i&gt; command: &lt;tt&gt;ant&lt;/tt&gt;. The price, copying and editing
slightly a file in the beginning, is something most developers
are willing to pay.&lt;/p&gt;

&lt;p&gt;It's the same with CLOPS. As soon as the command line starts
to get a little more complicated you begin to feel the benefits.
Are there two boolean options that shouldn't be given at the same
time? You add one line to &lt;tt&gt;hello.clo&lt;/tt&gt;: Your program and
your documentation are updated. Does an option represent a file
name that must exist? You add one keyword in &lt;tt&gt;hello.clo&lt;/tt&gt;:
Your program and your documentation are updated. Can an
option appear only after another certain option? You guessed: You
modify &lt;tt&gt;hello.clo&lt;/tt&gt; slightly and you are done. &lt;/p&gt;

&lt;p&gt;OK, now that you are convinced that it's worth using CLOPS
when you write a command line tool it is time to address another
question: Why would you write a command line tool in Java as
opposed to, say, C? (If you are still not convinced that you
should try CLOPS, then please pretend that you are for the next
5&amp;nbsp;minutes.) Well, why &lt;i&gt;not?&lt;/i&gt; There are &lt;i&gt;many&lt;/i&gt;
programs that contain command line tools and are written in
Java, such as &lt;a href="http://www.soapui.org/userguide/commandline/index.html"&gt;
web service testers&lt;/a&gt;, &lt;a href="http://brlcad.org/wiki/Documentation"&gt;
3D graphics tools&lt;/a&gt;, &lt;a href="http://findbugs.sourceforge.net/manual/running.html"&gt;
bug finders&lt;/a&gt;, &lt;a href="http://www.zimbra.com/docs/ne/latest/administration_guide/A_app-command-line.18.1.html"&gt;
messenging and communication tools&lt;/a&gt;, &lt;a href="http://staf.sourceforge.net/"&gt;
testing frameworks&lt;/a&gt;, &lt;a href="http://areca.sourceforge.net/documentation.php#tocHelp38"&gt;
backup tools&lt;/a&gt;, and &lt;a href="http://datavision.sourceforge.net/DataVision/rundv.html#runcmd"&gt;
data reporting tools&lt;/a&gt;. It is true that at the moment most
command line tools are written in&amp;nbsp;C, but this &lt;i&gt;will&lt;/i&gt;
change. Of course, we'd be happy to see a C port of 
&lt;a href="http://clops.sf.net/"&gt;CLOPS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We'd also be happy &lt;a href="mailto:clops-users@lists.sourceforge.net"&gt;
to hear what you think&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-1804904298127592656?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/g-VqxdMQgXc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/1804904298127592656/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/03/command-line-options.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/1804904298127592656?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/1804904298127592656?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/g-VqxdMQgXc/command-line-options.html" title="Command Line Options" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/03/command-line-options.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EAR3szeyp7ImA9WxVbEUQ.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-966920138587340470</id><published>2009-03-28T02:20:00.001+02:00</published><updated>2009-03-28T02:20:46.583+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-28T02:20:46.583+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="meta" /><title>A Change</title><content type="html">&lt;p&gt;&lt;i&gt;Welcome to my new blog.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Hurray to a new beginning!&lt;p&gt;

&lt;ul&gt;
&lt;li&gt;Blogger provides the new look&amp;amp;feel that replaces the 
ancient one I designed.&lt;/li&gt;
&lt;li&gt;The title reflects a focus on readers.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-966920138587340470?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/2_20aE6SAI4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/966920138587340470/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/03/change.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/966920138587340470?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/966920138587340470?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/2_20aE6SAI4/change.html" title="A Change" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/03/change.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UNRnk8fyp7ImA9WxVUEUQ.&quot;"><id>tag:blogger.com,1999:blog-5829875.post-7424129543991412022</id><published>2009-03-16T10:09:00.002+02:00</published><updated>2009-03-16T10:14:57.777+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-16T10:14:57.777+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><title>The 13th World Multi-Conference on Systemics, Cybernetics and Informatics</title><content type="html">&lt;p&gt;I've just been invited to submit a paper to &lt;i&gt;The 13th World Multi-Conference on Systemics, Cybernetics and Informatics&lt;/i&gt;. I wonder what I did to deserve such an honor. I also wonder if there are idiots that don't suspect what this is after reading the name of the conference: an idiocracy-style joke. I googled for the name of the organizer (Nagib Callaos), and sure enough, he's a prank. Stay away if you don't want your name tainted forever.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5829875-7424129543991412022?l=rgrig.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RgrigsBlog/~4/KdzNkmyn1kA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://rgrig.blogspot.com/feeds/7424129543991412022/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://rgrig.blogspot.com/2009/03/13th-world-multi-conference-on.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7424129543991412022?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5829875/posts/default/7424129543991412022?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RgrigsBlog/~3/KdzNkmyn1kA/13th-world-multi-conference-on.html" title="The 13th World Multi-Conference on Systemics, Cybernetics and Informatics" /><author><name>rgrig</name><uri>http://www.blogger.com/profile/02991214367108471744</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08043799635865071699" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://rgrig.blogspot.com/2009/03/13th-world-multi-conference-on.html</feedburner:origLink></entry></feed>
