InductiveGraph (InductiveGraph v0.1.0) View Source
Functions that work on graphs as an inductive data structure.
Link to this section Summary
Construction Functions
Builds a graph from contexts.
Creates an empty graph.
Inserts contexts into graph.
Inserts tagged_edge into graph.
Inserts tagged_edges into graph.
Inserts tagged_vertex into graph.
Inserts tagged_vertices into graph.
Creates a graph from lists tagged_vertices and tagged_edges.
Merges context into graph.
Destruction Functions
Decomposes graph into an arbitrary context and the remaining graph.
Decomposes graph into the context containing vertex and the remaining
graph.
Deletes edge from graph.
Deletes edges from graph.
Deletes vertex from graph.
Deletes vertices from graph.
Update Functions
Filters edges based on edge values that fails predicate in graph.
Applies function to every edge value in graph.
Applies function to every context in graph.
Applies function to every vertex value in graph.
Applies vertex_function to every vertex value and edge_function to every
edge value in graph.
Folds function over graph with starting value accumulator.
Inspection Functions
Counts number of edges in graph.
Counts number of vertices in graph.
Determines if graph is empty.
Checks if two graphs are equal.
Determines if edge is in graph.
Determines if vertex is in graph.
Lists all tagged edges in graph.
Lists all tagged vertices in graph.
Pretty prints inductive representation of graph.
Gets range of vertex values in graph.
Link to this section Types
Specs
adjacents() :: [{edge_value(), neighbor()}]
Specs
context() :: {predecessors(), vertex(), vertex_value(), successors()}
Specs
Specs
edge_value() :: value()
Specs
neighbor() :: vertex()
Specs
predecessors() :: adjacents()
Specs
successors() :: adjacents()
Specs
t()
Specs
tagged_edge() :: {from_vertex :: vertex(), to_vertex :: vertex(), edge_value()}
Specs
tagged_vertex() :: {vertex(), vertex_value()}
Specs
value() :: term()
Specs
vertex() :: integer()
Specs
vertex_value() :: value()
Link to this section Construction Functions
Specs
Builds a graph from contexts.
Examples
iex> contexts = [{[{"down", 2}], 3, "c", [{"up", 1}]}, {[{"right", 1}], 2, "b", [{"left", 1}]}, {[], 1, "a", []}]
iex> {:ok, graph1} = InductiveGraph.build_graph(contexts)
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> {:ok, graph2} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> InductiveGraph.equal?(graph1, graph2)
true
Specs
empty_graph() :: t()
Creates an empty graph.
Examples
iex> graph = InductiveGraph.empty_graph()
#InductiveGraph<>
iex> InductiveGraph.pretty_print(graph)
"| Empty"
Specs
Inserts contexts into graph.
Examples
iex> graph1 = InductiveGraph.empty_graph()
iex> contexts = [{[{"down", 2}], 3, "c", [{"up", 1}]}, {[{"right", 1}], 2, "b", [{"left", 1}]}, {[], 1, "a", []}]
iex> {:ok, graph2} = InductiveGraph.insert_contexts(graph1, contexts)
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> {:ok, graph3} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> InductiveGraph.equal?(graph2, graph3)
true
Specs
insert_tagged_edge(t(), tagged_edge()) :: {:ok, t()} | :error
Inserts tagged_edge into graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}]
iex> new_tagged_edge = {3, 1, "up"}
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, graph} = InductiveGraph.insert_tagged_edge(graph, new_tagged_edge)
iex> InductiveGraph.pretty_print(graph) <> "\n"
~s'''
| {[{"down", 2}], 3, "c", [{"up", 1}]}
& {[{"right", 1}], 2, "b", [{"left", 1}]}
& {[], 1, "a", []}
& Empty
'''
Specs
insert_tagged_edges(t(), [tagged_edge()]) :: {:ok, t()} | :error
Inserts tagged_edges into graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}] iex> tagged_edges = [] iex> new_tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}] iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges) iex> {:ok, graph} = InductiveGraph.insert_tagged_edges(graph, new_tagged_edges) iex> InductiveGraph.pretty_print(graph) <> "\n" ~s''' | {[{"down", 2}], 3, "c", [{"up", 1}]} & {[{"right", 1}], 2, "b", [{"left", 1}]} & {[], 1, "a", []} & Empty '''
Specs
insert_tagged_vertex(t(), tagged_vertex()) :: {:ok, t()} | :error
Inserts tagged_vertex into graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> new_tagged_vertex = {4, "d"}
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, graph} = InductiveGraph.insert_tagged_vertex(graph, new_tagged_vertex)
iex> {:ok, context, _graph} = InductiveGraph.decompose(graph, 4)
iex> context
{[], 4, "d", []}
Specs
insert_tagged_vertices(t(), [tagged_vertex()]) :: {:ok, t()} | :error
Inserts tagged_vertices into graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> new_tagged_vertices = [{4, "d"}, {5, "e"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, graph} = InductiveGraph.insert_tagged_vertices(graph, new_tagged_vertices)
iex> InductiveGraph.pretty_print(graph, 2) <> "\n"
~s'''
| {[], 5, "e", []}
& {[], 4, "d", []}
& InductiveGraph
'''
Specs
make_graph([tagged_vertex()], [tagged_edge()]) :: {:ok, t()} | :error
Creates a graph from lists tagged_vertices and tagged_edges.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> graph |> InductiveGraph.list_tagged_vertices() |> Enum.sort()
[{1, "a"}, {2, "b"}, {3, "c"}]
iex> graph |> InductiveGraph.list_tagged_edges() |> Enum.sort()
[{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
Specs
Merges context into graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph1} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, context, graph2} = InductiveGraph.decompose(graph1, 3)
iex> {:ok, graph3} = InductiveGraph.merge(graph2, context)
iex> InductiveGraph.equal?(graph1, graph3)
true
Link to this section Destruction Functions
Specs
Decomposes graph into an arbitrary context and the remaining graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> InductiveGraph.count_vertices(graph)
3
iex> {:ok, _context, graph} = InductiveGraph.decompose(graph)
iex> InductiveGraph.count_vertices(graph)
2
Specs
Decomposes graph into the context containing vertex and the remaining
graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, context1, graph} = InductiveGraph.decompose(graph, 3)
iex> context1
{[{"down", 2}], 3, "c", [{"up", 1}]}
iex> {:ok, context2, graph} = InductiveGraph.decompose(graph, 2)
iex> context2
{[{"right", 1}], 2, "b", [{"left", 1}]}
iex> {:ok, context3, graph} = InductiveGraph.decompose(graph, 1)
iex> context3
{[], 1, "a", []}
iex> InductiveGraph.empty?(graph)
true
Specs
Deletes edge from graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> edge = {1, 2}
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, graph} = InductiveGraph.delete_edge(graph, edge)
iex> InductiveGraph.pretty_print(graph) <> "\n"
~s'''
| {[{"down", 2}], 3, "c", [{"up", 1}]}
& {[], 2, "b", [{"left", 1}]}
& {[], 1, "a", []}
& Empty
'''
Specs
Deletes edges from graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> edges = [{1, 2}, {2, 1}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, graph} = InductiveGraph.delete_edges(graph, edges)
iex> InductiveGraph.pretty_print(graph) <> "\n"
~s'''
| {[{"down", 2}], 3, "c", [{"up", 1}]}
& {[], 2, "b", []}
& {[], 1, "a", []}
& Empty
'''
Specs
Deletes vertex from graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, graph} = InductiveGraph.delete_vertex(graph, 3)
iex> InductiveGraph.has_vertex?(graph, 3)
false
Specs
Deletes vertices from graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> {:ok, graph} = InductiveGraph.delete_vertices(graph, [2, 3])
iex> InductiveGraph.has_vertex?(graph, 3)
false
Link to this section Update Functions
Specs
filter_edges(t(), (edge_value() -> boolean())) :: t()
Filters edges based on edge values that fails predicate in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> predicate = fn edge_value -> String.length(edge_value) == 4 end
iex> graph = InductiveGraph.filter_edges(graph, predicate)
iex> InductiveGraph.pretty_print(graph) <> "\n"
~s'''
| {[{"down", 2}], 3, "c", []}
& {[], 2, "b", [{"left", 1}]}
& {[], 1, "a", []}
& Empty
'''
Specs
map_edges(t(), (edge_value() -> edge_value())) :: t()
Applies function to every edge value in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> function = &String.reverse(&1)
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> graph = InductiveGraph.map_edges(graph, function)
iex> {:ok, context, _graph} = InductiveGraph.decompose(graph, 3)
iex> context
{[{"nwod", 2}], 3, "c", [{"pu", 1}]}
Specs
Applies function to every context in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> function = fn context = {_p, _v, value, _s} -> put_elem(context, 2, String.duplicate(value, 5)) end
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> graph = InductiveGraph.map_graph(graph, function)
iex> {:ok, context, _graph} = InductiveGraph.decompose(graph, 3)
iex> context
{[{"down", 2}], 3, "ccccc", [{"up", 1}]}
Specs
map_vertices(t(), (vertex_value() -> vertex_value())) :: t()
Applies function to every vertex value in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> function = &String.duplicate(&1, 5)
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> graph = InductiveGraph.map_vertices(graph, function)
iex> {:ok, context, _graph} = InductiveGraph.decompose(graph, 3)
iex> context
{[{"down", 2}], 3, "ccccc", [{"up", 1}]}
Specs
map_vertices_and_edges( t(), (vertex_value() -> vertex_value()), (edge_value() -> edge_value()) ) :: t()
Applies vertex_function to every vertex value and edge_function to every
edge value in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> vertex_function = &String.duplicate(&1, 5)
iex> edge_function = &String.reverse(&1)
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> graph = InductiveGraph.map_vertices_and_edges(graph, vertex_function, edge_function)
iex> {:ok, context, _graph} = InductiveGraph.decompose(graph, 3)
iex> context
{[{"nwod", 2}], 3, "ccccc", [{"pu", 1}]}
Specs
Folds function over graph with starting value accumulator.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> function = fn {_p, vertex, _v, _s}, result -> vertex + result end
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> InductiveGraph.unordered_fold(graph, 0, function)
6
Link to this section Inspection Functions
Specs
count_edges(t()) :: non_neg_integer()
Counts number of edges in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> graph |> InductiveGraph.count_edges()
4
Specs
count_vertices(t()) :: non_neg_integer()
Counts number of vertices in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, [])
iex> InductiveGraph.count_vertices(graph)
3
Specs
Determines if graph is empty.
Examples
iex> graph = InductiveGraph.empty_graph()
iex> InductiveGraph.empty?(graph)
true
iex> {:ok, graph} = InductiveGraph.make_graph([{1, 1}], [])
iex> InductiveGraph.empty?(graph)
false
Specs
Checks if two graphs are equal.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph1} = InductiveGraph.make_graph(tagged_vertices, [])
iex> {:ok, graph2} = InductiveGraph.insert_tagged_edges(graph1, tagged_edges)
iex> {:ok, graph3} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> InductiveGraph.equal?(graph1, graph2)
false
iex> InductiveGraph.equal?(graph2, graph3)
true
Specs
Determines if edge is in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> InductiveGraph.has_edge?(graph, {1, 2})
true
iex> InductiveGraph.has_edge?(graph, {1, 3})
false
Specs
Determines if vertex is in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> edges = []
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, edges)
iex> InductiveGraph.has_vertex?(graph, 3)
true
iex> InductiveGraph.has_vertex?(graph, 4)
false
Specs
list_tagged_edges(t()) :: [tagged_edge()]
Lists all tagged edges in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> graph |> InductiveGraph.list_tagged_edges() |> Enum.sort()
[{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
Specs
list_tagged_vertices(t()) :: [tagged_vertex()]
Lists all tagged vertices in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, [])
iex> graph |> InductiveGraph.list_tagged_vertices() |> Enum.sort()
[{1, "a"}, {2, "b"}, {3, "c"}]
Specs
Pretty prints inductive representation of graph.
If count is provided, then up to count number of contexts will be shown.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> tagged_edges = [{1, 2, "right"}, {2, 1, "left"}, {2, 3, "down"}, {3, 1, "up"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, tagged_edges)
iex> InductiveGraph.pretty_print(graph) <> "\n"
~s'''
| {[{"down", 2}], 3, "c", [{"up", 1}]}
& {[{"right", 1}], 2, "b", [{"left", 1}]}
& {[], 1, "a", []}
& Empty
'''
Specs
Gets range of vertex values in graph.
Examples
iex> tagged_vertices = [{1, "a"}, {2, "b"}, {3, "c"}]
iex> {:ok, graph} = InductiveGraph.make_graph(tagged_vertices, [])
iex> InductiveGraph.vertex_range(graph)
{:ok, 1, 3}