PAL is an acronym for Prototype Authoring Language.

An authoring language is a programming language which has been designed to be used specifically for the production of Computer Based Training software. As such, it has special functions/commands which may not be available in a more general purpose language such as BASIC, Pascal, or C.

Although there are many authoring languages on the market, PAL is superior to these in terms of its matching functions. It provides not only a suite of matching functions that cover most, if not all, of the kinds of response matching that an author would want to use, but also an intelligent spelling assistant. This spelling assistant is built into the matching functions, and will accept (if an author so wishes) answers which contain typographical and spelling errors.


This manual introduces you to PAL (Prototype Authoring Language). It describes the steps you take to get started, and discusses each command in detail.

The purpose of the manual is NOT to explain how to use your computer, or its operating system (MS-DOS); the assumption is that you already know how to do this, and that you are interested in using PAL. To use PAL you need to use the Microsoft QuickC windows and menus environment, therefore you will have to familiarise yourself with this. This manual tells you what you have to do in the QuickC environment, but not how to do it. In addition, you should be familiar with the concepts of CBT. In other words, you know what you want to do, but not necessarily how to do it with PAL.

Please check the following items, and if you are unfamiliar with any of them, refer to your computer manual(s):

default drive
drive (disk drive)
drive identifier (drive name)
parameters/parameter list
reserved words
source file
system prompt

For readers unfamiliar with the principles of CBT, an excellent introduction to the concepts of CBT and Authoring Languages is A Handbook of Computer Based Training by Dean & Whitlock (Nichols Publishing, 1988).


To help you understand the commands and their parameters, this manual uses the following typographic conventions:

< >parameters for you to replace with your own data appear within angle brackets. Also, in descriptions of messages, words contained in these would be replaced by a number when the message is displayed on screen.
[ ]optional parameters appear within square brackets.
...three dots indicate that an entry may be repeated as many times as needed.
|a vertical line indicates 'or'. You may use only one of the options or parameters shown.
{Enter}means press the Enter (Return) key.

These conventions are exemplified in chapter 5.

The words text and model refer to character strings, in other words, characters enclosed within double quotes. Example: "1) This is an example of a string." When you see <text> or <model> in the command format you can either write a string, or use a defined name to which a string has previously been assigned. (See 'Defining Models', chapter 4.6). Note that double quotes are not the same as two single quotes repeated; on your keyboard there should be a special key with double quotes on it.


If the following files are not on the supplied disk, please contact your distributors.
palex.exe tidy.bat

WARNING: Before you do anything else, make a copy of the PAL disk, and use this, rather than the original.


Sometimes words or phrases pertaining to the PAL system are used, with which you may be unfamiliar. Rather than explaining them on each occurrence, there is a reference to the section which deals with them in detail. If there is no reference, and something has not been explained, please be patient, as it will be discussed within a few paragraphs; remember, everything cannot be described at once.



The system requirements are those required for QuickC, namely:

In addition to the system requirements as such, you will also need Microsoft QuickC version 2.0 or later, plus the supporting documentation that is supplied with it, in particular, the introductory book 'Up and Running'. From now on, any reference to the QuickC manual should be taken to mean this book unless specifically stated otherwise.


Before you can run a PAL program, you must set up your computer system. You need do this only once. Once the system has been initialised you can compile and link (convert to machine readable form) your program.

PAL has been written using the 'C' programming language (Microsoft QuickC), and to compile a PAL program you need to use QuickC (version 2.0 or later). However, once an executable program has been made (automatically, when you com pile), the program can run independently of QuickC, on any machine that uses the MS-DOS operating system.

Refer to chapter two (Installing QuickC) of the QuickC manual for details of how to initialise the 'C' system. Note the following points:

When you run the initialisation program, called SETUP, you should use the suggested default values.

To run the PAL system you will need to put the following files in the include directory (details in the QuickC manual):


You may, if you wish, put all the standard library files (those with an .h extension) in the include directory.

After initialisation, the files supplied on the PAL system disk must be copied to various directories that will have been made during the set-up process.

Before you compile a PAL program you must alter the stack size, which should be set to 3072 (3 Kbytes). To do this start QuickC, press Alt (or the equivalent on your keyboard), 0, M (to enter the Make option in the Option menu), then press the tab key until the <Linker Flags> option is highlighted. Press {Enter}. Press the tab key until the cursor is on the Stack Size: option. Type 3072, and press the {Enter} key. The menu will revert to the previous one. Use the tab key to select the <OK> option, and press {Enter}. You should be back in the editor. You need do this operation only once, as QuickC will save the new value on disk. WARNING: for the value to be saved you must exit QuickC correctly ie by pressing Alt, F, X in sequence. If you switch the computer off before doing this, the value will not be saved.

Should you ever get the run-time error message 'Runtime error: R6000 - stack overflow', simply increase the stack size by a few kilobytes. This error will only occur if you write huge programs Inform your PAL system distributors if the problem still exists with a stack size that is greater than 5 Kbytes.


