| """ |
| Tamil Rule-Based Lemmatizer |
| Converts inflected Tamil word forms back to their root/base form. |
| |
| Strategy: |
| 1. Sandhi reversal — handles gemination changes that happen when |
| case suffixes attach (e.g. நாடு + தின் → நாட்டின் → நாடு) |
| 2. Plain suffix stripping — removes case/number markers that attach |
| without phonological change (e.g. கட்சிகள் → கட்சி) |
| |
| Rules are ordered longest-first within each table so the most specific |
| pattern always wins. |
| """ |
|
|
| |
| |
| |
| |
| _SANDHI_MAP = [ |
| |
| ("ங்களின்", "ம்"), |
| ("ங்களில்", "ம்"), |
| ("ங்களை", "ம்"), |
| ("ங்களுக்கு", "ம்"), |
| ("ங்கள்", "ம்"), |
|
|
| |
| ("ட்டின்", "டு"), |
| ("ட்டில்", "டு"), |
| ("ட்டை", "டு"), |
| ("ட்டோடு", "டு"), |
|
|
| |
| ("ண்டின்", "ண்டு"), |
| ("ண்டில்", "ண்டு"), |
|
|
| |
| ("த்தின்", "ம்"), |
| ("த்தில்", "ம்"), |
| ("த்தை", "ம்"), |
|
|
| |
| ("ற்றில்", "று"), |
| ("ற்றின்", "று"), |
|
|
| |
| ("க்கில்", "கு"), |
| ("க்கின்", "கு"), |
|
|
| |
| ("ப்பில்", "பு"), |
| ("ப்பின்", "பு"), |
|
|
| |
| ("ல்லில்", "ல்"), |
| ("ல்லின்", "ல்"), |
|
|
| |
| ("ர்களை", "ர்"), |
| ("ர்களின்", "ர்"), |
| ("ர்களில்", "ர்"), |
| ("ர்கள்", "ர்"), |
| ] |
|
|
| |
| |
| |
| |
| _SUFFIX_MAP = [ |
| |
| ("த்துக்களின்", "த்து"), |
| ("த்துக்களை", "த்து"), |
| ("த்துக்கள்", "த்து"), |
|
|
| |
| |
| ("களுக்கு", "கள்"), |
| ("களிடம்", "கள்"), |
| ("களோடு", "கள்"), |
| ("களால்", "கள்"), |
|
|
| |
| ("களின்", ""), |
| ("களில்", ""), |
| ("களை", ""), |
| ("கள்", ""), |
|
|
| |
| ("யின்", ""), |
| ("யில்", ""), |
| ("யை", ""), |
| ("யோடு", ""), |
|
|
| |
| ("விற்கு", "வு"), |
| ("வின்", "வு"), |
| ("வில்", "வு"), |
| ("வை", "வு"), |
|
|
| |
| ("ராகவே", "ர்"), |
| ("ராக", "ர்"), |
| ("வராக", "வர்"), |
|
|
| |
| ("ஆக", ""), |
| ("இன்", ""), |
| ("இல்", ""), |
| ("க்கு", ""), |
| ("டன்", ""), |
| ("உடன்", ""), |
| ("ஓடு", ""), |
| ("ஆல்", ""), |
| ("இருந்து", ""), |
| ("க்காக", ""), |
| ("உக்கு", ""), |
| ] |
|
|
| |
| _MIN_ROOT_LEN = 2 |
|
|
|
|
| def get_root(word: str) -> str: |
| """ |
| Return the root/base form of a Tamil word. |
| |
| Examples |
| -------- |
| >>> get_root("சட்டமன்றத்தில்") |
| 'சட்டமன்றம்' |
| >>> get_root("கட்சிகள்") |
| 'கட்சி' |
| >>> get_root("சென்னை") |
| 'சென்னை' # proper noun with no suffix — returned unchanged |
| """ |
| word = word.strip() |
|
|
| |
| for suffix, replacement in _SANDHI_MAP: |
| if word.endswith(suffix): |
| root = word[: -len(suffix)] + replacement |
| if len(root) >= _MIN_ROOT_LEN: |
| return root |
|
|
| |
| for suffix, replacement in _SUFFIX_MAP: |
| if word.endswith(suffix): |
| root = word[: -len(suffix)] + replacement |
| if len(root) >= _MIN_ROOT_LEN: |
| return root |
|
|
| return word |
|
|
|
|
| def get_root_with_surface(surface_word: str) -> tuple[str, str]: |
| """ |
| Return (root, surface_word). |
| Convenience wrapper so callers can keep both forms easily. |
| """ |
| return get_root(surface_word), surface_word |
|
|