next up previous contents
Next: Running and Debugging Up: No Title Previous: Phrase Structure Grammars

Compiling ALE Programs

This section is devoted to showing how ALE programs can actually be compiled. ALE was developed to be run with a Prolog compiler, such as SICStus or Quintus Prolog. As the system was developed with SICStus, which is meant to be compatible with Quintus, ALE should work with either of these Prolog compilers. It would be futile to run ALE with only a Prolog interpreter, as it would be slowed by at least two orders of magnitude. The local systems administrator should be able to provide help in running Prolog. This documentation only assumes the user has figured out how to run Prolog as well as write and edit files. It is otherwise self-contained.

File Management

After firing up Prolog, the following command should be used to load the ALE system:

| ?- compile(AleFile).
where AleFile is an atom specifying the file name in which ALE resides. For instance, in Unix, you might need to use something like: compile('/users/carp/Prolog/ALE/ale.pl')., or a local abbreviation for it like compile(ale). if the system is in a file named ale.pl in the local directory (SICStus, at least, can fill in the ``.pl'' suffix). Note that the argument to compile must be an atom, which means it should be single-quoted if it is not otherwise an atom. After the system has compiled, you should see another Prolog prompt. It is necessary to have write permission in the directory from which Prolog is invoked, because ALE creates files during compilation. But note that neither the grammar nor ALE have to be locally defined; it is only necessary to have local write permission.

ALE source code, being a kind of Prolog code, must be organized so that predicate definitions are not spread across files.

gif For instance, the sub/intro clauses specifying the type hierarchy must all be in one file. Similarly, the definite clauses must all be in one file, as must the grammar rules and macros.

Compiling Programs

ALE can compile a program incrementally to some extent. In particular, the compiler is broken down into five primary components for compiling the type hierarchy, type constraints, the attribute-value logic, the definite clauses and the grammar. Compiling the type hierarchy consists of compiling type subsumption, type unification, appropriateness specifications, and extensionality information. The logic compiler compiles predicates which know how to add a type to a feature structure, how to find a feature value in a type and how to perform feature structure unification. Compiling the grammar consists of compiling the lexicon, empty categories, rules and lexical rules. Macros are not compiled, but are rather interpreted during compilation.

There is one predicate compile_gram/1  which can be used to compile a whole ALE grammar from one file, as follows:

| ?- compile_gram(GramFile).
where GramFile is the name of the file in which the grammar resides. The compiler will display error messages to the screen when it is compiling. But since ALE uses the Prolog compiler to read the files, Prolog might also complain about syntax errors in specifying the files. In either case, there should be some indication of what the error is and which clause of the file contained it.

The following predicates are available to compile grammars and their component parts. They are listed hierarchically, with each command calling all those listed under it. Each higher-level command is nothing more than the combination of those commands below it .

  Command                      Requires            File  Clause
  -------------------------------------------------------------
  compile_gram                 nothing               *
    compile_sig                nothing               *
      compile_sub_type                               *     sub
      compile_unify_type       compile_sub_type  
      compile_approp           compile_unify_type    *     intro
      compile_extensional      compile_approp        *     ext
    compile_cons               compile_sig           *     cons
    compile_logic                                     
      compile_add_to_type      compile_sig
      compile_featval          compile_add_to_type
      compile_u                compile_sig
    compile_dcs                compile_logic         *     if
    compile_grammar            compile_logic         *
      compile_lex              compile_logic         *     --->
      compile_empty            compile_logic         *     empty
      compile_rules            compile_logic         *     rule
The table above lists which compilations must have already been compiled before the next stage of compilation can begin. Thus before compile_grammar can be called, compile_logic must be called (or equivalently, the sequence of compile_add_to_type, compile_featval, and compile_u). Each command with an asterisk in its clauses column in the above table may be given an optional file argument. The file argument should be an atom which specifies the file in which the relevant clauses can be found. The clauses needed before each stage of compilation can begin are listed to the right of the asterisks. For instance, the if clauses must be loaded before compile_dcs is called. But note that compile_unify_type does not require any clauses to be loaded, as it uses the compiled definition of sub_type rather than the user specification in its operation. Thus changes to the signature in the source file, even if the source file is recompiled, will not be reflected in compile_unify_type if they have not been recompiled by compile_sub_type first. If an attempt is made to compile a part of a program where the relevant clauses have not been asserted, an error will result.

