ontocast.tool.agg.signatures¶
Literal/object signatures and schema harvesting for merge guards.
Merge guards need cheap, canonical views of what an entity asserts: which literal values it holds per predicate, and which IRI objects it points at per predicate. Two entities asserting conflicting values for the same predicate are distinct individuals no matter how similar their labels are — a false merge silently corrupts data, while a false split leaves visible, recoverable redundancy.
Everything here is domain-agnostic: functionality is harvested from the
ontology context (owl:FunctionalProperty and OWL max-cardinality-1
restrictions) or inferred empirically from the corpus, never hardcoded
per vocabulary.
Attributes¶
SIBLING_GROUP_CAP = 32
module-attribute
¶
logger = logging.getLogger(__name__)
module-attribute
¶
Classes¶
MergeGuardContext
dataclass
¶
Corpus- and schema-derived context consulted by merge guards.
Attributes:
| Name | Type | Description |
|---|---|---|
sibling_pairs |
set[frozenset[URIRef]]
|
Pairs of entities that co-occur as objects of one subject (scope-dependent) and therefore denote distinct individuals. |
functional_predicates |
set[URIRef]
|
Predicates with a schema-asserted or empirically observed max-1 object constraint. |
Source code in ontocast/tool/agg/signatures.py
Functions:¶
build_sibling_pairs(object_groups, *, scope)
¶
Build never-merge pairs from co-object groups.
Two URIs listed as objects on one subject describe distinct things — merging the endpoints of a range, the samples of areas 1–3, or the grants of one acknowledgement destroys exactly the distinction the author asserted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
object_groups
|
dict[tuple[URIRef, URIRef], set[URIRef]]
|
|
required |
scope
|
str
|
|
required |
Returns:
| Type | Description |
|---|---|
set[frozenset[URIRef]]
|
Set of unordered entity pairs that must never merge. |
Source code in ontocast/tool/agg/signatures.py
canonical_literal(literal)
¶
Return a canonical (value, kind) pair for a guard-relevant literal.
Numeric literals (typed with an XSD numeric datatype, or untyped with a
numeric lexical form) canonicalize through :class:~decimal.Decimal so
230, "230"^^xsd:decimal and "230.0"^^xsd:double compare equal.
Temporal literals canonicalize to their lexical form. Strings return
None — string conflicts are handled by the strict lexical bar, not by
value comparison.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
literal
|
Literal
|
Literal to canonicalize. |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, str] | None
|
|
tuple[str, str] | None
|
or |
Source code in ontocast/tool/agg/signatures.py
clean_label_token(token)
¶
Strip punctuation from token edges: "baranov," / "d." -> "baranov" / "d".
normalize_text deliberately keeps punctuation, so token-level
comparisons must shed it themselves — an initial written "D." is two
characters lexically and one character semantically.
Source code in ontocast/tool/agg/signatures.py
empirically_functional_predicates(object_groups, *, min_support)
¶
Infer predicates that behave single-valued across the corpus.
A predicate qualifies when it is observed on at least min_support
subjects and no subject anywhere holds two distinct IRI objects for it
(e.g. qudt:unit: every quantity node carries exactly one unit, even
though no catalog declares the property functional). Multi-valued domain
predicates are exempt by construction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
object_groups
|
dict[tuple[URIRef, URIRef], set[URIRef]]
|
|
required |
min_support
|
int
|
Minimum distinct subjects required before the inference is trusted. |
required |
Returns:
| Type | Description |
|---|---|
set[URIRef]
|
Set of empirically single-valued predicate IRIs. |
Source code in ontocast/tool/agg/signatures.py
harvest_max_one_predicates(ontology_graph)
¶
Harvest predicates the schema constrains to at most one value.
Sources, both fully generic:
- subjects typed
owl:FunctionalProperty; owl:onPropertytargets of OWL restrictions carryingowl:maxCardinality/owl:cardinality(or their qualified variants) equal to 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ontology_graph
|
RDFGraph | None
|
Merged ontology context, or None. |
required |
Returns:
| Type | Description |
|---|---|
set[URIRef]
|
Set of predicate IRIs with a schema-asserted max-1 constraint. |
Source code in ontocast/tool/agg/signatures.py
label_tokens(label)
¶
Split a normalized label into punctuation-cleaned tokens.
labels_alias_with_initials(left_labels, right_labels)
¶
True when a label pair matches token-injectively allowing initials.
Every token of the shorter label must match a distinct token of the longer one (exactly, or as a single-character initial), and at least one matched token must be a full word (len > 2). Generic abbreviation structure — nothing person-specific.
Source code in ontocast/tool/agg/signatures.py
labels_differ_only_by_initials(left_labels, right_labels)
¶
True when some label pair is identical except for conflicting initials.
"french company s" vs "french company t" — the full-word token sets are
identical and each side carries its own short token (an initial or
single-letter identifier) absent from the other. Authors write exactly
this shape to distinguish entities, so it is evidence of distinctness,
not of identity — the inverse of :func:labels_alias_with_initials,
where the initial expands a full word on the other side.
Source code in ontocast/tool/agg/signatures.py
normalize_string_value(text)
¶
Normalize a string for identity comparison.
Lowercase, diacritics removed, special characters cleaned, CamelCase split so it yields the same tokens as snake_case. Single source for the normalizer and the validation gate, which must agree on what counts as "the same string".
Source code in ontocast/tool/agg/signatures.py
string_values_compatible(left, right)
¶
Compatible when equal, prefix-related, or initial-abbreviations.
Source code in ontocast/tool/agg/signatures.py
tokens_alias_compatible(left, right)
¶
Exact token match, or a (possibly dotted) single-char initial of it.