Packages

The Phi Programming Language

Current section

Files

Jump to
phi priv Data Digraph.erl
Raw

priv/Data/Digraph.erl

%%---------------------------------------------------------------------------
%% |
%% Module : Digraph
%% Copyright : (c) 2020-2021 EMQ Technologies Co., Ltd.
%% License : BSD-style (see the LICENSE file)
%%
%% Maintainer : Feng Lee, feng@emqx.io
%% Zhang Shiwei, zhangsw@emqx.io
%% Stability : experimental
%% Portability : portable
%%
%% The Digraph FFI Module.
%%
%%---------------------------------------------------------------------------
-module('Data.Digraph.FFI').
-include("../Foreign.hrl").
%% FFI
-export([ edgeOf/1
, vertexOf/1
, edgeID/1
, vertexID/1
, new/1
, addEdge/4
, modifyEdge/5
, addVertex/2
, edge/2
, vertex/2
, getCycle/2
, getPath/3
, getShortCycle/2
, getShortPath/3
, info/1
, eqImpl/2
]).
-define(Left(V), {'Left', V}).
-define(Right(V), {'Right', V}).
edgeOf(ID) -> ['$e' | ID].
vertexOf(ID) -> ['$v' | ID].
edgeID(['$e' | ID]) -> ID.
vertexID(['$v' | ID]) -> ID.
eqImpl(X, Y) -> X =:= Y.
trans([]) -> [];
trans([X | Xs]) ->
[case X of
{'Cyclic'} -> digraph:cyclic();
{'Acyclic'} -> digraph:acyclic();
{'Protected'} -> digraph:protected();
{'Private'} -> digraph:private()
end | trans(Xs)].
new(Type) -> ?IO(digraph:new(trans(Type))).
addEdge(G, V1, V2, Labal) -> ?IO(
case digraph:add_edge(G, V1, V2, Labal) of
{error, {bad_edge, Path}} -> ?Left({'BadEdge', Path});
{error, {bad_vertex, V}} -> ?Left({'BadVertex', V});
V -> ?Right(V)
end).
modifyEdge(G, E, V1, V2, Labal) -> ?IO(
case digraph:add_edge(G, E, V1, V2, Labal) of
{error, {bad_edge, Path}} -> ?Left({'BadEdge', Path});
{error, {bad_vertex, V}} -> ?Left({'BadVertex', V});
V -> ?Right(V)
end).
addVertex(G, Labal) -> ?IO(
digraph:add_vertex(G, digraph:add_vertex(G), Labal)).
edge(G, E) -> ?IO(
case digraph:edge(G, E) of
{E, V1, V2, Labal} -> ?Just({V1, V2, Labal});
false -> ?Nothing
end).
vertex(G, V) -> ?IO(
case digraph:vertex(G, V) of
{V, Labal} -> ?Just(Labal);
false -> ?Nothing
end).
getCycle(G, V) -> ?IO(
case digraph:get_cycle(G, V) of
false -> [];
Else -> Else
end).
getPath(G, V1, V2) -> ?IO(
case digraph:get_path(G, V1, V2) of
false -> [];
Else -> Else
end).
getShortCycle(G, V) -> ?IO(
case digraph:get_short_cycle(G, V) of
false -> [];
Else -> Else
end).
getShortPath(G, V1, V2) -> ?IO(
case digraph:get_short_path(G, V1, V2) of
false -> [];
Else -> Else
end).
info(G) -> ?IO(
lists:map(fun({memory, M}) ->
{'GraphMemoryInfo', M};
({cyclicity, Y}) ->
{'GraphTypeInfo', {case Y of cyclic -> 'Cyclic'; acyclic -> 'Acyclic' end}};
({portection, Y}) ->
{'GraphTypeInfo', {case Y of protected -> 'Protected'; private -> 'Private' end}}
end, digraph:info(G))).