Apertium-recursive/Formalism

From Apertium
Jump to navigation Jump to search

A proposal for a recursive transfer rule formalism.

Basic Rule Syntax

Rules consist of a node type, a weight (optional?), a pattern, and an output.

NP -> 2: @det @adj @n {3 2 1} ;

This gathers an det node, a adj node, and an n node and produces an NP node. Once all rules have been applied, the nodes they have gathered will be output according to their patterns. In this case in the order n adj det (the 3rd, the 2nd, the 1st).

The weight of a parse is the sum (?) of all the rules involved in producing it and the parse with the lowest weight is output. There should probably be an additional factor of how many unconsolidated pieces a parse has so we prefer more complete parses (that is, "NP cnj NP" as 3 separate nodes has a lower weight than the consolidated version, but we want the consolidated one).

Multiple rules which produce the same node type can be joined with pipes:

NP -> 1: @det @n {2 1} |
      2: @num @n {1 2} ;


Comments
  • When you say "output" do you mean immediately? or do you mean the AST will be built with that order in mind? - Francis Tyers (talk) 05:48, 13 March 2019 (CET)
    • It uses the patterns to build the tree bottom-up and then when that's done it applies the output sections top-down (that way the verb phrase can set case on the noun phrase which can then set case on the noun). Popcorndude (talk) 14:59, 13 March 2019 (CET)
  • I guess the weights should also be lexicalised, but a priori rule weights are probably also a good idea(?) - Francis Tyers (talk) 05:48, 13 March 2019 (CET)
  • Why isn't it @det @adj @n etc. (per below)? —Firespeaker (talk) 05:53, 13 March 2019 (CET)
    • Because I changed it partway through writing this page and forgot to fix this part. Popcorndude (talk) 14:59, 13 March 2019 (CET)

Attribute Lists

A list of attributes can be defined like this:

gender = m f GD ;
number = sg pl ND ;

Lexical Units

Lexical units are matched like this:

potato@n.sg ! matches "potato" with tags <n> and <sg>, possibly with others
@n          ! matches any noun

Any of these literals can be replaced with an attribute category using $

potato@n.$number ! matches potato<n><sg> and potato<n><pl>
vegetable = potato carrot radish ;
$vegetable@n.sg  ! matches potato<n><sg>, carrot<n><sg>, and radish<n><sg>

The last one would probably also match potato<n><m><sg>, potato<sg><n>, and potato<x><sg><bloop><n>

Variables

A node can have variables attached to it. Lexical units have variables corresponding to any attribute categories that match their tags.

NP.number./case.gender/ -> @adj.$number @n.$number.$gender {2(case=$case) 1(case=$case)} ;

This rule specifies that NP has 3 variables associated with it. The / before case indicates it only appears in the target language and the / after gender indicates it only occurs in the source language. Since number has neither, it appears in both. The NP will initially have a value for $number which will the number marking of the adjective and noun (which must match) and for $gender, which will be the gender tag of the noun. $case will initially be empty. If the value of $case is set by some other rule further up the tree, then the case tag will be set on both lexical units in the output phase, otherwise they will keep their default marking.

Values can also be transferred between nodes in the output phase:

VP -> NP @v {2(number=1.number, gender=1.gender) 1(case=nom)} ;

This makes the verb agree with the subject in number and gender and sets the subject's case to <nom>.

The 3 possible assignments are "attr=literal", "attr=index.attr", and "attr=$var".

Similar patterns can be used if the output is a literal lexical unit with agreement:

el@det.def.[1.gender].sg
el@det.def.$gender.sg

Variable Conflicts

I have yet to deal how to have a rule with multiple variables that all reference the same attribute category. I have 3 potential ways of handling this:

! Desired pattern: adj1 adj2 n1 n2
! adj1 and n2 have the same case, as do adj2 and n1

! Option 1: variable subscripts
@adj.$case#a @adj.$case#b @n.$case#b @n.$case#a

! Option 2: require multiple attribute lists
case = nom acc dat ;
case2 = nom acc dat ;
@adj.$case @adj.$case2 @n.$case2 @n.$case

! Option 3: conditionals and variables that aren't attribute names
@adj.$case @adj(case=$othercase) @n(case=$othercase) @n.$case
! I say "conditionals" because this syntax makes it easy to have things like
@n(case=$othercase not $case)
@adj(case=$othercase not nom)

I find it difficult to come up with situations in which this would be needed, but in the ones where it is, the conditionals are also wanted, so maybe Option 3 is best, or maybe there should be a way to specify restrictions outside of just the pattern, such as

! using Option 1
XP -> 3: @adj.$case#a @adj.$case#b @n.$case#b @n.$case#a ($case#a != $case#b) {1 4 2 3} ;
! note: this particular syntax conflicts with the current use of ! for comments

Blanks

The current transfer system deal with blanks, so in the output section "_n" is the formatting after node "n", so {1 _1 2} is "change nothing". Adding blanks could be either "_", corresponding to the current system, or they could be inserted automatically. Alternatively, the transfer module could ignore blanks.