CLUTRR · kinship reasoning · bicyclic-kinship

Kinship Reasoning Without a Neural Network

Who is your daughter's grandfather?

Your father, or your spouse's father. The words alone can't say which. This model says so: it answers father or father-in-law, and then tells you which one the evidence favours.

A plain-language explainer of an algebraic model on the CLUTRR benchmark.

married parent parent parent parent Your father Your spouse's father You Your spouse Your daughter father father-in-law
Two routes, one question. Your daughter's grandfather is two steps up from her. Through you, that's your father. Through your spouse, it's your spouse's father. The chain (daughter, grandfather) doesn't say which route, so the model answers father or father-in-law.

The short version

CLUTRR (Sinha et al., 2019) is a benchmark that asks questions like "Alice's father's father's daughter is Alice's what?" (Her aunt.) It's easy to train a system on short chains of relations like that. It's hard to get that system to answer longer chains than it was trained on. Statistical machine learning is known to struggle with that step.

This repository answers those questions with no neural network, no trained weights and no random seeds. It is given the relation words as opaque symbols, strings whose meaning it never sees, plus a few thousand short examples. From those it derives the rules by which the symbols combine. Then it applies those rules to chains of any length.

On CLUTRR's standard "train short, test long" splits it scores at the level of the best published rule-learning systems, and it is sound on every test story. Sound means the correct answer is always inside the set of answers it gives.

Why this matters

I wanted a reasoning system that can explain itself in the strong sense. Most explanations from AI systems today are a story told about an answer after the fact: a heat map over the input, or a paragraph of reasoning generated alongside the output. If the story is wrong, nothing breaks, because there is nothing underneath it to check it against. The other kind of explanation is a derivation, like long division or a proof. The steps are the computation itself, and you can check each one.

Relational reasoning, chaining facts together to get a new one, is where story-style explanations are normal today. Kinship is the smallest version of it that can't be faked. Nobody memorizes the answer to a ten-step chain. You either combine the steps correctly or you don't, and anyone can check.

The point. On problems that have a composition law, you can derive the law instead of learning it. The derived model reaches the accuracy of the best trained systems, and it gives you things they can't:

The default in this field is to learn. Every published CLUTRR system I have found either learns its rules by training or is given them by hand, as a logic program (Yang, Ishay & Lee, 2023). None derives them. Meanwhile the mathematics that solves it, the algebra of relations and the program-analysis theory behind sound answers, has been mature for decades, and it runs inside production tools every day. The two literatures rarely talk to each other. This project connects them.

What I don't know yet is how much of reasoning has a law like this. Kinship has one. Filesystem paths and grid movement have one. Clock arithmetic has one too, but it's a shape this model doesn't have yet, and the model says so rather than forcing a fit. The method is cheap enough to point at a new domain and ask. If most things have a law, that's a large result. If only a few tidy corners do, it's a small one. Finding out is the work.

Questions and answers

Each question reaches the model as a chain of relation words. It answers with every word its rules allow. When that's more than one word, it also says which one the training data favours. These are real outputs of the model trained on CLUTRR.

What this is, and what it isn't

Four limits come first, because each one matters.

Not statistical machine learning

Most systems evaluated on CLUTRR are neural networks: graph networks, recurrent networks, transformers. The strongest ones are hybrids, networks trained to find logical rules, such as CTP (Minervini et al., 2020), R5 (Lu et al., 2022) and NCRL (Cheng et al., 2023). All of them tune millions of numbers by gradient descent or reinforcement learning, and report the average over several runs with different random seeds.

This model does none of that. All it learns is a small table of whole numbers, derived with exact fractional arithmetic. Nothing is sampled, nothing is approximated, and running it twice gives the same answer to every decimal place. Training takes a fraction of a second.

Why statistical ML finds CLUTRR hard. A network trained on chains of two or three steps learns what two-to-three-step chains look like. Ask it about a ten-step chain and it is outside anything it has seen. The CLUTRR authors built the benchmark to expose exactly this (Sinha et al., 2019), and the published numbers show it.

Trained on 2–3 step chains. Published numbers from R5 (Lu et al., 2022), Table 2.

SystemKind4 steps10 steps
GCNgraph neural network84%39%
GATgraph neural network91%45%
Multi-head attentiontransformer-style81%67%
LSTMrecurrent network98%75%
40%60%80%100%45678910chain length (trained on 2 and 3 only)GCN, 4 steps: 84%GCN, 5 steps: 68%GCN, 6 steps: 53%GCN, 7 steps: 47%GCN, 8 steps: 42%GCN, 9 steps: 45%GCN, 10 steps: 39%GCNGAT, 4 steps: 91%GAT, 5 steps: 76%GAT, 6 steps: 54%GAT, 7 steps: 56%GAT, 8 steps: 54%GAT, 9 steps: 55%GAT, 10 steps: 45%GATAttention, 4 steps: 81%Attention, 5 steps: 76%Attention, 6 steps: 74%Attention, 7 steps: 70%Attention, 8 steps: 69%Attention, 9 steps: 64%Attention, 10 steps: 67%AttentionLSTM, 4 steps: 98%LSTM, 5 steps: 95%LSTM, 6 steps: 88%LSTM, 7 steps: 87%LSTM, 8 steps: 81%LSTM, 9 steps: 75%LSTM, 10 steps: 75%LSTMCTP-A, 4 steps: 99%CTP-A, 5 steps: 99%CTP-A, 6 steps: 99%CTP-A, 7 steps: 96%CTP-A, 8 steps: 94%CTP-A, 9 steps: 89%CTP-A, 10 steps: 90%CTP-AR5, 4 steps: 98%R5, 5 steps: 99%R5, 6 steps: 98%R5, 7 steps: 96%R5, 8 steps: 97%R5, 9 steps: 98%R5, 10 steps: 97%R5This model, 4 steps: 99.5%This model, 5 steps: 99.4%This model, 6 steps: 100%This model, 7 steps: 100%This model, 8 steps: 100%This model, 9 steps: 100%This model, 10 steps: 100%This model
Longer chains than it was trained on. Every point is a chain longer than anything in training. The trained networks decay as chains grow, because length is something they had to learn. The model's line stays flat, because length never enters its calculation. Published numbers from R5 (Lu et al., 2022), Table 2. Hover a point for its value.

Why this model doesn't have that problem. It never learns what chains look like. It learns how two relations combine, and a ten-step chain is just nine of those combinations, one after another. Length never enters the calculation, so there's nothing to degrade.

What "opaque symbols" means

The model's input is a list of facts of the form "symbol A followed by symbol B gives symbol C." On CLUTRR there are 62 such facts, taken from the two-step training chains. For all the model knows, the symbols could be x17, x4 and x9.

That claim can be checked in the code:

A model that chooses its own rules

This is a model, even though there's no neural network in it. What makes it one is what it does with data.

A rule engine starts with rules a person wrote and applies them to the input. This model starts with no rules about the domain at all. It has a small menu of rule shapes (a counter, a stack, and two kinds of classification, all explained below), and it looks at the data to decide which of them apply:

grandfathergrandfathergrandmothergrandmotherfatherfathermothermotherfather-in-lawfather-in-lawmother-in-lawmother-in-lawuncleuncleauntaunthusbandhusbandwifewifebrotherbrothersistersistersonsondaughterdaughterson-in-lawson-in-lawdaughter-in-lawdaughter-in-lawnephewnephewnieceniecegrandsongrandsongranddaughtergranddaughtergrandfather, then grandfather: no word (no word)grandfather, then grandmother: no word (no word)grandfather, then father: no word (no word)grandfather, then mother: no word (no word)grandfather, then father-in-law: no word (no word)grandfather, then mother-in-law: no word (no word)grandfather, then uncle: no word (no word)grandfather, then aunt: no word (no word)grandfather, then husband: no word (no word)grandfather, then wife: no word (no word)grandfather, then brother: no word (no word)grandfather, then sister: no word (no word)grandfather, then son: uncle (computed)grandfather, then daughter: aunt (computed)grandfather, then son-in-law: no word (no word)grandfather, then daughter-in-law: no word (no word)grandfather, then nephew: no word (no word)grandfather, then niece: no word (no word)grandfather, then grandson: no word (no word)grandfather, then granddaughter: no word (no word)grandmother, then grandfather: no word (no word)grandmother, then grandmother: no word (no word)grandmother, then father: no word (no word)grandmother, then mother: no word (no word)grandmother, then father-in-law: no word (no word)grandmother, then mother-in-law: no word (no word)grandmother, then uncle: no word (no word)grandmother, then aunt: no word (no word)grandmother, then husband: no word (no word)grandmother, then wife: no word (no word)grandmother, then brother: no word (no word)grandmother, then sister: no word (no word)grandmother, then son: uncle (computed)grandmother, then daughter: aunt (computed)grandmother, then son-in-law: no word (no word)grandmother, then daughter-in-law: no word (no word)grandmother, then nephew: no word (no word)grandmother, then niece: no word (no word)grandmother, then grandson: no word (no word)grandmother, then granddaughter: no word (no word)father, then grandfather: no word (no word)father, then grandmother: no word (no word)father, then father: grandfather (seen in training)father, then mother: grandmother (seen in training)father, then father-in-law: grandfather (computed)father, then mother-in-law: grandmother (computed)father, then uncle: no word (no word)father, then aunt: no word (no word)father, then husband: no word (no word)father, then wife: no word (no word)father, then brother: uncle (seen in training)father, then sister: aunt (seen in training)father, then son: brother (seen in training)father, then daughter: sister (seen in training)father, then son-in-law: no word (no word)father, then daughter-in-law: no word (no word)father, then nephew: no word (no word)father, then niece: no word (no word)father, then grandson: nephew (computed)father, then granddaughter: niece (computed)mother, then grandfather: no word (no word)mother, then grandmother: no word (no word)mother, then father: grandfather (seen in training)mother, then mother: grandmother (seen in training)mother, then father-in-law: grandfather (computed)mother, then mother-in-law: grandmother (computed)mother, then uncle: no word (no word)mother, then aunt: no word (no word)mother, then husband: no word (no word)mother, then wife: no word (no word)mother, then brother: uncle (seen in training)mother, then sister: aunt (seen in training)mother, then son: brother (seen in training)mother, then daughter: sister (seen in training)mother, then son-in-law: no word (no word)mother, then daughter-in-law: no word (no word)mother, then nephew: no word (no word)mother, then niece: no word (no word)mother, then grandson: nephew (computed)mother, then granddaughter: niece (computed)father-in-law, then grandfather: no word (no word)father-in-law, then grandmother: no word (no word)father-in-law, then father: grandfather (computed)father-in-law, then mother: grandmother (computed)father-in-law, then father-in-law: grandfather (computed)father-in-law, then mother-in-law: grandmother (computed)father-in-law, then uncle: no word (no word)father-in-law, then aunt: no word (no word)father-in-law, then husband: no word (no word)father-in-law, then wife: no word (no word)father-in-law, then brother: uncle (computed)father-in-law, then sister: aunt (computed)father-in-law, then son: brother (computed)father-in-law, then daughter: sister (computed)father-in-law, then son-in-law: no word (no word)father-in-law, then daughter-in-law: no word (no word)father-in-law, then nephew: no word (no word)father-in-law, then niece: no word (no word)father-in-law, then grandson: nephew (computed)father-in-law, then granddaughter: niece (computed)mother-in-law, then grandfather: no word (no word)mother-in-law, then grandmother: no word (no word)mother-in-law, then father: grandfather (computed)mother-in-law, then mother: grandmother (computed)mother-in-law, then father-in-law: grandfather (computed)mother-in-law, then mother-in-law: grandmother (computed)mother-in-law, then uncle: no word (no word)mother-in-law, then aunt: no word (no word)mother-in-law, then husband: no word (no word)mother-in-law, then wife: no word (no word)mother-in-law, then brother: uncle (computed)mother-in-law, then sister: aunt (computed)mother-in-law, then son: brother (computed)mother-in-law, then daughter: sister (computed)mother-in-law, then son-in-law: no word (no word)mother-in-law, then daughter-in-law: no word (no word)mother-in-law, then nephew: no word (no word)mother-in-law, then niece: no word (no word)mother-in-law, then grandson: nephew (computed)mother-in-law, then granddaughter: niece (computed)uncle, then grandfather: no word (no word)uncle, then grandmother: no word (no word)uncle, then father: grandfather (computed)uncle, then mother: grandmother (computed)uncle, then father-in-law: grandfather (computed)uncle, then mother-in-law: grandmother (computed)uncle, then uncle: no word (no word)uncle, then aunt: no word (no word)uncle, then husband: no word (no word)uncle, then wife: no word (no word)uncle, then brother: uncle (computed)uncle, then sister: aunt (computed)uncle, then son: no word (no word)uncle, then daughter: no word (no word)uncle, then son-in-law: no word (no word)uncle, then daughter-in-law: no word (no word)uncle, then nephew: no word (no word)uncle, then niece: no word (no word)uncle, then grandson: no word (no word)uncle, then granddaughter: no word (no word)aunt, then grandfather: no word (no word)aunt, then grandmother: no word (no word)aunt, then father: grandfather (computed)aunt, then mother: grandmother (computed)aunt, then father-in-law: grandfather (computed)aunt, then mother-in-law: grandmother (computed)aunt, then uncle: no word (no word)aunt, then aunt: no word (no word)aunt, then husband: no word (no word)aunt, then wife: no word (no word)aunt, then brother: uncle (computed)aunt, then sister: aunt (computed)aunt, then son: no word (no word)aunt, then daughter: no word (no word)aunt, then son-in-law: no word (no word)aunt, then daughter-in-law: no word (no word)aunt, then nephew: no word (no word)aunt, then niece: no word (no word)aunt, then grandson: no word (no word)aunt, then granddaughter: no word (no word)husband, then grandfather: grandfather (computed)husband, then grandmother: grandmother (computed)husband, then father: father, father-in-law (seen in training)husband, then mother: mother, mother-in-law (seen in training)husband, then father-in-law: father, father-in-law (computed, two possible)husband, then mother-in-law: mother, mother-in-law (computed, two possible)husband, then uncle: uncle (computed)husband, then aunt: aunt (computed)husband, then husband: husband (computed)husband, then wife: no word (no word)husband, then brother: brother (computed)husband, then sister: sister (computed)husband, then son: son (seen in training)husband, then daughter: daughter (seen in training)husband, then son-in-law: son-in-law (computed)husband, then daughter-in-law: daughter-in-law (computed)husband, then nephew: nephew (computed)husband, then niece: niece (computed)husband, then grandson: grandson (seen in training)husband, then granddaughter: granddaughter (seen in training)wife, then grandfather: grandfather (computed)wife, then grandmother: grandmother (computed)wife, then father: father, father-in-law (seen in training)wife, then mother: mother, mother-in-law (seen in training)wife, then father-in-law: father, father-in-law (computed, two possible)wife, then mother-in-law: mother, mother-in-law (computed, two possible)wife, then uncle: uncle (computed)wife, then aunt: aunt (computed)wife, then husband: no word (no word)wife, then wife: wife (computed)wife, then brother: brother (computed)wife, then sister: sister (computed)wife, then son: son (seen in training)wife, then daughter: daughter (seen in training)wife, then son-in-law: son-in-law (computed)wife, then daughter-in-law: daughter-in-law (computed)wife, then nephew: nephew (computed)wife, then niece: niece (computed)wife, then grandson: grandson (seen in training)wife, then granddaughter: granddaughter (seen in training)brother, then grandfather: grandfather (seen in training)brother, then grandmother: grandmother (seen in training)brother, then father: father, father-in-law (seen in training)brother, then mother: mother, mother-in-law (seen in training)brother, then father-in-law: father, father-in-law (computed, two possible)brother, then mother-in-law: mother, mother-in-law (computed, two possible)brother, then uncle: uncle (computed)brother, then aunt: aunt (computed)brother, then husband: no word (no word)brother, then wife: no word (no word)brother, then brother: brother (seen in training)brother, then sister: sister (seen in training)brother, then son: nephew (seen in training)brother, then daughter: niece (seen in training)brother, then son-in-law: no word (no word)brother, then daughter-in-law: no word (no word)brother, then nephew: nephew (computed)brother, then niece: niece (computed)brother, then grandson: no word (no word)brother, then granddaughter: no word (no word)sister, then grandfather: grandfather (seen in training)sister, then grandmother: grandmother (seen in training)sister, then father: father, father-in-law (seen in training)sister, then mother: mother, mother-in-law (seen in training)sister, then father-in-law: father, father-in-law (computed, two possible)sister, then mother-in-law: mother, mother-in-law (computed, two possible)sister, then uncle: uncle (computed)sister, then aunt: aunt (computed)sister, then husband: no word (no word)sister, then wife: no word (no word)sister, then brother: brother (seen in training)sister, then sister: sister (seen in training)sister, then son: nephew (seen in training)sister, then daughter: niece (seen in training)sister, then son-in-law: no word (no word)sister, then daughter-in-law: no word (no word)sister, then nephew: nephew (computed)sister, then niece: niece (computed)sister, then grandson: no word (no word)sister, then granddaughter: no word (no word)son, then grandfather: father, father-in-law (seen in training)son, then grandmother: mother, mother-in-law (seen in training)son, then father: no word (no word)son, then mother: no word (no word)son, then father-in-law: no word (no word)son, then mother-in-law: no word (no word)son, then uncle: brother (seen in training)son, then aunt: sister (seen in training)son, then husband: son-in-law (computed)son, then wife: daughter-in-law (seen in training)son, then brother: son (seen in training)son, then sister: daughter (seen in training)son, then son: grandson (seen in training)son, then daughter: granddaughter (seen in training)son, then son-in-law: no word (no word)son, then daughter-in-law: no word (no word)son, then nephew: grandson (computed)son, then niece: granddaughter (computed)son, then grandson: no word (no word)son, then granddaughter: no word (no word)daughter, then grandfather: father, father-in-law (seen in training)daughter, then grandmother: mother, mother-in-law (seen in training)daughter, then father: no word (no word)daughter, then mother: no word (no word)daughter, then father-in-law: no word (no word)daughter, then mother-in-law: no word (no word)daughter, then uncle: brother (seen in training)daughter, then aunt: sister (seen in training)daughter, then husband: son-in-law (seen in training)daughter, then wife: daughter-in-law (computed)daughter, then brother: son (seen in training)daughter, then sister: daughter (seen in training)daughter, then son: grandson (seen in training)daughter, then daughter: granddaughter (seen in training)daughter, then son-in-law: no word (no word)daughter, then daughter-in-law: no word (no word)daughter, then nephew: grandson (computed)daughter, then niece: granddaughter (computed)daughter, then grandson: no word (no word)daughter, then granddaughter: no word (no word)son-in-law, then grandfather: father, father-in-law (computed, two possible)son-in-law, then grandmother: mother, mother-in-law (computed, two possible)son-in-law, then father: no word (no word)son-in-law, then mother: no word (no word)son-in-law, then father-in-law: no word (no word)son-in-law, then mother-in-law: no word (no word)son-in-law, then uncle: brother (computed)son-in-law, then aunt: sister (computed)son-in-law, then husband: son-in-law (computed)son-in-law, then wife: daughter-in-law (computed)son-in-law, then brother: son (computed)son-in-law, then sister: daughter (computed)son-in-law, then son: grandson (computed)son-in-law, then daughter: granddaughter (computed)son-in-law, then son-in-law: no word (no word)son-in-law, then daughter-in-law: no word (no word)son-in-law, then nephew: grandson (computed)son-in-law, then niece: granddaughter (computed)son-in-law, then grandson: no word (no word)son-in-law, then granddaughter: no word (no word)daughter-in-law, then grandfather: father, father-in-law (computed, two possible)daughter-in-law, then grandmother: mother, mother-in-law (computed, two possible)daughter-in-law, then father: no word (no word)daughter-in-law, then mother: no word (no word)daughter-in-law, then father-in-law: no word (no word)daughter-in-law, then mother-in-law: no word (no word)daughter-in-law, then uncle: brother (computed)daughter-in-law, then aunt: sister (computed)daughter-in-law, then husband: son-in-law (computed)daughter-in-law, then wife: daughter-in-law (computed)daughter-in-law, then brother: son (computed)daughter-in-law, then sister: daughter (computed)daughter-in-law, then son: grandson (computed)daughter-in-law, then daughter: granddaughter (computed)daughter-in-law, then son-in-law: no word (no word)daughter-in-law, then daughter-in-law: no word (no word)daughter-in-law, then nephew: grandson (computed)daughter-in-law, then niece: granddaughter (computed)daughter-in-law, then grandson: no word (no word)daughter-in-law, then granddaughter: no word (no word)nephew, then grandfather: father, father-in-law (computed, two possible)nephew, then grandmother: mother, mother-in-law (computed, two possible)nephew, then father: no word (no word)nephew, then mother: no word (no word)nephew, then father-in-law: no word (no word)nephew, then mother-in-law: no word (no word)nephew, then uncle: brother (computed)nephew, then aunt: sister (computed)nephew, then husband: no word (no word)nephew, then wife: no word (no word)nephew, then brother: nephew (computed)nephew, then sister: niece (computed)nephew, then son: no word (no word)nephew, then daughter: no word (no word)nephew, then son-in-law: no word (no word)nephew, then daughter-in-law: no word (no word)nephew, then nephew: no word (no word)nephew, then niece: no word (no word)nephew, then grandson: no word (no word)nephew, then granddaughter: no word (no word)niece, then grandfather: father, father-in-law (computed, two possible)niece, then grandmother: mother, mother-in-law (computed, two possible)niece, then father: no word (no word)niece, then mother: no word (no word)niece, then father-in-law: no word (no word)niece, then mother-in-law: no word (no word)niece, then uncle: brother (computed)niece, then aunt: sister (computed)niece, then husband: no word (no word)niece, then wife: no word (no word)niece, then brother: nephew (computed)niece, then sister: niece (computed)niece, then son: no word (no word)niece, then daughter: no word (no word)niece, then son-in-law: no word (no word)niece, then daughter-in-law: no word (no word)niece, then nephew: no word (no word)niece, then niece: no word (no word)niece, then grandson: no word (no word)niece, then granddaughter: no word (no word)grandson, then grandfather: no word (no word)grandson, then grandmother: no word (no word)grandson, then father: no word (no word)grandson, then mother: no word (no word)grandson, then father-in-law: no word (no word)grandson, then mother-in-law: no word (no word)grandson, then uncle: son (computed)grandson, then aunt: daughter (computed)grandson, then husband: no word (no word)grandson, then wife: no word (no word)grandson, then brother: grandson (seen in training)grandson, then sister: granddaughter (seen in training)grandson, then son: no word (no word)grandson, then daughter: no word (no word)grandson, then son-in-law: no word (no word)grandson, then daughter-in-law: no word (no word)grandson, then nephew: no word (no word)grandson, then niece: no word (no word)grandson, then grandson: no word (no word)grandson, then granddaughter: no word (no word)granddaughter, then grandfather: no word (no word)granddaughter, then grandmother: no word (no word)granddaughter, then father: no word (no word)granddaughter, then mother: no word (no word)granddaughter, then father-in-law: no word (no word)granddaughter, then mother-in-law: no word (no word)granddaughter, then uncle: son (computed)granddaughter, then aunt: daughter (computed)granddaughter, then husband: no word (no word)granddaughter, then wife: no word (no word)granddaughter, then brother: grandson (seen in training)granddaughter, then sister: granddaughter (seen in training)granddaughter, then son: no word (no word)granddaughter, then daughter: no word (no word)granddaughter, then son-in-law: no word (no word)granddaughter, then daughter-in-law: no word (no word)granddaughter, then nephew: no word (no word)granddaughter, then niece: no word (no word)granddaughter, then grandson: no word (no word)granddaughter, then granddaughter: no word (no word)seen in training (62)computed, one word (112)computed, two words (16)no word (210)row: first wordcolumn: second word
62 facts in, 190 answers out. Each cell is one pair of words, such as "mother, then son". Training showed the model 62 of the 400 pairs. The rules it derived answer 128 more, with no lookup table. The 210 empty cells are pairs CLUTRR's twenty words have no name for, such as a cousin, and the model returns nothing there instead of guessing. Hover a cell for its answer.

