Skip to main content

prerelation

DOI PyPI

A coefficient for prerequisite relations between traits reported on a common anchored scale.

Two abilities can be strongly correlated without either being a prerequisite for the other, and they can be perfectly ordered without being distinct. prerelation asks a narrower question than correlation and a different one from necessity analysis:

does the candidate prerequisite X act as a ceiling on Y, and does Y keep the freedom below that ceiling which a prerequisite structure implies?

Pi(X -> Y) = A1 * A2        in [0, 1]

A1   the corner {Y > X} is empty, relative to what independence would give
A2   below the ceiling Y varies as a free component should (q), and the
     censoring thins out at high x (ell)

Delta = Pi(X -> Y) - Pi(Y -> X)

The product structure is what lets a single number separate the four extremes. Independence is annihilated by A1 alone; exact equivalence is annihilated by A2 alone. A coefficient that scores only the emptiness of the corner gives equivalence its maximal value, because equivalence has an empty corner — necessity and prerequisiteness are different concepts.

Install

pip install prerelation                # core + screening + ceiling + study
pip install "prerelation[ctm]"         # adds the bounded-trait scoring extra

Quick start

import numpy as np
from prerelation import prereq_index, direction, scan_pairs

rng = np.random.default_rng(0)
x = rng.uniform(0, 1, 500)
y = x * rng.uniform(0, 1, 500)          # X is a ceiling on Y

prereq_index(x, y)["PI"]                 # -> about 0.94
direction(x, y)                          # (Delta, forward, reverse); reverse is 0.0

theta = np.column_stack([x, y, y * rng.uniform(0, 1, 500)])
res = scan_pairs(theta, names=["A", "B", "C"], n_perm=199)
res.edges                                # [('A','B'), ('A','C'), ('B','C')]
res.reduced_edges                        # [('A','B'), ('B','C')] — the implied edge is gone
res.table                                # tidy DataFrame of every ordered pair

The scan recovers a dominance preorder over the attributes — which attributes act as ceilings on which others — not a direct-prerequisite DAG. Indirect dominance produces edges of its own, and siblings under a common ceiling can be linked even though neither is a prerequisite for the other; the transitive reduction cleans up chains but cannot distinguish a direct edge from a dominated one in general. When the recovered order disagrees with an expert-specified prerequisite graph, the two are answering different questions. The permutation screen also has a design floor: with K ordered pairs, no edge can survive BH control at level alpha unless n_perm >= K / alpha - 1.

Estimating the ceiling itself:

from prerelation import ceiling_fit, prereq_index_referenced

fit = ceiling_fit(x, y, tau=0.95)        # monotone quantile envelope, split-half
pi_ref = prereq_index_referenced(x, y, fit)

ceiling_fit(..., postulate_correction=True) divides the raw envelope by tau. Its validity domain, from the docstring: the correction is grounded only under the calibrated product model Y = c(X) U with U ~ Uniform(0, 1) independent of X (the uniform freedom postulate) — under that model the tau-quantile envelope estimates tau * c, so dividing by tau is a consistent correction. It is not applicable to the weakest-link form Y = min(c(X), T), where division by tau strictly over-estimates the ceiling wherever the censoring binds, nor to non-uniform free components, where 1/tau carries no information about the quantile being estimated. In both cases leave the default False.

Correcting for scoring error with plausible values:

from prerelation import pv_correct   # requires: pip install "prerelation[ctm]"

pv_correct consumes grid posteriors from the bounded-trait scorer, which is deliberately an optional extra — prerelation.core imports numpy and nothing else, and a test enforces that.

Scope, stated plainly

Pi is defined for traits on a common bounded scale whose endpoints are substantive anchors — 0 means absence of the ability, 1 means full mastery. This is an interpretability requirement on the scale, not a claim about the measurement precision of any scoring model. The ratio Y / X and the corner moment (Y - X)+ carry the reading "how much of the ceiling granted by X is used by Y", and that reading does not survive an arbitrary monotone rescaling: on a location-scale standardised latent trait, Pi computed from the numbers is not a prerequisite statistic at all. Accordingly Pi is deliberately not invariant to rescaling either axis, and it is not symmetric.

