<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>This sentence is false</title>
	<atom:link href="http://obfuscatedcode.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://obfuscatedcode.wordpress.com</link>
	<description>functional programming, software, and emacs.</description>
	<lastBuildDate>Sat, 24 Dec 2011 15:16:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='obfuscatedcode.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>This sentence is false</title>
		<link>http://obfuscatedcode.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://obfuscatedcode.wordpress.com/osd.xml" title="This sentence is false" />
	<atom:link rel='hub' href='http://obfuscatedcode.wordpress.com/?pushpress=hub'/>
		<item>
		<title>WebCert+ Phishing Attempt</title>
		<link>http://obfuscatedcode.wordpress.com/2011/08/04/webcert-phishing-attempt/</link>
		<comments>http://obfuscatedcode.wordpress.com/2011/08/04/webcert-phishing-attempt/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 01:23:30 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=393</guid>
		<description><![CDATA[UPDATE: Definitely phishing. I recently got an email ostensibly from Bank of America. It said I needed to sign up for their new &#8220;WebCert+&#8221; service and if I didn&#8217;t, my account would be suspended and imposed a hefty $45 reactivation fee. I received one email (which went to Spam) containing an embedded web form in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=393&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>UPDATE: Definitely phishing.</p>
<p>I recently got an email ostensibly from Bank of America. It said I needed to sign up for their new &#8220;WebCert+&#8221; service and if I didn&#8217;t, my account would be suspended and imposed a hefty $45 reactivation fee. I received one email (which went to Spam) containing an embedded web form in which I was to fill out all kinds of personal information. And three others adjuring me to fill it out lest terrible things happen to me and my bank account.</p>
<p>I think this is a phishing attempt. I want to know if there are others getting the same thing and if anyone can confirm that it is illegitimate.</p>
<p>My first clue that it&#8217;s a phishing attempt is that it&#8217;s sent from alerts@bankofamericaalerts.0nlinereport.com. These days it&#8217;s so easy (right?) to spoof a FROM address, you wonder why more people don&#8217;t.</p>
<p>Second was the embedded form. Who sends embedded email forms? I should have to log into my account online and _then_ fill out the form.</p>
<p>But all of that is circumstantial.</p>
<p>Anyone else see this or can confirm that it is attempted thievery?</p>
<br />Filed under: <a href='http://obfuscatedcode.wordpress.com/category/security/'>security</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/393/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=393&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2011/08/04/webcert-phishing-attempt/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>iPod Touch Troubles</title>
		<link>http://obfuscatedcode.wordpress.com/2011/07/30/ipod-touch-troubles/</link>
		<comments>http://obfuscatedcode.wordpress.com/2011/07/30/ipod-touch-troubles/#comments</comments>
		<pubDate>Sat, 30 Jul 2011 16:46:30 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[ipod]]></category>
		<category><![CDATA[trivia]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=388</guid>
		<description><![CDATA[My 1st generation iPod Touch would not sync today. As soon as I plugged the USB cable into the computer, iTunes would register the new iPod&#8217;s presence, but immediately error out with: The iPod Minerva cannot be synced. The required disk cannot be found. After googling a bit, it seemed most people solved this by [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=388&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>My 1st generation iPod Touch would not sync today. As soon as I plugged the USB cable into the computer, iTunes would register the new iPod&#8217;s presence, but immediately error out with:</p>
<blockquote><p>The iPod Minerva cannot be synced. The required disk cannot be found.</p></blockquote>
<p>After googling a bit, it seemed most people solved this by removing or plugging in a different device&#8217;s USB cable right after hitting the Sync button. Unfortunately, this didn&#8217;t work for me because iTunes chose automatically to sync as soon as I plugged my iPod in (no matter what options I set). Finally, I stumbled on one person&#8217;s advice: the cable is bad.</p>
<p>Or at least unable to sufficiently communicate with iTunes.</p>
<p>So I switched cables and everything&#8217;s working fine now.</p>
<br />Filed under: <a href='http://obfuscatedcode.wordpress.com/category/howto/'>howto</a>, <a href='http://obfuscatedcode.wordpress.com/category/ipod/'>ipod</a>, <a href='http://obfuscatedcode.wordpress.com/category/trivia/'>trivia</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/388/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/388/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/388/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/388/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/388/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/388/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/388/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/388/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/388/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/388/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/388/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/388/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/388/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/388/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=388&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2011/07/30/ipod-touch-troubles/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting mGSD to work on Chrome under Ubuntu</title>
		<link>http://obfuscatedcode.wordpress.com/2011/05/07/getting-mgsd-to-work-on-chrome-under-ubuntu/</link>
		<comments>http://obfuscatedcode.wordpress.com/2011/05/07/getting-mgsd-to-work-on-chrome-under-ubuntu/#comments</comments>
		<pubDate>Sat, 07 May 2011 19:38:54 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=374</guid>
		<description><![CDATA[mGSD is a getting things done organizer for your web browser. It&#8217;s based on TiddlyWiki. It&#8217;s pretty neat. Anyway, out of the box, you can&#8217;t use mGSD on Google Chrome because it needs a java plugin and the ability to store cookies. The former may work out of the box for you, but you&#8217;ll need [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=374&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://mgsd-docs.tiddlyspace.com/" title="mGSD">mGSD</a> is a <a href="http://lmgtfy.com/?q=getting+things+done">getting things done</a> organizer for your web browser. It&#8217;s based on <a href="http://lmgtfy.com/?q=tiddlywiki">TiddlyWiki</a>. It&#8217;s pretty neat.</p>
<p>Anyway, out of the box, you can&#8217;t use mGSD on <a href="http://google.com/chrome">Google Chrome</a> because it needs a java plugin and the ability to store cookies. The former may work out of the box for you, but you&#8217;ll need a special flag for Chrome to grant a local html file the ability to store cookies.</p>
<p>I&#8217;m using Ubuntu 11.04 (64 bit) with the Unity interface on my new netbook. Also, I&#8217;m not using chromium, available through Synaptic, I&#8217;m actually using a Chrome I downloaded for Google. Anyway, here&#8217;s how you do it.</p>
<p>Edit the file ~/.local/share/applications/google-chrome.desktop. Scroll to the bottom where you see the line</p>
<blockquote><p><code>Exec=/opt/google/chrome/google-chrome %U</code></p></blockquote>
<p>Change it to:</p>
<blockquote><p><code>Exec=/opt/google/chrome/google-chrome --enable-file-cookies %U</code></p></blockquote>
<p>Next, kill openjdk:</p>
<blockquote><p><code>sudo apt-get remove default-jdk openjdk-6-jre openjdk-6-jdk<br />
sudo apt-get autoremove</code></p></blockquote>
<p>And install sun&#8217;s JDK:</p>
<blockquote><p><code>sudo apt-get install sun-java6-jdk sun-java6-jre sun-java6-fonts</code></p></blockquote>
<p>Finally, tell Chrome about the new plugin. If you&#8217;re on a 32 bit machine, use i386 instead of amd64 in the next command.</p>
<blockquote><p><code>sudo mkdir /opt/google/chrome/plugins<br />
sudo ln -s /usr/lib/jvm/java-6-sun/jre/lib/amd64/libnpjp2.so /opt/google/chrome/plugins/</code></p></blockquote>
<p>Then restart Chrome and you should see the java plugin if you browse to chrome://plugins. Now try running and saving your very own mGSD.</p>
<br />Filed under: <a href='http://obfuscatedcode.wordpress.com/category/uncategorized/'>Uncategorized</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/374/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/374/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/374/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/374/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/374/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/374/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/374/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/374/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/374/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/374/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/374/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/374/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/374/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/374/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=374&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2011/05/07/getting-mgsd-to-work-on-chrome-under-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>New versions of funsat and bitset</title>
		<link>http://obfuscatedcode.wordpress.com/2011/03/04/new-versions-of-funsat-and-bitset/</link>
		<comments>http://obfuscatedcode.wordpress.com/2011/03/04/new-versions-of-funsat-and-bitset/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 04:37:42 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[funsat]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[sat-solver]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=355</guid>
		<description><![CDATA[I wrote (and sometimes maintain) two Haskell programs: funsat and bitset. Funsat is a native haskell CDCL (conflict-driven clause-learning) SAT solver. Bitset is a small library for representing sets of items using bits under the hood (as opposed to trees, which is common in functional programming). I just released version funsat 0.6.2 and bitset 1.1. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=355&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I wrote (and sometimes maintain) two Haskell programs: <a href="http://hackage.haskell.org/package/funsat">funsat</a> and <a href="http://hackage.haskell.org/package/bitset">bitset</a>. Funsat is a native haskell CDCL (conflict-driven clause-learning) SAT solver. Bitset is a small library for representing sets of items using bits under the hood (as opposed to trees, which is common in functional programming).</p>
<p>I just released version <a href="http://hackage.haskell.org/package/funsat-0.6.2">funsat 0.6.2</a> and <a href="http://hackage.haskell.org/package/bitset-1.1">bitset 1.1</a>.</p>
<p>Funsat 0.6.2 has some compatibility changes so it now works with ghc 6.12. Also, it is cabal-installable. (Before, it would die because of stupid dependencies, or something.)</p>
<p>Bitset 1.1 now gives you access to the Integer that is used in the underlying bit representation.</p>
<br />Filed under: <a href='http://obfuscatedcode.wordpress.com/category/funsat/'>funsat</a>, <a href='http://obfuscatedcode.wordpress.com/category/haskell/'>haskell</a>, <a href='http://obfuscatedcode.wordpress.com/category/sat-solver/'>sat-solver</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/355/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=355&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2011/03/04/new-versions-of-funsat-and-bitset/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>Functional Priority Queues</title>
		<link>http://obfuscatedcode.wordpress.com/2011/03/04/functional-priority-queues/</link>
		<comments>http://obfuscatedcode.wordpress.com/2011/03/04/functional-priority-queues/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 04:00:20 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[sat-solver]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[heaps]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=48</guid>
		<description><![CDATA[In a previous post on my SAT solver I promised to post about a dead end using functional priority queues. I believe the most efficient data structure for the dynamic variable ordering should be a priority queue. In fact, it looks like a job for a Fibonacci heap (animation). According to CLRS, &#8220;Fibonacci heaps are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=48&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://obfuscatedcode.wordpress.com/2008/04/18/a-modern-sat-solver-in-haskell/">previous post on my SAT solver</a> I promised to post about a dead end using functional priority queues.  I believe the most efficient data structure for the dynamic variable ordering should be a priority queue.  In fact, it looks like a job for a <a href="http://en.wikipedia.org/wiki/Fibonacci_heap">Fibonacci heap</a> (<a href="http://www.cse.yorku.ca/~aaw/Jason/FibonacciHeapAnimation.html">animation</a>).  According to <a href="http://projects.csail.mit.edu/clrs/">CLRS</a>, &#8220;Fibonacci heaps are especially desirable when the number of <em>Extract-Min</em> and <em>Delete</em> operations is small relative to the number of other operations performed.&#8221; At least if just a few decisions will lead to a conflict, then we might end up adjusting the priority of many variables (to handle the conflict) so that there&#8217;s more adjusting than making decisions.</p>
<p>The asymptotic complexity of the Fibonacci heap works out because of its mutable tree structure.  Specifically, adjusting the key of a node in the heap requires the caller to provide a pointer to that node in the heap, and that node needs to be able to navigate anywhere else in the heap. This can be done in Haskell (either with the <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#1">IO monad</a> or the <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad-ST.html#1">ST monad</a>), but the result isn&#8217;t elegant by any means.  It also feels <em>wrong</em> &#8212; I program in a functional language because it lets me do equational reasoning, and think about <em>data dependencies</em> rather than <em>state machine models</em> of computation.</p>
<h2>Functional Fibonacci Heap?</h2>
<p>I tried for a while to see if I could come up with a <a href="http://en.wikipedia.org/wiki/Zipper_(data_structure)">Zipper</a> view of the heap instead of the traditional linked-lists-of-heap-ordered-trees approach.  That is, maybe a zipper could approximate a pointer.  What I&#8217;d really need is a zipper with arbitrarily-many points of access into the heap (instead of one), and I&#8217;ve no idea how to write that.  But any update of the heap requires updating all these zippers, which seems to destroy the complexity of the <em>Decrease-Key</em> operation.</p>
<p>Another option is to implement <em>Decrease-Key</em> by searching for the node to update, instead of providing a pointer.  But I couldn&#8217;t figure out a way to integrate searching within the structure of a Fibonacci heap.</p>
<p>Eventually I considered this a dead end and <a href="http://groups.google.com/group/comp.lang.functional/browse_thread/thread/6b3932b08f74a1e7/f51577dbbc07ec92?lnk=gst&amp;q=heap#f51577dbbc07ec92">posted to comp.lang.functional</a>, where Ben Franksen pointed me to finger trees.</p>
<h2>Finger Trees</h2>
<p>Finger trees are a functional data structure for persistent sequences.  Ralf Hinze described a Haskell implementation of <em>2-3 finger trees</em> which is <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/fingertree">available from Hackage</a>, so I used this.  In the paper Hinze even describes how to implement max-priority queues on top of finger trees, which seemed like a good idea at first.  Unfortunately, I don&#8217;t think it admits an efficient <em>Decrease-Key</em>, so I used the paper&#8217;s description of ordered sequences instead.  This seems like the right thing to do, given that the paper says:</p>
<blockquote><p>Ordered sequences subsume priority queues, as we have immediate access to the smallest <em>and</em> the greatest element, and search trees, as we can partition ordered sequences in logarithmic time.</p></blockquote>
<p>The ability to do search trees gives us an efficient (sub-linear) <em>Decrease-Key</em>.  Finally, my priority queue operations are:</p>
<pre>
extractMax :: (Ord k) =&gt; Heap k a -&gt; (Info k a, Heap k a)
extractMax (OrdSeq s) = (x, OrdSeq s')
    where x :&lt; s' = viewl s
</pre>
<pre>
increaseKey :: (Ord k, Eq a) =&gt; Info k a -&gt; k -&gt; Heap k a -&gt; Heap k a
increaseKey oldInfo newKey (OrdSeq t) = OrdSeq (l' &gt;&lt; eqs' &gt;&lt; r')
    where (l, r)    = split (&lt;= measure oldInfo) t
          (eqs, r') = split (&lt; measure oldInfo) r
          eqs' = foldr (\i t' -&gt; if i == oldInfo then t' else i &lt;| t')
                 FT.empty eqs
           -- newInfo is bigger, so must fit on bigger side of split
          (OrdSeq l') = insert newInfo (OrdSeq l)
          newInfo = oldInfo{ key = newKey }
</pre>
<p>These implementations essentially do what I described in the previous section: implement a pointer approximation and integrate efficient searching.  (Read the paper for more details.)</p>
<h2>So What?</h2>
<p>Well, I used finger trees in funsat. They were faster than whatever I was doing before.</p>
<br />Filed under: <a href='http://obfuscatedcode.wordpress.com/category/haskell/'>haskell</a>, <a href='http://obfuscatedcode.wordpress.com/category/sat-solver/'>sat-solver</a> Tagged: <a href='http://obfuscatedcode.wordpress.com/tag/data-structures/'>data structures</a>, <a href='http://obfuscatedcode.wordpress.com/tag/heaps/'>heaps</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/48/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=48&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2011/03/04/functional-priority-queues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>Wondermark wonderland</title>
		<link>http://obfuscatedcode.wordpress.com/2009/11/21/wondermark-wonderland/</link>
		<comments>http://obfuscatedcode.wordpress.com/2009/11/21/wondermark-wonderland/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 16:10:59 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[fun]]></category>
		<category><![CDATA[comics]]></category>
		<category><![CDATA[wondermark]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=330</guid>
		<description><![CDATA[Wondermark is a webcomic that I enjoy reading. It is one of the few that I read consistently. You should read it. Here are a few choice ones that I enjoy: http://wondermark.com/566/ &#8212; supernatural collective nouns http://wondermark.com/554/ &#8212; mad libs http://wondermark.com/442/ &#8212; the best comeback ever http://wondermark.com/538/ &#8212; a popular show What&#8217;s your favorite Wondermark? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=330&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.wondermark.com">Wondermark</a> is a webcomic that I enjoy reading.  It is one of the few that I read consistently.  You should read it.</p>
<p>Here are a few choice ones that I enjoy:</p>
<ul>
<li><a href="http://wondermark.com/566/">http://wondermark.com/566/</a> &#8212; supernatural collective nouns</li>
<li><a href="http://wondermark.com/554/">http://wondermark.com/554/</a> &#8212; mad libs</li>
<li><a href="http://wondermark.com/442/">http://wondermark.com/442/</a> &#8212; the best comeback ever</li>
<li><a href="http://wondermark.com/538/">http://wondermark.com/538/</a> &#8212; a popular show</li>
</ul>
<p>What&#8217;s your favorite Wondermark?</p>
<br />Posted in fun Tagged: comics, wondermark <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/330/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=330&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2009/11/21/wondermark-wonderland/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>Converting RealMedia Audio to MP3</title>
		<link>http://obfuscatedcode.wordpress.com/2009/07/04/converting-realmedia-audio-to-mp3/</link>
		<comments>http://obfuscatedcode.wordpress.com/2009/07/04/converting-realmedia-audio-to-mp3/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 17:11:57 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[realmedia]]></category>
		<category><![CDATA[rm]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=320</guid>
		<description><![CDATA[I used mplayer and lame. MPlayer decodes the input rm audio stream into a WAVE file; lame encodes that to an mp3. Just save the following script to a file and run it on your favorite rm file. #!/bin/bash FILE="$1" OUTDIR="mp3" OUTPUT=$OUTDIR/`basename "$FILE" .rm`.mp3 # We use a fifo file so that encoding the mp3 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=320&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I used <a href="http://www.mplayerhq.hu/">mplayer</a> and <a href="http://lame.sourceforge.net/">lame</a>.  MPlayer decodes the input rm audio stream into a WAVE file; lame encodes that to an mp3.</p>
<p>Just save the following script to a file and run it on your favorite rm file.</p>
<blockquote><pre>#!/bin/bash

FILE="$1"

OUTDIR="mp3"
OUTPUT=$OUTDIR/`basename "$FILE" .rm`.mp3

# We use a fifo file so that encoding the mp3 with lame can start immediately
# after decoding with mplayer starts.
FIFO=rm2mp3.fifo

if ! test -f "$FILE"; then
    echo "error: '$FILE' does not exist"
    exit 1
fi
if ! test -p "$FIFO"; then
    mkfifo "$FIFO"
fi
if ! test -d "$OUTDIR"; then
    mkdir mp3
fi

echo "Input: '$FILE'"
echo "Output: '$OUTPUT'"
sleep 2 # Give time for user to kill if the input/output is wrong

# Show commands as they are executed.
set -x

# Send rm audio to fifo
mplayer -ao pcm:fast -ao pcm:file=$FIFO -vc null -vo null "$FILE" &gt;/dev/null 2&gt;&amp;1 &amp;

# Create MP3 from WAV
lame -h -V 6 $FIFO "$OUTPUT"

rm -f "$FIFO"
</pre>
</blockquote>
<p>Please send along any improvements (such as better flags for mplayer/lame).</p>
<br />Posted in Uncategorized Tagged: mp3, realmedia, rm <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/320/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=320&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2009/07/04/converting-realmedia-audio-to-mp3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>Dealing with Data Corruption with GIT, or, I&#8217;m Famous!</title>
		<link>http://obfuscatedcode.wordpress.com/2009/03/09/dealing-with-data-corruption-with-git-or-im-famous/</link>
		<comments>http://obfuscatedcode.wordpress.com/2009/03/09/dealing-with-data-corruption-with-git-or-im-famous/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 04:03:40 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[corruption]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=54</guid>
		<description><![CDATA[I store all the data I care about in git. Not so recently I had updated a few files in one of my repositories when my computer kernel panic&#8216;d. Right before the panic I was getting ready to push my changes into a backup repository on another machine. Upon reboot I went to do this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=54&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I store all the data I care about in <a href="http://git-scm.com/">git</a>.  Not so recently I had updated a few files in one of my repositories when my computer <a href="http://en.wikipedia.org/wiki/Kernel_panic">kernel panic</a>&#8216;d.  Right before the panic I was getting ready to push my changes into a backup repository on another machine.  Upon reboot I went to do this when git noticed what turned out to be data corruption.</p>
<p>One minor aside: if I had been using any of some other VCSs, one that did not hash whatever I put into it, I probably wouldn&#8217;t have to deal with this problem.  But then I would only notice the corruption much later, when I&#8217;ve forgotten all the changes, and I run into some hard-to-diagnose problem.  Dealing with this up front is definitely better.</p>
<p>This prompted <a href="http://kerneltrap.org/mailarchive/git/2008/6/10/2085274">a thread</a> on the git mailing list (the post contains a detailed description of the symptoms).  The problem was that two git objects corresponding to two different, recent commits in my repository had been corrupted.  Now, there are several ways one can proceed when <a href="http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#recovering-from-repository-corruption">dealing with corruption</a>, in ascending order of simplicity:</p>
<ol>
<li>Copy the corrupted objects from a backup repository.</li>
<li><strong>Replace the offending commit with a new commit altogether, re-creating <em>approximately</em> the same changes.</strong></li>
<li>Re-create <em>exactly</em> the changes that turn the commit-before-offending-commit into the offending commit.</li>
</ol>
<p>I couldn&#8217;t take option 1, because I didn&#8217;t have a backup; and I couldn&#8217;t take option 3 because I didn&#8217;t remember the exact changes between the previous and offending commits.  So I had to go with 2.  This option, incidentally, is an option that is not covered explicitly in the relevant section of the manual.  Also, as I usually commit early and often, it was pretty easy for me to reproduce these changes.</p>
<h2>Replacing a Corrupted Commit</h2>
<p>As noted in the thread, my git repository was in the following state:</p>
<blockquote><p>
<code>$ git fsck --full<br />
    error: 320bd6e82267b71dd2ca7043ea3f61dbbca16109: object corrupt or missing<br />
    missing blob 320bd6e82267b71dd2ca7043ea3f61dbbca16109<br />
</code></p></blockquote>
<p>Jakub Narebski was kind enough to <a href="http://kerneltrap.org/mailarchive/git/2008/6/10/2085624">explain</a> with diagrams how this is done.  Assume that <code>A</code> is the SHA1 ID of the commit preceding the corrupt commit, and <code>B</code> is the ID of the commit immediately following.  First, create a new branch, here called <code>corruption</code>, whose head is the commit before the corrupt commit.</p>
<blockquote><pre>
$ git checkout -b corruption A
$ ... edit edit edit ...
$ git commit -a -m &lt;something-like-corrupted-commit-msg&gt;
</pre>
</blockquote>
<p>The next step is teaching the git repository to ignore the corrupted commit.  To accomplish this we use the undocumented grafts file.  Conceptually, this file is extremely simple.  It consists of any number of entries, one per line.  Each entry is of the form:</p>
<blockquote><pre>&lt;sha1-id&gt; &lt;sha1-id&gt;*</pre>
</blockquote>
<p>that is, a SHA1 ID followed by zero or more IDs.  The effect of this is that <em>in your local repository</em>, git will treat the first named object as having the parents given.  In this way we can trick git, by adding the entry:</p>
<blockquote><pre>
$ echo B '&lt;new-commit&gt;' &gt;&gt; .git/info/grafts
</pre>
</blockquote>
<p>At this point, switch back to master.</p>
<blockquote><pre>
$ git checkout master
$ git fsck --full</pre>
</blockquote>
<p>There should be no errors.  (There might be warnings.)</p>
<p>Unfortunately, this is not the whole story.  The grafts file is purely a local measure.  Every clone of this repository will still have the corruption.  So we have to teach git to write the grafts information directly into the history.  Enter <code>git filter-branch</code>.</p>
<h2>Replacing a Corrupted Commit For All Time</h2>
<p><code>git filter-branch</code> rewrites history while allowing filters to alter the history.  We&#8217;ll use it to carve the grafts file into an actual git history.</p>
<blockquote><pre>(on master)
$ git filter-branch HEAD
Rewrite  (3/3)
Ref 'refs/heads/master' was rewritten</pre>
</blockquote>
<p>Now the clones should use the new history.  Voilà!</p>
<h2>You shouldn&#8217;t lie about being famous</h2>
<p>Behold, recorded for all time in the <a href="http://git.kernel.org/?p=git/git.git;a=commit;h=e9039dd35194b7c1cf4ecd479928638166b8458f">git source tree</a>:</p>
<blockquote><pre>
commit e9039dd35194b7c1cf4ecd479928638166b8458f
Author: Linus Torvalds
Date:   Tue Jun 10 18:47:18 2008 -0700

    Consolidate SHA1 object file close

    This consolidates the common operations for closing the new
    temporary file that we have written, before we move it into
    place with the final name.

    There's some common code there (make it read-only and check
    for errors on close), but more importantly, this also gives a
    single place to add an fsync_or_die() call if we want to add
    a safe mode.

    This was triggered due to Denis Bueno apparently twice being
    able to corrupt his git repository on OS X due to an unlucky
    combination of kernel crashes and a not-very-robust
    filesystem.

    Signed-off-by: Linus Torvalds
    Signed-off-by: Junio C Hamano
</pre>
</blockquote>
<p>Also, I think I&#8217;m the reason for a recent patch adding a new git configuration option, <code>core.fsyncobjectfiles</code>, described as:</p>
<blockquote><p>This is a total waste of time and effort on a filesystem that orders data writes properly, but can be useful for filesystems that do not use journalling (traditional UNIX filesystems) or that only journal metadata and not file contents (OS X&#8217;s HFS+, or Linux ext3 with &#8220;data=writeback&#8221;).</p></blockquote>
<br />Posted in howto Tagged: corruption, git <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=54&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2009/03/09/dealing-with-data-corruption-with-git-or-im-famous/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>Linear-time First UIP calculation</title>
		<link>http://obfuscatedcode.wordpress.com/2009/03/09/linear-time-first-uip-calculation/</link>
		<comments>http://obfuscatedcode.wordpress.com/2009/03/09/linear-time-first-uip-calculation/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 03:12:03 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[sat-solver]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[learning]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=112</guid>
		<description><![CDATA[In a previous post I mentioned I was using a super-linear algorithm for calculating the first unique implication point (UIP) learned clause in funsat. The algorithm basically uses the definition of first UIP and requires calculating graph dominators of an explicitly-constructed conflict graph. By contrast, the linear-time algorithm described in the Minisat paper never explicitly [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=112&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://obfuscatedcode.wordpress.com/2008/04/18/a-modern-sat-solver-in-haskell/">a previous post</a> I mentioned I was using a super-linear algorithm for calculating the first unique implication point (UIP) learned clause in <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/funsat">funsat</a>.  The algorithm basically uses the definition of first UIP and requires calculating graph dominators of an explicitly-constructed conflict graph.  By contrast, the linear-time algorithm described in the <a href="http://minisat.se/downloads/MiniSat.ps.gz">Minisat paper</a> never explicitly constructs the graph, it merely inspects the trail in reverse, figuring out which literals should be inserted in the conflict clause using the reasons for each assignment.  The former algorithm has the advantage that it implements what it means to calculate the first UIP clause; in other words, it&#8217;s easily seen as a correct implementation.  The latter isn&#8217;t, but when it works, it&#8217;s faster and leaner.</p>
<p>The Minisat paper only gives lightly documented pseudocode for the algorithm.  There are no data structure invariants nor proof of correctness.  Here&#8217;s my attempt at explaining how and why it works.</p>
<p>The <em>implication graph</em> is described well in this <a href="http://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf">handbook chapter</a>.  Basically, it is a directed graph in which the nodes are literals from the assignment, and an edge <em>x</em> &rarr; <em>y</em> indicates the assignment <em>x</em> helped propagate the assignment <em>y</em>.</p>
<blockquote><p>A UIP of an implication graph is a node at the current decision level <em>d</em> such that every path from the decision variable at level <em>d</em> to the conﬂict variable or its negation must go through it. Intuitively, it is a single reason at level <em>d</em> that causes the conﬂict. (This paragraph is from <a href="http://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf">the same chapter</a>.)</p></blockquote>
<p>There may be many UIPs for the current decision level.  The last decision variable is always a UIP.  The <em>first UIP</em> is one with the shortest path to the conflict node.</p>
<p>From the UIP definition it is clear why graph dominators are involved: every UIP is a dominator of the conflict variables with respect to the last decision variable.  My first implementation explicitly calculated those dominators, and chose the one closest to the conflict nodes.</p>
<p>Once the desired UIP is found, we have to calculate the corresponding learned clause.  It turns out that good learned clauses correspond to <a href="http://en.wikipedia.org/wiki/Graph_cut">cuts</a> of the implication graph during a conflict (this is often called the conflict graph).  The learned clause corresponding to a cut (S,T) is the set of nodes that are cut edge sources.  Formally, this is the set <img src='http://s0.wp.com/latex.php?latex=%5C%7Bx+%5Cin+S+%7E%7C%7E+%5Cexists+y+%5Cin+T.++x+%5Crightarrow+y+%5C%7D&amp;bg=e6e6e6&amp;fg=333333&amp;s=0' alt='&#92;{x &#92;in S ~|~ &#92;exists y &#92;in T.  x &#92;rightarrow y &#92;}' title='&#92;{x &#92;in S ~|~ &#92;exists y &#92;in T.  x &#92;rightarrow y &#92;}' class='latex' />.  To tie the knot, one only need know that the UIP <em>u</em> determines the cut (S,T) where T = <img src='http://s0.wp.com/latex.php?latex=%5C%7Bx+%7E%7C%7E+%5Ctext%7Bthere+is+a+path+of+length+at+least+1+from+%7D+u+%5Ctext%7B+to+%7D+x%5C%7D&amp;bg=e6e6e6&amp;fg=333333&amp;s=0' alt='&#92;{x ~|~ &#92;text{there is a path of length at least 1 from } u &#92;text{ to } x&#92;}' title='&#92;{x ~|~ &#92;text{there is a path of length at least 1 from } u &#92;text{ to } x&#92;}' class='latex' />.  This information is sufficient to calculate the learned clause corresponding to a UIP.</p>
<p>The <em>trail</em> is the current assignment arranged in reverse chronological unit-propagation order (last assigned first out).  The <em>reason</em> for a literal q is the set <img src='http://s0.wp.com/latex.php?latex=%5C%7Bx+%7E%7C%7E+%5Ctext%7Bthe+edge+%7D+x+%5Crightarrow+q+%5Ctext%7B+is+part+of+the+implication+graph%7D+%5C%7D&amp;bg=e6e6e6&amp;fg=333333&amp;s=0' alt='&#92;{x ~|~ &#92;text{the edge } x &#92;rightarrow q &#92;text{ is part of the implication graph} &#92;}' title='&#92;{x ~|~ &#92;text{the edge } x &#92;rightarrow q &#92;text{ is part of the implication graph} &#92;}' class='latex' />.</p>
<h2>Algorithm</h2>
<p>The algorithm outputs a learned clause (sequence of literals).  There are a few important variables and conventions for the following pseudocode:</p>
<ul>
<li>
<em>p</em> &#8212; Invariant: literal from the current decision level, initially the propagated literal that caused the conflict.  The top of the trail is not <em>p</em>.
</li>
<li><em>c</em> &#8212; Invariant: number of unprocessed but seen variables from current decision level, initially 0.</li>
<li>We can mark a variable as seen.  All variables are initially unseen.</li>
<li>Every literal included in the learned clause has sign opposite what it does under the current assignment.  (In the case of the conflicting literal, we include its negation.)</li>
</ul>
<p>Onto the pseudocode:</p>
<blockquote><p>
<em>Process literals starting with p until we process all the literals we see at the current decision level.</em><br />
<strong>do</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp; <em>Process literal p:</em><br />
&nbsp;&nbsp;&nbsp;&nbsp; <strong>foreach</strong> literal q <strong>in</strong> the reason for p<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> <em>var</em>(q)<sup>1</sup> is unseen<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; mark <em>var</em>(q) seen<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> q is from the current decision level<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; increment c<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <strong>else if</strong> q is from a lower decision level<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; add q to the learned clause</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <em>Select the next interesting literal to follow:</em><br />
&nbsp;&nbsp;&nbsp;&nbsp; <strong>do</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; assign p to head of trail<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; undo head of trail<br />
&nbsp;&nbsp;&nbsp;&nbsp; <strong>while</strong> <em>p</em> is unseen<br />
&nbsp;&nbsp;&nbsp;&nbsp; decrement c</p>
<p><strong>while</strong> c &gt; 0</p>
<p>By now, <em>p</em> is the first UIP node of the current decision level.  Add the negation of <em>p</em> to the learned clause and output it.</p></blockquote>
<p><sup>1</sup> <em>var(x)</em> is the variable corresponding to the literal <em>x</em>.</p>
<h2>Correctness</h2>
<p>The algorithm performs a backwards breadth-first search for the first UIP node.  The trail is the BFS queue.  The counter allows us to deduce when <em>p</em> is the closest dominator of the conflict variable.  Recall that a node&#8217;s being seen means having been discovered as a reason during another node&#8217;s processing.  At the bottom of the loop, the counter contains the number of unprocessed but seen nodes we know about which end a reverse path from the conflict variable backwards consisting only of current-level nodes (say it three times fast).  When <em>c</em> reaches zero, it means there are no seen reverse paths back from the conflict node to the decision variable.  Since <em>p</em> is from the current decision level, however, it must have a path from the decision variable.  Therefore <em>p</em> must dominate all paths from the decision variable to the conflict variable.  <em>p</em> is a UIP node.  Moreover, since <em>p</em> is the first such node, it must be the first UIP node.</p>
<p>The first UIP learned clause is determined by the literals that cross the cut (S,T) determined by <em>p</em>, as indicated above.  Every proper descendant of <em>p</em> is on the T side of the cut.  Therefore, any lower-decision-level node must be on the S side of the cut.  (If such a node <em>x</em> were on the T side, there would be a path from the decision node for <em>d</em> to <em>x</em>, and <em>x</em> would have level <em>d</em>, contradicting the assumption that <em>x</em> has a lower decision level.)  The first such nodes encountered during traversal, as well as <em>p</em>, cross the cut.  The algorithm includes exactly these variables in the learned clause.</p>
<p><strong>Update 2011-12-24:</strong> Corrected algorithm to decrement <em>c</em> properly, as Peter reported in the comments.</p>
<br />Posted in haskell, sat-solver Tagged: algorithms, learning <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/112/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=112&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2009/03/09/linear-time-first-uip-calculation/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
		<item>
		<title>ICFP Contest 2008 &#8212; The One Liners</title>
		<link>http://obfuscatedcode.wordpress.com/2008/07/30/icfp-contest-2008-the-one-liners/</link>
		<comments>http://obfuscatedcode.wordpress.com/2008/07/30/icfp-contest-2008-the-one-liners/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 15:01:41 +0000</pubDate>
		<dc:creator>dbueno</dc:creator>
				<category><![CDATA[fun]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[icfp]]></category>

		<guid isPermaLink="false">http://obfuscatedcode.wordpress.com/?p=70</guid>
		<description><![CDATA[This year I participated in the International Conference on Functional Programming (ICFP) contest with a friend, Sooraj Bhat. Our team was The One Liners. As it is the fashion, and we found the exercise rewarding, here is our official ICFP 2008 post mortem. We used git to manage our source (tarball). Here are some basic [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=70&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This year I participated in the <a href="http://icfpcontest.org/">International Conference on Functional Programming</a> (ICFP) contest with a friend, <a href="http://www.cc.gatech.edu/~sooraj/">Sooraj Bhat</a>.  Our <a href="https://projects.cecs.pdx.edu/~jgmorris/icfpc08/index.cgi/wiki/TeamPages">team</a> was The One Liners.  As it is the fashion, and we found the exercise rewarding, here is our official ICFP 2008 post mortem.</p>
<p>We used <a href="http://git.or.cz/">git</a> to manage <a href="http://churn.ath.cx:8080/?p=icfp2008.git;a=summary">our source</a> (<a href="http://www.cc.gatech.edu/~sooraj/one-liners-icfp08.tgz">tarball</a>).  Here are some basic statistics:</p>
<ul>
<li>We wrote 447 lines of <a href="http://www.haskell.org">Haskell</a> (generated using <a href="http://www.dwheeler.com/sloccount/">David A. Wheeler&#8217;s &#8216;SLOCCount&#8217;</a>).</li>
<li>Individual commits: 206 (me), 41 (Lazy<sup>*</sup>)</li>
<li>Changed lines: 120620 (me), 2953 (Sleepy)</li>
</ul>
<h2>Introduction</h2>
<p><a href="http://smlnj.org/icfp08-contest/task.html">The task</a> was to write software to control a Mars rover and make it to home base, while avoiding three types of obstacles: boulders, craters, and martians.  The rover would ricochet after hitting a boulder, fall into craters, and get captured by martians.  Thus, you really want to try avoiding all obstacles if you can, although boulders are the least penalising.  Our basic strategy was to accelerate toward home base unless there was an obstacle along that path.  If there was an obstacle, we&#8217;d pick a point to the left or the right of it, and go there, preferring directions we were already facing.</p>
<p>We chose Haskell because we&#8217;re both functional programming nuts.  It worked out well.  A priori, I thought speed would be an issue, but, we never used more than 2% of our processor (both of us had dual core machines), whereas the server was close to 100% constantly.  Our model of the world is basically a list of all known, static objects (boulders and craters).  The collision avoidance code looks through this list, looking for the closest object to avoid.  I know that some other teams had cleverer obstacle representations (like <a href="http://en.wikipedia.org/wiki/Quadtree">quadtrees</a>), to get the nearest obstacle more quickly.  But it appears not to have been necessary, at least on the maps provided by the contest organisers.</p>
<h2>A Sad Tale</h2>
<p>When the contest started, we got right to work.  Sooraj went off to get lunch for three hours, and I prepared <a href="http://churn.ath.cx:8080/?p=icfp2008.git;a=blob_plain;f=bin/test-submission;hb=cd7dafd546ed260dfb8e1d9fdc8e497844691364">a script</a> that would make a tarball of the repo from HEAD, and test each of the contest requirements (the README, bin/install, etc. are present and non-empty).  I then wrote <a href="http://churn.ath.cx:8080/?p=icfp2008.git;a=blob_plain;f=bin/install;hb=cd7dafd546ed260dfb8e1d9fdc8e497844691364"><code>bin/install</code></a>, which attempted to build our source using only the (paltry number of) packages available on the LiveCD.</p>
<p>Since one of the requirements was that <code>bin/install</code> should not attempt to write outside of the <code>icfp08</code> directory, I planned to use the <code>--package-db</code> and <code>--prefix</code> Cabal flags to make it compile and install all the libraries to a place under <code>icfp08</code>.  This was a great idea, except that every release of Cabal has bugs with this flag.  (I did not realise this until several hours into trying this out.)  Duncan Coutts (<code>dcoutts</code> on <code>#haskell</code>) was kind enough to apply a patch from the bleeding edge Cabal (1.5 branch) to the 1.4 branch for me, fixing the issue (I found out later it was only part of the issue, unfortunately).  After a while, I stopped, confident I could probably figure it out later, and had better actually think about the problem.</p>
<p>Around 1330 EDT on Monday 14 July, we started preparing our submission.  I again went to work trying to convince Cabal to install to and read from the right places.  Every package built fine except <code>network</code>, which has some C glue code.  For some reason I never figured out, Cabal wasn&#8217;t passing the <code>-package-conf</code> flag to GHC in this case.</p>
<p>In any case, 40 minutes before contest end, when I was feverishly trying to figure out why this wasn&#8217;t working, a message was posted saying that network package would be available.  At that point I could have deleted 4 lines from bin/install and submitted, but I never saw the message.  (Sooraj didn&#8217;t see it either.  He was making cookies or something.  Oh yeah, he wasn&#8217;t subscribed to the mailing list.)  So, with great anguish, <em>we didn&#8217;t actually submit anything</em>.</p>
<p>In any case, we had a lot of fun, and here are our thoughts.</p>
<h2>Thoughts</h2>
<h4>What Worked</h4>
<ul>
<li>Since Sooraj is in Atlanta and I&#8217;m in New York, we used webcams and <a href="http://skype.com">Skype</a> for communication, and we were rarely not in communication.  We recommend microphones you don&#8217;t have to wear.</li>
<li>For tricky code, working together on the same code helped noticeably, instead of on independent subtasks.  It&#8217;s tempting to concentrate on the parallelism afforded by a team, but ours benefitted especially from <strong>synchronous</strong> activity.
<p>For example, <code>beeline</code> was the name of our tactic which, given a desired end position, generated rover commands to control the steering and acceleration to send us roughly in that direction.  I was working on this alone while Sooraj was working on other things, and both of us came up with mediocre half-solutions.  When we started working together things started clicking, and we produced shorter, simpler, and correct code.</p>
<p>However, for straightforward stuff, parallelism worked well.  For example, we needed code that would establish a TCP/IP connection and manage the incoming stream of messages, as well as send outgoing control messages.  Also, we needed a parser that would take a message and turn it into a convenient Haskell data type.  I worked on the former while Sooraj worked on the latter, and after an hour or two when we had finished, both had at most one bug.</li>
<li><strong>git-gui</strong>: Sooraj, aka, the four-hour-dinner man, had never used git.  git-gui, a graphical front-end for interacting with a git repository, made using git relatively painless.  Personally, I&#8217;ve always found GUIs for version control to be inhibiting, but git-gui gives me exactly what I want, 95% of the time.  I used it, too.</li>
</ul>
<h4>Advice for Next Time</h4>
<ul>
<li><strong>More testing tools</strong>: we later found out that other teams had come up with some neat tools for debugging and testing their rovers.  <a href="http://www.mattryall.net/blog/2008/07/icfp-programming-contest-2008">One team</a> even drew a map the same size as the rover&#8217;s, and on it had the rover&#8217;s heading vector and subgoal position marked.  We should have made a similar effort in making the modify-test-feedback loop tighter.  If we had, we would have found bugs earlier.</li>
<li>This particular task we think would benefit from a <strong>higher-level control</strong> interface. We should have come up with several types of <strong>explicit goals</strong> which reflect a high level structure, and which some series of translations turns into tactics over time.
<p>One way in which we did this right is by explicitly choosing a goal location (either the home base or to the side of the nearest obstacle) for the rover, and generating commands to meet that goal.  This is done by what we called the <code>sidestep</code> planner.  However, we do not do this for the acceleration of the rover &#8212; we mostly just accelerate as much as possible.  We should have come up with a way to describe acceleration goals, and planned using those.</li>
<li>Use a <strong>console logger</strong> that can separate output from different programmers.  This way each developer can insert his own debugging messages without creating a bunch of noise for the others.  It looks like <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hslogger">hslogger</a> would fit the bill nicely.  Early on in development, we used the Haskell equivalent of printf(), because that was really all we needed.  After our parsing and basic tactic infrastructure was in place, we really didn&#8217;t need a logger anymore, so we got rid of the output.</li>
<li>Have a <strong>quantitative, automatic way to assess progress over time</strong>, e.g. performance/score graphs.  We didn&#8217;t spend any time coming up with a way to store our results so that we could compare to them later.  This will save you time in the end, because you can quickly reject approaches that aren&#8217;t working.</li>
</ul>
<h4>Finally, our README</h4>
<p>For posterity.</p>
<blockquote><pre>
=== ICFP 2008 Contest Submission README ===

Team: The One Liners
Language: Haskell
Compiler: GHC 6.8.2

== Third Party Libraries ==

bytestring-0.9.1.0  --  Fast strings
Cabal-1.4.0.2       --  Build/package manager
mtl-1.1.0.1         --  Monad transformers
network-2.1.0.0     --  Network facilities
parsec-3.0.0        --  Parser combinators

== Overview of the modules / our strategy ==

Main --

Controller -- This contains our main logic.  The basic structure
    consists of a a low-level routine who is responsible for
    navigating to a specified location, and a high-level routine who
    is responsible for choosing subgoal locations to go to.

Controller.Util -- Generically useful support routines for our
    controller strategies.

Controller.World -- Any state that the controller wishes to
    persist between runs.

Protocol -- Basic datastructures that hold information from the
    messages.

Protocol.Wire -- Routines to read/write the messages from/to
    the network.

Data.Vector -- Vectors in R^2
</pre>
</blockquote>
<p>* &#8212; Warning: all denigrating comments toward Sooraj are more <del datetime="00">true</del> sarcastic than they appear.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/obfuscatedcode.wordpress.com/70/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/obfuscatedcode.wordpress.com/70/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/obfuscatedcode.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/obfuscatedcode.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/obfuscatedcode.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/obfuscatedcode.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/obfuscatedcode.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/obfuscatedcode.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/obfuscatedcode.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/obfuscatedcode.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/obfuscatedcode.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/obfuscatedcode.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/obfuscatedcode.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/obfuscatedcode.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/obfuscatedcode.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/obfuscatedcode.wordpress.com/70/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=obfuscatedcode.wordpress.com&amp;blog=958235&amp;post=70&amp;subd=obfuscatedcode&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://obfuscatedcode.wordpress.com/2008/07/30/icfp-contest-2008-the-one-liners/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0aa0013bf7a5451dfb36bbce25f75526?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbueno</media:title>
		</media:content>
	</item>
	</channel>
</rss>