Nothing in that process knows it's looking at families. Give it a different dataset whose relations combine in one of these shapes and it derives that dataset's rules instead. The tests do exactly that, with the same code, on filesystem paths, movement on a grid and several small algebras. That's what makes it general-purpose: the domain comes from the data, not from the code.

"Fits" here means fits exactly. A shape is kept only if it explains every observed fact, not most of them. That's what makes the answers checkable, and it's also why noisy data is a weakness (see where this approach stops).

The four rule shapes

A relation word such as grandmother gets a few coordinates, like an address. Each rule shape says how the address of a combined relation follows from the addresses of its parts. The model searches all four shapes and keeps whichever ones the data supports.

  1. A counter. Some quantity simply adds up along the chain. For kinship it turns out to be generations: up one for a parent, down one for a child, zero for a sibling or spouse. Nobody told it that. It is the only additive quantity the 62 facts allow.
  2. A stack, where up-then-down cancels. This is the important one. Your mother's son is your brother, not a "mother-son": going up and then down partly cancels. A plain counter can't express that, but a stack can. Think of a browser's back button, or .. in a file path: going into a folder and then back out leaves you where you started. The model finds that each kinship word is some number of steps up followed by some number of steps down:
    • father↑(1,0)
    • son↓(0,1)
    • brother↑↓(1,1)
    • grandfather↑↑(2,0)
    • uncle↑↑↓(2,1)
    • nephew↑↓↓(1,2)
    • husband·(0,0)
    Mathematicians call this structure the bicyclic monoid, first described by Lyapin in 1953. An anthropologist built the same structure for kinship by hand in 1984 (Read, 1984; see the next section). The model re-derived it from 62 facts about symbols it can't read.
  3. "The last step decides." Some properties come only from the final word of the chain. Gender is the obvious one: whoever you pass through, a chain ending in mother names a woman. The model finds six such classes. It is never told the word "gender".
  4. "The first step decides." This is the mirror image of shape 3. The model searches for it and finds that kinship has no such property, so it is dropped. Nobody declares that in advance.
