10 namespace graph_algorithm
13 NetlistGraph::NetlistGraph(Netlist* nl) : m_nl(nl)
17 NetlistGraph::NetlistGraph(
Netlist* nl, igraph_t&& graph, std::unordered_map<u32, Gate*>&& nodes_to_gates) : m_nl(nl), m_graph(
std::move(graph)), m_nodes_to_gates(
std::move(nodes_to_gates))
22 m_graph_initialized =
true;
23 m_graph_ptr = &m_graph;
25 for (
const auto& [node, gate] : m_nodes_to_gates)
29 m_gates_to_nodes[gate] = node;
38 if (m_graph_initialized)
40 igraph_destroy(&m_graph);
48 return ERR(
"netlist is a nullptr");
51 auto graph = std::unique_ptr<NetlistGraph>(
new NetlistGraph(nl));
55 for (
const auto*
net : graph->m_nl->get_nets(filter))
57 std::vector<Gate*> src_gates;
58 for (
const auto* src_ep :
net->get_sources())
60 src_gates.push_back(src_ep->get_gate());
63 std::vector<Gate*> dst_gates;
64 for (
const auto* dst_ep :
net->get_destinations())
66 dst_gates.push_back(dst_ep->get_gate());
69 if (src_gates.empty() && create_dummy_vertices)
73 edge_counter += dst_gates.size();
75 else if (dst_gates.empty() && create_dummy_vertices)
79 edge_counter += src_gates.size();
84 edge_counter += dst_gates.size() * src_gates.size();
89 igraph_vector_int_t edges;
90 auto err = igraph_vector_int_init(&edges, 2 * edge_counter);
91 if (err != IGRAPH_SUCCESS)
93 return ERR(igraph_strerror(err));
100 for (
auto* g : graph->m_nl->get_gates())
102 const u32 node = node_counter++;
103 graph->m_gates_to_nodes[g] = node;
104 graph->m_nodes_to_gates[node] = g;
107 for (
const auto*
net : graph->m_nl->get_nets(filter))
109 std::vector<Gate*> src_gates;
110 for (
const auto* src_ep :
net->get_sources())
112 src_gates.push_back(src_ep->get_gate());
115 std::vector<Gate*> dst_gates;
116 for (
const auto* dst_ep :
net->get_destinations())
118 dst_gates.push_back(dst_ep->get_gate());
121 if (src_gates.empty() && create_dummy_vertices)
124 const u32 dummy_node = node_counter++;
125 graph->m_nodes_to_gates[dummy_node] =
nullptr;
126 for (
auto* dst_gate : dst_gates)
128 VECTOR(edges)[edge_index++] = dummy_node;
129 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(dst_gate);
132 else if (dst_gates.empty() && create_dummy_vertices)
135 const u32 dummy_node = node_counter++;
136 graph->m_nodes_to_gates[dummy_node] =
nullptr;
137 for (
auto* src_gate : src_gates)
139 VECTOR(edges)[edge_index++] = dummy_node;
140 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
145 for (
auto* dst_gate : dst_gates)
147 for (
auto* src_gate : src_gates)
149 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
150 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(dst_gate);
156 graph->m_graph_ptr = &(graph->m_graph);
157 err = igraph_create(graph->m_graph_ptr, &edges, node_counter, IGRAPH_DIRECTED);
159 igraph_vector_int_destroy(&edges);
161 if (err != IGRAPH_SUCCESS)
163 return ERR(igraph_strerror(err));
166 graph->m_graph_initialized =
true;
168 return OK(std::move(graph));
175 return ERR(
"netlist is a nullptr");
178 auto graph = std::unique_ptr<NetlistGraph>(
new NetlistGraph(nl));
180 const auto& graph_gates = gates.empty() ? graph->m_nl->get_gates() : gates;
182 u32 node_counter = 0;
183 for (
auto* g : graph_gates)
185 const u32 node = node_counter++;
186 graph->m_gates_to_nodes[g] = node;
187 graph->m_nodes_to_gates[node] = g;
190 graph->m_graph_ptr = &(graph->m_graph);
191 auto err = igraph_empty(graph->m_graph_ptr, node_counter, IGRAPH_DIRECTED);
192 if (err != IGRAPH_SUCCESS)
194 return ERR(igraph_strerror(err));
197 graph->m_graph_initialized =
true;
199 return OK(std::move(graph));
204 auto graph = std::unique_ptr<NetlistGraph>(
new NetlistGraph(m_nl));
206 if (
const auto res = igraph_copy(&(graph->m_graph), &(this->m_graph)); res != IGRAPH_SUCCESS)
208 return ERR(igraph_strerror(res));
211 graph->m_graph_initialized =
true;
212 graph->m_graph_ptr = &(graph->m_graph);
213 graph->m_gates_to_nodes = this->m_gates_to_nodes;
214 graph->m_nodes_to_gates = this->m_nodes_to_gates;
216 return OK(std::move(graph));
231 std::vector<Gate*> res;
232 for (
const auto& vertex : vertices)
234 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
236 Gate* g = it->second;
241 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, added nullptr", vertex);
246 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
254 std::vector<Gate*> res;
255 for (
const auto& vertex : vertices)
257 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
259 Gate* g = it->second;
264 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, added nullptr", vertex);
269 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
277 std::vector<Gate*> res;
278 const u32 num_vertices = igraph_vector_int_size(vertices);
279 for (
u32 i = 0; i < num_vertices; i++)
281 u32 vertex = VECTOR(*vertices)[i];
282 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
284 Gate* g = it->second;
289 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, added nullptr", vertex);
294 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
303 for (
const auto& vertex : vertices)
305 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
307 Gate* g = it->second;
311 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, skipping vertex", vertex);
318 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
327 for (
const auto& vertex : vertices)
329 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
331 Gate* g = it->second;
335 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, skipping vertex", vertex);
342 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
351 const u32 num_vertices = igraph_vector_int_size(vertices);
352 for (
u32 i = 0; i < num_vertices; i++)
354 u32 vertex = VECTOR(*vertices)[i];
355 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
357 Gate* g = it->second;
361 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, skipping vertex", vertex);
368 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
379 return ERR(res.get_error());
382 return OK(res.get().front());
387 std::vector<u32> res;
388 for (
u32 i = 0; i < gates.size(); i++)
390 auto* g = gates.at(i);
394 return ERR(
"gate at index " + std::to_string(i) +
" is a nullptr");
397 if (
const auto it = m_gates_to_nodes.find(g); it != m_gates_to_nodes.end())
399 res.push_back(it->second);
403 return ERR(
"no node for gate '" + g->get_name() +
"' with ID " + std::to_string(g->get_id()) +
" exists in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
411 std::vector<u32> res;
412 for (
auto* g : gates)
416 return ERR(
"set of gates contains a nullptr");
419 if (
const auto it = m_gates_to_nodes.find(g); it != m_gates_to_nodes.end())
421 res.push_back(it->second);
425 return ERR(
"no node for gate '" + g->get_name() +
"' with ID " + std::to_string(g->get_id()) +
" exists in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
433 igraph_vector_int_t out;
434 if (
auto res = igraph_vector_int_init(&out, gates.size()); res != IGRAPH_SUCCESS)
436 return ERR(igraph_strerror(res));
439 for (
u32 i = 0; i < gates.size(); i++)
441 auto* g = gates.at(i);
445 return ERR(
"gate at index " + std::to_string(i) +
" is a nullptr");
448 if (
const auto it = m_gates_to_nodes.find(g); it != m_gates_to_nodes.end())
450 VECTOR(out)[i] = it->second;
454 return ERR(
"no node for gate '" + g->get_name() +
"' with ID " + std::to_string(g->get_id()) +
" exists in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
457 return OK(std::move(out));
462 igraph_vector_int_t out;
463 if (
auto res = igraph_vector_int_init(&out, gates.size()); res != IGRAPH_SUCCESS)
465 return ERR(igraph_strerror(res));
469 for (
auto gates_it = gates.begin(); gates_it != gates.end(); gates_it++)
475 return ERR(
"gate at index " + std::to_string(i) +
" is a nullptr");
478 if (
const auto nodes_it = m_gates_to_nodes.find(g); nodes_it != m_gates_to_nodes.end())
480 VECTOR(out)[i] = nodes_it->second;
484 return ERR(
"no node for gate '" + g->get_name() +
"' with ID " + std::to_string(g->get_id()) +
" exists in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
489 return OK(std::move(out));
497 return ERR(res.get_error());
500 return OK(res.get().front());
505 u32 num_vertices = igraph_vcount(&m_graph);
513 u32 num_connected_vertices = 0;
515 igraph_vector_int_t degrees;
516 igraph_vector_int_init(°rees, num_vertices);
518 igraph_vs_t v_sel = igraph_vss_all();
519 igraph_degree(&m_graph, °rees, v_sel, IGRAPH_ALL, IGRAPH_LOOPS);
521 for (
u32 i = 0; i < num_vertices; i++)
523 if (VECTOR(degrees)[i] != 0)
525 num_connected_vertices++;
529 igraph_vector_int_destroy(°rees);
530 igraph_vs_destroy(&v_sel);
532 return num_connected_vertices;
538 return igraph_ecount(&m_graph);
543 u32 num_vertices = igraph_vcount(&m_graph);
547 std::vector<u32> vertices(num_vertices);
548 for (
u32 i = 0; i < num_vertices; i++)
556 std::vector<u32> vertices;
558 igraph_vector_int_t degrees;
559 if (
auto res = igraph_vector_int_init(°rees, num_vertices); res != IGRAPH_SUCCESS)
561 return ERR(igraph_strerror(res));
564 igraph_vs_t v_sel = igraph_vss_all();
565 if (
auto res = igraph_degree(&m_graph, °rees, v_sel, IGRAPH_ALL, IGRAPH_LOOPS); res != IGRAPH_SUCCESS)
567 igraph_vs_destroy(&v_sel);
568 igraph_vector_int_destroy(°rees);
569 return ERR(igraph_strerror(res));
572 for (
u32 i = 0; i < num_vertices; i++)
574 if (VECTOR(degrees)[i] != 0)
576 vertices.push_back(i);
580 igraph_vector_int_destroy(°rees);
581 igraph_vs_destroy(&v_sel);
589 const u32 ecount = igraph_ecount(&m_graph);
591 igraph_vector_int_t edges;
592 if (
auto res = igraph_vector_int_init(&edges, 2 * ecount); res != IGRAPH_SUCCESS)
594 return ERR(igraph_strerror(res));
597 if (
auto res = igraph_get_edgelist(&m_graph, &edges,
false); res != IGRAPH_SUCCESS)
599 igraph_vector_int_destroy(&edges);
600 return ERR(igraph_strerror(res));
603 std::vector<std::pair<u32, u32>> e_vec(ecount);
604 for (
u32 i = 0; i < ecount; i++)
606 const u32 src_vertex = (
u32)VECTOR(edges)[2 * i];
607 const u32 dst_vertex = (
u32)VECTOR(edges)[2 * i + 1];
609 e_vec[i] = std::make_pair(src_vertex, dst_vertex);
617 const u32 ecount = igraph_ecount(&m_graph);
619 igraph_vector_int_t edges;
620 if (
auto res = igraph_vector_int_init(&edges, 2 * ecount); res != IGRAPH_SUCCESS)
622 return ERR(igraph_strerror(res));
625 if (
auto res = igraph_get_edgelist(&m_graph, &edges,
false); res != IGRAPH_SUCCESS)
627 igraph_vector_int_destroy(&edges);
628 return ERR(igraph_strerror(res));
631 std::vector<std::pair<Gate*, Gate*>> e_vec(ecount);
632 for (
u32 i = 0; i < ecount; i++)
634 const u32 src_vertex = (
u32)VECTOR(edges)[2 * i];
635 const u32 dst_vertex = (
u32)VECTOR(edges)[2 * i + 1];
636 Gate *src_gate, *dst_gate;
638 if (
const auto it = m_nodes_to_gates.find(src_vertex); it != m_nodes_to_gates.end())
640 src_gate = it->second;
641 if (src_gate ==
nullptr)
644 "ignored edge (" + std::to_string(src_vertex) +
"," + std::to_string(dst_vertex) +
") at dummy source vertex '" + std::to_string(src_vertex) +
"'");
649 if (
const auto it = m_nodes_to_gates.find(dst_vertex); it != m_nodes_to_gates.end())
651 dst_gate = it->second;
652 if (dst_gate ==
nullptr)
655 "ignored edge (" + std::to_string(src_vertex) +
"," + std::to_string(dst_vertex) +
") at dummy destination vertex '" + std::to_string(dst_vertex) +
"'");
660 e_vec[i] = std::make_pair(src_gate, dst_gate);
668 igraph_vector_int_t e_vec;
669 if (
auto res = igraph_vector_int_init(&e_vec, 2 * edges.size()); res != IGRAPH_SUCCESS)
671 return ERR(igraph_strerror(res));
675 for (
const auto& [src_gate, dst_gate] : edges)
677 if (
auto it = m_gates_to_nodes.find(src_gate); it != m_gates_to_nodes.end())
679 VECTOR(e_vec)[edge_index++] = it->second;
683 igraph_vector_int_destroy(&e_vec);
684 return ERR(
"no node for gate '" + src_gate->get_name() +
"' with ID " + std::to_string(src_gate->get_id()) +
" exists in graph for netlist with ID "
685 + std::to_string(m_nl->
get_id()));
688 if (
auto it = m_gates_to_nodes.find(dst_gate); it != m_gates_to_nodes.end())
690 VECTOR(e_vec)[edge_index++] = it->second;
694 igraph_vector_int_destroy(&e_vec);
695 return ERR(
"no node for gate '" + dst_gate->get_name() +
"' with ID " + std::to_string(dst_gate->get_id()) +
" exists in graph for netlist with ID "
696 + std::to_string(m_nl->
get_id()));
700 if (
auto res = igraph_add_edges(&m_graph, &e_vec,
nullptr); res != IGRAPH_SUCCESS)
702 igraph_vector_int_destroy(&e_vec);
703 return ERR(igraph_strerror(res));
711 igraph_vector_int_t e_vec;
712 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edges.size()); err != IGRAPH_SUCCESS)
714 return ERR(igraph_strerror(err));
717 u32 vcount = igraph_vcount(&m_graph);
720 for (
const auto& [src_vertex, dst_vertex] : edges)
722 if (src_vertex >= vcount)
724 igraph_vector_int_destroy(&e_vec);
725 return ERR(
"source vertex '" + std::to_string(src_vertex) +
"' does not exist in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
727 if (dst_vertex >= vcount)
729 igraph_vector_int_destroy(&e_vec);
730 return ERR(
"destination vertex '" + std::to_string(dst_vertex) +
"' does not exist in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
733 VECTOR(e_vec)[edge_index++] = src_vertex;
734 VECTOR(e_vec)[edge_index++] = dst_vertex;
737 if (
auto err = igraph_add_edges(&m_graph, &e_vec,
nullptr); err != IGRAPH_SUCCESS)
739 igraph_vector_int_destroy(&e_vec);
740 return ERR(igraph_strerror(err));
749 for (
const auto& [_, dst_gates] : edges)
751 edge_count += dst_gates.size();
754 igraph_vector_int_t e_vec;
755 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edge_count); err != IGRAPH_SUCCESS)
757 return ERR(igraph_strerror(err));
761 for (
const auto& [src_gate, dst_gates] : edges)
764 if (
auto it = m_gates_to_nodes.find(src_gate); it != m_gates_to_nodes.end())
766 src_vertex = it->second;
770 igraph_vector_int_destroy(&e_vec);
771 return ERR(
"no node for gate '" + src_gate->get_name() +
"' with ID " + std::to_string(src_gate->get_id()) +
" exists in graph for netlist with ID "
772 + std::to_string(m_nl->
get_id()));
775 for (
auto* dst_gate : dst_gates)
777 if (
auto it = m_gates_to_nodes.find(dst_gate); it != m_gates_to_nodes.end())
779 VECTOR(e_vec)[edge_index++] = src_vertex;
780 VECTOR(e_vec)[edge_index++] = it->second;
784 igraph_vector_int_destroy(&e_vec);
785 return ERR(
"no node for gate '" + dst_gate->get_name() +
"' with ID " + std::to_string(dst_gate->get_id()) +
" exists in graph for netlist with ID "
786 + std::to_string(m_nl->
get_id()));
791 if (
auto err = igraph_add_edges(&m_graph, &e_vec,
nullptr); err != IGRAPH_SUCCESS)
793 igraph_vector_int_destroy(&e_vec);
794 return ERR(igraph_strerror(err));
802 igraph_vector_int_t e_vec;
803 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edges.size()); err != IGRAPH_SUCCESS)
805 return ERR(igraph_strerror(err));
808 u32 vcount = igraph_vcount(&m_graph);
811 for (
const auto& [src_gate, dst_gate] : edges)
813 if (
auto it = m_gates_to_nodes.find(src_gate); it != m_gates_to_nodes.end())
815 VECTOR(e_vec)[edge_index++] = it->second;
819 igraph_vector_int_destroy(&e_vec);
820 return ERR(
"no node for gate '" + src_gate->get_name() +
"' with ID " + std::to_string(src_gate->get_id()) +
" exists in graph for netlist with ID "
821 + std::to_string(m_nl->
get_id()));
824 if (
auto it = m_gates_to_nodes.find(dst_gate); it != m_gates_to_nodes.end())
826 VECTOR(e_vec)[edge_index++] = it->second;
830 igraph_vector_int_destroy(&e_vec);
831 return ERR(
"no node for gate '" + dst_gate->get_name() +
"' with ID " + std::to_string(dst_gate->get_id()) +
" exists in graph for netlist with ID "
832 + std::to_string(m_nl->
get_id()));
837 if (
auto res = igraph_es_pairs(&e_sel, &e_vec, IGRAPH_DIRECTED); res != IGRAPH_SUCCESS)
839 igraph_vector_int_destroy(&e_vec);
840 return ERR(igraph_strerror(res));
843 if (
auto res = igraph_delete_edges(&m_graph, e_sel); res != IGRAPH_SUCCESS)
845 igraph_es_destroy(&e_sel);
846 igraph_vector_int_destroy(&e_vec);
847 return ERR(igraph_strerror(res));
850 igraph_es_destroy(&e_sel);
851 igraph_vector_int_destroy(&e_vec);
858 igraph_vector_int_t e_vec;
859 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edges.size()); err != IGRAPH_SUCCESS)
861 return ERR(igraph_strerror(err));
864 u32 vcount = igraph_vcount(&m_graph);
867 for (
const auto& [src_vertex, dst_vertex] : edges)
869 if (src_vertex >= vcount)
871 igraph_vector_int_destroy(&e_vec);
872 return ERR(
"source vertex '" + std::to_string(src_vertex) +
"' does not exist in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
874 if (dst_vertex >= vcount)
876 igraph_vector_int_destroy(&e_vec);
877 return ERR(
"destination vertex '" + std::to_string(dst_vertex) +
"' does not exist in graph for netlist with ID " + std::to_string(m_nl->
get_id()));
880 VECTOR(e_vec)[edge_index++] = src_vertex;
881 VECTOR(e_vec)[edge_index++] = dst_vertex;
885 if (
auto res = igraph_es_pairs(&e_sel, &e_vec, IGRAPH_DIRECTED); res != IGRAPH_SUCCESS)
887 igraph_vector_int_destroy(&e_vec);
888 return ERR(igraph_strerror(res));
891 if (
auto res = igraph_delete_edges(&m_graph, e_sel); res != IGRAPH_SUCCESS)
893 igraph_es_destroy(&e_sel);
894 igraph_vector_int_destroy(&e_vec);
895 return ERR(igraph_strerror(res));
898 igraph_es_destroy(&e_sel);
899 igraph_vector_int_destroy(&e_vec);
906 igraph_write_graph_edgelist(&m_graph, stdout);
A directed graph corresponding to a netlist.
Netlist * get_netlist() const
Get the netlist associated with the netlist graph.
u32 get_num_vertices(bool only_connected=false) const
Get the number of vertices in the netlist graph.
Result< std::vector< Gate * > > get_gates_from_vertices(const std::vector< u32 > &vertices) const
Get the gates corresponding to the specified vertices.
static Result< std::unique_ptr< NetlistGraph > > from_netlist(Netlist *nl, bool create_dummy_vertices=false, const std::function< bool(const Net *)> &filter=nullptr)
Create a directed graph from a netlist.
Result< Gate * > get_gate_from_vertex(const u32 vertex) const
Get the gate corresponding to the specified vertex.
Result< std::unique_ptr< NetlistGraph > > copy() const
Create a deep copy of the netlist graph.
Result< std::set< Gate * > > get_gates_set_from_vertices(const std::vector< u32 > &vertices) const
Get the gates corresponding to the specified vertices.
~NetlistGraph()
Default destructor for NetlistGraph.
Result< std::set< Gate * > > get_gates_set_from_vertices_igraph(const igraph_vector_int_t *vertices) const
Get the gates corresponding to the specified vertices.
@ ALL
Explore in both directions, i.e., treat the graph as undirected.
@ NONE
No direction, invalid default setting.
@ IN
Explore through the inputs of the current node, i.e., traverse backwards.
@ OUT
Explore through the outputs of the current node, i.e., traverse forwards.
Result< u32 > get_vertex_from_gate(Gate *g) const
Get the vertex corresponding to the specified gate.
Result< igraph_vector_int_t > get_vertices_from_gates_igraph(const std::vector< Gate * > &gates) const
Get the vertices corresponding to the specified gates.
Result< std::vector< u32 > > get_vertices_from_gates(const std::vector< Gate * > &gates) const
Get the vertices corresponding to the specified gates.
Result< std::monostate > add_edges(const std::vector< std::pair< Gate *, Gate * >> &edges)
Add edges between the specified pairs of source and destination gates to the netlist graph.
void print() const
Print the edge list of the graph to stdout.
Result< std::vector< Gate * > > get_gates_from_vertices_igraph(const igraph_vector_int_t *vertices) const
Get the gates corresponding to the specified vertices.
Result< std::vector< std::pair< u32, u32 > > > get_edges() const
Get the edges between vertices in the netlist graph.
u32 get_num_edges() const
Get the number of edges in the netlist graph.
Result< std::vector< std::pair< Gate *, Gate * > > > get_edges_in_netlist() const
Get the edges between gates in the netlist corresponding to the netlist graph.
Result< std::monostate > delete_edges(const std::vector< std::pair< Gate *, Gate * >> &edges)
Delete edges between the specified pairs of source and destination gates from the netlist graph.
Result< std::vector< u32 > > get_vertices(bool only_connected=false) const
Get the vertices in the netlist graph.
static Result< std::unique_ptr< NetlistGraph > > from_netlist_no_edges(Netlist *nl, const std::vector< Gate * > &gates={})
Create an empty directed graph from a netlist.
igraph_t * get_graph() const
Get the graph object of the netlist graph.
#define log_warning(channel,...)
This file contains the class that holds a netlist graph.