2009/01/31

Algebra of programming in Agda: dependent types for relational program derivation

中文摘要:

關係式程式推導(relational program derivation)是「以代數規則將關係式規格(relational specification)逐步特化為程式」的技巧。因為建構過程的保證,如此得到的程式必然是正確的。另一方面,依值型別理論(dependent type theory)已發展得十分豐富,足以表達多種正確性質且可透過型別檢驗加以驗證。

我們造了一套程式庫 AoPA,使用者可在支援依值型別的程式語言 Agda 中編寫關係式推導。每個程式都附帶一個代數推導,由型別系統擔保其正確性。

我們提出兩個有意思的例子:一個最佳化問題和快速排序的推導,後者用良基遞迴(well-founded recursion)在支援歸納式型別(inductive types)的語言中模映「計算終必停止的生滅式」(terminating hylomorphisms)。

嘔,好噁心的翻譯(特別是把所有名詞都譯出來之後 ─「生滅式」還滿惡搞的 XD)。要看原文摘要和 paper 請到 scm 老師的官方網頁。

--
是太久沒翻譯還是這段本來就難譯啊?不知道這個問題的答案代表可能是前者 XD。

Labels: , ,

2008/11/21

Fold 刻劃定理

今天很簡單用 Church encoding 開場,然後講下面這個 fold 的刻劃定理,描述「一個 total function 可以寫成 fold」的充要條件:

