Lingua-Phonology
view release on metacpan or search on metacpan
Phonology/FileFormatPOD.pm view on Meta::CPAN
[-anterior voice]
The features inside the square brackets may be specified in three different
ways:
=over 4
=item * privative style
In this style, you simply list the name of the feature to test or set any true
value: C<[nasal]>. To test for or set a false value, you precede the name of
the feature with an asterisk: C<[*nasal]>. This is most appropriate for
privative features which are either true (present) or false (absent).
=item * binary style
In this style, you put a '+' before the name of the feature to test or set the
value 1: C<[+anterior]>. You put a '-' before the name of the feature to test
or set the value 0: C<[-anterior]>. You may also put an '*' before the name of
the feature to set its value to undefined: C<[*anterior]>. This is most
appropriate for binary features which are either positive, negative, or
undefined.
=item * scalar style
In this style, you put the name of the feature first, followed by an '=', then
any value. If the value you give is a numeral or a word with no non
alphanumeric characters, you do not need to include the value in quotes:
C<[aperture=2], [scalar=word]>. If the value you wish to assign includes
non-alphanumeric characters, you need to put the value in double quotes:
C<[scalar="long, strange value"]>. This is best for scalar features which can
have a range of values.
=back
Strictly speaking, any type of feature can be tested or set with any of the
styles above, but it's recommended that you use each style with the appropriate
type of feature.
Example:
[dorsal -anterior] => [nasal]
Read: "Any segment that is dorsal and -anterior (i.e. a palatal) becomes nasal."
In formal linguistic literature you must always define your segments with
feature bundles like above. However, Lingua::Phonology also allows you to
define a segment with a symbol from the current symbol set. This is done by
writing the symbol between /slashes/, like so: C</s/>. This makes many rules
clearer. Example:
/z/ => /s/
Read: "All /z/'s become /s/'s."
You can, of course, mix the two styles
[Coronal] => /s/
Read: "All coronals (dentals, alveolars, etc.) become /s/."
Remember that whatever comes between the slashes is the symbol. If you write
C</sk/>, Lingua::Phonology will look for a single segment whose symbol is 'sk'.
If you want an /s/ followed by a /k/, write C</s//k/>.
Another extension of strict linguistic form is the fact that you can include
more than one segment in your input and output segments. Your linguistics
professor might not like the following rule, but Lingua::Phonology has no
problem with it:
/s/[nasal] => /z/[*nasal voice]
Read: "/s/ followed by a nasal is replaced with /z/ followed by a voiced stop."
The only stipulation here is that your statement must be B<balanced>: there
must be the same number of segments on both sides of the arrow.
One final trick is to use an empty set of braces, C<[]>, which will match
anything at all on the left side of an arrow, and leave a segment unchanged on
the right side. For example:
/s/[]/r/ => /S/[]/l/
Read: "/s/ followed by anything, followed by an /r/, becomes /S/, followed by
the same thing, followed by an /l/."
The only thing that C<[]> does not match is nothing at all--it implies that
some segment exists there, but you don't care what it is. (To match nothing at
all you can use C<0>, but see below at L<"Inserting and deleting">.
See L<"Details of parsing"> for some warnings and more detail about how
segments are parsed.
=head2 Conditions
The rules we have written so far have been unconditioned rules, which don't
depend on segments other than the ones being changed. However most linguistic
rules are not unconditional, and so we need to add the condition clause. The
general format for rules with conditions is this:
input_segments => output_segments / conditions
A slash normally separates the condition from the rest of the rule. However,
this can sometimes get lost amid the slashes used around symbols, so you can
also write it with a colon:
input_segments => output_segments : conditions
The condition itself is written just like the input and output segments, with
bracketed feature bundles or symbols. However, you put an underscore '_' where
the input/output segment(s) go. No matter how many segments you use, you only
put a SINGLE underscore there to represent them. For example:
/s/ => /S/ : _/i/
Read: "Replace /s/ with /S/ when the next segment is /i/".
You can put segments before and after the underscore:
[vocoid] => [nasal] / [voice]_[nasal]
Phonology/FileFormatPOD.pm view on Meta::CPAN
=head2 Sets of segments and conditions
Sometimes you want to do something when this OR that is true, and nothing can
be found in common between this and that. (Linguists hate such rules, but they
do exist, unfortunately.) To accomplish this, you need a set, which lists a
group of segments or conditions. In either case, a set consists of two
parenthesis '()' enclosing the options, which are themselves separated by pipes
'|'.
Here's an example segment set:
/s/ => /x/ : _(/r/ | /k/ | /u/ | /i/)
Read: "/s/ becomes /x/ when the next segment is any of /r/, /k/, /u/, or /i/".
This rule, by the way, actually exists in Old Church Slavic. I didn't make it
up, unlike most of the other example rules.
You can mix different kinds of feature definitions in a set, of course:
(/d/ | /g/ | [labial]) => [*Place] / _$
Read: "/d/, /g/, or any labial delink their Place node (and become glottals) at
the end of a word."
You can also make a set of conditions. Example:
[labial] => /m/ : ( _/m/ | [nasal]_ )
Read: "Any labial becomes /m/, either when the next segment is /m/ or when the
preceding segment is a nasal."
When you make a set of conditions, the set must be the B<entire> condition part
of the rule. For example, the following variation of the preceding rule is
wrong, and won't parse:
# WRONG
[labial] => /m/ : ( _/m/ | [nasal]_ )$
Intention: "Any labial becomes /m/, either when it precedes an /m/ which is the
last segment in the word, or when it follows a nasal and is the last segment in
the word." As nice as this sounds, it doesn't work. Sorry.
=head2 Inserting and deleting
Insertion and deletion are both accomplished with the special symbol '0'. You
can use a '0' on either the left-hand or right-hand side of the arrow in a
linguistic rule, but it has a slightly different meaning on each side. You
CANNOT use a C<0> in the condition part of the rule, nor inside a segment set.
Both of the following are wrong:
(/k/ | [voice] | 0) => [nasal] #WRONG, will not parse
/s/ => /z/ : _0/d/ # WRONG, will not parse
On the left-hand side of an arrow, the C<0> means "Don't look for a segment
here, but insert a segment in this spot." The segment to be inserted is
whatever is in the corresponding spot on the right side of the arrow. Example:
/s/0[Coronal] => []/i/[] : _[*vocoid]
Read: "Insert an /i/ between /s/ and another coronal when the following segment
is not a vocoid". Remember that [] can be used on the left-hand side of a rule
to mean "match anything" and on the right-hand side of an arrow to mean "don't
change anything". This rule is exactly equivalent to the following rule:
0 => /i/ : /s/_[Coronal][*vocoid]
The second form here is more formally correct, but the first illustrates how
you can include a C<0> anywhere in a rule to insert a segment at that point.
On the right-hand side of an arrow, the C<0> means "Delete whichever segment is
in this spot." The segment to be deleted is whichever segment occupies the same
spot on the right-hand side of the arrow. Example:
/s//k/ => /S/0 : _$
Read: "An /s/ followed by a /k/ becomes /S/ followed by nothing at the end of a
word."
Here's a similar example:
[vocoid][nasal coda] => [nasal]0
Read: "A vowel folllowed by a coda nasal is nasalized, and the nasal is
deleted."
=head2 Using linguistic rules with other rule parameters
You can use a linguistic rule together with other tags or parameters that are
normally part of a rule. In fact, it is often necessary to do so to create a
rule. For example, suppose you wish to have a front vowel harmony rule. You
could try to write something like this
[vocoid] => [-anterior] / _[][-anterior vocoid]
Read: "A vocoid becomes [-anterior] (front) when the segment after the next one
is also a front vocoid". Here we assume that the C<[]> represents the
intervening consonant, which we don't care about. However, this rule will break
if there is not exactly one consonant between the vowels. To remedy this, you
should specify a tier of C<vocoid>, which will cause the rule to ignore all
non-vocoids. The whole rule declaration would then look like this:
<rule name="Vowel Harmony" >
<tier value="vocoid" />
[] => [-anterior] / _[-anterior]
</rule>
Note that we've removed the C<vocoid> statements from the feature bundles.
That's because they are now redundant--we know that only vocoids are included
in this rule. We also removed the C<[]> from the condition, because any
intervening consonant will not appear at all in our word. This rule will work
no matter how many consonants appear between the vowels.
The parameters that you can specify this way are C<direction, tier, filter,
domain, result>. You should not try to specify a C<where> or C<do> property
together with a linguistic rule, because the linguistic rule I<is> the C<where>
and C<do> properties. Any C<where> or C<do> that you specify will be ignored.
=head2 Limitations
There is one important aspect of linguistic rules which is missing in the
( run in 0.653 second using v1.01-cache-2.11-cpan-364913b4093 )