Application Center - Maplesoft

App Preview:

Maple Programming: 4.1 & 4.2: From execution group to procedure

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application


 

4.01and4.02.mws

Programming in Maple

Roger Kraft
Department of Mathematics, Computer Science, and Statistics
Purdue University Calumet

roger@calumet.purdue.edu

4.1. Introduction

An idea that we keep returning to is that there are two ways to represent a mathematical function in Maple, as either a Maple expression or as a Maple function. As we showed in the last chapter, the underlying idea of Maple expressions is a data structure. In this chapter we show that the underlying idea of Maple functions is a procedure. Recall that our initial definition of a data structure was that it is a collection of data. Our initial definition of a procedure is that it is a collection of instructions to Maple. But just as a data structure is more than just a collection of data, a procedure is more than just a collection of instructions. In this chapter we see what we mean by a collection of instructions, how we turn a collection of instructions into a procedure, and why a procedure is more than just the collection of instructions. We show that Maple functions are a special case of procedures, we compare mathematical functions to Maple procedures to see what they have in common and how they differ, and we see how mathematical functions can be represented by Maple procedures. We look at several examples of procedures, some that represent mathematical functions and some that do not, and we see how procedures can manipulate data structures.

>   

4.2. From execution group to procedure

A procedure is essentially a collection of instructions, but this is an over simplification. For example, an execution group  is a collection of instructions to Maple but, as we will see, an execution group is not a procedure.  Let us look at a simple example.

Every positive integer can be decomposed into its prime factorization. Maple has a command to do this.

>    ifactor( 650650 );

``(2)*``(5)^2*``(7)*``(11)*``(13)^2

Let us find a sequence of Maple commands that will compute for us the largest prime in an integer's prime factorization. The last command produced a (nested) data structure as its output. The largest prime factor is contained in the last piece of that data structure. We can use the op  command to get that last piece.

>    op( nops(%), % );

``(13)^2

And we can use another op  command to get the base of the exponential.

>    op( 1, % );

``(13)

Another op command will get the largest prime from out of the parentheses.

>    op( 1, % );

13

Now let us put these commands together in an execution group that will always compute the largest prime factor contained in a positive integer n . To understand how this execution group "works", compare the comment to the right of each command with the command's output line below the execution group.

>    650650;           # Choose a positive integer.

>    ifactor( % );     # Factor it.

>    op( nops(%), % ); # Pick off the largest (i.e., last) factor.

>    op( 1, % );       # Remove the exponent (if there is one).

>    op( 1, % );       # Remove the parentheses.

650650

``(2)*``(5)^2*``(7)*``(11)*``(13)^2

``(13)^2

``(13)

13

Suppose that we only want to see the final result. We can replace semicolons with colons to suppress all the outputs except for the final one.  

>    650650:

>    ifactor( % ):

>    op( nops(%), % ):

>    op( 1, % ):

>    op( 1, % );

13

If we go back and change the value of the positive integer, we can do the same calculation for a different number. (Try this execution group with several different positive integers.) So we can say that this execution group takes a positive integer n  as an "input" and returns as an "output" the largest prime number in the prime factorization of n .

>   

So now we have a collection of Maple commands that we have combined into an execution group and the execution group performs a useful calculation for us. Since this calculation might be useful to us later on, we would like to be able to reuse the execution group. But this execution group is not very convenient to reuse. To use it later on you either have to go back in the worksheet to where the execution group is and use it or you have to cut and paste the execution group to some other place in the worksheet and then use it. And there is no way that we could use this execution group in the middle of some expression that we wanted to compute. This problem of not being able to conveniently reuse a collection of instructions is one motivation for the idea of a procedure .

What would make the execution group easier to use? First, it would be nice if the group of commands that make up the execution group could be given a name so that we could refer to them from anywhere in our worksheet, much like we can give an expression or a function a name and refer to it from anywhere in a worksheet. Second, it would be nice if we could tell the execution group, at the same time that we refer to it by its new name, what integer it is we want it to work on. Suppose we gave the execution group the name largest_prime . It would be nice if we could tell the group of instructions to work on the integer 650650 by using something like largest_prime(650650)  (which should look to you a lot like a function call).

>   

Here is how we do exactly what we described in the last paragraph. We convert our execution group into a procedure using the following procedure definition .

>    largest_prime := proc(n)

>       ifactor( n );     # Factor the input.

>       op( nops(%), % ); # Pick off the last factor.

>       op( 1, % );       # Remove any exponent.

>       op( 1, % );       # Remove the parentheses.

>    end;

largest_prime := proc (n) ifactor(n); op(nops(%),%); op(1,%); op(1,%) end proc

Notice several things about the procedure definition. The procedure definition itself begins with the word proc  (which is an abbreviation of " proc edure") and ends with the word end . The assignment operator in the first line assigns the procedure a name. We gave our procedure the name largest_prime . The input has moved to a different place from where it was in the execution group. The input to the procedure (which we named n ) appears inside the parentheses after the word proc . The procedure definition then has four Maple commands in it, almost, but not exactly, the same four commands that are in the execution group. (Find the one difference.)

>   

Now here is one very big and very important difference between the procedure definition and the execution group. When you put the cursor inside the procedure definition and hit the Enter key, you do not execute the instructions in the procedure like you would execute the instructions in an execution group. Instead, you only inform Maple about the procedure and its name. The name we choose becomes an assigned variable and the value of this variable is the definition of the procedure. If you have not yet "executed" the above procedure definition, do so now. Then the following command will remind us of the definition of our procedure.

>    eval( largest_prime );

proc (n) ifactor(n); op(nops(%),%); op(1,%); op(1,%) end proc

So how do we execute the instructions in the procedure? We use a procedure call . For example, we can call our new procedure with the input 650650 .

>    largest_prime( 650650 );

13

But now we can also call our procedure many times with many different inputs.

>    seq( largest_prime(i), i=550550..550560);

13, 101, 68819, 550553, 1031, 739, 137639, 971, 5857, 5051, 37

We just used our procedure ten times! We can also use the result from our procudure in an expression.

>    evalb( largest_prime(650650) = largest_prime(550550) );

true

So we see that our procedure is very convenient to use and reuse. The fact that we have named the instructions in the procedure makes the procedure a lot more useful than the execution group. The procedure can now be used anywhere in our worksheet, and in any expression that we want.

>   

Exercise : The result from the ifactor  command seems to be in a somwhat unusual form.

>    ifactor( 650650 );

``(2)*``(5)^2*``(7)*``(11)*``(13)^2

>    ifactor( 4735616809 );

``(7)^3*``(11)^4*``(23)*``(41)

Determine the exact structure of the data structure returned by ifactor . Can you create one of these data structures yourself?

>   

Exercise : In our original execution group, we changed the semi colons at the ends of the command lines to colons so that we would only see the final result of the execution group. Notice that the commands in the procedure body all have semi colons at the end of them and yet we do not see any of the intermediate results from the procedure calls, only the final result. Go back to the procedure definition and change all  of the semicolons to colons and then re-execute the procedure definition. What affect does this have?

>   

For some practical tips on how to work with execution groups and procedure definitions, see the last section of this chapter.

>   

>