從這個定理的 list 版可以推得 zip 和 zip xs 都是 fold。zip 是 fold 還可以想像,zip xs 是 fold 就有點匪夷所思 ─ 怎麼從 zip xs ys 造出 zip xs (y :: ys) 啊?(這個問題我在 FLOLAC '07 的時候就問過了,一直擱到現在。)事實上我今天一開始說 zip xs 不是 fold,卻造不出反例 XD。

再從這個定理的自然數版(依 CS 慣例,自然數包括 0)可以推得 factorial function 不是 fold,因為 fact 0 = 1 = fact 1 但 fact 1 = 1 /= 2 = fact 2。不過這是唯一的反例。如果把 fact 定義在正整數上,就會發現 fact 是一個 fold 了。這是因為 fact 在正整數上是 injective,所以可以經過複雜計算從 fact n 推得 n,然後算出 (1+n) * fact n。當然計算上最有效率的解法還是用 primitive recursion (paramorphism)。

回到定理本身。臨時準備的東西果然強度不夠,蔡老師要求直覺詮釋的時候我就掛在台上了 XD。不過蔡老師也很快發揮功力,給 "ker f ⊆ ker g" 一個直覺詮釋:f 的 "discrimination power" 不弱於 g。證明定理的一個關鍵引理是 "∃h : B -> C s.t. g = h . f" iff "ker f ⊆ ker g and ∃h' : B -> C"。先不理會右側的 "∃h' : B -> C" 條件,蔡老師把 g 詮釋為我們想完成的動作,而 f 只做了一半。如果想宣稱有個 function h 能夠從 f 結束的地方出發,把 g 的動作完成,那麼 g 把 a 和 a' 映射到不同的值時,f 必定不能把 a 和 a' 映射到同一個值 b,因為 h 沒辦法把單一個值 b 分射到 g a 和 g a'。從另一個方向看,如果當 g 把 a 和 a' 映射到不同的值時,f 都會把 a 和 a' 映射到不同的值 b 和 b',那就一定有辦法繼續把 b 和 b' 送到 g a 和 g a'。

如果把這個詮釋類推到定理的 "ker(Fh) ⊆ ker(h . α)" 呢?我目前認為這個條件捕捉的是「fold 的結果僅依賴於遞迴算得的結果(即 Fh 算出的 FA-structure)」。當 h 拿到一個 object of type T,我們可以把它拆成一個 FT-structure,改而考慮 h . α。假設我們有兩個 FT-structures,只有內藏的 T object(s) 不同,其餘成分皆相同。當我們遞迴地把那些 T object(s) 轉換成 A object(s) 而且這兩堆 A object(s) 完全相同時,h . α 套用在這兩個 FT-structures 的結果也會相同。因此即便 h 拿到的是兩個「內藏的 T object(s) 不同」的 FT-structures,只要遞迴地轉換後的 A object(s) 相同,h 就必須給相同的結果 ─「內藏的 T object(s) 不同」這樣的資訊是 h 無法利用(得知)的。

話說回來,「fold 的結果僅依賴於遞迴算得的結果」不就是 universal property 所說的一部份事情嗎?這樣有沒有重造輪子的嫌疑呢?這就回到我們打造這個定理的初衷:我們之所以搜尋一個不同於 universal property 的刻劃,是因為 universal property 要求我們找到 fold 用的 algebra,而這樣的要求對於「檢驗一個函式是不是 fold」太麻煩了。至於這個定理找到的刻劃只涉及函式的外延(extensional)行為,檢驗上比較方便。而剛剛的分析告訴我們這個刻劃講的事情和 universal property 相當吻合,這就更穩固我們對這個定理的信心嘍。

--
我還是覺得 zip xs 是 fold 很奇怪… 如果可以用 xs 就行,但是可以嗎?好像可以 XD。

Labels:

2008/11/01

Notes on Categorical Functional Derivation

這是下星期五打算講的東西,除了最後的 "derivation examples" 之外,內容是 AoP chapter 2 的 "very proper" subset。目標很明確是 initial types,所以對理解 initial types 沒有立即幫助的東西(例如 natural transformations)都被毫不猶疑地丟掉了 XD。

--
不是原味的 category theory…

Labels:

2008/07/11

Fast Exponentiation

Today Shin and I were grading the final exam of Program Construction and Reasoning in FLOLAC 2008 and one of the students presented an interesting derivation for the O(lg n) fast exponentiation algorithm where n is the exponent. In fact, he derived two different solutions by induction and fold-fusion respectively, the second of which is the standard version. Shin later observed that the first solution (the interesting one) is a higher-order fold. Below I'll describe the solution in (more or less) point-free style, but of course it would be much easier to do the derivation by induction.

I prefer to define unfoldr on Maybe functors.

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f s = case f s of Nothing -> []
                          Just (x, s') -> x : unfoldr f s'
A function binary can be defined to produce a "reversed binary bit list" representing the input number.
binary :: Integer -> [Bool]
binary = unfoldr (\n -> if n == 0 then Nothing
                                  else Just (odd n, n `div` 2))
For example, binary 11 = [True, True, False, True]. Its left inverse decimal can be defined as a fold.
decimal :: [Bool] -> Integer
decimal = foldr (\x y -> if x then 1 + 2 * y else 2 * y) 0
Let exp m n = mn. A naïve implementation of exp requires n - 1 multiplications. But we can introduce a hylomorphism and do fold-fusion to reduce the number of multiplications to O(lg n):
  exp m n
=   { identity }
  (exp m . id) n
=   { decimal is a left inverse of binary }
  (exp m . decimal . binary) n
=   { fusion, see below }
  (binexp m . binary) n
where binexp m . binary takes only O(lg n) time, since the length of the intermediate list is only O(lg n) and both binexp m and binary runs in time linear to the length of the intermediate list. The function binexp is specified by
binexp m xs = exp m (decimal xs)
The standard solution can be derived by directly fusing exp m into decimal, which gives
binexp m []           = 1
binexp m (True  : xs) = m * square (binexp m xs)
binexp m (False : xs) = square (binexp m xs)
The interesting solution, on the other hand, may be derived by first introducing flip on both sides:
flip binexp xs m = flip exp (decimal xs) m
After some eta-conversions we would get a point-free specification of flip binexp:
flip binexp = flip exp . decimal
Now it's obvious that we should try to fuse flip exp into decimal. The fusion condition is justified as follows:

Therefore flip binexp = foldr g (flip exp 0) = foldr g (const 1). (In fact this involves the debate of whether 00 is defined. Currently I am convinced by Knuth's argument --- see Two Notes on Notation.) Applying flip to both sides again, we get binexp = flip (foldr g (const 1)), which expands to

binexp m []           = 1
binexp m (True  : xs) = m * binexp (square m) xs
binexp m (False : xs) = binexp (square m) xs
Notice that the last equation is a tail-recursive one.

--
Derivations using higher-order fusion always look much more frightening than the corresponding pointwise, inductive derivations...

Labels:

2008/07/05

Interpreting a New Kind of Monotonicity

The following theorem is a slight generalisation from the original monotonicity and greedy theorem:

Thm. Let R : A ← A be a preorder and S : A ← FA
be monotonic on Rº in the sense that

    S . FRº . Tº  ⊆  Rº . S

where T : FA ← FA satisfies

    S . T  ⊆  S.

Then

    min R . Λ⦇S⦈  ⊇  ⦇min R . ΛS . T⦈.
There is a way to interpret the new monotonicity condition:
  S . FRº . Tº   ⊆   Rº . S
y   b     a   a'   y    x   a'
Here we are comparing two partial solutions a and b, where b is worse than a. A complete solution y is generated from b. The monotonicity condition says that instead of choosing b as the input, we should take another partial solution a' which is transformed from a by T, since from a' one can generate another complete solution x which is better than y.

The interpretation is a bit strange, though. It seems that we are mixing two different levels of solutions. The premise compares a and b, but the conclusion is that a solution generated from b is worse than another solution generated from a', which is transformed from a.

      R
  a ----- b
  |       |
T |       |
  ↓       |
  a'      | S
  |       |
S |       |
  ↓       ↓
  x ----- y
      R
It seems to be more sensible if what the monotonicity says is like this:
      R
  a ----- b
  |       |
T |       | T
  ↓       ↓
  a'      b'
  |       |
S |       | S
  ↓       ↓
  x ----- y
      R
The partial greedy theorem is a special case of this theorem, where T is a coreflexive. When deriving the activity-selection problem, I do have to do some "coreflexive propagation" and fusion to make the monotonicity look like the second diagram. Maybe this peculiarity would be understood if we can solve some concrete problem by this theorem.

Another point to make: If T is entire, then the conditions of the theorem would imply the original monotonicity condition:

  S . FRº . Tº  ⊆  Rº . S
⇒  { composition is monotonic }
  S . FRº . Tº . T  ⊆  Rº . S . T
⇒  { T entire }
  S . FRº  ⊆  Rº . S . T
⇒  { S . T ⊆ S }
  S . FRº  ⊆  Rº . S.
Then we can just apply the original greedy theorem and get rid of T. So this theorem is interesting only if T is not entire, which is just the case of partial greedy theorem.

And finally, we can also prove a similar variation of thinning theorem. This would potentially allow more problems to be solved by identifying this new kind of monotonicity.

--
More clarifications needed...

Labels:

2008/06/20

Notes on a Derivation of Activity-Selection

I wrote some brief notes explaining the Partial Greedy Theorem and a derivation of an algorithm for the Activity-Selection problem taken from Chapter 16 of Introduction to Algorithms, second edition (Cormen et al, 2001). Some tedious details are omitted in the notes but (painfully) verified in AoPA.

The main derivation is:

One can see that the rightmost fin-ordered in the specification propagates itself into the generating fold and absorbs redundant coreflexives, which somehow justifies that sortedness of the input list is indeed essential to the derived algorithm.

--
Please click the title for the notes.

Labels:

2008/05/24

也沒那麼差

昨天我以為我導的 partial greedy theorem 沒什麼用,今天再想想,其實還是可以只用這個定理而不用 inherently ordered lists 導出 activity-selection problem(CLRS 第 16 章的開場問題)的解。Specification 是

max ≤ℓ . Λ(mutex . subseq) . ordered
把 mutex . subseq 融成單一個 fold mutex-subseq 之後,可以用昨天證明的等式把 ordered 傳播到 Λ 裡面。再一次融合 mutex-subseq . ordered 成為 mutex-ordered-subseq,但這次只能得到
mutex-subseq . ordered  ⊆  mutex-ordered-subseq
而不是等式,因為給一個 unordered list 仍可能產出一個 ordered (and mutually-exclusive) subsequence。不過顯然 mutex-ordered-subseq ⊆ mutex-subseq,因此我們可以如下推導
  mutex-subseq . ordered
=   { coreflexives are "idempotent" }
  mutex-subseq . ordered . ordered
⊆   { fusion }
  mutex-ordered-subseq . ordered
⊆   { observation above }
  mutex-subseq . ordered
而完成精確的 fusion。Λ 裡贅餘的 ordered 同樣藉著昨天的等式可以被外面的 ordered 吸收。如此一來,partial monotonicity 裡面就會多出我們想要的條件了。整個過程基本上就對應 externalism 處理 ordered lists 的做法吧,看得出來挺麻煩的 XD。

定理本身的限制也很好丟掉,只要把 C-preserving 右邊多出來的 C 改成另一個 coreflexive D 就行了。然後定理本身可能會被拆成兩段吧。至於最後證不出來的 claim,逐點地看沒問題,我也特別用 AoPA 證了一次。當然我還是很希望可以有一個比較 AoP 的證明啦。

--
終究不是完全沒用的東西 XD。

Labels:

2008/05/23

Partial Greedy Theorem

The partial greedy theorem can help derive greedy algorithms whose input is constrained in some way. The theorem is actually quite restricted since the feasible solutions must be lists of the same type. Generalisation is possible, but the original purpose of its development has disappeared. Now this post exists only for historical reasons.

First we need to extend the usual monotonicity to a weaker one (which is why one would need a different greedy theorem). (The inclusion is not a proper one; somehow the line denoting equality is truncated.)

For our purpose, C is taken to be coreflexive. We need another concept that ensures the restriction on the input is propagated through the folding process.

The inclusion becomes equality if C is coreflexive. Now we have our theorem:

The proof consists of two parts. The first part establishes that cata (min R . ΛS . C) ⊆ min R . Λ(cata S), which in essence is the proof of the original greedy theorem.

The second part refines cata (min R . ΛS . C) to cata (min R . ΛS) . cata (α . C) (i.e., the former includes the latter) by fold fusion. The fusion condition is:

Oops, my first proof of the claim is not right. But it looks good pointwisely. Of course, we need to prove the claim in order to establish the theorem's validity.

--
But I won't continue unless the theorem looks useful again...

Labels:

2008/05/12

Details

I'm reading Shin's Maximum segment sum is back: deriving algorithms for two segment problems with bounded lengths and trying to work out the details as exercises. So far I've just gone through 3/4 of the first page deriving mssu.

The first claim we need is

  sum . fitlen
=   { split cancellation (backwards) }
  fst . <sum, len> . fitlen
=   { claim: <R, S> . C = <R, S . C> }
  fst . <sum, len . fitlen>
=   { len . fitlen = (≤ U) . len }
  fst . <sum, (≤ U) . len>
=   { product relator }
  fst . (id × (≤ U)) . <sum, len>
=   { definition of fit }
  fst . fit . <sum, len>
The subclaim follows from R ∩ (S . C) = (R ∩ S) . C where C is coreflexive, since <R, S> = (outlº . R) ∩ (outrº . S).
  R ∩ (S . C)
⊆   { modular law }
  ((R . Cº) ∩ S) . C
⊆   { C coreflexive }
  (R ∩ S) . C
=   { C simple }
  (R . C) ∩ (S . C)
⊆   { C coreflexive }
  R ∩ (S . C)

Next we have to invent R such that the fusion condition

  fit . <sum, len> . (const [] ∪ cons)
= R . (id × (fit . <sum, len>))
holds. We reason:
  fit . <sum, len> . (const [] ∪ cons)
=   { composition distributes over join }
  (fit . <sum, len> . const []) ∪ (fit . <sum, len> . cons)
=   { naturality of const (??) }
  const (0, 0) ∪ (fit . <sum, len> . cons)
=   { <sum, len> is a fold by banana-split law (??); fold evaluation }
  const (0, 0) ∪ (fit . add . (id × <sum, len>))
=   { claim: fit . add = fit . add . (id × fit) }
  const (0, 0) ∪ (fit . add . (id × (fit . <sum, len>)))
=   { naturality of const (??); composition distributes over join }
  (const (0, 0) ∪ (fit . add)) . (id × (fit . <sum, len>))
Therefore we have R = const (0, 0) ∪ (fit . add). The subclaim holds since 1 + l ≤ U implies l ≤ U.

And now we reach the monotonicity condition. There is a somewhat irrelevant component left out in the antecedent given in the paper:

s₁ ≤ s₂ ∧ (s₃ = 0 ∨ (s₃ = a + s₁ ∧ 1 + l₁ ≤ U))

But 1 + l₁ ≤ U doesn't help ensuring that l₄ = 1 + l₂ ≤ U, since the two lengths are unrelated. Thus one can enhance the antecedent:

s₁ ≤ s₂ ∧ l₁ ≥ l₂ ∧ (s₃ = 0 ∨ (s₃ = a + s₁ ∧ 1 + l₁ ≤ U))
and we'll have 1 + l₂ ≤ 1 + l₁ ≤ U.

Finally, the proof of the thinning theorem is structurally equivalent to that of the greedy theorem.

It reveals that I haven't understood datatypes (products, coproducts, ...) and their properties in Rel. For example I am not certain whether naturality (in particular "theorems for free") can be applied as one would do in Fun. (And I don't understand theorems for free, either.)

--
I'll try to finish the rest in the evening...

Labels:

2008/05/10

Why naive program transformation systems are unlikely to work

這篇是 E.W. Dijkstra 對於 program transformation 的小評論,編號 EWD 636。(Dijkstra 的 manuscripts 收集在 E.W. Dijkstra Archive,有空可以上去逛逛。)前面一半介紹 program transformation 並和傳統方法比較,後面一半是 Dijkstra 的質疑。他的主要論點大概有三:

  • Derivation 的過程太長,因為已發現的 transformation steps 太過瑣細;
  • 正確的 specification 並不見得好寫;
  • 從 specification 不一定能透過一條 semantic-preserving path 而抵達理想的演算法。
Dijkstra 針對的應該是(至少接近)「自動的」(機械式的)程式轉換系統,所以第一個論點對 AoP-style derivation 並不造成絕大的衝擊(雖然我覺得的確需要發展更強的定理)。後面兩個就真的比較麻煩,特別是第三個。不知道有沒有人做過這種 "completeness" 的證明?

--
我猜不外乎要重整到 formal logic 或 / 和 lambda calculus 吧?

Labels:

2008/05/03

Thoughts on the Greedy Theorem

On the train back to Changhua, I thought about why the greedy theorem requires S to be monotonic on Rº instead of R. Read naïvely, "S . FR ⊆ R . S" (which is not the monotonicity condition of greedy theorem) says that if we decrease (improve) the input to S, the result would be smaller (better) than what we get from feeding the original input to S. To compare, the real monotonicity condition "S . FRº ⊆ Rº . S" says if we increase (\sth -> make sth worse) the input to S, the result would be larger (worse) than what we get from feeding the original input to S. The two statement seems to be the same, both suggesting that we always choose the least result during folding, while the first one looks more intuitive.

But it's an imprecise interpretation. What the two monotonicity conditions tell us is when we decrease/increase the input to S, the result would be smaller/larger than one of the possible results we get from feeding the original input to S. This makes a difference. Say we have a smaller input i and a larger input j, and ΛS i = {a, b}, ΛS j = {c, d}. Given S is monotonic on R, we can only guarantee that any of a and b is better (smaller) than one of c and d but not necessarily both, and it is therefore possible that the optimum result is one of c and d. On the other hand, if we have that S is monotonic on Rº, choosing c or d as the final result would be unwise, since one of a and b is going to be better.

A remaining question is: isn't it possible that we need some suboptimum steps in order to reach the final optimum result? The key is that we are using folds as the generating structure. Very informally, the folding process may be interrupted at any time, so we must give the optimum result after every folding step. More formally, it may be possible to exploit the min/max principle to prove that after every step the optimum result must be produced. But we do not need another formal proof since the greedy theorem is already proved, so the informal explanation is quite enough.

However, why is the naïve interpretation wrong? The problem is that S may generate more than one possible results. This immediately suggests that if S is a function, we may be able to prove that the first monotonicity condition is equivalent to the second one, which is indeed a fact that can be easily proven by shunting and already pointed out in AoP.

--
Well, it is beyond my English writing ability to express such a complicated discussion...

Labels:

2008/04/28

Proving the Greedy Theorem by Fold Fusion

In hope of finally deriving algorithms for optimisation problems in AoPA, I naturally start from the Greedy Theorem and its applications, since it is the simplest yet nontrivial theorem for optimisation problems in AoP and, maybe more importantly, it involves only folds. The proof recorded in AoP makes essential use of the Hylomorphism Theorem, but it is easier (for me) to prove the theorem by fold fusion, as hinted by Shin's Proving the Thinning Theorem by Fold Fusion. In fact, being new to the material, I occasionally need to look into the blog post for directions. Therefore I must thank the extra Λ for getting Shin writing down the proof. :P

The statement of the Greedy Theorem is as follows.

We first reduce the conclusion to two fusion conditions.

The first fusion condition is an easy consequence of the fact that min R is included in the membership relation.

The second fusion condition makes use of the monotonicity condition and transitivity of R (since Rº is a preorder).

And the theorem is proven.

--
Now I need to find a suitable optimisation problem to work with...

Labels:

Yet Another Small Exercise

The following problem description is taken from exercise 7.39 of AoP:

The function takeWhile of functional programming can be specified by

takeWhile p = max R . Λ(list p . prefix)
where R = lengthº . leq . length. In word, takeWhile p x returns the longest prefix of x with the property that all its elements satisfy p. (Question: why the longest here rather than a longest?) Using prefix = cata [nil, cons ∪ nil] and the greedy theorem, derive the standard implementation of takeWhile.

(The answer to the small question is that a prefix of a given length is unique.) My aim, however, is to play with functional derivation. Therefore

The purpose of the first fusion is to transform the generating part into a fold, in hope that the greedy theorem can be applied.

One small property I didn't prove is filter ((t ∧) . p) = (const t → filter p, nil . !), which is a rather straightforward one.

And the second fusion tries to promote max into the generating fold, which is the spirit of the greedy theorem. I didn't formulate the greedy theorem in functional form, though, so I simply do the fusion.

In fact I don't know precisely which part should be called the monotonicity condition. Maybe it will become clear to me after I prove the greedy theorem (by fold fusion) and compare the proof to this derivation and the derivation of maximum prefix sum. Having experience dealing with maximum prefix sum, I guess the following property is an essential one.

This is the fusion condition for (x:) . max ≤ℓ. Applying type functor fusion to max ≤ℓ . map (x:), we would have max ≤ℓ . map (x:) = (x:) . max ≤ℓ, a premise used in the second fusion.

The entire derivation is very similar to maximum prefix sum, which is certainly no surprise. They are both applications of the greedy theorem. I mixed Haskell and AoP syntax as well as curried and uncurried forms. Hope it's not too confusing.

--
Time to study AoP chap. 7!

Labels:

2008/04/22

Tabulations and a Small Equivalence

After Shin's kind explanation, I've finally got some idea about tabulations. In Rel it's just like how database theory models relations --- by building a table for each relation. (This reminds me of the always-smiling professor Hao who taught the course on databases.) Given a relation R : A ← B, it can be tabulated as R = f . gº where f : A ← C and g : B ← C and C is a subset of A × B. C is just the table for R, and the thing between f and gº, a member of C, is exactly one of the table entries. Following this line of thought, the condition (fº . f) ∩ (gº . g) = id can be interpreted as "two table entries are equal if and only if they are component-wise equal". Regarding R as a nonderministic mapping, gº is like looking up the table for entries whose right component equals the input, and then f selects one of the matched entries and returns its left component as the output. Everything goes smoothly! (In fact, more correspondences between database theory and relational calculus can be found. For example, relational composition is comparable to the "natural join" operation in database systems. That's no surprise, since they are essentially the same thing viewed from different angles.)

Before the midterm on computer architecture this afternoon (which turned out to be much, much easier than I expected), I practiced proving that (fº . f) ∩ (gº . g) = id is equivalent to "(f, g) is jointly monic" in a tabular allegory. When proving the "only if" direction, I simply weakened f . h = f . k to f . h ⊆ f . k and then got h . kº ⊆ fº . f by applying the shunting rules. Later when I was proving the other direction, I couldn't go backward, since the route I took from f . h = f . k to h . kº ⊆ fº . f is only one-way. Then I realised that I should go like this to have an equivalence:

in which converse, again, played an essential role.

--
On the other hand, I need to think more about why tabulation enables pointwise proofs...

Labels:

2008/04/20

Game

本來我想等到某個(或是某些)特定事件發生才貼文,結果還是自己撐不住。隨便貼個小練習充版面:

其中唯一沒收錄在 AoP 的性質是

<(p -> f1, f2), (p -> g1, g2)> = (p -> <f1, f2>, <g1, g2>)
不過這是 exchange law 的簡單 corollary。然後 cat . (wrap × id) = cons 其實也不是 by definition,不過不管啦。

--
玩不到一半(大概吧,說不定快完了)就覺得這遊戲有點無味了…

Labels:

2008/04/16

Beautiful Formulation

Relational calculation 一開始很吸引我的一個特點是它能夠很簡潔地表現一些常見的性質。(現在還是很吸引我 XD。)給予以下的基本定義(in Rel)

我們可以用 6 個以內的 tokens 表示以下的常見性質

而且都可以藉著把 relations 詮釋為 nondeterministic mappings 而讀出 operational meanings!

--
現在正在一條一條地證明 AoP 列出來的相關性質,modular law 有比較上手了 XD。

Labels:

2008/04/12

Algebra of Programming using Dependent Types

出現在 scm 老師的網頁上了!!!

S-C. Mu, H-S. Ko, and P. Jansson. Algebra of programming using dependent types. In Mathematics of Program Construction 2008. July 2008.

是完美的 16 頁 XD。

--
晚點再看一遍 XD。

Labels: ,

2008/04/03

Unfold Fusion

一直沒辦法感受 coinduction 的直覺意義。在豁然貫通的那一個時刻來臨以前,最簡單的方式大概就是用 unfold fusion 嘍,因為 category theory 裡面的 duality 很明確很好操作,只要把 inductive datatypes 那一套的箭頭全部反過來就行了。

第一個 coinductive proof 當然是

map f . iterate f = iterate f . f        (*)
我們需要一些基本定義(in Haskell)。
-- constructor
-- Maybe (A, B) is isomorphic to 1 + A * B
alpha :: Maybe (a, [a]) -> [a]
alpha Nothing       = []
alpha (Just (a, t)) = a : t

-- deconstructor
ahpla :: [a] -> Maybe (a, [a])
ahpla []       = Nothing
ahpla (x : xs) = Just (x, xs)

-- products
split f g a = (f a, g a)
cross f g   = split (f . fst) (g . snd)

-- base functor
listrF f g Nothing       = Nothing
listrF f g (Just (a, t)) = Just (cross f g (a, t))

接著是一些 coinductive lists 的相關定義。

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f = alpha . listrF id (unfoldr f) . f

-- type functor
mapana :: (a -> b) -> [a] -> [b]
mapana f = unfoldr (listrF f id . ahpla)

iterate :: (a -> a) -> a -> [a]
iterate f = unfoldr (Just . split id f)

為了對稱,我們把 inductive lists 的相關定義重寫一遍。

foldr :: (Maybe (a, b) -> b) -> [a] -> b
foldr f = f . listrF id (foldr f) . ahpla

mapcata :: (a -> b) -> [a] -> [b]
mapcata f = foldr (alpha . listrF f id)
以上其實就是莊老師在 FLOLAC '07 講的一部份東西。真恐怖,FLOLAC 花了快一年時間都還沒消化完 XD。

Inductive lists 有 fusion law

h . foldr f = foldr g    <=    h . f = g . listrF id h
以及雖為特例但很好用的 type functor fusion law
foldr f . mapcata g = foldr (f . listrF g id)
現在把 function composition 的方向顛倒,就直接得到 coinductive lists 的 fusion law 和 type functor fusion law!
unfoldr f . h = unfoldr g    <=    f . h = listrF id h . g

mapana g . unfoldr f = unfoldr (listrF g id . f)

我沒預期要鋪這麼多路 XD。Anyway,(*) 式左邊可直接從 type functor fusion law 得到:

  map f . iterate f
=   { definition of iterate }
  map f . unfoldr (Just . split id f)
=   { type functor fusion }
  unfoldr (listrF f id . Just . split id f)
=   { definition of listF }
  unfoldr (Just . cross f id . split id f)
=   { product functor }
  unfoldr (Just . split f f)
右邊很自然地湊湊看 fusion condition:
  (Just . split id f) . f
=   { split fusion }
  Just . split f (f . f)
=   { product functor }
  Just . cross id f . split f f
=   { definition of listrF }
  listrF id f . Just . split f f
=   { let g = Just . split f f }
  listrF id f . g
所以依 fusion law 就得到
iterate f . f = unfoldr (Just . split f f)
於是 (*) 式兩邊都等於同一個 unfold,證畢。Coinduction 大概就先這樣弄吧 XD。

--
寫完才發現 this post should have been written in English XD。

Labels: ,

2008/03/30

Relational Division

向 scm 老師求得看懂兩個 relations 相除意義的撇步後,一些本來跟天書一樣的定義如 specifications of optimisation problems 裡面最重要的

min R = ∈ ∩ (R/∈)
和 thinning algorithms 用的
thin Q = (∈\∈) ∩ ((∋·Q)/∋)
突然都讀得出意思了!

--
又燃起了希望 XD。

Labels:

2008/03/23

Paramorphisms

Paramorphisms correspond to the concept of primitive recursion. A paramorphism can be defined in terms of products and catamorphisms

or characterised by the universal property

It is a (strict) specialisation of the generalised tupling transformation mentioned before. I didn't get the statement about generalised tupling precise enough at the beginning, so I was confused by why the universal property of paramorphisms can be a bidirectional implication, until I realised that the statement of general tupling can be proven to be bidirectional:

Once the full-fledged tupling rule is established, the universal property of paramorphisms follows as an easy corollary since id = cata α.

--
It took me more time than I expected...

Labels: