topos

Topos deals with the abstract mathematical and structural foundations of music, providing topological scaffolding that can be instantiated into any musical context.

Collections

Patterns

General functions for generating and transforming sequences in a topological manner.

klotho.topos.collections.patterns.permute_list(lst, pt, preserve_signs=False)[source]

Algorithm 4: PermutList with optional sign preservation

Parameters:
  • lst (tuple) – List of elements to be permuted.

  • pt (int) – Starting position for the permutation.

  • preserve_signs (bool) – If True, preserves signs while rotating absolute values.

Return type:

tuple

Returns:

Circularly permuted list.

klotho.topos.collections.patterns.autoref(*args, preserve_signs=False)[source]

Algorithm 5: AutoRef with optional sign preservation

Parameters:
  • args – One or two lists to be doubly circularly permuted.

  • preserve_signs (bool) – If True, preserves signs while rotating absolute values.

Returns:

List containing the original element and its permutations.

klotho.topos.collections.patterns.autoref_rotmat(*args, mode='G', preserve_signs=False)[source]

AutoRef rotation matrices with optional sign preservation

Parameters:
  • args – One or two lists to generate rotation matrices from.

  • mode – Rotation mode (‘G’, ‘S’, ‘D’, or ‘C’).

  • preserve_signs (bool) – If True, preserves signs while rotating absolute values.

Returns:

Tuple of rotation matrices based on the specified mode.

klotho.topos.collections.patterns.iso_pairs(*lists)[source]

Generates tuples of elements from any number of input lists in a cyclic manner.

Creates a list of tuples where each tuple contains one element from each input list. The pairing continues cyclically until the length of the generated list equals the product of the lengths of all input lists. When the end of any list is reached, the iteration continues from the beginning of that list, effectively cycling through the shorter lists until all combinations are created.

This is a form of “cyclic pairing” or “modulo-based pairing” and is different from computing the Cartesian product.

Parameters:

*lists – Any number of input lists.

Returns:

A tuple of tuples where each inner tuple contains one element from each input list.

Return type:

tuple

Raises:

ValueError – If no lists are provided.

Example

>> iso_pairs([1, 2], [‘a’, ‘b’, ‘c’]) ((1, ‘a’), (2, ‘b’), (1, ‘c’), (2, ‘a’), (1, ‘b’), (2, ‘c’))

klotho.topos.collections.patterns.pair_adjacent(elements)[source]

Creates groups where elements are paired with their adjacent elements.

Parameters:

elements – A tuple of elements to be grouped.

Returns:

A tuple of valid groups.

Example

>> pair_adjacent((1, 2, 3, 4, 5)) ((1, (2, 3)), (2, (3, 4)), (3, (4, 5)), (4, (5, 1)), (5, (1, 2)))

klotho.topos.collections.patterns.nested_chain(elements)[source]

Creates a nested chain structure with elements.

Parameters:

elements – A tuple of elements to chain.

Returns:

A valid group with a nested chain structure.

Example

>> nested_chain((1, 2, 3, 4, 5)) (1, (2, 3, 4, 5))

klotho.topos.collections.patterns.alternate_sequence(elements)[source]

Creates a sequence where elements alternate between being part of the head and tail.

Parameters:

elements – A tuple of elements to alternate.

Returns:

A valid group with alternating elements.

Example

>> alternate_sequence((1, 2, 3, 4, 5)) (1, (3, 5, 2, 4))

Sequences

class klotho.topos.collections.sequences.Norg[source]

Bases: object

Per Nørgård’s “infinity” sequences.

Provides static methods for generating various integer sequences devised by the Danish composer Per Nørgård, most notably the infinity series used extensively in his compositional practice.

References

Examples

>>> Norg.inf(size=8)
array([ 0,  1, -1,  2,  1,  0, -2,  3])
static inf(start=0, size=128, step=1)[source]

Generate the infinity series.

When start is 0 and step is 1 an optimised pair-wise recurrence is used. For arbitrary start/step combinations the series is computed element-wise via inf_num.

Parameters:
  • start (int, optional) – Index at which to begin the series (default is 0).

  • size (int, optional) – Number of elements to generate (default is 128).

  • step (int, optional) – Index step between successive elements (default is 1).

Returns:

One-dimensional integer array of length size.

Return type:

numpy.ndarray

References

Examples

>>> Norg.inf(size=8)
array([ 0,  1, -1,  2,  1,  0, -2,  3])
>>> Norg.inf(start=4, size=4)
array([1, 0, -2, 3])
static inf_num(n)[source]

Compute the n-th value of the infinity series.

Uses the recursive definition: f(0) = 0, f(2n) = -f(n), f(2n+1) = f(n) + 1.

Parameters:

n (int) – Non-negative index into the infinity series.

Returns:

The value of the infinity series at position n.

Return type:

int

References

Examples

>>> Norg.inf_num(0)
0
>>> Norg.inf_num(7)
3
static n_partite(seed=[0, -2, -1], inv_pat=[-1, 1, 1], size=128)[source]

Generate a generalised n-partite infinity series.

Extends the tripartite construction to an arbitrary seed length and inversion pattern, producing self-similar integer sequences by recursively applying delta-inversion rules.

Parameters:
  • seed (list of int, optional) – Initial values of the series (default is [0, -2, -1]).

  • inv_pat (list of int, optional) – Cyclic pattern of inversion multipliers applied to successive deltas (default is [-1, 1, 1]).

  • size (int, optional) – Number of elements to generate (default is 128).

Returns:

One-dimensional integer array of length size.

Return type:

numpy.ndarray

References

Examples

>>> Norg.n_partite(size=9)
array([ 0, -2, -1,  2,  0, -1, -2,  0,  1])
static lake()[source]

Generate Nørgård’s tone lake sequence.

Note

Not yet implemented.

Return type:

None

References

class klotho.topos.collections.sequences.Pattern(iterable, end=False)[source]

Bases: object

Cyclical pattern iterator built from nested structure and delegates.

__init__(iterable, end=False)[source]
property length: int
property spec: NodeSpec
property pattern
property end
property position: int
reset()[source]
materialize_period()[source]
Return type:

tuple[Any, ...]

static from_random(elements, length=5, max_nesting_level=3, max_inner_length=3, weights=None, nesting_probability=0.333)[source]
Return type:

Pattern

class klotho.topos.collections.sequences.Cyclic(sequence)[source]

Bases: object

Finite repeating sequence for use as a Pattern delegate.

__init__(sequence)[source]
property sequence

Sets

class klotho.topos.collections.sets.Operations[source]

Bases: object

Static methods for mathematical set operations.

This class provides a collection of static methods for performing common set operations including union, intersection, difference, and specialized musical set operations like transposition and inversion.

union(set1, set2)[source]

Return the union of two sets.

intersect(set1, set2)[source]

Return the intersection of two sets.

diff(set1, set2)[source]

Return the difference of two sets.

symm_diff(set1, set2)[source]

Return the symmetric difference of two sets.

is_subset(subset, superset)[source]

Check if the first set is a subset of the second set.

is_superset(superset, subset)[source]

Check if the first set is a superset of the second set.

invert(set1, axis, modulus)[source]

Invert a set around a given axis using modular arithmetic.

transpose(set1, transposition_interval, modulus)[source]

Transpose a set by a given interval using modular arithmetic.

complement(S, modulus)[source]

Return the complement of a set within a given modulus.

congruent(S, modulus, residue)[source]

Return elements congruent to a residue modulo the given modulus.

intervals(S)[source]

Calculate intervals between successive numbers in a sorted sequence.

interval_vector(set1, modulus)[source]

Compute the interval vector of a set of pitches.

Examples

Basic set operations:

>>> set1 = {0, 1, 4, 7}
>>> set2 = {0, 2, 5, 9}
>>> Operations.union(set1, set2)
{0, 1, 2, 4, 5, 7, 9}

Musical transformations:

>>> chord = {0, 4, 7}  # C major triad
>>> Operations.transpose(chord, 5, 12)  # Transpose up a fourth
{5, 9, 0}
static union(set1, set2)[source]

Return the union of two sets.

Parameters:
  • set1 (set) – The first set.

  • set2 (set) – The second set.

Returns:

A new set containing all unique elements from both sets.

Return type:

set

static intersect(set1, set2)[source]

Return the intersection of two sets.

Parameters:
  • set1 (set) – The first set.

  • set2 (set) – The second set.

Returns:

A new set containing only elements present in both sets.

Return type:

set

static diff(set1, set2)[source]

Return the difference of two sets.

Parameters:
  • set1 (set) – The first set.

  • set2 (set) – The second set.

Returns:

A new set containing elements in set1 but not in set2.

Return type:

set

static symm_diff(set1, set2)[source]

Return the symmetric difference of two sets.

Parameters:
  • set1 (set) – The first set.

  • set2 (set) – The second set.

Returns:

A new set containing elements in either set1 or set2 but not both.

Return type:

set

static is_subset(subset, superset)[source]

Check if the first set is a subset of the second set.

Parameters:
  • subset (set) – The potential subset.

  • superset (set) – The potential superset.

Returns:

True if subset is a subset of superset, False otherwise.

Return type:

bool

static is_superset(superset, subset)[source]

Check if the first set is a superset of the second set.

Parameters:
  • superset (set) – The potential superset.

  • subset (set) – The potential subset.

Returns:

True if superset is a superset of subset, False otherwise.

Return type:

bool

static invert(set1, axis=0, modulus=12)[source]

Invert a set around a given axis using modular arithmetic.

Parameters:
  • set1 (set) – The set to invert.

  • axis (int, optional) – The axis of inversion (default is 0).

  • modulus (int, optional) – The modulus for the arithmetic (default is 12).

Returns:

The inverted set.

Return type:

set

Examples

>>> chord = {0, 4, 7}  # C major triad
>>> Operations.invert(chord, axis=0, modulus=12)
{0, 8, 5}
static transpose(set1, transposition_interval, modulus=12)[source]

Transpose a set by a given interval using modular arithmetic.

Parameters:
  • set1 (set) – The set to transpose.

  • transposition_interval (int) – The interval to transpose by.

  • modulus (int, optional) – The modulus for the arithmetic (default is 12).

Returns:

The transposed set.

Return type:

set

Examples

>>> chord = {0, 4, 7}  # C major triad
>>> Operations.transpose(chord, 7, 12)  # Transpose up a fifth
{7, 11, 2}
static complement(S, modulus=12)[source]

Return the complement of a set within a given modulus.

Parameters:
  • S (set) – The set to complement.

  • modulus (int, optional) – The modulus defining the universal set (default is 12).

Returns:

The complement set containing all elements from 0 to modulus-1 not in S.

Return type:

set

Examples

>>> pentatonic = {0, 2, 4, 7, 9}
>>> Operations.complement(pentatonic, 12)
{1, 3, 5, 6, 8, 10, 11}
static congruent(S, modulus, residue)[source]

Return elements congruent to a residue modulo the given modulus.

Parameters:
  • S (set) – The input set.

  • modulus (int) – The modulus for congruence testing.

  • residue (int) – The residue value to match.

Returns:

Elements from S that are congruent to residue modulo modulus.

Return type:

set

Examples

>>> numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> Operations.congruent(numbers, 3, 1)  # Numbers ≡ 1 (mod 3)
{1, 4, 7}
static intervals(S)[source]

Calculate intervals between successive numbers in a sorted sequence.

Parameters:

S (set) – A set of numbers.

Returns:

The intervals between consecutive elements when sorted.

Return type:

set

Examples

>>> scale = {0, 2, 4, 5, 7, 9, 11}  # Major scale
>>> Operations.intervals(scale)
{1, 2}
static interval_vector(set1, modulus=12)[source]

Compute the interval vector of a set of pitches.

The interval vector represents the number of occurrences of each interval between pitches in a set. Intervals larger than half the modulus are inverted to their complements.

Parameters:
  • set1 (set) – A set of integers representing pitches.

  • modulus (int, optional) – The modulus for interval calculations (default is 12).

Returns:

An array representing the interval vector with length modulus//2.

Return type:

numpy.ndarray

Examples

>>> chord = {0, 4, 7}  # C major triad
>>> Operations.interval_vector(chord, 12)
array([0, 0, 1, 1, 1, 0])
class klotho.topos.collections.sets.Sieve(modulus=1, residue=0, N=255)[source]

Bases: object

Xenakis-style sieve for generating sets through modular arithmetic operations.