husbandwife(self)sondaughterson-in-lawdaughter-in-lawgrandsongranddaughterfathermotherfather-in-lawmother-in-lawbrothersisternephewniecegrandfathergrandmotheruncleauntno word(a cousin sits here)0 up1 up2 up0 down1 down2 down
Where each word lives, as derived. Rows count steps up, columns steps down. Nobody placed these words: this layout is what the model derived from 62 facts about opaque symbols. The shaded cell is the in-law limit. Father and father-in-law share one address, and no rule separates them. (Son and son-in-law also share a cell, but the "last step decides" rule tells them apart.) Two up and two down is a real place with no CLUTRR word. That's where a cousin would be.

To answer a question, the model follows each chain through every rule that survived, which gives an address. It then returns every word that sits at that address. Usually that is one word. Sometimes it is two, and when that happens it is almost always telling the truth (see what it noticed about CLUTRR).

What each rule shape is worth, measured by switching it off (on gen_train23).

ConfigurationTop-1 accuracy
Everything99.4%
Without the stack72.3%
Without "the last step decides"87.4%
Without the counter98.7%

The stack is the largest single contributor here, and it is what lets most answers be pinned to a single word. The "last step" rule carries every male/female distinction. Without it, no answer is ever narrowed to one word. The counter is almost redundant once the stack exists, because the stack already contains it: steps down minus steps up is the generation count.

