Library Reference

ACSets.ACSetInterface.DensePartsType

Part IDs are densely packed without gaps.

Mutations are eager and garbage collection is a no-op. Deletion or identification of parts may invalidate external references to particular parts.

ACSets.ACSetInterface.MarkAsDeletedType

Mark parts as deleted when they are removed.

Deletions are lazy and arrays are not resized until garbage collection. Parts can be deleted without invalidating external references to other parts.

ACSets.ACSetInterface.PartsTypeType

Type of part IDs to use in an acset.

The choice of parts type does not alter the mathematical model but it does affect the performance tradeoffs of the acset data structure, the assumptions that can be made about the part IDs, and whether garbage collection (gc!) is relevant.

Type parameter S is the collection type (Int, BitSet, etc) and type parameter T is the element type (Int, Symbol, etc), mirroring the two type parameters of FinSet in Catlab.

The default choice of parts type is DenseParts.

ACSets.ACSetInterface.UnionFindType

Allow distinct part IDs to refer to the same logical part.

Implemented using union-find. Garbage collection is an operation that makes sense to perform. Parts can be identified with each other without invalidating external references to particular parts.

ACSets.ACSetInterface.codom_partsFunction

Get the parts of the codomain of a morphism in an acset

dom_parts(acs, f) == parts(acs, Y)

where Y is the codom of the f in the schema

ACSets.ACSetInterface.copy_parts!Function

Copy parts from a C-set to a C′-set.

The selected parts must belong to both schemas. All subparts common to the selected parts, including data attributes, are preserved. Thus, if the selected parts form a sub-C-set, then the whole sub-C-set is preserved. On the other hand, if the selected parts do not form a sub-C-set, then some copied parts will have undefined subparts.

TODO: handle colons

ACSets.ACSetInterface.copy_parts_only!Function

Copy parts from a C-set to a C′-set, ignoring all non-data subparts.

The selected parts must belong to both schemas. Attributes common to both schemas are also copied, but no other subparts are copied.

See also: copy_parts!.

ACSets.ACSetInterface.dom_partsFunction

Get the parts of the domain of a morphism in an acset

dom_parts(acs, f) == parts(acs, X)

where X is the dom of the f in the schema

ACSets.ACSetInterface.incidentFunction

Get superparts incident to part in acset.

If the subpart is indexed, this takes constant time; otherwise, it takes linear time. As with subpart, both single and vectorized access, as well as chained access, are supported. Note that sequences of morphisms are supplied in the usual left-to-right order, so that

incident(g, x, [:src, :vattr])

returns the list of all edges whose source vertex has vertex attribute x.

If the chaining of subparts is given as a tuple (e.g.; (:src, :vattr)), then code generation is used to check that the subparts and their order is a valid composition and to improve performance.

Note that when the subpart is indexed, this function returns a view of the underlying index, which should not be mutated. To ensure that a fresh copy is returned, regardless of whether indexing is enabled, set the keyword argument copy=true.

ACSets.ACSetInterface.rem_part!Function

Remove part from a C-set.

The part is removed using the "pop and swap" strategy familiar from Graphs.jl, where the "removed" part is actually replaced by the last part, which is then deleted. This strategy has important performance benefits since only the last part must be assigned a new ID, as opposed to assigning new IDs to every part following the removed part.

The removal operation is not recursive. When a part is deleted, any superparts incident to it are retained, but their subparts become undefined (equal to the integer zero). For example, in a graph, if you call rem_part! on a vertex, the edges incident the src and/or tgt vertices of the edge become undefined but the edge itself is not deleted.

Indexing has both positive and negative impacts on performance. On the one hand, indexing reduces the cost of finding affected superparts from linear time to constant time. On the other hand, the indices of subparts must be updated when the part is removed. For example, in a graph, indexing src and tgt makes removing vertices faster but removing edges (slightly) slower.

See also: rem_parts!.

ACSets.ACSetInterface.subpartFunction

Get subpart of part in acset.

Both single and vectorized access are supported, with a view of the underlying data being returned in the latter case. Chaining, or composition, of subparts is also supported. For example, given a vertex-attributed graph g,

subpart(g, e, [:src, :vattr])

returns the vertex attribute of the source vertex of the edge e. As a shorthand, subparts can also be accessed by indexing:

g[e, :src] == subpart(g, e, :src)

If the chaining of subparts is given as a tuple (e.g.; (:src, :vattr)), then code generation is used to check that the subparts and their order is a valid composition and to improve performance.

Be warned that indexing with lists of subparts works just like subpart: g[e,[:src,:vattr]] is equivalent to subpart(g, e, [:src,:vattr]). This convention differs from DataFrames but note that the alternative interpretation of [:src,:vattr] as two independent columns does not even make sense, since they have different domains (belong to different tables).