A Sieve implements Iannis Xenakis’s concept of sieves, which are mathematical structures based on modular arithmetic used in algorithmic composition. A sieve can represent a single modular constraint or complex combinations of multiple constraints using logical operations.

In Xenakis’s notation, a basic sieve is written as (m,r) where m is the modulus and r is the residue. Complex sieves combine these using union (∪), intersection (∩), and complement operations.

Parameters:
  • modulus (int, optional) – The step size of the arithmetic progression (default is 1).

  • residue (int, optional) – The starting value of the progression (default is 0).

  • N (int, optional) – The upper bound for generated values (default is 255).

S

The generated sieve values.

Type:

set

N

The upper bound for generated values.

Type:

int

period

The modulus (step size) of the sieve.

Type:

int

r

The residue (starting value) of the sieve.

Type:

int

congr

Values congruent to the residue modulo the period.

Type:

set

compl

The complement of the sieve within [0, N].

Type:

set

Examples

Create a basic sieve (3,1) - multiples of 3 starting from 1:

>>> sieve = Sieve(modulus=3, residue=1, N=10)
>>> print(sorted(sieve.S))
[1, 4, 7, 10]

See also

Operations.union

Combine sieves using union operation

Operations.intersect

Combine sieves using intersection operation

Notes

This implementation provides the foundation for Xenakis sieve theory. For complex sieve expressions, use the Operations class methods to combine multiple Sieve instances with logical operations.

__init__(modulus=1, residue=0, N=255)[source]

Initialize a Sieve.

Parameters:
  • modulus (int, optional) – The step size of the arithmetic progression (default is 1).

  • residue (int, optional) – The starting value of the progression (default is 0).

  • N (int, optional) – The upper bound for generated values (default is 255).

property S

The generated sieve values.

Returns:

The set of integers generated by the sieve.

Return type:

set

property period

The modulus (step size) of the sieve.

Returns:

The step size of the arithmetic progression.

Return type:

int

property r

The residue (starting value) of the sieve.

Returns:

The starting value of the arithmetic progression.

Return type:

int

property congr

Values congruent to the residue modulo the period.

Returns:

Elements in S that are congruent to residue mod period.

Return type:

set

property compl

The complement of the sieve within [0, N].

Returns:

All integers from 0 to N that are not in the sieve.

Return type:

set

property N

The upper bound for generated values.

Returns:

The maximum value in the sieve range.

Return type:

int

__str__()[source]

String representation of the Sieve.

Returns:

A formatted string showing the sieve parameters and values.

Return type:

str

__repr__()[source]

String representation of the Sieve.

Returns:

A formatted string showing the sieve parameters and values.

Return type:

str

__or__(other)[source]

Union operation between two sieves (Xenakis: A ∪ B).

Parameters:

other (Sieve) – The other sieve to combine with.

Returns:

The union of both sieve sets.

Return type:

set

Examples

>>> sieve1 = Sieve(3, 1, 10)  # (3,1)
>>> sieve2 = Sieve(5, 2, 10)  # (5,2)
>>> combined = sieve1 | sieve2
>>> print(sorted(combined))
[1, 2, 4, 7, 10]
__and__(other)[source]

Intersection operation between two sieves (Xenakis: A ∩ B).

Parameters:

other (Sieve) – The other sieve to intersect with.

Returns:

The intersection of both sieve sets.

Return type:

set

Examples

>>> sieve1 = Sieve(2, 0, 20)  # Even numbers
>>> sieve2 = Sieve(3, 0, 20)  # Multiples of 3
>>> intersection = sieve1 & sieve2
>>> print(sorted(intersection))
[0, 6, 12, 18]
__sub__(other)[source]

Difference operation between two sieves (Xenakis: A - B).

Parameters:

other (Sieve) – The sieve to subtract from this one.

Returns:

Elements in this sieve but not in the other.

Return type:

set

Examples

>>> sieve1 = Sieve(2, 0, 10)  # Even numbers
>>> sieve2 = Sieve(4, 0, 10)  # Multiples of 4
>>> difference = sieve1 - sieve2
>>> print(sorted(difference))
[2, 6, 10]
__xor__(other)[source]

Symmetric difference operation between two sieves (A ⊕ B).

Parameters:

other (Sieve) – The other sieve for symmetric difference.

Returns:

Elements in either sieve but not in both.

Return type:

set

Examples

>>> sieve1 = Sieve(2, 0, 10)  # Even numbers
>>> sieve2 = Sieve(3, 0, 10)  # Multiples of 3
>>> sym_diff = sieve1 ^ sieve2
>>> print(sorted(sym_diff))
[2, 3, 4, 8, 9, 10]
__invert__()[source]

Complement operation for the sieve (~A).

Returns:

All integers from 0 to N that are not in this sieve.

Return type:

set

Examples

>>> sieve = Sieve(2, 0, 10)  # Even numbers
>>> complement = ~sieve
>>> print(sorted(complement))
[1, 3, 5, 7, 9]
class klotho.topos.collections.sets.CombinationSet(factors=('A', 'B', 'C', 'D'), r=2)[source]

Bases: object

A combinatorial set generating all r-combinations from a set of factors.

This class generates all possible combinations of size r from a given set of factors, useful for combinatorial analysis and set operations. It also creates symbolic aliases and an associated graph structure for analysis.

Parameters:
  • factors (tuple, optional) – The factors to combine (default is (‘A’, ‘B’, ‘C’, ‘D’)).

  • r (int, optional) – The size of each combination (default is 2).

factors

The sorted tuple of input factors.

Type:

tuple

rank

The size of each combination.

Type:

int

combos

The set of all r-combinations from the factors.

Type:

set

graph

A complete graph with combinations as nodes.

Type:

networkx.Graph

factor_to_alias

Mapping from factors to symbolic aliases.

Type:

dict

alias_to_factor

Mapping from symbolic aliases to factors.

Type:

dict

Examples

Create combinations with default parameters:

>>> cs = CombinationSet()  # Uses ('A', 'B', 'C', 'D') with r=2
>>> print(cs.combos)
{('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')}
__init__(factors=('A', 'B', 'C', 'D'), r=2)[source]

Initialize a CombinationSet.

Parameters:
  • factors (tuple, optional) – The factors to combine (default is (‘A’, ‘B’, ‘C’, ‘D’)).

  • r (int, optional) – The size of each combination (default is 2).

