Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

Expand Down
4 changes: 2 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ This separation is key: the LLM handles ambiguity, intent, and synthesis; the KC
## Namespace Conventions

```turtle
@prefix kc: <https://example.org/kc#> . # core framework
@prefix kcs: <https://example.org/kc/shape#> . # core shapes
@prefix kc: <https://w3id.org/kc#> . # core framework
@prefix kcs: <https://w3id.org/kc/shape#> . # core shapes
@prefix aaa: <https://example.org/aaa#> . # user namespace (example)
@prefix aaas: <https://example.org/aaa/shape#> .# user shapes (example)
```
Expand Down
67 changes: 33 additions & 34 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,40 @@ pip install -e ".[dev]"

## Quick start

Load a pre-built complex, discover hidden structure, and extend it:

```python
from knowledgecomplex import KnowledgeComplex, find_cliques, betti_numbers

# 1. Load a pre-built complex (vertices and edges, no faces yet)
kc = KnowledgeComplex.load("examples/01_quickstart/data/pipeline")

# 2. Discover triangles hiding in the edge graph
triangles = find_cliques(kc, k=3)
print(f"Found {len(triangles)} triangles") # 2

# 3. Check topology — independent cycles exist
print(betti_numbers(kc)) # [1, 2, 0] — two cycles

# 4. Declare face types and fill them in
from knowledgecomplex import infer_faces
kc._schema.add_face_type("operation")
infer_faces(kc, "operation")

# 5. Cycles are now filled
print(betti_numbers(kc)) # [1, 0, 0] — no more cycles

# 6. Visualize
from knowledgecomplex import plot_hasse, plot_geometric
fig, ax = plot_hasse(kc)
fig, ax = plot_geometric(kc)
```

