Core API¶
This section of the documentation covers all of Padmini’s core interfaces. In order, we cover:
the main user-facing API
Padmini’s core data structures
the internal APIs that modify these data structures
For the implementation of specific rules, see the Prakaraṇa API.
High-level API¶
- padmini.ashtadhyayi.tinanta(dhatu: str, dhatu_code: str, la: str, tags=None, options=None) Prakriya ¶
Generate a tinanta (verb).
- Parameters:
dhatu – the dhātu to use. dhatu must include any relevant accent marks. See
dhatupatha.tsv
for examples.dhatu_code – the number in the Dhatupatha. This help distinguish between identical roots in separate ganas.
la – the lakāra to use. This must use a nasal vowel; use
"la~w"
, not"law"
.tags – extra tags to add to the derivation. For details, see
Tag
.options – enables or disables various optional rules in the Ashtadhyayi. For details, see the comments in
Prakriya
.
- Returns:
the complete prakriyā.
- padmini.ashtadhyayi.subanta(pratipadika: str, linga: str, tags=None, options=None) Prakriya ¶
Generate a subanta (nominal).
- Parameters:
pratipadika – the prAtipadika to use.
tags – extra tags to add to the derivation. For details, see
Tag
.options – enables or disables various optional rules in the Ashtadhyayi. For details, see the comments in
Prakriya
.
- Returns:
the complete prakriyā.
Data Structures¶
Padmini stores its data in three main data structures:
an ordinary
str
, which denotes a sequence of sounds in SLP1 transliteration. We use SLP1 because it represents each sound with exactly one character, which greatly simplifies the code. (For example, a string’s last sound is justs[-1]
.)a
Term
, which is astr
with extra metadata. Metadata includes any saṁjñās associated with the string, the string’s substitution history, and other minor information.a
Prakriya
, which is a list ofTerm
and extra metadata. Metadata includes the derivation history, saṁjñās that apply to the prakriyā as a whole, and other minor information.
- class padmini.prakriya.Term(u: str, text: str, tags: Set[str], gana: Optional[int], number: Optional[int])¶
A term is a generalized version of an upadesha. In addition to upadeshas, the term concept includes abhyāsas and any group of sounds that is not aupadeśika.
- Parameters:
u – The upadesha form of the term. If this is empty or missing, the term is not treated as an upadesha.
text – The “visible” text of the term. At the end of the derivation, we join the text of all terms together to create our final word.
tags – Any metadata associated with the term. Usually, this includes various samjnas. But it can also include past versions of the term (pratyayalope pratyayalakṣaṇam).
gana – For dhātus, this is the gana. Since a given dhātu can appear in multiple ganas, we use this parameter to disambiguate.
- class padmini.prakriya.Prakriya(terms: List[Term], tags: Set[str], history: List[Tuple[str, str]], options_override: Dict[str, bool], options_seen: List[Tuple[str, bool]])¶
A prakriya is a derivation within the Paninian system. It adds, removes, and modifies various terms until the result is a valid Sanskrit word or expression.
The
Prakriya
object manages all of the state associated with a prakriya. When the prakriya is complete, the final result can be accessed through the text attribute.In addition,
Prakriya
manages all of the state related to optional rules (rules declared with vA, vibhASA, anyatarasyAm, or in the opinion of some vaiyAkaraNa). This state makes it easy for calling code to try different permutations of options and generate all of the possible forms for some given input.- Parameters:
terms – the derivation state. The program modifies this list and its members during execution. If you want to preserve the initial state, provide a deep copy instead.
tags – any meta information that applies to the prakriya overall. This mainly contains semantic information (purusha, vacana) or sets the derivation context (chandasi). It is also used to manage “global” state that we cannot easily define on
Tag
objects.history – the derivation history. This is a list of 2-tuples, where the first member is the current result and the second member is the rule we applied to get that result. If you want to log different information in the history, you can override the step method of this class.
options_override – maps a rule code to whether the rule can be used or not. This mapping has meaning only for optional rules and is ignored for mandatory rules.
options_seen – optional rules seen during the derivation. This is a list of 2-tuples, where the first member is the rule and the second is whether the rule was accepted or not.
Constants¶
Views¶
- class padmini.term_views.TermView(terms)¶
A view groups multiple terms into a convenient unit so that they can be used together in rules. For example, consider the partial derivation below:
dviz + (luk) yAs + s + t
If dviz is the anga, we may wish to condition on the following sound from
yAs
; on the presence or absence ofluk
; on the semantics of t; or on various other properties. So we generalize this behavior into a singleTermView
:dviz + [(luk) yAs + s + t]
A
TermView
and aTerm
offer similar APIs. But whereas aTerm
can be freely modified, aTermView
is generally read-only.If needed, we can always access its terms attribute to modify the specific terms. But if you want to add or remove terms, create a new
TermView
instead.
Sounds¶
Sounds in the Ashtadhyayi have two main functions:
They condition operations by their presence or absence.
They transform according specific rules.
To handle these two use cases, this module exposes two primary functions:
- padmini.sounds.s(terms: str) OrderedSet[str] ¶
Create an ordered set of Sanskrit sounds.
The function understands the following sounds:
bare vowels (“a i u”)
udit (“ku~”)
pratyāhāras (“ac hal”)
For convenience, all arguments can be passed in one string.
The return value is a set so that membership checks are constant-time, and it is an
OrderedSet
per yathāsaṁkhyam anudeśaḥ samānām (i.e. list substitution is done in 1:1 correspondence).Example usage:
ik = s("ik") cavarga = s("cu~") kanthya = s("a ku~ h H")
To use the second
R
of the pratyāhāra, use the following syntax:first_n = s("iR") second_n = s("iR2")
- Parameters:
terms – a string of upadeshas.
- Returns:
an
OrderedSet
of sounds
- padmini.sounds.map_sounds(left: OrderedSet, right: OrderedSet) Dict[str, str] ¶
Map one sound group to another.
Every Sanskrit sound has various properties, e.g.:
sthāna (point of articulation)
prayatna (articulatory effort)
ghoṣa (voicing)
prāṇa (aspiration),
This function maps the sounds in left to their closest counterpart in right, per rule 1.1.50:
1.1.50 sthāne’ntaratamaḥ
- Parameters:
left – the “input” side of the mapping.
right – the “output” side of the mapping.
- Returns:
a mapping from each sound in left to its closest sound in right.
Filters¶
Before we apply a rule, we must first test if it meets the necessary
conditions. Many conditions are simple or adhoc (e.g. t.antya in s('ac')
to
test if a term ends in a vowel). More complex conditions are specified below:
Operations¶
The Ashtadhyayi modifies the derivation state with three types of rules:
vidhi (transformation), which change the sounds in a prakriyā.
saṃjñā (designation), which adds new saṁjñās to a prakriyā.
atideśa (analogy), which usually extends an it-saṁjñā to a prakriyā.
More abstractly, all of these rule types modify the prakriyā by changing its sounds and designations. We call this abstract category the operation.
As much as possible, any changes to the Prakriya
are applied through
this module (as opposed to ad-hoc logic). By doing so, we keep the code DRY and
concise.
Most operations apply to a single term and have this basic structure:
def some_operation(rule: str, p: Prakriya, t: Term, *args):
# Modify the term in some way
t.text = [...]
# Record which rule was applied
p.step(rule)
- padmini.operations.adi(rule: Optional[str], p: Prakriya, u: Term, sub: str)¶
Replace the first sound.
- padmini.operations.antya_yatha(base: str, before, after) str ¶
Legacy function. Replace from the last sound on.
- padmini.operations.insert_after(rule: Optional[str], p: Prakriya, needle: Term, new_term: Term)¶
Insert after the given term.
- padmini.operations.insert_before(rule: str, p: Prakriya, needle: Term, new_term: Term)¶
Insert before the given term.
- padmini.operations.optional(func, rule: str, p: Prakriya, *args) bool ¶
Wrapper that defines an optional operation.
If the original operation has this syntax:
func(rule, p, *args)
Then we can make the operation optional with:
optional(func, rule, p, *args)
- Parameters:
func – the
operation
function to applyrule – the rule ID
p – the prakriya
args – the args to pass to func
- Returns:
True
iff the option was accepted.
- padmini.operations.upadesha(rule: str, p: Prakriya, u: Term, sub: str)¶
Replace Term.upadesha and apply it_samjna.run.
- padmini.operations.upadesha_no_it(rule: str, p: Prakriya, u: Term, sub: str)¶
Replace Term.upadesha with no follow_up, in case we need to apply lopa.
- padmini.operations.upadha(rule_code: str, p: Prakriya, u: Term, sub: str)¶
Replace the penultimate sound.
- padmini.operations.yatha(text: str, before, after)¶
Legacy function. Replace in 1:1 correspondence.