# Rule: Generic Slots, Specific Classes **Identifier**: `generic-slots-specific-classes` **Severity**: **CRITICAL** ## Core Principle **Slots MUST be generic predicates** that can be reused across multiple classes. **Classes MUST be specific** to provide context and constraints. **DO NOT** create class-specific slots when a generic predicate can be used. ## Rationale 1. **Predicate Proliferation**: Creating bespoke slots for every class explodes the schema size (e.g., `has_museum_name`, `has_library_name`, `has_archive_name` instead of `has_name`). 2. **Interoperability**: Generic predicates (`has_name`, `has_identifier`, `has_part`) map cleanly to standard ontologies (Schema.org, Dublin Core, RiC-O). 3. **Querying**: It's easier to query "all entities with a name" than "all entities with museum_name OR library_name OR archive_name". 4. **Maintenance**: Updating one generic slot propagates to all classes. ## Examples ### ❌ Anti-Pattern: Class-Specific Slots ```yaml # WRONG: Creating specific slots for each class slots: has_museum_visitor_count: range: integer has_library_patron_count: range: integer classes: Museum: slots: - has_museum_visitor_count Library: slots: - has_library_patron_count ``` ### ✅ Correct Pattern: Generic Slot, Specific Class Usage ```yaml # CORRECT: One generic slot reused slots: has_or_had_quantity: slot_uri: rico:hasOrHadQuantity range: Quantity multivalued: true classes: Museum: slots: - has_or_had_quantity slot_usage: has_or_had_quantity: description: The number of visitors to the museum. Library: slots: - has_or_had_quantity slot_usage: has_or_had_quantity: description: The number of registered patrons. ``` ## Intermediate Class Pattern Making slots generic often requires introducing **Intermediate Classes** to hold structured data, rather than flattening attributes onto the parent class. ### ❌ Anti-Pattern: Specific Flattened Slots ```yaml # WRONG: Flattened specific attributes classes: Museum: slots: - has_museum_budget_amount - has_museum_budget_currency - has_museum_budget_year ``` ### ✅ Correct Pattern: Generic Slot + Intermediate Class ```yaml # CORRECT: Generic slot pointing to structured class slots: has_or_had_budget: range: Budget multivalued: true classes: Museum: slots: - has_or_had_budget Budget: slots: - has_or_had_amount - has_or_had_currency - has_or_had_year ``` ## Specificity Levels | Level | Component | Example | |-------|-----------|---------| | **Generic** | **Slot (Predicate)** | `has_or_had_identifier` | | **Specific** | **Class (Subject/Object)** | `ISILCode` | | **Specific** | **Slot Usage (Context)** | "The ISIL code assigned to this library" | ## Migration Guide If you encounter an overly specific slot: 1. **Identify the generic concept** (e.g., `has_museum_opening_hours` → `has_opening_hours`). 2. **Check if a generic slot exists** in `modules/slots/`. 3. **If yes**, use the generic slot and add `slot_usage` to the class. 4. **If no**, create the **generic** slot, not a specific one. ## Naming Indicators **Reject slots containing:** * Class names (e.g., `has_custodian_name` → `has_name`) * Narrow types (e.g., `has_isbn_identifier` → `has_identifier`) * Contextual specifics (e.g., `has_primary_email` → `has_email` + type/role) ## See Also * Rule 55: Broaden Generic Predicate Ranges * Rule: Slot Naming Convention (Current Style)