Transfer Rules
Dokumentasjon av transferreglar.
"Apertium is a more complicated and less user friendly version of sed."
Documentation:
-
http://wiki.apertium.org/wiki/Apertium_New_Language_Pair_HOWTO
-
http://wiki.apertium.org/wiki/A_long_introduction_to_transfer_rules
- http://wiki.apertium.org/wiki/Chunking:_A_full_example
Task:
Num Sg (Nom|Acc) + N Sg Gen => Num Sg Nom + N Par
- sme: Leat guokte guoli.
- smn: Láá kyehti kyellid.
Input:
$ echo "Leat guokte guoli" | apertium -d . sme-smn-biltrans ^Leat<vblex><iv><indic><pres><pl3><@+FMAINV>/Leđe<vblex><indic><pres><pl3><@+FMAINV>$ ^guokte<num><sg><nom><@←SUBJ>/kyehti<num><sg><nom><@←SUBJ>$ ^guolli<n><sem_ani><sg><gen><@Num←>/kyeli<n><sem_ani><sg><gen><@Num←>$
Output:
$ echo "Láá kyehti kyellid" | hfst-proc smn-sme.automorf.hfst ^Láá/Leđe<vblex><iv><indic><pres><pl3>$ ^kyehti/kyehti<num><sg><nom>$ ^kyellid/kyeli<n><par>$
Rule 1:Ignore disambiguation errors!
$ echo "Leat guokte guoli" | apertium -d . sme-smn #Leđe #kyehti kyele
So what output do we current have ?
$ echo "Leat guokte guoli" | apertium -d . sme-smn-postchunk ^Leđe<vblex><indic><pres><pl3>$ ^kyehti<num><sg><nom>$ ^kyeli<n><sg><gen>$^.<sent>$
So, what do we actually want to do ?
<n><sg><gen> --> <n><par> || [ <num><sg><nom> | <num><sg><acc>
In Apertium we call the first part (before the two pipes) the "action", and
So:
Pattern = [ <num><sg><nom> | <num><sg><acc> ] <n><sg><gen> Action = <n><sg><gen> --> <n><par> <sg> --> "" <gen> --> <par>
Patterns are defined by "def-cat" entries. The "cat" stands for category.
<def-cat n="num-nomacc"> <cat-item tags="num.sg.nom.*"/> <cat-item tags="num.sg.acc.*"/> </def-cat>
This is a set of two items, one containing nom and one containing acc.
You can change the order of the "cat-items" (they are more or less a set). The
To do "or" in the category entries, you just add more cat-item lines.
<def-cat n="n-sg-gen"> <cat-item tags="n.sg.gen.*"/> </def-cat>
So, to match the pattern "numeral singular in nominative or accusative followed
<pattern> <pattern-item n="num-nomacc"/> <pattern-item n="n-sg-gen"/> </pattern>
Here the order is important, this is a sequence.
The "." is not a regular expression "." it is ><
so:
n.sg.gen.* = <n><sg><gen>(<*>)+ n.*.gen.* = <n><*><gen>(<*>)+
Let´s start to define our rule file:
------------------------------------------------------- <transfer> <section-def-cats> <def-cat n="num-nomacc"> <cat-item tags="num.sg.nom.*"/> <cat-item tags="num.sg.acc.*"/> </def-cat> <def-cat n="n-sg-gen"> <cat-item tags="n.sg.gen.*"/> </def-cat> </section-def-cats> <section-rules> <rule> <pattern> <pattern-item n="num-nomacc"/> <pattern-item n="n-sg-gen"/> </pattern> </rule> </section-rules> </transfer> -------------------------------------------------------
Input:
^guokte<num><sg><nom><@←SUBJ>/kyehti<num><sg><nom><@←SUBJ>$ ^guolli<n><sem_ani><sg><gen><@Num←>/kyeli<n><sem_ani><sg><gen><@Num←>$ |__________________________| |__________________________| Source language (SL) Target language (TL) |_________________________________________________________| Lexical unit (LU) Now we look at the action. Actions are defined within the <rule>. The action may contain different instructions, and most importantly determine the output string. The instructions can work on both the source and target side of the input lexical unit. <action> <out> </out> </action> Output: ^num-noun<SN>{^kyehti<num><sg><nom>$ ^kyeli<n><par>$}$ |______| name |____________________________________________________| Chunk
We define this with:
<chunk name="num-noun"> </chunk>
This is essentially like writing
^num-noun{}$.
Each chunk has a name, some tags and some contents, for example
<out> <chunk name="num-noun"> <tags> <tag><lit-tag v="SN"/></tags> </tags> </chunk> </out>
This is essentially like writing
^num-noun<SN>{}$.
Looking at this in the file context:
------------------------------------------------------- <transfer> <section-def-cats> <def-cat n="num-nomacc"> <cat-item tags="num.sg.nom.*"/> <cat-item tags="num.sg.acc.*"/> </def-cat> <def-cat n="n-sg-gen"> <cat-item tags="n.sg.gen.*"/> </def-cat> </section-def-cats> <section-rules> <rule> <pattern> <pattern-item n="num-nomacc"/> <pattern-item n="n-sg-gen"/> </pattern> <action> <out> <chunk name="num-noun"> <tags> <tag><lit-tag v="SN"/></tags> </tags> </chunk> </out> </action> </rule> </section-rules> </transfer> -------------------------------------------------------
This matches the input pattern <num><sg>(<nom>|<acc) <n><sg><gen>
And outputs:
^num-noun<SN>{}$
What is missing here is the chunk contents (e.g. the lexical units
<chunk name="num-noun"> <tags> <tag><lit-tag v="SN"/></tags> </tags> <lu> <clip pos="2" side="tl" part="whole"/> </lu> </chunk>
- pos = position. the position is defined the order in the pattern.
- side = which side of the LU to output.
- part = a substring within one of the sides of a lexical unit.
__side="sl" part="whole"___ | | |_lem_ | | | | ^guokte<num><sg><nom><@←SUBJ>/kyehti<num><sg><nom><@←SUBJ>$ |__________________________| |__________________________| Source language (sl) Target language (tl)
For "part" we can define our own patterns of substrings, but there
- whole = the whole string kyehti<num><sg><nom><@←SUBJ>
- lem = the lemma kyehti
- tags = the tags <num><sg><nom><@←SUBJ>
- lit = literal
- v = value
- n = name
So, for the rule above, it will currently output:
^num-noun<SN>{^kyeli<n><sg><gen><@Num←>$}$
So, now that we have some output, we can start with the interesting
We´ll start with the easy way, which is just specifying directly what
input is the output from sme-smn-biltrans
<out> <chunk name="num-nomacc"> <!-- Output: ^num-noun --> <tags> <tag><lit-tag v="SN"/></tags> <!-- Output: <SN> --> </tags> <!-- Output: { --> <lu> <!-- Output: ^ --> <clip pos="2" side="tl" part="lem"/> <!-- Output: kyeli --> <lit-tag v="n.par"/> <!-- Output: <n><par> --> </lu> <!-- Output: $ --> </chunk> <!-- Output: }$ --> </out>
The lit-tag instruction outputs strings encased in < and >.
the the output is what we get by calling sme-smn-chunker1
^num-noun<SN>{^kyeli<n><par>$}
Now, how would we output both lexical units ? The output we
^num-noun<SN>{^kyehti<num><sg><nom>$ ^kyeli<n><par>$}$
The rule:
<out> <chunk name="num-noun"> <!-- Output: ^num-noun --> <tags> <tag><lit-tag v="SN"/></tags> <!-- Output: <SN> --> </tags> <!-- Output: { --> <lu> <!-- Output: ^ --> <clip pos="1" side="tl" part="lem"/> <!-- Output: kyehti --> <clip pos="1" side="tl" part="tags"/> <!-- Output: <num><sg><nom><@←SUBJ> --> </lu> <!-- Output: $ --> <lu> <!-- Output: ^ --> <clip pos="2" side="tl" part="lem"/> <!-- Output: kyeli --> <lit-tag v="n.par"/> <!-- Output: <n><par> --> </lu> <!-- Output: $ --> </chunk> <!-- Output: }$ --> </out>
This will give:
^num-noun<SN>{^kyehti<num><sg><nom><@←SUBJ>$ ^kyeli<n><par>$}$
This is good, but we don´t want the syntax tag... <@←SUBJ>
How can we change the tags? We first need to define patterns that
These patterns are defined in a separate section:
<section-def-attrs> <def-attr n="function"> <attr-item tags="@←SUBJ"/> <attr-item tags="@←OBJ"/> <attr-item tags="@←ADVL"/> </def-attr> </section-def-attrs>
The "def-attr" stands for define attribute.
The procedure for changing something goes something like:
<let> <clip pos="2" side="tl" part="function"/> <lit v=""/> </let>
This replaces anything substring that matches one of the patterns
Here "lit" means "literal" and the attribute "v" is the value. e.g.
(@←SUBJ|@←OBJ|@←ADVL) --> 0
So now if we have
<lu> <!-- Output: ^ --> <clip pos="1" side="tl" part="lem"/> <!-- Output: kyehti --> <clip pos="1" side="tl" part="tags"/> <!-- Output: <num><sg><nom> --> </lu> <!-- Output: $ -->
We will get:
^kyehti<num><sg><nom>$
Note that all <let> statements must go outside of the <out> statement.
What will the whole rule file look like?
<action> <let><clip pos="1" side="tl" part="tense"/><lit-tag v="past"/></let> <out> <let> A B </let> ------------------------------------------------------- ------------------------------------------------------- <transfer> <section-def-cats> <def-cat n="num-nomacc"> <cat-item tags="num.sg.nom.*"/> <cat-item tags="num.sg.acc.*"/> </def-cat> <def-cat n="n-sg-gen"> <cat-item tags="n.sg.gen.*"/> </def-cat> </section-def-cats> <section-def-attrs> <def-attr n="function"> <attr-item tags="@←SUBJ"/> <attr-item tags="@←OBJ"/> </def-attr> </section-def-attrs> <section-rules> <rule> <pattern> <pattern-item n="num-nomacc"/> <pattern-item n="n-sg-gen"/> </pattern> <action> <let> <clip pos="2" side="tl" part="tags"/> <lit-tag v="n.par"/> </let> <let> <clip pos="1" side="tl" part="function"/> <lit-tag v=""/> </let> <out> <chunk name="num-noun"> <tags> <tag><lit-tag v="SN"/></tag> </tags> <lu> <clip pos="1" side="tl" part="lem"/> <clip pos="1" side="tl" part="tags"/> </lu> <b/> <lu> <clip pos="2" side="tl" part="whole"/> </lu> </chunk> </out> </action> </rule> </section-rules> </transfer> -------------------------------------------------------
Homework: The data in:
A-3lex_ordinals_uptoten_gt-norm.gen.yaml
Command:
hfst-proc sme-smn.automorf.hfst
More phrases:
- num adv adj-attr noun - Mun oasttán guokte hui varas guoli.
- num n-gen adj-attr noun - Mun gávdnen guokte eatni boares girjji.
- num adv adj noun -