6.19 Example: A Famous Triangle¶
In this example we write some functions that display Pascal’s triangle. Pascal’s triangle It demonstrates the use of piece-wise definitions and some output operations you probably haven’t seen before.
To make these output operations available, we have to expose the domain OutputForm. OutputForm See ugTypesExpose for more information about exposing domains and packages.
)set expose add constructor OutputForm
OutputForm is now explicitly exposed in frame G82322
Define the values along the first row and any column i.
pascal(1,i) == 1
Type: Void
Define the values for when the row and column index i are equal. Repeating the argument name indicates that the two index values are equal.
pascal(n,n) == 1
Type: Void
pascal(i,j | 1 < i and i < j) ==
pascal(i-1,j-1)+pascal(i,j-1)
Type: Void
Now that we have defined the coefficients in Pascal’s triangle, let’s write a couple of one-liners to display it.
First, define a function that gives the n-th row.
pascalRow(n) == [pascal(i,n) for i in 1..n]
Type: Void
Next, we write the function displayRow to display the row, separating entries by blanks and centering.
displayRow(n) == output center blankSeparate pascalRow(n)
Type: Void
Here we have used three output operations. Operation outputoutputOutputForm displays the printable form of objects on the screen, centercenterOutputForm centers a printable form in the width of the screen, and blankSeparateblankSeparateOutputForm takes a list of nprintable forms and inserts a blank between successive elements.
Look at the result.
for i in 1..7 repeat displayRow i
Compiling function pascal with type (Integer,Integer) ->
PositiveInteger
Compiling function pascalRow with type PositiveInteger -> List
PositiveInteger
Compiling function displayRow with type PositiveInteger -> Void
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
Type: Void
Being purists, we find this less than satisfactory. Traditionally, elements of Pascal’s triangle are centered between the left and right elements on the line above.
To fix this misalignment, we go back and redefine pascalRow to right adjust the entries within the triangle within a width of four characters.
pascalRow(n) == [right(pascal(i,n),4) for i in 1..n]
Compiled code for pascalRow has been cleared.
Compiled code for displayRow has been cleared.
1 old definition(s) deleted for function or rule pascalRow
Type: Void
Finally let’s look at our purely reformatted triangle.
for i in 1..7 repeat displayRow i
Compiling function pascalRow with type PositiveInteger -> List
OutputForm
+++ |*1;pascalRow;1;G82322| redefined
Compiling function displayRow with type PositiveInteger -> Void
+++ |*1;displayRow;1;G82322| redefined
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
Type: Void
Unexpose OutputForm so we don’t get unexpected results later.
)set expose drop constructor OutputForm
OutputForm is now explicitly hidden in frame G82322