Skip to content

Commit 5807953

Browse files
committed
__repr__ and documentation
1 parent cb6b8ca commit 5807953

File tree

7 files changed

+138
-3
lines changed

7 files changed

+138
-3
lines changed

ARCHITECTURE.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,101 @@ These seams are documented as comments in the relevant `.ttl` files.
140140

141141
---
142142

143+
## Interoperability: Flexo MMS and OpenMBEE
144+
145+
Because knowledgecomplex stores all data as RDF and enforces constraints via standard W3C technologies (OWL, SHACL, SPARQL), it is natively compatible with [Flexo MMS](https://github.com/Open-MBEE/flexo-mms-deployment) — the Model Management System developed by the [OpenMBEE](https://www.openmbee.org/) community.
146+
147+
### Why the fit is natural
148+
149+
Flexo MMS is a version-controlled model repository that speaks RDF natively. A KC instance graph is already a valid RDF dataset, so the integration path is direct:
150+
151+
| KC concept | MMS equivalent | Notes |
152+
|---|---|---|
153+
| `kc:Complex` (instance graph) | MMS model/branch | A KC export is a self-contained RDF graph that can be committed as an MMS model revision |
154+
| `kc:boundedBy`, `kc:hasElement` | MMS element relationships | Topological structure is expressed as standard RDF triples |
155+
| SHACL shapes (`kc_core_shapes.ttl` + user shapes) | MMS validation profiles | Shapes can be registered in MMS to enforce KC constraints on committed models |
156+
| `kc:uri` | MMS element cross-references | Provides traceability from KC elements to external artifacts (files, documents, URIs) |
157+
| JSON-LD export (`dump_graph(format="json-ld")`) | MMS ingest format | JSON-LD is the primary API format for Flexo MMS |
158+
159+
### Integration patterns
160+
161+
**Push to MMS:** Export a KC instance via `kc.export()` or `dump_graph(format="json-ld")`, then commit to a Flexo MMS repository via its REST API. The OWL ontology and SHACL shapes can be committed alongside the instance data, enabling MMS-side validation.
162+
163+
**Pull from MMS:** Retrieve a model revision as JSON-LD from Flexo MMS, then load it into a KC instance via `load_graph(kc, "model.jsonld")`. The KC's SHACL verification (`kc.verify()`) ensures the imported data satisfies all topological and ontological constraints.
164+
165+
**Version control:** MMS provides branching, diffing, and merge capabilities at the RDF triple level. KC's `ComplexDiff` and `ComplexSequence` classes complement this by providing simplicial-complex-aware diffing (element-level adds/removes rather than triple-level changes).
166+
167+
### What KC adds beyond MMS
168+
169+
Flexo MMS manages RDF models generically — it stores, versions, and queries them but does not enforce simplicial complex structure. KC adds the topological layer: boundary-closure, closed-triangle constraints, typed simplicial hierarchy, and algebraic topology computations (Betti numbers, Hodge decomposition). Together, MMS provides the model management infrastructure and KC provides the mathematical structure.
170+
171+
### Reference
172+
173+
OpenMBEE (Open Model-Based Engineering Environment) is an open-source community developing tools for model-based systems engineering. Flexo MMS is its core model management system. See [openmbee.org](https://www.openmbee.org/) and [github.com/Open-MBEE](https://github.com/Open-MBEE).
174+
175+
---
176+
177+
## Deployment Architecture
178+
179+
The internal design described above (2x2 map, component layers, static resources) is the library's foundation. In practice, a knowledge complex is deployed through a stack of five layers, each building on the one below:
180+
181+
```
182+
┌─────────────────────────────────────────────────────────────┐
183+
│ 5. LLM Tool Integration │
184+
│ Register KC operations as callable tools for a language │
185+
│ model. The complex serves as a deterministic expert │
186+
│ system — the LLM navigates, queries, and analyzes via │
187+
│ tool calls; the KC guarantees topological correctness │
188+
│ and returns structured, verifiable results. │
189+
├─────────────────────────────────────────────────────────────┤
190+
│ 4. MCP Server │
191+
│ Model Context Protocol server exposing KC as tools for │
192+
│ AI assistants (Claude, etc.). Each KC operation becomes │
193+
│ a tool: add_vertex, boundary, betti_numbers, audit, etc. │
194+
├─────────────────────────────────────────────────────────────┤
195+
│ 3. Microservice (REST API) │
196+
│ Python-hosted service exposing KC operations over HTTP. │
197+
│ CRUD for elements, SPARQL query execution, SHACL │
198+
│ verification, algebraic topology analysis, export/import.│
199+
├─────────────────────────────────────────────────────────────┤
200+
│ 2. Concrete Knowledge Complex │
201+
│ An instance using a specific ontology. Typed vertices, │
202+
│ edges, and faces with attributes. SHACL-verified on │
203+
│ every write. Serialized as RDF (Turtle, JSON-LD). │
204+
│ Versioned via Flexo MMS or git. │
205+
├─────────────────────────────────────────────────────────────┤
206+
│ 1. KC-Compatible Ontology │
207+
│ OWL class hierarchy extending kc:Vertex/Edge/Face. │
208+
│ SHACL shapes for attribute constraints. Publicly hosted │
209+
│ at persistent URIs (w3id.org). Dereferenceable — tools │
210+
│ can fetch the ontology and understand the type system. │
211+
└─────────────────────────────────────────────────────────────┘
212+
```
213+
214+
### Layer 1: Ontology
215+
216+
A KC-compatible ontology is an OWL ontology whose classes extend `kc:Vertex`, `kc:Edge`, and `kc:Face`, paired with SHACL shapes for instance-level constraints. Ontologies are authored via `SchemaBuilder` and exported as standard `.ttl` files. For public use, the ontology should be hosted at a persistent URI (e.g. `https://w3id.org/kc/`) so that other systems can dereference the IRI and retrieve the OWL/SHACL definitions. The `knowledgecomplex.ontologies` package ships three reference ontologies (operations, brand, research) as starting points.
217+
218+
### Layer 2: Concrete Complex
219+
220+
A concrete knowledge complex is an RDF instance graph conforming to a specific ontology. It contains typed elements (vertices, edges, faces) with attributes, linked by `kc:boundedBy` and collected by `kc:hasElement`. SHACL verification enforces topological and ontological constraints on every write. The complex is serializable to Turtle, JSON-LD, or N-Triples and can be versioned via Flexo MMS or committed to a git repository as `.ttl` files.
221+
222+
### Layer 3: Microservice
223+
224+
A Python-hosted HTTP service wraps the `KnowledgeComplex` API in a REST interface. Typical endpoints: element CRUD, named SPARQL queries, topological operations (boundary, star, closure), algebraic topology analysis (Betti numbers, Hodge decomposition, edge PageRank), SHACL verification and audit, and schema introspection. The service loads a schema at startup and manages one or more complex instances.
225+
226+
### Layer 4: MCP Server
227+
228+
A [Model Context Protocol](https://modelcontextprotocol.io/) server exposes KC operations as tools that AI assistants can call. Each KC method becomes an MCP tool: `add_vertex`, `boundary`, `find_cliques`, `betti_numbers`, `audit`, etc. The MCP server is a thin adapter over the microservice or the library directly, translating between MCP tool calls and KC Python API calls.
229+
230+
### Layer 5: LLM Tool Integration
231+
232+
The knowledge complex is registered as a set of callable tools for a language model. The LLM uses the complex as a **deterministic expert system** — it navigates the simplicial structure, retrieves typed elements and their attributes, runs topological queries, and performs algebraic topology analysis via tool calls. The KC guarantees that every result is topologically valid and SHACL-verified. The LLM provides natural language understanding and reasoning; the KC provides structured, auditable, mathematically rigorous retrieval.
233+
234+
This separation is key: the LLM handles ambiguity, intent, and synthesis; the KC handles structure, correctness, and computation. Neither replaces the other.
235+
236+
---
237+
143238
## Namespace Conventions
144239

145240
```turtle

docs/ontology.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ The abstract SHACL shapes graph enforces instance-level constraints that exceed
2222

2323
These constraints use `sh:sparql` validators because they require cross-individual reasoning.
2424

25+
## Interoperability
26+
27+
Because KC stores all data as standard RDF and enforces constraints via W3C SHACL, instance graphs are natively compatible with RDF-based model management systems such as [Flexo MMS](https://github.com/Open-MBEE/flexo-mms-deployment) from the [OpenMBEE](https://www.openmbee.org/) community. JSON-LD export (`dump_graph(format="json-ld")`) provides the primary bridge format. See the [Interoperability section of ARCHITECTURE.md](https://github.com/blockscience/knowledgecomplex/blob/main/ARCHITECTURE.md#interoperability-flexo-mms-and-openmbee) for integration patterns.
28+
2529
## Design rationale
2630

2731
See [ARCHITECTURE.md](https://github.com/blockscience/knowledgecomplex/blob/main/ARCHITECTURE.md) for the full 2x2 responsibility map and design decisions.

knowledgecomplex/analysis.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class BoundaryMatrices:
3636
index_edge: dict[int, str]
3737
index_face: dict[int, str]
3838

39+
def __repr__(self) -> str:
40+
return (f"BoundaryMatrices(vertices={len(self.vertex_index)}, "
41+
f"edges={len(self.edge_index)}, faces={len(self.face_index)})")
42+
3943

4044
@dataclass
4145
class HodgeDecomposition:
@@ -63,6 +67,9 @@ class SweepCut:
6367
volume: int
6468
boundary_edges: int
6569

70+
def __repr__(self) -> str:
71+
return f"SweepCut(vertices={len(self.vertices)}, conductance={self.conductance:.4f})"
72+
6673

6774
@dataclass
6875
class EdgeSweepCut:
@@ -71,6 +78,9 @@ class EdgeSweepCut:
7178
conductance: float
7279
volume: int
7380

81+
def __repr__(self) -> str:
82+
return f"EdgeSweepCut(edges={len(self.edges)}, conductance={self.conductance:.4f})"
83+
7484

7585
@dataclass
7686
class HodgeAnalysisResults:
@@ -83,6 +93,10 @@ class HodgeAnalysisResults:
8393
decompositions: dict[str, HodgeDecomposition]
8494
influences: dict[str, EdgeInfluence]
8595

96+
def __repr__(self) -> str:
97+
ne = len(self.decompositions)
98+
return f"HodgeAnalysisResults(betti={self.betti}, edges={ne})"
99+
86100

87101
# ---------------------------------------------------------------------------
88102
# Weight matrices

knowledgecomplex/filtration.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ def __init__(self, kc: "KnowledgeComplex") -> None:
4343
self._kc = kc
4444
self._steps: list[frozenset[str]] = []
4545

46+
def __repr__(self) -> str:
47+
return f"Filtration(steps={len(self._steps)}, complete={self.is_complete})"
48+
4649
@property
4750
def complex(self) -> "KnowledgeComplex":
4851
"""The parent KnowledgeComplex."""

knowledgecomplex/graph.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ def __init__(self, kc: "KnowledgeComplex", id: str) -> None:
9696
self._id = id
9797
self._iri = URIRef(f"{kc._schema._base_iri}{id}")
9898

99+
def __repr__(self) -> str:
100+
try:
101+
t = self.type
102+
except ValueError:
103+
t = "?"
104+
return f"Element({self._id!r}, type={t!r})"
105+
99106
@property
100107
def id(self) -> str:
101108
return self._id
@@ -213,6 +220,10 @@ def __init__(
213220
self._defer_verification = False
214221
self._init_graph()
215222

223+
def __repr__(self) -> str:
224+
n = len(self.element_ids())
225+
return f"KnowledgeComplex(namespace={self._schema._namespace!r}, elements={n})"
226+
216227
def _init_graph(self) -> None:
217228
"""
218229
Initialize the instance graph and create the kc:Complex individual.
@@ -851,7 +862,11 @@ def boundary(self, id: str, *, type: str | None = None) -> set[str]:
851862
return self._ids_from_query(sparql)
852863

853864
def coboundary(self, id: str, *, type: str | None = None) -> set[str]:
854-
"""Return δ(id): all simplices whose boundary contains id.
865+
"""Return the cofaces of id: all simplices whose boundary contains id.
866+
867+
Computes {τ ∈ K : id ∈ ∂(τ)} — the set of (k+1)-simplices that
868+
have id as a boundary element. This is the combinatorial coface
869+
relation, not the algebraic coboundary operator δ on cochains.
855870
856871
Parameters
857872
----------

knowledgecomplex/queries/star.sparql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
#
44
# St(sigma) = {tau in K : sigma is a face of tau}
55
#
6-
# Uses the inverse property path ^kc:boundedBy* to walk zero-or-more
7-
# coboundary hops from sigma upward.
6+
# Uses kc:boundedBy* from ?star to {simplex}: since boundedBy points
7+
# downward (high-dim → low-dim), ?star can only reach {simplex} if
8+
# {simplex} is a face of ?star — exactly the star definition.
89
#
910
# Usage: substitute {simplex} with the IRI of the element.
1011
# substitute {type_filter} with a type constraint or empty string.

knowledgecomplex/schema.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ def __init__(self, namespace: str) -> None:
202202
self._queries: dict[str, str] = {} # name -> SPARQL template string
203203
self._init_graphs()
204204

205+
def __repr__(self) -> str:
206+
return f"SchemaBuilder(namespace={self._namespace!r}, types={len(self._types)})"
207+
205208
def _init_graphs(self) -> None:
206209
"""Load core OWL and SHACL static resources into internal graphs."""
207210
self._owl_graph = Graph()

0 commit comments

Comments
 (0)