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))
19 m_graph_ptr = &m_graph;
21 for (
const auto& [node, gate] : m_nodes_to_gates)
25 m_gates_to_nodes[gate] = node;
32 igraph_destroy(&m_graph);
39 return ERR(
"netlist is a nullptr");
42 auto graph = std::unique_ptr<NetlistGraph>(
new NetlistGraph(nl));
46 for (
const auto*
net : graph->m_nl->get_nets(filter))
48 std::vector<Gate*> src_gates;
49 for (
const auto* src_ep :
net->get_sources())
51 src_gates.push_back(src_ep->get_gate());
54 std::vector<Gate*> dst_gates;
55 for (
const auto* dst_ep :
net->get_destinations())
57 dst_gates.push_back(dst_ep->get_gate());
60 if (src_gates.empty() && create_dummy_vertices)
64 edge_counter += dst_gates.size();
66 else if (dst_gates.empty() && create_dummy_vertices)
70 edge_counter += src_gates.size();
75 edge_counter += dst_gates.size() * src_gates.size();
80 igraph_vector_int_t edges;
81 auto err = igraph_vector_int_init(&edges, 2 * edge_counter);
82 if (err != IGRAPH_SUCCESS)
84 return ERR(igraph_strerror(err));
91 for (
auto*
g : graph->m_nl->get_gates())
93 const u32 node = node_counter++;
94 graph->m_gates_to_nodes[
g] = node;
95 graph->m_nodes_to_gates[node] =
g;
98 for (
const auto*
net : graph->m_nl->get_nets(filter))
100 std::vector<Gate*> src_gates;
101 for (
const auto* src_ep :
net->get_sources())
103 src_gates.push_back(src_ep->get_gate());
106 std::vector<Gate*> dst_gates;
107 for (
const auto* dst_ep :
net->get_destinations())
109 dst_gates.push_back(dst_ep->get_gate());
112 if (src_gates.empty() && create_dummy_vertices)
115 const u32 dummy_node = node_counter++;
116 graph->m_nodes_to_gates[dummy_node] =
nullptr;
117 for (
auto* dst_gate : dst_gates)
119 VECTOR(edges)[edge_index++] = dummy_node;
120 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(dst_gate);
123 else if (dst_gates.empty() && create_dummy_vertices)
126 const u32 dummy_node = node_counter++;
127 graph->m_nodes_to_gates[dummy_node] =
nullptr;
128 for (
auto* src_gate : src_gates)
130 VECTOR(edges)[edge_index++] = dummy_node;
131 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
136 for (
auto* dst_gate : dst_gates)
138 for (
auto* src_gate : src_gates)
140 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
141 VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(dst_gate);
147 graph->m_graph_ptr = &(graph->m_graph);
148 err = igraph_create(graph->m_graph_ptr, &edges, node_counter, IGRAPH_DIRECTED);
150 igraph_vector_int_destroy(&edges);
152 if (err != IGRAPH_SUCCESS)
154 return ERR(igraph_strerror(err));
157 return OK(std::move(graph));
164 return ERR(
"netlist is a nullptr");
167 auto graph = std::unique_ptr<NetlistGraph>(
new NetlistGraph(nl));
169 const auto& graph_gates = gates.empty() ? graph->m_nl->get_gates() : gates;
171 u32 node_counter = 0;
172 for (
auto*
g : graph_gates)
174 const u32 node = node_counter++;
175 graph->m_gates_to_nodes[
g] = node;
176 graph->m_nodes_to_gates[node] =
g;
179 graph->m_graph_ptr = &(graph->m_graph);
180 auto err = igraph_empty(graph->m_graph_ptr, node_counter, IGRAPH_DIRECTED);
181 if (err != IGRAPH_SUCCESS)
183 return ERR(igraph_strerror(err));
186 return OK(std::move(graph));
191 auto graph = std::unique_ptr<NetlistGraph>(
new NetlistGraph(m_nl));
193 if (
const auto res = igraph_copy(&(graph->m_graph), &(this->m_graph)); res != IGRAPH_SUCCESS)
195 return ERR(igraph_strerror(res));
198 graph->m_graph_ptr = &(graph->m_graph);
199 graph->m_gates_to_nodes = this->m_gates_to_nodes;
200 graph->m_nodes_to_gates = this->m_nodes_to_gates;
202 return OK(std::move(graph));
217 std::vector<Gate*> res;
218 for (
const auto& vertex : vertices)
220 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
222 Gate*
g = it->second;
227 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, added nullptr", vertex);
232 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
240 std::vector<Gate*> res;
241 for (
const auto& vertex : vertices)
243 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
245 Gate*
g = it->second;
250 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, added nullptr", vertex);
255 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
263 std::vector<Gate*> res;
264 const u32 num_vertices = igraph_vector_int_size(vertices);
265 for (
u32 i = 0; i < num_vertices; i++)
267 u32 vertex = VECTOR(*vertices)[i];
268 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
270 Gate*
g = it->second;
275 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, added nullptr", vertex);
280 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
289 for (
const auto& vertex : vertices)
291 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
293 Gate*
g = it->second;
297 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, skipping vertex", vertex);
304 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
313 for (
const auto& vertex : vertices)
315 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
317 Gate*
g = it->second;
321 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, skipping vertex", vertex);
328 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
337 const u32 num_vertices = igraph_vector_int_size(vertices);
338 for (
u32 i = 0; i < num_vertices; i++)
340 u32 vertex = VECTOR(*vertices)[i];
341 if (
const auto it = m_nodes_to_gates.find(vertex); it != m_nodes_to_gates.end())
343 Gate*
g = it->second;
347 log_warning(
"graph_algorithm",
"no gate exists for dummy vertex {}, skipping vertex", vertex);
354 return ERR(
"no gate for vertex " + std::to_string(vertex) +
" exists in netlist with ID " + std::to_string(m_nl->
get_id()));
365 return ERR(res.get_error());
368 return OK(res.get().front());
373 std::vector<u32> res;
374 for (
u32 i = 0; i < gates.size(); i++)
376 auto*
g = gates.at(i);
380 return ERR(
"gate at index " + std::to_string(i) +
" is a nullptr");
383 if (
const auto it = m_gates_to_nodes.find(
g); it != m_gates_to_nodes.end())
385 res.push_back(it->second);
389 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()));
397 std::vector<u32> res;
398 for (
auto*
g : gates)
402 return ERR(
"set of gates contains a nullptr");
405 if (
const auto it = m_gates_to_nodes.find(
g); it != m_gates_to_nodes.end())
407 res.push_back(it->second);
411 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()));
419 igraph_vector_int_t out;
420 if (
auto res = igraph_vector_int_init(&out, gates.size()); res != IGRAPH_SUCCESS)
422 return ERR(igraph_strerror(res));
425 for (
u32 i = 0; i < gates.size(); i++)
427 auto*
g = gates.at(i);
431 return ERR(
"gate at index " + std::to_string(i) +
" is a nullptr");
434 if (
const auto it = m_gates_to_nodes.find(
g); it != m_gates_to_nodes.end())
436 VECTOR(out)[i] = it->second;
440 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()));
443 return OK(std::move(out));
448 igraph_vector_int_t out;
449 if (
auto res = igraph_vector_int_init(&out, gates.size()); res != IGRAPH_SUCCESS)
451 return ERR(igraph_strerror(res));
455 for (
auto gates_it = gates.begin(); gates_it != gates.end(); gates_it++)
461 return ERR(
"gate at index " + std::to_string(i) +
" is a nullptr");
464 if (
const auto nodes_it = m_gates_to_nodes.find(
g); nodes_it != m_gates_to_nodes.end())
466 VECTOR(out)[i] = nodes_it->second;
470 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()));
475 return OK(std::move(out));
483 return ERR(res.get_error());
486 return OK(res.get().front());
491 u32 num_vertices = igraph_vcount(&m_graph);
499 u32 num_connected_vertices = 0;
501 igraph_vector_int_t degrees;
502 igraph_vector_int_init(°rees, num_vertices);
504 igraph_vs_t v_sel = igraph_vss_all();
505 igraph_degree(&m_graph, °rees, v_sel, IGRAPH_ALL, IGRAPH_LOOPS);
507 for (
u32 i = 0; i < num_vertices; i++)
509 if (VECTOR(degrees)[i] != 0)
511 num_connected_vertices++;
515 igraph_vector_int_destroy(°rees);
516 igraph_vs_destroy(&v_sel);
518 return num_connected_vertices;
524 return igraph_ecount(&m_graph);
529 u32 num_vertices = igraph_vcount(&m_graph);
533 std::vector<u32> vertices(num_vertices);
534 for (
u32 i = 0; i < num_vertices; i++)
542 std::vector<u32> vertices;
544 igraph_vector_int_t degrees;
545 if (
auto res = igraph_vector_int_init(°rees, num_vertices); res != IGRAPH_SUCCESS)
547 return ERR(igraph_strerror(res));
550 igraph_vs_t v_sel = igraph_vss_all();
551 if (
auto res = igraph_degree(&m_graph, °rees, v_sel, IGRAPH_ALL, IGRAPH_LOOPS); res != IGRAPH_SUCCESS)
553 igraph_vs_destroy(&v_sel);
554 igraph_vector_int_destroy(°rees);
555 return ERR(igraph_strerror(res));
558 for (
u32 i = 0; i < num_vertices; i++)
560 if (VECTOR(degrees)[i] != 0)
562 vertices.push_back(i);
566 igraph_vector_int_destroy(°rees);
567 igraph_vs_destroy(&v_sel);
575 const u32 ecount = igraph_ecount(&m_graph);
577 igraph_vector_int_t edges;
578 if (
auto res = igraph_vector_int_init(&edges, 2 * ecount); res != IGRAPH_SUCCESS)
580 return ERR(igraph_strerror(res));
583 if (
auto res = igraph_get_edgelist(&m_graph, &edges,
false); res != IGRAPH_SUCCESS)
585 igraph_vector_int_destroy(&edges);
586 return ERR(igraph_strerror(res));
589 std::vector<std::pair<u32, u32>> e_vec(ecount);
590 for (
u32 i = 0; i < ecount; i++)
592 const u32 src_vertex = (
u32)VECTOR(edges)[2 * i];
593 const u32 dst_vertex = (
u32)VECTOR(edges)[2 * i + 1];
595 e_vec[i] = std::make_pair(src_vertex, dst_vertex);
603 const u32 ecount = igraph_ecount(&m_graph);
605 igraph_vector_int_t edges;
606 if (
auto res = igraph_vector_int_init(&edges, 2 * ecount); res != IGRAPH_SUCCESS)
608 return ERR(igraph_strerror(res));
611 if (
auto res = igraph_get_edgelist(&m_graph, &edges,
false); res != IGRAPH_SUCCESS)
613 igraph_vector_int_destroy(&edges);
614 return ERR(igraph_strerror(res));
617 std::vector<std::pair<Gate*, Gate*>> e_vec(ecount);
618 for (
u32 i = 0; i < ecount; i++)
620 const u32 src_vertex = (
u32)VECTOR(edges)[2 * i];
621 const u32 dst_vertex = (
u32)VECTOR(edges)[2 * i + 1];
622 Gate *src_gate, *dst_gate;
624 if (
const auto it = m_nodes_to_gates.find(src_vertex); it != m_nodes_to_gates.end())
626 src_gate = it->second;
627 if (src_gate ==
nullptr)
630 "ignored edge (" + std::to_string(src_vertex) +
"," + std::to_string(dst_vertex) +
") at dummy source vertex '" + std::to_string(src_vertex) +
"'");
635 if (
const auto it = m_nodes_to_gates.find(dst_vertex); it != m_nodes_to_gates.end())
637 dst_gate = it->second;
638 if (dst_gate ==
nullptr)
641 "ignored edge (" + std::to_string(src_vertex) +
"," + std::to_string(dst_vertex) +
") at dummy destination vertex '" + std::to_string(dst_vertex) +
"'");
646 e_vec[i] = std::make_pair(src_gate, dst_gate);
654 igraph_vector_int_t e_vec;
655 if (
auto res = igraph_vector_int_init(&e_vec, 2 * edges.size()); res != IGRAPH_SUCCESS)
657 return ERR(igraph_strerror(res));
661 for (
const auto& [src_gate, dst_gate] : edges)
663 if (
auto it = m_gates_to_nodes.find(src_gate); it != m_gates_to_nodes.end())
665 VECTOR(e_vec)[edge_index++] = it->second;
669 igraph_vector_int_destroy(&e_vec);
670 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 "
671 + std::to_string(m_nl->
get_id()));
674 if (
auto it = m_gates_to_nodes.find(dst_gate); it != m_gates_to_nodes.end())
676 VECTOR(e_vec)[edge_index++] = it->second;
680 igraph_vector_int_destroy(&e_vec);
681 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 "
682 + std::to_string(m_nl->
get_id()));
686 if (
auto res = igraph_add_edges(&m_graph, &e_vec,
nullptr); res != IGRAPH_SUCCESS)
688 igraph_vector_int_destroy(&e_vec);
689 return ERR(igraph_strerror(res));
697 igraph_vector_int_t e_vec;
698 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edges.size()); err != IGRAPH_SUCCESS)
700 return ERR(igraph_strerror(err));
703 u32 vcount = igraph_vcount(&m_graph);
706 for (
const auto& [src_vertex, dst_vertex] : edges)
708 if (src_vertex >= vcount)
710 igraph_vector_int_destroy(&e_vec);
711 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()));
713 if (dst_vertex >= vcount)
715 igraph_vector_int_destroy(&e_vec);
716 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()));
719 VECTOR(e_vec)[edge_index++] = src_vertex;
720 VECTOR(e_vec)[edge_index++] = dst_vertex;
723 if (
auto err = igraph_add_edges(&m_graph, &e_vec,
nullptr); err != IGRAPH_SUCCESS)
725 igraph_vector_int_destroy(&e_vec);
726 return ERR(igraph_strerror(err));
735 for (
const auto& [_, dst_gates] : edges)
737 edge_count += dst_gates.size();
740 igraph_vector_int_t e_vec;
741 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edge_count); err != IGRAPH_SUCCESS)
743 return ERR(igraph_strerror(err));
747 for (
const auto& [src_gate, dst_gates] : edges)
750 if (
auto it = m_gates_to_nodes.find(src_gate); it != m_gates_to_nodes.end())
752 src_vertex = it->second;
756 igraph_vector_int_destroy(&e_vec);
757 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 "
758 + std::to_string(m_nl->
get_id()));
761 for (
auto* dst_gate : dst_gates)
763 if (
auto it = m_gates_to_nodes.find(dst_gate); it != m_gates_to_nodes.end())
765 VECTOR(e_vec)[edge_index++] = src_vertex;
766 VECTOR(e_vec)[edge_index++] = it->second;
770 igraph_vector_int_destroy(&e_vec);
771 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 "
772 + std::to_string(m_nl->
get_id()));
777 if (
auto err = igraph_add_edges(&m_graph, &e_vec,
nullptr); err != IGRAPH_SUCCESS)
779 igraph_vector_int_destroy(&e_vec);
780 return ERR(igraph_strerror(err));
788 igraph_vector_int_t e_vec;
789 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edges.size()); err != IGRAPH_SUCCESS)
791 return ERR(igraph_strerror(err));
794 u32 vcount = igraph_vcount(&m_graph);
797 for (
const auto& [src_gate, dst_gate] : edges)
799 if (
auto it = m_gates_to_nodes.find(src_gate); it != m_gates_to_nodes.end())
801 VECTOR(e_vec)[edge_index++] = it->second;
805 igraph_vector_int_destroy(&e_vec);
806 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 "
807 + std::to_string(m_nl->
get_id()));
810 if (
auto it = m_gates_to_nodes.find(dst_gate); it != m_gates_to_nodes.end())
812 VECTOR(e_vec)[edge_index++] = it->second;
816 igraph_vector_int_destroy(&e_vec);
817 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 "
818 + std::to_string(m_nl->
get_id()));
823 if (
auto res = igraph_es_pairs(&e_sel, &e_vec, IGRAPH_DIRECTED); res != IGRAPH_SUCCESS)
825 igraph_vector_int_destroy(&e_vec);
826 return ERR(igraph_strerror(res));
829 if (
auto res = igraph_delete_edges(&m_graph, e_sel); res != IGRAPH_SUCCESS)
831 igraph_es_destroy(&e_sel);
832 igraph_vector_int_destroy(&e_vec);
833 return ERR(igraph_strerror(res));
836 igraph_es_destroy(&e_sel);
837 igraph_vector_int_destroy(&e_vec);
844 igraph_vector_int_t e_vec;
845 if (
auto err = igraph_vector_int_init(&e_vec, 2 * edges.size()); err != IGRAPH_SUCCESS)
847 return ERR(igraph_strerror(err));
850 u32 vcount = igraph_vcount(&m_graph);
853 for (
const auto& [src_vertex, dst_vertex] : edges)
855 if (src_vertex >= vcount)
857 igraph_vector_int_destroy(&e_vec);
858 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()));
860 if (dst_vertex >= vcount)
862 igraph_vector_int_destroy(&e_vec);
863 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()));
866 VECTOR(e_vec)[edge_index++] = src_vertex;
867 VECTOR(e_vec)[edge_index++] = dst_vertex;
871 if (
auto res = igraph_es_pairs(&e_sel, &e_vec, IGRAPH_DIRECTED); res != IGRAPH_SUCCESS)
873 igraph_vector_int_destroy(&e_vec);
874 return ERR(igraph_strerror(res));
877 if (
auto res = igraph_delete_edges(&m_graph, e_sel); res != IGRAPH_SUCCESS)
879 igraph_es_destroy(&e_sel);
880 igraph_vector_int_destroy(&e_vec);
881 return ERR(igraph_strerror(res));
884 igraph_es_destroy(&e_sel);
885 igraph_vector_int_destroy(&e_vec);
892 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.