ACSets.ACSetInterface.@acsetMacro

This provides a shorthand for constructing an acset by giving its parts and subparts

Usage:

@acset WeightedGraph{String} begin V = 2 E = 1 src = [1] tgt = [2] weight = ["fig"] end

ACSets.ACSetSerialization.read_acsetMethod

Read/deserialize an acset from an external source.

Supported source types include:

  • AbstractDict: assumed to be JSON data
  • XLSX.XLSXFile: Microsoft Excel file (requires XLSX.jl)

Arguments

  • cons: constructor for acset, e.g., the type of a struct acset
  • source: source to read from
ACSets.ColumnImplementations.AttrVarType

Maps from attribute variables can go into arbitrary Julia types or other variables (indexed by integers). This wrapper types allows us to not confuse our Attr Variable indices with the Julia type of Int

ACSets.Columns.ColumnType

A column wraps a mapping and a cache of its preimages, and provides methods that do coordinated updates of both.

Abstract Fields:

  • m::Mapping{S,T}
  • pc::PreimageCache{S,T}
ACSets.Defaults.DefaultType

This is a hack in order to pass in a default initializer for DefaultVecMap as a type parameter

ACSets.DenseACSetsModule

These are ACSets where the set associated to each object is of the form 1:n

ACSets.DenseACSets.AnonACSetType

This works the same as something made with @acset_type, only the types of the parts and subparts are stored as type parameters. Thus, this can be used with any schema.

ACSets.DenseACSets.SimpleACSetType

A SimpleACSet is an abstract type for any acset that has a certain layout

Specifically, subtypes of SimpleACSet are expected to have a parts field which is a mapping from symbols to ints, and a subparts field which is a mapping from symbols to columns, which are any data structure that satisfies the interface given in Columns.jl.

ACSets.DenseACSets.StructACSetType

A StructACSet is a SimpleACSet where the schema and the types assigned to the attrtypes are available in the type.

ACSets.ACSetInterface.gc!Method

Reindex the parts of the acset such that there are no gaps between the indices. Return a vector for each part mapping the new parts into the old parts.

ACSets.ACSetInterface.incidentMethod

Calling incident on a range of values, e.g. incident(G, 1:2, :src) is equivalent to concatenating the results of incident on each part, i.e. [incident(G,1,:src), incident(G,2,:src)].

ACSets.DenseACSets.ACSetTableTypeMethod

This takes an ACSet type, and produces an AnonACSet which represents an acset with just the object passed in, and then all of the attributes of that object.

TODO: rename this to be less confusing with ACSetTable. Maybe ASet (attributed set)

ACSets.DenseACSets.delete_subobj!Method

Return a mapping of from parts of updated X to the old X

Note: the correctness is dependent on the implementation details of rem_parts!

ACSets.DenseACSets.delete_subobjMethod

Identify which parts of an ACSet need to be deleted if some initial collection of parts is to be deleted. E.g. deleting a vertex deletes its edge

ACSets.DenseACSets.genericizeMethod

The type variables that we have generated might not match up with the type variables that are created as generic parameters to the struct acset, this is a way of making the two line up

ACSets.DenseACSets.idxMethod

Get index of row in parent acset.

Given an ACSetRow object from the Tables.jl interface, return the ID of the correspond part in the parent acset the row was derived from.

Base.parentMethod

Get parent acset.

Given a ACSetTable or ACSetRow object from the Tables.jl interface, return the parent acset the object was derived from.

ACSets.DenseACSets.@abstract_acset_typeMacro

We want control over the type class hierarchy of acsets; this allows us to create abstract types that subtype StructACSet. For instance, we might have an AbstractGraph type, and then assume (this is not enforced) that any subtype of AbstractGraph has E,V,src,tgt in its schema.

ACSets.DenseACSets.@acset_typeMacro

This macro creates custom structs that subclass StructACSet{S} for specific S. These are used for acsets whose schema is known at compile time.

ACSets.ACSetSerialization.ExcelACSets.read_xlsx_acsetMethod

Read acset from an Excel (.xlsx) file.

This is a convenience function that loads the Excel file and then calls read_acset. To use this function, the package XLSX.jl must be installed and imported.

Arguments

  • cons: constructor for acset, e.g., the acset type for struct acsets
  • source: filename or IO stream from which to read Excel file
  • tables=(;): dictionary or named tuple mapping object names in acset schema to Excel table specifications
ACSets.IndexUtils.deletesorted!Method

Delete one occurrence of value from sorted vector, if present.

Returns whether an occurence was found and deleted.

ACSets.InterTypes.ACSetTypeSpecType

A specification for the type of an acset.