The same algebra, built by hand in 1984

Symbolic methods stand on established mathematics, and this one is no exception. People have been writing kinship down as algebra for more than 75 years. André Weil worked out the algebra of marriage rules for Claude Lévi-Strauss in 1949. Harrison White's An Anatomy of Kinship (1963), Boyd, 1969 and Lorrain & White, 1971 treated kinship and other social ties as algebras in which relations compose, the way "my mother's brother" composes two relations into one.

The closest match is Dwight Read's algebra of the American kinship terminology (Read, 1984). Read built it by hand, knowing what every word means. He defined a kin term product ("father of mother is grandfather"), took parent and child as generating terms with spouse added later, and wrote down the structural equations that generate the whole terminology. It was later implemented as software, the Kinship Algebra Expert System (Read, 2006).

The model derived the same structure from 62 facts about symbols it can't read:

Read's structural equationWhat the model derivedMatch
parent of child = selfchild, then parent, lands on (0,0): no steps up or downYes
child of parent = siblingparent, then child, lands on (1,1): brother or sisterYes
spouse is a separate generatorhusband and wife also land on (0,0), beside selfPartly

Both equations are quoted in Read, Fischer & Leaf, 2013. The first one is the whole definition of the bicyclic monoid: in mathematics it is written pq = 1 (Lyapin, 1953). Read's version reads it with p as "parent of" and q as "child of". The second equation is the other order, which does not cancel. That one-sided cancellation is exactly the "stack" shape the model chose.

