One relation, one predicate - #569
Merged
Merged
Conversation
WaylandYang
force-pushed
the
feat/predicate-canon
branch
from
September 9, 2026 17:52
05f019a to
0830b34
Compare
WaylandYang
marked this pull request as ready for review
September 9, 2026 17:52
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: WaylandYang <wayland0916@gmail.com>
WaylandYang
force-pushed
the
feat/predicate-canon
branch
from
September 9, 2026 22:40
0830b34 to
4bf8e61
Compare
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.
Closes #560.
Where the duplicates come from
Three sources, read off the AI-companies base (2,135 facts under 136 predicates from a 1,701-relation ontology):
employeesisschema:supersededBy schema:employee,foundersbyfounder; both survive the import as separate relations, and because both keys exist, the extractor's exact-key match keeps them apart. The inflection fold inpredicate_matchnever gets a turn.comprisedcame in next tohas_member.What changed
schema:supersededBy(utopia-ingest), the same way it readsowl:inverseOfandrdfs:subPropertyOf; it no longer lands in the unprojected report.superseded, listed in the preview likekey_takenand counted in the summary asrelations_superseded. Onceemployeesis not a key, the model'semployeesfolds ontoemployeeby inflection, asfoundersdoes ontofounder.Existing bases keep their
employees/foundersrows; re-applying the pack skips the superseded ones from then on but does not rewrite stored facts. That repair, if wanted, is a separate cut.Measured
Same two extractions as #568 (eight documents, schema.org pack, DeepSeek-V3;
devversus this branch merged with #568), base-level jobs settled.employee/employees/employs/works_foremployed1)founder/founders/founded/founded_bymember/members/member_of/has_memberThe superseded pairs are gone from the after run:
employees,founders,members,employsno longer exist as keys, so the model's forms fold ontoemployee,founder,member/has_memberby inflection. The distinct-predicate count barely moves because the corpus's own vocabulary (the ~90 voted-in relations) is the same in both runs; what changed is that one relation is no longer two.The fold by meaning, calibrated on this run. 213 candidate distances were logged for the forms the vote created. Exactly one folded:
started → commencesat 0.14. The closest non-synonyms sat at 0.24–0.29 (replaces → substitute_product0.25,improved → changes0.24,launched → commences0.27,deal_with → issue0.28), and one true synonym sat above them:employed → employeeat 0.29. So 0.20 is the right cut for a bare-word embedding and cannot be raised: what a wider threshold gains (employed) it pays for three times over (replaces,improved,deal_with). Folding the rest needs the relation's description in the comparison, or a person; this branch settles for not folding wrong.The 17 unembedded relations in the baseline are what the bootstrap minted after the import-time embedding, with nothing to embed them; in the after run each bootstrap pass was followed by a refresh (the log shows four, 63 + 42 + 59 + 42 rows), and the 2 left over were minted by the pass that ran after the last refresh.
Tests
🤖 Generated with Claude Code