Source code for latticelang.phonology
1"""Phonology module for LatticeLang.
2
3This module provides classes for representing and manipulating phoneme
4inventories in constructed languages.
5"""
6
7from __future__ import annotations
8
9from dataclasses import dataclass, field
10from enum import Enum
11from typing import Any
12
13
[docs]
14class PhonemeCategory(Enum):
15 """Categories of phonemes."""
16
17 CONSONANT = "consonant"
18 VOWEL = "vowel"
19 DIPHTHONG = "diphthong"
20 TONE = "tone"
21
22
[docs]
23@dataclass
24class Phoneme:
25 """Represents a single phoneme with its linguistic features.
26
27 A phoneme is the smallest unit of sound that distinguishes meaning
28 in a language. Each phoneme has an IPA symbol and a set of features
29 that describe its articulatory properties.
30
31 Example:
32 >>> p = Phoneme(symbol="p", category=PhonemeCategory.CONSONANT,
33 ... features={
34 "voiced": False,
35 "place": "bilabial",
36 "manner": "plosive"
37 })
38 >>> p.symbol
39 'p'
40 >>> p.features["voiced"]
41 False
42 """
43
44 symbol: str
45 category: PhonemeCategory
46 features: dict[str, Any] = field(default_factory=dict)
47
48 def __post_init__(self) -> None:
49 """Validate the phoneme after initialization."""
50 if not self.symbol:
51 raise ValueError("Phoneme symbol cannot be empty")
52
[docs]
53 def has_feature(self, feature: str, value: Any = True) -> bool:
54 """Check if this phoneme has a specific feature value.
55
56 Args:
57 feature: The feature name to check.
58 value: The expected value (defaults to True for boolean features).
59
60 Returns:
61 True if the phoneme has the feature with the specified value.
62
63 Example:
64 >>> p = Phoneme("b", PhonemeCategory.CONSONANT, {"voiced": True})
65 >>> p.has_feature("voiced")
66 True
67 >>> p.has_feature("nasal")
68 False
69 """
70 return self.features.get(feature) == value
71
72 def __str__(self) -> str:
73 """Return the IPA symbol as the string representation."""
74 return self.symbol
75
76 def __repr__(self) -> str:
77 """Return a detailed representation for debugging."""
78 return f"Phoneme('{self.symbol}', {self.category.value}, {self.features})"