Skip to content

Commit 9c76f17

Browse files
authored
Merge pull request #1 from BlockScience/dev
Built it out in prep for making repo open
2 parents a3f17bc + 5807953 commit 9c76f17

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+12420
-52
lines changed

ARCHITECTURE.md

Lines changed: 103 additions & 2 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
@@ -162,5 +257,11 @@ User namespaces are set via `SchemaBuilder(namespace="aaa")`. The URI base `http
162257
| `knowledgecomplex/schema.py` | Python API — schema authoring | `SchemaBuilder` DSL: `add_*_type`, `dump_owl`, `dump_shacl`, `export`, `load` |
163258
| `knowledgecomplex/graph.py` | Python API — instance I/O | `KnowledgeComplex`: `add_vertex`, `add_edge`, `add_face`, `query`, `dump_graph`, `export`, `load` |
164259
| `knowledgecomplex/exceptions.py` | Public exceptions | `ValidationError`, `SchemaError`, `UnknownQueryError` |
165-
| `knowledgecomplex/queries/vertices.sparql` | Framework SPARQL | Return all vertices and their types |
166-
| `knowledgecomplex/queries/coboundary.sparql` | Framework SPARQL | Inverse boundary operator |
260+
| `knowledgecomplex/io.py` | Python API — serialization | `save_graph`, `load_graph`, `dump_graph` — multi-format file I/O (Turtle, JSON-LD, N-Triples) |
261+
| `knowledgecomplex/viz.py` | Python API — visualization | Hasse diagrams (`plot_hasse`), geometric realization (`plot_geometric`), `to_networkx`, `verify_networkx` |
262+
| `knowledgecomplex/analysis.py` | Python API — algebraic topology | `betti_numbers`, `euler_characteristic`, `hodge_laplacian`, `edge_pagerank` (optional: numpy, scipy) |
263+
| `knowledgecomplex/clique.py` | Python API — clique inference | `find_cliques`, `infer_faces`, `fill_cliques` — flagification and typed face inference |
264+
| `knowledgecomplex/filtration.py` | Python API — filtrations | `Filtration` — nested subcomplex sequences, birth tracking, `from_function` |
265+
| `knowledgecomplex/diff.py` | Python API — diffs and sequences | `ComplexDiff`, `ComplexSequence` — time-varying complexes with SPARQL UPDATE export/import |
266+
| `knowledgecomplex/codecs/markdown.py` | Codec — markdown files | `MarkdownCodec` — YAML frontmatter + section-based round-trip; `verify_documents` |
267+
| `knowledgecomplex/queries/*.sparql` | Framework SPARQL | 7 templates: vertices, coboundary, boundary, star, closure, skeleton, degree |

README.md

Lines changed: 123 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,27 @@ sb.add_vertex_type("activity", attributes={"name": text()})
3838
sb.add_vertex_type("resource", attributes={"name": text()})
3939
sb.add_edge_type("performs", attributes={"role": vocab("lead", "support")})
4040
sb.add_edge_type("requires", attributes={"mode": vocab("read", "write")})
41+
sb.add_edge_type("produces", attributes={"mode": vocab("read", "write")})
42+
sb.add_edge_type("accesses", attributes={"mode": vocab("read", "write")})
4143
sb.add_edge_type("responsible", attributes={"level": vocab("owner", "steward")})
4244
sb.add_face_type("operation")
45+
sb.add_face_type("production")
4346

4447
# 2. Build an instance
4548
kc = KnowledgeComplex(schema=sb)
46-
kc.add_vertex("alice", type="actor", name="Alice")
47-
kc.add_vertex("etl-run", type="activity", name="Daily ETL")
48-
kc.add_vertex("dataset", type="resource", name="Sales DB")
49+
kc.add_vertex("alice", type="actor", name="Alice")
50+
kc.add_vertex("etl-run", type="activity", name="Daily ETL")
51+
kc.add_vertex("dataset1", type="resource", name="JSON Records")
52+
kc.add_vertex("dataset2", type="resource", name="Sales DB")
4953

50-
kc.add_edge("e1", type="performs", vertices={"alice", "etl-run"}, role="lead")
51-
kc.add_edge("e2", type="requires", vertices={"etl-run", "dataset"}, mode="write")
52-
kc.add_edge("e3", type="responsible", vertices={"alice", "dataset"}, level="owner")
54+
kc.add_edge("e1", type="performs", vertices={"alice", "etl-run"}, role="lead")
55+
kc.add_edge("e2", type="requires", vertices={"etl-run", "dataset1"}, mode="read")
56+
kc.add_edge("e3", type="produces", vertices={"etl-run", "dataset2"}, mode="write")
57+
kc.add_edge("e4", type="accesses", vertices={"alice", "dataset1"}, mode="read")
58+
kc.add_edge("e5", type="responsible", vertices={"alice", "dataset2"}, level="owner")
5359

54-
kc.add_face("op1", type="operation", edges={"e1", "e2", "e3"})
60+
kc.add_face("op1", type="operation", boundary=["e1", "e2", "e4"])
61+
kc.add_face("prod1", type="production", boundary=["e1", "e3", "e5"])
5562

5663
# 3. Query
5764
df = kc.query("vertices") # built-in SPARQL template
@@ -61,17 +68,120 @@ print(df)
6168
print(kc.dump_graph()) # Turtle string
6269
```
6370

64-
## The `kc:uri` attribute
71+
See [`examples/`](examples/) for 10 runnable examples covering all features below.
72+
73+
## Topological queries
74+
75+
Every `KnowledgeComplex` has methods for the standard simplicial complex operations.
76+
All return `set[str]` for natural set algebra:
77+
78+
```python
79+
kc.boundary("face-1") # {e1, e2, e3} — direct boundary
80+
kc.star("alice") # all simplices containing alice
81+
kc.link("alice") # Cl(St) \ St — the horizon around alice
82+
kc.closure({"e1", "e2"}) # smallest subcomplex containing these edges
83+
kc.degree("alice") # number of incident edges
84+
85+
# Set algebra composes naturally
86+
shared = kc.star("alice") & kc.star("bob")
87+
```
88+
89+
All operators accept an optional `type=` filter for OWL-subclass-aware filtering.
90+
91+
## Clique inference
92+
93+
Discover higher-order structure from the edge graph:
94+
95+
```python
96+
from knowledgecomplex import find_cliques, infer_faces
97+
98+
triangles = find_cliques(kc, k=3) # pure query — what triangles exist?
99+
infer_faces(kc, "operation") # fill in all triangles as typed faces
100+
infer_faces(kc, "team", edge_type="collab") # restrict to specific edge types
101+
```
102+
103+
## Visualization
104+
105+
Two complementary views — Hasse diagrams (all elements as nodes, boundary as directed arrows) and geometric realization (vertices as 3D points, edges as lines, faces as filled triangles):
106+
107+
```python
108+
from knowledgecomplex import plot_hasse, plot_geometric
109+
110+
fig, ax = plot_hasse(kc) # directed boundary graph, type-colored
111+
fig, ax = plot_geometric(kc) # 3D triangulation with matplotlib
112+
```
65113

66-
Every element (vertex, edge, or face) can carry an optional `kc:uri` property pointing to its source file:
114+
Export to NetworkX for further analysis:
67115

68116
```python
69-
kc.add_vertex("alice", type="actor", uri="file:///actors/alice.md", name="Alice")
70-
kc.add_edge("e1", type="performs", vertices={"alice", "etl-run"},
71-
uri="file:///edges/e1.md", role="lead")
117+
from knowledgecomplex import to_networkx, verify_networkx
118+
119+
G = to_networkx(kc) # nx.DiGraph with exact degree invariants
120+
verify_networkx(G) # validate cardinality + closed-triangle constraints
72121
```
73122

74-
SHACL enforces at-most-one `kc:uri` per element. This is useful for domain applications where each element corresponds to an actual document or record.
123+
## Algebraic topology
124+
125+
Betti numbers, Euler characteristic, Hodge Laplacian, and edge PageRank (requires `pip install knowledgecomplex[analysis]`):
126+
127+
```python
128+
from knowledgecomplex import betti_numbers, euler_characteristic, edge_pagerank
129+
130+
betti = betti_numbers(kc) # [beta_0, beta_1, beta_2]
131+
chi = euler_characteristic(kc) # V - E + F
132+
pr = edge_pagerank(kc, "e1") # personalized edge PageRank vector
133+
```
134+
135+
## Filtrations and time-varying complexes
136+
137+
Filtrations model strictly growing subcomplexes. Diffs model arbitrary add/remove sequences:
138+
139+
```python
140+
from knowledgecomplex import Filtration, ComplexDiff, ComplexSequence
141+
142+
filt = Filtration(kc)
143+
filt.append_closure({"v1", "v2", "e12"}) # Q0: founders
144+
filt.append_closure({"v3", "e23", "face1"}) # Q1: first triangle
145+
print(filt.birth("face1")) # 1
146+
147+
diff = ComplexDiff().add_vertex("eve", type="Person").remove("old-edge")
148+
diff.apply(kc) # mutate the complex
149+
print(diff.to_sparql(kc)) # export as SPARQL UPDATE
150+
```
151+
152+
## I/O and codecs
153+
154+
Multi-format serialization and round-trip with external files:
155+
156+
```python
157+
from knowledgecomplex import save_graph, load_graph, MarkdownCodec
158+
159+
save_graph(kc, "data.jsonld", format="json-ld")
160+
load_graph(kc, "data.ttl") # additive loading
161+
162+
codec = MarkdownCodec(frontmatter_attrs=["name"], section_attrs=["notes"])
163+
kc.register_codec("Paper", codec)
164+
kc.element("paper-1").compile() # KC -> markdown file
165+
kc.element("paper-1").decompile() # markdown file -> KC
166+
```
167+
168+
## Constraint escalation
169+
170+
Escalate topological queries to SHACL constraints enforced on every write:
171+
172+
```python
173+
sb.add_topological_constraint(
174+
"requirement", "coboundary",
175+
target_type="verification",
176+
predicate="min_count", min_count=1,
177+
message="Every requirement must have at least one verification edge",
178+
)
179+
```
180+
181+
## The `kc:uri` attribute
182+
183+
Every element can carry an optional `kc:uri` property pointing to its source file.
184+
SHACL enforces at-most-one `kc:uri` per element.
75185

76186
## Architecture
77187

docs/api/analysis.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
::: knowledgecomplex.analysis

docs/api/clique.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
::: knowledgecomplex.clique

docs/api/codecs.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
::: knowledgecomplex.codecs.markdown

docs/api/diff.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
::: knowledgecomplex.diff

docs/api/filtration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
::: knowledgecomplex.filtration

docs/api/io.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
::: knowledgecomplex.io

docs/api/viz.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
::: knowledgecomplex.viz

0 commit comments

Comments
 (0)