Import of Cabra version 1.0 revision 2011.1214 (just HTML fixes.)
Cat's Eye Technologies
11 years ago
0 | 0 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
1 | <!-- encoding: UTF-8 --> | |
1 | 2 | <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> |
2 | 3 | <head> |
3 | 4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
4 | 5 | <title>The Cabra Programming Language</title> |
6 | <!-- begin html doc dynamic markup --> | |
7 | <script type="text/javascript" src="/contrib/jquery-1.6.4.min.js"></script> | |
8 | <script type="text/javascript" src="/scripts/documentation.js"></script> | |
9 | <!-- end html doc dynamic markup --> | |
5 | 10 | </head> |
6 | 11 | <body> |
7 | 12 | |
27 | 32 | relation</em> is introduced there in order to make sense of how program texts (syntax) can be manipulated in |
28 | 33 | tandem with the programs (semantics) they represent. In short, many different program texts are equivalent to |
29 | 34 | the same (abstract) program, so the equality operator = used in the group axioms is simply replaced |
30 | by the equivalence operator, ≡. Obviously, this technique isn't restricted to groups, and the idea can be | |
35 | by the equivalence operator, ≡. Obviously, this technique isn't restricted to groups, and the idea can be | |
31 | 36 | extended to that of any <em>algebra over an equivalence relation</em>, and it is this notion that |
32 | 37 | is applied in Cabra to dioids.</p> |
33 | 38 | |
161 | 166 | problems any easier.</p> |
162 | 167 | |
163 | 168 | <p>Another reason is that Cabra, despite almost being, say, just a kind of algebraical structure, <em>looks</em> a lot |
164 | like the beginnings of a programming language. It's got a conditional form, and imperative update. It almost looks like an overspecified language — | |
165 | heck, a <em>machine</em> — because of the definition of how parallel composition works in terms of cycles and everything.</p> | |
169 | like the beginnings of a programming language. It's got a conditional form, and imperative update. It almost looks like an overspecified language — | |
170 | heck, a <em>machine</em> — because of the definition of how parallel composition works in terms of cycles and everything.</p> | |
166 | 171 | |
167 | 172 | <p>A third reason is that it's just a little... askew. Note that if we had a <code>WHILE</code> instruction, |
168 | 173 | we wouldn't need a <code>BOTTOM</code> instruction |
176 | 181 | |
177 | 182 | <h2>Dioid Theory</h2> |
178 | 183 | |
179 | <p>Now, recall — or go look up in an abstract algebra textbook — or just take my word for it — that | |
180 | an idempotent semiring is a triple ⟨<var>S</var>, +, *⟩ where:</p> | |
184 | <p>Now, recall — or go look up in an abstract algebra textbook — or just take my word for it — that | |
185 | an idempotent semiring is a triple 〈<var>S</var>, +, *〉 where:</p> | |
181 | 186 | |
182 | 187 | <ul> |
183 | 188 | <li><var>S</var> is a set of elements;</li> |
184 | <li> + : <var>S</var> × <var>S</var> → <var>S</var> is a binary operation on <var>S</var>; and</li> | |
185 | <li> * : <var>S</var> × <var>S</var> → <var>S</var> is another binary operation on <var>S</var>,</li> | |
189 | <li>+ : <var>S</var> × <var>S</var> → <var>S</var> is a binary operation on <var>S</var>; and</li> | |
190 | <li>* : <var>S</var> × <var>S</var> → <var>S</var> is another binary operation on <var>S</var>,</li> | |
186 | 191 | </ul> |
187 | 192 | <p>where the following axioms of dioid theory (over an equivalence relation!) hold:</p> |
188 | 193 | |
189 | 194 | <ul> |
190 | <li> (<var>a</var> + <var>b</var>) + <var>c</var> ≡ <var>a</var> + (<var>b</var> + <var>c</var>) (addition is associative)</li> | |
191 | <li> <var>a</var> + <var>b</var> ≡ <var>b</var> + <var>a</var> (addition is commutative)</li> | |
192 | <li> <var>a</var> + 0 ≡ 0 + <var>a</var> ≡ <var>a</var> (existence of additive identity)</li> | |
193 | <li> <var>a</var> + <var>a</var> ≡ <var>a</var> (addition is idempotent)</li> | |
194 | <li> (<var>a</var> * <var>b</var>) * <var>c</var> ≡ <var>a</var> * (<var>b</var> * <var>c</var>) (multiplication is associative)</li> | |
195 | <li><var>a</var> * 1 ≡ 1 * <var>a</var> ≡ <var>a</var> (existence of multiplicative identity)</li> | |
196 | <li><var>a</var> * (<var>b</var> + <var>c</var>) ≡ (<var>a</var> * <var>b</var>) + (<var>a</var> * <var>c</var>) (multiplication left-distributes over addition)</li> | |
197 | <li>(<var>a</var> + <var>b</var>) * <var>c</var> ≡ (<var>a</var> * <var>c</var>) + (<var>b</var> * <var>c</var>) (multiplication right-distributes over addition)</li> | |
198 | <li><var>a</var> * 0 ≡ 0 * <var>a</var> ≡ 0 (additive identity is multiplicative annihiliator)</li> | |
195 | <li> (<var>a</var> + <var>b</var>) + <var>c</var> ≡ <var>a</var> + (<var>b</var> + <var>c</var>) (addition is associative)</li> | |
196 | <li> <var>a</var> + <var>b</var> ≡ <var>b</var> + <var>a</var> (addition is commutative)</li> | |
197 | <li> <var>a</var> + 0 ≡ 0 + <var>a</var> ≡ <var>a</var> (existence of additive identity)</li> | |
198 | <li> <var>a</var> + <var>a</var> ≡ <var>a</var> (addition is idempotent)</li> | |
199 | <li> (<var>a</var> * <var>b</var>) * <var>c</var> ≡ <var>a</var> * (<var>b</var> * <var>c</var>) (multiplication is associative)</li> | |
200 | <li><var>a</var> * 1 ≡ 1 * <var>a</var> ≡ <var>a</var> (existence of multiplicative identity)</li> | |
201 | <li><var>a</var> * (<var>b</var> + <var>c</var>) ≡ (<var>a</var> * <var>b</var>) + (<var>a</var> * <var>c</var>) (multiplication left-distributes over addition)</li> | |
202 | <li>(<var>a</var> + <var>b</var>) * <var>c</var> ≡ (<var>a</var> * <var>c</var>) + (<var>b</var> * <var>c</var>) (multiplication right-distributes over addition)</li> | |
203 | <li><var>a</var> * 0 ≡ 0 * <var>a</var> ≡ 0 (additive identity is multiplicative annihiliator)</li> | |
199 | 204 | </ul> |
200 | 205 | |
201 | 206 | <p>Now I'll attempt to show that Cabra programs form an idempotent semiring, over the equivalence relation of "semantically identical", under the |
212 | 217 | this is completely independent of the order in which they are considered to have been organized into a parallel arrangement.</p> |
213 | 218 | |
214 | 219 | <p>Parallel composition is commutative. When running programs in parallel, one would naturally expect that the order of the programs |
215 | doesn't matter — in fact, the concept doesn't really make sense. In <code><var>a</var>+<var>b</var></code>, <var>a</var> and <var>b</var> aren't | |
220 | doesn't matter — in fact, the concept doesn't really make sense. In <code><var>a</var>+<var>b</var></code>, <var>a</var> and <var>b</var> aren't | |
216 | 221 | really running in any order; they're running at the same time. The result of <code><var>a</var>+<var>b</var></code> |
217 | 222 | is determined by which of <var>a</var> or <var>b</var> terminates first, and this is not affected by which order they appear on either |
218 | 223 | side of the <code>+</code> operator. (In fact, that was why I introduced the "lexical order" tie-breaker, |
220 | 225 | |
221 | 226 | <p>There is a neutral element for parallel composition. Indeed, <code>BOTTOM</code> is this neutral element. |
222 | 227 | Any program <var>a</var> that terminates will by definition terminate before <code>BOTTOM</code>, |
223 | therefore <code><var>a</var>+BOTTOM</code> ≡ <code>BOTTOM+<var>a</var></code> ≡ <code><var>a</var></code>.</p> | |
228 | therefore <code><var>a</var>+BOTTOM</code> ≡ <code>BOTTOM+<var>a</var></code> ≡ <code><var>a</var></code>.</p> | |
224 | 229 | |
225 | 230 | <p>Parallel composition is idempotent. Intuitively, executing two copies of the same program in parallel will have the same result as |
226 | 231 | executing only one copy would. Since they both have the same input set and they both |
253 | 258 | Now suppose we sequentially compose <var>c</var> onto each of these subprograms: |
254 | 259 | <code><var>a</var>*<var>c</var></code> will take <var>x</var> + <var>z</var> cycles, and |
255 | 260 | <code><var>b</var>*<var>c</var></code> will take <var>y</var> + <var>z</var> cycles. |
256 | Because addition is monotonic — if x > y then x + z > y + z — whichever branch was the "winner" of <code><var>a</var>+<var>b</var></code>, | |
261 | Because addition is monotonic — if x > y then x + z > y + z — whichever branch was the "winner" of <code><var>a</var>+<var>b</var></code>, | |
257 | 262 | the same branch will be the winner of <code>(<var>a</var>*<var>c</var>)+(<var>b</var>*<var>c</var>)</code>. |
258 | 263 | Also, in this branch, the input set to <var>c</var> will still be <var>T</var>, the output set of the winning branch of <code><var>a</var>+<var>b</var></code>. |
259 | 264 | Thus the final result will be the same. (See below for much more on this.)</p> |
276 | 281 | |
277 | 282 | <p>For Cabra programs to form a full-fledged ring, every program would need to have a unique additive inverse. |
278 | 283 | That is, for every program <var>a</var>, there would need to be another program <var>b</var>, |
279 | where <code><var>a</var>+<var>b</var></code> ≡ <code>BOTTOM</code>. | |
284 | where <code><var>a</var>+<var>b</var></code> ≡ <code>BOTTOM</code>. | |
280 | 285 | But there can be no such program, as Cabra has been defined: if <var>a</var> terminates, then there's nothing <var>b</var> can do to |
281 | 286 | stop <var>a</var> from terminating.</p> |
282 | 287 | |
283 | 288 | <p>So Cabra programs do not form a ring. Further, it's unclear what would have to change to allow this. |
284 | 289 | A simple instruction <code>HANGOTHERS</code> could be defined as sort of throwing a monkey wrench into every other |
285 | currently executing program: <code><var>a</var>+HANGOTHERS</code> ≡ <code>HANGOTHERS+<var>a</var></code> ≡ <code>BOTTOM</code>. | |
290 | currently executing program: <code><var>a</var>+HANGOTHERS</code> ≡ <code>HANGOTHERS+<var>a</var></code> ≡ <code>BOTTOM</code>. | |
286 | 291 | But every element is supposed to have a <em>unique</em> additive inverse, and this doesn't do that, because <code>HANGOTHERS</code> |
287 | 292 | causes every other program to hang.</p> |
288 | 293 | |
340 | 345 | |
341 | 346 | <p>Also, both of these approaches would, naturally, require both of the parallel programs to terminate before |
342 | 347 | their results could be merged to form the combined result (whether it be union or intersection.) This means that if either of them was <code>BOTTOM</code>, |
343 | the result would be <code>BOTTOM</code> — which in turn suggests that <code>BOTTOM</code> | |
348 | the result would be <code>BOTTOM</code> — which in turn suggests that <code>BOTTOM</code> | |
344 | 349 | would be an annihilator for addition as well as for multiplication, and that (at least in the union case) <code>SKIP</code> |
345 | 350 | also serves as a neutral element for both multiplication and addition. |
346 | 351 | This is less than swell, in terms of conforming to ring axioms, because one theorem of ring theory is that |
347 | 352 | the multiplicative identity and the additive identity are equal iff the ring consists of <em>only one element</em>, |
348 | 353 | which is clearly not the case here.</p> |
349 | 354 | |
350 | <p>(I think, also, that if you do manage to have a "ring" where 1 ≡ 0, but where there are clearly elements that aren't | |
355 | <p>(I think, also, that if you do manage to have a "ring" where 1 ≡ 0, but where there are clearly elements that aren't | |
351 | 356 | either 0 or 1, it's that the additive operation and multiplicative operation are really the <em>same</em> operation |
352 | 357 | under the semantic equivalence relation. One of my very early designs for Cabra came up against this, and it's |
353 | 358 | somewhat intuitive once you think about |
354 | 359 | it: if two programs which <em>don't depend on each other at all</em> have some given result |
355 | 360 | when one is executed after the other, they'll have the <em>same</em> result when |
356 | they are executed concurrently — because they don't depend on each other at all! Thus | |
361 | they are executed concurrently — because they don't depend on each other at all! Thus | |
357 | 362 | in this case <code>+</code> = <code>*</code> |
358 | 363 | and we're really talking about something that's a monoid or group or something, <em>not</em> a ring.)</p> |
359 | 364 | |
365 | 370 | |
366 | 371 | <h3>Other Algebras</h3> |
367 | 372 | |
368 | <p>There are ways to address the problems of Cabra — or otherwise try to make it more interesting — | |
373 | <p>There are ways to address the problems of Cabra — or otherwise try to make it more interesting — | |
369 | 374 | by formulating other algebras using other sets of axioms.</p> |
370 | 375 | |
371 | 376 | <p>Take, for example, Kleene algebras. |
372 | A Kleene algebra is a dioid with an additional unary postfix operator *: <var>S</var> → <var>S</var>. | |
377 | A Kleene algebra is a dioid with an additional unary postfix operator *: <var>S</var> → <var>S</var>. | |
373 | 378 | It denotes a kind of additive closure: for any element <var>a</var>, |
374 | <var>a</var>* ≡ 0 + <var>a</var> + (<var>a</var> * <var>a</var>) + (<var>a</var> * <var>a</var> * <var>a</var>) | |
379 | <var>a</var>* ≡ 0 + <var>a</var> + (<var>a</var> * <var>a</var>) + (<var>a</var> * <var>a</var> * <var>a</var>) | |
375 | 380 | + (<var>a</var> * <var>a</var> * <var>a</var> * <var>a</var>) + ... Kleene algebras are used for such things |
376 | 381 | as the theory of regular expressions, where the Kleene star indicates "zero or more occurrences."</p> |
377 | 382 | |
378 | 383 | <p>If we try to extend Cabra from a dioid to a Kleene algebra by adding a Kleene star, we appear to get a nonplussing |
379 | 384 | result. Since <code><var>a</var></code> always takes fewer cycles than <code><var>a</var>*<var>a</var></code> |
380 | (except when <var>a</var> is <code>SKIP</code>, and in that case <code><var>a</var>*<var>a</var></code> ≡ <code><var>a</var></code>,) | |
385 | (except when <var>a</var> is <code>SKIP</code>, and in that case <code><var>a</var>*<var>a</var></code> ≡ <code><var>a</var></code>,) | |
381 | 386 | and since any <var>a</var> takes fewer cycles than <code>BOTTOM</code>, it appears that |
382 | <code><var>a</var>*</code> ≡ <code><var>a</var></code> in Cabra.</p> | |
387 | <code><var>a</var>*</code> ≡ <code><var>a</var></code> in Cabra.</p> | |
383 | 388 | |
384 | 389 | <p>What does that get us? I'm not sure. I suspect nothing, unless there is some neat property of the |
385 | 390 | ordering induced by the Kleene algebra that shows up. But it doesn't seem worth checking, to me.</p> |
402 | 407 | |
403 | 408 | <h2>History</h2> |
404 | 409 | |
405 | <p>I came up with the idea to make a language whose programs formed a ring shortly after getting Burro basically done — | |
410 | <p>I came up with the idea to make a language whose programs formed a ring shortly after getting Burro basically done — | |
406 | 411 | fall or winter of 2005. I didn't develop the idea until around the spring of 2007, when it occurred to me that parallel and sequential execution |
407 | 412 | could work for the operators. Developing the language itself (and compromising on a dioid) occurred in late summer and fall of 2007.</p> |
408 | 413 |