yog

Yog - A comprehensive graph algorithm library for Gleam.

Provides efficient implementations of classic graph algorithms with a clean, functional API.

Quick Start

import yog
import yog/pathfinding
import gleam/int

pub fn main() {
  let graph =
    yog.directed()
    |> yog.add_node(1, "Start")
    |> yog.add_node(2, "Middle")
    |> yog.add_node(3, "End")
    |> yog.add_edge(from: 1, to: 2, with: 5)
    |> yog.add_edge(from: 2, to: 3, with: 3)
    |> yog.add_edge(from: 1, to: 3, with: 10)

  case pathfinding.shortest_path(
    in: graph,
    from: 1,
    to: 3,
    with_zero: 0,
    with_add: int.add,
    with_compare: int.compare
  ) {
    Some(path) -> {
      // Path(nodes: [1, 2, 3], total_weight: 8)
      io.println("Shortest path found!")
    }
    None -> io.println("No path exists")
  }
}

Modules

Core

Algorithms

Data Structures

Transformations

Visualization

Features

Types

pub type Graph(node_data, edge_data) =
  model.Graph(node_data, edge_data)
pub type GraphType =
  model.GraphType
pub type NodeId =
  Int

Values

pub fn add_edge(
  graph: model.Graph(n, e),
  from src: Int,
  to dst: Int,
  with weight: e,
) -> model.Graph(n, e)

Adds an edge to the graph with the given weight.

For directed graphs, adds a single edge from src to dst. For undirected graphs, adds edges in both directions.

Example

graph
|> yog.add_edge(from: 1, to: 2, with: 10)
pub fn add_node(
  graph: model.Graph(n, e),
  id: Int,
  data: n,
) -> model.Graph(n, e)

Adds a node to the graph with the given ID and data. If a node with this ID already exists, its data will be replaced.

Example

graph
|> yog.add_node(1, "Node A")
|> yog.add_node(2, "Node B")
pub fn add_simple_edge(
  graph: model.Graph(n, Int),
  from src: Int,
  to dst: Int,
) -> model.Graph(n, Int)

Adds a simple edge with weight 1.

This is a convenience function for graphs with integer weights where a default weight of 1 is appropriate (e.g., unweighted graphs, hop counts).

Example

graph
|> yog.add_simple_edge(from: 1, to: 2)
|> yog.add_simple_edge(from: 2, to: 3)
// Both edges have weight 1
pub fn add_unweighted_edge(
  graph: model.Graph(n, Nil),
  from src: Int,
  to dst: Int,
) -> model.Graph(n, Nil)

Adds an unweighted edge to the graph.

This is a convenience function for graphs where edges have no meaningful weight. Uses Nil as the edge data type.

Example

let graph: Graph(String, Nil) = yog.directed()
  |> yog.add_node(1, "A")
  |> yog.add_node(2, "B")
  |> yog.add_unweighted_edge(from: 1, to: 2)
pub fn all_nodes(graph: model.Graph(n, e)) -> List(Int)

Returns all unique node IDs that have edges in the graph.

pub fn directed() -> model.Graph(n, e)

Creates a new empty directed graph.

This is a convenience function that’s equivalent to yog.new(Directed), but requires only a single import.

Example

import yog

let graph =
  yog.directed()
  |> yog.add_node(1, "Start")
  |> yog.add_node(2, "End")
  |> yog.add_edge(from: 1, to: 2, with: 10)
pub fn neighbors(
  graph: model.Graph(n, e),
  id: Int,
) -> List(#(Int, e))

Gets all nodes connected to the given node, regardless of direction. For undirected graphs, this is equivalent to successors. For directed graphs, this combines successors and predecessors.

pub fn new(graph_type: model.GraphType) -> model.Graph(n, e)

Creates a new empty graph of the specified type.

Example

import yog
import yog/model.{Directed}

let graph = yog.new(Directed)
pub fn predecessors(
  graph: model.Graph(n, e),
  id: Int,
) -> List(#(Int, e))

Gets nodes you came FROM to reach the given node (predecessors). Returns a list of tuples containing the source node ID and edge data.

pub fn successor_ids(
  graph: model.Graph(n, e),
  id: Int,
) -> List(Int)

Returns just the NodeIds of successors (without edge data). Convenient for traversal algorithms that only need the IDs.

pub fn successors(
  graph: model.Graph(n, e),
  id: Int,
) -> List(#(Int, e))

Gets nodes you can travel TO from the given node (successors). Returns a list of tuples containing the destination node ID and edge data.

pub fn undirected() -> model.Graph(n, e)

Creates a new empty undirected graph.

This is a convenience function that’s equivalent to yog.new(Undirected), but requires only a single import.

Example

import yog

let graph =
  yog.undirected()
  |> yog.add_node(1, "A")
  |> yog.add_node(2, "B")
  |> yog.add_edge(from: 1, to: 2, with: 5)
Search Document