<?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/"
	>

<channel>
	<title>Functional Lens &#187; Mathematics</title>
	<atom:link href="http://www.kennknowles.com/blog/category/mathematics/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kennknowles.com/blog</link>
	<description>on Mathematics and Computation</description>
	<lastBuildDate>Mon, 26 Dec 2011 21:15:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>What is defunctionalization?</title>
		<link>http://www.kennknowles.com/blog/2008/05/24/what-is-defunctionalization/</link>
		<comments>http://www.kennknowles.com/blog/2008/05/24/what-is-defunctionalization/#comments</comments>
		<pubDate>Sat, 24 May 2008 21:57:15 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Reading]]></category>
		<category><![CDATA[church encoding]]></category>
		<category><![CDATA[continuations]]></category>
		<category><![CDATA[defunctionalization]]></category>
		<category><![CDATA[operational semantics]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2008/05/24/what-is-defunctionalization/</guid>
		<description><![CDATA[I gave a little demonstration entitled &#8220;What is Defunctionalization?&#8221; for UCSC TWIGS (the acronym, stolen from a similar seminar in the the U. Mass. math department, stands for The &#8220;What Is &#8230; ?&#8221; Graduate Seminar). The inspiration for this talk was just to present what I&#8217;d learned after Conor McBride&#8217;s brilliant presentation at POPL&#8217;08 drove [...]]]></description>
			<content:encoded><![CDATA[<p>I gave a little demonstration entitled &#8220;What is Defunctionalization?&#8221; for <a href="http://slang.soe.ucsc.edu/wiki/doku.php?id=twigs#spring08">UCSC TWIGS</a> (the acronym, stolen from a <a href="http://www.math.umass.edu/~hajir/twigsf03.html">similar seminar</a> in the the U. Mass. math department, stands for <strong>T</strong>he &#8220;<strong>W</strong>hat <strong>I</strong>s &#8230; ?&#8221; <strong>G</strong>raduate <strong>S</strong>eminar).  The inspiration for this talk was just to present what I&#8217;d learned after Conor McBride&#8217;s brilliant presentation at POPL&#8217;08 drove me to put the words &#8220;Olivier Danvy defunctionalize continuation&#8221; into Google.</p>

<p>I coded the simplest examples from</p>

<ul>
<li><a href="http://www.brics.dk/RS/01/23/">Defunctionalization at work</a>. O Danvy, LR Nielsen.  PPDP 2001.</li>
</ul>

<p>in literate Haskell for the audience, and also showed off QuickCheck a little to make sure the translation was correct (finding one error, if I recall).</p>

<p><center><img src='http://www.kennknowles.com/blog/wp-content/uploads/2008/05/nolambda-med.png' alt='nolambda-med.png' /></center></p>

<p>This blog post is a merging of my talk outline and new stuff that came up live.  Try loading it up in GHCi or Haskell-mode and running the examples and QuickCheck properties.
<span id="more-62"></span></p>

<pre>
> {-# LANGUAGE RankNTypes #-}

> import Prelude hiding (reverse)
> import Control.Monad
> import Control.Monad.Cont
> import Test.QuickCheck
</pre>

<p>Broadly, defunctionalization is transforming a program to eliminate higher-order functions.  Rather than focus on its use for compilation (see this H Cejtin, S Jagannathan, S Weeks <a href="http://mlton.org/pages/References/attachments/CejtinEtAl00.pdf">paper on MLTon</a>)
or analyses (see <a href="http://www-users.cs.york.ac.uk/~ndm/firstify/">Firstify</a> from N Mitchell and C Runciman). I wanted to emphasize its use in understanding your own program, along the lines of Wand&#8217;s <a href="http://www.diku.dk/undervisning/2005e/224/papers/Wand80.pdf">Continuation-Based Program Transformation Strategies</a> (JACM 1980).</p>

<p>Here is the first example from Danvy.</p>

<pre>
> aux1 :: (Int -> Int) -> Int
> aux1 f = f 1 + f 10
>
> main1 x y b = (aux1 (\z -> x + z)) * 
>               (aux1 (\z -> if b then y + z else y - z))
</pre>

<p>Defunctionalization replaces all the first-class functions with an explicit data structure <code>Lam1</code> and a global <code>apply1</code> function, essentially embedding a mini-interpreter for just those lambda terms occurring in the program.</p>

<pre>
> data Lam1 = Lam1A Int      -- (Lam1A x)   ~ (\z -> x + z)
>           | Lam1B Int Bool -- (Lam1B y b) ~ (\z -> if b then y + z else y - z)
>
> apply1 :: Lam1 -> Int -> Int
> apply1 (Lam1A x)   z = x + z
> apply1 (Lam1B y b) z = if b then y + z else y - z
>
> aux1defun :: Lam1 -> Int
> aux1defun f = (apply1 f 1) + (apply1 f 10)
>
> main1defun x y b = (aux1defun (Lam1A x)) *
>                    (aux1defun (Lam1B y b))
</pre>

<p>Is it correct?  Ask quickcheck:</p>

<pre>
> prop1 x y b = (main1 x y b == main1defun x y b)

*Main> quickCheck prop1
+++ OK, passed 100 tests.
</pre>

<p>Next example: flattening a binary tree</p>

<pre>
> data BinaryTree a = Leaf a
>                   | Node (BinaryTree a) (BinaryTree a)
</pre>

<p>First, there is the straightforward, inefficient version of flatten</p>

<pre>
> flatten (Leaf x) = [x]
> flatten (Node t1 t2) = (flatten t1) ++ (flatten t2)
</pre>

<p>We can represent our output with <a href="http://www.cse.unsw.edu.au/~dons/dlist.html">difference lists</a> offering O(1) append.</p>

<pre>
> flatten' t = walk t []
>   where walk (Leaf x)     = (x:)
>         walk (Node t1 t2) = (walk t1) . (walk t2)
</pre>

<p>And now that we&#8217;ve introduced a bunch of first-class functions, let&#8217;s see what happens when we defunctionalize them.</p>

<pre>
> data LamBTree a = LamBTreeA a -- (x:)
>                 | LamBTreeB (LamBTree a) (LamBTree a) -- (u . v)
>
> applyBTree (LamBTreeA x)   l = x:l
> applyBTree (LamBTreeB u v) l = applyBTree u (applyBTree v l)
>
> flatten_defun t = applyBTree (walk t) []
>   where walk (Leaf x)     = LamBTreeA x
>         walk (Node t1 t2) = LamBTreeB (walk t1) (walk t2)
</pre>

<p>Note how <code>LamBTree</code> looks just like the definition of <code>BinaryTree</code>, because it is a catamorphism, hence a hylomorphism, i.e. a recursive function with a call tree that looks like a <code>BinaryTree</code> or whatever structure you are hylo&#8217;ing over.  (See <a href="http://www.fing.edu.uy/inco/cursos/proggen/Articulos/sorting.ps.gz">Sorting morphisms</a> for a beautiful examples of using this to understand your program (L Augusteijn.  AFP 1998)).  So <code>walk</code> is pretty much the identity function on trees, and then <code>applyBTree</code> is a flatten function with an accumulating parameter.  Ignoring the intermediate structure, then we see defunctionalization as a way to derive accumulating parameters.</p>

<pre>
> prop_flatten :: BinaryTree Int -> Bool
> prop_flatten t = (flatten_defun t == flatten t)

*Main> quickCheck prop_flatten
OK, passed 100 tests
</pre>

<h2>Defunctionalization as an inverse to church encoding</h2>

<p>This was possibly my favorite part of Danvy&#8217;s paper, but I unfortunately had to elide it from my talk as being slightly
too esoteric for the mixed crowd.</p>

<p>Let us suppose that tuples were not built in to Haskell but we needed to make them ourselves.  The data type and destructors
would look like this:</p>

<pre>
> data MyPair a b = P a b 
>                 deriving (Eq,Show)
>
> myPair x y    = P x y
> myFst (P x y) = x
> mySnd (P x y) = y
</pre>

<p>And we can ask Quickcheck to test extensionality.</p>

<pre>
> prop_pair :: MyPair Int Int -> Bool
> prop_pair p = (p == myPair (myFst p) (mySnd p))

*Main> quickCheck prop_pair
+++ OK, passed 100 tests.
</pre>

<p>So, if you recall whatever lambda-calculus course you may have taken,
we can represent them with only functions.  I like having rank-N
type available for this.</p>

<pre>
> type ChurchPair a b = (forall c . a -> b -> (a -> b -> c) -> c)

> churchPair x y = (\operation -> operation x y)
> churchFst  p   = p (\x y -> x)
> churchSnd  p   = p (\x y -> y)
</pre>

<p>Rather than make an <code>Arbitrary</code> instance, I&#8217;ll settle for reduction
rules in this case.</p>

<pre>
> prop_churchPair :: Int -> Int -> Bool
> prop_churchPair x y = (x == churchFst (churchPair x y)) &#038;&#038;
>                       (y == churchSnd (churchPair x y))

*Main> quickCheck prop_churchPair
+++ OK, passed 100 tests.
</pre>

<p>But now I&#8217;ve introduced a bunch of higher-order functions, so we just <em>have to</em> see how they defunctionalize!</p>

<pre>
> data LamSelector = LamFst | LamSnd
> applySelector (LamFst) x y = x
> applySelector (LamSnd) x y = y
>
> data LamPair a b = LamPair a b
> applyPair (LamPair x y) operation = applySelector operation x y
>
> defunPair x y = (LamPair x y)
> defunFst  p   = applyPair p LamFst
> defunSnd  p   = applyPair p LamSnd
</pre>

<p>You can see that this just reproduces the original, modulo inlining!</p>

<p>Now let&#8217;s church-encode <code>BinaryTree</code> as its own fold (or catamorphism, if you like).  So we have something to defunctionalize, let&#8217;s write <code>churchDepth</code> to calculate the depth of the tree.</p>

<pre>
> type ChurchTree a = forall c. (a -> c) -> (c -> c -> c) -> c

> churchLeaf x     = \onLeaf onNode -> onLeaf x
> churchNode t1 t2 = \onLeaf onNode -> onNode (t1 onLeaf onNode) (t2 onLeaf onNode)
>
> churchFold onLeaf onNode t = t onLeaf onNode

> churchDepth t = t (\x -> 0) (\d1 d2 -> 1 + (d1 `max` d2))
</pre>

<p>Acknowledging that the church encoding is just the fold, we can defunctionalize the fold over any functor to recover the data type. Anyhow&#8230;</p>

<pre>
> data LamLeaf = LamLeaf -- onLeaf
> applyLeaf LamLeaf x = 0
>
> data LamNode = LamNode -- onNode
> applyNode LamNode d1 d2 = 1 + (d1 `max` d2)
>
> data LamTree a = LamTreeLeaf a   -- churchLeaf
>                | LamTreeNode (LamTree a) (LamTree a) -- churchNode
>
> applyTree (LamTreeLeaf x)     onLeaf onNode = applyLeaf onLeaf x
> applyTree (LamTreeNode t1 t2) onLeaf onNode = 
>   applyNode onNode (applyTree t1 onLeaf onNode)
>                    (applyTree t2 onLeaf onNode)
> depth_defun t = applyTree t LamLeaf LamNode
</pre>

<p><code>applyTree</code> is just fold over a tree, as promised, and we&#8217;ve recovered the tree data structure.</p>

<h2>Defunctionalize your continuation</h2>

<p>Suppose you have a first-order (boring!) program.  You can&#8217;t have any fun until you find a way to introduce some first-class functions.  A classic way to introduce a gratuitous number is to convert your code into continuation-passing
style.  Let&#8217;s try it.</p>

<p>This is Danvy&#8217;s &#8216;s example of a parser to recognize the language <img src='http://s.wordpress.com/latex.php?latex=0%5En%201%5En&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='0^n 1^n' title='0^n 1^n' class='latex' />. It is written with an auxiliary function in the <code>Maybe</code> monad to simulate throwing an exception as soon as we can reject the string.</p>

<pre>
> recognize :: [Int] -> Bool
> recognize xs = case walk xs of Just [] -> True
>                                _       -> False 
>   where 
>     walk :: [Int] -> Maybe [Int]
>     walk (0:xs') = do remaining <- walk xs'
>                       case remaining of (1:ys) -> Just ys
>                                         _      -> Nothing
>     walk xs = Just xs -- otherwise
</pre>

<p>The audience insisted that I test this, because it <em>is</em> a bit of a weird way to write a trivial function.</p>

<pre>
> prop_recognize1 n = recognize (take n (repeat 0) ++ take n (repeat 1))
> prop_recognize2 m n = (m >= 0 &#038;&#038; n >= 1 &#038;&#038; m /= n) 
>    ==> (not (recognize (take m (repeat 0) ++ take n (repeat 1))))

*Main> quickCheck prop_recognize1
+++ OK, passed 100 tests.
*Main> quickCheck prop_recognize2
+++ OK, passed 100 tests.
</pre>

<p>Now if we CPS it, we no longer need the <code>Maybe</code> because we can just discard the continuation and return <code>False</code>.</p>

<pre>
> recognize' :: [Int] -> Bool
> recognize' xs = walk xs (\xs' -> [] == xs')
>   where
>     walk :: [Int] -> ([Int] -> Bool) -> Bool
>     walk (0:xs') k = walk xs' (\rem -> case rem of (1:ys) -> k ys
>                                                    _      -> False)
>     walk xs      k = k xs -- otherwise
</pre>

<p>And defunctionalizing it</p>

<pre>
> data Continuation = ContToplevel     -- (\xs' -> null xs')
>                   | ContRecurse Continuation -- (\remaining -> ... )
>
> applyCont ContToplevel    l = (l==[])
> applyCont (ContRecurse k) l = case l of (1:ys) -> applyCont k ys
>                                         _      -> False
>
> recognize'' xs = walk xs ContToplevel
>   where
>     walk (0:xs') k = walk xs' (ContRecurse k)
>     walk xs      k = applyCont k xs
</pre>

<p>But now we can look and see that the continuation data structure is just implementing natural numbers, so we replace it by an Int.</p>

<pre>
> applyNumCont 0 []     = True
> applyNumCont k (1:xs) = applyNumCont (k-1) xs
> applyNumCont _ _      = False

> recognize_final xs = walk xs 0
>   where walk (0:xs') k = walk xs' (k+1)
>         walk xs      k = k xs
</pre>

<p>We get the program we should have written in the first place.</p>

<p>I didn&#8217;t get to the rest of this in my talk, and anyhow it is most interesting to people who play with operational semantics a lot.  This last bit is from Danvy&#8217;s paper <a href="http://www.cs.bham.ac.uk/~hxt/cw04/danvy.pdf">On Evaluation Contexts, Continuations, and The Rest of Computation</a> from the continuation workshop in 2004.</p>

<p>We have a simple arithmetic language, and two ways of giving it a semantics:  We can either <code>reduce</code> the expression a single small step, using <code>reduceAllTheWay</code> to normalize it, or we can <code>eval</code> the expression directly to a result.</p>

<pre>
> data Exp = Value Int
>          | Add Exp Exp
>
> reduce :: Exp -> Exp
> reduce (Add (Value v1) (Value v2)) = Value (v1 + v2)
> reduce (Add (Value v1) e2        ) = Add (Value v1) (reduce e2)
> reduce (Add e1         e2        ) = Add (reduce e1) e2
>
> reduceAllTheWay :: Exp -> Int
> reduceAllTheWay (Value v) = v
> reduceAllTheWay e = reduceAllTheWay (reduce e)
>
> eval :: Exp -> Int
> eval (Value v)   = v
> eval (Add e1 e2) = (eval e1) + (eval e2)
</pre>

<p>Now we CPS both of them</p>

<pre>
> reduceCPS :: Exp -> (Exp -> a) -> a
> reduceCPS (Add (Value v1) (Value v2)) k = k (Value (v1 + v2))
> reduceCPS (Add (Value v1) e2        ) k = reduceCPS e2 (\e -> k (Add (Value v1) e))
> reduceCPS (Add e1         e2        ) k = reduceCPS e1 (\e -> k (Add e e2))
>
> reduceAllTheWayCPS :: Exp -> (Int -> a) -> a
> reduceAllTheWayCPS (Value v) k = k v
> reduceAllTheWayCPS e         k = reduceCPS e (flip reduceAllTheWayCPS k)

> evalCPS :: Exp -> (Int -> a) -> a
> evalCPS (Value v)   k = k v
> evalCPS (Add e1 e2) k = evalCPS e1 (\v1 -> evalCPS e2 (\v2 -> k (v1 + v2)))
</pre>

<p>CPS code is easier to read when I write it like this</p>

<pre>
> evalCPS' :: Exp -> (Int -> a) -> a
> evalCPS' (Value v)   k = k v
> evalCPS' (Add e1 e2) k = evalCPS e1 (\v1 ->
>                          evalCPS e2 (\v2 ->
>                          k (v1+v2)  ))
</pre>

<p>and I might as well admit that Haskell already has this in the bag</p>

<pre>
> evalCPS'' :: Exp -> Cont a Int
> evalCPS'' (Value v)   = return v
> evalCPS'' (Add e1 e2) = do v1 <- evalCPS'' e1
>                            v2 <- evalCPS'' e2
>                            return (v1 + v2)
</pre>

<p>Now we defunctionalize both semantics</p>

<pre>
> data ContReduce = ContReduce  -- (flip reduceAllTheWay)
>                 | ContAddV1 Exp ContReduce -- (\e -> Add (Value v1) e)
>                 | ContAddE2 ContReduce Exp -- (\e -> Add e e2)
>
> applyContReduce :: ContReduce -> Exp -> Exp
> applyContReduce ContReduce e = e
> applyContReduce (ContAddV1 v1 k) e = applyContReduce k (Add v1 e)
> applyContReduce (ContAddE2 k e2) e = applyContReduce k (Add e e2)
>
> reduceCPSdefun :: Exp -> ContReduce -> Exp
> reduceCPSdefun (Add (Value v1) (Value v2)) k = applyContReduce k (Value (v1 + v2))
> reduceCPSdefun (Add (Value v1) e2        ) k = reduceCPSdefun e2 (ContAddV1 (Value v1) k)
> reduceCPSdefun (Add e1         e2        ) k = reduceCPSdefun e1 (ContAddE2 k e2)
</pre>

<p>The data type <code>ContReduce</code> is the now-common notion of an &#8220;evaluation context&#8221; which some researchers prefer because it separates the important rules about how terms are reduced from the rules that just tell you where in a term reduction happens.</p>

<p>Next&#8230;</p>

<pre>
> data ContEval = ContEval -- toplevel
>               | ContE1 ContEval Exp
>               | ContE2 Int ContEval
>
> applyContEval :: ContEval -> Int -> Int
> applyContEval (ContEval) v = v
> applyContEval (ContE1 k e2) v1 = evalCPSdefun e2 (ContE2 v1 k) 
> applyContEval (ContE2 v1 k) v2 = applyContEval k (v1 + v2)
>
> evalCPSdefun (Value v)   k = applyContEval k v
> evalCPSdefun (Add e1 e2) k = evalCPSdefun e1 (ContE1 k e2)
</pre>

<p>Hey it looks like almost the same thing!  The difference is in how we interpret the data structure.  In the previous case, <code>applyContReduce</code> just used it for navigation.  In this case, <code>applyContEval</code> calls back into <code>evalCPSdefun</code> to keep the evaluation rolling.</p>

<p>If, like myself, you liked this because you feel there is important and interesting structure underlying operational semantics that is
hidden by its many superficial forms, then you&#8217;ll probably like this additional reading:</p>

<ul>
<li><a href="http://www.cs.nott.ac.uk/~gmh/bib.html#modular">Modularity and implementation of mathematical operational semantics</a>.  M Jaskelioff, N Ghani, G Hutton.  MSFP 2008.</li>
<li><a href="http://www.cs.nott.ac.uk/~gmh/bib.html#semantics">Fold and unfold for program semantics</a>.  G Hutton.  ICFP 1998.</li>
</ul>

<p>And I leave you with my hidden instances of arbitrary&#8230;</p>

<pre>
> instance Arbitrary a => Arbitrary (BinaryTree a) where
>   arbitrary = oneof [liftM Leaf arbitrary, liftM2 Node arbitrary arbitrary]

> instance (Arbitrary a, Arbitrary b) => Arbitrary (MyPair a b) where
>   arbitrary = liftM2 myPair arbitrary arbitrary
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2008/05/24/what-is-defunctionalization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging with Open Recursion Mixins</title>
		<link>http://www.kennknowles.com/blog/2008/05/10/debugging-with-open-recursion-mixins/</link>
		<comments>http://www.kennknowles.com/blog/2008/05/10/debugging-with-open-recursion-mixins/#comments</comments>
		<pubDate>Sat, 10 May 2008 21:19:25 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[coproduct]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[expression problem]]></category>
		<category><![CDATA[mixin]]></category>
		<category><![CDATA[monad]]></category>
		<category><![CDATA[open recursion]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2008/05/10/debugging-with-open-recursion-mixins/</guid>
		<description><![CDATA[The call is out for submissions to the next issue of The Monad.Reader! To get an idea of the content (and because Don Stewart told us all to read every past issue) I cracked open Issue 10, which has a nice tutorial by B Pope on the GHCi debugger. But having just finished a post [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.haskell.org/pipermail/haskell-cafe/2008-May/042493.html">call is out</a> for submissions to the next issue of <a href="http://www.haskell.org/haskellwiki/The_Monad.Reader">The Monad.Reader</a>!  To get an idea of the content (and because <a href="http://www.haskell.org/pipermail/haskell-cafe/2008-May/042580.html">Don Stewart told us all to read every past
issue</a>) I cracked open <a href="http://www.haskell.org/sitewiki/images/0/0a/TMR-Issue10.pdf">Issue 10</a>, which has a nice tutorial by B Pope on the GHCi debugger.</p>

<p>But having just finished <a href="http://www.kennknowles.com/blog/2008/05/07/ctl-model-checking-in-haskell-a-classic-algorithm-explained-as-memoization/">a post using open recursion</a>, it immediately cried out to me that open-recursive functions already have some debugging hooks for tracing/breakpoints/etc.  Naturally, some complications arose, and I got to try out some other cool ideas from the literature.</p>

<p>To combine the <code>State</code> in which I store the memoization table with the <code>IO</code> I use for debugging, I use</p>

<ul>
<li><a href="http://www.mcs.le.ac.uk/~ng13/papers/icfp02.ps.gz">Composing monads using coproducts</a>.  C Lüth, N Ghani.  ICFP 2002.</li>
</ul>

<p>And then to reduce the plumbing overhead I use</p>

<ul>
<li><a href="http://www.cs.nott.ac.uk/~wss/Publications/DataTypesALaCarte.pdf">Data Types a la Carte</a>.  W Swierstra. Accepted to JFP.</li>
</ul>

<p>This post is, as usual, a literate Haskell file so load it up in GHCi or Emacs Haskell-mode and see what happens.
<span id="more-61"></span></p>

<pre>
> {-# LANGUAGE TypeOperators,ScopedTypeVariables,PatternSignatures,RankNTypes,FlexibleInstances,UndecidableInstances,OverlappingInstances,IncoherentInstances,MultiParamTypeClasses,FlexibleContexts #-}

> import qualified Data.Map as M
> import Control.Monad.State hiding (fix)
</pre>

<p>Here&#8217;s the previous example of a monadified, open-recursion fibonacci, </p>

<pre>
> type Gen a = (a -> a)
>
> fix :: Gen a -> a
> fix f = f (fix f)
>
> gmFib :: Monad m => Gen (Int -> m Int)
> gmFib recurse 0     = return 0
> gmFib recurse 1     = return 1
> gmFib recurse n = do a <- recurse (n-1)
>                      b <- recurse (n-2)
>                      return (a + b)
</pre>

<p>&#8230; and the <a href="http://www.cs.utexas.edu/~wcook/Drafts/2006/MemoMixins.pdf">memoization mixin</a></p>

<pre>
> type Memoized a b = State (M.Map a b)
>
> memoize :: (Ord a) => Gen (a -> Memoized a b b)
> memoize self x = do memo <- check x
>                     case memo of
>                               Just y  -> return y
>                               Nothing -> do y <- self x
>                                             store x y
>                                             return y
>
> check :: Ord a => a -> Memoized a b (Maybe b)
> check x = do memotable <- get
>              return (M.lookup x memotable)
>
> store :: Ord a => a -> b -> Memoized a b ()
> store x y = do memotable <- get
>                put (M.insert x y memotable)
>
> runMemo :: Ord a => Memoized a b c -> c
> runMemo m = evalState m M.empty
>
> fibMemo n = runMemo $ fix (gmFib . memoize) n
</pre>

<p>So let us begin debugging.  The first thing that comes to
mind is viewing the results of each recursive call.</p>

<pre>
> inspect :: (Show a, Show b) => String -> Gen (a -> IO b)
> inspect name self arg = do result <- self arg
>                            putStrLn $ name ++ " " ++ show arg 
>                                       ++ " = " ++ show result
>                            return result

> fibInspect n = fix (gmFib . inspect "fib") n
</pre>

<p>Trying it out&#8230;</p>

<pre>
*Main> fibInspect 5
fib 1 = 1
fib 0 = 0
fib 1 = 1
fib 2 = 1
fib 3 = 2
fib 0 = 0
fib 1 = 1
fib 2 = 1
fib 1 = 1
fib 0 = 0
fib 1 = 1
fib 2 = 1
fib 3 = 2
fib 4 = 3
5
</pre>

<p>That was easy!  Now when I also mix in the memoization I should see a lot of those recursive calls drop away.  But I cannot simply write <code>fix (gmFib . inspect "fib" . memoize)</code> because mixing in <code>inspect</code> fixes the underlying monad to <code>IO</code>, while mixing in <code>memoize</code> fixes it to <code>Memoized Int Int</code>.  I need to run this computation in a monad that supports the operations of both <code>IO</code> and <code>State</code>.  Well, in category theory terms, the smallest <a href="http://www.math.harvard.edu/~mazur/preprints/when_is_one.pdf">&#8220;thing&#8221;</a> that contains two other &#8220;things&#8221; is their coproduct, so this is exactly what the Luth-Ghani paper mentioned above is for!</p>

<p>I&#8217;ll be inlining and de-generalizing a bunch of the (beautiful) code from the paper to get the point across quickly.  The linked papers and other references are highly recommended for a deeper understanding.</p>

<pre>
> data Plus m1 m2 a = T1 (m1 (Plus m1 m2 a))
>                   | T2 (m2 (Plus m1 m2 a))
>                   | Var a
</pre>

<p>This data type is not <em>exactly</em> the coproduct, but rather a data type that can represent it, like using a list to represent a set &#8211; there are multiple lists that represent the same set, but if you respect the abstraction you are OK.  Most of the ways of processing this data structure can be written in Haskell using only <code>Functor</code> instances for the underlying structure, but to make sure we only use it in the appropriate places I&#8217;ve just made the stronger requirement that <code>m1</code> and <code>m2</code> be <code>Monad</code>s everywhere.  But I still want <code>fmap</code> so I turn on undecidable instances and add the following.</p>

<pre>
> instance Monad m => Functor m where
>     fmap f m = m >>= (return . f)
</pre>

<p>Now you might ask why I&#8217;m not using monad transformers.  Four reasons come to mind:</p>

<ol>
<li>I wanted to try out the contents of this paper.</li>
<li>The coproduct is defined for two arbitrary monads, without writing a special
version of either that &#8220;holds&#8221; another inside.</li>
<li>The coproduct can have the two &#8220;layers&#8221; interleaved in more arbitrary ways</li>
<li>The coproduct is theoretically simpler and more fundamental.</li>
</ol>

<p>This is now one of those structures that is so abstract that you can figure out how to process it just by writing the only function of the proper type.</p>

<pre>
> fold :: (Monad f1, Monad f2) => -- fold by cases over Plus
>             (a -> b)     -> -- variables
>             (f1 b -> b)  -> -- bits from f1 
>             (f2 b -> b)  -> -- bits from f2
>             Plus f1 f2 a -> -- the input
>             b -- Yay!

> fold e f1 f2 (Var x) = e x
> fold e f1 f2 (T1 t) = f1 (fmap (fold e f1 f2) t)
> fold e f1 f2 (T2 t) = f2 (fmap (fold e f1 f2) t)

> instance (Monad m1, Monad m2) => Monad (Plus m1 m2) where
>     return x = Var x
>     m >>= f = fold f T1 T2 m
</pre>

<p>The functor instance induced by the monad would look like this</p>

<pre>
 instance (Monad m1, Monad m2) => Functor (Plus m1 m2) where
     fmap f = fold (Var . f) T1 T2
</pre>

<p>Here <code>fmap</code> traverse the shapes of <code>m1</code> and <code>m2</code> and applies <code>f</code> where
it finds a <code>Var</code> constructor.  To get a better picture, try combining
the bodies of <code>fold</code> and <code>fmap</code>:</p>

<pre>
 fmap f (Var x) = Var (f x)
 fmap f (T1 t) = T1 (fmap (fmap f) t)
 fmap f (T2 t) = T2 (fmap (fmap f) t)
</pre>

<p>And then we want to be able to inject things from <code>m1</code> and <code>m2</code> into the coproduct.</p>

<pre>
> inl :: Monad m1 => m1 a -> Plus m1 m2 a
> inl = T1 . fmap Var

> inr :: Monad m2 => m2 a -> Plus m1 m2 a
> inr = T2 . fmap Var

> liftL :: Monad m1 => (a -> m1 b) -> (a -> Plus m1 m2 b)
> liftL f = inl . f 

> liftR :: Monad m2 => (a -> m2 b) -> (a -> Plus m1 m2 b)
> liftR f = inr . f 
</pre>

<p>At this point I&#8217;ve got the machinery to combine the <code>IO</code> and <code>Memoized</code> monads as desired, but my code would be full of <code>inr</code>, <code>inl</code>, <code>liftL</code> and <code>liftR</code>. This is where we bring in the Swierstra pearl (used and discussed all over place: See <a href="http://www.cs.nott.ac.uk/~gmh/modular.pdf">Modularity and implementation of mathematical operational semantics</a>, <a href="http://wadler.blogspot.com/2008/02/data-types-la-carte.html">Phil Wadler&#8217;s blog</a>, <a href="http://www.haskell.org/pipermail/haskell-cafe/2008-February/040098.html">a thread on haskell-cafe</a>, and of course <a href="http://lambda-the-ultimate.org/node/2700">Lambda the Ultimate</a>)</p>

<p>Again, I&#8217;m specializing all the types to <code>Monad</code> but they were presented for more general functors.</p>

<pre>
> class (Monad smaller, Monad larger) => Included smaller larger where
>     inject :: smaller a -> larger a

> instance Monad f => Included f f where
>     inject = id

> instance (Monad f, Monad g) => Included f (Plus f g) where
>     inject = inl

> instance (Monad f, Monad g) => Included g (Plus f g) where
>     inject = inr
</pre>

<p>Also, since for this example I don&#8217;t use nested coproducts I&#8217;m leaving
out this instance, which opens up a can of worms:</p>

<pre>
 instance (Monad f, Monad g, Monad h, Included f h) => Included f (Plus g h) where
    inject = inr . inject
</pre>

<p>Definitely see the links above if you are curious about how this plays out.</p>

<p>Back to the debugging story.  Here is how we modify <code>inspect</code> and <code>memoize</code>.</p>

<pre>
> inspectM :: (Show a, Show b, Monad m, Included IO m) => String -> Gen (a -> m b)
> inspectM name self arg = do result <- self arg
>                             inject $ putStrLn $ name ++ " " ++ show arg 
>                                                 ++ " = " ++ show result
>                             return result

> memoizeM :: (Ord a, Monad m, Included (Memoized a b) m) => Gen (a -> m b)
> memoizeM self x = do memo <- inject $ check x
>                      case memo of
>                               Just y  -> return y
>                               Nothing -> do y <- self x
>                                             inject $ store x y
>                                             return y

> mFibTraceMemo :: Int -> Plus (Memoized Int Int) IO Int
> mFibTraceMemo = fix (gmFib . memoizeM . inspectM "fib")
</pre>

<p>But wait, how do I run this thing?  It has <code>IO</code> and <code>Memoized</code> layers all mixed up!  Intuitively, I&#8217;m sure you believe that if I start with an empty memo table and start running an <code>IO</code> that has some memoized bits in it, I can thread the memo table throughout.</p>

<p>In classic Haskell style, we can separate the &#8220;threading&#8221; concern from the &#8220;running&#8221; by writing an untangling function of type <code>Plus m1 m2 a -&gt; m1 (m2 a)</code>.  But in fact, we don&#8217;t even need to do that much work. Discussed in the Luth-Ghani paper is the idea of a <em>distributivity law</em>, which in hacking terms means a function that just does one bit of the untangling, specifically a single &#8220;untwist&#8221; of type <code>forall a. m2 (m1 a) -&gt; (m1 (m2 a))</code>.  If we can write an untwist function, then a fold over the monad coproduct does the rest of the untangling.</p>

<p>Let us make this concrete for <code>IO</code> and <code>State</code>.</p>

<pre>
> ioState :: IO (State s c) -> State s (IO c)
> ioState io = State $ \s -> ((do st <- io
>                                 return (evalState st s)), s)
</pre>

<p>This function essentially corresponds to the <code>MonadIO</code> instance of the <code>StateT</code> monad transformer.  More generally, Luth-Ghani show that when you can write one of these distributivity laws, then using the coproduct is isomorphic to using monad transformers, so I already knew this part would work out <img src='http://www.kennknowles.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<p>Here is how we fold an &#8220;untwist&#8221; into an &#8220;untangle&#8221;</p>

<pre>
> distribL :: (Monad m1, Monad m2) => 
>               (forall b. m2 (m1 b) -> m1 (m2 b)) -> -- A flick of the wrist
>               Plus m1 m2 a ->                       -- A tangled skein
>               m1 (m2 a)                             -- A silken thread
> distribL untwist = fold (return . return) join (fmap join . untwist)
</pre>

<p>It may be easier to see it written out in pointful style.</p>

<pre>
distribL untwist (Var x) = return (return x)
distribL untwist (T1 t)  = join (fmap (distribL untwist) t)
distribL untwist (T2 t)  = fmap join (untwist (fmap (distribL untwist) t))
</pre>

<p>Another way to convince yourself that your function is correct is to think&#8230; how many functions even have the necessary type?  Not very many, since you <em>need</em> the higher-rank type for the parameter for this guy to even type check!  When dealing with very abstract functions, you
often gain enough via parametericity to make up for the loss in intuitive clarity.  (Sounds like a Grothendieck quote that I can&#8217;t Google up at the moment &#8211; something about piling layers and layers of abstraction on a problem until it unravels itself before your eyes)</p>

<pre>
> runMemoIO :: Plus (Memoized a b) IO b -> IO b
> runMemoIO result = evalState (distribL ioState result) M.empty

> fibTraceMemo = runMemoIO . mFibTraceMemo
</pre>

<p>Now we can visually confirm that it is not repeating any computation:</p>

<pre>
*Main> fibTraceMemo 10
fib 1 = 1
fib 0 = 0
fib 2 = 1
fib 3 = 2
fib 4 = 3
fib 5 = 5
fib 6 = 8
fib 7 = 13
fib 8 = 21
fib 9 = 34
55
</pre>

<p>Note that this is a little sensitive to explicit type signatures again.  When I inlined
the body of <code>mFibTraceMemo</code> I needed to ascribe a type to <code>memoizeM</code> like so:</p>

<pre>
 memoizeM' :: Gen (Int -> Plus (Memoized Int Int) IO Int) = memoizeM
</pre>

<p>Now that the vamp is playing, let&#8217;s riff on it.  How about catching calls to
negative numbers?</p>

<pre>
> guardedBail :: forall a b m. (Monad m, Included (Memoized a b) m) => 
>                              (a -> Bool) -> Gen (a -> m b)
> guardedBail pred self arg = if pred arg then error "Forbidden!" else self arg
</pre>

<p>Or suppose we have memory consumption concerns, and we want to watch the size
of the memo table?</p>

<pre>
> printSize :: forall a b m. 
>              (Monad m, Included (Memoized a b) m, Included IO m) => 
>              Gen (a -> m b)
> printSize self arg = do result <- self arg
>                         size <- inject $ getSize
>                         inject $ putStrLn $ "Memo table size: " ++ show size
>                         return result
>     where getSize :: Memoized a b Int = do memotable <- get
>                                            return $ M.size memotable
</pre>

<p>When I try to separate <code>getSize</code> as an independent function I get 
type class error message pain, so I left it in the <code>where</code> clause.</p>

<pre>
> mFibSizeTrace :: Int -> Plus (Memoized Int Int) IO Int
> mFibSizeTrace = fix (gmFib . memoizeM . printSize 
>                      . inspectM "fib" . guardedBail (<0)) 

> fibSizeTrace n = runMemoIO $ mFibSizeTrace n
</pre>

<p>And running it&#8230;</p>

<pre>
*Main> fibSizeTrace 10
fib 1 = 1
Memo table size: 0
fib 0 = 0
Memo table size: 1
fib 2 = 1
Memo table size: 2
fib 3 = 2
Memo table size: 3
fib 4 = 3
Memo table size: 4
fib 5 = 5
Memo table size: 5
fib 6 = 8
Memo table size: 6
fib 7 = 13
Memo table size: 7
fib 8 = 21
Memo table size: 8
fib 9 = 34
Memo table size: 9
55
*Main> fibSizeTrace (-1)
*** Exception: Forbidden!
</pre>

<p>Of course, we are storing all these past results that don&#8217;t matter
anymore.  I can certainly delete the entry that is three less than the
current argument.</p>

<pre>
> clearPrev :: forall b m. 
>              (Monad m, Included (Memoized Int b) m) => Gen (Int -> m b)
> clearPrev self arg = do inject $ clear (arg - 3)
>                         self arg
>     where clear :: Int -> Memoized Int b ()
>           clear key = do memotable <- get
>                          put (M.delete key memotable)

> mFibFinal :: Int -> Plus (Memoized Int Int) IO Int
> mFibFinal = fix (gmFib . clearPrev . memoizeM . inspectM "fib" 
>                  . guardedBail (<0) . printSize)

> fibFinal n = runMemoIO $ mFibFinal n
</pre>

<p>Running it&#8230;</p>

<pre>
*Main> fibFinal 15
Memo table size: 0
fib 1 = 1
Memo table size: 1
fib 0 = 0
Memo table size: 2
fib 2 = 1
Memo table size: 3
fib 3 = 2
Memo table size: 4
fib 4 = 3
Memo table size: 4
fib 5 = 5
Memo table size: 4
fib 6 = 8
Memo table size: 4
fib 7 = 13
Memo table size: 4
fib 8 = 21
Memo table size: 4
fib 9 = 34
Memo table size: 4
fib 10 = 55
Memo table size: 4
fib 11 = 89
Memo table size: 4
fib 12 = 144
Memo table size: 4
fib 13 = 233
Memo table size: 4
fib 14 = 377
610
</pre>

<p>I have a vague feeling that a real debugging package could be made from this approach, but if not at least today was some fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2008/05/10/debugging-with-open-recursion-mixins/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CTL Model Checking in Haskell:  A Classic Algorithm Explained as Memoization</title>
		<link>http://www.kennknowles.com/blog/2008/05/07/ctl-model-checking-in-haskell-a-classic-algorithm-explained-as-memoization/</link>
		<comments>http://www.kennknowles.com/blog/2008/05/07/ctl-model-checking-in-haskell-a-classic-algorithm-explained-as-memoization/#comments</comments>
		<pubDate>Wed, 07 May 2008 09:13:46 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Reading]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[model checking]]></category>
		<category><![CDATA[monads]]></category>
		<category><![CDATA[open recursion]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2008/05/07/ctl-model-checking-in-haskell-a-classic-algorithm-explained-as-memoization/</guid>
		<description><![CDATA[As an exercise, since my reading group was discussing model checking this week, I implemented the classic model checker for CTL specifications from the 1986 paper Automatic Verification of Concurrent Systems Using Temporal Logic Specifications by EM Clarke, EM Emerson, AP Sistla. The &#8220;efficient algorithm&#8221; presented in the paper is, upon reflection, merely a memoized [...]]]></description>
			<content:encoded><![CDATA[<p>As an exercise, since my reading group was discussing model checking this week, I implemented the classic model checker for CTL specifications from the 1986 paper</p>

<ul>
<li><a href="http://research.microsoft.com/users/qadeer/cse599f/papers/clarke-toplas.pdf">Automatic Verification of Concurrent Systems Using Temporal Logic Specifications</a> by EM Clarke, EM Emerson, AP Sistla.</li>
</ul>

<p>The &#8220;efficient algorithm&#8221; presented in the paper is, upon reflection, merely a memoized traversal of the state machine,
so I combined it with a modified version of</p>

<ul>
<li><a href="http://www.cs.utexas.edu/~wcook/Drafts/2006/MemoMixins.pdf">Monadic Memoization Mixins</a> by D Brown, WR Cook</li>
</ul>

<p>which actually eliminated an auxilliary function from the algorithm, yielding an efficiently-executable 20-line Haskell specification of the meaning of CTL (which is probably clearer than my English prose explanation, and certainly more fun to play with).</p>

<p><a href='http://www.kennknowles.com/blog/wp-content/uploads/2008/05/redyellowgreen.png' title='redyellowgreen.png'><img src='http://www.kennknowles.com/blog/wp-content/uploads/2008/05/redyellowgreen.png' alt='redyellowgreen.png' /></a></p>

<p>This post is, as usual, literate Haskell.  Load it up in GHCi, Haskell-mode, or compile it with <code>ghc --make</code> and try it out.  Maybe you can convince my state space exploration not to terminate <img src='http://www.kennknowles.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> 
<span id="more-58"></span></p>

<pre>
> {-# LANGUAGE TypeOperators,ScopedTypeVariables,PatternSignatures #-}

> import qualified Data.Map as M
> import qualified Data.Set as S
> import Data.List
> import Control.Monad 
> import Control.Monad.State hiding (fix)
</pre>

<h2>Memoization Mixins</h2>

<p>Here is the easy example from the Brown-Cook paper, before getting on to model checking.</p>

<p>To enable functional mixins, we write our functions using open recursion.  Instead of a function of type <code>a -&gt; b</code> 
we write one of type <code>Gen (a -&gt; b)</code> and then later &#8220;tie the knot&#8221; with <code>fix</code> (reproduced here for reference)</p>

<pre>
> type Gen a = (a -> a)

> fix :: Gen a -> a
> fix f = f (fix f)
</pre>

<p>The classic example they start with is calculating the nth fibonacci number, but don&#8217;t stop reading just because this example is simple!  It is just to illustrate the technique.</p>

<pre>
> fib :: Int -> Int
> fib 0     = 0
> fib 1     = 1
> fib (n+2) = fib n + fib (n+1)
</pre>

<p>By the time you get to <code>fib 30</code> it takes a dozen or seconds to return
on my poor old computer.  Rewrittin in open recursion as</p>

<pre>
> gFib :: Gen (Int -> Int)
> gFib recurse 0     = 0
> gFib recurse 1     = 1
> gFib recurse (n+2) = recurse n + recurse (n+1)

> fib' = fix gFib
</pre>

<p>This <code>fib'</code> has essentially the same performance, up to constant factors: slow.</p>

<p>To enable us to store the memoization table in something like a <code>State</code>, we parameterize over an underlying monad.  A beautiful technique in its own right, if you ask me.  I agree with the authors that open recursion and monadification are important and powerful enough to deserve language support; you probably will think <code>gmFib</code> below looks a bit crufty.</p>

<pre>
> gmFib :: Monad m => Gen (Int -> m Int)
> gmFib recurse 0     = return 0
> gmFib recurse 1     = return 1
> gmFib recurse (n+2) = do a <- recurse n
>                          b <- recurse (n+1)
>                          return (a + b)
</pre>

<p>And now we can mix in <code>memoize</code></p>

<pre>
> type Memoized a b = State (M.Map a b)

> memoize :: Ord a => Gen (a -> Memoized a b b)
> memoize self x = do memo <- check x
>                     case memo of
>                       Just y  -> return y
>                       Nothing -> do y <- self x
>                                     store x y
>                                     return y

> check :: Ord a => a -> Memoized a b (Maybe b)
> check x = do memotable <- get
>              return (M.lookup x memotable)

> store :: Ord a => a -> b -> Memoized a b ()
> store x y = do memotable <- get
>                put (M.insert x y memotable)
</pre>

<p>Here&#8217;s the final fib, which returns instantly up to at least <code>10000</code>.</p>

<pre>
> fib'' n = evalState (fix (gmFib . memoize) n) M.empty
</pre>

<h2>Computation Tree Logic (CTL)</h2>

<p>The language for which Clarke et al give a graph-based algorithm is called CTL; nowadays people are interested in a bunch of variants like CTL* and ACTL.  I&#8217;m not a model-checking researcher so I don&#8217;t really know the subtleties of their differences.  CTL is
a logic for specifying certain restricted kinds of predicates over the possible traces of a state machine, for today a finite state machine.</p>

<p>Let&#8217;s just look at the Haskell definition:</p>

<pre>
> data CTL p = TT | FF
>            | Atomic p
>            | Not (CTL p)
>            | And (CTL p) (CTL p)
>            | AllSucc  (CTL p)
>            | ExSucc   (CTL p)
>            | AllUntil (CTL p) (CTL p)
>            | ExUntil  (CTL p) (CTL p)
>              deriving (Eq,Ord)
</pre>

<p>Some of these are simply your usual logic</p>

<ul>
<li><code>TT</code> holds of any state</li>
<li><code>FF</code> never holds</li>
<li><code>Atomic p</code> is some atomic proposition over a state, like inequality over program variables, etc.</li>
<li><code>Not</code> and <code>And</code> have their expected meanings</li>
</ul>

<p>The successor constructions let you talk about &#8220;the next&#8221; state:</p>

<ul>
<li><code>AllSucc f</code> (respectively <code>ExSucc</code>) holds of a state <code>s</code> when the formula <code>f</code> holds for all (respectively some) successor states.</li>
</ul>

<p>The interesting ones though, are &#8220;Always Until&#8221; and &#8220;Exists Until&#8221;:</p>

<ul>
<li><code>AllUntil f1 f2</code> holds of a state <code>s</code> when for <em>all</em> prefixes of any trace starting at <code>s</code> you eventually reach a state satisfying <code>f2</code>, and everywhere along the way <code>f1</code> holds.</li>
<li><code>ExUntil</code> is the existential version of that.</li>
</ul>

<p>We can then define some more predicates like &#8220;forever in the future&#8221; and &#8220;eventually&#8221;</p>

<pre>
> allFuture f = AllUntil TT f
> existsFuture f = ExUntil TT f

> allGlobal f = Not(existsFuture(Not f))
> existsGlobal f = Not(allFuture(Not f))
</pre>

<p>Now, to apply a formula to a state machine, first I need the state machine.
I&#8217;ll just represent it by its successor function.</p>

<pre>
> type Succ st = st -> [st]
</pre>

<p>And we need some interpretation of atomic formulas as predicates over states</p>

<pre>
> type Interp p st = p -> st -> Bool
</pre>

<p>And since I&#8217;m using a monadified form of computation, I will lift a bunch
of operations into monads to make everything readable.</p>

<pre>
> andThen,orElse :: Monad m => m Bool -> m Bool -> m Bool
> andThen = liftM2 (&#038;&#038;) 
> orElse  =  liftM2 (||) 

> notM :: Monad m => m Bool -> m Bool
> notM = liftM not

> anyM,allM :: Monad m => (s -> m Bool) -> [s] -> m Bool
> allM f = liftM and . mapM f
> anyM f = liftM or  . mapM f
</pre>

<h2>The Model-Checking Algorithm</h2>

<p>In the Clarke et al paper, the algorithm is expressed by induction on the formula <code>f</code> you want to check:  First, label your state-space graph with all the atomic formula that hold at each state.  Then, label with each the compound formula of height two that holds.  Etc, etc, you are guaranteed that the graph is already labeled with each subformula by the time it becomes necessary.</p>

<p>Like dynamic programming, this is simply a complicated way of expressing memoization.  In fact, they even use a depth-first search helper function that is completely eliminated by expressing it as a memoized function.  This code is considerably shorter and, I think, clearer than the pseudocode in the paper, modulo the overhead of &#8220;mixing in&#8221; and &#8220;tying the knot&#8221;.</p>

<p>Today we have fancy algorithms involving BDDs and abstraction, so I&#8217;m not claiming anything <em>useful</em> except pedagogically.  I do wonder, though, if this code gains something through laziness.  It certainly traverses the state space fewer times (but I&#8217;m sure an implementation of their algorithm would do similar optimizations).</p>

<pre>
> checkCTL :: forall p st . (Ord p, Ord st) => 
>                           Interp p st -> Succ st -> st -> CTL p -> Bool
> checkCTL interp succ init f = 
>    evalState (fix (gCheckCTL . cyclicMemoize2 False) f init) M.empty
>  where 
>    gCheckCTL :: Monad m => Gen (CTL p -> st -> m Bool)
>    gCheckCTL recurse f s = checkFormula f
>      where checkFormula TT           = return True
>            checkFormula FF           = return False
>            checkFormula (Atomic p)   = return (interp p s)
>            checkFormula (Not f1)     = notM (recurse f1 s)
>            checkFormula (And f1 f2)  = recurse f1 s `andThen` recurse f2 s
>            checkFormula (AllSucc f1) = allM (recurse f1) (succ s)
>            checkFormula (ExSucc f1)  = anyM (recurse f1) (succ s)

>            checkFormula (AllUntil f1 f2) = recurse f2 s `orElse` 
>                            (recurse f1 s `andThen` allM (recurse f) (succ s))

>            checkFormula (ExUntil f1 f2)  = recurse f2 s `orElse` 
>                            (recurse f1 s `andThen` anyM (recurse f) (succ s))
</pre>

<p>You may also notice that I cheated a little, perhaps.  I have used <code>cyclicMemoize2</code> instead of <code>memoize</code>:</p>

<pre>
> cyclicMemoize2 :: (Ord a, Ord b) => c -> Gen (a -> b -> Memoized (a,b) c c)
> cyclicMemoize2 backEdge self x y = do memo <- check (x,y)
>                                       case memo of
>                                          Just z  -> return z
>                                          Nothing -> do store (x,y) backEdge
>                                                        z <- self x y
>                                                        store (x,y) z
>                                                        return z
</pre>

<p>One reason is simply that I need a curry/uncurry wrapper for my two argument monadified function.
The deeper thing is that <code>cyclicMemoize2 False</code> inserts a fake memoization entry while a computation
is progressing.  If there is ever a &#8220;back edge&#8221; in the search, it will return this dummy entry.
For CTL, the auxilliary depth-first search used in the paper for <code>AllUntil</code> returns <code>False</code> in these 
cases, so I seed the memo table accordingly.  This is because by the time you have recursed
around a cycle, that means that the <code>f2</code> you are searching for did not occur on the cycle, so it
never will.</p>

<p>To play with it, I&#8217;ve only made a couple of examples involving stop lights (of occasionally curious colors).  I&#8217;d love more, and you&#8217;ll undoubtedly find
bugs if you actually run something significant.</p>

<pre>
> ex1interp p s = (p == s)

> ex1succ "Red"    = ["Green"]
> ex1succ "Green"  = ["Yellow"]
> ex1succ "Yellow" = ["Red"]

> ex2succ "Red"    = ["Green"]
> ex2succ "Green"  = ["Yellow", "Orange"]
> ex2succ "Orange" = ["Red"]
> ex2succ "Yellow" = ["Red"]
</pre>

<p>But it looks kind of OK,</p>

<pre>
*Main> let ch2 = checkCTL ex1interp ex2succ
*Main> let ch1 = checkCTL ex1interp ex1succ
*Main> ch1 "Red" (existsFuture (Atomic "Red"))
True
*Main> ch1 "Red" (existsFuture (Atomic "Blue"))
False
*Main> ch2 "Green" (ExUntil TT (Atomic "Red"))
True
*Main> ch2 "Green" (ExUntil (Atomic "Green") (Atomic "Orange"))
True
*Main> ch1 "Green" (Not (AllUntil (Not (Atomic "Yellow")) (Atomic "Red")))
True
*Main> ch1 "Green" (Not (ExUntil (Not (Atomic "Yellow")) (Atomic "Red")))
True
*Main> ch2 "Green" (Not (ExUntil (Not (Atomic "Yellow")) (Atomic "Red")))
False
</pre>

<p>Quite fun!</p>

<p><a href='http://www.kennknowles.com/blog/wp-content/uploads/2008/05/redyelloworangegreen.png' title='redyelloworangegreen.png'><img src='http://www.kennknowles.com/blog/wp-content/uploads/2008/05/redyelloworangegreen.png' alt='redyelloworangegreen.png' /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2008/05/07/ctl-model-checking-in-haskell-a-classic-algorithm-explained-as-memoization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using HaXml to make a PDF slideshow from an Inkscape SVG</title>
		<link>http://www.kennknowles.com/blog/2008/04/20/using-haxml-to-make-a-pdf-slideshow-from-an-inkscape-svg/</link>
		<comments>http://www.kennknowles.com/blog/2008/04/20/using-haxml-to-make-a-pdf-slideshow-from-an-inkscape-svg/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 09:01:21 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[gournal]]></category>
		<category><![CDATA[HaXml]]></category>
		<category><![CDATA[Inkscape]]></category>
		<category><![CDATA[jarnal]]></category>
		<category><![CDATA[note-taking]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[slide]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[xournal]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2008/04/20/using-haxml-to-make-a-pdf-slideshow-from-an-inkscape-svg/</guid>
		<description><![CDATA[I recently got a tablet to input handwritten math for slideshow presentations, but instead of using a note-taking program (Jarnal, Xournal, Gournal) I decided that I wanted the full power of image manipulation of a program like Gimp or Inkscape. Neither of these, though, has the level of support for multi-page documents that you find [...]]]></description>
			<content:encoded><![CDATA[<p>I recently got a tablet to input handwritten math for slideshow presentations, but instead of using a note-taking program (<a href="http://www.dklevine.com/general/software/tc1000/jarnal.htm">Jarnal</a>,
<a href="http://xournal.sourceforge.net/">Xournal</a>,
<a href="http://www.adebenham.com/gournal/">Gournal</a>) I decided that I wanted the full power of image manipulation of a program like <a href="http://www.gimp.org/">Gimp</a> or <a href="http://www.inkscape.org/">Inkscape</a>.  Neither of these, though, has the level of support for multi-page documents that you find in note-taking software.  But Inkscape uses SVG as its native file format, so I wrote this Haskell script to transform the layers of an Inkscape SVG file into the slides of a PDF presentation.  I use the
<a href="http://www.cs.york.ac.uk/fp/HaXml/">HaXml</a> library to manipulate the SVG, the Inkscape command-line interface to convert each page to PDF, and <a href="http://www.pdfhacks.com/pdftk/">pdftk</a> to glue the whole thing back together.</p>

<p><a href='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/Slide001.svg' title='slide001.svg'><img width='200' src='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/slide001.png' alt='slide001.png' /></a>
<a href='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/Slide002.svg' title='slide002.png'><img width='200' src='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/slide002.png' alt='slide002.png' /></a></p>

<p><a href='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/Slide003.svg' title='slide003.png'><img width='200' src='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/slide003.png' alt='slide003.png' /></a>
<a href='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/Slide004.svg' title='slide004.png'><img width='200' src='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/slide004.png' alt='slide004.png' /></a></p>

<p>As usual, this post is a literate Haskell file, so you can try it out by saving it to <code>Inkscape.lhs</code>, compiling with <code>ghc --make Inkscape</code>, grabbing the <a href="http://www.kennknowles.com/blog/wp-content/uploads/2008/04/demo.svg">source file for the images above</a>, and running <code>./Inkscape &lt; demo.svg</code>.  The output will appear in <code>Slides.pdf</code> (and your directory will be polluted with temp files, so be aware).
<span id="more-53"></span></p>

<p>For the record, multi-page documents have been on the Inkscape feature
request tracker for many versions, so I presume it is a significant
change.  I <em>do</em> grok C and C++, thanks to the legacy-oriented
education system, but take little enough pleasure from them that I
would rather hack around the issue in Haskell.</p>

<pre>
> import Text.XML.HaXml
> import Text.XML.HaXml.Pretty
> import Text.XML.HaXml.Posn
> import Text.PrettyPrint.HughesPJ
> import Text.Printf
> import Data.List
> import System.IO
> import System.Cmd
</pre>

<p>HaXml is based on a combinator library for <code>CFilter</code>s to filter, search, output, etc XML content.  It is a little crufty in some ways &#8212; many datatypes are transpararent, and you have to do a lot of your own set up and tear down.  The expected way to use it seems to be via <code>processXmlWith :: CFilter -&gt; IO ()</code> which is not sufficient for today&#8217;s task.  The Hackage documentation pointed to an old version of the API, so I used the current version of the source code for documentation.  I&#8217;d love any criticism like &#8220;you didn&#8217;t have to do X&#8221; or &#8220;here is an easier, safer way to do Y&#8221;.</p>

<p>I couldn&#8217;t think of a better way to narrate this code, so I&#8217;ll start with <code>main</code> for a high-level read, and then later fill in all the helper functions. Naturally we start with a call to <code>xmlParse</code>; the <code>"-"</code> is a required filename for error reporting.</p>

<pre>
> main = do input <- getContents
>           let xml = xmlParse "-" input
</pre>

<p>Then I grab the names of all the layer objects in the order they appear in the file, except for the special layer &#8220;Background&#8221; which I&#8217;ll include behind every slide.  The call to <code>verbatim</code> spits them out as <code>String</code>s instead of XML <code>Content</code>, and the <code>"-"</code> is yet another required filename for error reporting.</p>

<pre>
>           let names = delete "Background" 
>                       $ map verbatim 
>                       $ filterElem "-" getLayerNames
>                       $ xmlElem 
>                       $ xml
>           putStrLn $ "Making slides from layers:" 
>                        ++ concatMap ("\n\t"++) names ++ "\n"
</pre>

<p>Then for each layer, make a new version of the file with just that layer visible.</p>

<pre>
>           let outXmls = map (flip selectLayer xml) names
>               usedSlides = take (length names) slideNames
>           mapM_ (uncurry writeFile) 
>                 (zip (map (++".svg") slideNames) 
>                      (map (renderStyle xmlStyle . document) outXmls))
</pre>

<p>And some shell scripting done in Haskell.  I didn&#8217;t even try to find a scripting library or anything to e.g. prevent me from building a malformed command.</p>

<pre>
>           mapM_ (\slide -> do 
>                    system $ "inkscape --export-text-to-path --export-pdf='" 
>                             ++ slide ++ ".pdf' '" ++ slide ++ ".svg'")
>                 usedSlides
>           
>           system $ "pdftk " 
>                      ++ concat (intersperse " " (map (++".pdf") usedSlides)) 
>                      ++ " cat output Slides.pdf"
</pre>

<p>So now to the little details:</p>

<h2>Grabbing the layer names</h2>

<p>Here is the first helper I wrote, wrapping HaXml&#8217;s <code>attrval</code> for a common case.  This filter returns every tag whose <code>attr</code> attribute has the string value <code>val</code>.</p>

<pre>
> matchAttrString :: String -> String -> CFilter i
> matchAttrString attr val = attrval (attr, AttValue [Left val])
</pre>

<p>The next helper is one that maps a tag to its attribute value, otherwise discards anything else it sees.  The HaXml function <code>iffind</code> will pass the <code>attr</code> attribute value of a tag to <code>literal</code> which just returns it.  If the attribute isn&#8217;t found, or the XML data isn&#8217;t a tag, then <code>none</code> will discard it.</p>

<pre>
> showAttr :: String -> CFilter i
> showAttr attr = iffind attr literal none
</pre>

<p>The Inkscape layers are contained in <code>&lt;g inkscape:groupmode='layer' ...&gt;</code> tags.  The name of the layer is in the <code>inkscape:label</code> attribute.  I imagine this will change as Inkscape evolves.  The <code>o</code> is the composition operator for <code>CFilter</code>s.</p>

<pre>
> isLayer = matchAttrString "inkscape:groupmode" "layer"
> getLayerNames = showAttr "inkscape:label" `o` isLayer `o` children
</pre>

<h2>Isolating the layers</h2>

<p>Again proceeding from the outside of my program inwards, a layer is isolated with this helper, using <code>iffind</code> to match either the layer name or the layer &#8220;Background&#8221; which I&#8217;m going to leave in all the output files.  The final <code>keep</code> argument to <code>iffind</code> says to keep
parts of the XML that don&#8217;t have the <code>"inkscape:label"</code> attribute.</p>

<pre>
> selectLayer :: String -> Document Posn -> Document Posn
> selectLayer layer doc = onContent "-" (chip (visible `o` onlyLayer)) doc
>     where onlyLayer = iffind "inkscape:label" layerOrBG keep
>           layerOrBG l = if l == layer || l == "Background" then keep else none
</pre>

<p>In writing <code>visible</code> I was surprised that there was a combinator to set <em>all</em> attributes for a tag, but none to set a single attribute.</p>

<pre>
> visible = setAttr "style" "display:inline"
> setAttr key val (CElem (Elem tag attrs cs) i) = [CElem (Elem tag newattrs cs) i]
>     where newattrs = (key, AttValue [Left val]) : filter ((/= key) . fst) attrs
> setAttr key val other = [other] -- Hackish?
</pre>

<p>As I mentioned before, there is no way that I see to directly apply this filter to an XML file using HaXml.  The type <code>CFilter = Content -&gt; [Content]</code> needs wrapping to apply to an XML <code>Element</code> directly. Notice how I have to pass in a <code>file</code> for error reporting; it feels like I&#8217;m doing things I&#8217;m not supposed to.</p>

<pre>
> filterElem :: FilePath -> CFilter Posn -> Element Posn -> [Content Posn]
> filterElem file f e = f (CElem e (posInNewCxt file Nothing))

> xmlElem (Document _ _ e _) = e
</pre>

<p>And now the function to actually apply a filter to an XML document.  This is straight from the body of <code>processXmlWith</code> in the HaXml source, with <code>filterElem</code> pulled out.</p>

<pre>
> onContent :: FilePath -> (CFilter Posn) -> Document Posn -> Document Posn
> onContent file filter (Document p s e m) =
>     case filterElem file filter e of
>              [CElem e' _] -> Document p s e' m
>              []           -> error "produced no output"
>              _            -> error "produced more than one output"
</pre>

<h2>Bits and pieces</h2>

<p>I also used a modified style for the HughesPJ pretty printer</p>

<pre>
> xmlStyle = style { mode = LeftMode }
</pre>

<p>And a big list of slide names with three digits, for this one-off job.  Better would be to use an API for generating fresh temporary files.</p>

<pre>
> slideNumbers = map (printf "%03d") ([1..999] :: [Int])
> slideNames = map ("Slide"++) slideNumbers
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2008/04/20/using-haxml-to-make-a-pdf-slideshow-from-an-inkscape-svg/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Drawing fractals in Haskell with a cursor graphics DSEL and a cute list representation</title>
		<link>http://www.kennknowles.com/blog/2008/04/16/drawing-fractals-in-haskell-with-a-cursor-graphics-dsel-and-a-cute-list-representation/</link>
		<comments>http://www.kennknowles.com/blog/2008/04/16/drawing-fractals-in-haskell-with-a-cursor-graphics-dsel-and-a-cute-list-representation/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 18:02:52 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[cantor set]]></category>
		<category><![CDATA[fractal]]></category>
		<category><![CDATA[heighway dragon]]></category>
		<category><![CDATA[iterated function system]]></category>
		<category><![CDATA[koch curve]]></category>
		<category><![CDATA[koch snowflake]]></category>
		<category><![CDATA[list representation]]></category>
		<category><![CDATA[monoid homomorphism]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2008/04/16/drawing-fractals-in-haskell-with-a-cursor-graphics-dsel-and-a-cute-list-representation/</guid>
		<description><![CDATA[I&#8217;m reading the very fun Measure, Topology, and Fractal Geometry by GA Edgar, and thought I&#8217;d hack up some of the examples in Haskell. So this post implements cursor graphics in OpenGL in (I think) DSEL style, demonstrating the StateT and Writer monad gadgets from the standard library and a cool &#8220;novel representation of lists&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m reading the very fun <em>Measure, Topology, and Fractal Geometry</em> by GA Edgar, and thought I&#8217;d hack up some of the examples in Haskell.  So this post implements cursor graphics in OpenGL in (I think) DSEL style, demonstrating the <code>StateT</code> and <code>Writer</code> monad gadgets from the
standard library and a cool &#8220;novel representation of lists&#8221; due to R Hughes. On the fractal side, the examples will hopefully convince you that fractals are not just cute pictures, but extremely important illustrations that the real numbers are weird.</p>

<p><img width='400' src='http://kennknowles.com/blog/wp-content/uploads/2008/04/heighway3small.png' /></p>

<p>As usual, you can save this post to <code>Fractals.lhs</code> and compile it with <code>ghc --make Fractals</code><span id="more-42"></span></p>

<p>It seems that a couple of people have gone before me making actually useful fractal packages (the packages are more specifically for &#8220;Iterated Function Systems&#8221; and &#8220;L-systems&#8221;, respectively) or prettier pictures in their blog posts.</p>

<ul>
<li><a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/IFS-0.1.1">IFS</a> (and <a href="http://www.alpheccar.org/en/posts/show/69">related blog entry</a>)</li>
<li><a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/nymphaea-0.2">Nymphaea</a></li>
<li><a href="http://scsibug.com/2007/04/21/mandelbrot-hs/">Fractal-hs</a></li>
</ul>

<p>But I didn&#8217;t let that stop me from doing a little hacking.  This article is hopefully more entertaining to read than a library API. So let&#8217;s get started!</p>

<pre>
> import Data.IORef
> import Data.List
> import Graphics.Rendering.OpenGL as GL
> import Graphics.UI.Gtk as Gtk
> import Graphics.UI.Gtk.OpenGL
> import Control.Monad.Writer
> import Control.Monad.State as S
</pre>

<p>The state of the cursor is a <code>pos</code>ition, <code>dir</code>ection, and whether the <code>ink</code> is activated (so I can move it about without drawing lines everywhere).  The neutral state is at the origin, pointed due east, with the ink on.</p>

<pre>
> type Point2 = Vertex2 GLfloat
>
> data CursorState = TS { pos :: Point2
>                       , dir :: Float
>                       , ink :: Bool }
>
> neutral = TS { pos = Vertex2 0 0
>              , dir = 0
>              , ink = True }
</pre>

<p>Now rather than define the syntax of cursor commands and make functions for creating and consuming it, I want to embed the commands into Haskell.  This is quite easy, of course.</p>

<pre>
> type Instruction = CursorState -> CursorState
>
> leftI    angle s = s { dir = dir s + angle }
> rightI   angle s = s { dir = dir s - angle }
> penI     b     s = s { ink = b }
> forwardI dist  s = s { pos = move (pos s) dist (dir s) }
>     where move (Vertex2 x y) dist dir = Vertex2 (x + dist * cos dir) 
>                                                 (y + dist * sin dir)
</pre>

<p>A first approach to the semantics is that sequence of commands should have the state threaded through it.  The type of a program would be <code>State CursorState ()</code> (the unit is because there is no return value).  I would then get the final state of <code>prog</code> starting from the neutral state with <code>execState program neutral</code>.</p>

<p>But I don&#8217;t actually care about the final state; I want to evaluate this program only for its side effects: Whenever I run a <code>forward</code> command, it should leave a line segment if <code>ink</code> was enabled.  This situation is just what the <code>Writer</code> monad is for.  When I move from
<code>s1</code> to <code>s2</code>, I call <code>tell [(s1,s2)]</code> in order to &#8220;log&#8221; this line segment.</p>

<p>I actually need to carry the state <em>and</em> the log around, so how do I combine these monads?  Well, there&#8217;s a huge trail of literature to follow on that!  If you are interested, <a href="http://www.cs.le.ac.uk/~nghani/papers/icfp02.ps.gz">Composing Monads Using Coproducts</a> by C Lüth, N Ghani has a canonical way, and lots of references.  But for today, the officially sanctioned approach is to use a monad transformer; in many practical cases this coincides with the
coproduct.</p>

<p>So a first attempt at the type of a cursor program would be:</p>

<p><code>type CursorProgram = StateT CursorState (Writer [(Point2,Point2)]) ()</code></p>

<p>What is all this?  Well, <code>CursorState</code> is the state I want to pass around, and <code>Writer [(Point2, Point2)]</code> is the <em>internal</em> monad.  The type is large, but it says a lot!  The only thing I have to watch for is to use <code>lift . tell</code> instead of <code>tell</code> because I need to apply it to the inner <code>Writer</code>.</p>

<p>But you <a href="http://www.haskell.org/all_about_monads/html/writermonad.html">shouldn&#8217;t use list append for a log in real life</a>.  In the above hypothetical definition, the log is accumulated via the <code>(++)</code> monoid, so every time computations are combined with <code>&gt;&gt;=</code> the writer monad will invoke a potentially-costly list append operation.  The log will always grow
from its tail, so I could build the list backwards and it would be efficient, but there is a cooler trick (Kefer points out in the comments that the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/dlist">dlist package</a> provides a usable library for this representation, also called &#8220;difference lists&#8221;), from this paper:</p>

<ul>
<li>A novel representation of lists and its application to the function
&#8220;reverse&#8221;.  RJM Hughes.  Information Processing Letters.  1986</li>
</ul>

<p>In a nutshell: lists and partial applications of <code>(++)</code> are in bijection, so I can swap them.  Here&#8217;s the definition, the bijection, and the monoid instance.  &#8220;List&#8221; concatenation is now function composition, and the empty list is the identity function.  What a pretty monoid morphism!</p>

<pre>
> newtype List a = L ([a] -> [a])
> instance Monoid (List a) where
>     mappend (L x) (L y) = L (x . y)
>     mempty = L id

> inject :: [a] -> List a
> inject l = L (l++)

> recover :: List a -> [a]
> recover (L list) = list []

> singleton :: a -> List a
> singleton x = L (x:)
</pre>

<p>Notice how if I append a bunch of singletons, it is the same number of applications of <code>:</code> as if I had built the list backwards.  Then when I <code>recover</code> the list it costs O(n), the same as efficient reversal, so the two are equally good strategies in this case.  It would be best to make a <code>newtype</code> for backwards lists with its own monoid instance anyhow, so the programming overhead is also the same.</p>

<p>Now I just wrap all the instructions to operate on this more-complicated state, adding logging to <code>forward</code>.</p>

<pre>
> type CursorProgram = StateT CursorState (Writer (List (Point2,Point2))) ()
>
> liftI :: (CursorState -> CursorState) -> CursorProgram
> liftI instr = S.put . instr =<< S.get

> forward, left, right :: Float -> CursorProgram
> left    angle = liftI (leftI angle)
> right   angle = liftI (rightI angle)
> forward dist  = do s <- S.get
>                    liftI (forwardI dist)
>                    s' <- S.get
>                    when (ink s) $ lift $ tell $ singleton (pos s, pos s')

> pen :: Bool -> CursorProgram
> pen b = liftI (penI b)

> run :: CursorProgram -> CursorState -> [(Point2,Point2)]
> run prog state = recover $ execWriter $ execStateT prog state
</pre>

<p>That&#8217;s not so bad, is it?  So now let&#8217;s get on to some drawing.</p>

<p>Possibly the simplest fractal that already can blow your mind is the <a href="http://en.wikipedia.org/wiki/Cantor_set">Cantor Set</a>.</p>

<pre>
> cantor :: Int -> CursorProgram
> cantor depth = cantor' depth 1.0
>   where cantor' 0 size = forward size
>         cantor' n size = do cantor' (n-1) (size/3)
>                             pen False
>                             forward (size/3)
>                             pen True
>                             cantor' (n-1) (size/3)
</pre>

<p>Viewing that won&#8217;t be very interesting; it is just an excuse to talk about it.  But Wikipedia has a nice image:</p>

<p><img width='500' src='http://kennknowles.com/blog/wp-content/uploads/2008/04/cantor_iters.png' /></p>

<p>Take the segment <img src='http://s.wordpress.com/latex.php?latex=%5B0%2C1%5D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='[0,1]' title='[0,1]' class='latex' /> and remove the center third of it, keeping the endpoints intact.  Now remove the center third of each of those segments, and again, and again.  Taking the intersection of all of these sets (i.e. the limit) gives the Cantor Set.</p>

<p>So what does it look like?  Well, it isn&#8217;t empty, since every point that is ever an endpoint sticks around forever.  But those aren&#8217;t the only points: Convince yourself that <img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%201%204&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac 1 4' title='\frac 1 4' class='latex' /> is in the set.  I&#8217;m pretty sure this can be phrased as a <a href="http://www.cs.cornell.edu/~kozen/papers/coinduction.pdf">coinductive proof</a> but for now the next paragraph will give you another approach.</p>

<p>The classic way of understanding the Cantor Set is to use ternary digits.  See if you can convince yourself that the cantor set contains every real number that doesn&#8217;t require a 1 in its ternary expansion (hint: 0.0222222&#8230; = 0.1 so 0.1 doesn&#8217;t <em>require</em> a 1 in its ternary
expansion)</p>

<p>So any number made of a possibly-infinite string of 0s and 2s is in there.  Sound familiar?  Well, if we use &#8220;1&#8243; instead of &#8220;2&#8243; then we are talking about all possibly-infinite binary strings, which a
programmer should intuitively see is all real numbers in <img src='http://s.wordpress.com/latex.php?latex=%5B0%2C1%5D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='[0,1]' title='[0,1]' class='latex' /> (&#8230;Cauchy sequences, mumble, mumble&#8230;).  So the Cantor Set is, in fact, uncountable!</p>

<p>Next, how about the <a href="http://en.wikipedia.org/wiki/Koch_curve">Koch curve</a>?</p>

<pre>
> koch :: Int -> CursorProgram
> koch depth = koch' depth 1.0
>   where koch' 0 size = forward size
>         koch' n size = do koch' (n-1) (size/3)
>                           left (pi/3)
>                           koch' (n-1) (size/3)
>                           right (pi * 2/3)
>                           koch' (n-1) (size/3)
>                           left (pi/3)
>                           koch' (n-1) (size/3)
</pre>

<p><img width='250' src='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/koch1small.png' /> <img width='250' src='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/koch2small.png' />
<img width='400' src='http://www.kennknowles.com/blog/wp-content/uploads/2008/04/koch3small.png' /></p>

<p>This curve (in the limit) is continuous everywhere but differentiable nowhere.</p>

<p>But what is more fun is when you stick three of them end-to-end, for Koch&#8217;s Snowflake.</p>

<pre>
> kochFlake :: Int -> CursorProgram
> kochFlake depth = do -- lining up
>                      pen False
>                      forward 1.0
>                      right (pi/2)
>                      forward (1 / (2*sqrt(3)))
>                      right (pi/2)
>                      pen True
>                      -- draw in a triangle shape
>                      koch depth
>                      right (2*pi/3)
>                      koch depth
>                      right (2*pi/3)
>                      koch depth
</pre>

<p>Here, the area is finite, and yet the boundary is infinite, which is normal for fractal-boundaried regions.</p>

<p><img src='http://kennknowles.com/blog/wp-content/uploads/2008/04/kochflake1small.png' /> <img src='http://kennknowles.com/blog/wp-content/uploads/2008/04/kochflake2small.png' /> <img src='http://kennknowles.com/blog/wp-content/uploads/2008/04/kochflake3small.png' /></p>

<p>Finally, there&#8217;s <a href="http://en.wikipedia.org/wiki/Dragon_curve">Heighwey&#8217;s dragon</a>.</p>

<pre>
> heighway :: Int -> CursorProgram
> heighway depth = heighway' depth 1.0 1.0
>   where heighway' 0 size parity = forward size
>         heighway' n size parity = do left (parity * pi / 4)
>                                      heighway' (n-1) (size / sqrt 2) 1
>                                      right (parity * pi / 2)
>                                      heighway' (n-1) (size / sqrt 2) (-1)
>                                      left (parity * pi / 4)
</pre>

<p><img width='250' src='http://kennknowles.com/blog/wp-content/uploads/2008/04/heighway1small.png' /> <img width='250' src='http://kennknowles.com/blog/wp-content/uploads/2008/04/heighway2small.png' />
<img width='400' src='http://kennknowles.com/blog/wp-content/uploads/2008/04/heighway3small.png' /></p>

<p>This is what you get if you just keep folding a piece of paper in half in the same direction, then unfold it and set every fold to a right angle.  Rather than recite facts from Wikipedia, I&#8217;ll highly recommend the original article, as it is of rare quality.  In fact, all of the articles about these curves were so unexpectedly satisfying that I ended up not feeling the need to write much.</p>

<p><img src='http://kennknowles.com/blog/wp-content/uploads/2008/04/dragon_paper.png' /></p>

<p>What all of the above fractal curves except the Koch Snowflake have in common is self-similarity.  The cantor set is essentially identical to each of its left and right hand sides, i.e.  it is identical to the union of two scaled-down copies of itself, as the cursor-graphics code
makes obvious.  I said I wouldn&#8217;t talk about it, so I&#8217;ll just mention that if you write this as <img src='http://s.wordpress.com/latex.php?latex=C%20%3D%20f%28C%29%20%5Ccup%20g%28C%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C = f(C) \cup g(C)' title='C = f(C) \cup g(C)' class='latex' /> then <img src='http://s.wordpress.com/latex.php?latex=f&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f' title='f' class='latex' /> and <img src='http://s.wordpress.com/latex.php?latex=g&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='g' title='g' class='latex' /> are the functions in &#8220;iterated function systems.  I highly recommend a googling, or better yet, the book which prompted this post.</p>

<p>Below is the actual nitty-gritty OpenGL, Gtk, and IO code that plugs it together.</p>

<pre>
> render :: CursorProgram -> IO ()
> render fractal = do
>   clear [ColorBuffer]
>   loadIdentity
>   color3f (Color3 1 1 1)
>   translate3f $ Vector3 (-0.5) 0 0
>   renderPrimitive Lines $ mapM_ vertex $ combine $ run fractal neutral
>   where color3f = color :: Color3 GLfloat -> IO ()
>         translate3f = translate :: Vector3 GLfloat -> IO ()
>         scale3f = scale :: GLfloat -> GLfloat -> GLfloat -> IO ()
>         combine = concatMap (\(start,end) -> [start,end])

> draw :: GLDrawingArea -> IO () -> IO ()
> draw canvas render = do
>   -- This is all Gtk code, managing the internal structures
>   glContext <- glDrawingAreaGetGLContext canvas
>   glWin <- glDrawingAreaGetGLWindow canvas
>   (w,h) <- glDrawableGetSize glWin
>
>   glDrawableGLBegin glWin glContext
>   -- Scale up and use the whole canvas
>   (pos, _) <- GL.get viewport
>   viewport $= (pos, Size (fromIntegral w) (fromIntegral h))
>   render
>   GL.flush -- except this
>   glDrawableSwapBuffers glWin
>   glDrawableGLEnd glWin

> main = do
>   initGUI
>   glConfig <- glConfigNew [GLModeRGBA, GLModeDouble]
>   initGL
>
>   depthRef <- newIORef 0
>   fractalRef <- newIORef cantor
>
>   canvas  <- glDrawingAreaNew glConfig
>   let redraw = do depth <- readIORef depthRef
>                   fractal <- readIORef fractalRef
>                   draw canvas (render (fractal depth))
>
>   onExpose canvas (\_ -> do { redraw; return True } )
>
>   buttonBox <- vBoxNew False 0
>
>   incrButton <- buttonNew
>   Gtk.set incrButton [ buttonLabel := "More iterations." ]
>   onClicked incrButton (do oldval <- readIORef depthRef
>                            putStrLn $ show (oldval + 1) ++ " iterations!"
>                            writeIORef depthRef (oldval + 1)
>                            redraw)
>
>   decrButton <- buttonNew
>   Gtk.set decrButton [ buttonLabel := "Less iterations." ]
>   onClicked decrButton (do oldval <- readIORef depthRef
>                            putStrLn $ show (max 0 (oldval - 1)) ++ " iterations!"
>                            writeIORef depthRef (max 0 (oldval - 1))
>                            redraw)
>
>   boxPackStart buttonBox incrButton PackNatural 0
>   boxPackStart buttonBox decrButton PackNatural 0
>
>   dummy <- radioButtonNew -- All buttons join this group
>   mapM_ (\(fun,label) -> do button <- radioButtonNewWithLabelFromWidget dummy label
>                             onToggled button (do me <- toggleButtonGetActive button
>                                                  when me $ do writeIORef fractalRef fun
>                                                  redraw)
>                             boxPackStart buttonBox button PackNatural 0)
>             [ (cantor, "Cantor Set")
>             , (koch, "Koch Curve")
>             , (kochFlake, "Koch Flake")
>             , (heighway, "Heighway Dragon") ]
>
>   canvasBox <- hBoxNew False 0
>   boxPackStart canvasBox buttonBox PackNatural 0
>   boxPackStart canvasBox canvas PackGrow 0
>
>   window <- windowNew
>   Gtk.set window [ containerBorderWidth := 10,
>                    containerChild := canvasBox ]
>   onDestroy window mainQuit
>
>   widgetShowAll window
>   mainGUI
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2008/04/16/drawing-fractals-in-haskell-with-a-cursor-graphics-dsel-and-a-cute-list-representation/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Using OpenGL&#8217;s blending to visualize congestion in convex routing (in Haskell)</title>
		<link>http://www.kennknowles.com/blog/2008/03/23/using-opengls-blending-to-visualize-congestion-in-convex-routing-in-haskell/</link>
		<comments>http://www.kennknowles.com/blog/2008/03/23/using-opengls-blending-to-visualize-congestion-in-convex-routing-in-haskell/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 23:44:40 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[blending]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[routing]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2008/03/23/using-opengls-blending-to-visualize-congestion-in-convex-routing-in-haskell/</guid>
		<description><![CDATA[This is a question posed in my randomized algorithms class. If you are routing in a network whose connectivity looks &#8220;more or less&#8221; like a convex figure, what does the congestion look like? A quick way to make an educated guess is to draw a bunch of random line segments in such a convex shape [...]]]></description>
			<content:encoded><![CDATA[<p>This is a question posed in my randomized algorithms class.  If you are routing in a network whose connectivity looks &#8220;more or less&#8221; like a convex figure, what does the congestion look like?  A quick way to make an educated guess is to draw a bunch of random line segments in such a convex shape and see where the colors get the brightest:</p>

<p><img src="http://www.kennknowles.com/blog/wp-content/uploads/2008/03/congestion.png" alt="Congestion" /></p>

<p>This post is literate Haskell that will output that image, so save it to something like <code>Congestion.lhs</code> and run <code>ghc --make Congestion.lhs</code>.  <span id="more-40"></span> I started with the code from <a href="http://www.kennknowles.com/blog/2007/11/20/visualizing-2d-convex-hull-using-gtk-and-opengl-in-haskell/">an old post</a> and cut out the bits I didn&#8217;t need.  The libraries used can be found here:</p>

<ul>
<li><a href="http://www.haskell.org/haskellwiki/Opengl">Haskell OpenGL</a></li>
<li><a href="http://haskell.org/gtk2hs/">Gtk2hs</a></li>
</ul>

<p>First, there is the usual administrivia.</p>

<pre>
> import Data.IORef
> import Data.List
> import Graphics.Rendering.OpenGL as GL hiding (map2)
> import Graphics.UI.Gtk as Gtk hiding (drawSegments, Color)
> import Graphics.UI.Gtk.OpenGL
> import System.Random
</pre>

<p>Any proper Haskell programmer will of course want to create an infinite list of random segments,</p>

<pre>
> type Point3 = Vertex3 GLfloat
>
> randomPoints :: IO [Point3]
> randomPoints = do
>   xgen <- newStdGen
>   ygen <- newStdGen
>   let xs = randomRs (-0.9,0.9) xgen
>   let ys = randomRs (-0.9,0.9) ygen
>   return $ map2 (\x y -> Vertex3 x y 0) xs ys
>     where  map2 f first second = map (uncurry f) (zip first second)
</pre>

<p>Then <code>renderSegments</code> is straightforward.  I draw them very faint gray so that only in locations of congestion do we see brighter white.</p>

<pre>
> renderSegments :: [(Point3,Point3)] -> IO ()
> renderSegments segments = do
>   clear [ColorBuffer]
>   color3f (Color3 0.05 0.05 0.05)
>   mapM_ renderSegment segments
>     where
>     color3f = color :: Color3 GLfloat -> IO ()
>     renderSegment (start, end) = renderPrimitive LineStrip $ do vertex start
>                                                                 vertex end
</pre>

<p>There are a bunch of Gtk and OpenGL calls to add, yielding <code>drawSegments</code> below.  The only thing to note is the setting of <code>blendFunc</code> and <code>blendAdd</code> which tell OpenGL to add the color that is already on a pixel to the color
I&#8217;m trying to draw.  It is really a cheap trick to get OpenGL to intersect my line segments and add up the totals for me.  One gotcha that held me up is that these settings have to be within the <code>glDrawableGLBegin</code> and
<code>glDrawableGLEnd</code> calls.</p>

<pre>
> drawSegments :: GLDrawingArea -> [(Point3,Point3)] -> IO Bool
> drawSegments canvas segments = do
>
>   -- This is all Gtk code, managing the internal structures
>   glContext <- glDrawingAreaGetGLContext canvas
>   glWin <- glDrawingAreaGetGLWindow canvas
>   (w,h) <- glDrawableGetSize glWin
>
>   -- These are OpenGL calls to scale up and use the whole canvas
>   (pos, _) <- GL.get viewport
>   viewport $= (pos, Size (fromIntegral w) (fromIntegral h))
>
>   -- This is again Gtk code
>   glDrawableGLBegin glWin glContext
>   blend $= Enabled
>   blendFunc $= (One, One)
>   blendEquation $= FuncAdd
>   renderSegments segments
>   GL.flush -- except this
>   glDrawableSwapBuffers glWin
>   glDrawableGLEnd glWin
>   return True
</pre>

<p>And finally we just plug it all together with even more initialization code.</p>

<pre>
> main = do
>   initGUI
>   glConfig <- glConfigNew [GLModeRGBA, GLModeDouble]
>   initGL
>   startPoints <- randomPoints
>   endPoints <- randomPoints
>   let segments = take 10000 $ zip startPoints endPoints
>
>   canvas  <- glDrawingAreaNew glConfig
>   onExpose canvas (\_ -> drawSegments canvas segments)
>
>   window <- windowNew
>   Gtk.set window [ containerBorderWidth := 10,
>                    containerChild := canvas ]
>   onDestroy window mainQuit
>
>   widgetShowAll window
>   mainGUI
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2008/03/23/using-opengls-blending-to-visualize-congestion-in-convex-routing-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Infinite lazy Knuth-Bendix completion for monoids in Haskell</title>
		<link>http://www.kennknowles.com/blog/2007/12/20/infinite-lazy-knuth-bendix-completion-for-monoids-in-haskell/</link>
		<comments>http://www.kennknowles.com/blog/2007/12/20/infinite-lazy-knuth-bendix-completion-for-monoids-in-haskell/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 21:20:14 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[group]]></category>
		<category><![CDATA[Knuth-Bendix]]></category>
		<category><![CDATA[lazy lists]]></category>
		<category><![CDATA[monoid]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[rewriting]]></category>
		<category><![CDATA[Universal algebra]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2007/12/20/infinite-lazy-knuth-bendix-completion-for-monoids-in-haskell/</guid>
		<description><![CDATA[The Knuth-Bendix completion procedure (when it succeeds) transforms a collection of equations into a confluent, terminating rewrite system. Sometimes the procedure fails, and sometimes does not terminate, but The Handbook of Computational Group Theory by D Holt remarked that even in this case it generates an infinite set of rewrite rules that are complete, and [...]]]></description>
			<content:encoded><![CDATA[<p>The Knuth-Bendix completion procedure (when it succeeds) transforms a
collection of equations into a confluent, terminating rewrite
system.  Sometimes the procedure fails, and sometimes does not
terminate, but <em>The Handbook of Computational Group Theory</em> by D Holt
remarked that even in this case it generates an <em>infinite</em> set of
rewrite rules that are complete, and <em>An Introduction to Knuth-Bendix
Completion</em> by AJJ Dick also mentions that in the nonterminating case
one can derive a semi-decision procedure for equality checking.  I naturally had to hack
this up in Haskell, to create an infinite set of rewrite rules as a
lazy list.  This illustrates the very real software engineering
benefit of decoupling creation and consumption of infinite data.  As
usual, this post is a valid literate Haskell file, so save it so
something like <code>KnuthBendix.lhs</code> and compile with <code>ghc --make
KnuthBendix</code> or load it up with <code>ghci KnuthBendix.lhs</code>
<span id="more-37"></span></p>

<pre>
> module Main where
> import Control.Monad
> import Data.List
> import Test.QuickCheck hiding (trivial)
</pre>

<p>To give a little background, something I realize I&#8217;ve neglected in the
past, <a href="http://en.wikipedia.org/wiki/Knuth-Bendix_completion_algorithm">Knuth-Bendix completion</a> is a technique in 
<a href="http://en.wikipedia.org/wiki/Universal_algebra">universal algebra</a>, 
which is
essentially the study of unityped syntax trees for
operator/variable/constant expression languages, like these:</p>

<pre>
> data Term op a = Operator op [Term op a]
>                | Variable String
>                | Constant a
</pre>

<p>Your usual algebraic structures are for the most part special cases in
universal algebra &#8211; anything that has an ambient set with some bunch
of operators and equational axioms qualifies, and universal algebra
supplies the variables to represent unspecified quantities.</p>

<p>For example, a monoid <img src='http://s.wordpress.com/latex.php?latex=f%28x%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x)' title='f(x)' class='latex' /> is a set <img src='http://s.wordpress.com/latex.php?latex=S&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='S' title='S' class='latex' /> with an operator <img src='http://s.wordpress.com/latex.php?latex=%2A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='*' title='*' class='latex' /> and a special constant
<img src='http://s.wordpress.com/latex.php?latex=e&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='e' title='e' class='latex' /> obeying these axioms, where <img src='http://s.wordpress.com/latex.php?latex=x%2C%20y%2C%20z&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x, y, z' title='x, y, z' class='latex' /> are variables
that can be replaced by any term.</p>

<img src='http://s.wordpress.com/latex.php?latex=e%20%2A%20x%20%20%3D%20%20x%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='e * x  =  x ' title='e * x  =  x ' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=x%20%2A%20e%20%3D%20x%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x * e = x ' title='x * e = x ' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=%28x%20%2A%20y%29%20%2A%20z%20%3D%20x%20%2A%20%28y%20%2A%20z%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='(x * y) * z = x * (y * z)' title='(x * y) * z = x * (y * z)' class='latex' />

<p>Aside: Consider the obvious way to axiomatize a group in this
framework.  I think it is a nice example of the interaction of
constructive logic and computation.</p>

<p>But anyhow today I&#8217;m not going to use this structure because I can
explain and explore Knuth-Bendix more quickly by sticking
to monoids.  The full completion procedure, and its modern
enhancements, works on terms with variables and uses unification
where I use equality, and superposition where I use string matching.
In the case of a monoid, the associative law lets me simplify
the term structure from a tree to just a list, and since I&#8217;m
not including variables, I deal just with words over my alphabet
<code>a</code>:</p>

<pre>
> type Word a = [a]
</pre>

<p>A <em>presentation</em> is just a formalism as above, specifying
the ambient set <img src='http://s.wordpress.com/latex.php?latex=X&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='X' title='X' class='latex' /> (here, the type parameter <code>a</code>),
and some equalities <img src='http://s.wordpress.com/latex.php?latex=R&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='R' title='R' class='latex' /> called <em>relations</em>, written in 
mathematical notation as</p>

<img src='http://s.wordpress.com/latex.php?latex=%5Clangle%20X%20%7E%7C%7E%20R%20%5Crangle&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\langle X ~|~ R \rangle' title='\langle X ~|~ R \rangle' class='latex' />

<p>and in Haskell</p>

<pre>
> type Relation a = (Word a, Word a) 
> type Presentation a = [Relation a]
</pre>

<p>For an easy example of a monoid and its presentation, <code>Bool</code> forms a
monoid using the <code>&amp;&amp;</code> operator which has identity <code>True</code>.  Here is a
presentation for the monoid in each notation (in general,
presentations are not unique, and there&#8217;s a whole theory of messing
about with them, which is exactly what we are about to do!)</p>

<img src='http://s.wordpress.com/latex.php?latex=%5Clangle%20T%2C%20F%20%7E%7C%7E%20T%20%5Cwedge%20F%20%3D%20F%20%5Cwedge%20T%20%3D%20F%20%5Cwedge%20F%20%3D%20F%2C%20T%20%5Cwedge%20T%20%3D%20T%20%5Crangle&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\langle T, F ~|~ T \wedge F = F \wedge T = F \wedge F = F, T \wedge T = T \rangle' title='\langle T, F ~|~ T \wedge F = F \wedge T = F \wedge F = F, T \wedge T = T \rangle' class='latex' />

<pre>
> boolAnd = [ ([True,True], [True])
>           , ([True, False], [False])
>           , ([False, True], [False])
>           , ([False, False], [False]) ]
</pre>

<p>In this case, the equations are just the definition for &amp;&amp;.  Another
monoid you&#8217;ve certainly seen as a programmer is the free monoid
over X, which looks like this:</p>

<img src='http://s.wordpress.com/latex.php?latex=%5Clangle%20X%20%7E%7C%7E%20%5Crangle&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\langle X ~|~ \rangle' title='\langle X ~|~ \rangle' class='latex' />

<pre>
> freeMonoid = []
</pre>

<p>In other words, it is just lists of elements of X since there are no
rules for manipulating the words.  The List monad is intimately
related to this monoid.</p>

<p>Another good example is the following &#8211; see if you can figure out what it 
represents before going on.</p>

<img src='http://s.wordpress.com/latex.php?latex=%5Clangle%20x%20%7E%7C%7E%20x%5En%20%3D%20e%20%5Crangle&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\langle x ~|~ x^n = e \rangle' title='\langle x ~|~ x^n = e \rangle' class='latex' />

<p>Yes, it is a presentation for the monoid (in fact, group) <img src='http://s.wordpress.com/latex.php?latex=%5Cmathbb%7BZ%7D_n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\mathbb{Z}_n' title='\mathbb{Z}_n' class='latex' />, the integers
mod <img src='http://s.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' />.  You are intended to interpret the group operation as
addition modulo <img src='http://s.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' />, <img src='http://s.wordpress.com/latex.php?latex=x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x' title='x' class='latex' /> as 1, and <img src='http://s.wordpress.com/latex.php?latex=e&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='e' title='e' class='latex' /> as the identity 0, hence <img src='http://s.wordpress.com/latex.php?latex=x%5Ek&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x^k' title='x^k' class='latex' />
is really <img src='http://s.wordpress.com/latex.php?latex=k&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='k' title='k' class='latex' /> mod <img src='http://s.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' />.  Of course, the abstractness of the presentation meshes
well with this group&#8217;s other name, the &#8220;cyclic group of order <img src='http://s.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' />&#8220;.</p>

<hr />

<p>So, formalism is great fun and all, but sane folk prefer for computers
to deal with it if possible. Our goal is to decide whether two words
are equal according to the identities in the presentation.  In
general, this is undecidable, see</p>

<ul>
<li><a href="http://en.wikipedia.org/wiki/Word_problem_for_groups">http://en.wikipedia.org/wiki/Word_problem_for_groups</a></li>
</ul>

<p>Here are some more example presentations for groups in Haskell, so I
can use them.  They are mostly harvested from
<a href="http://en.wikipedia.org/wiki/Group_presentation">http://en.wikipedia.org/wiki/Group_presentation</a> and
<a href="http://en.wikipedia.org/wiki/Knuth-Bendix_completion_algorithm">http://en.wikipedia.org/wiki/Knuth-Bendix_completion_algorithm</a></p>

<p>The cyclic group of order n, as above:</p>

<pre>
> cyclic n = [ (take n (repeat 'x'),"") ]
</pre>

<p>The dihedral group of order 2n:</p>

<pre>
> dihedral n = [ (take n (repeat 'r'),"")
>              , ("ff", "")
>              , ("rfrf", "") ]
</pre>

<p>The basic thing we are going to do is interpret equalities as
rewriting rules.  Everywhere the left-hand side appears, we insert the
right-hand side.  This function rewrites just once, if it finds an
opportunity.  I&#8217;m not going to even try for efficiency, since I get
such a kick out of writing these pithy little Haskell functions.</p>

<pre>
> rewrite :: Eq a => Relation a -> Word a -> Word a
> rewrite _ [] = []
> rewrite rel@(lhs,rhs) word@(x:rest) = maybe (x:rewrite rel rest) ((rhs ++) . snd)
>                                             maybeRewritten
>   where maybeRewritten = find ((lhs ==) . fst) (zip (inits word) (tails word))
</pre>

<p>A natural way to check if two words are equal is to
reduce them until they can reduce no further, and see if
these <em>normal forms</em> are equal.</p>

<pre>
> reduce :: Eq a => Presentation a -> Word a -> Word a
> reduce pres word = if word' == word then word else reduce pres word'
>   where word' = foldr rewrite word pres
</pre>

<p>This function fully reduces a word, assuming the presentation has
&#8220;good&#8221; properties like always making words smaller according to a
well-founded ordering.  To make sure of this, we can orient any
relation according to such an ordering.</p>

<pre>
> shortlex :: Ord a => Word a -> Word a -> Ordering
> shortlex l1 l2 = if length l1 < length l2 then LT
>                  else if length l1 > length l2 then GT
>                       else lexical l1 l2
>     where lexical [] [] = EQ
>           lexical (x:xs) (y:ys) = case compare x y of
>                                     EQ -> lexical xs ys
>                                     other -> other
>
> orient :: Ord a => Relation a -> Relation a
> orient (lhs,rhs) = case shortlex lhs rhs of
>                      LT -> (rhs, lhs)
>                      _  -> (lhs, rhs)
</pre>

<p>But the results may be provably equal even though their
normal forms are not, for example if I have this monoid</p>

<img src='http://s.wordpress.com/latex.php?latex=%5Clangle%20x%2Cy%2Cz%20%7E%7C%7E%20xy%20%3D%20yx%20%3D%20z%5Crangle&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\langle x,y,z ~|~ xy = yx = z\rangle' title='\langle x,y,z ~|~ xy = yx = z\rangle' class='latex' />

<pre>
> xyzExample = [ ("yx", "z")
>              , ("xy", "z") ]
</pre>

<p>I know that <code>"xz" == "zx"</code> but I cannot obviously prove it</p>

<pre>
 *Main> reduce xyzExample "xz"
 "xz"
 *Main> reduce xyzExample "zx"
 "zx"
</pre>

<p>because the proof goes through <code>"xz" == "xyx" == "zx"</code>.
Knuth calls these &#8220;critical pairs&#8221; and they, in
some sense, represent the point in a proof where someone
had to be more clever than just cranking on the rules.
But just to preview how completion works,</p>

<pre>
 *Main> reduce (complete xyzExample) "xz"
 "xz"
 *Main> reduce (complete xyzExample) "zx"
 "xz"
</pre>

<p>Voila!</p>

<p>We&#8217;ll also want to reduce relations and presentations.  For relations,
this is just reducing both sides, and orienting for good measure.</p>

<pre>
> reduceRel :: Ord a => Presentation a -> Relation a -> Relation a
> reduceRel pres (lhs,rhs) = orient (reduce pres lhs, reduce pres rhs)
</pre>

<p>To reduce a presentation, we reduce each relation with all the other
relations.  If the two sides reduce to the same word, then the
relation was redundant and we can delete it.</p>

<pre>
> trivial :: Eq a => Relation a -> Bool
> trivial (x,y) = x == y  -- Otherwise known as `uncurry (==)`
>
> redundant :: Ord a => Presentation a -> Relation a -> Bool
> redundant pres = trivial . reduceRel pres
>
> reducePres :: Ord a => Presentation a -> Presentation a
> reducePres pres = filter (not . trivial) (reduceP [] pres) 
>     where reduceP prior [] = prior
>           reduceP prior (r:future) = let r' = reduceRel (prior++future) r 
>                                      in reduceP (r':prior) future
</pre>

<p>Now on to the Knuth-Bendix procedure.  The primary idea is to find all
the possible critical pairs as described above, and to make new
rewrite rules so they aren&#8217;t critical anymore.  In other terminology,
we look for exceptions to local confluence, and patch them up.</p>

<p>First, <code>partitions</code> is a list of ways to split a word into two
nonempty parts.</p>

<pre>
> partitions :: Word a -> [(Word a, Word a)]
> partitions x = reverse . tail . reverse . tail $ zip (inits x) (tails x)
</pre>

<p>Results looks like this:</p>

<pre>
 *Main> partitions "abcde"
 [("a","bcde"),("ab","cde"),("abc","de"),("abcd","e")]
</pre>

<p>Next, <code>superpositions</code> takes two words, and returns all the ways that
the back of the first word could be the front of the second word.</p>

<pre>
> superpositions :: Eq a => Word a -> Word a -> [(Word a, Word a, Word a)]
> superpositions x y = map merge $ filter critical $ allPairs
>     where critical ((a,b),(c,d)) = (b == c)
>           merge ((a,b),(c,d)) = (a,b,d)
>           allPairs = [(p1, p2) | p1 <- partitions x, p2 <- partitions y]

 *Main> superpositions "abb" "bbc"
 [("a","bb","c"),("ab","b","bc")]
</pre>

<p>Then <code>criticalPairs</code> takes all the superpositions <code>(x,y,z)</code>
where <code>xy</code> is reducible by one relation, and <code>yz</code> is reducible by the
second, and returns the result of the aforementioned reductions.  The
last function, <code>allCriticalPairs</code> just filters these for inequivalent
pairs.</p>

<pre>
> criticalPairs :: Eq a => Relation a -> Relation a -> [(Word a, Word a)]
> criticalPairs (l1,r1) (l2,r2) = map reduceSides (superpositions l1 l2)
>     where reduceSides (x,y,z) = (r1 ++ z, x ++ r2)
>
> allCriticalPairs :: Ord a => Presentation a -> [(Word a, Word a)]
> allCriticalPairs pres = filter (not . redundant pres) 
>                         $ concatMap (uncurry criticalPairs) rels
>     where rels = [(r1,r2) | r1 <- pres, r2 <- pres]
</pre>

<p>Just to save some redundant modification, we&#8217;ll assume the input
presentation is reduced and oriented, and maintain that invariant
ourselves.  Then completion is pretty simple &#8211; just add the first non-reducible
critical pair until there are no more.</p>

<pre>
> complete :: Ord a => Presentation a -> Presentation a
> complete pres = augment critPairs
>     where augment []    = pres
>           augment (x:_) = complete $ reducePres (x : pres)
>           critPairs = map orient (allCriticalPairs pres)
</pre>

<p>But this version of completion simplifies the presentation at every
step, as per the descriptions of the algorithm I&#8217;ve seen &#8211; I obviously
can&#8217;t do that if the result is infinite.  The best I can think of is
to track the finite number of relations I&#8217;ve already processed, and
reduce each relation as I consider it according to those.  And since I
bet the order that generated rewrite rules are visited matters, I use
the <code>interleave</code> function to make sure that all rewrite rules are
eventually hit.</p>

<pre>
> quasicomplete :: Ord a => Presentation a -> Presentation a
> quasicomplete pres = augment [] pres
>     where augment prior []     = []
>           augment prior (x:xs) | redundant prior x = augment prior xs
>                                | otherwise  = x':augment prior' rest
>               where x' = reduceRel prior x
>                     prior' = reducePres (x:prior)
>                     rest = map (reduceRel prior') (interleave critPairs xs)
>                     critPairs = allCriticalPairs prior'

> interleave :: [a] -> [a] -> [a]
> interleave [] ys = ys
> interleave xs [] = xs
> interleave (x:xs) ys = x:(interleave ys xs)
</pre>

<p>And I need to directly test equality rather than reducing a relation
and checking for triviality, since I don&#8217;t know when reduction is
done.</p>

<pre>
> equiv :: Ord a => Presentation a -> Word a -> Word a -> Bool
> equiv pres w1 w2 = or (map equivPrefix (inits pres))
>     where equivPrefix prefix = reduce prefix w1 == reduce prefix w2
</pre>

<p>The above function does not give the <em>same</em> completions as the finite
version, but it does seem to work.  Here is a quickcheck property to
test it.  Since interesting presentations are probably hard to
autogenerate, I just specialize it to the <code>xyzExample</code>.</p>

<pre>
> prop_quasiXYZ :: [XYZ] -> [XYZ] -> Bool
> prop_quasiXYZ xyz1 xyz2 = 
>     trivial (reduceRel (complete xyzExample) (w1,w2)) == 
>     trivial (reduceRel (quasicomplete xyzExample) (w1,w2))
>         where w1 = map unXYZ xyz1
>               w2 = map unXYZ xyz2
>
> newtype XYZ = XYZ { unXYZ :: Char } 
> instance Arbitrary XYZ where
>     arbitrary = liftM XYZ $ oneof [return 'x', return 'y', return 'z']
> instance Show XYZ where
>     show = show . unXYZ
</pre>

<p>All seems well!  Now here&#8217;s the example wikipedia uses for Knuth-Bendix:</p>

<pre>
> wikipediaExample = [ ("xxx", "")
>                    , ("yyy", "")
>                    , ("xyxyxy", "") ]
</pre>

<p>Indeed, the finite completion algorithm agrees with what Wikipedia says,
and the following property passes lots of tests:</p>

<pre>
> prop_quasiWiki :: [XY] -> [XY] -> Bool
> prop_quasiWiki xy1 xy2 = 
>     trivial (reduceRel (complete wikipediaExample) (w1,w2)) == 
>     trivial (reduceRel (quasicomplete wikipediaExample) (w1,w2))
>         where w1 = map unXY xy1
>               w2 = map unXY xy2
>
> newtype XY = XY { unXY :: Char } 
> instance Arbitrary XY where
>     arbitrary = liftM XY $ oneof [return 'x', return 'y']
> instance Show XY where
>     show = show . unXY
</pre>

<p>And the major test: Infinitude!  I accidentally found out that my procedures
don&#8217;t terminate for the <code>dihedral n</code> for <code>n &gt;= 3</code>, so
let&#8217;s make some tests of hand-checked equalities.</p>

<pre>
> d3 = quasicomplete (dihedral 3)

> prop_d3 :: Bool
> prop_d3 = all (uncurry $ equiv d3) [ ("rrf", "fr")
>                                    , ("frf", "rr")
>                                    , ("frr", "rf")
>                                    , ("f", "rfr")
>                                    , ("rfrff", "rrfrr") ]
</pre>

<p>It seems to work.  If I were really fancy I&#8217;d take random walks on the rewrite rules
and then see if completion could retrace those steps.  But I&#8217;m
not that fancy today!</p>

<p>Here&#8217;s my little pseudo-quickcheck main</p>

<pre>
> main = do mycheck ("prop_quasiXYZ", prop_quasiXYZ)
>           mycheck ("prop_quasiWiki", prop_quasiWiki)
>           mycheck ("prop_d3", prop_d3)
>   where mycheck (name,prop) = do 
>           putStr (name ++ ": ")
>           quickCheck prop
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2007/12/20/infinite-lazy-knuth-bendix-completion-for-monoids-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating the reflect-rotate-translate normal form for an isometry of the plane in Haskell, and verifying it with QuickCheck.</title>
		<link>http://www.kennknowles.com/blog/2007/12/03/calculating-the-reflect-rotate-translate-normal-form-for-an-isometry-of-the-plane-in-haskell-and-verifying-it-with-quickcheck/</link>
		<comments>http://www.kennknowles.com/blog/2007/12/03/calculating-the-reflect-rotate-translate-normal-form-for-an-isometry-of-the-plane-in-haskell-and-verifying-it-with-quickcheck/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 08:53:10 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Euclidean group]]></category>
		<category><![CDATA[Isometry]]></category>
		<category><![CDATA[QuickCheck]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2007/12/03/calculating-the-reflect-rotate-translate-normal-form-for-an-isometry-of-the-plane-in-haskell-and-verifying-it-with-quickcheck/</guid>
		<description><![CDATA[Any isometry of the plane has a unique normal form as the composition of a translation, rotation and reflection. This note computes this normal form and tests the implementation using the QuickCheck automated testing tool for Haskell. To generate random test data, I use another characterization of isometries as products of up to three reflections. [...]]]></description>
			<content:encoded><![CDATA[<p>Any isometry of the plane has a unique normal form as the composition of a translation, rotation and reflection.  This note computes this normal form and tests the implementation using the QuickCheck automated testing tool for Haskell. To generate random test data, I use another characterization of isometries as products of up to three reflections.  This post is a valid literate Haskell file, so save it to something like <code>Isometries.lhs</code> and run <code>ghc --make Isometries</code>.  Then check it with <code>quickCheck +names Isometries.lhs</code>.
<span id="more-22"></span></p>

<p>Two aspects of this post are given about equal weight:
<ol>
  <li> The mathematical content is elementary and can be understood by anyone familiar with basic trigonometry, as you might learn in high school.  It is inspired by the book <em>Symmetries</em> by DL Johnson, one of the very excellent Springer Undergraduate Mathematics Series.</li></p>

<p><li>The tool <a href="http://www.math.chalmers.se/~rjmh/QuickCheck/">QuickCheck</a> is a fairly brilliant and easy-to-use automatic testing library for Haskell.  I use it to verify each step of the post.  All but the first of my QuickCheck properties found real errors!</li>
</ol></p>

<pre>
> module Main where
> import Test.QuickCheck
</pre>

<p>Now, the reflect-rotate-translate normal form is defined relative to a point <img src='http://s.wordpress.com/latex.php?latex=P&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P' title='P' class='latex' /> (the center of rotation) and a line <img src='http://s.wordpress.com/latex.php?latex=L&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='L' title='L' class='latex' /> (of reflection).  Concisely: <img src='http://s.wordpress.com/latex.php?latex=f%20%3D%20t%20%5Ccirc%20s%20%5Ccirc%20r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f = t \circ s \circ r' title='f = t \circ s \circ r' class='latex' /> where <img src='http://s.wordpress.com/latex.php?latex=t&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='t' title='t' class='latex' /> is a translation, <img src='http://s.wordpress.com/latex.php?latex=s&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='s' title='s' class='latex' /> is a rotation about <img src='http://s.wordpress.com/latex.php?latex=P&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P' title='P' class='latex' />, and <img src='http://s.wordpress.com/latex.php?latex=r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='r' title='r' class='latex' /> is a reflection about <img src='http://s.wordpress.com/latex.php?latex=L&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='L' title='L' class='latex' /> (allowing the identity to be considered a reflection).</p>

<p>I will choose <img src='http://s.wordpress.com/latex.php?latex=P%20%3D%20%280%2C0%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P = (0,0)' title='P = (0,0)' class='latex' /> and <img src='http://s.wordpress.com/latex.php?latex=L%20%3D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='L = ' title='L = ' class='latex' /> the X axis since they are simple.</p>

<pre>
> newtype Translation = Translate (Double, Double) deriving Show
> newtype Rotation    = Rotate Double deriving Show
> newtype Reflection  = Reflect Bool deriving Show
>
> translate (Translate (dx,dy)) (x,y) = (x+dx,y+dy)
> rotate (Rotate angle) (x,y) = (x * cos angle - y * sin angle,
>                                x * sin angle + y * cos angle)
> reflect (Reflect b) (x,y) = if b then (x,-y) else (x,y)
>
> type IsometryNF = (Translation, Rotation, Reflection) 
> apply (t, s, r) (x,y) = (translate t . rotate s . reflect r) (x,y)
</pre>

<p>Aside from preserving distances, the other key aspect of an isometry is that it is invertible, so let&#8217;s express the invertibility of these basic isometries with a Haskell type class.</p>

<pre>
> class Invertible a where
>   inverse :: a -> a
>
> instance Invertible Translation where
>   inverse (Translate (dx,dy)) = (Translate (-dx,-dy))
>
> instance Invertible Rotation where
>   inverse (Rotate angle) = Rotate (-angle)
>
> instance Invertible Reflection where
>   inverse (Reflect b) = Reflect b
</pre>

<p>We can now express the <code>normalForm</code> function.  As input, it takes an arbitrary &#8220;black-box&#8221; isometry as a Haskell function (the type doesn&#8217;t enforce that the function is actually an isometry, of course).  As each component of the normal form is computed, the inverse of that component is applied before calculating the next component.</p>

<pre>
> type Point2D = (Double,Double)
> type Map2D = Point2D -> Point2D
> data Isometry = Isometry Map2D
>
> normalForm :: Isometry -> IsometryNF
> normalForm (Isometry f) = (t, s, r)
>   where t = translation f
>         s = rotation (translate (inverse t) . f)
>         r = reflection (rotate (inverse s) . translate (inverse t) . f)
</pre>

<p>The rest of this post is writing and specifying the <code>translation</code>, <code>rotation</code>, and <code>reflection</code> helper functions.  As an example, I&#8217;ve created this isometry using <a href='http://www.geogebra.org/'>GeoGebra</a>.  I will maintain the convention that the source objects are blue and the output of a transformation is red.
<img src='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/isom2.png' alt='isom2.png' /></p>

<p>Since reflections and rotations fix the origin, the translation is just wherever the origin gets sent.</p>

<pre>
> translation :: Map2D -> Translation
> translation f = Translate (f (0,0))
</pre>

<p>On translations, this should be the identity, and we express that fact with the first of these QuickCheck properties.  The second indicates that for an arbitrary isometry <img src='http://s.wordpress.com/latex.php?latex=f%20%3D%20t%20%5Ccirc%20s%20%5Ccirc%20r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f = t \circ s \circ r' title='f = t \circ s \circ r' class='latex' />, composing with the translation&#8217;s inverse should fix the origin, because <img src='http://s.wordpress.com/latex.php?latex=s&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='s' title='s' class='latex' /> and <img src='http://s.wordpress.com/latex.php?latex=r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='r' title='r' class='latex' /> leave the origin where it is:
   <img src='http://s.wordpress.com/latex.php?latex=t%5E%7B-1%7D%20%5Ccirc%20f%20%3D%20t%5E%7B-1%7D%20%5Ccirc%20t%20%5Ccirc%20s%20%5Ccirc%20r%20%3D%20s%20%5Ccirc%20r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='t^{-1} \circ f = t^{-1} \circ t \circ s \circ r = s \circ r' title='t^{-1} \circ f = t^{-1} \circ t \circ s \circ r = s \circ r' class='latex' />
Or in pictures:
<a href='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/isomtrans.png'>
<img src='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/isomtrans.png' alt='isomtrans.png' /></a></p>

<p>The operator <code>=~=</code> is an &#8220;approximate&#8221; equality operator for floating point numbers.  </p>

<pre>
> prop_translation :: Translation -> Point2D -> Bool
> prop_translation trans (x,y) = translate trans (x,y) =~=
>                                translate (translation (translate trans)) (x,y)
>
> prop_tInv :: Isometry -> Point2D -> Bool
> prop_tInv (Isometry f) (x,y)  =  (tInv . f) (0,0) =~= (0,0)
>   where tInv = (translate . inverse . translation) f
</pre>

<p>To find the rotation, we pick any point on the X axis and see where it is sent after inverting the translation.  A simple choice is (1,0) which will be rotated somewhere else on the unit circle.</p>

<pre>
> rotation :: Map2D -> Rotation
> rotation f = Rotate angle
>   where (x,y) = f (1,0)
>         yAngle = asin y
>         xAngle = acos x
>         angle  = if yAngle > 0 then xAngle else 2*pi - xAngle
</pre>

<p>To test this function, we use extensional equality on rotation functions rather than intensional equality on the angle since rotations do not have a unique representation (our function returns a canonical representation between 0 and <img src='http://s.wordpress.com/latex.php?latex=2%5Cpi&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2\pi' title='2\pi' class='latex' />).  As inverting the translation component of an isometry fixes the origin, inverting this rotation should fix the point (1,0) and by implication the entire X axis.  In pictures:</p>

<p><a href='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/isomrot.png' title='isomrot.png'><img src='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/isomrot.png' alt='isomrot.png' /></a></p>

<pre>
> prop_rotation :: Rotation -> Point2D -> Bool
> prop_rotation rot (x,y) = rotate rot (x,y) =~= 
>                            rotate (rotation (rotate rot)) (x,y)
>

> prop_sInv :: Isometry -> Point2D -> Bool
> prop_sInv (Isometry f) (x,y)  =  (sInv . tInv . f) (1,0) =~= (1,0)
>   where tInv = (translate . inverse . translation) f
>         sInv = (rotate . inverse . rotation) (tInv . f)
</pre>

<p>We have calculated <img src='http://s.wordpress.com/latex.php?latex=t&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='t' title='t' class='latex' /> and <img src='http://s.wordpress.com/latex.php?latex=s&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='s' title='s' class='latex' /> and now we have in hand:
   <img src='http://s.wordpress.com/latex.php?latex=s%5E%7B-1%7D%20%5Ccirc%20t%20%5E%7B-1%7D%20%5Ccirc%20f%20%3D%20s%5E%7B-1%7D%20%5Ccirc%20t%20%5E%7B-1%7D%20%5Ccirc%20t%20%5Ccirc%20s%20%5Ccirc%20r%20%3D%20r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='s^{-1} \circ t ^{-1} \circ f = s^{-1} \circ t ^{-1} \circ t \circ s \circ r = r' title='s^{-1} \circ t ^{-1} \circ f = s^{-1} \circ t ^{-1} \circ t \circ s \circ r = r' class='latex' /></p>

<p>Now we just figure out the reflection <img src='http://s.wordpress.com/latex.php?latex=r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='r' title='r' class='latex' /> by choosing any point not on the X axis and seeing if it was reflected or not.  An obvious choice is (0,1)</p>

<pre>
> reflection :: Map2D -> Reflection
> reflection f = Reflect (not (f (0,1) =~= (0,1)))
</pre>

<p>The correctness properties should be familiar by now:</p>

<pre>
> prop_reflection :: Reflection -> Point2D -> Bool
> prop_reflection refl (x,y)  =  reflect refl (x,y) =~=
>                                reflect (reflection (reflect refl)) (x,y)
>
> prop_rInv :: Isometry -> Point2D -> Bool
> prop_rInv (Isometry f) (x,y)  =  (rInv . sInv . tInv . f) (1,0) =~= (1,0)
>   where tInv = (translate . inverse . translation) f
>         sInv = (rotate . inverse . rotation) (tInv . f)
>         rInv = (reflect . inverse . reflection) (sInv . tInv . f)
</pre>

<p><a href='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/isomrefl.png' title='isomrefl.png'><img src='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/isomrefl.png' alt='isomrefl.png' /></a></p>

<p>And we are done!  To test, though, we need to tell QuickCheck how to generate isometries.  I could reuse the basic isometries, but code duplication is desirable for consistency checking, so I&#8217;ll use another mathematical property to generate random isometries: they are all the composition of three reflections, which may each be the identity, of course.</p>

<p>Reflecting about an arbitrary line is pretty easy: translate so the line passes through the origin, rotate the line onto the horizontal axis, then reflect (sound familiar?).  You can read more at <a href='http://planetmath.org/encyclopedia/DerivationOf2DReflectionMatrix.html'>Planet Math</a> if you like, or figure out the formulae yourself with some high school trigonometry, or just let the computer compose the functions for you.  Because I want to decouple my specifications and implementation, I worked out the formulae directly.</p>

<pre>
> instance Arbitrary Isometry where
>   arbitrary = do refl1 <- newRefl
>                  refl2 <- newRefl
>                  refl3 <- newRefl
>                  return (Isometry (refl3 . refl2 . refl1))
>       where newRefl = do angle <- arbitrary
>                          yOffset <- arbitrary
>                          return (reflectAbout yOffset angle)
>
> reflectAbout :: Double -> Double -> Map2D
> reflectAbout yOffset angle =
>   translateY yOffset . reflectRotate angle . translateY (-yOffset)
>     where translateY dy (x,y) = (x,y+dy)
>           reflectRotate angle (x,y) = (x * cos (2*angle) + y * sin (2*angle),
>                                        x * sin (2*angle) - y * cos (2*angle))
</pre>

<p>And we can use QuickCheck to test our generator. (This caught a typo in <code>reflectAbout</code>)</p>

<pre>
> prop_Isometry :: Isometry -> Point2D -> Point2D -> Bool
> prop_Isometry (Isometry f) p1 p2 =  distsq p1 p2 =~= distsq (f p1) (f p2)
>   where distsq (x,y) (x',y') = (x-x')**2 + (y-y')**2
</pre>

<p>Then the statement of correctness for the entire algorithm is:</p>

<pre>
> prop_NF :: Isometry -> Point2D -> Bool
> prop_NF f'@(Isometry f) (x,y)  =  f (x,y) =~= apply (normalForm f') (x,y)
</pre>

<p>And <code>normalForm</code> should also be the identity on normal forms, to check that I&#8217;ve written <code>apply</code> correctly.  A lot of these properties overlap so they fail together, but it doesn&#8217;t hurt to have a lot of properties.</p>

<pre>
> prop_NFNF nf (x,y)  =  apply nf (x,y) =~= 
>                        apply (normalForm $ Isometry $ apply nf) (x,y)
</pre>

<p>The QuickCheck page has a script to run your tests in hugs, but I had to edit it somewhat to run it on my machine.  In case you don&#8217;t want to do that, this file can just be compiled and run.  Either way you run the checks, then you should see something like this:</p>

<pre>
*Main> prop_translation: OK, passed 100 tests.
*Main> prop_tInv: OK, passed 100 tests.
*Main> prop_rotation: OK, passed 100 tests.
*Main> prop_sInv: OK, passed 100 tests.
*Main> prop_reflection: OK, passed 100 tests.
*Main> prop_rInv: OK, passed 100 tests.
*Main> prop_Isometry: OK, passed 100 tests.
*Main> prop_NF: OK, passed 100 tests.
*Main> prop_NFNF: OK, passed 100 tests.
</pre>

<p>Below here is just boilerplate &#8212; end of commentary.</p>

<pre>
> main = do check ("prop_translation", prop_translation)
>           check ("prop_tInv", prop_tInv)
>           check ("prop_rotation", prop_rotation)
>           check ("prop_sInv", prop_sInv)
>           check ("prop_reflection", prop_reflection)
>           check ("prop_rInv", prop_rInv)
>           check ("prop_Isometry", prop_Isometry)
>           check ("prop_NF", prop_NF)
>           check ("prop_NFNF", prop_NFNF)
>           
>   where check (name,prop) = do putStr (name ++ ": ")
>                                quickCheck prop
>
> instance Arbitrary Translation where 
>   arbitrary = do dx <- arbitrary
>                  dy <- arbitrary
>                  return (Translate (dx,dy))
>
> instance Arbitrary Rotation where
>   arbitrary = do angle <- arbitrary
>                  return (Rotate angle)
>
> instance Arbitrary Reflection where
>   arbitrary = do refl <- arbitrary 
>                  return (Reflect refl)
>
> instance ApproxEq Rotation where
>   (Rotate a) =~= (Rotate a')  =  a =~= a'
>
> instance Show Isometry where
>   show = show . normalForm -- cheating!
>
> class ApproxEq a where
>   (=~=) :: a -> a -> Bool
>
> instance (ApproxEq a, ApproxEq b) => ApproxEq (a,b) where
>   (x,y) =~= (x',y')  =  (x =~= x') &#038;&#038; (y =~= y') 
>     where epsilon = 0.001
>
> instance ApproxEq Double where
>   x =~= x'  =  (abs (x-x') < epsilon)
>     where epsilon = 0.001
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2007/12/03/calculating-the-reflect-rotate-translate-normal-form-for-an-isometry-of-the-plane-in-haskell-and-verifying-it-with-quickcheck/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visualizing 2D convex hull using Gtk and OpenGL in Haskell</title>
		<link>http://www.kennknowles.com/blog/2007/11/20/visualizing-2d-convex-hull-using-gtk-and-opengl-in-haskell/</link>
		<comments>http://www.kennknowles.com/blog/2007/11/20/visualizing-2d-convex-hull-using-gtk-and-opengl-in-haskell/#comments</comments>
		<pubDate>Tue, 20 Nov 2007 09:06:35 +0000</pubDate>
		<dc:creator>Kenn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[convex hull]]></category>
		<category><![CDATA[Geometry]]></category>
		<category><![CDATA[Gtk]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://www.kennknowles.com/blog/2007/11/20/visualizing-2d-convex-hull-using-gtk-and-opengl-in-haskell/</guid>
		<description><![CDATA[This note shows how to use OpenGL with Gtk in Haskell. The result is a little visualization to check our implementation of the classic iterative convex hull algorithm. This post is a valid literate Haskell file so save it to something like ConvexHull.lhs and compile with ghc --make ConvexHull. What you see above is what [...]]]></description>
			<content:encoded><![CDATA[<p>This note shows how to use OpenGL with Gtk in Haskell.  The result is a little visualization to check our implementation of the classic iterative convex hull algorithm. </p>

<p><img src='http://www.kennknowles.com/blog/wp-content/uploads/2007/12/hull1.png' alt='hull1.png' /></p>

<p>This post is a valid literate Haskell file so save it to something like <code>ConvexHull.lhs</code> and compile with <code>ghc --make ConvexHull</code>.  What you see above is what you&#8217;ll get when you run <code>./ConvexHull</code> <span id="more-17"></span></p>

<p>The best OpenGL tutorial for Haskell that I&#8217;ve found is <a href="http://blog.mikael.johanssons.org/archive/2006/09/opengl-programming-in-haskell-a-tutorial-part-1/">this one from Michi&#8217;s blog</a>, using GLUT to interface with X.  For this tutorial we are going to use the Gtk <code>GLDrawingArea</code> widget, to illustrate the differences, which can be rather hard to find in the documentation.</p>

<p>The libraries used can be found here:
<ul>
  <li><a href="http://www.haskell.org/haskellwiki/Opengl">Haskell OpenGL</a></li>
  <li><a href="http://haskell.org/gtk2hs/">Gtk2hs</a></li>
</ul>
These are thin bindings, so our code is all going to be pretty imperative.</p>

<pre>
> import Data.IORef
> import Data.List
> import Graphics.Rendering.OpenGL as GL
> import Graphics.UI.Gtk as Gtk
> import Graphics.UI.Gtk.OpenGL
> import System.Random
</pre>

<p>I&#8217;ll show main first.  If you are just looking for the outline of how to initialize everything and make it go, here it is:</p>

<pre>
> main = do
>   initGUI
>   glConfig <- glConfigNew [GLModeRGBA, GLModeDouble]
>   initGL
>   
>   pointRef <- (randomPoints 15 >>= newIORef)
>
>   canvas  <- glDrawingAreaNew glConfig
>   onExpose canvas (\_ -> readIORef pointRef >>= drawWithHull canvas)
>
>
>   button <- buttonNew
>   Gtk.set button [ buttonLabel := "Generate new points." ]
>   onClicked button (do newPoints <- randomPoints 15
>                        writeIORef pointRef newPoints
>                        drawWithHull canvas newPoints
>                        return ())
>
>   vbox <- vBoxNew False 0
>   boxPackStart vbox button PackNatural 0
>   boxPackStart vbox canvas PackGrow 0
>
>   window <- windowNew
>   Gtk.set window [ containerBorderWidth := 10,
>                    containerChild := vbox ]
>   onDestroy window mainQuit
>
>   widgetShowAll window
>   mainGUI              
</pre>

<p>Now, Haskell&#8217;s OpenGL binding has some quirks with regards to numeric overloading, so it helps to define some type aliases.  Since I want to take cross products I&#8217;ll work in three dimensions, and define some basic operations on my points.  The OpenGL binding has separate types for points and vectors, but I&#8217;m going to abuse the point type to represent both.</p>

<pre>
> type Point3 = Vertex3 GLfloat

> cross :: Point3 -> Point3 -> Point3
> cross (Vertex3 x0 y0 z0) (Vertex3 x1 y1 z1) = 
>    Vertex3 (y0*z1 - z0*y1) (z1*x0 - x0*z1) (x0*y1 - x1*y0)

> dot :: Point3 -> Point3 -> GLfloat
> dot (Vertex3 x0 y0 z0) (Vertex3 x1 y1 z1) = x0*x1 + y0*y1 + z0*z1

> randomPoints :: Int -> IO [Point3]
> randomPoints 0 = return []
> randomPoints n = do 
>   x <- randomRIO (-0.9,0.9) -- chosen to fit in the OpenGL window
>   y <- randomRIO (-0.9,0.9)
>   rest <- randomPoints (n - 1)
>   return $ Vertex3 x y 0 : rest
</pre>

<p>Now for the quirks with using Gtk for OpenGL &#8211; there are many more setup calls to make.  First, you need to explicitly grab a graphics context (glContext) and GL drawing window (glWin).  Then, we manage the viewport manually to scale our rendering up to fill the window.  Finally, there are Gtk calls to start and end OpenGL rendering calls.
It took me a while to discover them.</p>

<pre>
> drawWithHull :: GLDrawingArea -> [Point3] -> IO Bool
> drawWithHull canvas points = do
>
>   -- This is all Gtk code, managing the internal structures
>   glContext <- glDrawingAreaGetGLContext canvas
>   glWin <- glDrawingAreaGetGLWindow canvas
>   (w,h) <- glDrawableGetSize glWin
>
>   -- This is again Gtk code
>   glDrawableGLBegin glWin glContext
>
>   -- These are OpenGL calls to scale up and use the whole canvas
>   (pos, _) <- GL.get viewport
>   viewport $= (pos, Size (fromIntegral w) (fromIntegral h))
>
>   renderWithHull points
>   GL.flush -- except this
>   glDrawableSwapBuffers glWin
>   glDrawableGLEnd glWin
>   return True
</pre>

<p>I use the terminology &#8220;draw&#8221; to refer to Gtk drawing code, which tends to be bookkeeping, while I use &#8220;render&#8221; to refer to sequences of OpenGL calls.  Here is the code to actually render the points and their convex hull.  Note the color3f specialization, to help the type inferencer.</p>

<pre>
> renderWithHull :: [Point3] -> IO ()
> renderWithHull points = do
>   clear [ColorBuffer]
>   color3f (Color3 1 1 1)
>   renderPrimitive Quads $ mapM_ fatPoint $ points
>   color3f (Color3 1 0 0)
>   renderPrimitive LineStrip $ mapM_ vertex $ hull
>     where hull = convexHull points
>           color3f = color :: Color3 GLfloat -> IO ()

> fatPoint (Vertex3 x y z) = do 
>   vertex $ Vertex3 (x+0.005) (y+0.005) z
>   vertex $ Vertex3 (x-0.005) (y+0.005) z
>   vertex $ Vertex3 (x-0.005) (y-0.005) z
>   vertex $ Vertex3 (x+0.005) (y-0.005) z
</pre>

<p>From here on, I&#8217;m just implementing the convex hull algorithm.</p>

<p>This is an iterative algorithm that computes the upper half-hull by travelling left-to-right across the plane making sure to always make right turns; if ever a left turn occurs, it backtracks as far as necessary, patching up the hull.  I defer the obvious helper isLeftOf to the end of the file.</p>

<pre>
> upperHalfHull points = upperHalfHull' (sort points) []
>    where upperHalfHull' [] hull = hull
>          upperHalfHull' (v:vs) [] = upperHalfHull' vs [v]
>          upperHalfHull' (v:vs) [y] = upperHalfHull' vs [v,y]
>          upperHalfHull' (v:vs) (y:x:zs) = if v `isLeftOf` (x,y)
>                                           then upperHalfHull' (v:vs) (x:zs)
>                                           else upperHalfHull' vs (v:y:x:zs)
</pre>

<p>Then the lower half of the hull does the same thing right-to-left, and I rather naively combine them into convexHull (I traverse the points maybe three times unneccessarily)</p>

<pre>
> lowerHalfHull points = map rotate180 $ upperHalfHull $ map rotate180 $ points
> rotate180 (Vertex3 x y z) = Vertex3 (-x) (-y) z

> convexHull :: [Point3] -> [Point3]
> convexHull points = upperHalfHull points ++ lowerHalfHull points
</pre>

<p>There is a divide-and-conquer algorithm which is probably more idiomatic, and has the same asymptotic complexity (different pathological cases) but this is the one I was trying out.</p>

<p>This last helper function only makes sense when points are all on the z=0 plane.  It takes a point and a directed line segment, and indicates whether the point lies to the left of the line defined by that segment.</p>

<pre>
> isLeftOf :: Point3 -> (Point3, Point3) -> Bool
> isLeftOf (Vertex3 x2 y2 _) (Vertex3 x0 y0 _, Vertex3 x1 y1 _) =
>   let Vertex3 _ _ z = (Vertex3 (x1-x0) (y1-y0) 0) 
>                       `cross` 
>                       (Vertex3 (x2-x0) (y2-y0) 0) 
>   in z > 0
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kennknowles.com/blog/2007/11/20/visualizing-2d-convex-hull-using-gtk-and-opengl-in-haskell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