For building schemas from scratch, see [`examples/02_construction/`](https://github.com/blockscience/knowledgecomplex/tree/main/examples/02_construction). Three pre-built ontologies ship with the package:

```python
from knowledgecomplex import SchemaBuilder, KnowledgeComplex, vocab, text

# 1. Define a schema
sb = SchemaBuilder(namespace="ex")
sb.add_vertex_type("actor", attributes={"name": text()})
sb.add_vertex_type("activity", attributes={"name": text()})
sb.add_vertex_type("resource", attributes={"name": text()})
sb.add_edge_type("performs", attributes={"role": vocab("lead", "support")})
sb.add_edge_type("requires", attributes={"mode": vocab("read", "write")})
sb.add_edge_type("produces", attributes={"mode": vocab("read", "write")})
sb.add_edge_type("accesses", attributes={"mode": vocab("read", "write")})
sb.add_edge_type("responsible", attributes={"level": vocab("owner", "steward")})
sb.add_face_type("operation")
sb.add_face_type("production")

# 2. Build an instance
kc = KnowledgeComplex(schema=sb)
kc.add_vertex("alice", type="actor", name="Alice")
kc.add_vertex("etl-run", type="activity", name="Daily ETL")
kc.add_vertex("dataset1", type="resource", name="JSON Records")
kc.add_vertex("dataset2", type="resource", name="Sales DB")

kc.add_edge("e1", type="performs", vertices={"alice", "etl-run"}, role="lead")
kc.add_edge("e2", type="requires", vertices={"etl-run", "dataset1"}, mode="read")
kc.add_edge("e3", type="produces", vertices={"etl-run", "dataset2"}, mode="write")
kc.add_edge("e4", type="accesses", vertices={"alice", "dataset1"}, mode="read")
kc.add_edge("e5", type="responsible", vertices={"alice", "dataset2"}, level="owner")

kc.add_face("op1", type="operation", boundary=["e1", "e2", "e4"])
kc.add_face("prod1", type="production", boundary=["e1", "e3", "e5"])

# 3. Query
df = kc.query("vertices") # built-in SPARQL template
print(df)
from knowledgecomplex.ontologies import operations, brand, research
sb = brand.schema() # audience/theme with resonance, interplay, overlap
```

See the [examples/](https://github.com/blockscience/knowledgecomplex/tree/main/examples) directory for 10 runnable examples.
Expand Down
4 changes: 2 additions & 2 deletions examples/01_quickstart/data/pipeline/instance.ttl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@prefix ex: <https://example.org/ex#> .
@prefix kc: <https://example.org/kc#> .
@prefix kc: <https://w3id.org/kc#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
Expand Down Expand Up @@ -38,7 +38,7 @@ ex:role a owl:DatatypeProperty ;
rdfs:domain ex:performs ;
rdfs:range xsd:string .

<https://example.org/kc> a owl:Ontology ;
<https://w3id.org/kc> a owl:Ontology ;
rdfs:label "Knowledge Complex Core Ontology" ;
rdfs:comment "Abstract topological backbone: Element, Vertex, Edge, Face, Complex." .

Expand Down
4 changes: 2 additions & 2 deletions examples/01_quickstart/data/pipeline/ontology.ttl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@prefix ex: <https://example.org/ex#> .
@prefix kc: <https://example.org/kc#> .
@prefix kc: <https://w3id.org/kc#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
Expand Down Expand Up @@ -45,7 +45,7 @@ ex:role a owl:DatatypeProperty ;
rdfs:domain ex:performs ;
rdfs:range xsd:string .

<https://example.org/kc> a owl:Ontology ;
<https://w3id.org/kc> a owl:Ontology ;
rdfs:label "Knowledge Complex Core Ontology" ;
rdfs:comment "Abstract topological backbone: Element, Vertex, Edge, Face, Complex." .

Expand Down
10 changes: 5 additions & 5 deletions examples/01_quickstart/data/pipeline/shapes.ttl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@prefix ex: <https://example.org/ex#> .
@prefix exs: <https://example.org/ex/shape#> .
@prefix kc: <https://example.org/kc#> .
@prefix kcs: <https://example.org/kc/shape#> .
@prefix kc: <https://w3id.org/kc#> .
@prefix kcs: <https://w3id.org/kc/shape#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
Expand Down Expand Up @@ -83,7 +83,7 @@ kcs:ComplexShape a sh:NodeShape ;
each of its boundedBy targets must also be a hasElement of the complex.""" ;
sh:message "Complex is not closed under the boundary operator: an element's boundary element is missing from the complex." ;
sh:select """
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
SELECT $this WHERE {
$this kc:hasElement ?elem .
?elem kc:boundedBy ?boundary .
Expand All @@ -106,7 +106,7 @@ kcs:EdgeShape a sh:NodeShape ;
rdfs:comment "Edge boundary vertices must be distinct individuals." ;
sh:message "Edge boundary vertices must not be the same vertex." ;
sh:select """
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
SELECT $this WHERE {
$this kc:boundedBy ?v .
}
Expand Down Expand Up @@ -141,7 +141,7 @@ kcs:FaceShape a sh:NodeShape ;
""" ;
sh:message "Face boundary edges do not form a closed triangle over shared vertices." ;
sh:select """
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
SELECT $this WHERE {
$this kc:boundedBy ?e1 ;
kc:boundedBy ?e2 ;
Expand Down
6 changes: 6 additions & 0 deletions knowledgecomplex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
# Internal dependencies: rdflib, pyshacl, owlrl
# These are never re-exported. The public API is schema.py and graph.py only.

from importlib.metadata import version, PackageNotFoundError
try:
__version__ = version("knowledgecomplex")
except PackageNotFoundError:
__version__ = "unknown"

from knowledgecomplex.schema import SchemaBuilder, vocab, text, TextDescriptor, Codec
from knowledgecomplex.graph import KnowledgeComplex, Element
from knowledgecomplex.filtration import Filtration
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
if TYPE_CHECKING:
from knowledgecomplex.graph import KnowledgeComplex

_KC = Namespace("https://example.org/kc#")
_KC = Namespace("https://w3id.org/kc#")


class ComplexDiff:
Expand Down
8 changes: 4 additions & 4 deletions knowledgecomplex/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
_FRAMEWORK_QUERIES_DIR = Path(__file__).parent / "queries"

# Internal namespace constants
_KC = Namespace("https://example.org/kc#")
_KC = Namespace("https://w3id.org/kc#")


def _load_query_templates(
Expand Down Expand Up @@ -744,7 +744,7 @@ def element_ids(self, type: str | None = None) -> list[str]:
sparql = f"""
SELECT ?elem WHERE {{
?elem a/rdfs:subClassOf* <{type_iri}> .
<{self._complex_iri}> <https://example.org/kc#hasElement> ?elem .
<{self._complex_iri}> <https://w3id.org/kc#hasElement> ?elem .
}}
"""
results = self._instance_graph.query(
Expand Down Expand Up @@ -881,7 +881,7 @@ def coboundary(self, id: str, *, type: str | None = None) -> set[str]:
"""
tf = self._type_filter_clause("coboundary", type)
sparql = f"""\
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?coboundary WHERE {{
?coboundary kc:boundedBy <{self._iri(id)}> .
Expand Down Expand Up @@ -938,7 +938,7 @@ def closure(self, ids: str | set[str], *, type: str | None = None) -> set[str]:
values = " ".join(f"(<{self._iri(i)}>)" for i in ids)
tf = self._type_filter_clause("closure", type)
sparql = f"""\
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?closure WHERE {{
VALUES (?sigma) {{ {values} }}
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/ontologies/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Once your persistent URI is live, use it as your namespace:

```python
sb = SchemaBuilder(namespace="mydom")
# Currently generates: https://example.org/mydom#
# Currently generates: https://example.org/mydom# (user namespace)
# For production: update _base_iri to your w3id.org URI
```

Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/queries/boundary.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Usage: substitute {simplex} with the IRI of the element.
# substitute {type_filter} with a type constraint or empty string.

PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?boundary WHERE {
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/queries/closure.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Usage: substitute {simplex} with the IRI of the element.
# substitute {type_filter} with a type constraint or empty string.

PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?closure WHERE {
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/queries/coboundary.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#
# Usage: substitute {simplex} with the IRI of the element.

PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>

SELECT ?coboundary WHERE {
?coboundary kc:boundedBy {simplex} .
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/queries/degree.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# Usage: substitute {simplex} with the IRI of the vertex.

PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>

SELECT (COUNT(?edge) AS ?degree) WHERE {
?edge kc:boundedBy {simplex} .
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/queries/skeleton.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Usage: substitute {complex} with the IRI of the kc:Complex individual.
# substitute {dim_classes} with a UNION of type constraints.

PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?elem WHERE {
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/queries/star.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Usage: substitute {simplex} with the IRI of the element.
# substitute {type_filter} with a type constraint or empty string.

PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?star WHERE {
Expand Down
2 changes: 1 addition & 1 deletion knowledgecomplex/queries/vertices.sparql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# knowledgecomplex/queries/vertices.sparql
# Return all vertex individuals and their types.

PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

Expand Down
4 changes: 2 additions & 2 deletions knowledgecomplex/resources/kc_core.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix kc: <https://example.org/kc#> .
@prefix kc: <https://w3id.org/kc#> .

<https://example.org/kc>
<https://w3id.org/kc>
a owl:Ontology ;
rdfs:label "Knowledge Complex Core Ontology" ;
rdfs:comment "Abstract topological backbone: Element, Vertex, Edge, Face, Complex." .
Expand Down
10 changes: 5 additions & 5 deletions knowledgecomplex/resources/kc_core_shapes.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix kc: <https://example.org/kc#> .
@prefix kcs: <https://example.org/kc/shape#> .
@prefix kc: <https://w3id.org/kc#> .
@prefix kcs: <https://w3id.org/kc/shape#> .

# ---------------------------------------------------------------------------
# ElementShape — superstructure constraint: kc:uri is optional, at-most-one
Expand Down Expand Up @@ -84,7 +84,7 @@ kcs:EdgeShape
rdfs:comment "Edge boundary vertices must be distinct individuals." ;
sh:message "Edge boundary vertices must not be the same vertex." ;
sh:select """
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
SELECT $this WHERE {
$this kc:boundedBy ?v .
}
Expand Down Expand Up @@ -128,7 +128,7 @@ kcs:FaceShape
""" ;
sh:message "Face boundary edges do not form a closed triangle over shared vertices." ;
sh:select """
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
SELECT $this WHERE {
$this kc:boundedBy ?e1 ;
kc:boundedBy ?e2 ;
Expand Down Expand Up @@ -179,7 +179,7 @@ kcs:ComplexShape
each of its boundedBy targets must also be a hasElement of the complex.""" ;
sh:message "Complex is not closed under the boundary operator: an element's boundary element is missing from the complex." ;
sh:select """
PREFIX kc: <https://example.org/kc#>
PREFIX kc: <https://w3id.org/kc#>
SELECT $this WHERE {
$this kc:hasElement ?elem .
?elem kc:boundedBy ?boundary .
Expand Down
8 changes: 4 additions & 4 deletions knowledgecomplex/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
_CORE_SHAPES = _RESOURCES / "kc_core_shapes.ttl"

# Internal namespace constants
_KC = Namespace("https://example.org/kc#")
_KCS = Namespace("https://example.org/kc/shape#")
_KC = Namespace("https://w3id.org/kc#")
_KCS = Namespace("https://w3id.org/kc/shape#")
_SH = Namespace("http://www.w3.org/ns/shacl#")


Expand Down Expand Up @@ -861,7 +861,7 @@ def _build_topo_sparql(
)

return (
f"PREFIX kc: <https://example.org/kc#>\n"
f"PREFIX kc: <https://w3id.org/kc#>\n"
f"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
f"SELECT ?{result_var} WHERE {{\n"
f" {pattern}\n"
Expand Down Expand Up @@ -1000,7 +1000,7 @@ def add_topological_constraint(
# Wrap pattern in OPTIONAL so GROUP BY produces a row even when
# there are zero matches (otherwise HAVING never fires for empty results)
sparql = (
f"PREFIX kc: <https://example.org/kc#>\n"
f"PREFIX kc: <https://w3id.org/kc#>\n"
f"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
f"SELECT $this WHERE {{\n"
f" OPTIONAL {{ {pattern} }}\n"
Expand Down
7 changes: 7 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ nav:
- API Reference:
- Schema: api/schema.md
- Graph: api/graph.md
- Visualization: api/viz.md
- Algebraic Topology: api/analysis.md
- Clique Inference: api/clique.md
- Filtrations: api/filtration.md
- Diffs & Sequences: api/diff.md
- File I/O: api/io.md
- Codecs: api/codecs.md
- Exceptions: api/exceptions.md
Loading
Loading