Once you have written your program (details in chapter 3 of this manual), you will want to run it. Before you can do this, you must create a program list which contains palfun.obj plus the name of your file. This is so that your code, and the PAL code supplied can work together. Making a program list is explained fully in the QuickC manual under 'Creating a Program List' in chapter 3). You need to do this only once for any file that you work with.

Chapter three of the QuickC manual tells you how to compile, link, and run a program.

If there are no errors in the syntax of your program coding, the program will automatically start (this is what your students will see). You should then test this program very thoroughly, to ensure that it does what you want it to do. You may run the program as many times as you wish, simply by pressing F5. The program will not need to be compiled or linked—that only has to be done once.

There are two kinds of error that can occur—Author Errors, and typographical/syntactic errors.

2.3.1 Author Errors

These are described in detail in section 4.7. You will have to change the parameters of the relevant commands, because as they stand, you have tried to do something that is not allowed.

2.3.2 Typographical/Syntax Errors

When a program is compiled ('Compiling and Linking', QuickC manual, chapter 3), if there are any typographic/syntactic errors in the code, the screen will split into two parts, the upper part showing the program, and the lower containing a list of errors. In the upper portion of the screen the first error will be highlighted. Correct the error, then press Shift and F3 simultaneously. The highlight bar will move to the next error if there is one, whereupon you should correct it. When you have corrected all errors, save your program, and recompile it. If Shift + F3 is pressed when the highlight bar is at the end of the error list, you will hear a beep (unless it has been turned off), and the bar will move to the line in your program where the first error was.

Once you are satisfied with your program, leave QuickC. You can now run your exe program independently of QuickC by typing its name (without extension) at the system prompt. You can also transfer the file to other disks, and rename it if you wish. (See your operating system manual for details).

Note: You may produce an exe program without using the QuickC editor. (See the QuickC manual for details). However, this is not recommended, as it is time consuming if there are errors to correct.


During the compiling and linking processes a number of files are produced by the QuickC compiler, and are stored in the same directory as your source files. These files (with the extensions obj, ilk, mtd, and sym) should be deleted, to prevent your disk being filled with unwanted files.

There is a small utility program (tidy.bat), which will do this automatically. Type tidy at the system prompt, and all files with the aforementioned extensions (except palfun.obj) will be deleted.


We assume that you are familiar with the concepts of CBT, and have an idea of what you want to accomplish. If you are new to authoring, then the best approach is to start with modest aims, and become familiar with the PAL commands, before you attempt a large program. An experienced programmer might like to tackle a large program from the outset.

As part of our policy of providing a fully integrated CBT authoring language, with the needs of authors, as well as end-users, taken into consideration, we welcome suggestions for improvements and modifications to the PAL functions. If you want to do something, and find it difficult with PAL, let us know, so that we may investigate the possibility of including your suggestion in future releases.


  1. Decide on the content of each frame (screen), the questions you intend to set your students, and the action to take in response to their answers. A flow chart, or other graphical technique, is a useful way of encapsulating your ideas.
  2. Convert your ideas to PAL program code—how to do this can only come from experience! You can use the built-in QuickC editor, or any word-processor of your choice (so long as the file you produce contains only text, with no internal word-processor formatting control characters).
  3. Test your program thoroughly—although it may run, it may not do what you think it does. Pay particular attention to branching functions (described in section 5.5).
  4. Before you present a program to your students, do some trial runs with colleagues or friends who have little or no computing experience. This is likely to show up any unforeseen problems.


For full details of the QuickC editor, refer to the QuickC manual.

NOTE: For a file name you can use a maximum of eight characters, followed by an optional full stop, and a further three characters (ie an extension). If you do not use an extension, then your program will be saved with the extension c. You should use this system default, because when you come to make a program list (PAL manual, section 2.3) the only allowed extensions are c and obj.

When you are satisfied with your program, you should compile it. See PAL User Manual section 2.3 (Compiling and Running a PAL program).


Chapter 4 gives general information about the PAL system, and how you can use it. Please read it before reading chapter 5, as many terms are used in chapter 5 which are introduced and explained here.


The screen is divided into three areas: header, display, and message. The following are prototypical default values, and cannot be altered by an author. Header is one line, and is used for information such as title of program, unit number, frame number, etc. Message is one line, and contains instructions to the student, some of which are generated automatically by certain functions, the rest being at the discretion of the author. The number of lines available for display depends upon the screen which is being used—in most cases 23 lines would be available. In most cases the width of the screen is 80 columns, although the program should run correctly with screens of other widths.

Schematic of the screen. Header is 1 line. Display area is 23 lines. Message area is 1 line.

4.2 COMMANDS—general information

All commands must end with a semi-colon (;). Some commands take parameters, in which case the parameters are contained within left and right brackets, and they are separated by commas. There must be no space between the command name and the opening left bracket, but you may leave spaces between parameters.