Each of the lowest level commands generates a hidden file (e.g. in Unix, one beginning with '.') in the directory from which Prolog was called. ( add_to_type and featval actually generate two files each). These files contain Prolog source code that is then compiled to generate the run-time environment for ALE. Thus it is important to have write permission in the directory from which ALE is being called. While these files are in an ASCII format, they are not intended to be read by ALE users.

As long as these files remain undisturbed, they can be reloaded into ALE, or loaded into a different ALE session called from the same directory, without recompiling the grammar file, by typing:

| ?- reload. 
If these hidden files are loaded into a different ALE session, the grammar file itself must be consulted first:
| ?- consult(GramFile). 

In general, whenever the ALE source program is changed, it should be recompiled from the point of change. For instance, if the definite clauses are the only thing that have changed since the last compilation, then only compile_dcs( FileSpec) needs to be run. But if in changing the definite clauses, the type hierarchy had to be changed, then everything must be recompiled.

Unfortunately, the ALE compiler is itself not very efficient, though it produces rather efficient code. Thus it is always a good idea to recompile as little as possible. The savings in time can be significant.

Compile-Time Error Messages

There are three sources of compile-time messages generated by ALE: Prolog messages, ALE errors, and ALE warnings.

ALE uses Prolog term input and output, thus requiring the input to be specified as a valid Prolog program. Of course, any ALE program meeting the ALE syntax specification will not cause Prolog errors. If there is a Prolog error generated, there is a corresponding bug in the grammar file(s). Prolog error messages usually generate a message indicating what kind of error it found, and just as importantly, which line(s) of the input the error was found in. The most common Prolog error messages concern missing periods or operators which can not be parsed. Such errors are usually caused by bad punctuation such as missing periods, misplaced commas, commas before semicolons in disjunctions, etc. These errors are usually easy to track down.

Prolog also generates warnings in some circumstances. In particular, if you only use a variable once in a definition, it will report a singleton variable warning. The reason for this is that variables that only occur once are useless in that they do not enforce any structure sharing. There is little use for singleton variables in ALE outside of the Prolog goals in morphological rules and some macro parameters. Usually a singleton variable indicates a typing error, such as typing AgrNum in one location and Agrnum in another. It is standard Prolog practice to replace all singleton variables with anonymous variables. An anonymous variable is a variable which begins with the underscore character. For instance, a singleton variable such as Head can be replaced with the anonymous variable _Head, or even just _, to suppress such singleton variable warnings. Two occurrences of the simple anonymous variable _ are not taken to be co-referential, but two occurrences of something like _Head are taken to be co-referential. In particular, the two descriptions, (foo:X, bar:X) and (foo:_X, bar:_X) are equivalent to each other, but distinct from (foo:_,bar:_) in that the latter description does not indicate any structure sharing. The second description above is considered bad style, though, as it uses the anonymous variable _X co-referentially.

Besides Prolog syntax errors, there are many errors that ALE is able to detect at compile time. These errors will be flagged during compilation. Most errors give some indication of the program clause in which they are found. Some errors may be serious enough to halt compilation before it is finished. In general, it is a good idea to fix all of the errors before trying to run a program, as the error messages only report serious bugs in the code, such as type mismatches, unspecified types, ill-formed rules, etc.

In certain cases, it is preferable to disable those error messages concerned with ALE's inability to add incompatible descriptions to a feature structure. This is especially true during lexicon and empty category compilation, when, due to the interaction of disjunctions and type constraints, the number of such errors can be overwhelming. In ALE 2.0, these errors are automatically disabled during lexicon and empty category compilation, and enabled otherwise. Commands will be added to future versions so that the user may control when these errors should be displayed.

Less serious problems are flagged with warning messages. Warning messages do not indicate an error, but may indicate an omission or less than optimal ALE programming style.

The ALE error and warning messages are listed in an appendix at the end of this report, along with an explanation. The manual for the Prolog in which ALE is being run in will probably list the kinds of errors generated by the Prolog compiler.



next up previous contents
Next: Running and Debugging Up: No Title Previous: Phrase Structure Grammars



Bob Carpenter
Wed Jul 26 14:25:05 EDT 1995