Yog.IO.TGF (YogEx v0.70.0)

Copy Markdown View Source

Trivial Graph Format (TGF) serialization support.

Provides functions to serialize and deserialize graphs in TGF format, a very simple text-based format suitable for quick graph exchange and debugging.

Format Overview

TGF consists of three parts:

  1. Node section: Each line is node_id node_label
  2. Separator: A single # character on its own line
  3. Edge section: Each line is source_id target_id [edge_label]

Example

iex> graph = Yog.directed()
...> |> Yog.add_node(1, "Alice")
...> |> Yog.add_node(2, "Bob")
...> |> Yog.add_edge!(from: 1, to: 2, with: "follows")
iex>
iex> tgf_string = Yog.IO.TGF.serialize(graph)
iex> String.contains?(tgf_string, "1 Alice")
true
iex> String.contains?(tgf_string, "1 2")
true

Parsing Behavior

When parsing TGF files, the following behaviors apply:

  • Auto-node creation: If an edge references a node ID that was not declared in the node section, a node is automatically created with the ID as its label.
  • Empty labels: Nodes without labels default to using their ID as the label.
  • Malformed lines: Lines that cannot be parsed are skipped and collected as warnings in the TgfResult.

Summary

Functions

Returns default TGF serialization options.

Creates TGF options with custom node and edge label functions.

Parses a TGF string into a graph with String labels.

Parses a TGF string into a graph with custom parsers.

Reads a graph from a TGF file using String labels.

Reads a graph from a TGF file with custom parsers.

Serializes a graph to TGF format using default label conversion.

Serializes a graph to TGF format with custom label functions.

Writes a graph to a TGF file using default label conversion.

Writes a graph to a TGF file with custom label functions.

Functions

default_options()

Returns default TGF serialization options.

Default behavior:

  • Node labels: Convert data to string using to_string/1
  • Edge labels: No labels (returns :none)

Example

iex> {:tgf_options, _node_fn, _edge_fn} = Yog.IO.TGF.default_options()
iex> :ok
:ok

options_with(node_label, edge_label)

Creates TGF options with custom node and edge label functions.

Time Complexity: O(1)

Parameters

  • node_label - Function to convert node data to string label (node_data) -> string
  • edge_label - Function to convert edge data to optional label (edge_data) -> :none | {:some, string}

Returns

TGF options tuple for use with serialize_with/2

Example

iex> options = Yog.IO.TGF.options_with(
...>   fn data -> "Node: " <> to_string(data) end,
...>   fn weight -> {:some, "W:" <> to_string(weight)} end
...> )
iex> {:tgf_options, _, _} = options
iex> :ok
:ok

parse(input, gtype)

Parses a TGF string into a graph with String labels.

Node and edge labels are stored as strings. For custom data structures, use parse_with/4.

Time Complexity: O(V + E)

Parameters

  • input - TGF format string
  • gtype - :directed or :undirected

Returns

  • {:ok, {:tgf_result, graph, warnings}} on success
  • {:error, reason} on parsing failure

The warnings list contains any malformed lines that were skipped.

Example

iex> tgf_string = """
...> 1 Alice
...> 2 Bob
...> #
...> 1 2 follows
...> """
iex> {:ok, {:tgf_result, graph, []}} = Yog.IO.TGF.parse(tgf_string, :directed)
iex> Yog.Model.node_count(graph)
2

parse_with(input, graph_type, node_parser, edge_parser)

Parses a TGF string into a graph with custom parsers.

This function allows you to transform TGF labels into custom Elixir data structures as the graph is built.

Time Complexity: O(V + E)

Parameters

  • input - TGF format string
  • graph_type - :directed or :undirected
  • node_parser - Function to transform node label to node data (string) -> node_data
  • edge_parser - Function to transform edge label to edge data (string | nil) -> edge_data

Returns

  • {:ok, {:tgf_result, graph, warnings}} on success
  • {:error, reason} on parsing failure

Example

tgf = "1 Alice\n2 Bob\n#\n1 2 5\n"

node_parser = fn label -> String.upcase(label) end
edge_parser = fn label ->
  case label do
    nil -> 1
    val -> String.to_integer(val)
  end
end

{:ok, {:tgf_result, graph, _warnings}} =
  Yog.IO.TGF.parse_with(tgf, :directed, node_parser, edge_parser)

read(path, gtype)

Reads a graph from a TGF file using String labels.

Time Complexity: O(V + E) + file I/O

Parameters

  • path - File path to read from
  • gtype - :directed or :undirected

Returns

  • {:ok, {:tgf_result, graph, warnings}} on success
  • {:error, reason} on file read or parse failure

Example

{:ok, {:tgf_result, graph, warnings}} =
  Yog.IO.TGF.read("network.tgf", :directed)

if warnings != [] do
  IO.puts("Warning: Some lines were malformed")
end

read_with(path, gtype, node_parser, edge_parser)

Reads a graph from a TGF file with custom parsers.

serialize(graph)

Serializes a graph to TGF format using default label conversion.

Node data is converted to strings, edge labels are omitted.

Time Complexity: O(V + E)

Example

iex> graph = Yog.directed()
...> |> Yog.add_node(1, "Alice")
...> |> Yog.add_node(2, "Bob")
...> |> Yog.add_edge!(from: 1, to: 2, with: "follows")
iex> tgf = Yog.IO.TGF.serialize(graph)
iex> String.contains?(tgf, "1 Alice") and String.contains?(tgf, "1 2")
true

serialize_with(options, graph)

Serializes a graph to TGF format with custom label functions.

Allows full control over how node and edge data are converted to TGF labels.

Time Complexity: O(V + E) where V is nodes and E is edges

Parameters

  • options - TGF options tuple (see options_with/2)
  • graph - The graph to serialize

Returns

TGF format string

Example

iex> graph = Yog.directed()
...> |> Yog.add_node(1, %{name: "Alice"})
...> |> Yog.add_node(2, %{name: "Bob"})
...> |> Yog.add_edge!(from: 1, to: 2, with: 10)
iex> options = Yog.IO.TGF.options_with(
...>   fn data -> data.name end,
...>   fn weight -> {:some, Integer.to_string(weight)} end
...> )
iex> tgf_string = Yog.IO.TGF.serialize_with(options, graph)
iex> String.contains?(tgf_string, "1 Alice") and String.contains?(tgf_string, "1 2 10")
true

write(path, graph)

Writes a graph to a TGF file using default label conversion.

Time Complexity: O(V + E) + file I/O

Parameters

  • path - File path to write to
  • graph - The graph to serialize

Returns

  • :ok on success
  • {:error, reason} on file write failure

Example

graph = Yog.directed()
|> Yog.add_node(1, "Alice")
|> Yog.add_node(2, "Bob")
|> Yog.add_edge!(from: 1, to: 2, with: "follows")

Yog.IO.TGF.write("network.tgf", graph)
# => :ok

write_with(path, options, graph)

Writes a graph to a TGF file with custom label functions.

Time Complexity: O(V + E) + file I/O

Parameters

  • path - File path to write to
  • options - TGF options tuple (see options_with/2)
  • graph - The graph to serialize

Returns

  • :ok on success
  • {:error, reason} on file write failure

Example

graph = Yog.directed() |> Yog.add_node(1, %{name: "Alice"})
options = Yog.IO.TGF.options_with(fn d -> d.name end, fn _ -> :none end)

Yog.IO.TGF.write_with("network.tgf", options, graph)