I’ve realised that it would be good to pin down the semantics of ±features in more detail, so…
(Warning: this is another one of my rambly posts, and somewhat Brassica-specific in parts. Feel free to ignore it.)
Let’s write down a very simple set of features:
V = a i o u á í ó ú
+Round = o u ó ú
-Round = a i á í
+Stress = á ó í ú
-Stress = a o i u
The tricky case is a feature assimilation rule, such as
$Round V / V $Round. The intention is for the second vowel to take on the roundedness of the first: /au/→/ai/, /oi/→/ou/, etc. As zompist noted earlier, this is ‘a sort of cut and paste operation’: the first
$Round causes some variable somewhere to be set to ‘+’ or ‘-’ depending on which vowel is seen, and then that gets transferred to the replacement
$Round with the second vowel.
Problem: this implicitly requires some sort of correspondence between
$Round and
V. Somehow, the
$Round in the replacement needs to know to take its value from
V in the target. It could do this by position, I guess, since that’s how category matching-up already works. But my experience with Brassica’s existing half-broken attempt at a feature system suggests that merging two different kinds of things like this is a recipe for disaster (because it’s too easy to make a mistake when matching them up).
The cleanest solution would be to forbid using $features on their own. Instead, say they must always accompany some actual list of graphemes:
[V $Round] V / V [V $Round]. (This is in fact how I wrote it
earlier.) I like this, because it gives a clear separation of concerns: categories are for describing the overall structure of the input and the output, and features are for adjusting precisely how the two correspond to each other.
So when
[V $Round] is encountered in the replacement, what exactly happens? Taking Brassica as a reference, it would first use
V to find the underlying grapheme. Then it would read the setting of
$Round, and alter that already-chosen grapheme to conform with the roundedness setting if it doesn’t already.
(And what if
V were to contain a grapheme listed in neither
+Round nor
-Round? It could remain unchanged, or perhaps it could be an error. Either is justifiable, I think, though I lean towards the former.)
What if multiple features were present? As in a rule like, say,
[V $Round $Stress] V / [V $Round $Stress]. I think the same procedure suffices: first find the replacement
V, then force it to have the right roundedness setting, then force the result of
that to have the right stress setting. Responsibility would be on the user to make sure that each feature pair preserves the other feature settings (though this is a very easy requirement to satisfy).
That settles the behaviour of $feature, I think. What about +feature and -feature? What kind of thing are those? I think it’s fine to make them ordinary categories. The only guarantee they need is that, when combined with other categories (in intersections or subtractions), the order of their graphemes is preserved. This is critical to making sound changes like
[V +Round] / [V -Round] to work, but it’s easily ensured. And, with this, the ‘magic’ is confined to sound changes which use
$.
Further question: if ±features are simply ordinary categories, is it possible to represent $features as ones too? How much ‘magic’ is even needed? After all, I
started this conversation by establishing that $feature can be replicated in current Brassica using nested categories. Is it possible to internally simplify $features down to to regular category expressions?
Unfortunately, the answer seems to be, ‘not easily’. The issue is working out how to rewrite stuff in the target. If one writes
[V $Round], then Brassica needs some way to express that
$Round variable. This can be done using a nested category match,
[{[a i á í]} {[o u ó ú]}]. The outer category matches
$Round, the inner one matches
V. Unfortunately, this completely messes up the replacement, where one expects to be able to write a simple
V to transfer the grapheme to the replacement. I’m not sure it’s possible to get around this problem.
Another issue is predefinition. This is important, because nothing in current Brassica requires predefinition — it can all be expressed inline. In theory, one could invent a syntax for inline $features too: perhaps something like,
[V $Round(o/a u/i ó/á ú/í)] V / V [V $Round(o/a u/i ó/á ú/í)]. I probably will allow something like this, for consistency with all the other parts of Brassica, but I don’t anticipate the syntax itself to see wide use.
That last point made me think of something else — what if one feature in the target corresponds to a
different feature in the replacement? I wondered if this could actually happen, but then I thought of a case where it’s necessary: transphonologisation changes where, say, coda consonant voicing turns into vocalic tone. It would be nice to be able to represent this as
V [C $Voice] / [V $Tone] C. This suggests that matches between target and replacement features should be made ignoring feature names — except that there are problems with this…
(Another point: sometimes you might want +Voice to correspond to -Tone, rather than +Tone. It’s probably a sensible idea to add syntax for negating the feature value, say
-$Tone.)
One problem is that this complicates another idea I had — that of multivalent features. A multivalent feature for place of articulation, for instance, would mean that e.g. nasal assimilation could be expressed nicely as
N [C $POA] / [N $POA] C. I hadn’t yet fully worked out all the details of how this could work, but a fairly important aspect was that a POA feature in the target would correspond only to a POA feature in the replacement, so that the feature values are transferred easily. If a POA feature in the target could correspond to, say, a Backness feature in the replacement (not inconceivable!), that would complicate matters.
Finally, circling back around to my original problem: does this help with suprasegmental or autosegmental categories? I think it does. With features as described above, an ‘autosegment’ would simply be a cross-section through a feature pair: like
a/á, or
o/ó. If combining a variable with a category makes a feature transfer declaration (as
[V $Round]), combining a variable with a grapheme would make an autosegment (as
a$Stress). This is not equivalent to a category (like
[a á]), because the information travels through different ‘channels’, so to speak — a binary feature value, as opposed to a category index.
(This poses the question of whether
[V $Round] shouldn’t be written as
V$Round. Come to think of it, the latter is more consistent.)
Then, declaring a feature ‘autosegmental’ could simply mean that every occurrence of, say,
a is reinterpreted as
a$Stress, in the target and replacement (and presumably environment too, though there it’s less important). To be usable this actually requires that feature transfer should
not ignore feature names as suggested earlier, because otherwise it would be too easy to accidentally transphonologise the autosegmental feature onto some other random feature which happens to be mentioned in the replacement. In this case, presumably there can be special syntax for transphonologisation when it is desired: say,
V [C $Voice#ref] / [V $Tone#ref].
I feel like this notion of ‘keeping separate features separate’ is sort of what I’ve been grasping for since the beginning of Brassica. This way, each opposition which is phonologically meaningful gets its own name, allowing it to be kept separate from other oppositions by default. Meanwhile, categories give an easy way to specify groupings which don’t form any coherent opposition, or are specified on an ad-hoc basis. I like this!