property factors

The sorted tuple of input factors.

Returns:

The factors used to generate combinations.

Return type:

tuple

property rank

The size of each combination.

Returns:

The number of elements in each combination.

Return type:

int

property combos

The set of all r-combinations from the factors.

Returns:

All possible combinations of size r from the factors.

Return type:

set

property graph

A complete graph with combinations as nodes.

Returns:

A complete graph where each node represents a combination.

Return type:

Graph

property factor_to_alias

Mapping from factors to symbolic aliases.

Returns:

Dictionary mapping each factor to a symbolic representation.

Return type:

dict

property alias_to_factor

Mapping from symbolic aliases to factors.

Returns:

Dictionary mapping symbolic representations back to factors.

Return type:

dict

__str__()[source]

String representation of the CombinationSet.

Returns:

A formatted string showing rank, factors, and combinations.

Return type:

str

__repr__()[source]

String representation of the CombinationSet.

Returns:

A formatted string showing rank, factors, and combinations.

Return type:

str

class klotho.topos.collections.sets.PartitionSet(n, k, graph_type='feature_distance')[source]

Bases: object

A set of integer partitions with associated graph structures for analysis.

This class generates all partitions of an integer n into exactly k parts, analyzes their structural properties, and creates various graph representations for studying relationships between partitions.

Parameters:
  • n (int) – The integer to partition.

  • k (int) – The number of parts in each partition.

  • graph_type ({'feature_distance', 'decomposition_tree', 'substructure_embedding'}, optional) – The type of graph to construct (default is ‘feature_distance’).

data

DataFrame containing partitions and their computed features.

Type:

pandas.DataFrame

partitions

Tuple of all generated partitions.

Type:

tuple

mean

The mean value of partition parts (n/k).

Type:

float

graph

Graph representation based on the specified graph_type.

Type:

networkx.Graph or networkx.DiGraph

graph_type

The type of graph construction used.

Type:

str

Examples

Generate partitions of 8 into 3 parts:

>>> ps = PartitionSet(8, 3)
>>> ps.data
   partition  unique_count  span  variance
0  (6, 1, 1)             2     5    5.5556
1  (5, 2, 1)             3     4    2.8889
2  (4, 3, 1)             3     3    1.5556
3  (4, 2, 2)             2     2    0.8889
4  (3, 3, 2)             2     1    0.2222
__init__(n, k, graph_type='feature_distance')[source]

Initialize a PartitionSet.

Parameters:
  • n (int) – The integer to partition.

  • k (int) – The number of parts in each partition.

  • graph_type ({'feature_distance', 'decomposition_tree', 'substructure_embedding'}, optional) – The type of graph to construct (default is ‘feature_distance’).

property data

DataFrame containing partitions and their computed features.

Returns:

DataFrame with partition, unique_count, span, and variance columns.

Return type:

pandas.DataFrame

property partitions

Tuple of all generated partitions.

Returns:

All partitions of n into k parts.

Return type:

tuple

property mean: float

The mean value of partition parts.

Returns:

The arithmetic mean n/k.

Return type:

float

property graph

Graph representation based on the specified graph_type.

Returns:

The graph representation of partition relationships.

Return type:

Graph

property graph_type

The type of graph construction used.

Returns:

The graph type identifier.

Return type:

str

__str__()[source]

String representation of the PartitionSet.

Returns:

A formatted string showing partition data and statistics.

Return type:

str

__repr__()[source]

String representation of the PartitionSet.

Returns:

A formatted string showing partition data and statistics.

Return type:

str

class klotho.topos.collections.sets.GenCol(generator='3/2', period=2, iterations=7)[source]

Bases: object

Generated Collection - A multiplicative collection formed by repeatedly applying a generator.

A multiplicative collection created by starting with an initial value and repeatedly multiplying by the generator, reducing modulo the period. This is the multiplicative analog to the Sieve class, useful for generating multiplicative pitch collections and harmonic series subsets.

Parameters:
  • generator (Union[str, int, float, Fraction]) – The generator value used for multiplication.

  • period (Union[str, int, float, Fraction], optional) – The period of equivalence (default is 2).

  • iterations (int, optional) – Number of times to apply the generator (default is 12).

generator

The generator value as a Fraction.

Type:

Fraction

period

The period of equivalence as a Fraction.

Type:

Fraction

iterations

Number of generator applications.

Type:

int

collection

The raw generated collection values.

Type:

list of Fraction

normalized_collection

Collection values normalized within the period.

Type:

list of Fraction

steps

Interval steps between consecutive normalized values.

Type:

set of Fraction

Examples

Create a collection with default parameters (perfect fifth generator):

>>> gen_col = GenCol()  # Uses '3/2' generator, period=2, iterations=7
>>> print(*[str(f) for f in gen_col.normalized_collection])
1 3/2 9/8 27/16 81/64 243/128 729/512 2187/2048
__init__(generator='3/2', period=2, iterations=7)[source]

Initialize a Generated Collection.

Parameters:
  • generator (Union[str, int, float, Fraction], optional) – The generator value used for multiplication (default is ‘3/2’).

  • period (Union[str, int, float, Fraction], optional) – The period of equivalence (default is 2).

  • iterations (int, optional) – Number of times to apply the generator (default is 7).

property generator: Fraction

The generator value as a Fraction.

Returns:

The generator used for multiplication.

Return type:

Fraction

property period: Fraction

The period of equivalence as a Fraction.

Returns:

The period within which values are considered equivalent.

Return type:

Fraction

property iterations: int

Number of generator applications.

Returns:

The number of times the generator is applied.

Return type:

int

property collection: List[Fraction]

The raw generated collection values.

Returns:

A copy of the generated collection values.

Return type:

list of Fraction

property normalized_collection: List[Fraction]

Collection values normalized within the period.

Returns:

The collection values reduced to within the period range.

Return type:

list of Fraction

property steps: Set[Fraction]

Interval steps between consecutive normalized values.

Returns:

The intervals between consecutive values in the normalized collection.

Return type:

set of Fraction

__str__()[source]

String representation of the GenCol.

Returns:

Compact string representation showing generator, period, and iterations.

Return type:

str

__repr__()[source]

String representation of the GenCol.

Returns:

Compact string representation showing generator, period, and iterations.

Return type:

str

Formal Grammars

Grammars

klotho.topos.formal_grammars.grammars.rand_rules(symbols, word_length_min=1, word_length_max=3)[source]
klotho.topos.formal_grammars.grammars.constrain_rules(rules, constraints)[source]
klotho.topos.formal_grammars.grammars.apply_rules(rules={}, axiom='')[source]

e.g., context-free grammar:

Alphabet V: A B Axiom w: B Production Rules P1: A : AB P2: B : A

klotho.topos.formal_grammars.grammars.gen_str(generations=0, axiom='', rules={}, display=False)[source]

Graphs

Core Graphs

class klotho.topos.graphs.graphs.Graph(directed=False)[source]

Bases: object

__init__(directed=False)[source]

Initialize an empty Klotho graph.

property nodes

Return a view of the nodes that can be subscripted.

property edges

Return a view of the edges.

__getitem__(node)[source]

Get node data for a given node.

__len__()[source]

Return the number of nodes.

__str__()[source]

String representation of the graph.

__repr__()[source]

String representation of the graph.

__iter__()[source]

Iterate over node objects.

__contains__(node)[source]

Check if a node is in the graph.

out_degree(node)[source]

Get the out-degree of a node

in_degree(node)[source]

Get the in-degree of a node

classmethod directed()[source]

Create an empty directed graph.

classmethod digraph()[source]

Alias for directed graph creation.

classmethod from_rustworkx(graph, copy_graph=True)[source]

Create a Graph from an existing RustworkX graph.

classmethod from_networkx(graph, copy_graph=True)[source]

Create a Graph from a NetworkX graph.

classmethod from_nodes_edges(nodes=None, edges=None, directed=False, node_mode='label', node_key='label')[source]

Create a graph from node and edge iterables.

classmethod from_edges(edges, directed=False, node_mode='label', node_key='label')[source]

Create a graph from an edge list.

classmethod empty_graph(n_nodes=0, labels=None, directed=False, node_key='label')[source]

Create an empty graph with optional labeled nodes.

classmethod path_graph(n_nodes, labels=None, directed=False, node_key='label')[source]

Create a path graph with optional labels.

classmethod cycle_graph(n_nodes, labels=None, directed=False, node_key='label')[source]

Create a cycle graph with optional labels.

classmethod star_graph(n_nodes, center=0, labels=None, directed=False, node_key='label')[source]

Create a star graph with optional labels.

classmethod random_graph(n_nodes, p=0.3, labels=None, directed=False, seed=None, node_key='label')[source]

Create a random Erdos-Renyi style graph with optional labels.

neighbors(node)[source]

Get neighbors of a node

predecessors(node)[source]

Returns all predecessors of a node.

Parameters:

node (int) – The node whose predecessors to return.

Returns:

All predecessors of the node.

Return type:

tuple

successors(node)[source]

Returns all successors of a node.

Parameters:

node (int) – The node whose successors to return.

Returns:

All successors of the node in sorted order (left-to-right).

Return type:

tuple

descendants(node)[source]

Returns all descendants of a node using native RustworkX algorithm.

Parameters:

node (int) – The node whose descendants to return.

Returns:

All descendants of the node.

Return type:

tuple

ancestors(node)[source]

Returns all ancestors of a node using native RustworkX algorithm.

Parameters:

node (int) – The node whose ancestors to return.

Returns:

All ancestors of the node.

Return type:

tuple

topological_sort()[source]

Returns nodes in topological order.

Returns:

Nodes in topological order.

Return type:

generator

to_directed()[source]

Return a directed version of this graph.

Returns:

A new Graph instance with directed edges.

Return type:

Graph

number_of_nodes()[source]

Return the number of nodes in the graph.

Returns:

Number of nodes.

Return type:

int

number_of_edges()[source]

Return the number of edges in the graph.

Returns:

Number of edges.

Return type:

int

nodes_with_data(data=True)[source]

Return nodes with their data.

Parameters:

data (bool) – If True, return node data as well.

Returns:

Iterator of (node, data) pairs if data=True, else just nodes.

Return type:

Iterator

subgraph(node, renumber=True)[source]

Extract a subgraph starting from a given node.

Parameters:
  • node (int) – The node to use as the starting point of the subgraph.

  • renumber (bool) – Whether to renumber the nodes in the new graph.

Returns:

A new Graph object representing the subgraph.

Return type:

Graph

property root_nodes

Returns root nodes (nodes with no predecessors)

add_node(**attr)[source]

Add a node to the graph.

Parameters:

**attr (dict) – Node attributes as keyword arguments.

Returns:

The node ID that was added.

Return type:

int

set_node_data(node, **attr)[source]

Update data for an existing node.

Parameters:
  • node (int) – The node to update.

  • **attr (dict) – Node attributes to set.

update_node_data(node, attrs)[source]

Update data for an existing node from a dictionary.

replace_node_data(node, attrs)[source]

Replace all data for an existing node.

remove_node(node)[source]

Remove a node from the graph.

add_edge(u, v, **attr)[source]

Add an edge to the graph with optional attributes.

has_edge(u, v)[source]

Check if an edge exists between two nodes.

remove_edge(u, v)[source]

Remove an edge from the graph.

update(edges=None, nodes=None)[source]

Update the graph with nodes and edges.

clear()[source]

Remove all nodes and edges from the graph.

set_node_attributes(node, attributes)[source]

Set attributes for a node.

clear_node_attributes(nodes=None)[source]

Clear attributes of specified nodes or all nodes.

Parameters:

nodes (list, optional) – Specific nodes to clear attributes for, or None for all nodes.

renumber_nodes(method='default')[source]

Renumber the nodes in the graph to consecutive integers.

Parameters:

method (str) – The method to use for renumbering: - ‘default’: Use sequential numbering - ‘dfs’: Use depth-first search preorder - ‘bfs’: Use breadth-first search

Returns:

Self with renumbered nodes.

Return type:

Graph

copy()[source]

Create a deep copy of this graph.

is_directed()[source]

Return True if graph is directed, False otherwise.

is_multigraph()[source]

Return True if graph is a multigraph, False otherwise.

to_networkx()[source]

Convert this Graph to a NetworkX graph for compatibility with NetworkX functions.

Returns:

