API

Lists

vyakarana.lists

Lists of various terms, designations, and sounds. Some of these lists could probably be inferred programmatically, but for the sake of basic sanity these are encoded explicitly. Thankfully these lists are rather small.

license:MIT and BSD
vyakarana.lists.DHATUKA = ['sarvadhatuka', 'ardhadhatuka']

saṃjñā for verb suffixes

vyakarana.lists.IT = set(['wvit', 'Git', 'adit', 'odit', 'Sit', 'anudattet', 'kit', 'Yit', 'wit', 'xdit', 'Udit', 'qit', 'pit', 'qvit', 'anudatta', 'Rit', 'svarita', 'idit', 'Kit', 'fdit', 'svaritet', 'cit', 'udit', 'mit', 'Nit'])

Technical designations (1.3.2 - 1.3.9)

vyakarana.lists.KARAKA = ['karta', 'karma', 'karana', 'adhikarana', 'sampradana', 'apadana']

saṃjñā for kāraka relations (currently unused)

vyakarana.lists.LA = set(['la~w', 'li~N', 'lf~N', 'le~w', 'lu~N', 'lo~w', 'lu~w', 'li~w', 'la~N', 'lf~w'])

Abstract suffixes that are replaced with items from TIN. Collectively, they are called the “lakāra” or just “la”.

vyakarana.lists.PADA = ['parasmaipada', 'atmanepada']

saṃjñā for verb ‘pada’

vyakarana.lists.PRATYAYA = set(['la~w', 'lf~N', 'Snam', 'SnA', 'Slu', 'lu~N', 'lo~w', 'la~N', 'li~w', 'Sa', 'lf~w', 'lup', 'li~N', 'Sap', 'le~w', 'Rin', 'Snu', 'u', 'Syan', 'lu~w', 'luk', 'Ric'])

Various pratyaya

vyakarana.lists.PURUSHA = ['prathama', 'madhyama', 'uttama']

saṃjñā for various persons

vyakarana.lists.SAMJNA = set(['pada', 'atmanepada', 'abhyasta', 'vrddhi', 'ekavacana', 'prathama', 'saptami', 'sarvadhatuka', 'bahuvacana', 'apadana', 'caturthi', 'dhatu', 'ardhadhatuka', 'guna', 'tin', 'dvitiya', 'parasmaipada', 'pratyaya', 'sup', 'madhyama', 'pancami', 'sampradana', 'uttama', 'dvivacana', 'sasthi', 'abhyasa', 'karta', 'anga', 'karana', 'trtiya', 'krt', 'adhikarana', 'taddhita', 'karma'])

All saṃjñā

vyakarana.lists.SOUNDS = set(['ac', 'yaY', 'Sar', 'Jay', 'S', 'ak', 'am', 'wu~', 'ec', 'yaR', 'ik', 'at', 'aw', 'vaS', 'et', 'ic', 'haS', 'ku~', 'eN', 'Ft', 'val', 'cu~', 'iR', 'JaS', 'yar', 'yam', 'Kar', 'aR', 'sal', 'Nam', 'Kay', 'ral', 'Jar', 'ft', 'baS', 'tu~', 'may', 'Ut', 'Baz', 'Cav', 'Jaz', 'it', 'pu~', 'x', 'yay', 'Ot', 'a', 'f', 'i', 'ut', 'jaS', 'It', 'Ec', 'hal', 'al', 'Jal', 'u', 'At', 'uk', 'car', 'Et', 'ot'])

A collection of various sounds, including:

  • savarṇa sets (1.1.69)
  • single-item sets (1.1.70)
  • pratyāhāra (1.1.71)
vyakarana.lists.TIN = ['tip', 'tas', 'Ji', 'sip', 'Tas', 'Ta', 'mip', 'vas', 'mas', 'ta', 'AtAm', 'Ja', 'TAs', 'ATAm', 'Dvam', 'iw', 'vahi', 'mahiN']

