Dedekind 0.0.0
A structuralist C++23 Module Library
Loading...
Searching...
No Matches
nanobind_jlt.cpp File Reference

Nanobind extension module for the Jlt arrow DSL (#961). More...

#include <nanobind/nanobind.h>
#include <nanobind/stl/optional.h>
#include <nanobind/stl/pair.h>
#include <nanobind/stl/string.h>
#include <nanobind/stl/string_view.h>
#include <nanobind/stl/vector.h>
#include <algorithm>
#include <concepts>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
#include <ranges>
#include <span>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>
import dedekind.category;
Include dependency graph for nanobind_jlt.cpp:

Classes

struct  jlt::Factor< N >
 A factor of a count, \(b^e\): a base raised to an exponent. More...
struct  jlt::FreeMonoid< C, F, N >
 The free monoid on a filtered alphabet, truncated below a length: \(\Sigma^{<L} = \coprod_{n < L} \Sigma^n\), the coproduct of the tensor powers, concatenation of words its operation. More...
struct  jlt::LetterMap
 An arrow on the bytes given by a table, each letter of from to the letter at the same place of to, every other byte fixed: letter_map("ACGT", "TGCA") is the complement of a base, an involution. More...
struct  jlt::Letters
 A subobject of the bytes given by its letters, \(\chi : \Sigma \to \Omega\) as a packed word of 256 bits: the predicate a filtered alphabet is built from, letters("ACGT"). More...
struct  jlt::Power< C, F, N >
 The tensor power \(\Sigma^n\): the words of length n over the letters of a chain that a predicate keeps, a box of n legs, each the filtered alphabet, never built. More...
struct  jlt::PowerMap< T >
 An arrow on the letters applied to every letter of a word, of any length: the list functor's action on arrows, \(\tau^{\times n}\) at each length \(n\) at once, beside power on the alphabet, Listing 4's power one level up. It commutes with every permutation of the positions, which is naturality read on words. More...
struct  jlt::ReflectedReverse
 ~rev: the reversal, then the reflection of the alphabet on every letter, the reverse complement. ~f is :posetal's: f then the reflection of its codomain's chain, which on the ranks of ACGT is \(x \mapsto 3 - x\), bitwise NOT on two bits. A word carries no alphabet, so ~rev is a family indexed by the alphabet, with a component at each, power(refl(Σ)) >> rev at Σ, taken where fixed_by(~rev) meets a power over Σ, as the exhibit's oligos & len(6) & fixed_by(~rev). Each component is an involution, two commuting involutions (commutes and is_involutive above). (#1141: an alphabet over another carrier has its component from its rank, as refl does.) More...
struct  jlt::Reflection
struct  jlt::Reverse
 An involution on a carrier that is not a number: reversing a word twice is the identity, on any word a value holds, a std::string or a std::vector of letters; not a view, whose copy would alias the caller's letters. A pure function object, value in and value out, so that it is an arrow in the sense of the Jlt paper's Rule 1, and a family of them, one per word type, as std::logical_not is one per truth type; endo<W>(rev) names the domain. More...
struct  jlt::Rotation< N >
 The rotation of the positions of a word by shift, \(i \mapsto i + d \bmod n\), the symmetry of a power \(u^j\): on a word, the letter at i moves to i + d, as std::rotl moves a bit. A family of arrows, one per word type, as Reverse is. More...
struct  jlt::Automaton< Sigma, Q >
 A matcher's plan: the transitions on each letter, and the states where a word of the set has just been read. More...

Enumerations

enum class  jlt::Holes
 What a byte outside the alphabet does to a match: break it, the matcher back at its start (no word of the set holds the byte), or be skipped, the matcher as it was. Never a match itself.

Functions

 NB_MODULE (_jlt, m)
template<IsCountWord W = std::size_t, IsByteText R, IsCountWord N>
constexpr W jlt::count (const ReflectedWindows< R, N > &q)
 The count of a section fixed by reversal and reflection, without asking each window: the law says a window is independent pairs, so no position depends on another. The overload is narrow, and in practice it is DNA's and RNA's: exactly four letters, their own reflection, a word of even length up to 16. It names a law of biochemistry and no instruction of any machine. The alphabet and the length are values, here as in a binding. Any other section takes the plain fold, whose answer this one must equal.
template<IsCountWord N>
constexpr AtMost< Factor< N >, 1 > jlt::count_factors (const Offsets< N > &o)
template<typename P, typename S>
requires requires(const P& p, const S& s) { occurrences(p, s); }
constexpr auto jlt::exact_count (const WindowJoin< P, S > &j)
template<IsCountWord N = std::size_t, HasNNOStep C, IsArrow F>
requires std::totally_ordered<C> && std::same_as<Dom<F>, C> && std::convertible_to<Cod<F>, bool>
constexpr FreeMonoid< C, F, N > jlt::free_monoid (const unfold_view< std::optional< C >, detail_chain::SliceStep< C, F > > &leg, std::type_identity_t< N > below)
template<IsCountWord N = std::size_t, HasNNOStep C, IsArrow F>
requires std::totally_ordered<C> && std::same_as<Dom<F>, C> && std::convertible_to<Cod<F>, bool>
constexpr Power< C, F, N > jlt::power (const unfold_view< std::optional< C >, detail_chain::SliceStep< C, F > > &leg, std::type_identity_t< N > n)
template<HasNNOStep C, IsArrow F, IsCountWord N, typename S>
requires HasCycleType<S, N>
constexpr Symmetric< Power< C, F, N >, S, Identity< C > > jlt::symmetric (const Power< C, F, N > &p, S sigma)
template<typename F>
requires std::invocable<const F&, std::integral_constant<std::size_t, 8>>
constexpr auto jlt::with_width (std::size_t n, const F &f)
 A width known only at run time, dispatched to the narrowest precompiled bit word that holds it: 8, 16, 32 or 64 bits, a machine word, or 128, 256 or 512, a std::bitset. f is called with the width as a type, so it can name BitWord of it. Refused past max_packed_width.

Detailed Description

Nanobind extension module for the Jlt arrow DSL (#961).

Description

A fluent DSL over the real category arrows, bound as the private native extension pynzli._jlt (NumPy-style, re-exported by the pure-Python pynzli.jlt facade). It exposes the actual :morphism arrows over TWO objects, bool and int — the identity Identity<T> and the type-erased Morphism<T,T> — as duck-typed handles: an "arrow" is the protocol __call__ / __rshift__ + the free functions dom / cod, not a base class. The generators are id and refl (the reflection involution: ¬ on bool, negation on int).

Composability is structural: __rshift__ is bound only for same-object operands, so id(bool) >> refl(int) finds no overload and raises — the runtime image of the C++ operator>>'s static same_as<Cod,Dom>. Composition type-erases to a Morphism (Python arrows are extensional); no captured Python callable, so no refleak.

Function Documentation

◆ count()

template<IsCountWord W = std::size_t, IsByteText R, IsCountWord N>
W dedekind::category::count ( const ReflectedWindows< R, N > & q)
constexpr

The count of a section fixed by reversal and reflection, without asking each window: the law says a window is independent pairs, so no position depends on another. The overload is narrow, and in practice it is DNA's and RNA's: exactly four letters, their own reflection, a word of even length up to 16. It names a law of biochemistry and no instruction of any machine. The alphabet and the length are values, here as in a binding. Any other section takes the plain fold, whose answer this one must equal.

Parameters
qthe query.
Returns
how many of its windows hold.

◆ count_factors()

template<IsCountWord N>
AtMost< Factor< N >, 1 > dedekind::category::count_factors ( const Offsets< N > & o)
constexpr
Parameters
othe offsets.
Returns
their count, one factor.

◆ exact_count()

template<typename P, typename S>
requires requires(const P& p, const S& s) { occurrences(p, s); }
auto dedekind::category::exact_count ( const WindowJoin< P, S > & j)
constexpr
Parameters
ja join on the window.
Returns
its count exactly, or none where the word cannot hold it: exact_occurrences.

◆ free_monoid()

template<IsCountWord N = std::size_t, HasNNOStep C, IsArrow F>
requires std::totally_ordered<C> && std::same_as<Dom<F>, C> && std::convertible_to<Cod<F>, bool>
FreeMonoid< C, F, N > dedekind::category::free_monoid ( const unfold_view< std::optional< C >, detail_chain::SliceStep< C, F > > & leg,
std::type_identity_t< N > below )
constexpr
Parameters
lega chain of letters under a predicate.
belowthe bound on the length, excluded.
Returns
the words shorter than it.

◆ power()

template<IsCountWord N = std::size_t, HasNNOStep C, IsArrow F>
requires std::totally_ordered<C> && std::same_as<Dom<F>, C> && std::convertible_to<Cod<F>, bool>
Power< C, F, N > dedekind::category::power ( const unfold_view< std::optional< C >, detail_chain::SliceStep< C, F > > & leg,
std::type_identity_t< N > n )
constexpr
Parameters
lega chain of letters under a predicate, the filtered alphabet.
nthe length.
Returns
the words of length n over it.

◆ symmetric()

template<HasNNOStep C, IsArrow F, IsCountWord N, typename S>
requires HasCycleType<S, N>
Symmetric< Power< C, F, N >, S, Identity< C > > dedekind::category::symmetric ( const Power< C, F, N > & p,
S sigma )
constexpr
Parameters
pa tensor power.
sigmaa permutation of its positions, rev or rotate(d).
Returns
the words it fixes.

◆ with_width()

template<typename F>
requires std::invocable<const F&, std::integral_constant<std::size_t, 8>>
auto dedekind::category::with_width ( std::size_t n,
const F & f )
constexpr

A width known only at run time, dispatched to the narrowest precompiled bit word that holds it: 8, 16, 32 or 64 bits, a machine word, or 128, 256 or 512, a std::bitset. f is called with the width as a type, so it can name BitWord of it. Refused past max_packed_width.

Parameters
nthe width.
fwhat to do in that word.
Returns
its result.