The following discusses some additions to the ALE description language which are included in TRALE .
TRALE's logical variable macros, unlike ALE macros, use logical variables in their definitions rather than true macro variables. Logical variables entail structure-sharing if used more than once in a predicate. For example, the Prolog expression foo(X,X) means that the two arguments of foo are structure-shared.4.13 True macro variables, on the other hand, simply serve as place holders and their multiple occurrence does not entail structure sharing. This makes a difference when a formal parameter to a macro occurs more than once in a macro definition, e.g.:
In this ALE macro (which uses true macro variables), F's and G's values will not be shared in the result. That is, foo(a,b) for types, a and b, will expand to
in which F and G are not structure-shared unless a is extensional.4.14 One way to make the two features' values structure-shared is to substitute a (logical) variable as an actual parameter for X, i.e. foo(A,b). Note that the first argument of the macro foo here is a variable rather than an atom. This variable is a ``logical'' variable because it is used as a first-class citizen of ALE's description logic, rather than at the macro level. In this case the macro expands to the following:
TRALE's logical variable macros, on the other hand, automatically interpret macro parameters such as X and Y as logical variables, and thus implicitly enforce structure-sharing with multiple occurrences. For example:
will automatically structure-share the values of F and G. The infix operator :=/2 indicates a logical variable macro.
Guard declarations for macros can optionally be applied to these parameters by appending the guard with a hyphen:
This declaration says that X must be consistent with type a, and Y must be consistent with type b for this macro clause to apply. If it does, F's and G's values are shared. Thus foo(a,b) expands to the following:
Note that ALE macros can still be declared (with macro/2). As in ALE , @ is used to call a macro in a description. Let us assume that this signature is defined:
type_hierarchy bot person gender:gen nationality:nat name:name gen male female nat american canadian name john mary .
The following macros can then be defined in the theory file:
man(X-name,Y-nat) := (person, name:X, gender:male, nationality:Y). woman(X-name,Y-nat) := (person, name:X, gender:female, nationality:Y).
The above macros can now be called in feature descriptions using @ as in these lexical entries:
john ---> @ man(john,american). mary ---> @ woman(mary,canadian).
The integrity of lexical entries can be checked by lex/1. Given the above information for example, lex john results in the following output in TRALE :
| ?- lex john. WORD: john ENTRY: person GENDER male NAME john NATIONALITY american ANOTHER? n. yes
In addition, one may check the integrity of macro definitions by macro/1. In this case, macro woman(X,Y) produces the following output:
| ?- macro woman(X,Y). MACRO: woman([0] name, [1] nat) ABBREVIATES: person GENDER female NAME [0] NATIONALITY [1] ANOTHER? n. yes
W. Detmar Meurers, Ohio State University 4.15
Macros can be hierarchically organized by calling one macro in the definition of another. The macro X occuring in the definition of a macro Y then can be referred to as a supermacro of X. And conversely, Y is a submacro of macro X.
The notions of sub- and supermacro thus in one sense are parallel to the notion of sub- and supertype. But it is important to keep in mind that ontologically macros and types are very different; in particular an object of a type will also be of one of its subtypes, and of exactly one of its most specific subtypes. There is no equivalent to this with macro hierarchies, which are just subsumption hierarchies of some descriptions that were given names. Different from types, macros have no theoretical status; they just serve to write down a theory more compactly.
In terms of the macro hiearchy comands below, note that (parallel to types) the sub- and supermacro relations only include macros on the same level, not those embedded under features.
This file provides the following top-level predicates, where
<(sub/super)macro>
is the macro name (incl. its argument
slots). Many of the predicates exist in two version, one that returns
single results and can be backtracked into, and the other (same
predicate name, but ending in s) which returns the list of all
results. Note that the list returned by the second kind of predicates
is sorted though. Also, it is worth noting that the predicates
returning a list will always succeed (they return a [] in the case
where setof would fail).
submacro(<macro>,<submacro>).
submacros(<macro>,<list(submacros)).
supermacro(<macro>,<supermacro>).
supermacros(<macro>,<list(supermacros)>).
show_submacros(<macro>).
show_all_submacros(<macro>).
show_supermacros(<macro>).
show_all_supermacros(<macro>).
show_all_macros.
shows the entire macro hierarchy
macro(<macro>)
shows the most general satisfier of the description abbreviated
by the macro (predicate provided by core ale.pl)
is_macro(<macro>)
returns every macro that's defined (if tracked back into)
macros(<list(macro)>)
returns list of macros that are defined
most_specific_macro(<macro>)
most_specific_macros(<list(macro)>)
most_general_macro(<macro>)
most_general_macros(<list(macro)>)
isolated_macro(<macro>)
isolated_macros(<list(macro)>)
Isolated macros are those that are most general and most specific
at the same time, i.e. they neither occur in other macro
definitions nor are they defined in terms of other macros.
Since HPSG theories usually formulate constraints about different kind of objects, the grammar writer usually has to write a large number of macros to access the same attribute, or to make the same specification, namely one for each type of object which this macro is to apply to. For example, when formulating immediate dominance schemata, one wants to access the VFORM specification of a sign. When specifying the valence information one wants to access the VFORM specification of a synsem object. And when specifying something about non-local dependencies, one may want to refer to VFORM specifications of local objects.
TRALE therefore provides a mechanism which derives definitions of macros describing one type of object on the basis of macros describing another type of object - as long as the linguist tells the system which path of attributes leads from the first type of object to the second.
The path from one type of object to another is specified by including a declarations of the following form in the grammar:
Such a statement is interpreted as: From type1 objects you get to type2 objects by following path path.
Since only certain macros are supposed to undergo this extension, they are specified using slightly different operators than standard TRALE macros: access macros are specified using the ':==' instead of the ':=' operator of ordinary macros. The type of the macro is determined on the basis of the access suffix. The typing of each of the arguments (if any) is added using the - operator after each argument.
To distinguish the macro names for different type of objects, a naming convention for macros is needed. All macros on objects of a certain type therefore have the same suffix, e.g., "_s" for all macros describing signs. The type-suffix pairing chosen by the linguist is specified by including declarations of the following form in the grammar:
Such a statement declares that the names of macros describing objects of type type end in suffix.
So the extend access mechanism reduces the work of the linguist to providing
Access macros are not compiled directly. Instead the access macros
must be translated to ordinary TRALE macros at some point before
compiling a grammar using a call to
extend_access(<FileList>,<OutFileName>).
, where
<FileList>
is a Prolog list of Filenames containing access
macro declarations and <OutFileName>
is a single file
containing the ordinary TRALE macros. Note that this resulting file
needs to be explicitly loaded as part of the theory file that one
compiles (as usual, using compile_gram
/1) in order for those
macros to be compiled as part of the grammar.
As an example, say we want to have abbreviations to access the VFORM of a sign, a synsem, local, cat, and a head object. Then we need to define a macro accessing the most basic object having a VFORM, namely head:
Second, (once per grammar) access_suffix and access_rule declarations for the grammar need to be provided. The former define a naming convention for the generated macros by pairing types with macro name suffixes. The latter define the rules to be used by the mechanism by specifying the relevant paths from one type of object to another.
This results in the following macros to be generated:
vform_h(X) | := | vform:X. |
vform_c(X) | := | head:vform_h(X). |
vform_l(X) | := | cat:vform_c(X). |
vform_s(X) | := | loc:vform_l(X). |
vformwhat_a_great_suffix(X) | := | synsem:vform_y(X). |
If we were only interested in a vform macro for certain objects, say those of type sign and synsem, it would suffice to specify access rules for those types instead of the access rules specified above. The following specifications would do the job:
The result would then be:
vform_h(X) | := | vform:X. |
vform_s(X) | := | loc:cat:head:vform_h(X). |
vformwhat_a_great_suffix(X) | := | synsem:loc:cat:head:vform_h(X). |
Whenever there is an object of type main_verb, its AUX and INV feature values must be set to minus. In the case of auxiliaries, their AUX feature has to be plus but their INV feature could be either plus or minus.
The following example shows a TRALE logical variable macro. This macro assumes subject verb agreement holds.
vp(Ind):= synsem:local:(content:index:Ind, cat:subcat:[synsem:local:content:index:Ind] ).
As mentioned in subsection T4.2.1, TRALE treats variables used in TRALE macro defini-tions (:=) as logical variables and therefore, assumes structure-sharing between multiple occurrences of such variables. Using a TRALE logical variable macro, we ensure that the values of the INDEX feature of the verb phrase and of the subject are structure-shared. Therefore,
is equivalent to:
synsem:local:(content:index:(Ind, person:third, number:singular), cat:subcat:[synsem:local:content:index:Ind])
In the above feature structure, the values of both INDEX features are structure-shared. Had we used a regular ALE macro (using macro/1), we would have reached a similar result but the values of the INDEX features would simply have been structure-identical.
We can also use the type guard declaration of TRALE macros to make sure that Ind is consistent with the type ind. This can be achieved by adding the guard to the head of the macro definition as follows:
vp(Ind-ind):= synsem:local:(content:index:Ind, cat:subcat:[synsem:local:content:index:Ind]).