You may have as many commands on a line as you wish, spaces and indentation have no effect on commands, although they should be used so that the structure of the code is clear to other authors who may need to change your programs in the future.

Please note that commands are case-sensitive (as are variable names and labels).


The structure of a PAL program is as follows:

     #include < >
     ANSWER <variable name>    SET [,<variable name> SET] ... ;
     MATCHRES <variable name>      [,<variable name>] ... ;

     /* Your code goes here */


At the top of your code you must put the include statement exactly as it is written in this case the angle brackets do not mean you use a variable name of your choice. This ensures that all the PAL commands can be used in your program.

The lines containing ANSWER and MATCHRES are not strictly necessary in all cases; however, if you use getanswer you need to use ANSWER, and if you use the model/answer comparison functions you must declare at least one MATCHRES variable. The variable declarations may extend over more than a single lineyou need not repeat the keywords (ANSWER and MATCHRES), although you can if you wish.

You may declare as many MATCHRES (match result) variables as you need, but you should limit the number of ANSWER variables to ten. The reason for this limit is that a lot of memory is used with ANSWER variables, even if the answers themselves are short, and therefore having a lot of these variables might lead to stack overflow problems (see section 2.2) when you run your program. In practice, you only need one ANSWER variable, since you can test an answer, and then overwrite the variable; you will still have the match result in a MATCHRES variable.

SET is used to initialise the variable, and is necessary due to the way in which the C programming language works.

At the end of your code you must put the word END. Note that nothing must follow it. As its name suggests, it signifies the end of your code.


There is a special command (strictly, it is called a compiler directive) which allows you to include sections of previously written code in a program. This is useful with large programs, as it can improve readability.

#include " <filename.ext> "

The line above will cause the contents of the file to replace the include statement when the program is compiled. You may have as many include files as you like, but it is not a good idea to nest them (ie include a file in an included file).

The files you include should be in the same directory as your PAL source files. Note the use of double quotes to enclose the file name.


All the match functions return a result, which will be one of the set of match results (listed with the relevant command description). Before you can use the result, you must assign, or store, it. The following example shows how this is done.

res3 = findword("red green blue", answer, DEF);

If answer is given as "red", "green", or "blue", res3 = MATCH
If answer is given as ""white"", or ""brown"" etc, res3 = NOMATCH
If Fl was pressed (help required), res3 = HELPREQ
If no answer was attempted, res3 = NOANS

res3 will equal one of the match results, and you can then take appropriate action by using if and goto commands (section 5.5).

Remember that match results can only be assigned to variables that you have listed as MATCHRES; answers can only be assigned to variables that you have listed as ANSWER. MATCHRES and ANSWER are the first things you write in your program—see Program Structure, section 4.3.

Variables may be overwritten if you wish, so rather than having a different name for each answer and each match result, you could declare just one variable for each.


You may have a model answer that you want to use in different commands. To save writing it afresh each time, you can give it a name, and then use that name in its place.


#define rainbow "red orange yellow green blue indigo violet"

Now you can write in your program, for example:

match_any(3, rainbow, answer, DEF );
write("The full list is "); write( rainbow );

The word define must be lowercase. Notice that unlike the commands, there is no semi-colon at the end of the define statement. You may put only one define on a line, and the only other thing allowed on that line is a comment. The name that you define can be only one word (ie no spaces in it), you must use double quotes around what is defined, and no other double quotes are allowed in the definition. Do not use double quotes around the defined name when you use it in commands.

