Catlab.jl

repository·main·Indexed 20 days ago

https://github.com/algebraicjulia/catlab.jl

A Julia-based framework for applied and computational category theory. It provides a programming library, interactive computing environment, and computer algebra system for categorical algebra, emphasizing monoidal categories and generalized algebraic theories. Key features include support for wiring diagrams (string diagrams), Acsets (Attribute Sets), sheaves for spatial data, and a standard library of categorical structures via Catlab.Theories.

Tokens
3.5K
Snippets
8
Records
19
Agent score
72%

What's inside Catlab.jl

  1. Overview of Catlab.jl

    main

    Catlab.jl is a Julia-based framework for applied and computational category theory. It provides a programming library and an interactive computing environment for scientific and engineering applications of category theory. While it emphasizes monoidal categories, it is designed to support any categorical structure formalizable as a generalized algebraic theory.

    Key capabilities include:

    • Programming Library: Provides data structures, algorithms, and serialization for applied category theory. It uses macros for specifying categorical doctrines and type-safe symbolic manipulation. It supports wiring diagrams (string diagrams) with serialization to GraphML and JSON.
    • Interactive Computing: Supports Jupyter notebooks with LaTeX rendering for symbolic expressions and visualization of wiring diagrams via Compose.jl, Graphviz, or TikZ.
    • Computer Algebra System: Acts as a computer algebra system for categorical algebra, using expressions typed via generalized algebraic theories. It implements algorithms for solving word problems and reducing expressions to normal forms for various doctrines (e.g., categories, symmetric monoidal categories).
  2. Use the Catlab.Theories standard library

    main

    The Catlab.Theories module provides a standard library of generalized algebraic theories (GATs) used to structure programs and provide a common interface for applied category theory. These theories correspond to standard definitions in category theory and are used throughout the AlgebraicJulia ecosystem.

    Supported categorical structures include:

    • Categories
    • Monoidal and symmetric monoidal categories
    • Cartesian and cocartesian categories
    • Semiadditive categories / biproduct categories
    • Hypergraph categories
    • Bicategories of relations
    • Categories with two monoidal products (e.g., distributive monoidal categories)

    Users can supplement these theories, create new syntax systems for them, or define entirely new theories. You can use many parts of Catlab without relying on this module.

  3. Choose between Static and Dynamic Acset implementations

    main

    Catlab offers three ways to implement acsets depending on whether your schema is known at compile-time or runtime:

    1. Static Acset Types (Compile-time)

    Best for performance and clear error messages when the schema is fixed.

    • @acset_type: Creates custom-derived structs.

      • Pros: Clear names (e.g., Graph) in error messages.
      • Cons: Requires eval if schemas are only known at runtime.
      • Usage: @acset_type MyType(MySchema) g = MyType()
    • AnonACSet: Uses AnonACSetType to create types that include the schema and field types in the type signature.

      • Pros: Can be used with schemas passed at runtime without eval.
      • Cons: Very long, complex type names in error messages.
      • Usage: const MyType = AnonACSetType(MySchema) g = MyType()

    2. Dynamic Acset Types (Runtime)

    • DynamicACSet: The schema is stored as a field within the object.
      • Pros: Faster if the schema is very large compared to the data; handles runtime schemas easily.
      • Cons: Does not benefit from code generation; many high-level constructions (like limits/colimits) currently require the schema to be derivable from the type, so they may not work as a drop-in replacement for static acsets yet.
      • Usage: g = DynamicACSet("MyGraph", MySchema; index=[:src,:tgt])
    # Static via @acset_type
    @acset_type WeightedGraph(SchWeightedGraph, index=[:src,:tgt])
    g = WeightedGraph()
    
    # Static via AnonACSet (for runtime schemas)
    const WeightedGraph = AnonACSetType(SchWeightedGraph, index=[:src,:tgt])
    g = WeightedGraph()
    
    # Dynamic
    g = DynamicACSet("WeightedGraph", SchWeightedGraph; index=[:src,:tgt])
  4. Understand the Abstract Field Convention in Catlab.jl

    main

    Catlab.jl uses an "Abstract Field Convention" to manage complex type parameters and reduce boilerplate. Instead of defining all fields in an abstract type (which Julia does not support), Catlab defines an abstract type and documents the expected fields in a comment. Subtypes are then expected to implement these fields in the same order.

    This convention is used instead of standard Julia field-access methods to:

    1. Avoid excessive boilerplate for large numbers of similar structs.
    2. Provide a stronger guarantee than a standard interface: it claims that subtypes have precisely these fields in this specific order, which is necessary for operations like copy.

    Note: This is a departure from standard Julia wisdom regarding encapsulation; it prioritizes reducing type name length in debug messages and enabling specific structural operations.

    # The convention pattern:
    
    """
    Abstract Fields
    - x1::A
    - x2::A
    """
    abstract type Pair{A} end
    
    add(xs::Pair) = xs.x1 + xs.x2
    
    struct IntPair <: Pair{Int}
      x1::Int
      x2::Int
    end
    
    # This allows structural operations like:
    function copy(p::T) where {T<:Pair}
      T(p.x1, p.x2)
    end
  5. Compute free diagrams, limits, and colimits

    main

    Catlab provides modules for defining free diagrams in an arbitrary category and computing limit/colimit cones over them.

    When you request a limit or colimit, the API returns a struct containing:

    • apex: The apex object of the cone.
    • legs: The leg morphisms of the cone.

    Best Practice: Because Catlab uses Julia's multiple dispatch to specialize computations for specific diagram shapes (like products, coproducts, equalizers, or coequalizers), it is highly recommended to use multiple dispatch in your own code to specialize on the diagram shape whenever possible.

    using CategoricalAlgebra.Cats.FreeDiagrams
    using CategoricalAlgebra.Cats.LimitsColimits
    
    # Example pattern for consuming limits:
    function process_limit(cone)
        a = apex(cone)
        l = legs(cone)
        # ... logic ...
    end
  6. Construct wiring diagrams with @program and @relation

    main

    The Catlab.Programs module provides domain-specific languages (DSLs) implemented as Julia macros to construct different types of wiring diagrams. These macros use Julia syntax but interpret it specifically for diagram construction.

    Use the following macros depending on the diagram type required:

    • @program: Used for constructing Directed Wiring Diagrams (DWDs).
    • @relation: Used for constructing Undirected Wiring Diagrams (UWDs).

    Additionally, DataMigrations.jl provides a family of related macros for constructing category-theoretic diagrams.

    // Note: Specific syntax for @program and @relation is not provided in this documentation segment, but they are the primary entry points for diagram construction.
  7. What Catlab.jl is not

    main

    It is important to distinguish Catlab.jl from other formal methods tools:

    • Not an Automated Theorem Prover: It does not produce formal certificates of correctness (proofs).
    • Not a Proof Assistant: It does not produce formally verifiable proofs; formal verification is outside its current scope.
    • Not a Graphical User Interface (GUI): Catlab is primarily a programming library and does not include a wiring diagram editor. For graphical interaction with wiring diagrams and Petri nets, use Semagrams.jl within the AlgebraicJulia ecosystem.
  8. Use Catlab.Parsers for constructing diagrams via DSLs

    main
    The Catlab.Parsers module provides parsing expression grammars designed to support domain-specific languages (DSLs) for constructing diagrams. These DSLs are implemented as Julia string macros. They are inspired by the syntax used in Catlab.Programs, which often interprets Julia-like syntax in a specialized way to define diagrammatic structures.
  9. What are Sheaves in Catlab.jl

    main
    In Catlab.jl, Sheaves are used for modeling spatial data and local-to-global properties. They generalize the concept of continuous functions over a topological space. A sheaf allows you to work with locally defined data (such as functions or vector fields) that are defined on subspaces (covers) and can be consistently extended to a larger domain if they agree on the overlaps of those subspaces.
  10. Define and use Acsets (Attribute Sets)

    main

    An Acset (Attribute Set) is a data structure parameterized by a schema. A schema defines the structure of the acset using four components:

    1. Objects (Ob): The primary entities (e.g., Vertices, Edges).
    2. Homomorphisms (Hom): Maps between objects (e.g., src and tgt maps).
    3. Attribute Types (AttrType): Data types used for attributes.
    4. Attributes (Attr): Maps from objects to attribute types (e.g., a weight attribute on an edge).

    Workflow Example

    To create a weighted graph, you first define a schema using the @present macro, then define an acset type, and finally instantiate the acset with data.

    using GATlab, Catlab.CategoricalAlgebra
    
    # 1. Define the schema
    @present SchWeightedGraph(FreeSchema) begin
      V::Ob
      E::Ob
      src::Hom(E,V)
      tgt::Hom(E,V)
      T::AttrType
      weight::Attr(E,T)
    end
    
    # 2. Define the acset type (using index to store backwards maps)
    @acset_type WeightedGraph(SchWeightedGraph, index=[:src,:tgt])
    
    # 3. Construct the acset with data
    g = @acset WeightedGraph{Float64} begin
      V = 4
      E = 5
      src = [1,1,1,2,3]
      tgt = [2,3,4,4,4]
      weight = [7.2, 9.3, 9.4, 0.1, 42.0]
    end