Graph

The Fossil Algorithm Graph module provides a unified, string-driven interface for executing common graph algorithms over an opaque graph representation. By decoupling algorithm selection from the underlying graph storage, it enables flexible traversal, pathfinding, connectivity, and ordering operations without exposing internal data structures. The C API emphasizes portability and minimal assumptions, while the C++ wrapper offers a lightweight, RAII-friendly façade that integrates naturally with modern C++ codebases and preserves full compatibility with the underlying C implementation.

HEADER REFERENCE #

#ifndef FOSSIL_ALGORITHM_GRAPH_H
#define FOSSIL_ALGORITHM_GRAPH_H

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

// ======================================================
// Fossil Algorithm Graph — Core Types
// ======================================================

/**
 * @brief Opaque graph handle.
 *
 * The concrete representation (adjacency list, matrix, CSR, etc.)
 * is implementation-defined and hidden from the algorithm layer.
 */
typedef struct fossil_graph fossil_graph_t;

/**
 * @brief Graph edge descriptor (optional utility).
 */
typedef struct fossil_graph_edge {
    uint64_t from;
    uint64_t to;
    double   weight;
} fossil_graph_edge_t;

/**
 * @brief Visitor callback for traversal algorithms.
 *
 * @param node_id Current node being visited.
 * @param user User-provided context pointer.
 * @return true to continue traversal, false to stop early.
 */
typedef bool (*fossil_graph_visit_fn)(uint64_t node_id, void *user);

// ======================================================
// Fossil Algorithm Graph — Exec Interface
// ======================================================

/**
 * @brief Executes a graph algorithm using string-identified options.
 *
 * Supported algorithm identifiers (implementation-defined, typical set):
 *   - Traversal: "bfs", "dfs"
 *   - Shortest path: "dijkstra", "bellman-ford", "floyd-warshall"
 *   - Connectivity: "connected", "components"
 *   - Spanning tree: "mst-prim", "mst-kruskal"
 *   - Ordering: "toposort"
 *
 * Supported graph properties:
 *   - Directed / undirected
 *   - Weighted / unweighted
 *
 * Notes:
 * - Not all algorithms require all parameters.
 * - Algorithms that require weights assume non-null edge weights.
 * - No runtime validation of graph correctness is guaranteed.
 *
 * Return values:
 *   >= 0 : algorithm-specific success code
 *   -1   : algorithm failed or target not reachable
 *   -2   : invalid input (null pointers, invalid node ids)
 *   -3   : unknown or unsupported algorithm
 *   -4   : unsupported graph properties for algorithm
 *
 * Example:
 * @code
 * fossil_algorithm_graph_exec(
 *     graph,
 *     "bfs",
 *     start_node,
 *     0,
 *     visitor,
 *     NULL
 * );
 * @endcode
 *
 * @param graph Graph handle.
 * @param algorithm_id Algorithm identifier string.
 * @param start_node Start node (if applicable).
 * @param target_node Target node (if applicable, else ignored).
 * @param visit Optional visitor callback.
 * @param user User context passed to visitor.
 * @return int Status or algorithm-specific result.
 */
int fossil_algorithm_graph_exec(
    fossil_graph_t *graph,
    const char *algorithm_id,
    uint64_t start_node,
    uint64_t target_node,
    fossil_graph_visit_fn visit,
    void *user
);

// ======================================================
// Extended Utility API
// ======================================================

/**
 * @brief Checks whether a graph algorithm is supported.
 *
 * @param algorithm_id Algorithm identifier string.
 * @return true if supported, false otherwise.
 */
bool fossil_algorithm_graph_supported(const char *algorithm_id);

/**
 * @brief Returns whether the algorithm requires weighted edges.
 *
 * @param algorithm_id Algorithm identifier string.
 * @return true if weights are required.
 */
bool fossil_algorithm_graph_requires_weights(const char *algorithm_id);

#ifdef __cplusplus
}

#include <string>

namespace fossil {
    namespace algorithm {
    
    /**
     * @brief RAII-friendly C++ wrapper for Fossil graph algorithms.
     */
    class Graph
    {
    public:
        /**
         * @brief Execute a graph algorithm.
         *
         * @param graph Graph handle.
         * @param algorithm_id Algorithm identifier.
         * @param start_node Start node id.
         * @param target_node Target node id (optional).
         * @param visit Visitor callback (optional).
         * @param user User context pointer.
         * @return int Status or algorithm-specific result.
         */
        static int exec(
            fossil_graph_t *graph,
            const std::string &algorithm_id,
            uint64_t start_node = 0,
            uint64_t target_node = 0,
            fossil_graph_visit_fn visit = nullptr,
            void *user = nullptr
        ) {
            return fossil_algorithm_graph_exec(
                graph,
                algorithm_id.c_str(),
                start_node,
                target_node,
                visit,
                user
            );
        }
    
        /**
         * @brief Checks whether an algorithm is supported.
         */
        static bool supported(const std::string &algorithm_id) {
            return fossil_algorithm_graph_supported(algorithm_id.c_str());
        }
    
        /**
         * @brief Checks whether an algorithm requires weighted edges.
         */
        static bool requires_weights(const std::string &algorithm_id) {
            return fossil_algorithm_graph_requires_weights(algorithm_id.c_str());
        }
    };
    
    } // namespace algorithm
} // namespace fossil

#endif /* __cplusplus */

#endif /* FOSSIL_ALGORITHM_GRAPH_H */

SAMPLE CODE C #

#include "fossil/algorithm/graph.h"
#include <stdio.h>
#include <stdbool.h>

/* Simple visitor that prints visited nodes */
bool print_node(uint64_t node_id, void *user) {
    (void)user;
    printf("Visited node %" PRIu64 "\n", node_id);
    return true; /* continue traversal */
}

int main(void) {
    fossil_graph_t *graph = /* graph creation is implementation-defined */ NULL;

    if (!fossil_algorithm_graph_supported("bfs")) {
        fprintf(stderr, "BFS not supported\n");
        return 1;
    }

    /* Breadth-first traversal starting from node 0 */
    int rc = fossil_algorithm_graph_exec(
        graph,
        "bfs",
        0,
        0,
        print_node,
        NULL
    );

    if (rc < 0) {
        fprintf(stderr, "Graph traversal failed: %d\n", rc);
    }

    return 0;
}

SAMPLE CODE C++ #

#include "fossil/algorithm/graph.h"
#include <iostream>

using fossil::algorithm::Graph;

/* Visitor that stops when a specific node is reached */
bool stop_at_target(uint64_t node_id, void *user) {
    uint64_t target = *static_cast<uint64_t *>(user);
    std::cout << "Visited node " << node_id << '\n';
    return node_id != target;
}

int main() {
    fossil_graph_t *graph = nullptr; /* graph ownership is external */

    if (!Graph::supported("dijkstra")) {
        std::cerr << "Dijkstra not supported\n";
        return 1;
    }

    uint64_t target = 5;

    int rc = Graph::exec(
        graph,
        "dijkstra",
        0,          /* start node */
        target,     /* target node */
        stop_at_target,
        &target
    );

    if (rc >= 0) {
        std::cout << "Path found or traversal completed\n";
    } else {
        std::cerr << "Graph algorithm failed: " << rc << '\n';
    }

    return 0;
}

What are your feelings

Updated on February 7, 2026