Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deromanization typing. Change supplement abbreviation from 'supp' to 'supl' to distinguish from support. #393

Merged
1 commit merged into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions nisaba/scripts/natural_translit/brahmic/deromanizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

"""Brahmic deromanizer."""

from typing import Iterable, Union
from typing import Any, Callable, Iterable, Union
import pynini as pyn
from nisaba.scripts.natural_translit.brahmic import derom_inventory as derom
from nisaba.scripts.natural_translit.brahmic import iso_inventory
Expand All @@ -40,18 +40,18 @@ class Deromanizer(inventory2.Inventory):

def __init__(self):
super().__init__()
self.script = ty.UNASSIGNED
self.script = ''
self.schwa_deletion = False
self._init_items()
self._init_supps()
self._init_supls()

def _add_fst_list(self, alias: str, *fsts) -> None:
self.add_item(fl.FstList.with_alias(alias, *fsts))

def _make_mapping_group(
self, alias: str, value: ... = ty.UNSPECIFIED
) -> None:
self.make_supp(alias, value if ty.is_specified(value) else {})
self.make_supl(alias, value if ty.is_specified(value) else {})

def _init_items(self) -> None:
ls.apply_foreach(self._add_fst_list, [
Expand All @@ -62,7 +62,7 @@ def _init_items(self) -> None:
['cluster_vir'], ['high_priority'], ['ind_to_sign']
])