The third row is where the derived model is weaker than the hand-built one. Read treats marriage as its own generator. The model puts spouses at the same point as self, because nothing in CLUTRR separates them. That is the in-law limit described further down.

Matching 1984 is the result, not a lack of novelty. A method that recovers, from a few dozen data points, a structure a field established by hand has found something real, not something that merely fits. The claim here is the derivation, not the algebra.

Results on all six CLUTRR datasets

The public CLUTRR release has six datasets, and all six are reported here. They fall into two groups that test different things.

The two extrapolation splits. Train on short chains and test on longer ones. These are what the benchmark exists for.

DatasetTrained onTested onStoriesSoundTop-1, unseen lengths
gen_train23_test2to102–3 steps4–10 steps1,003100%99.80%
gen_train234_test2to102–4 steps5–10 steps826100%99.39%

Per chain length, next to the best published systems. Published numbers are averages over several runs with ±1–5% spread. This model is deterministic and has no spread.

Trained on 2–3 steps. Published numbers from R5 (Lu et al., 2022), Table 2.

Steps45678910
This model99.599.4100100100100100
R5 (ICLR 2022)98999896979897
CTPA (ICML 2020)99999996948990

Trained on 2–4 steps. Published numbers from EpiGNN (Khalid & Schockaert, 2025), Table 1.

Steps5678910
This model98.410098.7100100100
NCRL (ICLR 2023)1009998989897
R5 (ICLR 2022)9999991009998
EpiGNN (ICLR 2025)999999999698

Read this as the same level as the best published systems, not better. The top systems sit within their own error bars of 100%. Also, the published papers use CLUTRR's original data release, while these runs use the HuggingFace release of the same splits. The two are generated the same way, but the story counts differ slightly, so they are not identical test sets. The claim that holds up: a model with no network and no weights, reading opaque symbols, reaches the level of trained neuro-symbolic rule learners, and it says when it is unsure instead of guessing.

The four robustness splits (rob_*: clean, disc, irr, sup). CLUTRR built these to test distracting sentences in the prose. This model never reads prose, so for it these are four more independently generated samples. They only contain chains of 2–3 steps (nine distinct chains per test set), so they test consistency, not extrapolation. The model was trained once on gen_train23 and never retrained.

DatasetStoriesSoundTop-1Best possible
rob_train_clean447100%100.00%100.00%
rob_train_disc445100%94.83%94.83%
rob_train_irr444100%93.69%93.69%
rob_train_sup447100%93.74%93.74%

"Best possible" is explained in the next section. The model derives the identical set of rules on every dataset, down to the last coordinate, whether it is trained on that dataset or not.

What the model noticed about CLUTRR itself

Because the model returns every answer its rules allow, it points to questions where the chain doesn't contain the answer.

Some CLUTRR questions have two right answers, and the dataset marks one wrong. Take wife → son → grandmother. Your wife's son is your son, and your son's grandmother is either your mother or your wife's mother. The chain alone can't say which, because both are real people it could be. CLUTRR has one correct label per story, and the same chain appears in the test set with both labels. In every one of the six datasets, every such case is mother vs mother-in-law or father vs father-in-law.

That puts a hard ceiling on any method that answers from the chain. In the worst case (rob_irr) 6.3% of test stories can't be scored correct by any such method. The model's two-word answer on those questions is correct; the benchmark just can't score it. The "best possible" column above is that limit. On all four rob_* datasets the model sits exactly on it, and on the two extrapolation splits it is within 0.2% and 1.4% of it.

These are not labelling mistakes. The labels are true of the family trees CLUTRR generated. The point is narrower: the symbolic version of the benchmark asks some questions its input can't settle. Anyone can check this without trusting the model. Group the test set by chain, and count the chains with more than one label.

Others have spotted individual cases by reading stories. Yang, Ishay & Lee (2023) found 16 faulty instances in a 400-story CLUTRR sample, one of them labelled mother where mother-in-law was right, and Zhang et al. (2024) note questions with several correct answers but one label. What the model adds is the exact count on all six datasets, found from the derived rules rather than by inspection, and the finding that every such case is a blood/in-law pair.

CLUTRR's coverage lets a false rule pass every test. In the entire corpus, every chain ending in husband has the answer son-in-law, because the only such chain that ever occurs is daughter → husband. So "the last step decides" happily files husband with son-in-law, and nothing in CLUTRR can contradict it. Run the model on a real, generated family tree instead and that rule is visibly false: your mother's husband is your father. Soundness there drops to 79–90%. Train on the tree's own data and the rule corrects itself, returning to 100%. Along the same lines, no in-law word ever appears inside a CLUTRR chain, only as an answer, so nothing in the benchmark shows how in-law relations combine.