NetworkX equivalent of this graph.

Return type:

networkx.Graph or networkx.DiGraph

classmethod grid_graph(dims, periodic=False)[source]

Create a grid graph with dimensions specified in dims.

Creates a grid graph where nodes are numbered sequentially 0, 1, 2, … and node data contains the coordinate as a tuple.

Parameters:
  • dims (list or tuple) – List of ranges or iterables defining the coordinate space for each dimension.

  • periodic (bool, optional) – Whether to create periodic boundary conditions (default is False)

Returns:

A new Graph instance with grid structure and coordinate data in nodes

Return type:

Graph

classmethod complete_graph(n_nodes, labels=None, directed=False, node_key='label')[source]

Create a complete graph.

Parameters:

n_nodes (int) – Number of nodes in the complete graph.

Returns:

A new Graph instance with complete structure.

Return type:

Graph

classmethod from_cost_matrix(cost_matrix, items)[source]

Create a Graph from a cost matrix.

Transform a symmetric cost matrix into an undirected graph where edge weights represent the costs between nodes. Self-loops are excluded from the resulting graph.

Parameters:
  • cost_matrix (numpy.ndarray) – Symmetric cost matrix with numeric values. Should be square with dimensions matching the length of items.

  • items (List[T]) – List of items corresponding to matrix indices. Used as node values in the resulting graph.

Returns:

Undirected graph with nodes corresponding to matrix indices and edge weights equal to the cost matrix values. Only edges with positive costs are included. Node attributes ‘value’ contain the original items.

Return type:

Graph

Examples

Create a graph from a simple cost matrix:

>>> import numpy as np
>>> matrix = np.array([[0, 1, 2], [1, 0, 3], [2, 3, 0]])
>>> items = ['A', 'B', 'C']
>>> graph = Graph.from_cost_matrix(matrix, items)
>>> list(graph.edges(data=True))
[('A', 'B', {'weight': 1}), ('A', 'C', {'weight': 2}), ('B', 'C', {'weight': 3})]
class klotho.topos.graphs.graphs.GraphNodeView(graph)[source]

Bases: object

View of graph nodes that mimics NetworkX NodeView behavior.

__init__(graph)[source]
__call__(data=False)[source]

Return nodes with optional data.

class klotho.topos.graphs.graphs.GraphEdgeView(graph)[source]

Bases: object

View of graph edges that mimics NetworkX EdgeView behavior.

__init__(graph)[source]
__call__(data=False)[source]

Return edges with optional data.

__getitem__(edge)[source]

Get edge data for a given edge (u, v).

Trees

Tree Implementation

class klotho.topos.graphs.trees.trees.Tree(root, children)[source]

Bases: Graph

A directed acyclic graph tree structure.

Represents a rooted tree where each node has at most one parent. Built from nested tuple structures and backed by a RustworkX directed graph inherited from Graph.

Subclasses can override _node_value_attr to use a different attribute name for the node value (e.g. RhythmTree uses 'proportion' instead of 'label').

Parameters:
  • root (hashable) – The value for the root node of the tree.

  • children (tuple) – Nested tuple structure defining the tree’s children. Each element is either a leaf value or a (value, children) pair.

__init__(root, children)[source]
property root
property group
classmethod from_tree_structure(source_tree)[source]

Create a new instance with the same topology as source_tree but no node data.

property depth

Maximum depth of the tree.

Returns:

The maximum depth of any node in the tree

Return type:

int

property k

Maximum branching factor of the tree

property leaf_nodes

Return leaf nodes (nodes with no successors) in tree traversal order.

Returns:

All leaf nodes in the tree, in left-right traversal order

Return type:

tuple

subtree_leaves(node)[source]

Return leaf nodes of the subtree rooted at the given node, in left-right order.

Parameters:

node (int) – The root of the subtree whose leaves to return

Returns:

Leaf nodes of the subtree in left-right traversal order

Return type:

tuple

Raises:

ValueError – If the node is not found in the tree

depth_of(node)[source]

Return the depth of a node in the tree.

The depth is the length of the path from the root to the node.

Parameters:

node (int) – The node to get the depth of

Returns:

The depth of the node (0 for root)

Return type:

int

Raises:

ValueError – If the node is not found in the tree

parent(node)[source]

Returns the parent of a node.

Parameters:

node (hashable) – The node to get the parent of.

Returns:

The parent node, or None if the node is the root.

Return type:

int or None

ancestors(node)[source]

Return all ancestors of a node in the tree.

Parameters:

node (int) – The node whose ancestors to return

Returns:

All ancestors from root to parent (excluding the node itself)

Return type:

tuple

Raises:

ValueError – If the node is not found in the tree

descendants(node)[source]

Return all descendants of a node in depth-first order.

Parameters:

node (int) – The node whose descendants to return

Returns:

All descendants of the node in depth-first order

Return type:

tuple

Raises:

ValueError – If the node is not found in the tree

branch(node)[source]

Return all nodes on the branch from the root to the given node.

Parameters:

node (int) – The target node

Returns:

All nodes from root to the given node (inclusive)

Return type:

tuple

Raises:

ValueError – If the node is not found in the tree

path_signature(root_node, target_node)[source]

Return child-index path from root_node to target_node.

The signature is a tuple of child indices describing how to navigate from root_node to target_node by repeated successors lookups.

node_from_signature(root_node, signature)[source]

Resolve a node by child-index signature from root_node.

map_parallel_nodes(other_tree, self_root=None, other_root=None)[source]

Map nodes between topologically parallel subtrees.

Returns a dict mapping nodes in self to corresponding nodes in other_tree by child-order traversal.

siblings(node)[source]

Returns the siblings of a node (nodes with the same parent).

lowest_common_ancestor(node_a, node_b)[source]
subtree(node, renumber=True)[source]

Extract a tree subtree rooted at the given node.

Parameters:
  • node (int) – The node to use as the root of the subtree

  • renumber (bool, optional) – Whether to renumber the nodes in the new tree (default: True)

Returns:

A new Tree object representing the subtree containing the node and all its descendants

Return type:

Tree

Raises:

ValueError – If the node is not found in the tree

at_depth(n, operator='==')[source]

Return nodes at a specific depth.

Parameters:
  • n (int) – The depth level to query

  • operator (str, optional) – Comparison operator (‘==’, ‘>=’, ‘<=’, ‘<’, ‘>’), default is ‘==’

