Skip to content

Add graph subsystem (Graph, generators, algorithms, GraphPlot) + notebook fixes#11

Open
msollami wants to merge 4 commits into
stblake:mainfrom
msollami:feat/canvas-notebook-frontend
Open

Add graph subsystem (Graph, generators, algorithms, GraphPlot) + notebook fixes#11
msollami wants to merge 4 commits into
stblake:mainfrom
msollami:feat/canvas-notebook-frontend

Conversation

@msollami

@msollami msollami commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a graph subsystem to Mathilda — Graph as a first-class symbol with
construction, queries, matrix views, generators, algorithms, and visualization —
plus notebook fixes so GraphPlot renders as a node-link diagram and cell
copy/paste works. Graphs are ordinary Expr trees
(Graph[List[verts], List[edges]]); no new EXPR_* tag and no changes under
src/external/.

Changes

  • Graph subsystem (src/graph/, 30 builtins, one per file): construction/
    normalization (Graph), predicates (GraphQ, DirectedGraphQ,
    ConnectedGraphQ), queries (VertexList, EdgeList, counts, AdjacencyList,
    degrees), matrix views (AdjacencyMatrix, IncidenceMatrix, AdjacencyGraph
    — interop with Det/Tr/Eigenvalues), generators (CompleteGraph,
    CycleGraph, PathGraph, RandomGraph), algorithms (FindShortestPath,
    GraphDistance, connected components incl. Tarjan SCC, FindSpanningTree,
    VertexConnectivity), and GraphPlot.
  • Parser/printer: <-> (TwoWayRule) operator; infix Directed/
    UndirectedEdge printing and a terse, round-trippable Graph form.
  • Notebook renderer (graphics_json.c): serialize Disk/Point as markers
    and Text as annotations, with an equal-aspect diagram layout so GraphPlot
    draws correctly (Plot output unchanged).
  • Diagnostics (repl.c): parse errors echo the received input.
  • Notebook clipboard (src-tauri/src/lib.rs): use predefined
    Cut/Copy/Paste/Select-All/Undo/Redo menu items so cell copy/paste works on
    macOS.
  • Docs: docs/spec/builtins/graphs.md + weekly changelog; Mathilda_spec.md
    rows.

Testing

  • New tests/test_graph.c (wired into the CMake suite): normalization of all
    edge sugars, vertex derivation, GraphQ truth table, malformed-input
    rejection, query builtins, AdjacencyMatrix symmetry + AdjacencyGraph
    round-trip, generator counts/degrees, shortest paths (incl. unreachable),
    weak vs. strong components, spanning-tree edge counts, connectivity values,
    and GraphPlot structure. All pass.
  • Clean -std=c99 -Wall -Wextra build; full Desired-End-State REPL walkthrough
    matches (e.g. Eigenvalues[AdjacencyMatrix[4-cycle]] = {-1, 1, -I, I}).
  • Note: valgrind is unavailable on the dev machine (Darwin ARM64); ownership
    follows the SPEC §4 build-from-copies / paired alloc-free contract.

JIRA Ticket

N/A

msollami added 4 commits June 29, 2026 18:21
- Drag on empty canvas draws a dashed selection rectangle; on release
  any notebooks whose bounds overlap the rect become selected (blue
  outline glow matching each notebook's accent color)
- Dragging a selected notebook by its title bar moves all selected
  notebooks together by the same world-space delta
- Notebook card and minimap now use the same palette index (nb.id
  numeric suffix) so card border colors always match minimap dots
- Horizontal split-handle now stretches full cell height (align-items:
  stretch) with a 12px hit area and animated ::before visual indicator
… algorithms, visualization

Introduce a new src/graph/ subsystem making Graph a first-class symbol,
mirroring the src/linalg/ layout (one builtin per translation unit, a graph.h
of entry points, and a graph_init() registered from core_init). Graphs are
ordinary Expr trees Graph[List[verts], List[edges]] with DirectedEdge/
UndirectedEdge; no new EXPR_* tag and no changes under src/external/.

30 builtins across 19 files:
- Construction/predicates: Graph (normalizes ->/<-> and Directed/UndirectedEdge,
  derives vertices, validates, canonicalizes), GraphQ, DirectedGraphQ,
  ConnectedGraphQ.
- Query: VertexList, EdgeList, VertexCount, EdgeCount, AdjacencyList,
  VertexDegree/In/Out.
- Matrix views: AdjacencyMatrix, IncidenceMatrix, AdjacencyGraph (interop with
  Det/Tr/Eigenvalues via dense List-of-Lists).
- Generators: CompleteGraph, CycleGraph, PathGraph, RandomGraph (seeded RNG).
- Algorithms: FindShortestPath, GraphDistance, ConnectedComponents,
  WeaklyConnectedComponents, StronglyConnectedComponents (Tarjan),
  FindSpanningTree, VertexConnectivity, over a shared adjacency builder.
- Visualization: GraphPlot (circular layout -> Graphics).

Parser gains the <-> (TwoWayRule) operator; the printer renders
Directed/UndirectedEdge infix and Graph as a terse summary with a
round-trippable InputForm. Every builtin has attributes, a docstring, a
docs/spec/builtins/graphs.md entry, and changelog notes. New tests/test_graph.c
covers normalization, queries, matrix round-trips, generators, algorithms, and
GraphPlot structure; wired into the CMake suite.
The notebook's Graphics-to-Plotly serializer only handled Line and Polygon, so
GraphPlot output rendered as a bare line (vertex Disks and Text labels were
dropped, with no equal-aspect layout). Extend graphics_json.c to serialize:
- Disk/Point as marker-mode scatter traces (vertices),
- Text[label, {x,y}] as Plotly annotations (labels),
- a "diagram mode" (triggered when Disk/Text are present) using a square canvas
  with hidden axes and yaxis.scaleanchor:"x" so a circular vertex layout stays
  circular,
- sub-1e-12 coordinate snapping so floating-point dust (e.g. sin(pi)) does not
  blow up an auto-ranged axis.
Plot[] output is unchanged (no Disk/Text, so it keeps the standard axed layout).

Also make the pipe-protocol parse error self-diagnosing: it now echoes the exact
input string ("Parse error: <input>") so a stray/invisible character or bracket
mismatch in the caller's text is visible rather than opaque.
The Edit menu bound custom, unhandled items to the clipboard accelerators
(Copy Cell(s) -> Cmd+C, Paste Cell(s) -> Cmd+V, Delete Cell(s) -> Backspace).
On macOS a menu accelerator captures the key combination app-wide, so those
shortcuts never reached the focused cell editor -- and no frontend listener
handled the events, so they did nothing but block the clipboard.

Replace them with the predefined Undo/Redo/Cut/Copy/Paste/Select All menu items,
which route through the macOS responder chain to the focused text editor.
Cmd+C/X/V/A and Cmd+Z now work inside cells, and Backspace is no longer hijacked.
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