18 Result<z3::expr> get_function_of_net(
const std::vector<Gate*>& subgraph_gates,
21 std::map<u32, z3::expr>& net_cache,
22 std::map<std::pair<u32, const GatePin*>, BooleanFunction>& gate_cache)
24 if (
const auto it = net_cache.find(
net->get_id()); it != net_cache.end())
26 return OK(it->second);
29 const std::vector<Endpoint*> sources =
net->get_sources();
32 if (sources.size() > 1)
34 return ERR(
"cannot get Boolean z3 function of net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
": net is multi driven.");
40 z3::expr ret = ctx.bv_const(BooleanFunctionNetDecorator(*net).get_boolean_variable_name().c_str(), 1);
41 net_cache.insert({
net->get_id(), ret});
45 const Endpoint* src_ep = sources.front();
47 if (src_ep->get_gate() ==
nullptr)
49 return ERR(
"cannot get Boolean z3 function of net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
": net source is null.");
52 const Gate* src = src_ep->get_gate();
55 if (std::find(subgraph_gates.begin(), subgraph_gates.end(), src) == subgraph_gates.end())
57 z3::expr ret = ctx.bv_const(BooleanFunctionNetDecorator(*net).get_boolean_variable_name().c_str(), 1);
58 net_cache.insert({
net->get_id(), ret});
63 if (
const auto it = gate_cache.find({src->get_id(), src_ep->get_pin()}); it == gate_cache.end())
65 const auto bf_res = src->get_resolved_boolean_function(src_ep->get_pin());
66 if (bf_res.is_error())
69 "cannot get Boolean z3 function of net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
": failed to get function of gate.");
73 gate_cache.insert({{src->get_id(), src_ep->get_pin()}, bf});
80 std::map<std::string, z3::expr> input_to_expr;
82 for (
const std::string& in_net_str : bf.get_variable_names())
85 if (in_net_res.is_error())
88 "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 "
91 const auto in_net = in_net_res.get();
93 const auto in_bf_res = get_function_of_net(subgraph_gates, in_net, ctx, net_cache, gate_cache);
94 if (in_bf_res.is_error())
99 const auto in_bf = in_bf_res.get();
101 input_to_expr.insert({in_net_str, in_bf});
105 net_cache.insert({
net->get_id(), ret});
110 Result<z3::expr> get_subgraph_z3_function_internal(
const std::vector<Gate*>& subgraph_gates,
113 std::map<u32, z3::expr>& net_cache,
114 std::map<std::pair<u32, const GatePin*>, BooleanFunction>& gate_cache)
117 if (subgraph_gates.empty())
119 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");
121 else if (std::any_of(subgraph_gates.begin(), subgraph_gates.end(), [](
const Gate* g) { return g == nullptr; }))
123 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'");
125 else if (
net ==
nullptr)
127 return ERR(
"could not get subgraph z3 function: net is a 'nullptr'");
129 else if (
net->get_num_of_sources() > 1)
131 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");
133 else if (
net->is_global_input_net())
135 const auto net_dec = BooleanFunctionNetDecorator(*
net);
136 return OK(ctx.bv_const(net_dec.get_boolean_variable_name().c_str(), 1));
138 else if (
net->get_num_of_sources() == 0)
140 return ERR(
"could not get subgraph function of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": net has no sources");
143 return get_function_of_net(subgraph_gates,
net, ctx, net_cache, gate_cache);
150 std::map<u32, z3::expr> net_cache;
153 return get_subgraph_z3_function_internal(subgraph_gates, subgraph_output, ctx, net_cache, gate_cache);
158 std::map<u32, z3::expr> net_cache;
161 std::vector<z3::expr> results;
163 for (
const auto&
net : subgraph_outputs)
165 const auto res = get_subgraph_z3_function_internal(subgraph_gates,
net, ctx, net_cache, gate_cache);
169 "unable to generate subgraph functions: failed to generate function for net " +
net->get_name() +
" with ID " + std::to_string(
net->get_id()) +
".");
172 results.push_back(res.get());
static Result< Net * > get_net_from(const Netlist *netlist, const BooleanFunction &var)
#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...