Fields

  • genericname::Union{Symbol, Nothing}: The name for the generic version of the acset, with type parameters.

    Note that the name assigned to this in the declaration is the name with type parameters pre-specified.

    If there are no attribute types, then this is nothing.

  • abstract_type::Union{Symbol, Nothing}: The parent abstract type for the acset.

  • schemaname::Symbol

  • schema::TypedSchema{Symbol, InterType}

  • index::Vector{Symbol}

  • unique_index::Vector{Symbol}

ACSets.InterTypes.FieldType

A field of a struct. Used in Variant and Record.

The T parameter will always be InterType, but this is mutually-recursive with InterType so we have to be generic here.

ACSets.InterTypes.InterTypeType

An intertype expression representing a type.

TODO: Generic types TODO: Remove anonymous sums, anonymous products TODO: Separate out primitives, so that this is something like

@data InterType begin
  PrimType(prim::InterTypePrimitive)
  TypeRef(path::RefPath)
  TypeApp(type::InterType, args::Vector{InterType})
end
ACSets.InterTypes.JSONTargetType
JSONTarget

Specifies a serialization target of JSON Schema when generating a module.

TODO: This should really be called something like JSONSchemaTarget.

ACSets.InterTypes.PydanticTargetType
PydanticTarget

Targets the creation of .py files that use the Pydantic library which enables integration with the Python language (specifically when (de)serializing JSON).

ACSets.InterTypes.SExpType

A very simple s-expression data structure.

We use this to write the intertype schema to a string and then hash it to get a version identifier.

ACSets.InterTypes.VariantType

One of the summands of a sum type.

Like Field, the T parameter will always be InterType, but this is mutually-recursive with InterType so we have to be generic here.

ACSets.InterTypes.VariantOfType

A variant of a sum type, i.e. one of the summands. These are implicitly produced when declaring a sum type, and the data of the variant (i.e. the fields) are in the parent sum type.

ACSets.InterTypes.generate_moduleFunction
generate_module(mod::Module, target::Type{<:ExportTarget}, path="."; target_specific_args...)

Generate files that define the intertypes for the specified target.

ACSets.InterTypes.tojsonschemaMethod
tojsonschema(type::InterType)

Convert an InterType to a JSONSchema representation.

TODO: We could use multiple dispatch instead of the @match here, which might be cleaner

ACSets.InterTypes.topyMethod
topy(intertype::InterType; forward_ref=true)

Converts an intertype into a python code string.

TODO: See comment for toexpr

TODO: Should we use something like a stringbuilder instead of manually concatenating strings? I.e., a tree of strings with O(1) append/splice, that we write out to a single string at the end?

ACSets.Schemas.toexprFunction
function toexpr(x) end

Used to convert intertype data types to Expr.

TODO: Should we unify tojsonschema, toexpr, and topy into a single function with an extra argument to control dispatch?

ACSets.InterTypes.@intertypesMacro
@intertypes "file.it" module modulename end

Used to import an intertypes file into Julia.

TODO: maybe we should just build a .jl file from an .it file directly.

JSON3.writeMethod

Dispatch for ACSet

Dispatches write to accept ACSets

ACSets.Mappings.MappingType

A mapping is essentially an AbstractDict, but we support a couple more methods, like map, and so in order to not do type piracy we make our own abstract type to define methods on. Additionally, access to undefined indices will return nothing rather than erroring; this means that a Mapping{K,Nothing} will behave as if everything is undefined. Don't do this.

ACSets.NautyInterface.CSetNautyResType

NautyResults must satisfy the following interface

  • strhsh: string value representing the isomorphism class
  • orbits: partitions of Cset parts into orbits e.g. if E#2 = E#5, then these two elements are symmetric
  • generators: generating automorphisms of the automorphism group
  • ngroup: number of elements in the automorphism group
  • canonmap: isomorphism from the input into the canonoical isomorph
  • canon: canonical isomorph (codom of canonmap)
ACSets.NautyInterface.all_autosMethod

Take advantage of the very special structure of automorphism generators given by nauty to efficiently enumerate the automorphism group. We iteratively expand our automorphism group with each generator. A while loop explores the possible words that we can built (starting with gₙ₊₁)

ACSets.NautyInterface.dreadnautMethod

Construct input for dreadnaut to compute automorphism group generators, canonical permutation/hash, and orbits.

Note the Julia colorsarray must be changed from being 1-indexed to 0-indexed.

Dreadnaut parameters:

n - # of vertices g - provide input graph via command line rather than via a file f - use an initial partition of the vertices in the undirected graph c - find a canonical graph b - write out a canonical graph x - run nauty z - make a canonical hash o - write out the orbits

ACSets.NautyInterface.from_adjMethod

Convert symmetric adjacency matrix to an ACSet which is isomorphic to X.

The main work is reverse-engineering triangles of the form

                    ↗ src′ₙ
                  ↙    ↕
              eₙ <-> srcₙ <-> vₘ

