Repository navigation
Correctness review and refactor (0.3.0) - #22
Merged
Merged
Conversation
…act Fischer/Krieger covers - Report topological entropy, collision entropy, and HMM log-likelihoods in bits; model-selection criteria convert to natural logs to keep their standard scale. - Count ATTR_MULTIPLICITY in TMC adjacency matrices (entropy and Parry measure). - Raise instead of silently truncating SFT presentations at max_states. - Markov words of length 0 and sample_path respect the initial distribution. - Raise a clear error when sampling from an initial law with no mass. - Exact crypticity C_mu - E in block_entropy_estimates(use_exact=True). - Narrow broad except-Exception fallbacks that silently changed results. - equivalent() compares over the union of both automata's alphabets. - Exact right/left Fischer covers (Lind-Marcus convention: right = right-resolving) and new exact right/left Krieger covers. Co-authored-by: Cursor <cursoragent@cursor.com>
…bility data, Buchi empty loops - SlidingBlockCode.apply tracks the source presentation so constraints longer than the window survive, and rejects block maps that miss an allowed block. - Baum-Welch raises when every sequence is impossible and warns when some are. - Buchi lasso acceptance rejects an empty loop (not an omega-word). - suggest_lmax encodes symbols injectively instead of via repr. - Tests: Viterbi on impossible data, YAML round trips for every cover class and SymbolicModel. ALERGIA's Hoeffding test, SlidingBlockCode.compose, and TextileSystem.induced_code were checked and are correct as written. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…toms, and NL* - ResidualTable decides residual inclusion and union coverage exactly on the minimal DFA; canonical_rfsa_from_language builds the Denis-Lemay-Terlutte canonical RFSA (was a relabeled minimal DFA). - Maximized prime atomaton = reverse of the canonical RFSA of the reversed language (Maarand & Tamm 2022). It need not be atomic (Tamm 2015), so it now subclasses NFA rather than AtomicAutomaton; CanonicalRFSA.dual() and MaximizedPrimeAtomaton.dual() reverse between them. - ResidualFiniteStateAutomaton.validate checks every state accepts a residual. - prime_residuals, atoms, prime_atoms are exact (were bounded-length checks that tested equality instead of union, and returned quotients as atoms). - Faithful NL* (Bollig et al. 2009) learning the canonical RFSA, a reversed learner for the prime atomaton, NL*-style table extraction, and an exact AutomatonEquivalenceOracle returning shortest counterexamples. Co-authored-by: Cursor <cursoragent@cursor.com>
…and a correct canonical VPA - Normalized VPA form (explicit bottom, guarded returns); documented wildcard returns as firing on every stack symbol and on the empty stack with a bottom. - Alur-Madhusudan determinization; DeterministicVisiblyPushdownAutomaton.from_vpa determinizes nondeterministic input instead of raising. - Concrete union, intersection, complement, difference, concatenation, and Kleene star (boundary-bit construction for per-factor empty stacks); the lazy CompositeVisiblyPushdownAutomaton and the *_vpa free functions are removed. - Emptiness via well-matched summary saturation, accepted_word witnesses, is_universal, includes, equivalent, and has_unmatched_word. - to_single_entry / to_multiple_entry convert well-matched VPAs into modular form; modular minimize converts automatically when no modules are given. - CanonicalVisiblyPushdownAutomaton raises NonWellMatchedLanguageError on languages with pending calls/returns, and no longer accepts pending calls or depends on class representatives (joint top-level/nested congruence). - NestedWordAutomaton operations delegate through the tagged VPA encoding. - Property tests check every operation against brute-force reference semantics. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…amples; fix stack CSSR history loss - generators/matrices.py is the one home for symbol-labeled joint matrices, stationary/limit laws, and start vectors (model vs stationary policy); shared word enumeration and entropy helpers; StochasticModel.reverse flattened. - CSSR family: shared suffix scan (_suffix_counts.py) and significance tests (_morph_tests.py) for process CSSR, transCSSR, and stack CSSR; dead helpers (_cssr_homogenize and others) removed. The two G-tests were already identical (scipy applies the same Yates correction); now documented. - Automata: one run_nfa, one bounded equivalence-oracle base, shared word iteration, removed intersect/concatenate/star aliases, VPA membership simulates the normalized form used by the constructions. - Viz: TikZ labels reuse the shared edge spec and probability formatter; fixes uncompilable \midcall / \uparrowA, escaped \times, and escaped sympy LaTeX. - Examples: nine duplicate process pairs now share one implementation; one stationary helper; same-name/different-process pairs cross-referenced. - Stack CSSR: determinization replaced a split state with its largest bucket, dropping histories that never emitted the splitting symbol (stale mappings and zero-mass states that crashed validation); they now stay, and states with no edge into the kept set are pruned. Co-authored-by: Cursor <cursoragent@cursor.com>
…learning, vpa, enumeration, canonical packages - sofic.inference.hmm (filtering, em, information) replaces generators/hmm_inference.py; sampling moves to generators/sampling.py. - sofic.inference.cssr (counts, significance, process, subtree, transducer, stack) replaces generators/epsilon_inference.py, epsilon_transducer_inference.py, stack_inference.py and their private helpers; the spectral wrapper joins inference/spectral.py. - sofic.automata.learning (active, rpni, edsm, dfasat, alergia, papni, nlstar, observation), sofic.automata.vpa (base, operations, deterministic, modular, canonical, simulation), sofic.automata.enumeration (icdfa, idfa, words), and sofic.automata.canonical (residual, rfsa, atomaton, dual). - Old modules deleted without shims; docs pages and toctrees moved with them. - Doctests and prose updated for topological entropy in bits. Co-authored-by: Cursor <cursoragent@cursor.com>
- Learners follow learn_<target>_<method> (learn_epsilon_machine_cssr, ...); Lmax/L -> max_history; suggest_max_history; forward/backward normalize=; joint_block_distribution(block_length=); quasi symbol_matrices; word helpers private behind model methods. sofic.inference.cssr/spectral are modules again. - Automata: generator_product, transducer_product, compose_transducers, compose_transducer_generator, determinize_wheeler, minimize_wheeler, encode_dyck_word(s), icdfa_/idfa_ prefixed helpers, ModularVisiblyPushdownAutomaton. - Shifts: ProductAlphabetShift, covers from_presentation, *_cover functions; top-level from_yaml alias removed. - Examples are snake_case only; cmpy duplicates of curated examples removed and look-alike processes given distinct names. - CHANGELOG.md lists behavior changes, new features, module moves, and the full old -> new migration table. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Full correctness review and breaking refactor of sofic, as a single PR (the same 9 commits as the stacked PRs #17–#21). Old names are not kept as aliases;
CHANGELOG.mdhas the full old → new migration table.Correctness fixes
max_states.SlidingBlockCode.applykeeps constraints longer than the window.prime_residualswas wrong (4 instead of 3 for Σ*aΣ), andatomsreturned quotients; both are now exact.equivalent()alphabet, Baum-Welch on impossible data, Büchi empty loops, TikZ LaTeX output, and narrowed broadexcept Exceptionfallbacks.New constructions
NFA.Restructure and renames
sofic.inference.hmmandsofic.inference.cssrreplacegenerators/*_inference.py.sofic.automatais split into thelearning,vpa,enumeration, andcanonicalsubpackages.learn_<target>_<method>, the history parameter ismax_history, automata operations use full words, and example factories are snake_case only.Testing
ruffis clean, and a full Sphinx build passes with-W.After merging, tag
v0.3.0.