You can use define anywhere in your program, and you can have as many as you like. The only constraint is that you should not overwrite a defined name. (There is a way round this, if you really feel it is necessary see #Define Directive in the 'C for Yourself' manual).


It is possible to write a program that is acceptable to the program compiler, but which contains errors that will be seen when the program is run. These are called Author Errors. An example is given below.


If this command is included in a program, the program will compile without errors, but clearly, column position 100 is meaningless if we are dealing with an 80 column screen. The following message will appear:

Author error in putcursor; values out of range.
Row must be between I and 23 inclusive.
Col must be between I and 80 inclusive.
You set row = 5, col = 100
Press any key to continue ...

Once you have read the message, press any key. The screen will be cleared. The program will not terminate immediately, but will search for other possible author errors (without trying to run the code you have written).

Once you have noted any author errors, correct your program, then re-compile and run it.


Match parameters are used to determine how a matching function will analyse an answer. For example, you may want a student to give an exact answer, and not allow any deviation from this. Match parameters let you do this. You may use the set_match_params function to set the parameters at the start of your program, or alternatively, you may set the parameters each time you use a function. If you wish, you may do neither, and simply use the system default (which is to ignore spelling errors, case, punctuation, and blanks). A final option is to set the parameters at the start of a program, and override them whenever you want to.

The match parameters are:

Bblanks (spaces) important (used in alphamatch only)
Ccase important
Ppunctuation important
Sspelling important
ALLexact character match required
NONEignore blanks, case, punctuation, spelling assistant on
DEFuse default values (either system, or those set using set_match_params). This parameter is not used with set_match_params.

The use of a match parameter restricts a match. Therefore, for example, if the parameter C is used, the case of the answer must match the case of the model for the answer to be accepted. If S is specified, the spelling assistant will be disabled, so that for an answer to be accepted it must contain no spelling errors. In most cases, authors would not want to switch of the spelling assistant.

Important note: if you specify any combination of B, C, or P, the spelling assistant will be disabled, so that the errors described below (4.9) will not be allowed. The reason for this is that it would be impossible to make a judgement as to what is acceptable, and what is not (try it for yourself with the following examples!).

If a PAL program is written to teach the rudiments of MS-DOS, and say the model answer were cd.., if a response were given as cd .., this would clearly be incorrect. If the spelling assistant were active, it would accept the answer, since the space would be considered an insertion.

Or consider a program which is used to teach the writing of business letters. How would an answer M.r be judged?

Clearly, if such things as spaces, punctuation, and case, are important, it is not practical to allow for keyboard errors.


When the spelling assistant is on, it is able to deal with all of the common typographical errors that are made (illustrated below).

Typing errorCorrect wordWrong word

Only one error per word is allowed, unless wildcards or wildcharacters are contained in the model answer, in which case one error for each part of a model contained within these is allowed. For details of wild cards and wildcharacters see section 4.10. Remember that if you make an error in your model, correct answers will be deemed wrong, so please check your model answers carefully.

In addition to dealing with keyboard errors, the spelling assistant is able to deal with what we might call true spelling errors, that is, where a student does not know the correct spelling of a word, or where a word has an optional spelling. Some examples are analyse and analyze, colour and color (we probably would not want to reject an Americanised answer!). To the spelling assistant, the first 'error' appears to be one of substitution (z for s), and the second is one of omission (no u). Any error that can be subsumed under the keyboard rules can be catered for.

Here are some more examples of what the spelling assistant will and will not accept.

testingtestingALLaccept (no errors)
testingtestinNONEaccept (omission)
testingTesstingNONEaccept (insertion)
testingTetsingNONEaccept (transposition)
testingTASTINGNONEaccept (substitution)
testingTESTINGCreject (case)
testingTestingALLreject (case)
fat catfat   catBreject (extra blanks)
testingtesting.Preject (extra punct)
testingtestignPreject (transposition)

Note the final example. Although there is no error in punctuation, the answer is rejected, because of the transposition error; remember that the spelling assistant is disabled when B, C, P, or any combination of these is specified.

Until now, we have used the word punctuation without defining it. For the purposes of the spelling assistant, punctuation characters are defined as follows:

! " £ $ ^ & { } [ ] : ; @ _ ' , . / ~ # | \

You will notice that + - = % < > * ? are omitted from this definition of punctuation.


The wildcharacter is *, and represents zero or more undefined characters. The wildcard is ?, and represents just one undefined character.

When you use a model/answer match comparison command you can put wildcards and wildcharacters in the model answer, so that an answer need not be exactly the same as the model for a match to be found. An example using wildcards illustrates this.

model = "Photo*"

if the answer is given as "photograph" or "photography" or "photo", or even "photo&k$" it will be accepted.

Note that this is in addition to the spelling assistant, which performs a different function, so if the spelling assistant were being used, "hpotographical" would also be an acceptable answer.

Here is an example using wildcharacters:

alphamatch( "analy?e", answer, NONE)

If the answer is analysed or "analyze" or even "analyxe" it will be accepted. Additionally, the spelling assistant, if not disabled, will deal with typing errors, so for example, "aalyte" will be accepted as a match.

From the foregoing examples, it can be seen that although wildcards and wildcharacters are extremely useful, great care must be taken not to use them indiscriminately, otherwise there is the danger of nonsensical answers being accepted.

If you want to use wildcards or wildcharacters in a model answer simply as an asterisk or a question mark, you must place a \ before them. So, if a model is defined as "char\*" it the matching functions will try to find a match with the word char*, whereas if the model is defined as "char", the functions will accept answers such as char, charm, characterisation, etc.


Comments can be inserted anywhere in your program. They may extend over more than one line if you wish. The start of a comment is indicated by /* and the close of a comment by */. There must not be any spaces between the asterisk and the slash. Comments must not be enclosed within other comments, and they cannot be used within text, such as with a model answer.


Braces ({ and }) can be used for two purposes. The first is to clarify the structure of sections of code for human readers, and for this purpose braces may be used freely. The second is to control how the computer interprets your instructions. Some examples will help here.

Example 1

/* only fragments of code are shown */
if( res IS NOMATCH) goto error;
  write("Your answer is wrong, press any key to try again");
  goto getit;

Example 2

  if( res IS NOMATCH)
    write("Your answer is wrong, press any key to try again");
    goto getit;

Normally, only one command is allowed after an if statement (in example 1 it is the goto command). However, if braces are used, a whole series of commands can be used, thus eliminating the need to branch to a different section of the program.


If you want to force a write statement to start a new line on screen, insert \n in the text. You may use as many of these as you like. Example:

write("\nStart on a new line,\n\ntwo blank lines");


You may use all the facilities provided by QuickC; in particular, since counters and scoring are not provided in this prototype, you can use C commands to do this. Refer to the 'C for Yourself' manual for details. Some C language constructs have already been explained, namely include (4.4), define (4.6), comments (4.11), and braces (4.12).


Chapter 5 describes in detail the PAL commands, which have been listed under the following five functional subheadings:

  1. Initialise match requirements
  2. Write to the screen
  3. Get an answer from the keyboard
  4. Compare an answer with a model
  5. Branch to different parts of a program

Refer to the sample program at the end of the User Manual to see how the functions might be used in a complete program. If you have not already done so, please read chapter four, as it introduces and explains many of the terms used here. In particular, section 4.8 explains the match parameters, B, C, P, S, ALL, NONE, DEF in detail.


set_match_params( "[B] [C] [P] [S]" | ALL | NONE )

Sets up standard parameters to be used (where applicable) in all the match functions. These may be overridden (but not changed) by specifying match parameters in a function call. Any combination of the parameters B, C, P, S, in the parameter list, or all (which is equivalent to the ALL option) may be chosen. You may use this function as many times as you wish, but it is suggested that once, at the start of your program is the most appropriate. If you intend to change the parameters frequently, it is better to put them in the match functions.

Spaces in the parameter string are unimportant, for example, "CSP" is a valid input. Only the characters B, C, P, S (or their lowercase equivalents) are allowed in the string. Any other character will cause this author error:

Author error in set_match_pararns: illegal match parameter

Notice that the parameters ALL and NONE should be uppercase only, and that they are not enclosed by quotes. See section 4.8, Match Parameters, for full details of match parameters.

Example: set_match_params( "P" );

When you call a match function, it will check that the punctuation and spelling in an answer matches your model exactly, but the case (capitals or lower) and the number of blanks (only applicable in alphamatch) will not be considered in the match..

Example: set_match_params( NONE );

Resets to the system default, ie the spelling assistant is on, and case, spaces, and punctuation are not important.



Clears the whole screen, including the message area. The cursor is set to row 1, column 1 in the display area.

clearbetween( <row m>,<row n> )

Clears the display screen between row m and row n inclusive. If the cursor is outside the area to be cleared, its position is not changed, otherwise it is set to row m, column 1 in the main display area.

Allowed values:
m ≥ 1, n ≥ m, n ≤ 23 (for 25 line screen).

If the numbers you specify are not in the allowed range, this author error will appear:

Author error in clearbetween: illegal row parameters.
row values must be between 1 and 23 inclusive,
and rowl ≤ row2.
You set: rowl = <row m>, row2 = <row n>


Clears the display area (main screen), but not the header or message areas. The cursor is set to row 1, column 1 in the display area.

header( <text> )

Clears the header area, and writes the text in the header area (maximum one line). The cursor location in the display area is not changed. You must not use the \n control character in the text, and the text must not be longer than 80 characters, otherwise the following author error message will appear:

Author error in header:
Length of text too long, or attempted new line.
Maximum 80 characters allowed.
The text contains <number of chars in text> characters.

message( <text> )

Clears the message area, and then writes the text (maximum one line). The cursor location in the display area is not changed. You must not use the \n control character in the text, and the text must not be longer than 80 characters, otherwise the following author error message will appear:

Author error in message:
Length of text too long, or attempted new line.
Maximum 80 characters allowed.
The text contains <number of chars in text> characters.


This waits for the user to press any key to continue. The message "Press any key to continue..." appears in the message area. The cursor position is not changed.

putcursor( <row X>,<column Y> )

Locates the cursor at row x, column y in the display area. Row must be between 1 and 23 inclusive, and column must be between 1 and 80 inclusive (for a 25×8O screen). If the coordinates are outside allowed range, this author error occurs when the program is run:

Author error in putcursor: values out of range.
Row must be between 1 and 23 inclusive.
Col must be between 1 and 80 inclusive.
You set row = <row x>, col = <column <y>

Example: putcursor(7,10);

Puts the cursor at row 7, column 10 in the display area.

write(<text> )

Writes text of any length, starting at the current cursor location, and changes the current cursor position to the screen position following the last character in the text. If the number of text rows plus the current row number is greater than the number of available rows, scrolling will occur. For any one line, if the number of text columns plus the current column number is greater than the width of the window, wrapround will occur.

You may use the control character \n within the text, to start a new line.

Example: write("This is\n an example\n\n");

Writes This is on one line, an example on the next line, and puts the cursor two rows below the last line of text, at column 1.


getanswer( <variable>, <length> )

This gets an answer from the keyboard, and assigns it to <variable>, which you will have set at the top of the program; later you will use the variable with the model/ answer comparison functions. Remember that <variable> must be an ANSWER type variable.

This function will not accept answers longer than the allowed maximum length (80 characters in the prototype). Additionally, if the value of the length parameter plus the current cursor position is greater than the rightmost column, the following author error will be generated when you run the program:

Author error in getanswer:
length less than 1, or length + current position > border or length > maximum allowed length (80).

You must reposition the cursor, either directly, with the putcursor command, or indirectly by using write.

A continuous line, <length> characters long appears where the answer must be typed. The cursor is put at the beginning of the line, and is not allowed to travel past the end of it, thus constraining the length of the answer. The message "Type your answer. (Back arrow to delete) . Press Enter." appears in the message area, and is removed when the answer is entered. The line is erased as the answer is written, and replaced if the back arrow key is pressed.

Example: getanswer( ans4, 15);

Writes a line 15 characters long starting at the current cursor position, and the previously specified message in the message area. You can now refer to the answer as ans4 when you use the model\answer comparison functions.

mc2( <stem>, <option 1>, <option 2> )

This uses a moving block cursor to accept multiple choice answers. The block is moved by pressing the up/down arrows; the movement is cyclical, so if the block is on the last option, and the down arrow is pressed, the block will move to the first option. The block always appears on the first option when the function is called. An option is selected by pressing the enter key. Help can be requested by pressing the Fl key. The following message appears in the message area:

Up/down arrows to move bar. Enter to select. Fl = help.

The stem can be any length, but the options can be a maximum of 80 characters (ie one line) each. If an option is longer than this, the following message appears at run-time:

Author error in mc: length of an option is greater than maximum allowed (80).

The length of the moving block is set to the length of the longest answer option. The stem and the answer options are written to the screen, starting on the row following the current cursor location, in column one, and separated by one line. If there is not enough room to display the stem and all the options, the following author error will be generated at run time. (If the function automatically cleared the screen an author would not have the option of leaving previous text on display):

Author error in mc:
Not enough screen lines to display all options.
Use one of the clear functions to remove previous text.

The function call need not be written on one line, so if the options are long, each one could be written on a separate line for clarity. However, the stem, and the options must be unbroken. Example:

resb = mc2( "Which of one these statements is correct?",
"In the mc functions, the option lines can be split",
"Options can be written on separate lines" );

This will display the stem and options on the screen, and when the user makes a selection, the variable (resb) will contain his\her selection (in this case either OPT1, OPT2, or HELPREQ).

Remember that the mc functions return MATCHRES values, not ANSWERS, so that res8 will have been declared as a MATCHRES variable at the top of the program.

mc3( <stem>, <o1>, <o2>, <o3> )

As mc2, but with three options.
Returns one of OPT1, OPT2, OPT3, HELPREQ.

mc4( <stem>, <o1>, <o2>, <o3>, <o4> )

As mc2, but with four options.
Returns one of OPTI, OPT2, OPT3, OPT4, HELPREQ.

mc5( <stem>, <o1>, <o2>, <o3>, <o4>, <o5> )

As mc2, but with five options.
Returns one of OPTI, OPT2, OPT3, OPT4, OPT5, HELPREQ.

mc6( <stem>, <o1>, <o2>, <o3>, <o4>, <o5>, <o6> )

As mc2, but with six options.
Returns one of OPT1, OPT2, OPT3, OPT4, OPT5, OPT6, HELPREQ.


In all of these comparison functions, if the match parameter list does not conform to the correct syntax, the following author error will occur:

Author error in match parameter list of a matching function.

Refer to set_match_params (section 5.1), and section 4.7, Match Parameters, for a detailed explanation of what the parameters do.

DEF, which is not used with set_match_params, should be used if you do not want to change any of the parameters that have been set using the set_match_params function. If this function has not been used, or the most recent call reset the parameters to the system default, then DEF equates to NONE.

Note that <match params>, which is used in this section is a shorthand form of "[B] [C] [P] [S]" | ALL | NONE | DEF.

alphamatch( <model>, <answer>, <match params>)

This function looks for a character match between the model and answer. The result can be one of:

MATCH - the answer is acceptable.
NOMATCH - the answer was wrong, or contained too many spelling errors.
NOANS - no attempt was made to answer; {Enter} only pressed.
HELPREQ - the Fl help key was pressed.

Example: res = alphamatch( "cat or dog", ans4, DEF );

findword( <model>, <answer>, <match params> )

This function determines whether the model is contained in the answer. The result.can be one of

MATCH - the answer is acceptable.
NOMATCH - the answer was wrong, or contained too many spelling errors.
NOANS - no attempt was made to answer; {Enter} only pressed.
HELPREQ - the Fl help key was pressed.

Example: findword("Cat", a4, "C" );

If the word cat appears in the answer, a4, then the answer is judged as correct, but if CAT appears, then the answer is wrong (because C, for case, was specified in the parameters list).

match_any( <n>, <model>, <answer>, <match params> )

Searches for any n words from a list in the model, n indicates the minimum number acceptable. The order of the words in the answer is not important.

n must be between 2 and the number of words in the model, or this author error appears:

Author error in match_any: required number of matches is out of range (2 to 9).

If n is greater than 9, this error is generated:

Author error in match -any: number of words in model is greater than the maximum allowed (9).

if n is greater than the number of words in the model, the following author error occurs:

Author error in match_any: required number of matches (<n>) is greater than the number of words (<number of words in model>) in the model answer.

If you wish to search for just one word, you should use the function findword.

The result can be one of:
MATCH - all (or more) required words found.
NOANS - no attempt to answer was made.
NOMATCH - no matching words were found.
HELPREQ - the Fl help key was pressed.
PMx - this indicates a partial match, some of the required words were found in the answer. x is always between 1 and 8, and is always at least one less than the integer <n>


res5 = match_any(3,"red green blue yellow", ans5, "S");

Consider the following answers:
Blue, Red, Yellow returns MATCH
red, blue, green returns MATCH
red blue black green returns MATCH
yellow, blue, white returns PM2


goto <label>

Transfers control to the next statement that follows <label> in the program code. <label> can be any unique name, upper or lowercase, or any combination, but there must not be any spaces in the label. Remember that, as with PAL commands, label names are case sensitive.

<label> can be placed anywhere in the program code, but it must be followed by :, and there must not be any spaces between the label name and the colon.

If there are no commands following the last label, then there must be a semicolon after it.

     :  /* some code */
    QUIT: ;

if( <result variable> IS | ISNT <match result> [AND | OR <result variable> IS | ISNT <match result>] ... ) <command> [ else <command> ]

<result variable> must of course have been previously used with a match function. <match result> can be any one of the possible results that can be returned from a matching function.

<command> can be any single PAL command, very often it will be goto, or a set of commands enclosed in curly brackets (see section 4.10).


  /* some code
  if( res4 IS MATCH) goto OK;
  if( res4 IS HELPREQ) write("Sorry, no help available");
  if( res4 IS NOANS)
    { write(" You must answer!"); pause; goto REPEAT; }
  else goto SUPPORT;
  /* take appropriate action
  goto end;
  /* take appropriate action

Remember that labels do not delimit code, therefore, you must use goto statements to prevent unrequired sections of the program being executed.

You need not test for every possible answer, the else clause (if used) will cover those results you have not specifically tested for.

Note that an else clause matches the last if statement that does not otherwise have an else clause. Curly brackets (described in 4.10) can be used to change this, (or simply to clarify the situation for authors who may need to change your code in the future).


If you want to practise the procedure for compiling and linking a program, then you could go through that procedure, which is explained in the QuickC Manual, and section 2.3 of this manual. If you do this, and if you have a copy of the palex.exe file in the source directory, this original version will be overwritten, but unless you have made changes to the example program code, this will not matter.

if you simply want to see the program in action, you do not need to use QuickC at all. Just run the program, as you would any other, by typing palex at the system prompt.

Due to limitations of the page size of this manual, some write commands could not be shown exactly as they appear on screen; they may extend over many lines here. They are clearly identifiable, because the indentation will be different from that of their immediate neighbours, and will always be the leftmost margin.

This example is small, but it shows how most of the functions can be used. It is designed to show the use of PAL functions, and is not to be taken as a model of good CBT. Ideally, there would be considerable help, and meaningful options, rather than the cryptic messages here, which are used to conserve space. The options of repeating sections of the program an unlimited number of times would not normally be available, but they are used here, so that the user may experiment with the model/answer comparison functions.

                    /* PALEX.C */
#include <>
#define rep_if_r write("\n\n Press R followed by Enter to
  repeat this section,\n or Enter only to continue: ");
  getanswer(al,l); res = match_any(2, "R r",al, ALL); if(
  res IS PM1) goto

MATCHRES res, res2;
  write("WELCOME TO PAL");
  write("Prototype Authoring Language\n\n");
  write("This is an example program, and contains all the commands shown in \n");
  write("the User Manual. The listing for this program is contained in the\n");
  write("manual, and you might like to follow it as you work through this\n");

  header("                 This is the header area");
  write("\n\nThe first example uses a multiple-choice question.");
  res = mc3("PAL is an acronym for:", "Paint all lamp-posts",
            "Please ask loudly", "neither of the above");
  if( res IS HELPREQ )
    write("\nYou requested help. The correct answer is option 3; try again");
  goto repeat_mc;

  if( res IS OPT3)
    write("\nYes, in this context neither of the first two options is right.");
  else write("\nNo, that's not correct.");

  write("\nPAL stands for Prototype Authoring Language.");

  rep_if_r repeat_mc; /* rep_if_r is defined at the top */
  write("\n\nYou have seen how the multiple choice functions 
        work.\nnow let's look at the other model/answer comparison functions,
        \nand their spelling assistant.");

  header("                     The alphamatch function");
  write("\nIf you look at the code, you will see that the
        answer we want is 'blue'.\nIf your answer cannot be analysed by
        the spelling assistant, you will be\nasked to try again,
        so you can play around to see how the system works.\n");

  putcursor(10,1); write("Type your answer - (the correct answer is blue!!) :");
  getanswer( al, 20 );
  res = alphamatch("blue",al, DEF);
  if( res IS MATCH) write("Yes, blue is the correct answer.");
  if( res IS NOMATCH)
    write("Your answer was incorrect. Please try again.");
  goto repeat_am;
  if( res IS HELPREQ) write("No help available - sorry.");
  if( res IS NOANS)
    { write("You MUST answer - try again"); pause; goto repeat_am; }

  rep_if_r AM_SECTN;

  header("       The findword function - (note new match parameters in code)");
  set_match_params(" S ");
  write("\nThis section of the program deals with the
        findword function.\nnotice in the code that the default
        match parameters have been changed.\nspelling is important,
        so the spelling assistant is disabled,");
  write("\nbut case and punctuation are not important.");
  /* max 255 characters on any one line */

  write("\nThe model answer is one word; if you type extra words they 
        will be ignored.\n\nIf your answer is judged correct, you will move to the 
        next section,\notherwise you will be asked to try again.");
  write("\n\nWho was the Prime Minister of Britain in 1988?");

  getanswer( al, 15);
  res = findword("Thatcher", al, DEF);
  if( (res IS NOANS) OR (res IS NOMATCH) OR (res IS HELPREQ) )
    write("\n\nEither you made no attempt to answer, or you asked for 
          help, \nor your answer could not be analysed. Try again.");
    pause; clearbetween(15,20); goto REPEAT_FW;

  /* answer must be MATCH, so needn't test for it */
  write("\n\nWho could forget!");

  rep_if_r FW_SECTN;

  #include "" /* code contained in this file
                                       will be inserted here */

  rep_if_r MA_SECTN;
  write("That's the end of the example program.\n\nFeel free to experiment 
        with the code, (but use a copy!)");
  header("Watch out for exciting new developments from the authors of PAL!");


                      /* MATCHANY.INC */
  header("              The match_any function");
  write("This is the final section, in which the match_any function\nis exemplified.");
  write("Note that the default match parameter (S, which was set earlier)\nis 
        ignored, because NONE is specified in the parameter list for this\nquestion.");

  write("Name four colours of the rainbow (any order).\n\n");
  #define rainbow "red orange yellow green blue indigo violet"

  getanswer(al, 50);
  res = match-any( 4, rainbow, al, NONE);

  if( (res IS NOMATCH) OR (res IS HELPREQ) OR (res IS PMI) OR 
      (res IS PM2) OR (res IS PM3) OR (res IS NOANS) )
    write("\n\nYou need help! Here's a reminder, then try again.\n\nThe colours are: ");
  pause; goto REPEAT_MATCHANY;
    write("\n\nGood. The full list is, of course, ");


alphamatchlooks for a match between the complete model and answer.
clearallclears the complete screen (header, main, and message).
clearbetweenclears the main screen between specified rows.
cleardisplayclears the main screen.
findwordlooks for a particular word in an answer.
getanswergets a student's answer.
gotocontrol to a specified section of program.
headerwrites a specified message in the header row.
ifthe following statement(s) are obeyed when a specified condition is true.
match_anymatches a specified number of words in an answer from a set of words in the model answer.
mc2writes a stem and two multiple-choice options on screen. The user selects one of the options.
mc3 as mc2, with 3 options.
mc4as mc2, with 4 options.
mc5as mc2, with 5 options.
mc6as mc2, with 6 options.
messagewrites a message in the message area.
pauseuntil user presses a key.
putcursorsets cursor at given location.
set_match_paramsdefines how answers will be analysed.
writewrites to the main screen area.
/* and */denote start and end of a comment.
\nin a string (with write command only) is used to start a new line.
;is used at the end of every command.
:is used at the end of a label.


Reserved words cannot be used as variable names, or labels for goto statements. However, they can be used within strings with the write, header, and message commands. In addition to all the QuickC reserved words (refer to 'C for Yourself' manual), there are the following:

ALL             MATCH           OPT4            PM4
AND             NOANS           OPT5            PM5
ANSWER          NOMATCH         OPT6            PM6
END             NONE            OR              PM7
HELPREQ         OPT1            PM1             PM8
IS              OPT2            PM2             MATCHRES
ISNT            OPT3            PM3


Editor's note 2008-01-17. The original printed document contained two indexes: one index for the PAL manual, and one for the dissertation. Sarah Starkey has created a single index that covers the entire dissertation including the PAL manual.

Preface | Contents | 1 Introduction | 2 Review | 3 Req. analysis | 4 Req. documents | 5 Specification | 6 Design | 7 Verification | 8 Discussion | 9 PAL manual | Appendix A | Appendix B | Appendix C | Glossary | References | Index