19 Result<z3::expr> get_function_of_net(
const std::vector<Gate*>& subgraph_gates,
22 std::map<u32, z3::expr>& net_cache,
25 if (
const auto it = net_cache.find(
net->get_id()); it != net_cache.end())
27 return OK(it->second);
30 const std::vector<Endpoint*> sources =
net->get_sources();
33 if (sources.size() > 1)
35 return ERR(
"cannot get Boolean z3 function of net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
": net is multi driven.");
41 z3::expr ret = ctx.bv_const(BooleanFunctionNetDecorator(*net).get_boolean_variable_name().c_str(), 1);
42 net_cache.insert({
net->get_id(), ret});
46 const Endpoint* src_ep = sources.front();
48 if (src_ep->get_gate() ==
nullptr)
50 return ERR(
"cannot get Boolean z3 function of net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
": net source is null.");
53 const Gate* src = src_ep->get_gate();
56 if (std::find(subgraph_gates.begin(), subgraph_gates.end(), src) == subgraph_gates.end())
58 z3::expr ret = ctx.bv_const(BooleanFunctionNetDecorator(*net).get_boolean_variable_name().c_str(), 1);
59 net_cache.insert({
net->get_id(), ret});
64 if (
const auto it = gate_cache.find({src->get_id(), src_ep->get_pin()}); it == gate_cache.end())
66 const auto bf_res = src->get_resolved_boolean_function(src_ep->get_pin());
67 if (bf_res.is_error())
70 "cannot get Boolean z3 function of net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
": failed to get function of gate.");
74 gate_cache.insert({{src->get_id(), src_ep->get_pin()}, bf});
81 std::map<std::string, z3::expr> input_to_expr;
83 for (
const std::string& in_net_str : bf.get_variable_names())
86 if (in_net_res.is_error())
89 "cannot get Boolean z3 function of net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
": failed to reconstruct input net from variable "
92 const auto in_net = in_net_res.get();
94 const auto in_bf_res = get_function_of_net(subgraph_gates, in_net, ctx, net_cache, gate_cache);
95 if (in_bf_res.is_error())
100 const auto in_bf = in_bf_res.get();
102 input_to_expr.insert({in_net_str, in_bf});
106 net_cache.insert({
net->get_id(), ret});
111 Result<z3::expr> get_subgraph_z3_function_internal(
const std::vector<Gate*>& subgraph_gates,
114 std::map<u32, z3::expr>& net_cache,
118 if (subgraph_gates.empty())
120 return ERR(
"could not get subgraph z3 function of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": subgraph contains no gates");
122 else if (std::any_of(subgraph_gates.begin(), subgraph_gates.end(), [](
const Gate* g) { return g == nullptr; }))
124 return ERR(
"could not get subgraph z3 function of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": subgraph contains a gate that is a 'nullptr'");
126 else if (
net ==
nullptr)
128 return ERR(
"could not get subgraph z3 function: net is a 'nullptr'");
130 else if (
net->get_num_of_sources() > 1)
132 return ERR(
"could not get subgraph z3 function of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": net has more than one source");
134 else if (
net->is_global_input_net())
136 const auto net_dec = BooleanFunctionNetDecorator(*
net);
137 return OK(ctx.bv_const(net_dec.get_boolean_variable_name().c_str(), 1));
139 else if (
net->get_num_of_sources() == 0)
141 return ERR(
"could not get subgraph function of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": net has no sources");
144 return get_function_of_net(subgraph_gates,
net, ctx, net_cache, gate_cache);
151 std::map<u32, z3::expr> net_cache;
154 return get_subgraph_z3_function_internal(subgraph_gates, subgraph_output, ctx, net_cache, gate_cache);
159 std::map<u32, z3::expr> net_cache;
162 std::vector<z3::expr> results;
164 for (
const auto&
net : subgraph_outputs)
166 const auto res = get_subgraph_z3_function_internal(subgraph_gates,
net, ctx, net_cache, gate_cache);
170 "unable to generate subgraph functions: failed to generate function for net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
".");
173 results.push_back(res.get());
static Result< Net * > get_net_from(const Netlist *netlist, const BooleanFunction &var)
std::map< std::pair< u32, const GatePin * >, BooleanFunction > SubgraphFunctionCache
#define ERR_APPEND(prev_error, message)
z3::expr from_bf(const BooleanFunction &bf, z3::context &ctx, const std::map< std::string, z3::expr > &var2expr={})
Result< z3::expr > get_subgraph_z3_function(const std::vector< Gate * > &subgraph_gates, const Net *subgraph_output, z3::context &ctx)
Get the z3 expression representation of a combined Boolean function of a subgraph of combinational ga...
Result< std::vector< z3::expr > > get_subgraph_z3_functions(const std::vector< Gate * > &subgraph_gates, const std::vector< Net * > &subgraph_outputs, z3::context &ctx)
Get the z3 expression representations of combined Boolean functions of a subgraph of combinational ga...