Returns:

Nodes satisfying the depth condition in breadth-first order

Return type:

list

Raises:

ValueError – If operator is not supported

add_node(**attr)[source]

Add a node to the tree

add_edge(u, v, **attr)[source]

Add an edge to the tree

remove_node(node)[source]

Remove a node and its subtree

remove_edge(u, v)[source]

Remove an edge from the tree

add_child(parent, index=None, **attr)[source]

Add a child node to a parent.

Parameters:
  • parent (int) – The parent node ID.

  • index (int or None, optional) – Position to insert child (default is None, which appends).

  • **attr (dict) – Node attributes.

Returns:

The new child node ID.

Return type:

int

add_subtree(parent, subtree, index=None)[source]

Add a subtree as a child of a parent node.

Parameters:
  • parent (int) – The parent node to attach to.

  • subtree (Tree) – Tree instance to attach.

  • index (int or None, optional) – Position to insert subtree (default is None, which appends).

Returns:

The root ID of the attached subtree.

Return type:

int

prune(node)[source]

Remove a node and promote its children to its parent.

Parameters:

node (int) – The node to remove.

remove_subtree(node)[source]

Remove a node and its entire subtree.

Parameters:

node (int) – The root of the subtree to remove.

replace_node(old_node, **attr)[source]

Replace a node with new attributes while preserving structure.

Parameters:
  • old_node (int) – The node to replace.

  • **attr (dict) – New attributes for the node.

Returns:

The replaced node ID.

Return type:

int

graft_subtree(target_node, subtree, mode='replace')[source]

Graft a subtree onto the tree at the specified leaf node.

Parameters:
  • target_node (int) – The leaf node where the subtree will be grafted

  • subtree (Tree) – The Tree instance to graft onto this tree

  • mode (str, optional) – Grafting mode - either ‘replace’ or ‘adopt’ (default: ‘replace’) - ‘replace’: Replace the leaf node with subtree root - ‘adopt’: Keep the leaf node and give it the children from subtree root

Returns:

The root node ID of the grafted subtree (for ‘replace’ mode) or the target_node ID (for ‘adopt’ mode)

Return type:

int

Raises:
  • TypeError – If subtree is not a Tree instance

  • ValueError – If target_node is not found in the tree, is not a leaf node, or mode is invalid

move_subtree(node, new_parent, index=None)[source]

Move a subtree to a new parent.

Parameters:
  • node (int) – Root of subtree to move.

  • new_parent (int) – New parent node.

  • index (int or None, optional) – Position under new parent (default is None, which appends).

prune_to_depth(max_depth)[source]

Prune the tree to a maximum depth, removing all nodes beyond that depth.

prune_leaves(n)[source]

Prune n levels from each branch, starting from the leaves.

__deepcopy__(memo)[source]

Create a deep copy of the tree including Tree-specific attributes.

Group

class klotho.topos.graphs.trees.group.Group(G)[source]

Bases: tuple

Immutable (D, S) pair representing a rhythmic subdivision group.

D is the top-level duration/divisor and S is a (possibly nested) tuple of subdivisions. Nested tuples within S are recursively converted to Group instances, so the entire tree is typed throughout.

Parameters:

G (tuple) – A two-element tuple (D, S) where D is a numeric duration and S is a subdivision value or nested tuple of subdivisions.

Examples

>>> g = Group((4, (1, 2, 1)))
>>> g.D
4
>>> g.S
(1, 2, 1)
property D
property S
klotho.topos.graphs.trees.group.factor_children(subdivs)[source]

Flatten a nested subdivision tuple into a flat tuple of leaf values.

Recursively traverses subdivs and collects every non-tuple element in depth-first order.

Parameters:

subdivs (tuple) – Arbitrarily nested tuple of numeric leaf values.

Returns:

Flat tuple containing all leaf values in traversal order.

Return type:

tuple

Examples

>>> factor_children((3, (2, 1), 4))
(3, 2, 1, 4)
klotho.topos.graphs.trees.group.refactor_children(subdivs, factors)[source]

Re-nest flat factors into the nested structure of subdivs.

Walks subdivs depth-first and replaces each leaf position with the next value from factors, preserving the original nesting topology.

Parameters:
  • subdivs (tuple) – Nested tuple whose structure (but not leaf values) is preserved.

  • factors (tuple) – Flat sequence of replacement leaf values. Must contain exactly as many elements as there are leaves in subdivs.

Returns:

A new nested tuple with the same shape as subdivs but with leaf values taken sequentially from factors.

Return type:

tuple

Examples

>>> refactor_children((3, (2, 1), 4), (10, 20, 30, 40))
(10, (20, 30), 40)
klotho.topos.graphs.trees.group.get_signs(subdivs)[source]

Extract the sign of each leaf value in a nested subdivision tuple.

Parameters:

subdivs (tuple) – Arbitrarily nested tuple of numeric values.

Returns:

Flat list of +1 or -1 for each leaf, in depth-first order.

Return type:

list of int

Examples

>>> get_signs((3, (-2, 1), -4))
[1, -1, 1, -1]
klotho.topos.graphs.trees.group.get_abs(subdivs)[source]

Get the absolute values of all leaves in a nested subdivision tuple.

Parameters:

subdivs (tuple) – Arbitrarily nested tuple of numeric values.

Returns:

Flat list of absolute leaf values in depth-first order.

Return type:

list of int or float

Examples

>>> get_abs((3, (-2, 1), -4))
[3, 2, 1, 4]
klotho.topos.graphs.trees.group.rotate_children(subdivs, n=1, preserve_signs=False)[source]

Rotate the leaf values of a nested subdivision tuple.

Flattens the leaves, performs a left-rotation by n positions, and re-nests them into the original structure. When preserve_signs is True, only the absolute values are rotated while the original sign at each leaf position is retained.

Parameters:
  • subdivs (tuple) – Arbitrarily nested tuple of numeric values.

  • n (int, optional) – Number of positions to rotate left (default is 1).

  • preserve_signs (bool, optional) – If True, rotate absolute values only and reapply the original signs at each position (default is False).

Returns:

A new nested tuple with the same shape as subdivs and rotated leaf values.

Return type:

tuple

Examples