def _init_supps(self) -> None:
def _init_supls(self) -> None:
ls.apply_foreach(self._make_mapping_group, [
['vowel'], ['monophthong'], ['always_long_vowel'], ['diphthong'],
['consonant'], ['has_aspirated'], ['no_aspirated'], ['drops_aspirated'],
Expand Down Expand Up @@ -174,9 +174,9 @@ def _apply_by_priority(
self,
group: dict[int, list[derom.DeromMapping]],
rule: fl.FstList,
rewriter: FstListArg,
rewriter: Callable[..., Any],
*args
) -> list[list[derom.DeromMapping]]:
) -> None:
"""Fills in a rewrite template with members of a group.

Currently priority is enforced by rule order.
Expand Down Expand Up @@ -297,6 +297,7 @@ def to_brahmic(self) -> pyn.Fst:
self.typ_ops,
self._rw_typ2brh()
).compose()
return self.to_iso()

# Rewrite templates

Expand All @@ -308,7 +309,7 @@ def _rw_typ2brh(self) -> pyn.Fst:
"""Brahmic typ to Brahmic script."""
return ls.cross_union_star(iso_inventory.ls_tr2brh(self.script))

def _rw_typ2iso(self) -> fl.FstList:
def _rw_typ2iso(self) -> pyn.Fst:
"""Brahmic typ to ISO."""
return fl.FstList(
rw.insert(iso.A, iso.SCH_CONS),
Expand All @@ -321,13 +322,13 @@ def _rw_fields(
self, mapping_list: list[derom.DeromMapping],
old_field: str, new_field: str,
preceding: pyn.FstLike = '', following: pyn.FstLike = ''
) -> pyn.Fst:
) -> fl.FstList:
"""Template for rewriting mapping fields."""
if not mapping_list: return []
return rw.rewrite_ls(
if not mapping_list: return fl.FstList()
return fl.FstList(rw.rewrite_ls(
[[m.get(old_field), m.get(new_field)] for m in mapping_list],
preceding, following
)
))

def _rw_vowel(
self, mapping_list: list[derom.DeromMapping],
Expand Down Expand Up @@ -388,7 +389,7 @@ def _rw_cons(

# Shortcuts for specific cases of consonant rewrites.

def _rw_gem_only(self, mapping_list: list[derom.DeromMapping]) -> pyn.Fst:
def _rw_gem_only(self, mapping_list: list[derom.DeromMapping]) -> fl.FstList:
return self._rw_cons(mapping_list, single=False)

def _rw_aspiration(
Expand Down Expand Up @@ -417,7 +418,7 @@ def _rw_foreign(
def _rw_cluster_wi(self) -> pyn.Fst:
return rw.insert(iso.VIR, al.BOW + iso.SCH_CONS, iso.ONSET_CONS)

def _rw_cluster_wf(self) -> pyn.Fst:
def _rw_cluster_wf(self) -> fl.FstList:
return fl.FstList(
rw.rewrite_word_final(iso.A, iso.AA),
rw.insert(iso.VIR, iso.SCH_CONS, iso.ONSET_CONS + al.EOW)
Expand Down
28 changes: 14 additions & 14 deletions nisaba/scripts/natural_translit/utils/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,10 @@ def populate(self, aspect: 'Feature.Aspect') -> None:
aspect: The aspect that will be populated by the features in this list.

Adds features in this list as items to the aspects. Updates the distance
dictionary. Adds self as supp to the aspect.
dictionary. Adds self as supplement to the aspect.

"""
aspect.add_supp(self)
aspect.add_supl(self)
for i, item in enumerate(self):
item.parent_list = self
if isinstance(item, Feature) and item not in aspect:
Expand Down Expand Up @@ -515,8 +515,8 @@ def add_feature(self, feature: 'Feature') -> None:
feature.inventory = self.inventory
self.distance_dict[feature] = {}

def supp_feature(self, feature: 'Feature') -> None:
self.add_supp(feature)
def supl_feature(self, feature: 'Feature') -> None:
self.add_supl(feature)
feature.aspect = self
feature.inventory = self.inventory

Expand All @@ -543,16 +543,16 @@ def _make_set(
return Feature.Set.with_alias(alias, to_add)

def set(self, alias: str, *features) -> None:
self.add_supp(self._make_set(alias, *features))
self.add_supl(self._make_set(alias, *features))

def set_not(self, alias: str, *features) -> None:
self.add_supp(self._make_set(alias, *features, negation=True))
self.add_supl(self._make_set(alias, *features, negation=True))

def set_range(
self, alias: str,
first: 'Feature.Aspect.VALUES', last: 'Feature.Aspect.VALUES'
) -> None:
self.add_supp(
self.add_supl(
self._make_set(alias, first.parent_list.range(first, last))
)

Expand All @@ -567,18 +567,18 @@ def populate(

The item values of the Aspect are the features in its root_list. Max_dist
of an aspect is the max possible distance between two features of
this aspect. Every aspect has two supp features: 'any' which returns 0
distance to all features of this aspect, and n_a (not applicable),
this aspect. Every aspect has two supplement features: 'any' which returns
0 distance to all features of this aspect, and n_a (not applicable),
which returns max_dist to all features. The root_list and any value list
within are added as supps to the aspect.
within are added as supplements to the aspect.

"""
self.inventory = inventory
self.inventory.add_item(self)
self.root_list.populate(self)
self.set('all', self)
self.supp_feature(Feature('any'))
self.supp_feature(Feature('n_a', 'not_applicable'))
self.supl_feature(Feature('any'))
self.supl_feature(Feature('n_a', 'not_applicable'))

class Inventory(inventory2.Inventory):
"""An inventory of Aspects and their contrastive features.
Expand Down Expand Up @@ -612,13 +612,13 @@ def add_profile(
self, alias: str,
*params: 'Feature.ITERABLE',
) -> None:
self.add_supp(Feature.Profile(self, alias, *params))
self.add_supl(Feature.Profile(self, alias, *params))

def copy_and_update_profile(
self, old: 'Feature.Profile', alias: str,
*params: 'Feature.ITERABLE',
) -> None:
self.add_supp(old.copy_and_update(alias, *params))
self.add_supl(old.copy_and_update(alias, *params))

class Profile(inventory2.Inventory):
""""Feature profile for an object based on a feature inventory.
Expand Down
4 changes: 2 additions & 2 deletions nisaba/scripts/natural_translit/utils/feature_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ def test_feature_text(self):
def test_aspect_of_feature(self):
self.assertEqual(r.warmth.warm.aspect, r.warmth)

def test_list_as_supp(self):
self.assertIn('cls', r.door.supp_aliases)
def test_list_as_supl(self):
self.assertIn('cls', r.door.supl_aliases)

def test_set_empty(self):
self.assertEmpty(f.Set())
Expand Down
19 changes: 9 additions & 10 deletions nisaba/scripts/natural_translit/utils/inventory2.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, alias: str = ''):
self.text = alias if alias else 'New Inventory'
self._item_values = []
self.item_aliases = []
self.supp_aliases = []
self.supl_aliases = []

def __iter__(self):
return self._item_values.__iter__()
Expand All @@ -61,15 +61,15 @@ def from_list(
items: list[ty.Thing],
attr: str = '',
typed: ty.TypeOrNothing = ty.UNSPECIFIED,
supps: ty.ListOrNothing = ty.UNSPECIFIED,
supls: ty.ListOrNothing = ty.UNSPECIFIED,
alias: str = '',
) -> 'Inventory':
"""Makes an Inventory from a list of things."""
new = cls(alias)
for item in items:
new.add_item(item, attr, typed)
for s in ty.enforce_list(supps):
new.add_supp(s)
for s in ty.enforce_list(supls):
new.add_supl(s)
return new

def _add_field(self, alias: str, value: ...) -> bool:
Expand Down Expand Up @@ -113,18 +113,17 @@ def add_item(
self.item_aliases.append(thing.alias)
return added

# TODO: Rename all supp to supl.
def add_supp(self, supp: ty.Thing) -> None:
def add_supl(self, supl: ty.Thing) -> None:
"""Adds the value of a Thing as a supplement."""
self.make_supp(supp.alias, supp.value)
self.make_supl(supl.alias, supl.value)

def make_supp(self, alias: str, value: ...) -> None:
def make_supl(self, alias: str, value: ...) -> None:
"""Adds the value as a supplement."""
if self._add_field(alias, value):
self.supp_aliases.append(alias)
self.supl_aliases.append(alias)

def get(self, alias: str, default: ... = ty.MISSING) -> ...:
if alias in self.item_aliases or alias in self.supp_aliases:
if alias in self.item_aliases or alias in self.supl_aliases:
return log.dbg_return(
getattr(self, alias, default), 'for alias ' + alias
)
Expand Down
18 changes: 9 additions & 9 deletions nisaba/scripts/natural_translit/utils/inventory2_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
_i1 = i.Inventory.from_list([_T_B_STR])

_i2 = i.Inventory.from_list(
[_T_B_STR, _T_C_STR], 'value', typed=str, supps=[_T_D_INT]
[_T_B_STR, _T_C_STR], 'value', typed=str, supls=[_T_D_INT]
)


Expand Down Expand Up @@ -81,25 +81,25 @@ def test_add_item_wrong_type(self):
def test_add_item_wrong_type_return_false(self):
self.assertFalse(_i1.add_item(_T_A_FST, typed=str))

def test_add_supp(self):
_i1.add_supp(_T_D_INT)
def test_add_supl(self):
_i1.add_supl(_T_D_INT)
self.assertEqual(_i1.d, 4)

def test_make_supp(self):
_i1.make_supp('e', 5)
def test_make_supl(self):
_i1.make_supl('e', 5)
self.assertEqual(_i1.e, 5)

def test_from_list_value(self):
self.assertEqual(_i2.b, _B_STR)

def test_from_list_supp(self):
def test_from_list_supl(self):
self.assertEqual(_i2.d, _D_INT)

def test_from_list_item_aliases(self):
self.assertEqual(_i2.item_aliases, ['b', 'c'])

def test_from_list_supp_aliases(self):
self.assertEqual(_i2.supp_aliases, ['d'])
def test_from_list_supl_aliases(self):
self.assertEqual(_i2.supl_aliases, ['d'])

def test_add_item_recurring_item(self):
_i2.add_item(_T_CB_STR, 'value')
Expand All @@ -108,7 +108,7 @@ def test_add_item_recurring_item(self):
def test_get_item(self):
self.assertEqual(_i2.get('b'), _B_STR)

def test_get_supp(self):
def test_get_supl(self):
self.assertEqual(_i2.get('d'), _D_INT)

def test_get_out_of_inventory(self):
Expand Down
Loading