Category Archives: Code sample

Transitive closure

I figured out how to write the code for Transitive Closure. Here it is in Andl.

// define recursive function
XYT := {{X:='',Y:=''}}
TRANCLO:XYT(XY:XYT) => do {
  TTT := XY[{*Z := Y}] compose XY[{*Z := X}] union XY if(TTT = XY, TTT, TRANCLO(TTT))
}
// call it
TRANCLO(MM[ {X:=MAJOR_P#, Y:= MINOR_P# } ]) [{MAJOR_P#:=X, MINOR_P#:=Y }]

Note

  1. XYT is an expression which provides the type information for what amounts to a function call. This is structural typing, there are no type names.
  2. The symbol ‘=>’ means deferred evaluation, in this case with arguments. A function call by any other name.
  3. The do {} block allows an arbitrary number of statements, and returns the value of the last expression.

I have to confess I’m quite pleased with the outcome.  Here is the equivalent code in Tutorial-D.

/* the function */
OPERATOR TRANCLO ( XY RELATION { X P#, Y P# } ) RETURNS RELATION { X P#, Y P# } ;
    RETURN 
  ( WITH ( XY UNION ( ( XY RENAME ( Y AS Z ) ) 
              COMPOSE ( XY RENAME ( X AS Z ) ) ) ) AS TTT :
    IF TTT = XY THEN TTT /* unwind recursion */
      ELSE TRANCLO ( TTT ) /* recursive invocation */
    END IF 
  ) ;
END OPERATOR ;
/* the call */
( TRANCLO ( MM RENAME ( MAJOR_P# AS X , MINOR_P# AS Y ) ) ) RENAME ( X AS MAJOR_P# , Y AS MINOR_P# )

The similarities are reasonably obvious.

Leave a Comment

Filed under Code sample

99 bottles of Andl beer!

In response to a challenge, I decided to actual solve the problem. Here it is. The lyrics are here: http://www.99-bottles-of-beer.net/lyrics.html

ten := {{ n:=0 },{ n:=1 },{ n:=2 },{ n:=3 },{ n:=4 },{ n:=5 },{ n:=6 },{ n:=7 },{ n:=8 },{ n:=9 }}
hundred := (ten join ten[{nn:=n}]) [ {neg := -10*nn-n,nnn := 10*nn+n}] [nnn>0]
line1 := hundred [{ neg, text := nnn || " bottle" || if(nnn=1,"","s") || " of beer on the wall, " || 
         nnn || " bottle" || if(nnn=1,"","s") || " of beer."}]
line2 := hundred [{ neg:=neg+0.5, text := "Take one down and pass it around, " || (nnn-1) || " bottle" ||
         if(nnn=2,"","s") || " of beer on the wall."}]
line3 := "No more bottles of beer on the wall, no more bottles of beer."
line4 := "Go to the store and buy some more, 99 bottles of beer on the wall."
(line1 union line2) [$] [{text}] union {{text:=line3},{text:=line4}}

The first two lines just generate the sequence. Later there will be a better way to do that. The 4 lines of text are dictated by the song lyrics. Most of the program is fiddly details to precisely match the song lyrics as published, and get the lines in the right order. The end result is a relation containing the song lyrics in the correct order, which is then simply printed.

I found this quite a fascinating exercise. I had to implement IF(,,) but I think the only other control structure needed is user-defined recursive functions. The result is a programming paradigm quite unlike any that I’m familiar with, and surprisingly powerful. And weird.

Leave a Comment

Filed under Code sample, Language