Skip to main content

ontologos_core/
lib.rs

1//! Core data model and reasoner API for OntoLogos.
2//!
3//! v0.4 provides an in-memory ontology representation with interned IRIs,
4//! typed entities, structured axioms, secondary indexes, and JSON v2 serialization.
5//!
6//! # Start here — load and reason
7//!
8//! **Do not use [`Ontology::from_file`] or [`Reasoner::classify`] for file loading / reasoning.**
9//!
10//! ```ignore
11//! use ontologos_parser::load_ontology;
12//! use ontologos_rdfs::RdfsEngine;
13//!
14//! let mut ontology = load_ontology(std::path::Path::new("ontology.owl"))?;
15//! let report = RdfsEngine::new().materialize(&mut ontology)?;
16//! println!("inferred {}", report.inferred_total());
17//! ```
18//!
19//! OWL RL saturation: `ontologos_rl::RlEngine::new(1)?.saturate(&mut ontology)?`
20//!
21//! # Builder-only (no parser)
22//!
23//! ```
24//! use ontologos_core::{Error, Ontology};
25//!
26//! fn main() -> Result<(), Error> {
27//!     let ontology = Ontology::builder()
28//!         .class("http://example.org/Pizza")?
29//!         .class("http://example.org/Food")?
30//!         .subclass_of("http://example.org/Pizza", "http://example.org/Food")?
31//!         .build()?;
32//!     assert_eq!(ontology.axiom_count(), 1);
33//!     Ok(())
34//! }
35//! ```
36
37#![warn(missing_docs)]
38
39mod axiom;
40mod entity;
41mod error;
42mod graph;
43mod iri;
44mod limits;
45mod ontology;
46mod parse_meta;
47mod reasoner;
48mod serialize;
49
50pub use axiom::{Axiom, AxiomId};
51pub use entity::{EntityId, EntityKind, EntityRecord, EntityRegistry};
52pub use error::{Error, Result};
53pub use graph::{AxiomIndex, AxiomStore};
54pub use iri::{InternPool, IriId};
55pub use limits::Limits;
56pub use ontology::{Ontology, OntologyBuilder};
57pub use parse_meta::{OwlConstruct, ParseMeta, ParseMetaSummary};
58pub use reasoner::{Profile, Reasoner, ReasonerBuilder, ReasonerConfig};
59
60#[cfg(test)]
61mod integration_tests {
62    use super::*;
63
64    #[test]
65    fn classify_returns_not_implemented_for_el() {
66        let ontology = Ontology::default();
67        let mut reasoner = Reasoner::builder()
68            .profile(Profile::El)
69            .build(ontology)
70            .expect("build");
71        assert_eq!(reasoner.classify().unwrap_err(), Error::NotImplemented);
72        assert_eq!(reasoner.ontology().entity_count(), 0);
73    }
74
75    #[test]
76    fn classify_rdfs_profile_returns_delegate_hint() {
77        let ontology = Ontology::default();
78        let mut reasoner = Reasoner::builder()
79            .profile(Profile::Rdfs)
80            .build(ontology)
81            .expect("build");
82        let err = reasoner.classify().expect_err("rdfs delegate hint");
83        assert!(matches!(err, Error::Message(_)));
84    }
85
86    #[test]
87    fn classify_rl_profile_returns_delegate_hint() {
88        let ontology = Ontology::default();
89        let mut reasoner = Reasoner::builder()
90            .profile(Profile::Rl)
91            .build(ontology)
92            .expect("build");
93        let err = reasoner.classify().expect_err("rl delegate hint");
94        assert!(matches!(err, Error::Message(_)));
95    }
96
97    #[test]
98    fn reasoner_rejects_invalid_parallelism() {
99        let ontology = Ontology::default();
100        let err = Reasoner::builder()
101            .config(ReasonerConfig {
102                parallelism: 0,
103                ..ReasonerConfig::default()
104            })
105            .build(ontology)
106            .expect_err("parallelism");
107        assert!(matches!(err, Error::Message(_)));
108    }
109}