fix(owlgen): warn on single-child covering axiom equivalence#5
Conversation
ece07d8 to
c2b7088
Compare
8841b3d to
2b9e4e9
Compare
🔍 Adversarial Review — PR #5SummarySolid, well-motivated PR. The OWL 2 semantics analysis is correct and the warning-not-skip approach aligns with upstream reviewer feedback. No actual bugs found — but there are test coverage gaps and a couple of design concerns worth discussing before merge. 🐛 Bugs & IssuesNo code bugs found. The control flow is correct: The One correctness note on the test assertion:
|
7ac6437 to
c7afa6e
Compare
Until we have figured out how to properly version the linkml-model one
e43010f to
6c55697
Compare
2a77d3c to
7306cd7
Compare
Emit warnings for abstract class covering axiom edge cases: - Zero children: warn that no covering axiom will be generated - One child: warn that the covering axiom degenerates to an equivalence (Parent = Child), recommending --skip-abstract-class-as-unionof-subclasses Both axioms are still emitted when applicable (semantically correct per OWL 2), but warnings alert users who extend the ontology downstream. Tests verify warnings are logged, flag suppression works, the single-child covering axiom triple is correctly asserted, plus negative tests for multi-child and concrete class cases, and the mixin-only children edge case. Refs: linkml#3309, linkml#3219 Signed-off-by: jdsika <carlo.van-driesten@bmw.de> Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
63dd8e7 to
982c7e0
Compare
Update metamodel test fixtures from linkml-model
Updated the community meeting schedule with the most up to date title for Joshua Send's presentation on May 21st ("Why TypeDB is the Natural Backend for LinkML")
Temporary update_model workflow
Replaces the recursive as_dict conversion in formatutils.is_empty with an O(1) native truthiness check. This resolves a massive performance cliff when instantiating or validating deeply nested LinkML models.
test(plantuml): use text-content parsing linkml#3463
fix(excel): class names longer than 31 chars
When a slot had no cardinality data the template still emitted the heading and an empty `| Property | Value | / | --- | --- |` table, and Python-Markdown's tables extension then consumed the next `### Slot Characteristics` heading as a one-cell table row. Guard the section behind a `has_cardinality` check, matching the pattern used elsewhere in the template. Fixes linkml#3569.
fix(docgen): omit empty Cardinality table in slot pages
…set (linkml#3537) Map LinkML's `readonly` meta slot to JSON Schema's `readOnly` annotation (default 2019-09 metadata vocabulary). When a slot has a non-empty `readonly` value, the generated JSON Schema property now carries `readOnly: true`. Absent / empty values are unchanged. The free-text reason is dropped — JSON Schema has no equivalent. Closes linkml#3528 Co-authored-by: Claude Code 2.1.146 / Claude opus-4-7 <noreply@anthropic.com>
Summary
Emit a warning when an abstract class has only one direct
is_achild, since the covering axiom degenerates to an equivalence (Parent ≡ Child). The warning recommends--skip-abstract-class-as-unionof-subclassesto suppress covering axioms if the equivalence is undesired.Motivation
The covering axiom feature (linkml#3219) correctly expresses that every instance of an abstract class must belong to one of its subclasses. With a single child, this is semantically equivalent to
Parent ≡ Childper OWL 2 Primer §4.2. While OWL-correct, this may surprise users building extensible ontologies where more children are added downstream — the equivalence causes new siblings to inherit constraints from the first child via RDFS transitivity.Rather than silently skipping the axiom (which would change the OWL semantics), a warning alerts users to the implication and points them to the existing escape hatch.
Changes
owlgen.py: Addlogger.warning()when an abstract class has exactly 1 child before the covering axiom is emitted. Update field docstring and CLI help text to document the warning.test_owlgen.py: Addtest_abstract_class_with_single_child_emits_warning(validates warning is logged with flag recommendation) andtest_single_child_warning_suppressed_by_skip_flag(validates no warning when skip flag is set).Design Decision
Per review feedback from @mgskjaeveland (linkml#3309): the single-child equivalence is not a generator error — it is the expected OWL semantics. The proper response is a warning, not a silent skip. Users who need to avoid the equivalence should use
--skip-abstract-class-as-unionof-subclasses.References
rdfs:subClassOf=owl:equivalentClassDisjointUnionas proper covering construct