The lesson generalizes: a benchmark's coverage decides which rules can be learned from it, and no amount of checking against that benchmark can see past it.

Why soundness matters

Returning all twenty words would be 100% sound and useless. The claim is soundness with an average answer of 1.1 words. Most answers are one word, and the rest are the genuinely ambiguous cases above.

The same property holds when the input is wrong. Add false facts to the story, so there are two routes between the people that disagree, and the model combines the routes by keeping only answers both allow. Two routes that disagree leave nothing, and an empty answer is a flagged contradiction. With ten false facts per story it flags 98% of stories and gives a confidently wrong answer on none. A system that returns a single best guess has nothing to disagree with.

This notion of soundness is borrowed, not invented. Each rule shape is a safe over-approximation of the truth, and answering with the overlap of several of them is the core idea of abstract interpretation (Cousot & Cousot, 1977), the theory behind the static analysers that check production software.

How deep can it go?

CLUTRR stops at ten steps. How far can this go? A thousand steps? Ten thousand?

The model doesn't care. A chain is folded one step at a time, so a 10,000-step chain is just more of the same arithmetic. The hard part is finding true answers to check it against, and that turns out to be a fact about families, not about the model.

Why real family trees stop at about twenty steps. A fair question never visits the same person twice. Once it does, the chain of words no longer decides the answer. (Your father's grandson is your son if he's your own child, and your nephew otherwise.) Any real family tree is finite, so a walk of about twenty steps runs out of new people. That's the same reason CLUTRR stops at ten.

So the test grows the family as it walks. Nobody exists until the walk needs them: parents are created the first time someone asks for one, and a new child can always be born. Walks of any length never meet anyone twice, and the true answer is still read off the family tree by counting generations to the nearest common ancestor. It is never worked out by combining the words.

Rules derived from CLUTRR (chains of 2–3 steps, never retrained), on walks that only pass through relatives CLUTRR has words for.

Chain lengthChainsSoundTop-1Answer sizeTime per answer
10300100%100%1.000.07 ms
100300100%100%1.000.28 ms
1,000100100%100%1.002.9 ms

Every answer at every length is the single correct word. That covers a thousand steps, from rules learned on chains of three.

Past the edge of the vocabulary. Let the walk wander freely and after 10,000 steps it lands on someone English has no word for, typically a couple of generations up and ten thousand down. The model correctly returns no name. Underneath, though, it still computes an address, and that address can be checked directly. On every walk tested, to 10,000 steps, the derived coordinates equal the true (generations up, generations down) exactly. The model knows precisely where that person sits in the family. It just has no word to call them.

For the curious: the CLUTRR data leaves four candidate coordinate systems standing. One is the anthropologists' system. The other three turn out to be the same system shifted by exactly one generation up and one down. That was measured, not assumed.

Where this approach stops

Every limit below is measured in the repository, not guessed.

Depth isn't on this list. As the previous section shows, it isn't a limit.

Making it more general

The method is a recipe that has nothing to do with families:

  1. Treat the relation words as opaque symbols, and collect observed combinations (A then B gives C).
  2. Keep a menu of rule shapes, each with an exact way to derive its numbers from data.
  3. Check every derived rule against all the data, and throw out any rule that fails once.
  4. Answer by combining the surviving rules, and return every answer they allow.

Generalizing means growing step 2's menu, or finding new places where the existing menu fits.

Shapes worth adding. These are the natural next ones, each aimed at a limit above. The last two have been built and tested; the results follow.

Places the existing shapes already fit. Two are tested here: filesystem paths (.. cancels a folder, the same up/down structure as kinship, exact to 10,000 steps) and movement on a grid, where the model finds it needs two counters, not one. Other domains share the up/down "stack" shape but are untested: undo/redo histories, matching brackets and nested function calls, and network packets that are wrapped and unwrapped in layers. Physical units have the "counter" shape, since combining metres per second with seconds adds the exponents.

Two extensions, tested

Both are optional and off by default, and neither changes any CLUTRR number on this page. Both passed the same controls as the core model: on the synthetic worlds that lack the structure they look for, they derive nothing.

Words with more than one meaning

Real vocabularies reuse words. In English, "first cousin once removed" means both your parent's cousin and your cousin's child, and "brother-in-law" means both your spouse's brother and your sister's husband. One word at two addresses breaks the counter and the stack for the whole vocabulary. With English-style cousin names on a generated family tree, the model derived no counter and no stack at all, and top-1 fell to 31% at two steps. It stayed sound, but it was nearly useless.

The fix is a domain-free rule. A word that only ever appears as an answer may split into the fewest senses its facts require, each with its own address. The model still answers with the surface word. A chain containing an ambiguous word is composed once per sense, so splitting can only widen an answer. It never drops a true one.

Two caveats. The family-tree walks never pass back through anyone, so every answer there is fully determined. On CLUTRR, where "your daughter's grandfather" genuinely has two answers, nothing splits and both answers stay. And a word that is ambiguous and used inside chains, not just as an answer, isn't handled yet.

Route memory

The second extension is a small state machine that updates step by step along a chain. It is found by searching for the smallest one that fits every training example exactly, then audited and combined like the other shapes.

The in-law problem was smaller than it first looked, and different. It was mostly two words hiding in one. That came from testing the claim instead of assuming it.

Why derived laws matter for new inputs

This is the heart of the argument, and the evidence is now in, so here it is plainly.