Any scale meeting the requirement will do. The bounded trait model of Choi (2022) is one such scale and prerelation.pv can consume its posteriors, but the coefficient itself is model-free: prerelation.core imports numpy and nothing else, and a test enforces that. This package is part of the research program around that bounded-trait framework (CTM/ALF), where the anchored [0, 1] scale supplies the interpretive ground the coefficient needs; the scale requirement here is about interpretability, not about the measurement quality of any model.

What is in the package

module contents
core prereq_index, direction, perm_pvalue
scan all ordered pairs, BH-FDR, cycle check, transitive reduction — read as a dominance preorder
ceiling monotone quantile ceiling, CTM-logistic ceiling, referenced index
pv plausible-value correction for scoring error (optional extra)
study the simulation frame: one config dict in, one tidy table out

The ceiling-referenced variant

When the ceiling is far from the identity the default coefficient is attenuated. ceiling_fit estimates c on one half of the sample and prereq_index_referenced evaluates the coefficient on the other half, on the transformed pair (c(x), y). Every component is recomputed there — replacing only one component while leaving the others on the identity reference is a different statistic, not a variant, so the API gives no way to do it.

Plausible values

Pi is computed from trait estimates, and estimates carry error. Because Pi is a nonlinear functional of the pair, plugging in point estimates understates the uncertainty. pv_correct consumes grid posteriors, draws plausible values, recomputes Pi per draw, and reports the spread.

Correctness standard

tests/oracle/prereq_index_v2.py is a verbatim copy of the reference implementation that produced the recorded results and is kept permanently. Every optimised path in the package is pinned by tests asserting agreement with it to within 1e-12, including the guards, the clipping, and the fact that the independence baseline is a V-statistic whose double sum includes the diagonal. Above DENSE_MAX_N the baseline is accumulated by sorting instead of forming the n x n matrix; the two differ only in summation order, which is what makes large scans and permutation loops possible at all.

Reproducibility and golden vectors

tests/golden/ contains fixed fixtures spanning the product, weakest-link, independence, equivalence and partial-equivalence regimes plus a real-data slice, with component-wise outputs (v, v0, A1, per-band interior mass, q, ell, A2, Pi, Delta) written to machine-readable files. The permutation index matrix itself is committed, generated once from a recorded seed, so an implementation in any language can apply identical permutations and match the p-values exactly rather than in distribution — the contract is documented in tests/golden/README.md. A pytest module regenerates every golden output from the fixtures and asserts equality at 1e-12, which pins this package as the reference implementation.

Citation

The methodological paper introducing the coefficient is in preparation. To cite the software, use the metadata in CITATION.cff (concept DOI 10.5281/zenodo.22132819, all versions; v0.2.0 archive: 10.5281/zenodo.22132820).

Status

0.2.0 — first public release. The API is settled enough to build on; the numbers in the test suite are verification fixtures rather than results.

License

MIT.

Release files for prerelation 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for prerelation 0.3.1
File Size Uploaded
prerelation-0.3.1.tar.gz 249.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for prerelation 0.3.1
File Interpreter ABI Platform
prerelation-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 278.1 kB

Release files / prerelation-0.3.1.tar.gz

Download URL prerelation-0.3.1.tar.gz
Size 249.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5acf0f48291f11ee1fd873f63a84457fdbcb54297171ae3b511d06fd53bdb17b
BLAKE2b-256 checksum
How to use checksums
6f8d1c9511e43147be4593033285c5dfc0e025336503f7cb7ad615ebf15545dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release files / prerelation-0.3.1-py3-none-any.whl

Download URL prerelation-0.3.1-py3-none-any.whl
Size 28.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8e0e40c13ebba3d241adb4f29c165b5d73a60aef49eb62f39fd3f4ab72ce03f3
BLAKE2b-256 checksum
How to use checksums
12bad16eadd06fbf8c67e3b1e7975fe200e889694d25a45c567466446636acef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.0

2 release files

0.3.2

2 release files

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page