into hom values for the resulting ACSet. We call srcₙ a "hom-object" and src′ₙ a "pseudo-hom-object". eₙ is the "src ind" and vₘ is the "tgt ind"

ACSets.NautyInterface.get_oindsMethod

Create partition of flattened indices (all parts altogether) to dict with indices for each distinct object, e.g.:

{V => 1:8, E => 9:13, src => 14:18, tgt => 19:23, src... => 24:28, tgt... => 29:33, weight => 34:38}

ACSets.NautyInterface.to_permMethod

Convert an all-parts permutation into a symbol-indexed set of permutations, given a partition of 1:n_total into ranges for each symbol.

ACSets.NautyInterface.to_udgMethod

Convert C-Set to an adjacency matrix of an undirected simple graph.

the matrix has rows for all parts (e.g. |E| and |V|), all homs (e.g. |E| quantity of src & tgt nodes), and another copy of all homs (called, e.g., _src and _tgt). For a given edge in the category of elements eₙ – srcₙ –> vₘ, we set edges in the simple diagraph:

    ↗ _srcₙ
  ↙    ↕
eₙ <-> srcₙ <-> vₘ

For attributes, there is no possibility of Attr(X,X), so we simply have, e.g.: eₘ <-> weightₘ <-> Numberₙ

ACSets.PreimageCaches.PreimageCacheType

A PreimageCache is a cache of the preimage of a Mapping. Many of the methods for PreimageCache take in a Mapping; this is so that PreimageCache can choose how much to cache. That is, PreimageCache could be a unit type, and simply dynamically compute the preimage mapping on demand, or it could store the full preimage mapping, or perhaps something in between.

Just like a Mapping, an PreimageCache has a definable codomain, which is a subset of T. Calling add_mapping! and remove_mapping! on elements out of this definable codomain will error.

However, a PreimageCache is always defined on all of its definable codomain; it defaults to the empty set.

PreimageCache also has a notion of "stored" codomain, where preimages are actually stored. It is only when the preimage is stored that referential equality of preimage sets will be preserved, and additionally storage can have performance implications.

PreimageCaches should support the following functions:

ACSets.PreimageCaches.StoredPreimageCacheType

An preimage mapping that works by storing the preimages directly. Note: the storage should be a storage that defaults to making empty preimages when expanded or queried out of band, so for instance DefaultVecMap{Preimage, DefaultEmpty{Preimage}}

ACSets.PreimageCaches.preimageFunction

Arguments:

  • dom::Iterable{S}
  • m::Mapping{S,T}
  • i::PreimageCache{S,T}
  • y::T

Returns an iterable of the values in the domain that map onto y.

ACSets.PreimageCaches.preimage_multiMethod

Arguments:

  • dom::Iterable{S}
  • m::Mapping{S,T}
  • i::PreimageCache{S,T}
  • ys::Iterable{T}

Semantically, this is the same as mapping preimage over ys, but the implementation might choose to use a view of an internal data structure of the index instead.

ACSets.Schemas.arrowsFunction

Parameters:

  • s::Schema{Name}

Named Parameters:

  • just_names::Bool=false
  • from::Any = nothing
  • to::Any = nothing

Same deal as homs, but for homs and attributes.

ACSets.Schemas.attrsFunction

Parameters:

  • s::Schema{Name}

Named Parameters:

  • just_names::Bool=false
  • from::Any = nothing
  • to::Any = nothing

Same deal as homs, but for attributes.

ACSets.Schemas.attrtypesFunction

Parameters:

  • s::Schema{Name}

Returns an iterable of the names of the attrtypes for this schema.

ACSets.Schemas.homsFunction

Parameters:

  • s::Schema{Name}

Named Parameters:

  • just_names::Bool=false
  • from::Any = nothing
  • to::Any = nothing

Defaults to returning an iterable of tuples (f,x,y) where f is the name of a homomorphism and x and y are its domain and codomain respectively.

If just_names is true, then it just returns the fs.

If from is not nothing then it should be either an object or an iterable of objects; this then filters to only morphisms that have domain in from. Mutatis mutandis for to.

ACSets.Schemas.objectsFunction

Parameters:

  • s::Schema{Name}

Returns an iterable of the names of the objects for this schema.

AlgebraicInterfaces.codomFunction

Parameters:

  • s::Schema{Name}
  • f::Name

Named Parameters:

  • from::Any = nothing

Same deal as dom, but for codomains.

AlgebraicInterfaces.domFunction

Parameters:

  • s::Schema{Name}
  • f::Name

Named Parameters:

  • to::Any = nothing

If to is nothing, then this returns the domain of the unique morphism with name f, and errors otherwise. If to is not nothing, then it should be either an object/attrtype or an iterable of objects/attrtypes, and this should return the domain of the unique morphism with codomain in to.