A statistical model learns a function from examples. It is most reliable where examples are dense, which is interpolation. Ask it about something outside what it saw, such as a chain three times longer than any in training, and it is extrapolating. Nothing inside it states what it will do there. It might be right, and some learned systems are remarkably good at this. But you find out one input at a time, after the fact, and the model can't tell you in advance which inputs it is sure about. Chollet argues that intelligence should be measured by how well a system handles situations it wasn't prepared for, not by its skill on familiar ones (Chollet, 2019).

A derived law is different in kind. "Up one, then down one" is a claim about every chain, including ones nobody has seen. The results above show what that buys:

Derived laws aren't automatically right. A law can fit all your data and still be false in the world, like the husband rule. It's also less forgiving of noisy labels than a statistical model. But when it's wrong, it's wrong in a way you can see, point to and fix with data. That's what "auditable" means here.

Related work

Deriving explicit laws from data isn't new, and this work belongs to a long line of systems that do it. A few neighbours, and how they differ:

What this model adds is narrow: exact derivation over a fixed menu of composition shapes, sound set-valued answers, and a direct comparison against trained systems on a benchmark built to test extrapolation.

Open questions

The introduction asked how much of reasoning has a law like this. No survey I know of answers it directly. The nearest are a general framework for the relation algebras used in qualitative spatial and temporal reasoning (Ligozat & Renz, 2004) and a review of what "generalization" means across NLP research (Hupkes et al., 2023). It breaks into smaller questions that can each be tested.

Putting it together

A family question like "who is your daughter's grandfather?" looks trivial, and it hides everything that matters about reasoning you can trust. The chain doesn't determine the answer. The data can't show some combinations. And a question can be longer than any example. A model that derives its laws handles all three honestly: it answers with every possibility, it exposes the rules it relies on, it treats a thousand-step question exactly like a two-step one, and when a word carries two meanings it can split them from the data. It does this from 62 facts about symbols it can't read, and it lands on the same algebra an anthropologist built by hand in 1984. The open question is how far that reaches beyond families. The method is cheap enough to find out one domain at a time.

Reproducing everything

pip install -e .
export CLUTRR_DIR=/path/to/clutrr/gen_train23_test2to10   # other datasets alongside it
python -m bicyclic_kinship.benchmark    # all six datasets, about 5 seconds
python -m bicyclic_kinship.worlds       # family trees, depth to 10,000, paths, grid
python -m bicyclic_kinship.stress       # the stress tests, a few minutes
pytest                                  # 59 tests

Zero dependencies, pure Python. The mathematics, the stress tests, the negative results and how the work was checked are in the technical companion, Deriving Composition Laws, and Trying to Break Them.

References

Benchmark and published systems. Sinha, Sodhani, Dong, Pineau & Hamilton (2019), CLUTRR, EMNLP, arXiv:1908.06177. Minervini et al. (2020), Learning Reasoning Strategies in End-to-End Differentiable Proving (CTP), ICML, arXiv:2007.06477. Bergen, O'Donnell & Bahdanau (2021), Systematic Generalization with Edge Transformers, NeurIPS, arXiv:2112.00578. Lu et al. (2022), R5, ICLR, arXiv:2205.06454. Cheng et al. (2023), NCRL, ICLR, arXiv:2303.03581. Khalid & Schockaert (2025), Systematic Relational Reasoning with Epistemic Graph Neural Networks, ICLR, proceedings. Yang, Ishay & Lee (2023), Coupling Large Language Models with Logic Programming for Robust and General Reasoning from Text, Findings of ACL, arXiv:2307.07696. Zhang et al. (2024), Extracting and Following Paths for Robust Relational Reasoning with Large Language Models (Path-of-Thoughts), TMLR 2026, arXiv:2412.17963.

Kinship algebra. Weil (1949), appendix to Lévi-Strauss, Les structures élémentaires de la parenté. White (1963), An Anatomy of Kinship. Boyd (1969), The algebra of group kinship, Journal of Mathematical Psychology, doi. Lorrain & White (1971), Structural equivalence of individuals in social networks, Journal of Mathematical Sociology, doi. Read (1984), An Algebraic Account of the American Kinship Terminology, Current Anthropology 25(4), link. Read (2006), Kinship Algebra Expert System (KAES), Social Science Computer Review 24(1), doi. Read, Fischer & Leaf (2013), What Are Kinship Terminologies, and Why Do We Care?, Social Science Computer Review, doi.

Mathematics and program analysis. Lyapin (1953), first published description of the bicyclic semigroup; Clifford & Preston (1961), The Algebraic Theory of Semigroups, vol. 1. Cousot & Cousot (1977), Abstract interpretation, POPL, doi. Gold (1978), Complexity of automaton identification from given data, Information and Control, doi. Ernst, Cockrell, Griswold & Notkin (1999), Dynamically discovering likely program invariants to support program evolution (Daikon), ICSE, doi.

Deriving laws and programs from data. Angluin (1987), Learning regular sets from queries and counterexamples, Information and Computation, doi. Schmidt & Lipson (2009), Distilling free-form natural laws from experimental data, Science, doi. Muggleton, Lin & Tamaddoni-Nezhad (2015), Meta-interpretive learning of higher-order dyadic datalog, Machine Learning, doi. Brunton, Proctor & Kutz (2016), Discovering governing equations from data by sparse identification of nonlinear dynamical systems, PNAS, doi. Evans & Grefenstette (2018), Learning explanatory rules from noisy data, JAIR, doi. Chollet (2019), On the Measure of Intelligence, arXiv:1911.01547. Sinha, Sodhani, Pineau & Hamilton (2020), Evaluating Logical Generalization in Graph Neural Networks (GraphLog), arXiv:2003.06560. Udrescu & Tegmark (2020), AI Feynman, Science Advances, doi. Cropper & Morel (2021), Learning programs by learning from failures, Machine Learning, doi. Ellis et al. (2021), DreamCoder, PLDI, doi.