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

<channel>
	<title>for the few of us.</title>
	<atom:link href="http://www.iis.sinica.edu.tw/~scm/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.iis.sinica.edu.tw/~scm</link>
	<description>Research Blog of 穆信成 Shin-Cheng Mu</description>
	<pubDate>Wed, 23 Jul 2008 03:54:06 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Tail-Recursive, Linear-Time Fibonacci</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/tail-recursive-linear-time-fibonacci/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/tail-recursive-linear-time-fibonacci/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 14:29:33 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Research Blog]]></category>

		<category><![CDATA[Fibonacci]]></category>

		<category><![CDATA[Program Derivation]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=55</guid>
		<description><![CDATA[How can I introduce accumulating parameters to derive the linear-time, tail recursive implementation of <mi>fib</mi>.]]></description>
			<content:encoded><![CDATA[<p>For two consecutive years I have been responsible for teaching the <a href="http://flolac.iis.sinica.edu.tw/flolac08/doku.php?id=derivation">program derivation course</a> in the <a href="http://flolac.iis.sinica.edu.tw/flolac08/">FLOLAC summer school</a>. It was an exam question last year to derive a linear-time solution computing the Fibonacci function, whose definition we all know very well:</p>
<blockquote><math>
  fib 0 = 0<br />
  fib 1 = 1<br />
  fib (n+2) = fib (n+1) + fib n<br />
</math>
</blockquote>
<p>I would like the students to see the derivation as an instance of <em>tupling</em>: to generalise the targeted function by having it return more results, hoping that the generalisation can actually be performed faster. For this problem, one may consider the generalisation:</p>
<blockquote><math>
 fib2 n = (fib n, fib (n+1))<br />
</math>
</blockquote>
<p>from which we may easily construct a recursive definition for <mi>fib2</mi> by simply unfolding and folding the definitions. Once we finish, take <mi>fib = fst . fib2</mi>.</p>
<h3>Tupling and Fold Fusion</h3>
<p>As a practice, however, I instructed the students to see this as an instance of fold fusion with the fold on natural numbers:</p>
<blockquote><math>
foldN f e 0 = e<br />
foldN f e (n+1) = f (foldN f e n)<br />
</math>
</blockquote>
<p>The derivation goes like</p>
<blockquote><math>
&nbsp;&nbsp;&nbsp;  fib2<br />
= &nbsp;&nbsp; { since id = foldN (1+) 0 }<br />
&nbsp;&nbsp;&nbsp;  fib2 . foldN (1+) 0<br />
= &nbsp;&nbsp; { fold fusion, see below }<br />
&nbsp;&nbsp;&nbsp; foldN step (0,1)<br />
</math>
</blockquote>
<p>To derive <mi>step</mi> through the fusion condition, we reason:</p>
<blockquote><math>
&nbsp;&nbsp;&nbsp;  fib2 (n+1)<br />
= &nbsp;&nbsp; { def. of fib2 }<br />
&nbsp;&nbsp;&nbsp;  (fib (n+1), fib (n+2))<br />
= &nbsp;&nbsp; { def. of fib }<br />
&nbsp;&nbsp;&nbsp;  (fib (n+1), fib (n+1) + fib n)<br />
= &nbsp;&nbsp; { let step (x,y) = (y,x+y) }<br />
&nbsp;&nbsp;&nbsp;  step (fib n, fib (n+1))<br />
= &nbsp;&nbsp; { def. of fib2 }<br />
&nbsp;&nbsp;&nbsp;  step (fib2 n)<br />
</math>
</blockquote>
<p>Therefore, we have <mi>fib2 = foldN step (0,1)</mi> where <mi>step (x,y) = (y,x+y)</mi>.</p>
<p>Oleg Kiselyov also used a similar definition of <mi>fib</mi> as a fold (on a list of length <mi>n</mi>) as an example in his <a href="http://okmij.org/ftp/Algorithms.html#zip-folds">library of fold transformers</a>.</p>
<h3>Accumulating Parameters</h3>
<p>I was perhaps so happy with seeing <mi>fib</mi> as a fold-fusion that I forgot one may want a tail recursive definition. This is one of the exercises of the <a href="http://flolac.iis.sinica.edu.tw/flolac08/doku.php?id=fp">functional programming course</a> (taught by  <a href="http://www.cs.nccu.edu.tw/~chenk/index-en.htm">Kung Chen</a>) this year, where the students may just write down the (obvious) tail recursive, linear-time function computing Fibonacci. The hint was to &#8220;introduce two accumulating parameters.&#8221; Can I derive this definition?</p>
<p>When I taught the students about accumulating parameters, I also told them to &#8220;look for some generalisation by adding more parameters.&#8221; The canonical example is perhaps generalising quadratic time <mi>reverse</mi> to <mi>fastrev xs ys = reverse xs ++ ys</mi>. For <mi>fib</mi>, it appeared reasonable to generalise the base cases. I was later told by Oleg that this function is called <mi>gib</mi>:</p>
<blockquote><math>
gib 0 x y = x<br />
gib 1 x y = y<br />
gib (n+2) x y = gib (n+1) x y + gib n x y<br />
</math>
</blockquote>
<p>From this definition, however, a linear-time implementation of <mi>gib</mi> does not follow immediately. We will need this lemma:</p>
<blockquote><math>
gib n (fib k) (fib (k+1)) = fib (n+k) <span style="float:right">(1)</span><br />
</math>
</blockquote>
<p>which can be proved by induction on <mi>n</mi>. For an intuitive understanding, it says that <mi>gib</mi> allows us to compute Fibonacci not only from the base cases <mi>0</mi> and <mi>1</mi>, but also from the middle: if we take <mi>fib k</mi> and <mi>fib (k+1)</mi> as base cases, we get <mi>fib (n+k)</mi>. </p>
<p>The property (1) came from some slides <a href="http://www.cs.nccu.edu.tw/~chenk/index-en.htm">Kung Chen</a> showed me, originated from John Hughes. John Hughes actually suggested to start with (1) as the specification. Either way, I wonder how one could come up with (1) in the first place. Given the definition of <mi>gib</mi>, (1) can be proved by induction. The rest of the derivation is not too hard. This is the derived program. Details omitted.</p>
<blockquote><math>
gib 0 x y = x<br />
gib (n+1) x y = gib n y (x+y)<br />
</math>
</blockquote>
<h3>Tail-Recursive Fibonacci</h3>
<p>Meanwhile, <a href="http://joshkos.blogspot.com/">Josh Ko</a> gave me this generalisation:</p>
<blockquote><math>
  ffib n x y = x × fib n + y × fib (n+1)<br />
</math>
</blockquote>
<p>The motivation came from, perhaps, the observation that every <mi>fib n</mi> can always be expressed as an linear combination of some smaller <mi>fib i</mi> and <mi>fib j</mi>:</p>
<blockquote><math>
   fib 2 = fib 1 + fib 0<br />
   fib 3 = fib 2 + fib 1 = 2 × fib 1 + fib 0<br />
   fib 4 = fib 3 + fib 2 = 2 × fib 2 + fib 1 = 3 × fib1 + 2 × fib 0<br />
   :<br />
</math>
</blockquote>
<p>Given the definition, it is immediate that <mi>ffib 0 x y = y</mi> and:</p>
<blockquote><math>
    ffib (n+1) x y<br />
  = x × fib (n+1) + y × fib (n+2)<br />
  = x × fib (n+1) + y × fib (n+1) + y × fib n<br />
  = (x+y) × fib (n+1) + y × fib n<br />
  = ffib n y (x+y)<br />
</math>
</blockquote>
<p>Therefore we have derived:</p>
<blockquote><math>
ffib 0 x y = y<br />
ffib (n+1) x y = ffib n y (x+y)<br />
</math>
</blockquote>
<p>which is more or less what one would expect. It differs from the derived linear-time implementation of <mi>gib</mi> only on the base case.</p>
<p>Finally, since <mi>gib</mi> and <mi>ffib</mi> define similar functions, <mi>ffib</mi> satisfies a property similar to (1):</p>
<blockquote><math>
    ffib n (fib k) (fib (k+1)) = fib (n+k+1) <span style="float:right">(2)</span><br />
</math>
</blockquote>
<p>The proof proceeds by induction on <mi>n</mi>. The base case is trivial. For the inductive case:</p>
<blockquote><math>
&nbsp;&nbsp; ffib (n+1) (fib k) (fib (k+1))<br />
     = fib k × fib (n+1) + fib (k+1) ×fib (n+2)<br />
     = fib k × fib (n+1) + fib (k+1) × fib (n+1) + fib (k+1) × fib n<br />
     = (fib k + fib (k+1)) × fib (n+1) + fib (k+1) × fib n<br />
     = ffib n (fib (k+1)) (fib (k+2))<br />
     =&nbsp;&nbsp; { induction }<br />
&nbsp;&nbsp;  fib (n+k+2)<br />
</math>
</blockquote>
<p>thus completes the proof.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/tail-recursive-linear-time-fibonacci/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Algebra of programming using dependent types</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/algebra-of-programming-using-dependent-types/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/algebra-of-programming-using-dependent-types/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 15:21:30 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Conference]]></category>

		<category><![CDATA[Agda]]></category>

		<category><![CDATA[Dependent Type]]></category>

		<category><![CDATA[Program Derivation]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=50</guid>
		<description><![CDATA[S-C. Mu, <a href="http://joshkos.blogspot.com/">H-S. Ko</a>, and <a href="http://www.cs.chalmers.se/~patrikj/">P. Jansson</a>. Algebra of programming using dependent types. In <i>Mathematics of Program Construction 2008</i>, LNCS 5133, pp 268-283. July 2008.<br/>[<a href="http://www.iis.sinica.edu.tw/~scm/pub/mpc08.pdf">PDF</a>]]]></description>
			<content:encoded><![CDATA[<p>S-C. Mu, <a href="http://joshkos.blogspot.com/">H-S. Ko</a>, and <a href="http://www.cs.chalmers.se/~patrikj/">P. Jansson</a>. In <i>Mathematics of Program Construction 2008</i>, LNCS 5133, pp 268-283. July 2008. [<a href="http://www.iis.sinica.edu.tw/~scm/pub/mpc08.pdf">PDF</a>]</p>
<p>Dependent type theory is rich enough to express that a program satisfies an input/output relational specification, but it could be hard to construct the proof term. On the other hand, <em>squiggolists</em> know very well how to show that one relation is included in another by algebraic reasoning. We demonstrate how to encode functional and relational derivations in a dependently typed programming language. A program is coupled with an algebraic derivation from a specification, whose correctness is guaranteed by the type system.</p>
<p>Code accompanying the paper has been developed into an <a href="http://www.iis.sinica.edu.tw/~scm/2008/aopa/">Agda library <strong>AoPA</strong></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/algebra-of-programming-using-dependent-types/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A programmable editor for developing structured documents based on bidirectional transformations</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/a-programmable-editor-for-developing-structured-documents-based-on-bidirectional-transformations-2/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/a-programmable-editor-for-developing-structured-documents-based-on-bidirectional-transformations-2/#comments</comments>
		<pubDate>Thu, 29 May 2008 02:17:53 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Journal]]></category>

		<category><![CDATA[Bidirectional Updating]]></category>

		<category><![CDATA[Program Inversion]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=23</guid>
		<description><![CDATA[<a href="http://www.ipl.t.u-tokyo.ac.jp/~hu/">Z. Hu</a>, S-C. Mu and <a href="http://www.ipl.t.u-tokyo.ac.jp/~takeichi/">M. Takeichi</a>, A programmable editor for developing structured documents based on bidirectional transformations. <i>Higher-Order and Symbolic Computation</i>, Vol 21(1-2), pp 89-118, May 2008.<br/>[<a href="http://www.iis.sinica.edu.tw/~scm/pub/hosc06.pdf">PDF</a>]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ipl.t.u-tokyo.ac.jp/~hu/">Z. Hu</a>, S-C. Mu and <a href="http://www.ipl.t.u-tokyo.ac.jp/~takeichi/">M. Takeichi</a>. <i>Higher-Order and Symbolic Computation</i>, Vol 21(1-2), pp 89-118, May 2008.<br/>[<a href="http://www.iis.sinica.edu.tw/~scm/pub/hosc06.pdf">PDF</a>]</p>
<p>This paper presents an application of bidirectional transformations to design and implementation of a novel editor supporting interactive refinement in the development of structured documents. The user performs a sequence of editing operations on the document view, and the editor automatically derives an efficient and reliable document source and a transformation that produces the document view. The editor is unique in its programmability, in the sense that transformation can be obtained through editing operations. The main tricks behind are the utilization of the view-updating technique developed in the database community, and a new bidirectional transformation language that can describe not only relationship between the document source and its  view, but also data dependency in the view.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/a-programmable-editor-for-developing-structured-documents-based-on-bidirectional-transformations-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Simple Exercise using the Modular Law</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/a-simple-exercise-using-the-modular-law/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/a-simple-exercise-using-the-modular-law/#comments</comments>
		<pubDate>Tue, 27 May 2008 09:57:38 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Research Blog]]></category>

		<category><![CDATA[Program Derivation]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=54</guid>
		<description><![CDATA[Prove the following property in point-free style:
<blockquote><math>
  S  ⊆ C . S &#160;&#160; &#160;⇐ &#160;&#160;&#160;   R ⊆ C . R  &#160; ∧ &#160;  S ⊆ R
</math></blockquote>]]></description>
			<content:encoded><![CDATA[<p><a href="http://joshkos.blogspot.com/2008/05/partial-greedy-theorem.html">Josh needs a property</a> for which there is an obvious pointwise proof. He wonders whether it is possible to prove it in point-free style. I haven&#8217;t practised point-free proofs for a while, so I&#8217;d give it a try.</p>
<p>The actual property he needs is that <mi>FT . C ⊆ C . FT . C</mi> where <mi>C</mi> is a coreflexive, given <mi>T ⊆ ⦇S⦈</mi> and <mi>F⦇S⦈ . C ⊆ C . F⦇S⦈ . C</mi>. It is sufficient to prove this generalised property:</p>
<blockquote><math>
  S  ⊆ C . S &nbsp;&nbsp; &nbsp;⇐ &nbsp;&nbsp;&nbsp;   R ⊆ C . R  &nbsp; ∧ &nbsp;  S ⊆ R<br />
</math>
</blockquote>
<p>Intuitively speaking, if <mi>C</mi> covers the range of <mi>R</mi> and <mi>S ⊆ R</mi>, then <mi>C</mi> covers the range of <mi>S</mi> too.</p>
<p>Well, the proof goes:</p>
<blockquote><math>
&nbsp;&nbsp; &nbsp;C . S<br />
=   <text>{ since <mi>C . C = C</mi> }</text><br />
&nbsp;&nbsp; &nbsp;C . C . S<br />
⊇    <text>{ since <mi>X ⊇ X ∩ Y</mi> }</text><br />
&nbsp;&nbsp; &nbsp; C . ((C . S)  ∩  R)<br />
⊇    <text>{ modular law <mi>X ∩ (Y.Z) ⊆ Y . ((Y˘.X) ∩ Z)</mi>, and <mi>C˘ = C</mi>  }</text><br />
&nbsp;&nbsp; &nbsp; S  ∩  (C . R)<br />
⊇    <text>{ given: <mi>R ⊆ C . R</mi>  }</text><br />
&nbsp;&nbsp; &nbsp; S  ∩  R<br />
=    <text>{ given: <mi>S ⊆ R</mi>  }</text><br />
&nbsp;&nbsp; &nbsp; S<br />
</math>
</blockquote>
<p>It is hard to explain the intuition behind the use of modular law. If we take <mi>C</mi> as a predicate, the property can be written pointwisely as:</p>
<blockquote><math>
  (b S a  ⇒ C b ∧ b S a) &nbsp;&nbsp; &nbsp;⇐ &nbsp;&nbsp;&nbsp;   (b R a  ⇒ C b ∧ b R a)  &nbsp; ∧ &nbsp;  b S a ⇒ b R a<br />
</math>
</blockquote>
<p>where <mi>a</mi> and <mi>b</mi> are both universally quantified. We may simplify <mi>b S a  ⇒ C b ∧ b S a</mi> to <mi>b S a  ⇒ C b</mi>, but that makes it more difficult to see the connection. Essentially, I was mimicking the following obvious proof:</p>
<blockquote><math>
&nbsp;&nbsp; &nbsp;C b ∧  b S a<br />
⇐   <text>{ strengthening }</text><br />
&nbsp;&nbsp; &nbsp;C b ∧ b S a  ∧ b R a<br />
⇐    <text>{ since <mi>b R a  ⇒ C b ∧ b R a</mi> }</text><br />
&nbsp;&nbsp; &nbsp;b S a  ∧ b R a<br />
⇐    <text>{ since <mi>b S a ⇒ b R a</mi>  }</text><br />
&nbsp;&nbsp; &nbsp; b S a<br />
</math>
</blockquote>
<p>The strengthening step corresponds to the use of <mi>X ⊇ X ∩ Y</mi>, while the next two steps respectively correspond to the last two steps of the point-free proof. The modular law, implicit in the pointwise proof, was used to group <mi>C</mi> and <mi>R</mi> to the right places.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/a-simple-exercise-using-the-modular-law/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Well-Foundedness and Reductivity</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/well-foundedness-and-reductivity/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/well-foundedness-and-reductivity/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 14:25:01 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Research Blog]]></category>

		<category><![CDATA[Agda]]></category>

		<category><![CDATA[Dependent Type]]></category>

		<category><![CDATA[Program Derivation]]></category>

		<category><![CDATA[Termination]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=52</guid>
		<description><![CDATA[It seems that reductivity of Doornbos and Backhouse is in fact accessibility, which is often taken by type theorists to be an alternative definition of well-foundedness.]]></description>
			<content:encoded><![CDATA[<p>Before learning dependent types, all I knew about program termination was from the work of Henk Doornbos and <a href="http://www.cs.nott.ac.uk/~rcb/">Roland Backhouse</a> [<a href="#DB95">DB95</a>, <a href="#DB96">DB96</a>]. I am curious about the connection between their formulation of well-foundedness by relational calculation and the type theoretic view.</p>
<p>It is generally accepted that a relation <mi>_&lt;_</mi> is <em>well-founded</em> if, for all <mi>x</mi>, there is no infinite chain <mi>x > x₁ > x₂ > x₃ > &#8230;. </mi>. A related concept is <em>inducvitity</em>. We say that a relation <em>admits induction</em> of we can use it to perform induction. For example, the less-than ordering on natural number is inductive.</p>
<p>Most of the type theoretical paper I have seen equate well-foundedness to the concept of accessibilty, which I talked about in a <a href="http://www.iis.sinica.edu.tw/~scm/2008/well-founded-recursion-and-accessibility/">previous post</a>. For example, <a href="http://www.cs.chalmers.se/~bengt/">Bengt Nordström</a> [<a href="#Nor88">Nor88</a>] introduced the datatype <code>Acc</code> as a &#8220;constructively more useful description&#8221; of well-foundedness. </p>
<p>Doornbos and Backhouse generalised well-foundedness and other related notions to an arbitrary <mi><b>F</b></mi>-algebra. Well-foundedness, however, was generalised to &#8220;having a unique solution.&#8221; A relation <mi>R : <b>F</b>A ← A </mi> is <mi><b>F</b></mi>-well-founded if there is a unique solution for <mi>X = S . <b>F</b>X . R</mi>. </p>
<h3>Reductivity</h3>
<p>Inductivity, on the other hand, is generalised to <mi><b>F</b></mi>-reductivity. While <mi><b>F</b></mi>-reductivity is a generalisation of strong induction, Doornbos and Backhouse called it reductivity &#8220;in order to avoid confusion with existing notions of inductivity.&#8221; [<a ref="DB95">DB95</a>] (Nevertheless, an equivalent concept in Algebra of Programming modelled using membership relation rather than monotype factors, calls itself &#8220;inductivity&#8221;. Different usage of similar terminology can be rather confusing sometimes.) </p>
<p>A relation <mi>R : <b>F</b>A ← A </mi> is <em><mi><b>F</b></mi>-reductive</em> if</p>
<blockquote><math>μ(λP . R⧷<b>F</b>P) = id</math>
</blockquote>
<p>where <mi>⧷</mi> is the <em>monotype factor</em> defined by <mi>ran(R . A) ⊆ B   ≡  A ⊆ R⧷B</mi>. The function <mi>λP . R⧷<b>F</b>P</mi> takes coreflexive (a relation that is a subset if <mi>id</mi>) <mi>P</mi> to coreflexive <mi>R⧷<b>F</b>P</mi>, and <mi>μ</mi> takes its least fixed-point. </p>
<p>Well, it is a definition that is very concise but also very hard to understand, unless you are one of the few who really like these sort of things. If we take <mi>P</mi> to be a predicate, <mi>R\<b>F</b>P</mi> expands to a predicate on <mi>x</mi> that is true if</p>
<blockquote><math>∀y . y R x ⇒ <b>F</b>P y</math>
</blockquote>
<p>Taking the fixed point means to look for the minimum <mi>P</mi> such that</p>
<blockquote><math>∀x . (∀y . y R x ⇒ <b>F</b>P y) ⇒ P x</math>
</blockquote>
<p>The expression now resembles strong induction we all know very well. Computationally, how do we take the fixed point? Of course, by defining a recursive datatype:</p>
<blockquote><p><code>data Acc {a : Set}(R : a -> a -> Set) : a -> Set where<br />
&nbsp;&nbsp;acc : (x : a) -> (forall y -> y < x -> f (Acc R) y) -> Acc R x</code></p></blockquote>
<p>where <code>f : (a -> Set) -> (F a -> Set)</code> is the arrow-operation of functor <code>F</code>. When we take <code>F</code> to be the identity functor, it is exactly the definition of accessibility in my <a href="http://www.iis.sinica.edu.tw/~scm/2008/well-founded-recursion-and-accessibility/">previous post</a>! Finally, the requirement that <mi>μ(λP . R⧷<b>F</b>P) = id</mi> means every element in <code>a</code> is accessible. </p>
<p>So, it seems that reductivity of Doornbos and Backhouse is in fact accessibility, which is often taken by type theorists to be an alternative definition of well-foundedness. Doornbos and Backhouse, however, showed that reductivity guarantees uniqueness solution of hylo equations (which is their definition of <mi><b>F</b></mi>-well-foundedness). The converse, however, is not true in general. </p>
<h3>New Reductive Relations from Old</h3>
<p>Doornbos and Backhouse also developed some principles to build new reductive relations from existing ones. Let us try to see their Agda counterparts. For simplicity, we take <code>F</code> to be the identity functor in the discussion below. </p>
<p>All initial algebras are reductive. For example, given <code>Pred</code> relating <code>n</code> and <code>suc n</code>, one can show that <code>Pred</code> is reductive.</p>
<blockquote><p><code>data Pred : ℕ -> ℕ -> Set where<br />
&nbsp;&nbsp;pre : (n : ℕ) -> Pred n (suc n)</p>
<p>ℕPred-wf : well-found Pred<br />
ℕPred-wf n = acc n (access n)<br />
&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;&nbsp;access : (n : ℕ) -> (m : ℕ) -> Pred m n -> Acc Pred m<br />
&nbsp;&nbsp;&nbsp;&nbsp;access .(suc n) .n (pre n) = acc n (access n) </code></p></blockquote>
<p>We have seen in the previous post that the less-than relation is reductive.</p>
<p>If <mi>R</mi> is reductive and <mi>S ⊆ R</mi>, then <mi>S</mi> is reductive too:</p>
<blockquote><p><code>acc-⊑ : {a : Set}{S R : a -> a -> Set} -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S ⊑ R-> (x : a) -> Acc R x -> Acc S x<br />
acc-⊑ {a}{S} S⊑R x (acc .x h) = acc x access<br />
&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;&nbsp;access : (y : a) -> (y S x) -> Acc S y<br />
&nbsp;&nbsp;&nbsp;&nbsp;access y y≪x = acc-⊑ S⊑R y (h y (S⊑R y x ySx))</code></p></blockquote>
<p>If <mi>f . R . f˘</mi> is reductive for some function <mi>f</mi>, so is <mi>R</mi>. This is how we often prove termination of loops using <mi>f</mi> as the variant.</p>
<blockquote><p><code>acc-fRf˘ : {a b : Set}{R : a -> a -> Set}{f : a -> b} -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(x : a) -> Acc (fun f ○ R ○ ((fun f) ˘)) (f x) -> Acc R x<br />
acc-fRf˘ {a}{b}{R}{f} x (acc ._ h) = acc x access<br />
&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;&nbsp;access : (y : a) -> R y x -> Acc R y<br />
&nbsp;&nbsp;&nbsp;&nbsp;access y xRy = acc-fRf˘ y<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(h (f y) (exists x (exists y (≡-refl , xRy) , ≡-refl))) </code></p></blockquote>
<p>where the operators for relational composition (<code>_○_</code>) and converse (<code>_˘</code>) is that defined in <a href="http://www.iis.sinica.edu.tw/~scm/2008/aopa/">AoPA</a>.</p>
<p>Finally, for the special case where <mi><b>F</b></mi> is the identity functor, <mi>R</mi> is reductive if and only if its transitive closure <mi>R⁺</mi> is. Let us first define transitive closure:</p>
<blockquote><p><code>data _⁺ {a : Set}(R : a -> a -> Set) : a -> a -> Set where<br />
&nbsp;&nbsp;⁺-base : forall {x y} -> R x y -> (R ⁺) x y<br />
&nbsp;&nbsp;⁺-step : forall {x z} -> ∃ a (\y -> R y z × (R ⁺) x y) -> (R ⁺) x z</code></p></blockquote>
<p>The &#8220;if&#8221; direction is easy. Let us prove the &#8220;only-if&#8221; direction.</p>
<blockquote><p><code>acc-tc : {a : Set}{R : a -> a -> Set} -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(x : a) -> Acc R x -> Acc (R ⁺) x<br />
acc-tc {a}{R} x ac = acc x (access x ac)<br />
&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;&nbsp;access : (x : a) -> Acc R x -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(y : a) -> (R ⁺) y x -> Acc (R ⁺) y<br />
&nbsp;&nbsp;&nbsp;&nbsp;access x (acc .x h) y (⁺-base yRx) = acc-tc y (h y yRx)<br />
&nbsp;&nbsp;&nbsp;&nbsp;access x (acc .x h) y (⁺-step (exists z (zRx , yR⁺z))) =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;access z (h z zRx) y yR⁺z  </code></p></blockquote>
<p>Combined with the proof that <code>Pred</code> is reductive, we have another way to show that the less-than relation is reductive. One may compare it with the proof of <code>well-found _<′_</code> in the <a href="http://www.iis.sinica.edu.tw/~scm/2008/well-founded-recursion-and-accessibility/">previous post</a>.</p>
<h3>References</h3>
<p>[<a name="DB95">DB95</a>] Henk Doornbos and Roland Backhouse. <a href="http://www.cs.nott.ac.uk/~rcb/papers/abstract.html#mpc">Induction and recursion on datatypes</a>. B. Moller, editor, <em>Mathematics of Program Construction, 3rd Internatinal Conference</em>, volume 947 of LNCS, pages 242-256. Springer-Verslag, July 1995.</p>
<p>[<a name="DB96">DB96</a>] Henk Doornbos and Roland Backhouse. <a href="http://www.cs.nott.ac.uk/~rcb/papers/abstract.html#reductivity">Reductivity</a>. <em>Science of Computer Programming</em>, 26, pp. 217&#8211;236, 1996.</p>
<p>[<a name="Nor88">Nor88</a>] Bengt Nordström. <a href="http://www.springerlink.com/content/j6427252866p6t01/">Terminating general recursion</a>. BIT archive, Volume 28,  Issue 3, pp 605-619.  1988.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/well-foundedness-and-reductivity/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Well-Founded Recursion and Accessibility</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/well-founded-recursion-and-accessibility/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/well-founded-recursion-and-accessibility/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 06:11:51 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Research Blog]]></category>

		<category><![CDATA[Agda]]></category>

		<category><![CDATA[Dependent Type]]></category>

		<category><![CDATA[Termination]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=51</guid>
		<description><![CDATA[Given a relation <mi>&#60;</mi> that has been shown to be well-founded, we know that a recursively defined function is terminating if its arguments becomes "smaller" with respect to <mi>&#60;</mi> at each recursive call. We can encode such well-founded recursion in Agda's style of structural recusion. ]]></description>
			<content:encoded><![CDATA[<p>Since <a href="http://www.cs.nott.ac.uk/~nad/">Nils Anders Danielsson</a> showed me how to use <code>Induction.WellFounded</code> in Agda&#8217;s <a href="http://appserv.cs.chalmers.se/users/ulfn/wiki/agda.php?n=Libraries.StandardLibrary">Standard Library</a>, I have been studying issues related to well-founded recursion. </p>
<p>In dependently typed programming, we would like to ensure that proof terms are  terminating. Apart from the type checker, Agda employs a separate termination checker. How it exactly works is still at times mysterious to me, but basically it recognises a program as terminating if some of its arguments become &#8220;structurally&#8221; smaller after each recursive call. This is already far more expressive than I thought &#8212; quite a number of programs can be written by structural recursion. Still, we occasionally need some more flexibility. One of such occasion was when I wished to <a href="http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-2/">express terminating unfolds in AoPA</a>. For another example, consider this function mentioned in the paper <a href="http://www.springerlink.com/content/j6427252866p6t01/">Terminating General Recursion</a> by <a href="http://www.cs.chalmers.se/~bengt/">Bengt Nordström</a>:</p>
<blockquote><math>f (n, k) = if k ≤ n then n else f(f (n + 1, k), k)</math>
</blockquote>
<p>It is a variation of <a href="http://en.wikipedia.org/wiki/McCarthy_91_function">McCarthy&#8217;s 91 function</a>, used as a popular example due to its non-trivial recursion pattern. Can we express this function in Agda while informing the termination checker that it does terminate?</p>
<p>Given a relation <mi>&lt;</mi> that has been shown to be well-founded, we know that a recursively defined function is terminating if its arguments becomes &#8220;smaller&#8221; with respect to <mi>&lt;</mi> at each recursive call. We can encode such well-founded recursion in Agda&#8217;s style of structural recusion. The earliest paper I could find about such encoding is <a href="http://www.springerlink.com/content/j6427252866p6t01/">Terminating General Recursion</a> by <a href="http://www.cs.chalmers.se/~bengt/">Bengt Nordström</a>. It may have appeared in other forms, however. </p>
<h3>Accessibility</h3>
<p>Given a binary relation <code>_&lt;_ : a -> a -> Set</code>, an element <code>x</code> is in the <em>well-founded subset</em> of <code>&lt;</code> if there is no infinite chain of <code>x₁, x₂, x₃ ... </code> such that <code>x > x₁ > x₂ > x₃ > ...</code>. The relation is <em>well-founded</em> if all elements of <code>a</code> are in its well-founded subset. The less-than ordering on natural number is well-founded, while the greater-than ordering is not. A more constructive way to talk about well-foundedness is via <em>accessibility</em>. Given a relation <code>_<_ : a -> a -> Set</code>, the proposition <code>Acc _<_ x</code> states that <code>x</code> is accessible under relation <code>&lt;</code>. An element <code>x : a</code> is accessible if all  <code>y : a</code> &#8220;smaller&#8221; than <code>x</code> are accessible:</p>
<blockquote><p><code>data Acc {a : Set}(_<_ : a -> a -> Set) : a -> Set where<br />
&nbsp;&nbsp;acc : (x : a) -> (forall y -> y < x -> Acc _<_ y) -> Acc _<_ x</code></p></blockquote>
<p>A relation <code>_<_ : a -> a -> Set</code> is well-founded if all elements in <code>a</code> are accessible:</p>
<blockquote><p><code>well-found : {a : Set} -> (a -> a -> Set) -> Set<br />
well-found _<_ = forall x -> Acc _<_ x</code></p></blockquote>
<p>For an example, consider the less-than-or-equal-to ordering on natural numbers. It is usually modelled by a datatype stating that <code>0 ≤ n</code> for all <code>n</code> and that <code>1+m ≤ 1+n</code> follows from <code>m ≤ n</code>. The strictly-less-than ordering is defined by <code>m < n = 1+m ≤ n</code>. For well-foundedness proofs, however, the following definitions turn out to be more convenient:</p>
<blockquote><p><code>data _≤′_ : ℕ -> ℕ -> Set where<br />
&nbsp;&nbsp;≤′-refl : forall {n} -> n ≤′ n<br />
&nbsp;&nbsp;≤′-step : forall {m n} -> m ≤′ n -> m ≤′ suc n</p>
<p>_<′_ : ℕ -> ℕ -> Set<br />
m <′ n = suc m ≤′ n<br />
</code></p></blockquote>
<p>Let&#8217;s prove that <code><′</code> is well-founded:</p>
<blockquote><p><code>ℕ<-wf : well-found _<′_<br />
ℕ<-wf n = acc n (access n)<br />
&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;&nbsp;access : (n : ℕ) -> (m : ℕ) -> m &lt;′ n -> Acc _&lt;′_ m<br />
&nbsp;&nbsp;&nbsp;&nbsp;access zero m ()<br />
&nbsp;&nbsp;&nbsp;&nbsp;access (suc n) .n ≤′-refl = acc n (access n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;access (suc n) m (≤′-step m&lt;n) = access n m m&lt;n </code></p></blockquote>
<p>An operational intuition for <code>access</code>: knowing that <code>m &lt;′ n</code>, <code>access</code> demonstrates that it is possible to reach <code>m</code> from <code>n</code> in a finite number of steps.</p>
<h3>Well-Founded Recursion</h3>
<p>As an inductively defined datatype, <code>Acc</code> naturally induces a fold operator:</p>
<blockquote><p><code>acc-fold : {a : Set} (_<_ : a -> a -> Set) {P : a -> Set} -><br />
&nbsp;&nbsp;((x : a) -> (forall y -> y < x -> P y) -> P x) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(z : a) -> Acc _<_  z -> P z<br />
acc-fold _<_ Φ z (acc .z h) =<br />
&nbsp;&nbsp;Φ z (\y y&lt;z -> acc-fold _<_ Φ y (h y y&lt;z))</code></p></blockquote>
<p>Its type says that if we can provide a function <code>Φ</code> that proves some property <code>P x</code> for all <code>x</code> provided that <code>P y</code> has been proved for all <code>y &lt; x</code>, then <code>P</code> holds for all accessible elements in <code>a</code>. Recall strong induction.</p>
<p>When <code>&lt;</code> is well-founded, all elements are accessible. Therefore we can define:</p>
<blockquote><p><code>rec-wf : {a : Set} {_<_ : a -> a -> Set} {P : a -> Set} -><br />
&nbsp;&nbsp;well-found _<_ -><br />
&nbsp;&nbsp;&nbsp;&nbsp;((x : a) -> ((y : a) -> y < x -> P y) -> P x) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(x : a) -> P x<br />
rec-wf {a}{_<_} wf f x = acc-fold _<_ f x (wf x) </code></p></blockquote>
<p>For an example, consider the function <code>half : ℕ -> ℕ</code> which divides a natural number by two. It can be defined by structural recursion:</p>
<blockquote><p><code>half : ℕ -> ℕ<br />
half zero = zero<br />
half (suc zero) = zer0<br />
half (suc (suc n)) = suc (half n)</code></p></blockquote>
<p>But if we define <code>half</code> by well-founded recursion anyway, it looks like:</p>
<blockquote><p><code>half : ℕ -> ℕ<br />
half = rec-wf ℕ<-wf body<br />
&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;&nbsp;body : (n : ℕ) -> ((m : ℕ) -> m <′ n -> ℕ) -> ℕ<br />
&nbsp;&nbsp;&nbsp;&nbsp;body zero rec = zero<br />
&nbsp;&nbsp;&nbsp;&nbsp;body (suc zero) rec = zero<br />
&nbsp;&nbsp;&nbsp;&nbsp;body (suc (suc n)) rec = suc (rec n (≤′-step ≤′-refl))</code></p></blockquote>
<p>Notice how <code>rec-wf ℕ<-wf</code> behaves like a fixed-point operator taking the &#8220;fixed-point&#8221; of <code>body</code>. The recursive call is replaced by a function <code>rec</code>, having type <code>(m : ℕ) -> m <′ n -> ℕ</code>. To call <code>rec</code>, the programmer has to provide a proof that the argument is indeed getting smaller with respect to the relation <code>_&lt;_</code>.</p>
<h3>Upper-Bounded Reverse Ordering</h3>
<p>As a practice, let us consider another ordering. For a given natural number <code>k</code>, define <code>n ◁ m =  m < n ≤ k</code>. That is, for <code>m</code> and <code>n</code> upper-bounded by <code>k</code>, the one closer to <code>k</code> is considered smaller. Apparently <code>◁</code> is well-founded. I tried to encode it in Agda by:</p>
<blockquote><p><code>_<_≤_ : ℕ -> ℕ -> ℕ -> Set<br />
m < n ≤ k = (m <′ n) × (n ≤′ k)</p>
<p>◁ : ℕ -> ℕ -> ℕ -> Set<br />
(◁ k) m n = n < m ≤ k</code></p></blockquote>
<p>However, the accessibility proof became very difficult to construct. I ended up defining yet another variation of the less-than-or-equal-to ordering:</p>
<blockquote><p><code>data _≤′′_ : ℕ -> ℕ -> Set where<br />
&nbsp;&nbsp;≤′′-refl : forall {n} -> n ≤′′ n<br />
&nbsp;&nbsp;≤′′-step : forall {m n} -> suc m ≤′′ n -> m ≤′′ n</code></p></blockquote>
<p>and defined <code>m < n ≤ k = (m <′′ n) × (n ≤′′ k)</code>.</p>
<p>A number of properties can be proved about <code>≤′</code>:</p>
<blockquote><p><code>m≤n⇒m≤1+n : forall {m n} -> m ≤′′ n -> m ≤′′ (suc n)<br />
m&lt;n⇒¬n≤m : forall {m n} -> m <′′ n -> ¬ (n ≤′′ m)<br />
¬[m&lt;n∧n≤m] : forall {m n} -> ¬ (m <′′ n × n ≤′′ m)<br />
≤′′-trans : forall {m n k} -> m ≤′′ n -> n ≤′′ k -> m ≤′′ k<br />
≤′′-antisym : forall {m n} -> m ≤′′ n -> n ≤′′ m -> m ≡ n</code></p></blockquote>
<p>Some of the properties above depends on the following:</p>
<blockquote><p><code> ¬1+n≤n : forall {n} -> ¬ (suc n ≤′′ n)</code></p></blockquote>
<p>which I have not yet proved.</p>
<p>Now let us show that <code>◁ k</code> is well-founded. </p>
<blockquote><p><code>ℕ◁-wf : forall k -> well-found (◁ k)<br />
ℕ◁-wf k m = acc m access<br />
&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;access : forall n -> (m < n ≤ k)  -> Acc (◁ k) n<br />
&nbsp;&nbsp;&nbsp;access n (m&lt;n , n≤k) =<br />
&nbsp;&nbsp;&nbsp;&nbsp;◁-access k m n (≤′′-trans m&lt;n n≤k) (m&lt;n , n≤k) </code></p></blockquote>
<p>The function <code>◁-access</code> needs, apart from proofs of <code>m < n</code> and <code>n ≤ k</code>, a proof of <code>m < k</code>, which can be established by transitivity of <code>≤′</code>. The definition is shown below:</p>
<blockquote><p><code>◁-access : forall k m n -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(m <′′ k) -> (m < n ≤ k) -> Acc (◁ k) n<br />
◁-access .(suc m) m .(suc m) ≤′′-refl (≤′′-refl , 1+m≤1+m) =<br />
&nbsp;&nbsp;acc (suc m)<br />
&nbsp;&nbsp;&nbsp;&nbsp;(\y 1+m&lt;y∧y≤1+m -> ⊥-elim (¬[m&lt;n∧n≤m] 1+m&lt;y∧y≤1+m))<br />
◁-access k m .(suc m) (≤′′-step 1+m&lt;k) (≤′′-refl , 1+m≤k) =<br />
&nbsp;&nbsp;acc (suc m) (\y -> ◁-access k (suc m) y 1+m&lt;k)<br />
◁-access .(suc m) m n ≤′′-refl (≤′′-step 1+m&lt;n , n≤1+m) =<br />
&nbsp;&nbsp;acc n (⊥-elim (m&lt;n⇒¬n≤m 1+m&lt;n n≤1+m))<br />
◁-access k m n (≤′′-step 1+m&lt;k) (≤′′-step 1+m&lt;n , n≤k) =<br />
&nbsp;&nbsp;◁-access k (suc m) n 1+m&lt;k (1+m&lt;n , n≤k)</code></p></blockquote>
<p>It is perhaps quite hard to understand unless you try to construct it yourself. The reader only needs to notice that in the two recursive calls to <code>◁-access</code> (in the second and the last clause), the argument <code>m</code> is incremented to <code>suc m</code>. That is why we need to include a proof term of  <code>m <′′ k</code> as an argument, which becomes structurally smaller in the recursive calls. This is how we inform the termination checker that, although <code>m</code> increases, the distance between <code>m</code> and <code>k</code> shrinks. The proof of <code>n ≤ k</code>, on the other hand, is used to establish the contradictions in the first and the third clause. </p>
<h3>A Variation of McCarthy&#8217;s 91 Function</h3>
<p>Back to the function <mi>f</mi> mentioned in the beginning, whose native Agda translation:</p>
<blockquote><p><code>f k n with k ≤? n<br />
... | yes _ = n<br />
... | no _ = f k (f k (suc n)) </code></p></blockquote>
<p>certainly does not pass the termination check.</p>
<p>In fact, the second argument (<code>n</code>) to <code>f</code> becomes smaller with respect to <code>◁ k</code>. This is obvious for the inner recursive call (<code>f k (suc n)</code>) since <code>k ≰ n</code> implies <code>n < 1 + n ≤ k</code>. To prove the termination of the outer recursive call, we have to show that <code>f k n</code> actually computes the maximum of <code>k</code> and <code>n</code>. Since <code>k ≰ n</code>, we have <code>f k (suc n) = k</code>. Therefore, <code>f k (suc n)</code> is smaller than <code>n</code> with respect to <code>◁ k</code>.</p>
<p>To prove the termination of <code>f</code> we have to prove something about its result. One of the possible ways to do so is to define:</p>
<blockquote><p><code>P : ℕ -> ℕ -> Set<br />
P k n = ∃ ℕ (\fn -> n ≤′′ k -> fn ≡ k)</code></p></blockquote>
<p>and extend the type of <code>f</code> to:</p>
<blockquote><p><code>f : (k : ℕ) -> (n : ℕ) -> P k n </code></p></blockquote>
<p>Now that <code>f</code> returns an existential type, we have to pattern math its result. A definition of <code>f</code> may look like:</p>
<blockquote><p><code>f k = rec-wf (ℕ◁-wf k) body<br />
&nbsp;where<br />
&nbsp;&nbsp;body : (i : ℕ) -> ((j : ℕ) -> i < j ≤ k -> P k j) -> P k i<br />
&nbsp;&nbsp;body n rec with (k ≤′′? n)<br />
&nbsp;&nbsp;&#8230; | inj₁ k≤n = exists n (\n≤k -> ≤′′-antisym n≤k k≤n)<br />
&nbsp;&nbsp;&#8230; | inj₂ n&lt;k with rec (1 + n) (≤′′-refl , n&lt;k)<br />
&nbsp;&nbsp;&#8230;&nbsp;&nbsp;| exists m 1+n≤k⇒m≡k with rec m (n&lt;m , m≤k)<br />
&nbsp;&nbsp;&#8230;&nbsp;&nbsp;&nbsp;&nbsp;| exists h m≤k⇒h≡k = exists h (\_ -> h≡k)<br />
&nbsp;&nbsp;&nbsp;where<br />
&nbsp;&nbsp;&nbsp;&nbsp;m≡k = 1+n≤k⇒m≡k n&lt;k<br />
&nbsp;&nbsp;&nbsp;&nbsp;n&lt;m = ≡-subst (\i -> n <′′ i) (≡-sym m≡k) n&lt;k<br />
&nbsp;&nbsp;&nbsp;&nbsp;m≤k = ≡-subst (\i -> m ≤′′ i) m≡k ≤′′-ref<br />
&nbsp;&nbsp;&nbsp;&nbsp;h≡k = m≤k⇒h≡k m≤k</code></p></blockquote>
<p>However, Agda&#8217;s scoping rule with the presence of both <code>with</code> and <code>where</code> still confuses me. Eventually I had to inline the subordinate proofs, which gives me:</p>
<blockquote><p><code>f : (k : ℕ) -> (n : ℕ) -> P k n<br />
f k = rec-wf (ℕ◁-wf k) body<br />
&nbsp;where<br />
&nbsp;&nbsp;body : (i : ℕ) -> ((j : ℕ) -> i < j ≤ k -> P k j) -> P k i<br />
&nbsp;&nbsp;body n rec with (k ≤′′? n)<br />
&nbsp;&nbsp;&#8230; | inj₁ k≤n = exists n (\n≤k -> ≤′′-antisym n≤k k≤n)<br />
&nbsp;&nbsp;&#8230; | inj₂ n&lt;k with rec (1 + n) (≤′′-refl , n&lt;k)<br />
&nbsp;&nbsp;&#8230;&nbsp;&nbsp;| exists m 1+n≤k⇒m≡k with 1+n≤k⇒m≡k n&lt;k<br />
&nbsp;&nbsp;&#8230;&nbsp;&nbsp;&nbsp;| m≡k with rec m (≡-subst (\i -> n <′′ i) (≡-sym m≡k) n&lt;k ,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;≡-subst (\i -> m ≤′′ i) m≡k ≤′′-refl)<br />
&nbsp;&nbsp;&#8230;&nbsp;&nbsp;&nbsp;&nbsp;| exists h m≤k⇒h≡k =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exists h (\_ -> m≤k⇒h≡k (≡-subst (\i -> m ≤′′ i) m≡k ≤′′-refl))</code></p></blockquote>
<p>Unfortunately it looks quite remote from the original <code>f</code>. Nevertheless, it does pass the termination checker of Agda.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/well-founded-recursion-and-accessibility/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Terminating Unfolds (2)</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-2/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-2/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 16:22:42 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Research Blog]]></category>

		<category><![CDATA[Agda]]></category>

		<category><![CDATA[Dependent Type]]></category>

		<category><![CDATA[Termination]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=49</guid>
		<description><![CDATA[After seeing <a href="http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-1/">our code</a>, <a href="http://www.cs.nott.ac.uk/~nad/">Nils Anders Danielsson</a> suggested two improvements. Firstly, to wrap the bound in the seed. Secondly, to define <code>unfoldT↓</code> using <em>well-founded recursion</em>.]]></description>
			<content:encoded><![CDATA[<p>After seeing <a href="http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-1/">our code</a>, <a href="http://www.cs.nott.ac.uk/~nad/">Nils Anders Danielsson</a> suggested two improvements. Firstly, to wrap the bound in the seed. The terminating <code>unfoldr↓</code> would thus have a simpler type as well as a simpler implemenation:</p>
<blockquote><p><code>unfoldr↓ : {a : Set}(b : ℕ -> Set){n : ℕ} -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(f : forall {i} -> b (suc i) -> ⊤ ⊎ (a × b i)) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b n -> [ a ]<br />
unfoldr↓ b {zero} f y = []<br />
unfoldr↓ b {suc i} f y with f y<br />
&#8230; | inj₁ _ = []<br />
&#8230; | inj₂ (x , y&#8217;) = unfoldr↓ b {i} f y&#8217;</code></p></blockquote>
<p>The definition passes the termination check, apparently, because <code>unfoldr↓</code> is defined inductively on <code>n</code>.</p>
<p>To generate a descending a list, one may invent a datatype <code>Wrap</code> that wraps the seed, whose bound is simply the seed itself:</p>
<blockquote><p><code>data Wrap : ℕ -> Set where<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;W : (n : ℕ) -> Wrap n</code></p></blockquote>
<p>The list may then be generated by an unfold:</p>
<blockquote><p><code>dec : forall {i} -> Wrap (suc i) -> ⊤ ⊎ (ℕ × Wrap i)<br />
dec {i} (W .(suc i)) = inj₂ (i , W i)</p>
<p>down↓ : ℕ -> [ ℕ ]<br />
down↓ n = unfoldr↓ Wrap dec (W n)<br />
</code></p></blockquote>
<p>Of course, this would defeat my original goal of reusing the non-dependently typed <code>dec</code>, which is probably a bad idea anyway.</p>
<p>To show that the bound need not be exact, let&#8217;s try to generate a descending list whose elements are decremented by 2 in each step. We may use this slightly generalised wrapper:</p>
<blockquote><p><code>data Wrap2 : ℕ -> Set where<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;W2 : (x : ℕ) -> (bnd : ℕ) -> x ≤ bnd -> Wrap2 bnd</code></p></blockquote>
<p>and a function <code>dec2</code> that decrements a <code>suc i</code>-bounded seed by 2 but showing that the new seed is bounded by <code>i</code>:</p>
<blockquote><p><code>dec2 : forall {i} -> Wrap2 (suc i) -> ⊤ ⊎ (ℕ × WAlt i)<br />
dec2 {i} (W2 0 .(1 + i) _) = inj₁ tt<br />
dec2 {i} (W2 1 .(1 + i) _) = inj₁ tt<br />
dec2 {i} (W2 (suc (suc n)) .(1 + i) 2+n≤1+i) =<br />
&nbsp;&nbsp;&nbsp; inj₂ (n , W2 n i (suc-≤-weaken-l (≤-pred 2+n≤1+i)))<br />
</code></p></blockquote>
<p>The list can then be unfolded by:</p>
<blockquote><p><code>down↓2 : ℕ -> [ ℕ ]<br />
down↓2 n = unfoldr↓ Wrap2 dec2 (W2 n n ≤-refl)</code></p></blockquote>
<p>where <code>suc-≤-weaken-l</code> is a proof of <code>forall {m n} -> suc m ≤ n -> m ≤ n</code>.</p>
<h3>Unfolding a Tree</h3>
<p>It is an easy exercise to come up with a tree version of the unfold above:</p>
<blockquote><p><code>unfoldT↓ : {a : Set}(b : ℕ -> Set){n : ℕ} -><br />
&nbsp;&nbsp;(f : forall {i} -> b (suc i) -> a ⊎ (b i × b i)) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;B n -> Tree a<br />
unfoldT↓ b {0} f y = Nul<br />
unfoldT↓ b {suc i} f y with f y<br />
... | inj₁ x = Tip x<br />
... | inj₂ (y₁ , y₂) =<br />
&nbsp;&nbsp;&nbsp;&nbsp;Bin (unfoldT↓ b {i} f y₁) (unfoldT↓ b {i} f y₂)</code></p></blockquote>
<p>To deal with the second task of building a roughly balanced binary tree, one may try this wrapper:</p>
<blockquote><p><code>data Split (a : Set): ℕ -> Set where<br />
&nbsp;&nbsp;Sp : (xs : [ a ]) -> (bnd : ℕ) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;length xs < bnd -> Split a bnd</code></p></blockquote>
<p>and try to code up a generator function <code>split↓</code> having this type:</p>
<blockquote><p><code>split↓ : forall {a i} -> Split a (suc i) ->  a ⊎ (Split a i × Split a i)<br />
</code></p></blockquote>
<p>The function <code>split↓</code> I eventually come up with, however, is much more complicated than I had wished. Even worse, it is now <code>split↓</code> that fails to pass the termination check.</p>
<p><a href="http://www.cs.chalmers.se/~ulfn/">Ulf Norell</a> suggested some possible fixes. The difficulties, however, is probably a hint that there is something wrong in my approach in the first place. Rather than trying to fix it, Nils Anders showed me how he would tackle the problem from the beginning.</p>
<h3>Using Well-Founded Recursion</h3>
<p>Nils Anders showed me how to define <code>unfoldT↓</code> using <em>well-founded recursion</em>. For a simplified explanation, the <a href="http://appserv.cs.chalmers.se/users/ulfn/wiki/agda.php?n=Libraries.StandardLibrary">Standard Library</a> provides a function <code><-rec</code> having type (after normalisation):</p>
<blockquote><p><code><-rec : (P : ℕ -> Set) -><br />
&nbsp;&nbsp;(f : (i : ℕ) -> (rec : (j : ℕ) -> j <′ i -> P j) -> P i) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(x : ℕ) -> P x </code></p></blockquote>
<p>With <code><-rec</code> one can define functions on natural numbers by recursion, provided that the argument strictly decreases in each recursive call. <code>P</code> is the type of the result, parameterised by the input. The function <code>f</code> is a template that specifies the body of the recursion which, given <code>i</code>, computes some result of type <code>P i</code>. The functional argument <code>rec</code> is supposed to be the recursive call. The constraint <code>j <′ i</code>, however, guarantees that it accepts only inputs strictly smaller than <code>i</code> (the ordering <code><′ </code> is a variation of <code>&lt;</code> that is more suitable for this purpose). One may perhaps think of <code><-rec</code> as a fixed-point operator computing the fixed-point of <code>f</code>, only that <code>f</code> has to take <code>i</code> before <code>rec</code> because the latter depends on the former.</p>
<p>Let us try to define an unfold on trees using <code><-rec</code>. The &#8220;base-functor&#8221; of the datatype <code>Tree⁺ a</code> is <code>F b = a ⊎ b × b</code>. One of the lessons we have learnt is that it would be more convenient for the generating function to return the bound information. We could use a type like this:</p>
<blockquote><p><code>F a b k = a ⊎ ∃ (ℕ × ℕ) (\(i , j) -> b i × b j × i <′ k × j <′ k)</code>
</p></blockquote>
<p>But it is perhaps more reader-friendly to define the base functor as a datatype:</p>
<blockquote><p><code>data Tree⁺F (a : Set) (b : ℕ -> Set) : ℕ -> Set where<br />
&nbsp;&nbsp;tip : forall {k} -> a -> Tree⁺F a b k<br />
&nbsp;&nbsp;bin : forall {i j k} -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b i -> b j -> i <′ k -> j <′ k -> Tree⁺F a b k<br />
</code></p></blockquote>
<p>The generating function for the unfold should thus have type <code>forall {a b i} -> b i -> Tree⁺F a b i</code>.</p>
<p>The function <code>unfoldT↓F</code> is the template for <code>unfoldT↓</code>:</p>
<blockquote><p><code>unfoldT↓F : {a : Set} {b : ℕ -> Set} -><br />
&nbsp;&nbsp;(f : forall {i} -> b i -> Tree⁺F a b i) -><br />
&nbsp;&nbsp;&nbsp;(n : ℕ) -> ((i : ℕ) -> i <′ n -> b i -> Tree⁺ a) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;b n -> Tree⁺ a<br />
unfoldT↓F f n rec y with f y<br />
&#8230; | tip a = Tip⁺ a<br />
&#8230; | bin {i} {j} y₁ y₂ i&lt;n j&lt;n =<br />
&nbsp;&nbsp;&nbsp;&nbsp;Bin⁺ (rec i i&lt;n y₁) (rec j j&lt;n y₂)<br />
</code></p></blockquote>
<p>Now <code>unfoldT↓</code> can be defined by:</p>
<blockquote><p><code>unfoldT↓ : {a : Set} {b : ℕ -> Set} -><br />
&nbsp;&nbsp;(f : forall {i} -> b i -> Tree⁺F a b i) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;forall {n} -> b n -> Tree⁺ a<br />
unfoldT↓ {a}{b} f {n} y =<br />
&nbsp;&nbsp;&nbsp;&nbsp;<-rec (\n -> b n -> Tree⁺ a) (unfoldT↓F f) n y </code></p></blockquote>
<p>All the definition above makes no recursive calls. All the tricks getting us through the termination check are hidden in <code><-rec</code>. How is it defined?</p>
<h3>Well-Founded Recursion Defined on <′</h3>
<p>Currently, well-founded recursion are defined in <code>Induction</code> and its sub-modules. They are very interesting modules to study. The definitions there, however, are very abstract. To understand how <code><-rec</code> works, let&#8217;s try to implement our own.</p>
<p>This is the definition of <code><′</code> from <code>Data.Nat</code>:</p>
<blockquote><p><code>data _≤′_ : Rel ℕ where<br />
  ≤′-refl : forall {n} -> n ≤′ n<br />
  ≤′-step : forall {m n} -> m ≤′ n -> m ≤′ suc n</p>
<p>_<′_ : Rel ℕ<br />
m <′ n = suc m ≤′ n</code></p></blockquote>
<p>Recall that the recursion template <code>f</code> has type <code>forall i -> (forall j -> j <′ i -> P j) -> P i</code>. That is, given <code>i</code>, <code>f</code> computes <code>P i</code>, provided that we know of a method to compute <code>P j</code> for all <code>j <′ i</code>. Let us try to construct such a method using <code>f</code>. The function <code> guard f i</code> computes <code>f</code>, provided that the input is strictly smaller than <code>i</code>:</p>
<blockquote><p><code>guard : {P : ℕ -> Set} -><br />
&nbsp;&nbsp;&nbsp;(forall i -> (forall j -> j <′ i -> P j) -> P i) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;forall i -> forall j -> j <′ i -> P j<br />
guard f zero _ ()<br />
guard f .(suc j) j ≤′-refl = f j (guard f j)<br />
guard f (suc i) j (≤′-step j&lt;i) = guard f i j j&lt;i </code></p></blockquote>
<p>Observe that <code>guard</code> terminates because it is defined inductively on <code>i</code>. If we discard the type information, all what <code>guard f i j</code> is to make a call to <code>f j</code>. Before doing so, however, it checks through the proof to make sure that <code>j</code> is strictly smaller than <code>i</code>. In <code>f j (guard f j)</code>, the call to <code>guard f j</code> ensures that subsequent calls to <code>f</code> are given arguments smaller than <code>j</code>.</p>
<p>Now <code><-rec</code> can be defined by:</p>
<blockquote><p><code><-rec : (P : ℕ -> Set) -><br />
&nbsp;&nbsp;&nbsp;(forall i -> (forall j -> j <′ i -> P j) -> P i) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;forall n -> P n<br />
<-rec P f n = f n (guard f n)</code></p></blockquote>
<p>In <code>Induction.Nat</code>, <code><-rec</code> is an instance of well-founded recursion defined using the concept of <em>accessibility</em>, defined in <code>Induction.WellFounded</code>. I find them very interesting modules about which I hope to understand more.</p>
<p><strong>To be continued&#8230;</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Terminating Unfolds (1)</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-1/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-1/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 03:32:44 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Research Blog]]></category>

		<category><![CDATA[Agda]]></category>

		<category><![CDATA[Dependent Type]]></category>

		<category><![CDATA[Termination]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/?p=48</guid>
		<description><![CDATA[I hope to come up with a variation of unfoldr which, given a proof of well-foundedness, somehow passes the termination check.]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.iis.sinica.edu.tw/~scm/2008/aopa/"><strong>AoPA</strong>(Algebra of Programming in Agda)</a> library allows one to derive programs in a style resembling that in the book <a href="http://portal.acm.org/citation.cfm?id=248932">Algebra of Programming</a> in Agda. For example, the following is a derivation of insertion sort:</p>
<blockquote><p><code>sort-der : ∃ ([ Val ] -> [ Val ]) (\f -> ordered? ○ permute ⊒ fun f )<br />
sort-der = exists (<br />
&nbsp;&nbsp;⊒-begin<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ordered? ○ permute<br />
&nbsp;&nbsp;⊒⟨ (\vs -> ·-monotonic ordered? (permute-is-fold vs)) ⟩<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ordered? ○ foldR combine nil<br />
&nbsp;&nbsp;⊒⟨ foldR-fusion ordered? ins-step ins-base ⟩<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foldR (fun (uncurry insert)) nil<br />
&nbsp;&nbsp;⊒⟨  foldR-to-foldr insert []  ⟩<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fun (foldr insert [])<br />
&nbsp;&nbsp;⊒∎)</p>
<p>isort : [ Val ] -> [ Val ]<br />
isort = witness sort-der<br />
</code></p></blockquote>
<p>The type of <code>sort-der</code> is a proposition that there exists a program of type <code>[ Val ] → [ Val ]</code> that is contained in <code>ordered ? ◦ permute</code>, a relation mapping a list to one of its ordered permutations. The combinator <code>fun</code> embeds a function in a relation. Relations on each line are related by relational inclusion (<code>⊒</code>), while the proof of inclusion are given in angle brackets. In the final step, the relation <code>foldR (fun (uncurry insert)) nil</code> is refined to a function using the rule:</p>
<blockquote><p><code>foldR-to-foldr : {A B : Set} -> (f : A -> B -> B) -> (e : B) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;foldR (fun (uncurry f)) (singleton e) ⊒ fun (foldr f e)<br />
</code></p></blockquote>
<p>which says that a relational fold is a functional fold if the algebra (<code>f</code>) is a function. When the proof is completed, an algorithm <code>isort</code> is obtained by extracting the witness of the proposition. It is an executable program that is backed by the type system to meet the speciﬁcation.</p>
<p>One may wonder: why insertion sort, rather than something more interesting such as mergesort or quicksort? Because we have not yet figured out how to properly deal with hylomorphism yet. One of the things still missing in AoPA is a treatment of unfolds. AoPA attempts to model the category of sets and relations. In this context one can talk about unfolds because they are  simply the converses of folds. We perform the derivations in terms of folds, and refine the converse of a relational fold to a functional unfold provided that the coalgebra is a function:</p>
<blockquote><p><code>foldR˘-to-unfoldr : {A B : Set} -> (f : B -> ⊤ ⊎ (A × B)) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(foldR ((fun f) ˘ ○ (fun inj₂)) (\b -> isInj₁ (f b))) ˘ ⊒ fun (unfoldr f)<br />
</code></p></blockquote>
<p>where <code>˘</code> denotes relational converse and <code>unfoldr</code> is given by the usual definition (one that a Haskell programmer would expect, modulo syntax):</p>
<blockquote><p><code>unfoldr : {A B : Set} -> (B -> ⊤ ⊎ (A × B)) -> B -> [ A ]<br />
unfoldr f b with f b<br />
&#8230; | inj₁ _ = []<br />
&#8230; | inj₂ (a , b&#8217;) = a ∷ unfoldr f b&#8217;</code></p></blockquote>
<p>The only problem is that this <code>unfoldr</code> cannot pass the termination check of Agda.</p>
<p>My first thought was to wait until Agda supports codata and coinduction. However, the reason I wanted an unfold in AoPA in the first place was to compose it with a fold to form a hylomorphism, which is not allowed if the unfold returns codata. I then attempted to model unfolds in a way similar to what we did in relational program derivation. We know that the recursive equation:</p>
<blockquote><math>R = S ○ <strong>F</strong>R ○ T<br />
<math></blockquote>
<p>has a unique solution <mi>R = ⦇S⦈ ○ ⦇T⦈˘</mi> if and only if <mi>T</mi> is well-founded. In program derivation, the proof of well-foundedness is usually given separately. Therefore I hope to come up with a variation of <code>unfoldr</code> which, given a proof of well-foundedness, somehow passes the termination check.</p>
<p>During <a href="http://sneezy.cs.nott.ac.uk/darcs/DTP08/">DTP 2008</a>, I consulted a number of people and was suggested at least three solutions. I am going to summarise them in turn.</p>
<h3>Canonical Examples</h3>
<p>With each approach I would like to tackle two tasks. Given the following function <code>dec</code>:</p>
<blockquote><p><code>dec : ℕ -> ⊤ ⊎ (ℕ × ℕ)<br />
dec zero = inj₁ tt<br />
dec (suc n) = inj₂ (n , n)</code></p></blockquote>
<p>One may attempt to define a function <code>down</code> using <code>unfoldr</code> such that <code>down n</code> produces a list from <code>n</code> to <code>0</code>. As mentioned above, <code>unfoldr</code> cannot pass the termination check. In fact, even the following definition fails the termination check:</p>
<blockquote><p><code>down : ℕ -> [ ℕ ]<br />
down n with dec n<br />
&#8230; | inj₁ _ = []<br />
&#8230; | inj₂ (a , n&#8217;) with down n&#8217;<br />
&#8230;&nbsp;&nbsp;&nbsp;&nbsp;| x = a ∷ x</code></p></blockquote>
<p>The first task is to define <code>down</code> using some kind of unfold. </p>
<p>In the second tasks, given a non-empty list, we would like to distribute its elements to a roughly balanced binary tree. The list and the tree are define by:</p>
<blockquote><p><code>data List⁺ (a : Set) : Set where<br />
&nbsp;&nbsp;&nbsp;&nbsp;[_]⁺ : a -> List⁺ a<br />
&nbsp;&nbsp;&nbsp;&nbsp;_∷⁺_ : a -> List⁺ a -> List⁺ a<br />
data Tree⁺ (a : Set) : Set where<br />
&nbsp;&nbsp;&nbsp;&nbsp;Tip⁺ : a -> Tree⁺ a<br />
&nbsp;&nbsp;&nbsp;&nbsp;Bin⁺ : Tree⁺ a -> Tree⁺ a -> Tree⁺ a</code></p></blockquote>
<p>If we apply, for example, <code>foldT merge wrap</code>, we get merge sort (I use non-empty lists to save the constructor for empty trees). In Haskell, one might first define a function that splits a list to roughly two halfs, something equivalent to this:</p>
<blockquote><p><code>split⁺ : {a : Set} -> List⁺ a -> a ⊎ (List⁺ a × List⁺ a)<br />
split⁺ [ x ]⁺ = inj₁ x<br />
split⁺ (x ∷⁺ xs) with split⁺ xs<br />
&#8230; | inj₁ y = inj₂ ([ y ]⁺ , [ x ]⁺)<br />
&#8230; | inj₂ (ys , zs) = inj₂ (zs , x ∷⁺ ys)</code></p></blockquote>
<p>and use an unfold on <code>Tree⁺</code>. The second task is to construct a function <code>expand : {a : Set} -> List⁺ a -> Tree⁺ a</code> that builds a roughly balanced tree, using some kind of unfold that makes use of <code>split⁺</code>, or at least some variation of it.</p>
<h3>Josh Ko&#8217;s Approach</h3>
<p><a href="http://joshkos.blogspot.com/">Josh</a> and I tried to extend unfolds with extra arguments representing a bound and proofs that the bound decreases with each call to <code>f</code>:</p>
<blockquote><p><code>unfoldr↓ : {a b : Set} {_≾_ : b -> ℕ -> Set} -><br />
&nbsp;&nbsp;(f : b -> ⊤ ⊎ (a × b)) -> (y : b) -> (t : ℕ) -><br />
&nbsp;&nbsp;y ≾ t -> (forall {y} -> y ≾ zero -> f y ≡ inj₁ tt) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(forall {y} t' {x y'} -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y ≾ suc t' -> f y ≡ inj₂ (x , y') -> y' ≾ t')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-> [ a ]</code></p></blockquote>
<p>Apart from the generating function <code>f</code> and the seed <code>b</code>, the function <code>unfoldr↓</code> takes a bound <code>t</code>, a natural number. The seed and the bound is related by <code>≾</code>, to be defined for each specific problem. Before producing the list, <code>unfoldr↓</code> demands that the current seed is bounded by the bound (<code>y ≾ t</code>), a proof that <code>f</code> must yield <code>inj₁</code> when the bound is <code>zero</code>, and a proof that if <code>f</code> returns <code>inj₂ (x , y')</code>, the new seed <code>y'</code> is bounded by a strictly smaller bound.</p>
<p>To define <code>unfoldr↓</code> we need the inspect idiom (see the explanation in <code>Relation.Binary.PropositionalEquality</code>):</p>
<blockquote><p><code>unfoldr↓ f y t y≾t p1 p2 with inspect (f y)<br />
... | (inj₁ tt) with-≡ inj₁≡fy = []<br />
&#8230; | (inj₂ (x , y&#8217;)) with-≡ inj₂≡fy with t<br />
&#8230;&nbsp;&nbsp;| zero    = contradiction (p1 y≾t)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(\fy≡inj₁ -> inj₁≢inj₂ (≡-sym (≡-trans inj₂≡fy fy≡inj₁)))<br />
&#8230;&nbsp;&nbsp;| suc t&#8217;  = x ∷ unfoldr↓ f y&#8217; t&#8217;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(p2 t&#8217; y≾t (≡-sym inj₂≡fy)) p1 p2</code></p></blockquote>
<p>Notice that <code>unfoldr↓</code> passes the termination check because it pattern matches on <code>t</code>.</p>
<h4>Descending List</h4>
<p>For the first task, the seed is a natural number, and we may simply define <code>≾</code> to be <code>≤</code>:</p>
<blockquote><p><code>_≾_ : ℕ -> ℕ -> Set<br />
n ≾ c = n ≤ c</code></p></blockquote>
<p>Then <code>down↓</code> can be defined in terms of  <code>unfoldr↓</code> and <code>dec</code> by:</p>
<blockquote><p><code>stop : forall {n} -> n ≾ zero -> dec n ≡ inj₁ tt<br />
stop {.zero} z≤n = ≡-refl</p>
<p>proceed : forall {n} c' {x n'} -> n ≾ suc c' -> dec n ≡ inj₂ (x , n') -> n' ≾ c'<br />
proceed {.zero} c' {x} {n'} z≤n dec-zero≡inj₂ = contradiction dec-zero≡inj₂ inj₁≢inj₂<br />
proceed {suc m} c' {.m} {.m} (s≤s m≤c') ≡-refl = m≤c'</p>
<p>down↓ : ℕ -> [ ℕ ]<br />
down↓ n = unfoldr↓ dec n n ≤-refl stop proceed</code></p></blockquote>
<p>where <code>≤-refl : forall x -> x ≤ x</code>.</p>
<h4>Expanding a Binary Tree</h4>
<p>The unfold above can be generalised to trees in the obvious way:</p>
<blockquote><p><code>unfoldT↓ : {a b : Set} {_≼_ : b -> ℕ -> Set} -><br />
&nbsp;&nbsp;(f : b -> a ⊎ b × b) -> (y : b) ->  (n : ℕ) -><br />
&nbsp;&nbsp;&nbsp;y ≼ n -> (forall y -> y ≼ zero -> ∃ a (\x -> f y ≡ inj₁ x)) -><br />
&nbsp;&nbsp;&nbsp;&nbsp;(forall y i y₁ y₂ -><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y ≼ suc i -> f y ≡ inj₂ (y₁ , y₂) -> (y₁ ≼ i × y₂ ≼ i))<br />
&nbsp;&nbsp;&nbsp;&nbsp;-> Tree⁺ a<br />
unfoldT↓ f y n y≼n p₁ p₂ with inspect (f y)<br />
... | inj₁ x with-≡ _ = Tip⁺ x<br />
... | inj₂ (y₁ , y₂) with-≡ inj₂≡fy  with n<br />
...&nbsp;&nbsp;| zero   = contradiction (proof (p₁ y y≼n))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(\fy≡inj₁ -> inj₁≢inj₂ (≡-sym (≡-trans inj₂≡fy fy≡inj₁)))<br />
...&nbsp;&nbsp;| suc m  with p₂ y m y₁ y₂ y≼n (≡-sym inj₂≡fy)<br />
...&nbsp;&nbsp;&nbsp;&nbsp;| (y₁≼m , y₂≼m) = Bin⁺ (unfoldT↓ f y₁ m y₁≼m p₁ p₂)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(unfoldT↓ f y₂ m y₂≼m p₁ p₂)</code></p></blockquote>
<p>One would wonder whether the condition <code>(y₁ ≼ i × y₂ ≼ i)</code> is too restrictive. When the proposition has to be proved inductively, we may need a stronger inductive hypothesis, for example, that both <code>y₁</code> and <code>y₂</code> are bounded by half of <code>suc i</code>. The current definition luckily works for our second task. We may need some generalisation later.</p>
<p>Repeated calls to <code>split⁺</code> eventually terminates because the lengths of the lists are strictly decreasing. Therefore we define:</p>
<blockquote><p><code>_#≤_ : {A : Set} -> List⁺ A -> ℕ -> Set<br />
xs #≤ n = pred (length⁺ xs) ≤ n</code></p></blockquote>
<p>With properly defined <code>lemma1</code> and <code>lemma2</code>, we can expand the tree by <code>unfoldT↓</code>:</p>
<blockquote><p><code>expand↓ : {a : Set} -> List⁺ a -> Tree⁺ a<br />
expand↓ {a} xs = unfoldT↓ {a} {List⁺ a} {_#≤_} split⁺ xs<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pred (length⁺ xs)) ≤-refl lemma1 lemma2</code></p></blockquote>
<p>where the two lemmas respectively have types:</p>
<blockquote><p><code>lemma1 : {a : Set}(xs : List⁺ a) -><br />
&nbsp;&nbsp;&nbsp;xs #≤ zero -> ∃ a (\x -> split⁺ xs ≡ inj₁ x)<br />
lemma2 : {a : Set} (xs : List⁺ a) (i : ℕ)<br />
&nbsp;&nbsp;(ys : List⁺ a) (zs : List⁺ a) -><br />
&nbsp;&nbsp;xs #≤ suc i -> split⁺ xs ≡ inj₂ (ys , zs) -> ys #≤ i × zs #≤ i</code></p></blockquote>
<p>Definition of <code>lemma1</code> is a simple application of <code>contradiction</code>. On the other hand, <code>lemma2</code> is <strong>very</strong> tedious to define. It appears to me that the definition inevitably becomes cumbersome because <code>split⁺</code> and <code>lemma2</code> are defined separately. It could be much easier if <code>split⁺</code> is defined to return the computed results as well as some proofs about them. For my application in AoPA, however, I would prefer to be able to reuse the old <code>split⁺</code>. I don&#8217;t know a good solution yet.</p>
<p><a href="http://www.cs.nott.ac.uk/~nad/">Nils Anders Danielsson</a> suggested that it would be nicer to integrate the bound into the type of the seed, while <a href="http://strictlypositive.org/">Conor McBride</a> suggested yet another approach. I will try to summarise them next time.</p>
<p><strong>To be continued&#8230;</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/terminating-unfolds-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>AoPA &#8212; Algebra of Programming in Agda</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/aopa/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/aopa/#comments</comments>
		<pubDate>Sat, 29 Mar 2008 16:20:08 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Software]]></category>

		<category><![CDATA[Agda]]></category>

		<category><![CDATA[Dependent Type]]></category>

		<category><![CDATA[Program Derivation]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/2008/derivation-carry-code-using-agda/</guid>
		<description><![CDATA[The <strong>AoPA</strong> library allows one to encode <a href="http://portal.acm.org/citation.cfm?id=248932">Algebra of Programming</a> style program derivation, both functional and relational, in <a href="http://appserv.cs.chalmers.se/users/ulfn/wiki/agda.php">Agda</a>, accompanying the paper <a href="http://www.iis.sinica.edu.tw/~scm/2008/algebra-of-programming-using-dependent-types/">Algebra of Programming Using Dependent Types</a> (<a href="http://mpc08.lri.fr/">MPC 2008</a>) developed in co-operation with <a href="http://joshkos.blogspot.com/">Hsiang-Shang Ko</a> and <a href="http://www.cs.chalmers.se/~patrikj/">Patrik Jansson</a>. ]]></description>
			<content:encoded><![CDATA[<p>An <a href="http://appserv.cs.chalmers.se/users/ulfn/wiki/agda.php">Agda</a> library accompanying the paper <a href="http://www.iis.sinica.edu.tw/~scm/2008/algebra-of-programming-using-dependent-types/">Algebra of Programming Using Dependent Types</a> (<a href="http://mpc08.lri.fr/">MPC 2008</a>) developed in co-operation with <a href="http://joshkos.blogspot.com/">Hsiang-Shang Ko</a> and <a href="http://www.cs.chalmers.se/~patrikj/">Patrik Jansson</a>. </p>
<p>Dependent type theory is rich enough to express that a program satisfies an input/output relational specification, but it could be hard to construct the proof term. On the other hand, <em>squiggolists</em> know very well how to show that one relation is included in another by algebraic reasoning. The <strong>AoPA</strong> library allows one to encode <a href="http://portal.acm.org/citation.cfm?id=248932">Algebra of Programming</a> style program derivation, both functional and relational, in Agda. </p>
<h3>Example</h3>
<p>The following is a derivation of insertion sort in progress:</p>
<blockquote><p><code>sort-der : ∃ ([ Val ] -> [ Val ]) (\f -> ordered? ○ permute ⊒ fun f )<br />
sort-der = exists (<br />
&nbsp;&nbsp;⊒-begin<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ordered? ○ permute<br />
&nbsp;&nbsp;⊒⟨ (\vs -> ·-monotonic ordered? (permute-is-fold vs)) ⟩<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ordered? ○ foldR combine nil<br />
&nbsp;&nbsp;⊒⟨ foldR-fusion ordered? ins-step ins-base ⟩<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foldR (fun (uncurry insert)) nil<br />
&nbsp;&nbsp;⊒⟨ <span style="background-color: #ccc">{ foldR-to-foldr insert []}0</span> ⟩<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color: #ccc">{ fun (foldr insert [])</span><br />
&nbsp;&nbsp;<span style="background-color: #ccc">⊒∎ }1</span>)</p>
<p>isort : [ Val ] -> [ Val ]<br />
isort = witness sort-der<br />
</code></p></blockquote>
<p>The type of <code>sort-der</code> is a proposition that there exists a program of type <code>[ Val ] → [ Val ]</code>that is contained in <code>ordered ? ◦ permute</code> , a relation mapping a list to one of its ordered permutations. The proof proceeds by derivation from the speciﬁcation towards the algorithm. The ﬁrst step exploits monotonicity of <code>◦</code> and that <code>permute</code> can be expressed as a fold. The second step makes use of relational fold fusion. The shaded areas denote interaction points — fragments of (proof ) code to be completed. The programmer can query Agda for the expected type and the context of the shaded expression. When the proof is completed, an algorithm <code>isort</code> is obtained by extracting the witness of the proposition. It is an executable program that is backed by the type system to meet the speciﬁcation.</p>
<p>The complete program is in the Example directory of the code.</p>
<h3>The Code</h3>
<p>The code consists of the following files and folders:</p>
<ul>
<li><strong>AlgebraicReasoning</strong>: a number of modules supporting algebraic reasoning. At present we implement our own because the <code>PreorderReasoning</code> module in earlier versions of the <a href="http://appserv.cs.chalmers.se/users/ulfn/wiki/agda.php?n=Libraries.StandardLibrary">Standard Library</a> was not expressive enough for our need. We may adapt to the new Standard Library later.</li>
<li><strong>ConvFunThm</strong>: the <a href="http://www.iis.sinica.edu.tw/~scm/tag/converse-of-a-function-theorem/">converse-of-a-function theorem</a>.</li>
<li><strong>Examples</strong>: currently we have prepared two examples: a functional derivation of the maximum segment sum problem, and a relational derivation of insertion sort (following the paper <a href="http://portal.acm.org/citation.cfm?coll=GUIDE&#038;dl=GUIDE&#038;id=227829">Functional Algorithm Design</a> by Richard Bird).</li>
<li><strong>Fold</strong>: a key module defining fold on lists, universal property of fold, fold-fusion theorem, etc.</li>
<li><strong>Relations</strong>: modules defining various properties of relations.</li>
<li><strong>Sets</strong>: a simple encoding of sets, upon with <strong>Relations</strong> are built.</li>
</ul>
<p>The module <strong>Unfold</strong> is not yet complete.</p>
<h3>Download</h3>
<p>The library is still under development. To grab the latest code, install <a href="http://darcs.net/">darcs</a> and check our the code from the repository:</p>
<blockquote><p><code>darcs get http://pc-scm.iis.sinica.edu.tw/repos/AoPA<br />
</code></p></blockquote>
<p>A <a href="http://www.iis.sinica.edu.tw/~scm/sw/2008/AoPA.tar.gz">gzipped tarball</a> of the latest stable release is also available.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/aopa/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Constructing List Homomorphism from Left and Right Folds</title>
		<link>http://www.iis.sinica.edu.tw/~scm/2008/constructing-list-homomorphism/</link>
		<comments>http://www.iis.sinica.edu.tw/~scm/2008/constructing-list-homomorphism/#comments</comments>
		<pubDate>Sat, 09 Feb 2008 16:56:45 +0000</pubDate>
		<dc:creator>Shin</dc:creator>
		
		<category><![CDATA[Research Blog]]></category>

		<category><![CDATA[List Homomorphism]]></category>

		<category><![CDATA[Program Derivation]]></category>

		<guid isPermaLink="false">http://www.iis.sinica.edu.tw/~scm/2008/constructing-list-homomorphism-from-left-and-right-folds/</guid>
		<description><![CDATA[Back in 2003, my colleagues there were discussing about <a href="http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#thirdht">the third homomorphism theorem</a> --- if a function <mi>f</mi> can be expressed both as a <mi>foldr</mi> and a <mi>foldl</mi>, there exists some associative binary operator <mi>⊚</mi> such that <mi>f</mi> can be computed from the middle. The aim was to automatically construct <mi>⊚</mi>.]]></description>
			<content:encoded><![CDATA[<p>Since <a href="http://joshkos.blogspot.com/2008/02/scm.html">Josh has already mentioned it</a>, I had better give it a full account.</p>
<p>Back in 2003 when I just started my postdoc in <a href="http://www.psdlab.org/e/index.html">PSD Lab</a> in University of Tokyo, my colleagues there were discussing about <a href="http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#thirdht">the third homomorphism theorem</a>. The theorem says that if a function <mi>f</mi> can be expressed both as a <mi>foldr</mi> and a <mi>foldl</mi>:</p>
<blockquote><math>
f = foldr (≪) e<br />
f = foldl (≫) e<br />
</math>
</blockquote>
<p>there exists some associative binary operator <mi>⊚</mi> such that</p>
<blockquote><math>
  f [] = e<br />
  f [a] = a ≪ e = e ≫ a<br />
  f (xs ⧺ ys) = f xs ⊚ f ys<br />
</math>
</blockquote>
<p>Being a list homomorphism implies the potential of parallel computation.</p>
<p>The paper we studied was, of course, <a href="http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#thirdht">The Thrid Homomorphism Theorem</a> by <a href="http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/">Jeremy</a>. The aim then was to automatically, or semi-automatically, derive <mi>⊚</mi>, given <mi>≪</mi>, <mi>≫</mi>, and <mi>e</mi>. The motivating examples include:</p>
<ul>
<li><mi>f = sum</mi>, where <mi>⊚</mi> can simply be <mi>+</mi>.</li>
<li><mi>f = sort</mi>, where <mi>⊚</mi> can be the function <mi>merge</mi> merging two sorted lists.</li>
<li><mi>f = scanr ⊛ e</mi>. While <mi>scanr</mi> appears to be an inherently sequential function, it is actually possible to compute <mi>f</mi> &#8220;from the middle&#8221;, provided that <mi>⊛</mi> is associative, if we take <mi>xs ⊚ (y : ys) = map (⊛y) xs ⧺ (y : ys)</mi>.</li>
</ul>
<p>Can we come up with a method to derive <mi>⊚</mi> for all these examples?</p>
<p>I myself was not particularly interested in automation. I was interested in the challenge for two reasons. Firstly, it appears that some kind of inverse function is needed. Secondly, when I looked at Jeremy&#8217;s proof, I felt there is a relational proof inside waiting to be discovered. So I tried.</p>
<h3>Setting the Stage</h3>
<p>For the ease of point-free calculation, we define alternatives of folds where the input is paired with the base-cases:</p>
<blockquote><math>
foldrp (≪) ([],a) = a<br />
foldrp (≪) (x:xs,a) = x ≪ foldrp (≪) (xs,a)<br />
foldlp (≫) (a,[]) = a<br />
foldlp (≫) (a, xs⧺[x]) = foldlp (≫) (a,xs) ≫ x<br />
</math>
</blockquote>
<p>The advantage is that we can shift a suffix or a prefix of the input list to the base case. That is:</p>
<blockquote><math>
foldr (≪) e (xs⧺ys) = foldrp≪ (xs, foldr≪ e ys)<br />
foldl (≫) e (xs⧺ys) = foldlp≪ (foldlp≪ e xs, ys)<br />
</math>
</blockquote>
<p>or, in point-free style:</p>
<blockquote><math>
foldr (≪) e . cat = foldrp (≪) . (id × foldr (≪) e)   <span style="float:right">(1)</span><br />
foldl (≫) e . cat = foldlp (≫) . (foldlp (≫)  e × id)  <span style="float:right">(2)</span><br />
</math>
</blockquote>
<p>where <mi>cat (xs,ys) = xs ⧺ ys</mi> and <mi>(f × g) (a,b) = (f a, g b)</mi>.</p>
<p>The key property, however, is one that was shown in (possibly among other literature) <a href="http://portal.acm.org/citation.cfm?id=248932">Algebra of Programming</a>: for a simple relation (i.e. a partial function) <mi>S</mi>, we have:</p>
<blockquote><math>
S . S° . S = S<br />
</math>
</blockquote>
<p>where <mi>°</mi> stands for relational converse (the relational concept of an &#8220;inverse function&#8221;).</p>
<p>Recall our aim: given <mi>f</mi>, look for <mi>⊚</mi> such that <mi>f xs ⊚ f ys = f (xs⧺ys)</mi>. It translates to point-free style as <mi>⊚ . (f × f) = f . cat</mi>.</p>
<h3>Proving the Theorem</h3>
<p>The third homomorphism theorem is a direct corollary of the following lemma:</p>
<blockquote><p>
Lemma 1: <mi>f = foldr (≪) e = f = foldl (≫) e</mi> implies that <mi>f</mi> is prefix and postfix insensitive. That is:</p>
<blockquote><math>f xs = f xs’ ∧ f ys = f ys’ ⇒ f (xs⧺ys) = f (xs’⧺ys’).</math>
</blockquote>
<p>In point-free style: <mi>f . cat . (f°. f × f°. f) = f . cat</mi>.
</p></blockquote>
<p>Once we have the lemma proved, the theorem follows by taking <mi>⊚ = f . cat . (f °× f °)</mi>. It has to be a (partial) function because <mi>⊚ . (f × f) = f . cat</mi> is a function. Futhermore, <mi>⊚</mi> is associative because <mi>cat</mi> is.</p>
<p>The proof of Lemma 1 is simply some applications of (1), (2), and <mi>S . S° . S = S</mi>:</p>
<blockquote><math>
&nbsp;&nbsp;&nbsp;&nbsp; f . cat<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (1) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp; foldrp (≪) . (id × f)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ since <mi>f . f° . f = f</mi> }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp; foldrp (≪) . (id × f) . (id × f° . f)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (1) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp; f . cat . (id × f° . f)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (2) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp; foldlp (≫) . (f × id) . (id × f° . f)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ since <mi>f . f° . f = f</mi> }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp; foldlp (≫) . (f × id) . (f° . f × f° . f)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (2) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp; f . cat . (f° . f × f° . f)<br />
</math>
</blockquote>
<p>The proof is still the same as that of Jeremy&#8217;s, but in a relational disguise.</p>
<h3>Refining to Functions</h3>
<p>To derive actual algorithms, we have yet to refine <mi>⊚ = f . cat . (f°× f°)</mi> so that it uses functional components only. We shall pick some <mi>g ⊆ f°</mi> whose domain equals the range of <mi>f</mi>, such that <mi>⊚ = f . cat . (g × g)</mi>. (An equality, rather than inclusion, holds because <mi>⊚</mi> in both definitions are partial functions having the same domain.)</p>
<p>For example, consider the special case <mi>sum = foldr (+) 0 = foldl (+) 0</mi>. Here <mi>⊚ = sum . cat . (sum°× sum°)</mi>. One simple choice is to pick <mi>wrap ⊆ sum°</mi>, where <mi>wrap a = [a]</mi>. In this case <mi>a ⊚ b = sum [a, b] = a + b</mi>.</p>
<p>For <mi>sort</mi>, define <mi>sorted = ran sort</mi>. It is a partial function such that <mi>sorted xs = xs</mi> iff <mi>xs</mi> is sorted. Notice that <mi>sorted ⊆ sort°</mi>. Therefore, a possible choice for <mi>⊚</mi> would be <mi>sort . cat (sorted × sorted)</mi> &#8212; concatenating two sorted lists, and sort them again. <a href="http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/index.html#thirdht"">Jeremy</a> then went on with this definition and proved that <mi>⊚ = merge</mi>, taking advantage of the fact that both input lists are sorted.</p>
<h3>Some more Properties</h3>
<p>Some more properties are needed to deal with <mi>scanr</mi>. The following properties allow <mi>foldrp</mi> and <mi>foldrp</mi> to proceed by shifting elements of the list to the base case:</p>
<blockquote><math>
foldrp (≪) (xs⧺[x],a) = foldrp (≪) (xs, x ≪ a)<br />
foldlp (≫) (a, x:xs) = foldlp (≫) (a ≫ x, xs) <span style="float:right">(3)</span><br />
</math>
</blockquote>
<p>When simple approaches of refining <mi>⊚ = f . cat . (f°× f°)</mi> does not work, the following approach sometimes does. Since <mi>f</mi> is a fold, one may attempt to take one of the <mi>f°</mi> as an unfold, thus forming an &#8220;unfold, then fold&#8221; pattern:</p>
<blockquote><math>
&nbsp;&nbsp;&nbsp;&nbsp;⊚ = f . cat . (f°× f°)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (1) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;foldrp (≪) . (id × f) . (f°× f°)<br />
⊇  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ since <mi>f . f° ⊇ ran f</mi> }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;foldrp (≪) . (f°× ran f)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ since <mi>f = foldl ≫ []</mi> }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;foldrp (≪) . ((foldl ≫ [])°× ran f)<br />
</math>
</blockquote>
<p>Symetrically, </p>
<blockquote><math>
 ⊚ = foldlp (≫) . (ran f × (foldr ≪ [])°) <span style="float:right">(4)</span><br />
</math>
</blockquote>
<h3>Scanr &#8220;from the Middle&#8221;</h3>
<p>Finally, consider <mi>f = scanr ⊛ e</mi> for some associative <mi>⊛</mi>. A scan can be defined both as a <mi>foldr</mi> and a <mi>foldl</mi> as below:</p>
<blockquote><math>
scanr ⊛ e = foldr ≪ []<br />
&nbsp;&nbsp;&nbsp;&nbsp;x ≪ [] = [x]<br />
&nbsp;&nbsp;&nbsp;&nbsp;x ≪ (y : xs) = x ⊛ y : y : xs<br />
scanr ⊛ e = foldl ≫ []<br />
&nbsp;&nbsp;&nbsp;&nbsp;xs ≫ x = map (⊛x) xs ⧺ [x]<br />
</math>
</blockquote>
<p>From <mi>⊚ = f . cat . (f°× f°)</mi>, we can prove that <mi>xs ⊚ (y : ys) = map (⊛ y) xs ⧺  ys</mi>. Here is the inductive case:</p>
<blockquote><math>
&nbsp;&nbsp;&nbsp;&nbsp;xs ⊚ (x : y : ys)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (4) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;foldlp (≫) (xs, (foldr ≪ [])° (x : y :ys))<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ definition of <mi>≪</mi>, let <mi>z ⊛ y = x</mi> }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;foldlp (≫) (xs, z : (foldr ≪ [])° (y :ys))<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (3) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;foldlp (≫) (xs ≫ z, (foldr ≪ [])° (y :ys))<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ (4) }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;(xs ≫ z) ⊚ (y : ys)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ induction }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;map (⊛ y) (xs ≫ z) ⧺ (y:ys)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ definition of <mi>≫</mi> }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;map (⊛ y) (map (⊛ z) xs ⧺ z) ⧺ (y:ys)<br />
=  &nbsp;&nbsp;&nbsp;&nbsp; <text>{ associtivity of <mi>⊛</mi>, <mi>z ⊛ y =x</mi> }</text><br />
&nbsp;&nbsp;&nbsp;&nbsp;map (⊛ x) xs ⧺ [x] ⧺ (y:ys)<br />
</math>
</blockquote>
<h3>Prologue</h3>
<p>Given the complexity of the proof above, I did not think there was a hope to automatically construct <mi>⊚</mi> for a reasonably useful set of list homomorphisms. My colleagues were talking about &#8220;weak inverses&#8221; &#8212; their attempts to look for a refinement of <mi>f°</mi>, which I considered too ad-hoc.</p>
<p>Being just graduated from <a href="http://web.comlab.ox.ac.uk/oucl/research/pdt/ap/">AoP</a>, I was perhaps too arrogant and proud of all the clever derivation we did to care about automatic program construction. (Like Jeremy, in the end of my thesis I quoted &#8220;善數不用籌策 (Those who good at calculation need no mechanical aids)&#8221; from 老子 Lao Tzu. And didn&#8217;t Dijkstra say &#8220;I hardly used the computer they gave me. I was perfectly happy without it.&#8221;?) The relational method, which seemed to cover everything, gave me a false feeling that I knew the problem inside out.</p>
<p>Last year, however, my colleagues and I met again and I was told that they eventually published a paper on this subject:</p>
<blockquote><p>Kazutaka Morita, Akimasa Morihata, Kiminori Matsuzaki, Zhenjiang Hu, Masato Takeichi. <a href=" http://www.ipl.t.u-tokyo.ac.jp/~hu/pub/pldi07.pdf">Automatic Inversion Generates Divide-and-Conquer Parallel Programs</a>, PLDI 2007.</p></blockquote>
<p>They focused on weak inverses that returns only lists with fixed lengths. The advantage is that calculations like the one above are no longer necessary &#8212; since the lists are of fixed-length, <mi>⊚</mi> always takes constant time. On the other hand, <mi>scanr</mi> and <mi>scanl</mi> are special cases dealt with on a different level. Such distinction is enforced by the language they allow to construct <mi>f</mi>. No, they do not seem to have handled <mi>sort</mi>. But their approach still covered a reasonably useful collection of functions.</p>
<p>Well, I think the moral is that we cannot just stop when it appears that is no elegant solution that suits our taste. It sometimes pays to get our hands dirty, through which we may eventually discover the beauty within.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iis.sinica.edu.tw/~scm/2008/constructing-list-homomorphism/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
