Skip to main content

owl_structural_model/
property_chain.rs

1//! Ordered property chains and the two forms of object subproperty expressions.
2
3use crate::{ObjectPropertyExpression, StructuralModelError};
4
5/// An ordered chain of at least two object property expressions.
6///
7/// Order and repeated members are significant. Construction and deserialization
8/// enforce the OWL 2 structural arity; ontology-wide regularity and simple-role
9/// restrictions require a separate profile check.
10#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
11#[serde(
12    try_from = "Vec<ObjectPropertyExpression>",
13    into = "Vec<ObjectPropertyExpression>"
14)]
15pub struct ObjectPropertyChain {
16    // bounded: members of one caller-owned structural chain, not a graph relation.
17    members: Vec<ObjectPropertyExpression>,
18}
19
20impl ObjectPropertyChain {
21    /// Create an ordered property chain.
22    ///
23    /// # Errors
24    ///
25    /// Returns [`StructuralModelError::InvalidFormat`] for fewer than two members.
26    pub fn try_new(members: Vec<ObjectPropertyExpression>) -> Result<Self, StructuralModelError> {
27        if members.len() < 2 {
28            return Err(StructuralModelError::InvalidFormat {
29                kind: "object property chain",
30                value: members.len().to_string(),
31                message: "requires at least two object property expressions",
32            });
33        }
34        Ok(Self { members })
35    }
36
37    /// Return the members in composition order.
38    #[must_use]
39    pub fn as_slice(&self) -> &[ObjectPropertyExpression] {
40        &self.members
41    }
42}
43
44impl TryFrom<Vec<ObjectPropertyExpression>> for ObjectPropertyChain {
45    type Error = StructuralModelError;
46
47    fn try_from(members: Vec<ObjectPropertyExpression>) -> Result<Self, Self::Error> {
48        Self::try_new(members)
49    }
50}
51
52impl From<ObjectPropertyChain> for Vec<ObjectPropertyExpression> {
53    fn from(chain: ObjectPropertyChain) -> Self {
54        chain.members
55    }
56}
57
58/// The subproperty operand of an OWL 2 `SubObjectPropertyOf` axiom.
59#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
60pub enum SubObjectPropertyExpression {
61    /// A single named or inverse object property expression.
62    Property(ObjectPropertyExpression),
63    /// An ordered composition of at least two object property expressions.
64    Chain(ObjectPropertyChain),
65}