>>> rotate_children((1, (2, 3), 4))
(2, (3, 4), 1)
>>> rotate_children((1, (-2, 3), -4), preserve_signs=True)
(2, (-3, 4), -1)
klotho.topos.graphs.trees.group.format_subdivisions(subdivs)[source]

Format a nested subdivision tuple as a human-readable string.

Produces a parenthesised, space-separated representation (no commas) suitable for display.

Parameters:

subdivs (tuple or list or scalar) – Arbitrarily nested structure of numeric values.

Returns:

String representation, e.g. "(3 (2 1) 4)".

Return type:

str

Examples

>>> format_subdivisions((3, (2, 1), 4))
'(3 (2 1) 4)'

Lattices

Lattice Implementation

class klotho.topos.graphs.lattices.lattices.Lattice(dimensionality=2, resolution=10, bipolar=True, periodic=False)[source]

Bases: Graph

A generic n-dimensional lattice structure.

A lattice provides a discrete sampling of n-dimensional space with integer coordinates. Nodes are accessed via coordinate tuples but stored internally as integer node IDs in the underlying RustworkX graph.

Parameters:
  • dimensionality (int) – Number of dimensions.

  • resolution (int or list of int) – Number of points along each dimension, or list of resolutions per dimension.

  • bipolar (bool, optional) – If True, coordinates range from -resolution to +resolution. If False, coordinates range from 0 to resolution (default is True).

  • periodic (bool, optional) – Whether to use periodic boundary conditions (default is False).

__init__(dimensionality=2, resolution=10, bipolar=True, periodic=False)[source]
__getitem__(coord)[source]

Get node data for a coordinate tuple.

__contains__(coord)[source]

Check if a coordinate exists in the lattice.

get_coordinates(node_id)[source]

Get coordinates for a given node ID.

get_node(coord)[source]

Get node ID for given coordinates.

property coords: List[Tuple[int, ...]]

Get coordinates in the lattice.

Returns:

List of lattice coordinates.

Return type:

list of tuple of int

property edges

Return a view of the edges with coordinate tuples.

property dimensionality: int

Number of dimensions in the lattice.

property resolution: List[int]

Resolution along each dimension.

property bipolar: bool

Whether the lattice uses bipolar coordinates.

number_of_nodes()[source]

Return total number of nodes in lattice.

number_of_edges()[source]

Return total number of edges in lattice.

neighbors(coord)[source]

Get neighbor coordinates of a coordinate.

add_edge(u, v, **attr)[source]

Add edge between two coordinates.

has_edge(u, v)[source]

Check if edge exists between two coordinates.

__str__()[source]

String representation of the lattice.

Return type:

str

class klotho.topos.graphs.lattices.lattices.LatticeEdgeView(lattice)[source]

Bases: object

View of lattice edges that returns coordinate tuples.

__init__(lattice)[source]
__iter__()[source]

Iterate over edges as coordinate tuple pairs.

__len__()[source]

Return number of edges.

__call__(data=False)[source]

Return edges with optional data.

Lattice Algorithms

klotho.topos.graphs.lattices.algorithms.random_walk(lattice, start_coord, num_steps, max_repeats=None, seed=None, avoid_backtrack=False, stuck_tolerance=3)[source]

Perform a random walk on a lattice starting from a given coordinate.

Parameters:
  • lattice (Lattice) – The lattice to perform the random walk on.

  • start_coord (Tuple[int, ...]) – Starting coordinate for the random walk.

  • num_steps (int) – Number of steps to take in the random walk.

  • max_repeats (Optional[int]) – Maximum number of times any coordinate can be visited. If None, no limit.

  • seed (Optional[int]) – Random seed for reproducible walks.

  • avoid_backtrack (bool) – If True, avoid immediately returning to the previous coordinate when possible.

  • stuck_tolerance (int) – When the walk gets stuck (all neighbors exceed max_repeats), temporarily allow one extra visit up to this many times before stopping. Resets after each non-stuck step. Default is 3.

Returns:

List of coordinates representing the random walk path.

Return type:

List[Tuple[int, …]]

Raises:
  • KeyError – If start_coord is not valid in the lattice.

  • ValueError – If num_steps is negative.

klotho.topos.graphs.lattices.algorithms.directed_walk(lattice, start_coord, direction_weights, num_steps, max_repeats=None, seed=None)[source]

Perform a biased random walk with directional preferences.

Parameters:
  • lattice (Lattice) – The lattice to perform the walk on.

  • start_coord (Tuple[int, ...]) – Starting coordinate for the walk.

  • direction_weights (List[float]) – Weights for each dimension direction. Length should be 2 * dimensionality, where indices [0, 1] are weights for dimension 0 [-1, +1], etc.

  • num_steps (int) – Number of steps to take.

  • max_repeats (Optional[int]) – Maximum visits per coordinate.

  • seed (Optional[int]) – Random seed for reproducibility.

Returns:

List of coordinates representing the walk path.

Return type:

List[Tuple[int, …]]

klotho.topos.graphs.lattices.algorithms.boundary_walk(lattice, start_coord, num_steps, boundary_preference=0.7, seed=None)[source]

Perform a random walk with preference for boundary coordinates.

Parameters:
  • lattice (Lattice) – The lattice to perform the walk on.

  • start_coord (Tuple[int, ...]) – Starting coordinate for the walk.

  • num_steps (int) – Number of steps to take.

  • boundary_preference (float) – Probability of choosing a boundary neighbor when available (0.0-1.0).

  • seed (Optional[int]) – Random seed for reproducibility.

Returns:

List of coordinates representing the walk path.

Return type:

List[Tuple[int, …]]

klotho.topos.graphs.lattices.algorithms.shortest_path(lattice, start_coord, end_coord)[source]

Find the shortest path between two coordinates in a lattice.

Uses breadth-first search on the underlying graph, so every edge has equal weight (one lattice step).

Parameters:
  • lattice (Lattice) – The lattice to search.

  • start_coord (Tuple[int, ...]) – Starting coordinate.

  • end_coord (Tuple[int, ...]) – Target coordinate.

Returns:

Ordered list of coordinates from start_coord to end_coord (inclusive).

Return type:

List[Tuple[int, …]]

Raises:
  • KeyError – If either coordinate is not in the lattice.

  • ValueError – If no path exists between the two coordinates.