<?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:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Sententia cdsmithus</title>
	<atom:link href="http://cdsmith.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cdsmith.wordpress.com</link>
	<description>software, programming languages, and other ideas</description>
	<pubDate>Sat, 07 Jun 2008 06:05:19 +0000</pubDate>
	<generator>http://wordpress.org/?v=MU</generator>
	<language>en</language>
			<item>
		<title>Another Screenshot of the Ray Tracer</title>
		<link>http://cdsmith.wordpress.com/2008/06/06/another-screenshot-of-the-ray-tracer/</link>
		<comments>http://cdsmith.wordpress.com/2008/06/06/another-screenshot-of-the-ray-tracer/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 22:30:39 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=59</guid>
		<description><![CDATA[Some people are remarkably picky.  They actually want to see reflections in a ray tracer.  Can you believe that?  Here you go then!

       ]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Some people are remarkably picky.  They actually want to see reflections in a ray tracer.  Can you believe that?  Here you go then!</p>
<p><img src="http://cdsmith.files.wordpress.com/2008/06/screenshot-ray-tracer-1.png?w=356&h=403" alt="Ray Tracer Second Screen Shot" width="356" height="403" class="alignnone size-full wp-image-58" /></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/59/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/59/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=59&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/06/06/another-screenshot-of-the-ray-tracer/feed/</wfw:commentRss>
	
		<media:content url="http://cdsmith.files.wordpress.com/2008/06/screenshot-ray-tracer-1.png" medium="image">
			<media:title type="html">Ray Tracer Second Screen Shot</media:title>
		</media:content>
	</item>
		<item>
		<title>Ray Tracing in Haskell</title>
		<link>http://cdsmith.wordpress.com/2008/06/06/ray-tracing-in-haskell/</link>
		<comments>http://cdsmith.wordpress.com/2008/06/06/ray-tracing-in-haskell/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 16:03:44 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=55</guid>
		<description><![CDATA[I&#8217;m giving a talk at a user group meeting next week on how to program in Haskell.  Rather than just listing off language constructs, I wanted to motivate the whole thing with an actual application.  So that&#8217;s how I ended up spending yesterday afternoon writing a ray tracer in Haskell.  I&#8217;m certainly [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;m giving a talk at a user group meeting next week on how to program in Haskell.  Rather than just listing off language constructs, I wanted to motivate the whole thing with an actual application.  So that&#8217;s how I ended up spending yesterday afternoon writing a ray tracer in Haskell.  I&#8217;m certainly not the first to do so, nor the best, but I am writing this blog post to explain the process I went through.  I&#8217;ll try making this a literate Haskell post, so you can copy and paste it into a source file (extension <code>.lhs</code>) and run it.  The actual code is split into three (very short) modules, but this should work.</p>
<p>Some imports to start us off:</p>
<blockquote>
<pre>
&gt; import Data.Maybe (mapMaybe)
&gt; import Data.Function (on)
&gt; import Data.List (minimumBy)
&gt; import Data.Ix (range)
&gt; import Control.Monad (forM_)
&gt; import Graphics.UI.Gtk hiding (Color, Point, Object)
&gt; import qualified Graphics.UI.Gtk as GTK
</pre>
</blockquote>
<p>First, I built a couple basics of vector math.  Out of a desire to demonstrate some list manipulation functions in the presentation, my <code>Vector</code> type is simply <code>[Double]</code>.</p>
<blockquote>
<pre>
&gt; type Vector = [Double]
&gt;
&gt; (&lt;+&gt;)       = zipWith (+)
&gt; (&lt;-&gt;)       = zipWith (-)
&gt; (&lt;*&gt;)       = zipWith (*)
&gt; vlength u   = sqrt (sum (map (^2) u))
&gt; normalize u = map (/ vlength u) u
&gt; u .*. v     = sum (u &lt;*&gt; v)
&gt; k #*  v     = map (*k) v
</pre>
</blockquote>
<p>Since vectors don&#8217;t really even approximate a ring, it seems quite inappropriate to call them <code>Num</code>.  Therefore, I&#8217;ve invented my own operators.  The operators in angle brackets are component-wise, while the normal dot and scalar products are given their own operators, <code>.*.</code> and <code>#*</code>, respectively.  I found this to be quite usable, though it would be equally reasonable to eschew operators, and define these as named functions to be used in infix notation.</p>
<p>I then define a few precedences, to make these easier to use.</p>
<blockquote>
<pre>
&gt; infixl 6 &lt;+&gt;
&gt; infixl 6 &lt;-&gt;
&gt; infixl 7 &lt;*&gt;
&gt; infixl 7 .*.
&gt; infixl 7 #*
</pre>
</blockquote>
<p>I&#8217;ll treat points as displacement vectors from an origin, and colors as vectors in a color space, but it helps to use separate names for them when writing type signatures:</p>
<blockquote>
<pre>
&gt; type Point = Vector
&gt; type Color = Vector
</pre>
</blockquote>
<p>Now for a few real data types.  The idea is that an object has some general-purpose properties, plus a shape.  The shape could be arbitrary, but is currently limited to only spheres and infinite planes.  (Hey, this talk is only an hour and a half long!)  So I&#8217;ve separated it out.  The other properties I&#8217;ve got are material properties: how shiny (that is, reflective) is the surface, and what is its color.  These are defined as functions from a point in space to the desired values, but in practice I&#8217;m just going to use <code>const</code>.</p>
<blockquote>
<pre>
&gt; data Object = Obj          { shape       :: Shape,
&gt;                              objectColor :: Point -&gt; Color,
&gt;                              objectShine :: Point -&gt; Double }
&gt;
&gt; data Shape  = Sphere       { center  :: Point, radius      :: Double }
&gt;             | Plane        { point   :: Point, normal      :: Vector }
</pre>
</blockquote>
<p>And lights are important to.  Right now, I&#8217;ve got point lights and ambient lights.  Adding directed lights (e.g. spot lights) wouldn&#8217;t be too difficult, but it is neither of critical importance nor necessary to demonstrate a Haskell language idea, so I&#8217;ve left it out.</p>
<blockquote>
<pre>
&gt; data Light  = PointLight   { lightPt :: Point, lightColor  :: Color  }
&gt;             | AmbientLight { lightColor :: Color                     }
</pre>
</blockquote>
<p>The two things we need to know about any shape are how to compute the distance to it along a given ray (specified by origin and a unit direction vector), and how to find the normal (another unit vector) at a given point on the surface of the object.  These next two functions do this.  They are defined for spheres and planes, but can of course be extended to new variants of <code>Shape</code> via additional pattern matching.</p>
<blockquote>
<pre>
&gt; shapeDistance :: Shape -&gt; Point -&gt; Vector -&gt; Maybe Double
&gt;
&gt; shapeDistance (Sphere c r) orig dir =
&gt;     let p    = orig &lt;+&gt; (c &lt;-&gt; orig) .*. dir #* dir
&gt;         d_cp = vlength (p &lt;-&gt; c)
&gt;         d    = vlength (p &lt;-&gt; orig) - sqrt (r^2 - d_cp^2)
&gt;         ans | d_cp &gt;= r                 = Nothing
&gt;             | (p &lt;-&gt; orig) .*. dir &lt;= 0 = Nothing
&gt;             | otherwise                 = Just d
&gt;     in  ans
&gt;
&gt; shapeDistance (Plane p n) orig dir
&gt;     | dir .*. n &gt;= 0  = Nothing
&gt;     | otherwise       = Just (((p &lt;-&gt; orig) .*. n) / (dir .*. n))
&gt;
&gt; shapeNormal :: Shape -&gt; Point -&gt; Vector
&gt; shapeNormal (Sphere c r) pt = normalize (pt &lt;-&gt; c)
&gt; shapeNormal (Plane p n)  pt  = n
</pre>
</blockquote>
<p>The math there can be derived without a whole lot of trouble, provided you&#8217;re relatively familiar with the basic ideas of vector operations.  It surprises me, though, how many people only understand dot products in terms of their implementation (the sum of the component-wise products, or <i>a b </i>cos(<i>theta</i>)), and not in terms of what they mean.  In particular, when one of the vectors in a dot product is a unit vector, the dot product is the component of the other vector along the direction of the unit vector.  That&#8217;s a pretty powerful tool to have.</p>
<p>Next come the lights.  For the lights, the general question is how much (in each color component) the given light illuminates a particular point with a particular normal.  The object list is needed here as well, since lights can be occluded.  This is all captured in a function <code>applyLight</code>, which is implemented for each type of light.  It&#8217;s trivial for ambient lights, since by definition they ignore all the specifics of the situation; but it&#8217;s non-trivial for point lights.  I also fence all light components to eliminate &#8220;negative&#8221; lights.</p>
<blockquote>
<pre>
&gt; fence a b x | x &lt; a     = a
&gt;             | x &gt; b     = b
&gt;             | otherwise = x
&gt;
&gt; applyLight :: [Object] -&gt; Point -&gt; Vector -&gt; Light -&gt; Vector
&gt; applyLight objs pt n (PointLight lpt color) =
&gt;     let dir   = normalize (lpt &lt;-&gt; pt)
&gt;         dist  = vlength   (lpt &lt;-&gt; pt)
&gt;         lval  = (n .*. dir) / dist^2 #* color
&gt;         final = map (fence 0 9999) lval
&gt;     in  case findNearest objs pt dir of
&gt;             Just (_,opt)
&gt;                 | vlength (opt &lt;-&gt; pt) &lt; dist -&gt; [0,0,0]
&gt;                 | otherwise                   -&gt; final
&gt;             Nothing                           -&gt; final
&gt;
&gt; applyLight objs pt n (AmbientLight color) = color
</pre>
</blockquote>
<p>Now for the common stuff.  A very common thing we want is to take our list of objects and find the nearest point of intersection for a given ray.  This function does that, by calling <code>objectDistance</code> for each object in turn, and then choosing the minimum one.  It gives back <code>Nothing</code> if there is no intersection, or <code>Just (obj,point)</code> if there is.</p>
<blockquote>
<pre>
&gt; findNearest :: [Object] -&gt; Point -&gt; Vector -&gt; Maybe (Object, Point)
&gt; findNearest objs orig dir =
&gt;         let consider obj = case shapeDistance (shape obj) orig dir of
&gt;                                 Nothing -&gt; Nothing
&gt;                                 Just d  -&gt; Just (obj, d)
&gt;             result = mapMaybe consider objs
&gt;         in  case result of
&gt;                 [] -&gt; Nothing
&gt;                 _  -&gt; let (obj,d) = minimumBy (compare `on` snd) result
&gt;                       in  Just (obj, orig &lt;+&gt; d #* dir)
</pre>
</blockquote>
<p>And finally, the ray tracing itself.  I&#8217;ve also thrown in <code>defaultColor</code>, which is the color assigned to rays that have either reflected back and forth beyond the recursion limit, or that proceed into infinity.  For now, this is always black.</p>
<blockquote>
<pre>
&gt; defaultColor :: Vector -&gt; Color
&gt; defaultColor _ = [0, 0, 0]
&gt;
&gt; trace :: [Object] -&gt; [Light] -&gt; Point -&gt; Vector -&gt; Int -&gt; Color
&gt; trace objs lights orig dir 0     = defaultColor dir
&gt; trace objs lights orig dir limit =
&gt;     case findNearest objs orig dir of
&gt;         Nothing        -&gt; defaultColor dir
&gt;         Just (obj, pt) -&gt;
&gt;             let n        = shapeNormal (shape obj) pt
&gt;                 ndir     = dir &lt;-&gt; 2 * (n .*. dir) #* n
&gt;                 refl     = trace objs lights pt ndir (limit - 1)
&gt;                 color    = objectColor obj pt
&gt;                 shine    = objectShine obj pt
&gt;                 lvals    = map (applyLight objs pt n) lights
&gt;                 lighting = (foldl (&lt;+&gt;) [0,0,0] lvals)
&gt;                 in_light = shine #* refl &lt;+&gt; (1 - shine) #* lighting
&gt;             in map (fence 0 1) (color &lt;*&gt; in_light)
</pre>
</blockquote>
<p>Finally, there&#8217;s the GUI stuff.  I won&#8217;t discuss this much, except to say that it&#8217;s horridly bad.  I&#8217;m doing the actual ray tracing in an <code>onExpose</code> event handler.  If I had even a modicum of common sense, I&#8217;d be rendering to an image or something, so that I wouldn&#8217;t have to redo all the ray tracing just because you switched over to a different window.  Oh well.  I&#8217;ll improve this before the talk on Tuesday.</p>
<blockquote>
<pre>
&gt; objs = [
&gt;     Obj (Sphere [-50, -50, 100] 100)
&gt;         (const [1.0, 0.3, 1.0])
&gt;         (const 0.1),
&gt;     Obj (Sphere [ 50,  50, 100] 100)
&gt;         (const [0.2, 1.0, 0.2])
&gt;         (const 0.1),
&gt;     Obj (Plane [-100,100,0] (normalize [1,-0.2,-0.2]))
&gt;         (const [1.0,1.0,1.0])
&gt;         (const 0.0)
&gt;     ]
&gt;
&gt; lights = [ PointLight   [175, -200, 10] [40000.0, 20000, 20000],
&gt;            AmbientLight                [0.0, 0.05, 0.1]
&gt;          ]
&gt;
&gt; drawScene d ev = do
&gt;     dw    &lt;- widgetGetDrawWindow d
&gt;     (w,h) &lt;- widgetGetSize d
&gt;     gc    &lt;- gcNew dw
&gt;
&gt;     let eye = [0, 0, -500]
&gt;
&gt;     forM_ (range ((0,0), (w-1, h-1))) $ \(x,y) -&gt; do
&gt;         let (x&apos;, y&apos;) = (fromIntegral x - fromIntegral w / 2,
&gt;                         fromIntegral y - fromIntegral h / 2)
&gt;         let [r,g,b]  = trace objs lights eye
&gt;                              (normalize ([x',y',0] &lt;-&gt; eye)) 5
&gt;         let fg       = GTK.Color (round (65535 * r))
&gt;                                  (round (65535 * g))
&gt;                                  (round (65535 * b))
&gt;         gcSetValues gc $ newGCValues { foreground = fg }
&gt;         drawPoint dw gc (x,y)
&gt;     return True
&gt;
&gt; main = do
&gt;     initGUI
&gt;     w &lt;- windowNew
&gt;     d &lt;- drawingAreaNew
&gt;     windowSetTitle w &quot;Ray Tracer&quot;
&gt;     containerAdd   w d
&gt;     onExpose  d (drawScene d)
&gt;     onDestroy w mainQuit
&gt;     widgetShowAll w
&gt;     mainGUI
</pre>
</blockquote>
<p>And there you go: a ray tracer!  Of course, there are many things that ought to be improved.  They range from the trivial (render to an off-screen image, perhaps save to an image file, and read from a file instead of coding the scene as an immediate data structure) to the very complex (implement diffuse effects, more complex interpolated curves, etc.).  But as a quick demo goes, this one didn&#8217;t turn out so bad.</p>
<p><img src="http://cdsmith.files.wordpress.com/2008/06/screenshot-ray-tracer.png?w=400&h=400" alt="Screenshot" width="400" height="400" class="aligncenter size-full wp-image-57" /></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/55/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/55/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/55/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=55&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/06/06/ray-tracing-in-haskell/feed/</wfw:commentRss>
	
		<media:content url="http://cdsmith.files.wordpress.com/2008/06/screenshot-ray-tracer.png" medium="image">
			<media:title type="html">Screenshot</media:title>
		</media:content>
	</item>
		<item>
		<title>Some video talks on programming topics</title>
		<link>http://cdsmith.wordpress.com/2008/06/04/some-video-talks-on-programming-topics/</link>
		<comments>http://cdsmith.wordpress.com/2008/06/04/some-video-talks-on-programming-topics/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 01:51:29 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=54</guid>
		<description><![CDATA[Last Thursday, I attended a meeting of the Colorado Springs Open Source Meetup Group.  I ended up offering to record and post videos of the presentations.  They are now available.  Matthew McCullough&#8217;s presentation on JavaFX is here, and Scott Ryan&#8217;s presentation on jQuery is here.  I should mention that I had [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Last Thursday, I attended a meeting of the <a href="http://opensource.meetup.com/88/">Colorado Springs Open Source Meetup Group</a>.  I ended up offering to record and post videos of the presentations.  They are now available.  Matthew McCullough&#8217;s presentation on JavaFX is <a href="http://video.google.com/videoplay?docid=7782106820957909146&amp;hl=en">here</a>, and Scott Ryan&#8217;s presentation on jQuery is <a href="http://video.google.com/videoplay?docid=5969491928662400587&amp;hl=en">here</a>.  I should mention that I had absolutely nothing to do with either of these presentations, except that I showed up with the video camera and microphone.  This was a test run for recording my presentations at <a href="http://www.csplat.org/">C-SPLAT</a> (the Colorado Springs Programming Languages and Tools interest group) next week.  So as far as content goes, I take no responsibility for inaccuracies or unusual views expressed in the talks.</p>
<p>As test runs go, all was pretty smooth.  The biggest problem was that Google Video has been having some problems, and took most of a week to actually make the videos available for viewing after I uploaded them.  Also, Google&#8217;s processing reduced the quality to the point that you can&#8217;t easily read the presentation slides.  Next time around, I might see about seeding them in BitTorrent as well as uploading to Google Video; and of course I&#8217;ll make my slides available in PDF alongside the video.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/54/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/54/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=54&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/06/04/some-video-talks-on-programming-topics/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Web Site Issues: Resolution</title>
		<link>http://cdsmith.wordpress.com/2008/06/04/web-site-issues-resolution/</link>
		<comments>http://cdsmith.wordpress.com/2008/06/04/web-site-issues-resolution/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 01:50:08 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=53</guid>
		<description><![CDATA[Well, after the catastrophic failure of my web site earlier this week, I&#8217;ve put everything back at http://www.pphsg.org/cdsmith.
In case you&#8217;re wondering, the PPHSG is a group I started in 2001 to organize science and math education activities for home-schooled children.  At the time, I had a neighbor who was home-schooling.  The PPHSG still [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Well, after the catastrophic failure of my web site earlier this week, I&#8217;ve put everything back at <a href="http://www.pphsg.org/cdsmith/">http://www.pphsg.org/cdsmith</a>.</p>
<p>In case you&#8217;re wondering, the PPHSG is a group I started in 2001 to organize science and math education activities for home-schooled children.  At the time, I had a neighbor who was home-schooling.  The PPHSG still continues to this day, but I&#8217;ve passed on leadership to some actual home-schooling parents who have decided not to use the web site.  So voila, instant replacement personal web site!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/53/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/53/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/53/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=53&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/06/04/web-site-issues-resolution/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Best Nigerian Scam Email Ever</title>
		<link>http://cdsmith.wordpress.com/2008/05/17/the-best-nigerian-scam-email-ever/</link>
		<comments>http://cdsmith.wordpress.com/2008/05/17/the-best-nigerian-scam-email-ever/#comments</comments>
		<pubDate>Sat, 17 May 2008 16:39:40 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=52</guid>
		<description><![CDATA[I just received this email.  The irony is great.

Subject: SCAMMED VICTIM COMPENSATION
Rev.Dr.Abraham Newman
Regional Director to Nigeria
International Drug and Terrorist Enforcement (IDTE)
United Nations Office,3 Whitehall Court
SW1A 2EL London U.K
Phone:+44 7045767393
Email: infoidte@yahoo.co.uk
Alt.stben09@gmail.com
Good day,
This is to bring to your notice that I,Rev.Dr.Abraham Newman, United Nations Regional Director to Nigeria representing the International Drug and Terrorist Enforcement (IDTE) [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I just received this email.  The irony is great.</p>
<blockquote><p>
<b>Subject: SCAMMED VICTIM COMPENSATION</b></p>
<p>Rev.Dr.Abraham Newman<br />
Regional Director to Nigeria<br />
International Drug and Terrorist Enforcement (IDTE)<br />
United Nations Office,3 Whitehall Court<br />
SW1A 2EL London U.K<br />
Phone:+44 7045767393<br />
Email: infoidte@yahoo.co.uk<br />
Alt.stben09@gmail.com</p>
<p>Good day,</p>
<p>This is to bring to your notice that I,Rev.Dr.Abraham Newman, United Nations Regional Director to Nigeria representing the International Drug and Terrorist Enforcement (IDTE) has been appointed by United Nation/International Financial &amp; Economic Crime Unit to Nigeria in association with AFRICA DEVELOPMENT BANK to pay 150 scammed victim&#8217;s the sum of $1000,000 USD (One million Dollars) each. You have been listed and approved for this payment as one of the scammed victims to be paid this amount in the second phase of the Economy Reform Project; I would like you to Provide/confirm your detail, so that your compensation would be paid out to you. Get back to me as soon as possible for more details on the immediate payments of your $1000, 000 USD compensations/Beneficiary funds.</p>
<p>According to the number of applicants at hand, 114 Beneficiaries has been paid, Most of the victims are from the United States while the rest are Europeans and Asians, and we still have more 36 left to be paid the compensations of $860,000 USD each. Your particulars was mentioned by one of the Syndicates who was arrested in Lagos, Nigeria as one of their victims of the operations, you are hereby warned not to communicate or duplicate this message to him/anyone for any reason what so ever as the Interpol is already on trace of the criminal. So keep it secret till they are all apprehended.</p>
<p>Other victims who have not been contacted can submit their application as well for scrutiny and possible consideration.</p>
<p>You can receive your compensations payments via ATM CASH CARD. I shall feed you with further modalities as soon as I hear from you.</p>
<p>Yours faithfully,<br />
Rev.Dr.Abraham Newman<br />
+44 7045767393
</p></blockquote>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/52/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/52/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/52/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=52&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/05/17/the-best-nigerian-scam-email-ever/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Why licenses don&#8217;t matter (and why they do)</title>
		<link>http://cdsmith.wordpress.com/2008/05/06/why-licenses-dont-matter-and-why-they-do/</link>
		<comments>http://cdsmith.wordpress.com/2008/05/06/why-licenses-dont-matter-and-why-they-do/#comments</comments>
		<pubDate>Tue, 06 May 2008 21:04:11 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=51</guid>
		<description><![CDATA[There&#8217;s a fairly long history in the free software and open source communities of being very interested in licensing.  It&#8217;s always been ironic to me, since free software is supposed to be about not exercising control over how people use your software.  Most recently, I read this article on whether the GPL can [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>There&#8217;s a fairly long history in the free software and open source communities of being very interested in licensing.  It&#8217;s always been ironic to me, since free software is supposed to be about not exercising control over how people use your software.  Most recently, I read <a href="http://blog.milkingthegnu.org/2008/05/dual-licensing.html">this article</a> on whether the GPL can be &#8220;revoked&#8221; on a project to which it has already been applied.  There are any number of other issues:  Can this library be used by that project?  Can I relicense your code to a less permissive license without making any substantial changes?  And so on&#8230;</p>
<p>I am of the opinion that the legal meaning of a license is completely irrelevant.  It doesn&#8217;t matter what someone has the legal ability to do.  It&#8217;s necessary to pay attention to the social influence and intentions of others.</p>
<h3>Example : MySQL</h3>
<p>Let me make the point by giving an example.  In fact, there&#8217;s one example that covers this very well.  Think about MySQL, the database company.  Yes, they are most definitely a company, with all the overriding profit motive that implies.  Profit motive isn&#8217;t bad; but it is a motive that might not align with your best interests.  They wrote this database, and released it under the GPL.  It made a big name for itself by being a &#8220;free&#8221; database.  In fact, at least until very recently, it was a really crappy database that couldn&#8217;t do basic stuff like transactions or handling reasonably complex SQL; the only reason you&#8217;ve ever heard of it is that it is &#8220;free&#8221;.  But it&#8217;s also dual licensed as a commercial database; and here&#8217;s the rub: ultimately, the GPL nature only matters if MySQL wants it to matter.  They let it matter when it means free publicity and a cult following; but when they see the opportunity for a profit, the GPL suddenly seems to grant you a lot fewer rights that you thought it did.  The legal and semantic machinery going on is rather elaborate; but it is not the point.  It&#8217;s only the excuse.  What it comes down to is this:</p>
<ol>
<li>MySQL can afford to hire a lawyer, and you probably can&#8217;t.</li>
<li>People accept MySQL as the expert on what &#8220;their&#8221; license means.</li>
</ol>
<p>What this means is this: if you use MySQL, you accept that you are at the mercy of MySQL&#8217;s whims.  If they decide you should give them money, you give them money.  In fact, it goes further than that.  As a test, some years ago, I approached a MySQL representative by email about one of the more peculiar and ridiculous re-interpretations of English words that they put forth.  In particular, I asked this.  Suppose I had an application (not free software itself) written in Java using JDBC; and that I distributed it with PostgreSQL, but since the application just uses simple SQL and JDBC, someone who uses my software might conceivably download MySQL and use that instead.  In fact, suppose I have customers who I suspect have done just that, since they prefer the administration tools for MySQL.  The response was a rather obtuse legal threat: something like &#8220;We can&#8217;t give you legal advice, but it&#8217;s always safest for you to buy a license.  The protection you get will be worth the investment.&#8221;  They want me to buy protection.  To bastardize a line from a Patricia Briggs book: And yes, just like the mafia, MySQL only protects you from themselves.</p>
<p>So if you have a free software application and the company doesn&#8217;t see any other reason to make a threat, then you may use MySQL.  But the other rights in the GPL are lost.  If you download MySQL and it interacts with some other (possibly non-free, possibly threatening to MySQL) application using publicly specified interfaces, MySQL feels they have the right to sue someone.  If you modify MySQL and try to distribute your changes, who knows what would happen?  And don&#8217;t imagine for a second that you could get away with forking the code, which is in the end the most fundamental free software right.  If you had any success, there would be lawyers knocking on your door before you could sneeze.</p>
<h3>Lessons from the example</h3>
<p>So this is the situation we&#8217;re in.  You may have legal rights granted to you by a document like the GPL (or BSD, or MIT, or Creative Commons, or&#8230;)  But because some other party holds some kind of power over you, you can&#8217;t really trust your ability to exercise those rights reliably.  Of course, there are many kinds of power involved here.  Not everyone is motivated by profit.  Some people are motivated by social status, or even a sincere desire to do good.  Power might include:</p>
<ol>
<li>Financial power.  You can&#8217;t hire a lawyer, a company profiting from their software can.</li>
<li>Presumed authority.  Since the software provider chose the license, people take their word on what it means.  This is regardless of the fact that in the free software world, virtually no one except major figureheads actually writes their own licenses.</li>
<li>Social expectations.  Even if I can get away with doing something that the author of the software doesn&#8217;t like, if they are going to be upset my it I&#8217;ll probably take a pass.  It would take a definite jerk to ignore the wishes of the person who did all that work and made it freely available to you.</li>
</ol>
<p>But whatever the kind of influence being wielded (and some of those kinds of influence are not entirely bad) the fact remains that you can&#8217;t tell everything about your ability to use software by the written license.</p>
<h3>What now?</h3>
<p>So how did we get here?  What do we do?</p>
<p>I think how we got here is that we&#8217;re computer programmers.  Computer programmers, by nature, tend to look for simple and unambiguous rules that define what is possible.  The license pretends to be that, and we miss that it&#8217;s a false set of rules.  It&#8217;s a set of rules only in theory, in an idealized sort of half-egalitarian, half Ayn Rand world, where everyone acts in their own best interests and has an equal understanding that others will too, and everyone is on equal footing in terms of the power they have to act in those interests.  Legal absolutism simply doesn&#8217;t translate into the real world, as much as we&#8217;d like to see it happen.</p>
<p>Instead, we need to realize what people have known since the beginning of time - but we&#8217;ve tried to forget.  It matters who you are dealing with.  We should take the time to find out the motivations of the people who build the things we use.  In particular, there are different kinds of groups of people building free or open-source software.  At least a few of them are as follows.  (Of course, I&#8217;m grabbing archetypes that no one will meet exactly.  There&#8217;s no intention that you can&#8217;t span a few of these groups.)</p>
<ul>
<li><b>Commercializers.</b> These are people who completely believe in their ability to turn a profit by building open source software.  They are often the dual-licensers, GPL+commercial, or sometimes the support sellers, or sometimes the people who build service businesses and use their software to provide those services.  In any case, the open source side is likely to use the GPL or a similar restrictive license just to stop the competition.  In its purest form, this sort of group doesn&#8217;t care about you unless you are making them a profit.  Maybe you&#8217;re actually paying them.  Maybe you&#8217;re getting your customers to pay them.  Maybe you&#8217;re giving them positive reviews and claims of popularity that they can use to take other people&#8217;s money.  Just make sure your intentions don&#8217;t conflict with their commercial interest.  This is the most dangerous group, as business sorts tend to believe it&#8217;s a perfectly normal &#8220;strategic decision&#8221; to make other people miserable.</li>
<li><b>Idealists.</b> Some groups are motivated by the pure idea that software should be free.  This certainly includes the entire GNU organization, and a number of others to boot.  The GPL license is pretty popular here.  The motivation is to make more software free.  If you aren&#8217;t building free software, this might be a good time to ask yourself if taking advantage of these people&#8217;s work is the right thing to do.  On the other hand, very few people are really extremists here.  No one is going to hate you for using gcc to compile and build closed commercial software; but you might be careful if the project is newer, and particularly if it&#8217;s a library licensed under the GPL, which is a clear sign that the authors don&#8217;t want you to do that.  (The legal meaning doesn&#8217;t matter; it wouldn&#8217;t be okay to use readline in a commercial product even if it turns out the license is unenforcable.)</li>
<li><b>Social Groups.</b> Often, free software is built by groups who are just having fun.  They want to develop ideas, work with other people, but avoid having obligations to customers or dealing with business concepts like marketing, payroll, etc.  Most of these groups will license software under the BSD or another very permissive license.  In less software-oriented groups, Creative Commons is also popular here.  They don&#8217;t care what you do with their software, so long as you don&#8217;t try to keep them from doing as they please.  Many groups of this form will be happy to hear that you are finding their software useful.  The biggest way to piss these people off is to adopt an attitude of entitlement.  If you avoid that, you&#8217;re fine.</li>
<li><b>Academics.</b> This last group is interested in writing the software for the sake of writing it, learning what they can from it, and moving on.  They will be thrilled if you use their software to solve other interesting problems.  (And I mean interesting in the academic sense.)  If you just have fun, they won&#8217;t mind.  If you commercialize it, expect an attitude of profound apathy.  There are academics who are interested in commercializing their work, but they don&#8217;t release their software with free licenses.  Most academic work tends to be released under BSD, MIT, or similar licenses.  In fact, it&#8217;s worth noting that both of those licenses are named after the major universities where they were originally written.</li>
</ul>
<h3>Licenses matter after all</h3>
<p>While I started this rant by saying that licenses don&#8217;t matter (in terms of the legal rights they grant you), it turns out that they actually matter quite a bit (because  it helps you tell what kind of group you&#8217;re working with).  This is important for using a project.  It&#8217;s also important for getting involved in a project.</p>
<p>Here&#8217;s a true story.  A few years back, I got involved in a group that was building libraries for C programming on an embedded device.  I write a lot of code for dealing with an LCD controlled, and built a graphics library and a user interface library on top of that.  Then one day, someone wanted to use our libraries to write a commercial application for these devices.  There followed a massive debate, wherein I realized that I had completely different goals than anyone else.  I&#8217;d just been having fun.  Others were talking about setting up a commercial dual license, deciding how to apportion the profits; or else insisting that we had built this to encourage free software, and we shouldn&#8217;t just give it away to people who would make money on the backs of our efforts.</p>
<p>The project had been licensed under the GPL.  In retrospect, I should have asked more questions about that before I got involved.  I just assumed it was the easy default choice, since it&#8217;s the license more people have heard of.  It turns out that some people in the project thought it mattered quite a bit.  Lesson: the license is a good way to get an initial idea of the kind of people you&#8217;ll be working with in a project.</p>
<p>Anyway, that&#8217;s my rant.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/51/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/51/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/51/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=51&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/05/06/why-licenses-dont-matter-and-why-they-do/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Solving a Logic Problem with Coq</title>
		<link>http://cdsmith.wordpress.com/2008/05/04/solving-a-logic-problem-with-coq/</link>
		<comments>http://cdsmith.wordpress.com/2008/05/04/solving-a-logic-problem-with-coq/#comments</comments>
		<pubDate>Sun, 04 May 2008 16:48:32 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=50</guid>
		<description><![CDATA[I&#8217;ve been playing around with the Coq proof assistant tool over the weekend.  Here&#8217;s an interesting problem and its solution proven with Coq.  I am by no means an expert in this.  I&#8217;ve used Coq for less than 6 hours at this point.  There are a lot of nicer tutorials out [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;ve been playing around with the <a href="http://coq.inria.fr/">Coq proof assistant tool</a> over the weekend.  Here&#8217;s an interesting problem and its solution proven with Coq.  I am by no means an expert in this.  I&#8217;ve used Coq for less than 6 hours at this point.  There are a lot of nicer tutorials out there, including the <a href="http://coq.inria.fr/V8.1/tutorial.html">one on the Coq web site</a>.  But this is an interesting motivating example, and I&#8217;m writing to share my experiences.</p>
<p>The puzzle I&#8217;ll solve here comes from <a href="http://www.johnpratt.com/items/puzzles/logic_puzzles.html">John Pratt&#8217;s page</a>.  A lot of supposed &#8220;logic puzzle&#8221; sites aren&#8217;t really logic puzzles at all, but just plays on words; but that one is okay.  Here&#8217;s the puzzle:</p>
<blockquote><p>
When asked her 3 children&#8217;s ages, Mrs. Muddled said that Alice is the youngest unless Bill is, and that if Carl isn&#8217;t the youngest then Alice is the oldest. Who is the oldest and who is the youngest?
</p></blockquote>
<p>The first step is to start up Coq.  In my case I&#8217;ve generally used <a href="http://coq.inria.fr/coqide/index.html">CoqIde</a>, which is a simple apt-get in Ubuntu.  However, for this blog post I&#8217;ll use the command-line <code>coq-interface</code> in hopes of more portability.  Let&#8217;s tell Coq a few of the basics of the problem, such as that there&#8217;s a domain of discourse, and it has three children in it named Alice, Bill, and Carl.</p>
<pre>
Section Ages.
Variable Child : Set.
Variable Alice : Child.
Variable Bill  : Child.
Variable Carl  : Child.
Variable Youngest : Child -&gt; Prop.
Variable Oldest   : Child -&gt; Prop.
</pre>
<p>The last two lines declare unary predicates for the domain of discourse, indicating whether a child is the youngest or the oldest.  Unfortunately, Coq doesn&#8217;t know some things that we&#8217;re assuming here.  One such fact is that the three children are different from each other.  So let&#8217;s tell it that.</p>
<pre>
Hypothesis Diff1 : Alice &lt;&gt; Carl.
Hypothesis Diff2 : Bill  &lt;&gt; Carl.
Hypothesis Diff3 : Alice &lt;&gt; Bill.
</pre>
<p>Each of these hypotheses has a name, so that we can refer to it in the proof later.</p>
<p>Next, there&#8217;s some implicit meaning in the superlative words &#8220;youngest&#8221; and &#8220;oldest&#8221;.</p>
<pre>
Hypothesis Superlative1 : forall A B, (A &lt;&gt; B) -&gt; Youngest A -&gt; ~Youngest B.
Hypothesis Superlative2 : forall A B, (A &lt;&gt; B) -&gt; Oldest   A -&gt; ~Oldest   B.
</pre>
<p>In other words, you can&#8217;t have two different children who are both the youngest or the oldest.  Even twins are usually born a few minutes apart!</p>
<p>Finally, &#8220;youngest&#8221; and &#8220;oldest&#8221; are opposites.  Since there is more than one child, no one can be both.</p>
<pre>
Hypothesis Antonym1 : forall A, Oldest   A -&gt; ~ Youngest A.
Hypothesis Antonym2 : forall A, Youngest A -&gt; ~ Oldest   A.
</pre>
<p>Having now explained the terminology to Coq, we may now enter the information given by Mrs. Muddled in the problem.</p>
<pre>
Hypothesis Given1 : ~ Youngest Alice -&gt; Youngest Bill.
Hypothesis Given2 : ~ Youngest Carl  -&gt; Oldest Alice.
</pre>
<p>Now that Coq understands the premises, we need to tell it what we are proving.  That requires solving the puzzle.  Simple enough: Alice is the youngest unless Bill is, which means Carl can&#8217;t be the youngest.  But if Carl is not the youngest, then Alice is the oldest, which leaves Bill as the youngest.  So the youngest is Bill, the middle child is Carl, and the oldest is Alice.  Let&#8217;s tell Coq that.</p>
<pre>
Goal Oldest Alice /\ Youngest Bill.
</pre>
<p>And Coq responds by listing the goal, and all the hypotheses we may use to prove it:</p>
<pre>
1 subgoal

  Child : Set
  Alice : Child
  Bill : Child
  Carl : Child
  Youngest : Child -&gt; Prop
  Oldest : Child -&gt; Prop
  Diff1 : Alice &lt;&gt; Carl
  Diff2 : Bill &lt;&gt; Carl
  Diff3 : Alice &lt;&gt; Bill
  Superlative1 : forall A B : Child, A &lt;&gt; B -&gt; Youngest A -&gt; ~ Youngest B
  Superlative2 : forall A B : Child, A &lt;&gt; B -&gt; Oldest A -&gt; ~ Oldest B
  Antonym1 : forall A : Child, Oldest A -&gt; ~ Youngest A
  Antonym2 : forall A : Child, Youngest A -&gt; ~ Oldest A
  Given1 : ~ Youngest Alice -&gt; Youngest Bill
  Given2 : ~ Youngest Carl -&gt; Oldest Alice
  ============================
   Oldest Alice /\ Youngest Bill
</pre>
<p>Fair enough.  The proof wizard doesn&#8217;t know how to solve this, so we&#8217;ll need to take it on by hand.  To prove a conjunction, we can individually prove each side.  Coq calls this the &#8220;split&#8221; tactic.</p>
<pre>
split.
</pre>
<p>And Coq responds:</p>
<pre>
2 subgoals

  Child : Set
  Alice : Child
  Bill : Child
  Carl : Child
  Youngest : Child -&gt; Prop
  Oldest : Child -&gt; Prop
  Diff1 : Alice &lt;&gt; Carl
  Diff2 : Bill &lt;&gt; Carl
  Diff3 : Alice &lt;&gt; Bill
  Superlative1 : forall A B : Child, A &lt;&gt; B -&gt; Youngest A -&gt; ~ Youngest B
  Superlative2 : forall A B : Child, A &lt;&gt; B -&gt; Oldest A -&gt; ~ Oldest B
  Antonym1 : forall A : Child, Oldest A -&gt; ~ Youngest A
  Antonym2 : forall A : Child, Youngest A -&gt; ~ Oldest A
  Given1 : ~ Youngest Alice -&gt; Youngest Bill
  Given2 : ~ Youngest Carl -&gt; Oldest Alice
  ============================
   Oldest Alice

subgoal 2 is:
 Youngest Bill
</pre>
<p>In other words, we&#8217;re currently working on proving <code>Oldest Alice</code>, but once we finish that, we&#8217;ll need to prove <code>Youngest Bill</code>.  Well, there&#8217;s only one good way to conclude <code>Oldest Alice</code>, and that&#8217;s to show that Carl is not the youngest.  So let&#8217;s prove the current subgoal by applying <code>Given2</code>.</p>
<pre>
apply Given2.
</pre>
<p>I&#8217;ll stop quoting the entirety of Coq&#8217;s responses, but here&#8217;s the important part:</p>
<pre>
  ============================
   ~ Youngest Carl
</pre>
<p>So how do we know that Carl is not the youngest?  Well, it&#8217;s because Bill is the youngest.  That&#8217;s rule <code>Superlative1</code>, but we&#8217;ll also have to tell Coq to use Bill as the other child.</p>
<pre>
apply Superlative1 with Bill.
</pre>
<p>And Coq responds:</p>
<pre>
  ============================
   Bill &lt;&gt; Carl

subgoal 2 is:
 Youngest Bill
</pre>
<p>So we need to prove that Bill is not Carl, and then that Bill is the youngest.  (That Bill is the youngest is also subgoal 3 left over from splitting the conjunction, a fact that we&#8217;ll think about shortly.)  For now, it&#8217;s easy to prove that Bill is not Carl, because that was one of our hypotheses.</p>
<pre>
apply Diff2.
</pre>
<p>And Coq responds:</p>
<pre>
  ============================
   Youngest Bill
</pre>
<p>Now it remains only to prove that Bill is the youngest.  The way to go about that is to apply the first given.</p>
<pre>
apply Given1.
</pre>
<p>And Coq responds:</p>
<pre>
  ============================
   ~ Youngest Alice
</pre>
<p>This is the tricky part.  The reason that Alice is not the youngest is that if she were the youngest, then Carl would not be the youngest, but then the second given statement would lead us to conclude that Alice is the oldest, which is a contradiction.  Proof by contradiction, though, is generally a technique valid only in classical logic, not in the constructive logic that Coq typically uses.  It turns out we won&#8217;t need to resort to classical logic for this theorem, but just to make things easier in our first pass we&#8217;ll go ahead and use it.  This is one statement in Coq.</p>
<pre>
Require Import Classical.
</pre>
<p>So now having classical logic at our disposal, we can go about proving that Alice is not the youngest by applying Peirce&#8217;s law.</p>
<pre>
apply Peirce.
</pre>
<p>And Coq&#8217;s response:</p>
<pre>
  ============================
   (~ Youngest Alice -&gt; False) -&gt; ~ Youngest Alice
</pre>
<p>We&#8217;ll split up the implication by giving a name to the hypothesis and then proving the conclusion.  This tactic is called &#8220;intro&#8221;.</p>
<pre>
intro H.
</pre>
<p>Coq responds:</p>
<pre>
  H : ~ Youngest Alice -&gt; False
  ============================
   ~ Youngest Alice
</pre>
<p>Note that the new hypothesis is the double-negation of &#8220;Alice is the youngest.&#8221;  In classical logic, which we&#8217;re now using, that&#8217;s the same as Alice being the youngest, so we&#8217;ve essentially used Peirce&#8217;s law to start the proof by contradiction.  Now we&#8217;ll go backward through the contradiction argument given above.  First, Alice can&#8217;t be the youngest because she&#8217;s the oldest.  She&#8217;s the oldest because Carl is not the youngest.  Carl is not the youngest because we&#8217;ve assumed (to obtain the contradiction) that Alice is the youngest.</p>
<pre>
apply Antonym1.
apply Given2.
apply Superlative1 with Alice.
apply Diff1.
</pre>
<p>And here&#8217;s where we are, according to Coq.</p>
<pre>
  H : ~ Youngest Alice -&gt; False
  ============================
   Youngest Alice
</pre>
<p>This is just a double negation: a rule from the Classical package that goes by the name NNPP.  Once we double-negate the conclusion, it will look slightly different from the hypothesis H, but they will actually mean the same thing.  (<code>~A</code> is just shorthand for <code>A -&gt; False</code>).</p>
<pre>
apply NNPP.
exact H.
</pre>
<p>Coq says:</p>
<pre>
  ============================
   Youngest Bill
</pre>
<p>So we&#8217;ve proven the left half of the conjunction: that Alice is the oldest.  We now need to prove the right half.  But wait!  We already did that, as the second step to proving the left half.  For now, we&#8217;ll just copy and paste the last part of the earlier proof.</p>
<pre>
apply Given1.
apply Peirce.
intro H.
apply Antonym1.
apply Given2.
apply Superlative1 with Alice.
apply Diff1.
apply NNPP.
exact H.
</pre>
<p>and Coq says:</p>
<pre>
Proof completed.
</pre>
<p>Finally, we get to say:</p>
<pre>
Qed.
</pre>
<p>Ah, we&#8217;re done.  But it turns out we can improve the proof a little by using a few more Coq features: specifically, by proving some lemmas (or lemmata, if your prefer), and by eliminating the use of classical logic (since this happens to be a constructively valid statement; not all classically true statements will be, though).</p>
<p>First, although Peirce&#8217;s law (<code>(~P -&gt; P) -&gt; P</code>) is not true in constructive logic, but we can prove <code>(P -&gt; ~P) -&gt; ~P</code>.  Let&#8217;s do so, by introducing a lemma, and then by using the automatic prover.</p>
<pre>
Lemma NPeirce : forall P : Prop, (P -&gt; ~P) -&gt; ~P.
auto.
Qed.
</pre>
<p>In this case, the automated theorem prover worked fine.  We could have proven the theorem by hand, as well (by treating the <code>~P</code> as <code>P -&gt; False</code>, using the intro tactic, applying the modus ponens rule, and then easily satisfying all of the hypotheses).  Using this, we can simplify our proof of <code>Youngest Bill</code>.  The process is the same, but instead of applying Peirce&#8217;s law and the beginning and the double-negation at the end, we apply our new NPeirce lemma at the beginning, and we don&#8217;t need double-negation at the end.</p>
<pre>
Lemma YoungBill : Youngest Bill.
apply Given1.
apply NPeirce.
intro H.
apply Antonym1.
apply Given2.
apply Superlative1 with Alice.
apply Diff1.
exact H.
Qed.
</pre>
<p>Notice that I&#8217;ve also defined this as a lemma.  That&#8217;s because we needed to prove it twice in the earlier attempt.  May as well prove it once up front instead.  So now comes the final goal.</p>
<pre>
Goal Oldest Alice /\ Youngest Bill.
split.
apply Given2.
apply Superlative1 with Bill.
apply Diff2.
apply YoungBill.
apply YoungBill.
Qed.
</pre>
<p>And we&#8217;re done.  For reference, here&#8217;s the entire proof as entered in CoqIde.</p>
<pre>
Variable Child : Set.
Variable Alice : Child.
Variable Bill  : Child.
Variable Carl  : Child.
Variable Youngest : Child -&gt; Prop.
Variable Oldest   : Child -&gt; Prop.

Hypothesis Diff1 : Alice &lt;&gt; Carl.
Hypothesis Diff2 : Bill  &lt;&gt; Carl.
Hypothesis Diff3 : Alice &lt;&gt; Bill.

Hypothesis Superlative1 : forall A B, (A &lt;&gt; B) -&gt; Youngest A -&gt; ~Youngest B.
Hypothesis Superlative2 : forall A B, (A &lt;&gt; B) -&gt; Oldest   A -&gt; ~Oldest   B.

Hypothesis Antonym1 : forall A, Oldest   A -&gt; ~ Youngest A.
Hypothesis Antonym2 : forall A, Youngest A -&gt; ~ Oldest   A.

Hypothesis Given1 : ~ Youngest Alice -&gt; Youngest Bill.
Hypothesis Given2 : ~ Youngest Carl  -&gt; Oldest Alice.

Lemma NPeirce : forall P : Prop, (P -&gt; ~P) -&gt; ~P.
auto.
Qed.

Lemma YoungBill : Youngest Bill.
apply Given1.
apply NPeirce.
intro H.
apply Antonym1.
apply Given2.
apply Superlative1 with Alice.
apply Diff1.
exact H.
Qed.

Goal Oldest Alice /\ Youngest Bill.
split.
apply Given2.
apply Superlative1 with Bill.
apply Diff2.
apply YoungBill.
apply YoungBill.
Qed.
</pre>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/50/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/50/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/50/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=50&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/05/04/solving-a-logic-problem-with-coq/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Code == Data: The Basics</title>
		<link>http://cdsmith.wordpress.com/2008/04/07/code-data-the-basics/</link>
		<comments>http://cdsmith.wordpress.com/2008/04/07/code-data-the-basics/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 16:36:11 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=49</guid>
		<description><![CDATA[There have been a lot of blog entries lately about code versus data: which is more valuable, are they the same, or maybe different, and so on.  Most recently, here.  That blog entry argues that code is data, and points out Turing&#8217;s work on universal Turing machines as an example.  The dual [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>There have been a lot of blog entries lately about code versus data: which is more valuable, are they the same, or maybe different, and so on.  Most recently, <a href="http://www.bofh.org.uk/articles/2008/04/07/code-is-data-and-it-always-has-been">here</a>.  That blog entry argues that code is data, and points out Turing&#8217;s work on universal Turing machines as an example.  The dual argument, that data is code, can be attributed to Church, thereby completing the pair of early computer science figureheads.  This won&#8217;t be new to most advanced computer science students, but I was unable to find a single place where it&#8217;s written down.</p>
<p>To start, two special cases will be helpful.  I will be assuming that the reader knows the basic evaluation rules of lambda calculus.  The technique here will be the same: use an appropriate function to represent data.</p>
<p><strong>Special Case 1: Finite Enumerated Types</strong></p>
<p>Suppose I want to write lambda calculus expressions to represent the four cardinal directions (north, south, east, and west), and left and right turns.  Here&#8217;s what I&#8217;m shooting for, in Haskell.</p>
<blockquote><pre>
data Dir = East | West | North | South
left  East  = North
left  West  = South
left  North = West
left  South = East
right East  = South
right West  = North
right North = East
right South = West
</pre>
</blockquote>
<p>To do this in lambda calculus, I need four &#8220;data&#8221; values, and as promised they will be defined as functions.</p>
<blockquote><pre>
East  := λabcd.a
West  := λabcd.b
North := λabcd.c
South := λabcd.d
</pre>
</blockquote>
<p>(Note that I&#8217;m using <code>:=</code> to denote definition of short-hand names; it is not, of course, part of the lambda calculus itself.  In particular, you have the right to complain loudly if I try to give circular definitions; there is no such thing as direct general recursion.)</p>
<p>These are functions that take four parameters and return, respectively, the first, second, third, and fourth ones.  Now defining functions case-wise on these values is trivial:</p>
<blockquote><pre>
left  := λd.d (North) (South) (West) (East)
right := λd.d (South) (North) (East) (West)
</pre>
</blockquote>
<p>Now the <code>left</code> function take a parameter <code>d</code>, which <em>is itself a function</em>, and operates by calling that function and passing it four arguments.  Now if the function happens to be <code>East</code>, then it will return its first result, thereby correctly concluding that north is a left turn from east.</p>
<p><strong>Special Case 2: Church Numerals</strong></p>
<p>A slightly more involved data type is natural numbers.  Alonzo Church defined natural numbers in terms of Church numerals.  The idea is that a natural number <em>n</em> is a function which iterates another function <em>n</em> times on some initial value.  For example, using the functions above, we can say that:</p>
<blockquote><pre>
0 left North = North
1 left North = West
2 left North = South
3 left North = East
4 left North = North
</pre>
</blockquote>
<p>So the first few natural numbers are:</p>
<blockquote><pre>
0 := λfx.x
1 := λfx.fx
2 := λfx.f(fx)
3 := λfx.f(f(fx))
4 := λfx.f(f(f(fx)))
</pre>
</blockquote>
<p>And here are a few operations on these natural numbers.  It can take some hard work with a pencil and paper to see why some of them work.</p>
<blockquote><pre>
inc := λp.(λfx.f(pfx))
add := λpq.(λfx.pf(qfx))
mul := λpq.(λfx.p(qf)x)
</pre>
</blockquote>
<p><strong>General Case: Algebraic Data Types</strong></p>
<p>Algebraic data types are a general approach to defining data types in a programming language.  A type may have several different forms, each of which may have several fields.  Another way of saying this is that an ADT is a sum of products of other types.  Here&#8217;s an example in Haskell:</p>
<blockquote><pre>
data Discount = FixedAmount Double
              | Percent Double
              | Rebate Date Double
</pre>
</blockquote>
<p>In other words, a discount is either a fixed amount of money at purchase, or a percent off the purchase price, or a rebate of some amount that happens at some future date.</p>
<p>Another example:</p>
<blockquote><pre>
data Tree = Leaf Char
          | Branch Tree Tree
</pre>
</blockquote>
<p>So a tree is either a leaf, or a branch node whose left and right children are trees in their own right.</p>
<p>Both of the special cases above are also algebraic data types.  Directions have four forms, each of which is an empty product:</p>
<blockquote><pre>
data Dir = East | West | North | South
</pre>
</blockquote>
<p>Church numerals implement natural numbers defined as:</p>
<blockquote><pre>
data Nat = Succ Nat | Zero
</pre>
</blockquote>
<p>As you may guess, we&#8217;re going to write functions to represent any kind of data of any algebraic data type as a function in the lambda calculus.  The idea will be this: we will ask the person using the data to write a handler for each form that the data may take.  Then they&#8217;ll give us all of these handler functions, and we&#8217;ll use the one that applies.  So a value of some algebraic data type will be a function that takes a bunch of handlers, and produces the result of one of them.  Examples follow:</p>
<p>For the <code>Discount</code> data type, the value <code>FixedAmount $2.75</code> looks like this:</p>
<blockquote><pre>
FixedAmount $2.75 := λfpr . f ($2.75)
</pre>
</blockquote>
<p>In other words, this is a function that takes three handlers <em>f</em>, <em>p</em>, and <em>r</em> (one for fixed amounts, one for percentages, and another for rebates).  It then calls the first handler, passing it the amount of the fixed discount.</p>
<p>To calculate the amount of money to hand someone as they are buying an item at a price <em>p</em> with a discount <em>d</em>, one may write:</p>
<blockquote><pre>
d (λa.a) (λp.(p*a)) (λda.0)
</pre>
</blockquote>
<p>The first handler says that if the discount is for a constant amount, you give back that amount.  The second says that if the discount is for some percent, you multiply it by the price and give that back.  The third handler says that if the discount is a rebate to be filled later, you don&#8217;t give them anything right now.  This is all done by calling the data as a function.</p>
<p>To use a Church numeral, you pass it two handlers.  The first says what you want back if it&#8217;s the successor of another number.  The next handler says what to do if it&#8217;s zero.  Using this, we can write a slightly wordier version of the <code>inc</code> function from before:</p>
<blockquote><pre>
inc := λp.p (λfx.f(pfx)) (λfx.fx)
</pre>
</blockquote>
<p>The second handler is just a value, since there are no fields in that case.</p>
<p>So there you have it, not only is code a type of data (Turing&#8217;s approach), but also data is a type of code (Church&#8217;s approach).</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/49/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/49/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/49/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=49&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/04/07/code-data-the-basics/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to Be a Jerk and Get Away With It</title>
		<link>http://cdsmith.wordpress.com/2008/03/30/how-to-be-a-jerk-and-get-away-with-it/</link>
		<comments>http://cdsmith.wordpress.com/2008/03/30/how-to-be-a-jerk-and-get-away-with-it/#comments</comments>
		<pubDate>Sun, 30 Mar 2008 19:55:13 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=48</guid>
		<description><![CDATA[In modern society, being a jerk has been raised to an art form.  Moral offenses that would shock most of us in plain view can be excused if you know how to play your hand.  Here, I cover the basics of getting away with being an immoral jerk.
Step 1: Pick on the Right [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In modern society, being a jerk has been raised to an art form.  Moral offenses that would shock most of us in plain view can be excused if you know how to play your hand.  Here, I cover the basics of getting away with being an immoral jerk.</p>
<p><strong>Step 1: Pick on the Right Victim</strong></p>
<p>The most part of successfully being a jerk is to pick on the right people.  If you&#8217;re going to mug someone, you wouldn&#8217;t pick the Queen of England as your victim.  You also shouldn&#8217;t go for a successful businessman or politician.  Instead, choose victims with whom the general public won&#8217;t sympathize.  Here are some more specific rules:</p>
<p>First, your victim should be poor.  Rich people are trusted, visible, and most importantly have access to the press and political representation.  These all work against you.  It may seem like it&#8217;s better to take money from people who have it to begin with.  You would be wrong.  Seriously, can anyone imagine Walmart getting away with <a href="http://wakeupwalmart.com/">what it does</a> if its average employees (or even customers) came from upper middle class and wealthy families?  Because most of power structure in the world likes to blame poor people for being poor, and doesn&#8217;t trust them, it&#8217;s actually easier to take $100 each from 10,000 poor people than it is to take a million dollars from a rich person.</p>
<p>Second, your victim should be a racial minority.  For some background reading on the importance of picking on racial minorities, see <a href="http://en.wikipedia.org/wiki/Missing_white_woman_syndrome">here</a>.  You&#8217;d be surprised what you can do without getting much attention.  Modern sentiment being what it is, having Arabic ancestry is like <em>asking</em> to be victimized.  The United States federal government has got this <a href="http://en.wikipedia.org/wiki/Guantanamo_Bay_detention_camp">figured out</a>.  You may as well take advantage, too.</p>
<p>Whether to victimize men or women is a tricky question.  The answer depends on what kind of jerk you plan to become.  Although women are disadvantaged in general, you are better off concentrating on which gender that will most reinforce more negative stereotypes about themselves by resisting.  If you want to do physical violence, or take someone&#8217;s children away, your victim should be male.  If you want to deny someone equal pay, a job, or a leadership position of any kind, women are ripe for the picking.</p>
<p>Targeting children is risky, but can pay off.  Stay away from children under 12, as they elicit too much sympathy from others.  Teenagers, though, are demonized for for their rebellious natures and their irrational &#8220;angst&#8221;.  If you manipulate the situation in the right way, and especially if you can put yourself in a position of authority (which is not too hard; even a bus driver job will do), your inexcusable behavior will be dismissed in the name of preserving order.</p>
<p>As you can see, there are some subtleties here.  It&#8217;s worth it in the end, though.  Assuming you don&#8217;t leave definite evidence of having broken the law, the only reasonable way anyone can stop you from being a jerk is to elicit enough sympathy that large numbers of people stand up to you.  Choosing the right victims can almost eliminate that unlikely event.</p>
<p><strong>Step 2: Appeal to Written Policy</strong></p>
<p>If you played the first step well, few other people will care about your victim, but your victim will care about him/her-self.  There is no more effective way to deal with such victims&#8217; complaints than an appeal to written policy.  You can even write the policy yourself, but it&#8217;s better if you can arrange to have the policy written by some nameless unidentifiable person, whom no one can blame as a result.  As odd as this may sound, it will rarely occur to anyone to blame you for enforcing a ridiculous policy or failing to change it.</p>
<p>This is a remarkably effective strategy.  Average people are very receptive to the argument that if someone doesn&#8217;t like your policies, they should have never done business with you.  Strangely, this remains true when you are getting tax breaks, driving others out of business, and basically providing people with no other choices.  Remarkably, it even remains true when you&#8217;re able to get the government to pass laws requiring people to do business with you.</p>
<p><strong>Step 3: Blame the Victim</strong></p>
<p>If you&#8217;ve still got significant opposition, then you have clearly failed to pick a victim that no one sympathizes with.  No worries.  You just have to stop people from sympathizing.  This will get ugly, though.</p>
<p>Guilt by association is an especially effective tactic here.  All you need to do is make enough public statements lumping your victim in with undesirable sorts, and your victim will lose all of their remaining sympathy.  For this reason, it&#8217;s a good idea to drag in a few genuinely evil people, if possible.  That way, you can throw the name of your real victims in the middle of a long list of terrorists, criminals, gang members, and so on.  People will conclude that your victims are all bad people anyway.</p>
<p>If guilt by association doesn&#8217;t work, you&#8217;ll have to engage in a direct game of character assassination.  Fortunately, this is easier than it sounds.  Most people are not accustomed to receiving the kind of abuse you plan on giving out.  They will make mistakes.  Perhaps some foul language, or even violence.  Maybe they will phrase something improvidently.  Unless you&#8217;ve made the grave error of picking media-saavy victims, they will certainly say things in public that you can take out of context.  With some care, you should be able to make sure the public hates your victim in no time at all, and any scrutiny you&#8217;re under should dry up quickly as a result.</p>
<p><strong>Step 4: Use Others&#8217; Common Sense as a Weapon</strong></p>
<p>Now things are getting serious.  If you can&#8217;t blame the victim, then people must have found real evidence for suspecting you.  This is no time to panic, though.  Most people aren&#8217;t willing to believe outrageous things, and you can use that in your favor.  If what you did is completely outrageous, no one will believe your accusers, and you&#8217;ll get away free.</p>
<p>You are already at an advantage here, because you&#8217;re reading a web page on how to get away with being a jerk.  Most people would find that beyond the bounds of common sense.  But you need to go further.  Never, ever, under any circumstances, should you do pick a victim who has harmed you in any way.  You should also not pick a victim that you&#8217;ve publicly argued with.  These things create &#8220;motive&#8221;, which helps random people believe that you are guilty.  Instead, you should pick random victims, do unbelievable things to them, and then just calmly laugh and ask whether we <em>really</em> believe that such a ridiculous story is true.</p>
<p><strong>Step 5: Tell People Everyone Does It</strong></p>
<p>Now things are really bad.  You have no chance of convincing people you are innocent.  So what do you do?  Easy: make it sound like it&#8217;s no big deal.</p>
<p>Here&#8217;s the idea.  People are going to be angry.  You can either let them be angry at you (bad idea) or you can encourage them to just be disgusted with the state of the world as a whole.  To accomplish the latter, you imply that you aren&#8217;t out of the ordinary, and that <a href="http://www.politico.com/news/stories/0208/8583.html">everyone does what you did</a>.</p>
<p>Occasionally, you may not want to be on the record as saying something that outrageous.  Then a weaker form of this strategy is called for.  You can merely <em>imply</em> that everyone does it, by unabashedly and calmly making a public statement about what you are doing.  If you word things right, you can make it seem like the most natural thing in the world for you to, say, <a href="http://www.kitv.com/money/15736470/detail.html">openly defy a court order</a>.</p>
<p><strong>Step 6: Procrastinate Admission of Guilt</strong></p>
<p>The most important step in avoiding responsibility for your actions is to wait until no one is looking to admit what you did.</p>
<p>A common beginner mistake is to avoid admitting guilt at all.  For small matters, this can work.  If you&#8217;re being enough of a major-league jerk to reach this point, though, people will launch investigations.  No, you have to admit what you&#8217;ve done.  but do it on your time frame.</p>
<p>At this point, get a lawyer.  You can be assured that any lawyer worth his salt will advise you not to talk about the case.  If he doesn&#8217;t, you should specifically request it.  This gives you an excuse for not commenting.  Later, you can wait until media fervor has died down, and quietly admit what you&#8217;ve done once the story is old and stale.  Oddly enough, the media will almost certainly play their part, holding off on the worst accusations because they can&#8217;t get &#8220;both sides&#8221; of the story.  They will forget that it&#8217;s you, whether under legal advice or not, preventing them from getting your side of the story.</p>
<p>Should the story resurrect itself later when you make your admission, you can always appeal to the stuck in the past line to avoid talking about it then.</p>
<p><strong>Step 7: Cry Terrorism</strong></p>
<p>It&#8217;s your last shot.  Now people are openly protesting against you in the streets.  There&#8217;s only one thing left to do: <a href="http://www.anonymous-exposed.org/">call them</a> <a href="http://jimbovard.com/blog/2007/08/29/the-terrorist-batting-average/">terrorists</a>.</p>
<p>[Of course this isn't serious.  I am, though, looking for more links to add.  If you've seen something that should be linked from here, please mention it in the comments.]</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/48/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/48/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/48/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=48&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/03/30/how-to-be-a-jerk-and-get-away-with-it/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Just For Fun: Autostereograms in Haskell</title>
		<link>http://cdsmith.wordpress.com/2008/03/11/just-for-fun-autostereograms-in-haskell/</link>
		<comments>http://cdsmith.wordpress.com/2008/03/11/just-for-fun-autostereograms-in-haskell/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 19:25:31 +0000</pubDate>
		<dc:creator>cdsmith</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cdsmith.wordpress.com/?p=44</guid>
		<description><![CDATA[I&#8217;ve added some code here, which I wrote last night, to generate autostereograms from depth maps.  It&#8217;s written in Haskell, but that doesn&#8217;t mean you should blame Haskell for its shortcomings.
To use:

Install GHC and gtk2hs.  Any recent version should do.
Copy this code into a file and build with ghc --make -O2 TheFile.hs.
Generate a [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://cdsmith.twu.net/demos/haskell.html">I&#8217;ve added some code here</a>, which I wrote last night, to generate autostereograms from depth maps.  It&#8217;s written in Haskell, but that doesn&#8217;t mean you should blame Haskell for its shortcomings.</p>
<p>To use:</p>
<ol>
<li>Install GHC and gtk2hs.  Any recent version should do.</li>
<li>Copy this code into a file and build with <code>ghc --make -O2 TheFile.hs</code>.</li>
<li>Generate a tiling background image of your choice.  GIMP&#8217;s Filter -&gt; Map -&gt; Make Seamless helps a lot with this, and it has some nice options under Filter -&gt; Render to generate nice-looking images.  The important thing is for your image to be seamlessly tileable, and have lots of easily identifiable points.  Save it as a PNG file.</li>
<li>Generate a depth map, on the order of about 100 x 100 pixels.  (Too much larger, and you&#8217;ll have to profile and optimize my code for me.)  Save it as a PNG file again.</li>
<li>Run the program with the depth map and the background image (in that order) as parameters.</li>
</ol>
<p>This code basically works, and realistically that&#8217;s about all I am going to do right now.  There are lots of things that could be improved about it.  The big three are: lots of performance issues; should be able to write out to a file instead of just the screen; and there&#8217;s something funky in the drawing that causes the depth to slope outward rather gently to each side no matter what the depth map looks like.  As far as performance, the problem is with a lot of fiddling with lists for control flow; I was able to do considerably better with Cairo; but unfortunately, Cairo&#8217;s matrices only allow for affine transformations, which doesn&#8217;t seem to be quite enough to scale between arbitrary trapezoids, so the result didn&#8217;t look great and I reverted to drawing pixel by pixel.  The last problem may be a rather fundamental issue in how I&#8217;m approaching the problem; but the current code works well enough to get the point.</p>
<p>Here are some obligatory screen shots.</p>
<p><a href='http://cdsmith.files.wordpress.com/2008/03/lambda_field.png' title='Autostereogram of a Lambda'><img src='http://cdsmith.files.wordpress.com/2008/03/lambda_field.thumbnail.png' alt='Autostereogram of a Lambda' /></a><a href='http://cdsmith.files.wordpress.com/2008/03/chess_field.png' title='Autostereogram of a Chess Board'><img src='http://cdsmith.files.wordpress.com/2008/03/chess_field.thumbnail.png' alt='Autostereogram of a Chess Board' /></a><a href='http://cdsmith.files.wordpress.com/2008/03/man_field.png' title='Autostereogram of a Human'><img src='http://cdsmith.files.wordpress.com/2008/03/man_field.thumbnail.png' alt='Autostereogram of a Human' /></a></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/cdsmith.wordpress.com/44/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/cdsmith.wordpress.com/44/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cdsmith.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cdsmith.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cdsmith.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cdsmith.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cdsmith.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cdsmith.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cdsmith.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cdsmith.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cdsmith.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cdsmith.wordpress.com/44/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cdsmith.wordpress.com&blog=1158345&post=44&subd=cdsmith&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://cdsmith.wordpress.com/2008/03/11/just-for-fun-autostereograms-in-haskell/feed/</wfw:commentRss>
	
		<media:content url="http://cdsmith.files.wordpress.com/2008/03/lambda_field.thumbnail.png" medium="image">
			<media:title type="html">Autostereogram of a Lambda</media:title>
		</media:content>

		<media:content url="http://cdsmith.files.wordpress.com/2008/03/chess_field.thumbnail.png" medium="image">
			<media:title type="html">Autostereogram of a Chess Board</media:title>
		</media:content>

		<media:content url="http://cdsmith.files.wordpress.com/2008/03/man_field.thumbnail.png" medium="image">
			<media:title type="html">Autostereogram of a Human</media:title>
		</media:content>
	</item>
	</channel>
</rss>