Defined in rule 3.4.78. These 18 affixes are used to form verbs. The first 9 are called “parasmaipada” (1.4.99), and the last 9 are called “ātmanepada” (1.4.100).

vyakarana.lists.VACANA = ['ekavacana', 'dvivacana', 'bahuvacana']

saṃjñā for various numbers

vyakarana.lists.VIBHAKTI = ['prathama', 'dvitiya', 'trtiya', 'caturthi', 'pancami', 'sasthi', 'saptami']

saṃjñā for case triplets

Inputs and Outputs

class vyakarana.terms.Upadesha(raw=None, **kw)

A term with indicatory letters.

data

The term`s data space. A given term is represented in a variety of ways, depending on the circumstance. For example, a rule might match based on a specific upadeśa (including ‘it’ letters) in one context and might match on a term’s final sound (excluding ‘it’ letters) in another.

samjna

The set of markers that apply to this term. Although the Ashtadhyayi distinguishes between samjna and it tags, the program merges them together. Thus this set might contain both 'kit' and 'pratyaya'.

lakshana

The set of values that this term used to have. Technically, only pratyaya need to have access to this information.

ops

The set of rules that have been applied to this term. This set is maintained for two reasons. First, it prevents us from redundantly applying certain rules. Second, it supports painless rule blocking in other parts of the grammar.

parts

The various augments that have been added to this term. Some examples:

  • 'aw' (verb prefix for past forms)
  • 'iw' (‘it’ augment on suffixes)
  • 'vu~k' (‘v’ for ‘BU’ in certain forms)
static as_anga(*a, **kw)

Create the upadesha then mark it as an 'anga'.

static as_dhatu(*a, **kw)

Create the upadesha then mark it as a 'dhatu'.

adi

The term’s first sound, or None if there isn’t one.

antya

The term’s last sound, or None if there isn’t one.

asiddha

The term’s value in the asiddha space.

asiddhavat

The term’s value in the asiddhavat space.

clean

The term’s value without svaras and anubandhas.

raw

The term’s raw value.

upadha

The term’s penultimate sound, or None if there isn’t one.

value

The term’s value in the siddha space.

add_lakshana(*names)
Parameters:names – the lakshana to add
add_op(*names)
Parameters:names – the ops to add
add_part(*names)
Parameters:names – the parts to add
add_samjna(*names)
Parameters:names – the samjna to add
any_samjna(*names)
Parameters:names
get_at(locus)
Parameters:locus
remove_samjna(*names)
Parameters:names – the samjna to remove
set_asiddha(asiddha)
Parameters:asiddha – the new asiddha value
set_asiddhavat(asiddhavat)
Parameters:asiddhavat – the new asiddhavat value
set_at(locus, value)
Parameters:
  • locus
  • value
set_raw(raw)
Parameters:raw – the new raw value
set_value(value)
Parameters:value – the new value
class vyakarana.derivations.State(terms=None, history=None)

A sequence of terms.

This represents a single step in some derivation.

terms

A list of terms.

Filters

vyakarana.filters

Excluding paribhāṣā, all rules in the Ashtadhyayi describe a context then specify an operation to apply based on that context. Within this simulator, a rule’s context is defined using filters, which return a true or false value for a given index within some state.

This module defines a variety of parameterized and unparameterized filters, as well as as some basic operators for combining filters.

license:MIT and BSD
class vyakarana.filters.Filter(*args, **kw)

Represents a “test” on some input.

Most of the grammar’s rules have preconditions. For example, the rule that inserts suffix śnam applies only if the input contains a root in the rudh group. This class makes it easy to define these preconditions and ensure that rules apply in their proper contexts. Since these conditions filter out certain inputs, these objects are called filters.

Originally, filters were defined as ordinary functions. But classes have one big advantage: they let us define custom operators, like &, |, and ~. These operators give us a terse way to create more complex conditions, e.g. al('hal') & upadha('a').

category = None

The filter type. For example, a filter on the first letter of a term has the category adi.

name = None

A unique name for the filter. This is used as a key to the filter cache. If a filter has no parameters, this is the same as self.category.

body = None

The function that corresponds to this filter. The input and output of the function depend on the filter class. For a general Filter, this function accepts a state and index and returns True or False.

domain = None

A collection that somehow characterizes the domain of the filter. Some examples:

  • for an al filter, the set of matching letters
  • for a samjna filter, the set of matching samjna
  • for a raw filter, the set of matching raw values
  • for an and/or/not filter, the original filters
classmethod no_params(fn)

Decorator constructor for unparameterized filters.

Parameters:fn – some filter function.
supersets

Return some interesting supersets of this filter.

Consider a universal set that contains every possible element. A filter defines a subset of the universal set, i.e. the set of items for which the filter returns True. Thus every filter defines a set. For two filters f1 and f2:

  • f1 & f2 is like an intersection of two sets
  • f1 | f2 is like a union of two sets
  • ~f1 is like an “antiset”

Now consider a filter f composed of n intersecting filters:

f = f1 & f2 & ... & fn

This function returns the n filters that compose f. Each fi is essentially a superset of f.

“Or” and “not” filters are tough to break up, so they’re treated as indivisible.

subset_of(other)

Return whether this filter is a subset of some other filter.

All members of some subset S are in the parent set O. So if it is the case that:

S applies -> O applies

then S is a subset of P. For the “set” interpretation of a filter, see the comments on supersets().

Parameters:other – a filter
class vyakarana.filters.TermFilter(*args, **kw)

A Filter whose body takes an Upadesha as input.

Term filters give us:

  • Convenience. Most filters apply to just a single term.
  • Performance. Since we can guarantee that the output of a term filter will change only if its term changes, we can cache results for an unchanged term and avoid redundant calls.
class vyakarana.filters.AlFilter(*args, **kw)

A filter that tests letter properties.

class vyakarana.filters.adi(*args, **kw)

Filter on a term’s first sound.

class vyakarana.filters.al(*args, **kw)

Filter on a term’s final sound.

class vyakarana.filters.contains(*args, **kw)

Filter on whether a term has a certain sound.

class vyakarana.filters.dhatu(*args, **kw)

Filter on whether a term represents a particular dhatu.

vyakarana.filters.gana(start, end=None)

Return a filter on whether a term is in a particular dhatu set.

Parameters:
  • start – the raw value of the first dhatu in the list
  • end – the raw value of the last dhatu in the list. If None, use all roots from start to the end of the gana.
class vyakarana.filters.lakshana(*args, **kw)

Filter on a term’s prior values.

class vyakarana.filters.part(*args, **kw)

Filter on a term’s augments.

class vyakarana.filters.raw(*args, **kw)

Filter on a term’s raw value.

class vyakarana.filters.samjna(*args, **kw)

Filter on a term’s designations.

class vyakarana.filters.upadha(*args, **kw)

Filter on a term’s penultimate sound.

class vyakarana.filters.value(*args, **kw)

Filter on a term’s current value.

vyakarana.filters.auto(*data)

Create a new Filter using the given data.

Most of the terms in the Ashtadhyayi have obvious interpretations that can be inferred from context. For example, a rule that contains the word dhātoḥ clearly refers to a term with dhātu as a saṃjñā, as opposed to a term with dhātu as its current value. In that example, it’s redundant to have to specify that F.samjna('dhatu') is a samjna filter.

This function accepts a string argument and returns the appropriate filter. If multiple arguments are given, the function returns the “or” of the corresponding filters. If the argument is a function, it remains unprocessed.

Parameters:data – arbitrary data, usually a list of strings

Operators

vyakarana.operators

Excluding paribhāṣā, all rules in the Ashtadhyayi describe a context then specify an operation to apply based on that context. Within this simulator, operations are defined using operators, which take some (state, index) pair and return a new state.

This module defines a variety of parameterized and unparameterized operators.

license:MIT and BSD
class vyakarana.operators.Operator(*args, **kw)

A callable class that returns states.

category = None

The operator type. For example, a substitution operator has category tasya.

name = None

A unique name for this operator. If the operator is not parameterized, then this is the same as self.category.

body = None

The function that corresponds to this operator. The input and output of the function depend on the operator class. For a general Operator, this function accepts a state and index and returns a new state.

params = None

the operator’s parameters, if any.

classmethod parameterized(fn)

Decorator constructor for parameterized operators.

Parameters:fn – a function factory. It accepts parameters and returns a parameterized operator function.
classmethod no_params(fn)

Decorator constructor for unparameterized operators.

Parameters:fn – some operator function
conflicts_with(other)

Return whether this operator conflicts with another.

Two operators are in conflict if any of the following hold:

  • they each insert something into the state
  • one prevents or nullifies the change caused by the other. By “nullify” I mean that the result is as if neither operator was applied.

For example, two insert operators are always in conflict. And hrasva and dirgha are in conflict, since hrasva undoes dirgha. But hrasva and guna are not in conflict, since neither blocks or nullifies the other.

Parameters:other – an operator
class vyakarana.operators.DataOperator(*args, **kw)

An operator whose body modifies a term’s data.

body accepts and returns a single string.

Rules and Rule Stubs

class vyakarana.rules.Rule(name, window, operator, modifier=None, category=None, locus='value', optional=False)

A single rule from the Ashtadhyayi.

Rules are of various kinds. Currently, the system deals only with transformational rules (“vidhi”) explicitly.

VIDHI = 'vidhi'

Denotes an ordinary rule

SAMJNA = 'samjna'

Denotes a saṃjñā rule

ATIDESHA = 'atidesha'

Denotes an atideśa rule

PARIBHASHA = 'paribhasha'

Denotes a paribhāṣā rule

name = None

A unique ID for this rule, e.g. '6.4.1'. For most rules, this is just the rule’s position within the Ashtadhyayi. But a few rules combine multiple rules and have hyphenated names, e.g. '1.1.60 - 1.1.63'.

filters = None

A list of filter functions to apply to some subsequence in a state. If the subsequence matches, then we can apply the rule to the appropriate location in the state..

operator = None

An operator to apply to some part of a state.

locus = None
optional = None

Indicates whether or not the rule is optional

utsarga = None

A list of rules. These rules are all blocked if the current rule can apply.

apply(state, index)

Apply this rule and yield the results.

Parameters:
  • state – a state
  • index – the index where the first filter is applied.
has_apavada(other)

Return whether the other rule is an apavada to this one.

Rule B is an apavada to rule A if and only if:

  1. A != B
  2. If A matches some position, then B matches too.
  3. A and B have the same locus
  4. The operations performed by A and B are in conflict

For details on what (4) means specifically, see the comments on operators.Operator.conflicts_with().

Parameters:other – a rule

vyakarana.templates

This module contains classes and functions that let us define the Ashtadhyayi’s rules as tersely as possible.

license:MIT and BSD
class vyakarana.templates.RuleStub(name, left, center, right, op, **kw)

Bases: object

Wrapper for tuple rules.

The Ashtadhyayi uses a variety of terms to control when and how a rule applies. For example, ‘anyatarasyām’ denotes that a rule specifies an optional operation that can be accepted or rejected.

In this system, these terms are marked by wrapping a rule in this class or one of its subclasses.

name = None

Thte rule name

window = None

The rule context

operator = None

The rule operator

class vyakarana.templates.Ca(name, left, center, right, op, **kw)

Bases: vyakarana.templates.RuleStub

Wrapper for a rule that contains the word “ca”.

“ca” has a variety of functions, but generally it preserves parts of the previous rule in the current rule.

class vyakarana.templates.Na(name, left, center, right, op, **kw)

Bases: vyakarana.templates.RuleStub

Wrapper for a rule that just blocks other rules.

class vyakarana.templates.Nityam(name, left, center, right, op, **kw)

Bases: vyakarana.templates.RuleStub

Wrapper for a rule that cannot be rejected.

This is used to cancel earlier conditions.

class vyakarana.templates.Option(name, left, center, right, op, **kw)

Bases: vyakarana.templates.RuleStub

Wrapper for a rule that can be accepted optionally.

This is a superclass for a variety of optional conditions.

class vyakarana.templates.Anyatarasyam(name, left, center, right, op, **kw)

Bases: vyakarana.templates.Option

Wrapper for a rule that is indifferently accepted.

Modern scholarship rejects the traditional definition of anyatarasyām, but this system treats it as just a regular option.

class vyakarana.templates.Va(name, left, center, right, op, **kw)

Bases: vyakarana.templates.Option

Wrapper for a rule that is preferably accepted.

Modern scholarship rejects the traditional definiton of vā, but this system treats it as just a regular option.

class vyakarana.templates.Vibhasha(name, left, center, right, op, **kw)

Bases: vyakarana.templates.Option

Wrapper for a rule that is preferably not accepted.

Modern scholarship rejects the traditional definiton of vibhāṣā, but this system treats it as just a regular option.

class vyakarana.templates.Artha(name, left, center, right, op, **kw)

Bases: vyakarana.templates.Option

Wrapper for a rule that applies only in some semantic condition.

Since the semantic condition can be declined, this is essentially an optional provision.

class vyakarana.templates.Opinion(name, left, center, right, op, **kw)

Bases: vyakarana.templates.Option

Wrapper for a rule that is accepted by prior opinion.

Since the opinion can be declined, this is essentially the same as an optional provision.

vyakarana.templates.Shesha = <object object>

Signals use of the śeṣa device, which affects utsarga-apavāda inference.

Texts

class vyakarana.ashtadhyayi.Ashtadhyayi(stubs=None)

Given some input terms, yields a list of Sanskrit words.

This is the most abstract part of the system and doesn’t expect any internal knowledge about how the system works. This is almost always the only class that client libraries should use.

The heart of the class is derive(), which accepts a list of terms and yields State objects that represent finished words.

derive(sequence)

Yield all possible results.

Parameters:sequence – a starting sequence
rule_tree = None

Indexed arrangement of rules

classmethod with_rules_in(start, end, **kw)

Constructor using only a subset of the Ashtadhyayi’s rules.

This is provided to make it easier to test certain rule groups.

Parameters:
  • start – name of the first rule to use, e.g. “1.1.1”
  • end – name of the last rule to use, e.g. “1.1.73”
class vyakarana.dhatupatha.Dhatupatha(filename=None)

A collection of all verb roots in the Sanskrit language.

This class makes it easy to select a continuous range of roots from the Dhātupāṭha and query for other properties of interest, such as the original gaṇa.

All data is stored in a CSV file, which is read when the program begins.

The Dhātupāṭha is traditionally given as a list of roots, each stated in upadeśa with a basic gloss. An example:

1.1 bhū sattāyām

The first number indicates the root gaṇa, of which there are ten. This gaṇa determines the form that the root takes when followed by sārvadhātuka affixes. The second number indicates the root’s relative position within the gaṇa.

Although few modern editions of the text have accent markings, the Sanskrit grammatical tradition has preserved the original accents all of the original items. Per the conventions of SLP1, these are written as follows:

Accent SLP1 Devanagari IAST
udātta (no mark)    
anudātta \    
svarita ^    
all_dhatu = None

List of all dhatu, one for each row in the original CSV file.

dhatu_list(start, end=None)

Get an inclusive list of of dhatus.

Parameters:
  • start – the first dhatu in the list
  • end – the last dhatu in the list. If None, add until the end of the gana.
index_map = None

Maps a dhatu to its indices in self.all_dhatu.

init(filename)
Parameters:filename – path to the Dhatupatha file