Skip to content

Add graph theory subsystem (src/graph/)#13

Draft
msollami wants to merge 1 commit into
stblake:mainfrom
msollami:graph-subsystem
Draft

Add graph theory subsystem (src/graph/)#13
msollami wants to merge 1 commit into
stblake:mainfrom
msollami:graph-subsystem

Conversation

@msollami

@msollami msollami commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a Mathematica-compatible graph theory subsystem (src/graph/) to
Mathilda, modelled on the Wolfram Language and mirroring the existing
src/linalg/ layout (one builtin per translation unit, registered via
graph_init()). Graphs are ordinary Expr trees —
Graph[List[verts], List[edges]] with each edge a DirectedEdge[u, v] or
UndirectedEdge[u, v] — so the generic tools (Part, Map, ReplaceAll,
pattern matching) work on them unchanged. Rule/-> and TwoWayRule/<->
are accepted as parse-time sugar and normalised on construction.

Builds cleanly under the existing toolchain (-std=c99 -Wall -Wextra,
USE_GRAPHICS/USE_LAPACK/USE_MPFR/USE_ECM) with no changes to any
existing subsystem's behaviour. PageRank and KatzCentrality are computed
exactly by assembling a rational matrix and calling the existing
LinearSolve.

Changes

  • src/graph/ (new, 103 files): construction/predicates (Graph, GraphQ,
    DirectedGraphQ, TreeGraphQ, BipartiteQ, ConnectedGraphQ, …); queries
    (VertexList, EdgeList, VertexCount, VertexDegree, DegreeSequence,
    AdjacencyList, GraphDensity, …); matrix views (AdjacencyMatrix,
    IncidenceMatrix, KirchhoffMatrix, DistanceMatrix); structural ops
    (GraphComplement, GraphUnion, GraphProduct, LineGraph,
    TransitiveClosureGraph, vertex/edge add/delete/contract, …); generators
    (CompleteGraph, CycleGraph, CirculantGraph, GeneralizedPetersenGraph,
    PrismGraph, RandomGraph, …); algorithms (FindShortestPath,
    ConnectedComponents, FindSpanningTree, VertexConnectivity,
    FindEulerianCycle, FindHamiltonianCycle, FindClique,
    FindVertexCover, FindGraphMatching, FindVertexColoring,
    ChromaticNumber, ChromaticPolynomial, …); centrality (PageRank,
    KatzCentrality, BetweennessCentrality, ClosenessCentrality,
    clustering coefficients); and drawing (GraphPlotGraphics,
    Graph3D/GraphPlot3DGraphics3D, HighlightGraph).
  • src/core.c: register graph_init() after graphics_init().
  • src/sym_names.{c,h}: intern Graph/Graph3D/DirectedEdge/
    UndirectedEdge/TwoWayRule and graph-drawing option symbols.
  • src/parse.c: add the <-> (TwoWayRule) operator at Rule precedence.
  • src/print.c: print edges infix (u -> v / u <-> v) and a bare Graph
    as a terse Graph[<n vertices, m edges>] summary; InputForm/FullForm
    round-trip through the literal constructor.
  • src/graphics/graphics_json.c: graph-diagram serialisation
    (graphics3d_to_plotly_json, diagram mode for Disk/Point/Text); a bare
    valid Graph/Graph3D result auto-renders like Graphics.
  • makefile: compile src/graph/*.c, add -I./src/graph.
  • tests/CMakeLists.txt: build the graph_tests target.
  • Docs: new docs/spec/builtins/graphs.md; index row in Mathilda_spec.md;
    layout/init notes in SPEC.md; changelog entry under
    docs/spec/changelog/2026-06-29.md.

Testing

  • make -j — clean build, ./Mathilda links with graphics/LAPACK/MPFR/ECM,
    zero warnings from src/graph/.
  • cd tests && cmake -B build && cmake --build build --target graph_tests then
    ./build/graph_testsall graph tests pass (1000+ assert_eval_eq
    assertions across ~90 test functions, exercising parse → eval → print,
    including <->/-> edge sugar).

JIRA Ticket

N/A

Introduce a Mathematica-compatible graph subsystem modelled on the
Wolfram Language, mirroring the src/linalg/ layout (one builtin per
translation unit, registered via graph_init()).

Graphs are ordinary Expr trees -- Graph[List[verts], List[edges]] with
each edge a DirectedEdge[u, v] or UndirectedEdge[u, v] -- so the generic
tools (Part, Map, ReplaceAll, pattern matching) work on them unchanged.
Rule/-> and TwoWayRule/<-> are accepted as parse-time sugar and
normalised on construction; <-> is added to the parser at Rule
precedence. The constructor validates structure (2-arg edges, endpoints
present, no self-loops, no parallel edges) and leaves malformed input
unevaluated.

Builtins span construction/predicates, queries, matrix views
(Adjacency/Incidence/Kirchhoff/Distance), structural operations,
generators, algorithms (shortest path, components, spanning tree,
connectivity, Euler/Hamilton, cliques, independent sets, covers,
matching, colouring, chromatic number/polynomial), centrality
(PageRank, Katz, betweenness, closeness, degree, clustering) and drawing
(GraphPlot -> Graphics, Graph3D/GraphPlot3D -> Graphics3D, HighlightGraph).

PageRank and KatzCentrality are computed exactly: a rational
transition/resolvent matrix is assembled and solved with the existing
LinearSolve, yielding exact rationals rather than floating-point
approximations.

Integration:
- src/core.c registers graph_init() after graphics_init().
- src/sym_names.{c,h} intern the Graph/edge/option symbols.
- src/parse.c adds the <-> (TwoWayRule) operator.
- src/print.c prints edges infix and a bare Graph as a terse
  Graph[<n vertices, m edges>] summary (InputForm/FullForm still
  round-trip through the literal constructor).
- src/graphics/graphics_json.c gains graph-diagram serialisation
  (graphics3d_to_plotly_json, diagram mode for Disk/Point/Text); a bare
  valid Graph/Graph3D result auto-renders in the REPL and notebook
  sidecar, the same way Graphics does.
- makefile compiles src/graph/*.c and adds -I./src/graph.
- tests/CMakeLists.txt builds the graph_tests target.

Every builtin is Protected, carries a docstring, is documented in
docs/spec/builtins/graphs.md, and is covered by tests/test_graph.c.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant