HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
boolean_influence.cpp
Go to the documentation of this file.
2 
7 #include "hal_core/netlist/net.h"
10 #include "z3_utils/z3_utils.h"
11 
12 #include <filesystem>
13 #include <fstream>
14 
15 namespace hal
16 {
17  namespace boolean_influence
18  {
19  namespace
20  {
21  const std::string probabilistic_function = R"(
22 #include <stdbool.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 static unsigned long x=123456789, y=362436069, z=521288629;
27 
28 // period 2^96-1
29 unsigned long xorshf96(void) {
30  unsigned long t;
31 
32  x ^= x << 16;
33  x ^= x >> 5;
34  x ^= x << 1;
35 
36  t = x;
37  x = y;
38  y = z;
39  z = t ^ x ^ y;
40 
41  return z;
42 }
43 
44 <C_FUNCTION>
45 
46 const int input_size = <INPUT_SIZE>;
47 
48 void build_values(bool* values) {
49  for (int i = 0; i < input_size; i++) {
50  bool random_value = xorshf96() % 2;
51  values[i] = random_value;
52  }
53 
54  return;
55 }
56 
57 int main(int argc, char *argv[]) {
58  unsigned long long b = strtoull(argv[1], 0, 10);
59  unsigned long long num = strtoull(argv[2], 0, 10);
60  unsigned long long count = 0;
61 
62  bool values[input_size];
63  for (unsigned long long i = 0; i < num; i++) {
64  build_values(values);
65 
66  values[b] = true;
67  bool r1 = func(values);
68 
69  values[b] = false;
70  bool r2 = func(values);
71 
72  if (r1 != r2) {
73  count++;
74  }
75  }
76 
77  printf("%lld\n", count);
78 
79  return int(count);
80 })";
81 
82  const std::string deterministic_function = R"(
83 #include <stdbool.h>
84 #include <stdio.h>
85 #include <stdlib.h>
86 
87 <C_FUNCTION>
88 
89 const int input_size = <INPUT_SIZE>;
90 
91 void build_values(bool* values, unsigned long long val) {
92  for (int idx = 0; idx < input_size; idx++) {
93  values[idx] = (val >> idx) & 0x1;
94  }
95 
96  return;
97 }
98 
99 int main(int argc, char *argv[]) {
100  unsigned long long b = strtoull(argv[1], 0, 10);
101  unsigned long long count = 0;
102 
103  bool values[input_size];
104  for (unsigned long long i = 0; i < (1 << input_size); i++) {
105  build_values(values, i);
106 
107  values[b] = true;
108  bool r1 = func(values);
109 
110  values[b] = false;
111  bool r2 = func(values);
112 
113  if (r1 != r2) {
114  count++;
115  }
116  }
117 
118  printf("%lld\n", count);
119 
120  return int(count);
121 })";
122 
123  // period 2^96-1
124  unsigned long xorshf96(u64& x, u64& y, u64& z)
125  {
126  unsigned long t;
127 
128  x ^= x << 16;
129  x ^= x >> 5;
130  x ^= x << 1;
131 
132  t = x;
133  x = y;
134  y = z;
135  z = t ^ x ^ y;
136 
137  return z;
138  }
139 
140  Result<std::unordered_map<std::string, double>> get_boolean_influence_internal(const z3::expr& expr, const u32 num_evaluations, const bool deterministic)
141  {
142  const auto to_replacement_var = [](const u32 var_idx) -> std::string { return "var_" + std::to_string(var_idx); };
143 
144  const auto extract_index = [](const std::string& var) -> Result<u32> {
145  if (!utils::starts_with(var, std::string("var_")))
146  {
147  return ERR("variable " + var + " does not start with prefix 'var_', so we cannot extract an index.");
148  }
149 
150  try
151  {
152  return OK(u32(std::stoul(var.substr(4))));
153  }
154  catch (const std::invalid_argument& e)
155  {
156  return ERR("could not get index from string '" + var + "': " + e.what());
157  }
158  catch (const std::out_of_range& e)
159  {
160  return ERR("could not get index from string '" + var + "': " + e.what());
161  }
162  };
163 
164  const auto to_original_var = [extract_index](const std::string& replacement_var, const std::vector<std::string>& original_vars) -> Result<std::string> {
165  const auto var_idx_res = extract_index(replacement_var);
166  if (var_idx_res.is_error())
167  {
168  return ERR_APPEND(var_idx_res.get_error(), "unable to reconstruct original variable from replacement variable" + replacement_var + ": failed to extract index.");
169  }
170  const auto var_idx = var_idx_res.get();
171 
172  if (var_idx > original_vars.size())
173  {
174  return ERR("unable to reconstruct original variable from replacement variable" + replacement_var + ": extracted index " + std::to_string(var_idx)
175  + " is bigger than the size of the original vars (" + std::to_string(original_vars.size()) + ").");
176  }
177 
178  return OK(original_vars.at(var_idx));
179  };
180 
181  std::unordered_map<std::string, double> influences;
182 
183  // substitute all variables in the expression to be of the format var_<INDEX>.
184  // This allows for a more efficient translation into a c function
185  std::vector<std::string> input_vars = utils::to_vector(z3_utils::get_variable_names(expr));
186 
187  if (input_vars.empty())
188  {
189  return OK(influences);
190  }
191 
192  if (deterministic && input_vars.size() > 16)
193  {
194  return ERR("unable to generate Boolean influence: Cannot evaluate Boolean function deterministically for more than 16 variables but got " + std::to_string(input_vars.size()));
195  }
196 
197  std::vector<std::string> replacement_vars;
198 
199  z3::expr_vector from_vec(expr.ctx());
200  z3::expr_vector to_vec(expr.ctx());
201 
202  for (u32 var_idx = 0; var_idx < input_vars.size(); var_idx++)
203  {
204  replacement_vars.push_back(to_replacement_var(var_idx));
205 
206  z3::expr from = expr.ctx().bv_const(input_vars.at(var_idx).c_str(), 1);
207  z3::expr to = expr.ctx().bv_const(to_replacement_var(var_idx).c_str(), 1);
208 
209  from_vec.push_back(from);
210  to_vec.push_back(to);
211  }
212 
213  auto replaced_e = expr;
214  replaced_e = replaced_e.substitute(from_vec, to_vec);
215 
216  // translate expression into a c program
217  auto directory_res = utils::get_unique_temp_directory("boolean_influence_");
218  if (directory_res.is_error())
219  {
220  return ERR_APPEND(directory_res.get_error(), "unable to generate Boolean influence: could not create temporary directory");
221  }
222  const std::filesystem::path directory = directory_res.get();
223  std::filesystem::create_directory(directory);
224  const std::filesystem::path file_path = directory / "boolean_func.cpp";
225 
226  std::string cpp_program = deterministic ? deterministic_function : probabilistic_function;
227  cpp_program = utils::replace(cpp_program, std::string("<C_FUNCTION>"), z3_utils::to_cpp(replaced_e));
228  cpp_program = utils::replace(cpp_program, std::string("<INPUT_SIZE>"), std::to_string(replacement_vars.size()));
229 
230  // write cpp program to file
231  std::ofstream ofs(file_path);
232  if (!ofs.is_open())
233  {
234  return ERR("unable to generate Boolean influence: could not open file " + file_path.string() + ".");
235  }
236  ofs << cpp_program;
237 
238  ofs.close();
239 
240  // compile the cpp file
241  const std::string program_name = file_path.string().substr(0, file_path.string().size() - 4);
242  const std::string compile_command = "g++ -o " + program_name + " " + file_path.string() + " -O3";
243  int res = system(compile_command.c_str());
244  UNUSED(res);
245 
246  // run boolean function program for every input
247  for (const auto& var : replacement_vars)
248  {
249  const auto idx_res = extract_index(var);
250  if (idx_res.is_error())
251  {
252  return ERR_APPEND(idx_res.get_error(), "unable to generate Boolean influence: failed to extract index from variable " + var + ".");
253  }
254  const auto idx = idx_res.get();
255 
256  const std::string num_evaluations_str = deterministic ? "" : std::to_string(num_evaluations);
257 
258  const std::string run_command = program_name + " " + std::to_string(idx) + " " + num_evaluations_str + " 2>&1";
259 
260  std::array<char, 128> buffer;
261  std::string result;
262 
263  FILE* pipe = popen(run_command.c_str(), "r");
264  if (!pipe)
265  {
266  return ERR("unable to generate Boolean influence: error during execution of compiled boolean program");
267  }
268  while (fgets(buffer.data(), 128, pipe) != NULL)
269  {
270  result += buffer.data();
271  }
272 
273  pclose(pipe);
274 
275  const u32 count = std::stoi(result);
276  const u32 real_evaluations = deterministic ? (1 << input_vars.size()) : num_evaluations;
277  double cv = (double)(count) / (double)(real_evaluations);
278 
279  const auto org_var_res = to_original_var(var, input_vars);
280  if (org_var_res.is_error())
281  {
282  return ERR_APPEND(org_var_res.get_error(), "unable to generate Boolean influence: failed to reconstruct original variable from replacement variable " + var + ".");
283  }
284  const auto org_var = org_var_res.get();
285 
286  influences.insert({org_var, cv});
287  }
288 
289  // delete files and temp directory
290  std::remove(file_path.string().c_str());
291  std::remove(program_name.c_str());
292  std::filesystem::remove(directory);
293 
294  return OK(influences);
295  }
296 
297  Result<std::map<Net*, double>> get_boolean_influences_of_subcircuit_internal(const std::vector<Gate*>& gates, const Net* start_net, const u32 num_evaluations, const bool deterministic)
298  {
299  for (const auto* gate : gates)
300  {
301  if (!gate->get_type()->has_property(GateTypeProperty::combinational) || gate->is_vcc_gate() || gate->is_gnd_gate())
302  {
303  return ERR("unable to get Boolean influence for net " + start_net->get_name() + " with ID " + std::to_string(start_net->get_id()) + ": sub circuit gates include gate "
304  + gate->get_name() + " with ID " + std::to_string(gate->get_id()) + " that is either not a combinational gate or is a VCC / GND gate.");
305  }
306  }
307 
308  // Generate function for the data port
309  auto ctx = z3::context();
310  auto func = z3::expr(ctx);
311 
312  if (!gates.empty())
313  {
314  const auto func_res = z3_utils::get_subgraph_z3_function(gates, start_net, ctx);
315  if (func_res.is_error())
316  {
317  return ERR_APPEND(func_res.get_error(),
318  "unable to get Boolean influence for net " + start_net->get_name() + " with ID " + std::to_string(start_net->get_id())
319  + ": failed to build subgraph function");
320  }
321  func = func_res.get();
322  }
323  // edge case if the gates are empty
324  else
325  {
326  func = ctx.bv_const(BooleanFunctionNetDecorator(*start_net).get_boolean_variable_name().c_str(), 1);
327  }
328 
329  // Generate Boolean influences
330  const auto inf_res = get_boolean_influence_internal(func, num_evaluations, deterministic);
331  if (inf_res.is_error())
332  {
333  return ERR_APPEND(inf_res.get_error(),
334  "unable to get Boolean influence for net " + start_net->get_name() + " with ID " + std::to_string(start_net->get_id())
335  + ": failed to get boolean influence for net " + start_net->get_name() + " with ID " + std::to_string(start_net->get_id()) + ".");
336  }
337  const std::unordered_map<std::string, double> var_names_to_inf = inf_res.get();
338 
339  // translate net_ids back to nets
340  std::map<Net*, double> nets_to_inf;
341 
342  Netlist* nl = start_net->get_netlist();
343  for (const auto& [var_name, inf] : var_names_to_inf)
344  {
345  const auto net_res = BooleanFunctionNetDecorator::get_net_from(nl, var_name);
346  if (net_res.is_error())
347  {
348  return ERR_APPEND(net_res.get_error(),
349  "unable to get Boolean influence for net " + start_net->get_name() + " with ID " + std::to_string(start_net->get_id())
350  + ": failed to reconstruct net from variable " + var_name + ".");
351  }
352  const auto net = net_res.get();
353 
354  nets_to_inf.insert({net, inf});
355  }
356 
357  return OK(nets_to_inf);
358  }
359 
360  Result<std::map<Net*, double>> get_boolean_influences_of_gate_internal(const Gate* gate, const u32 num_evaluations, const bool deterministic)
361  {
362  if (!gate->get_type()->has_property(GateTypeProperty::ff))
363  {
364  return ERR("unable to get Boolean influence for gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id()) + ": can only handle flip-flops but found gate type "
365  + gate->get_type()->get_name() + ".");
366  }
367 
368  // Check for the data port pin
369  auto d_pins = gate->get_type()->get_pins([](const GatePin* p) { return p->get_direction() == PinDirection::input && p->get_type() == PinType::data; });
370  if (d_pins.size() != 1)
371  {
372  return ERR("unable to get Boolean influence for gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id())
373  + ": can only handle flip-flops with exactly one data port, but found " + std::to_string(d_pins.size()) + ".");
374  }
375  const GatePin* data_pin = d_pins.front();
376  const Net* data_net = gate->get_fan_in_net(data_pin);
377 
378  if (data_net == nullptr)
379  {
380  return ERR("unable to get Boolean influence for gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id()) + ": failed to find net at data pin "
381  + data_pin->get_name());
382  }
383 
384  // Extract all gates in front of the data port and iterate backwards until another flip flop is found.
385  const auto function_gates_res = NetlistTraversalDecorator(*(gate->get_netlist())).get_next_combinational_gates(data_net, false);
386  if (function_gates_res.is_error())
387  {
388  return ERR_APPEND(function_gates_res.get_error(),
389  "unable to get Boolean influence for gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id()) + ": failed to get combinational fan-in gates.");
390  }
391  const auto function_gates = utils::to_vector(function_gates_res.get());
392 
393  // Generate Boolean influences
394  const auto inf_res = get_boolean_influences_of_subcircuit_internal(function_gates, data_net, num_evaluations, deterministic);
395  if (inf_res.is_error())
396  {
397  return ERR_APPEND(inf_res.get_error(),
398  "unable to get Boolean influence for gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id()) + ": failed to get Boolean influence for data net "
399  + data_net->get_name() + " with ID " + std::to_string(data_net->get_id()) + ".");
400  }
401 
402  return inf_res;
403  }
404 
405  } // namespace
406 
408  {
409  auto ctx = z3::context();
410  const auto z3_bf = z3_utils::from_bf(bf, ctx);
411 
412  return get_boolean_influence(z3_bf, num_evaluations);
413  }
414 
415  Result<std::unordered_map<std::string, double>> get_boolean_influence(const z3::expr& expr, const u32 num_evaluations)
416  {
417  return get_boolean_influence_internal(expr, num_evaluations, false);
418  }
419 
421  {
422  auto ctx = z3::context();
423  const auto z3_bf = z3_utils::from_bf(bf, ctx);
424 
426  }
427 
429  {
430  return get_boolean_influence_internal(expr, 0, true);
431  }
432 
433  Result<std::map<Net*, double>> get_boolean_influences_of_subcircuit(const std::vector<Gate*>& gates, const Net* start_net, const u32 num_evaluations)
434  {
435  return get_boolean_influences_of_subcircuit_internal(gates, start_net, num_evaluations, false);
436  }
437 
439  {
440  return get_boolean_influences_of_gate_internal(gate, num_evaluations, false);
441  }
442 
444  {
445  return get_boolean_influences_of_subcircuit_internal(gates, start_net, 0, true);
446  }
447 
449  {
450  return get_boolean_influences_of_gate_internal(gate, 0, true);
451  }
452 
454  {
455  std::unordered_map<std::string, double> influences;
456  std::set<std::string> variables = bf.get_variable_names();
457 
458  u64 x = 123456789, y = 362436069, z = 521288629;
459 
460  for (const auto& var : variables)
461  {
462  u32 count = 0;
463  for (unsigned long long i = 0; i < num_evaluations; i++)
464  {
465  std::unordered_map<std::string, BooleanFunction::Value> values;
466  // build value
467  for (const auto& var_to_set : variables)
468  {
469  if (var == var_to_set)
470  {
471  continue;
472  }
473 
474  BooleanFunction::Value random_value = (xorshf96(x, y, z) % 2) ? BooleanFunction::Value::ONE : BooleanFunction::Value::ZERO;
475  values.insert({var_to_set, random_value});
476  }
477 
478  // evaluate 1
479  values[var] = BooleanFunction::Value::ONE;
480  const auto res_1 = bf.evaluate(values);
481  if (res_1.is_error())
482  {
483  return ERR_APPEND(res_1.get_error(), "unable to evaluate boolean function ");
484  }
485 
486  // evaluate 0
487  values[var] = BooleanFunction::Value::ZERO;
488  const auto res_2 = bf.evaluate(values);
489  if (res_2.is_error())
490  {
491  return ERR_APPEND(res_2.get_error(), "unable to evaluate boolean function ");
492  }
493 
494  const auto r1 = res_1.get();
495  const auto r2 = res_2.get();
496 
497  if (r1 != r2)
498  {
499  count++;
500  }
501  }
502  double cv = (double)(count) / (double)(num_evaluations);
503  influences.insert({var, cv});
504  }
505 
506  return OK(influences);
507  }
508 
510  {
511  std::unordered_map<std::string, double> influences;
512  std::set<std::string> variables = bf.get_variable_names();
513 
514  auto ctx = z3::context();
515  auto z3_bf = z3_utils::from_bf(bf, ctx);
516 
517  u64 x = 123456789, y = 362436069, z = 521288629;
518 
519  for (const auto& var : variables)
520  {
521  const auto var_expr = ctx.bv_const(var.c_str(), 1);
522 
523  u32 count = 0;
524  for (unsigned long long i = 0; i < num_evaluations; i++)
525  {
526  z3::expr_vector from_vec(ctx);
527  z3::expr_vector to_vec(ctx);
528 
529  // build value
530  for (const auto& var_to_set : variables)
531  {
532  if (var == var_to_set)
533  {
534  continue;
535  }
536 
537  const auto var_to_set_expr = ctx.bv_const(var_to_set.c_str(), 1);
538 
539  auto random_value = (xorshf96(x, y, z) % 2) ? ctx.bv_val(1, 1) : ctx.bv_val(0, 1);
540 
541  from_vec.push_back(var_to_set_expr);
542  to_vec.push_back(random_value);
543  }
544 
545  auto z3_bf_substitute = z3_bf.substitute(from_vec, to_vec).simplify();
546 
547  z3::expr_vector from_vec_var(ctx);
548  z3::expr_vector to_vec_one(ctx);
549  z3::expr_vector to_vec_zero(ctx);
550 
551  from_vec_var.push_back(var_expr);
552  to_vec_one.push_back(ctx.bv_val(1, 1));
553  to_vec_zero.push_back(ctx.bv_val(0, 1));
554 
555  // evaluate 1
556  const auto res_1 = z3_bf_substitute.substitute(from_vec_var, to_vec_one).simplify();
557  if (!res_1.is_numeral())
558  {
559  std::cout << res_1 << std::endl;
560  return ERR("cannot determine boolean influence of variabel " + var + ": failed to simplify to a constant");
561  }
562 
563  // evaluate 0
564  const auto res_2 = z3_bf_substitute.substitute(from_vec_var, to_vec_zero).simplify();
565  if (!res_2.is_numeral())
566  {
567  std::cout << res_2 << std::endl;
568  return ERR("cannot determine boolean influence of variabel " + var + ": failed to simplify to a constant");
569  }
570 
571  const auto r1 = res_1.get_numeral_uint64();
572  const auto r2 = res_2.get_numeral_uint64();
573 
574  if (r1 != r2)
575  {
576  count++;
577  }
578  }
579  double cv = (double)(count) / (double)(num_evaluations);
580  influences.insert({var, cv});
581  }
582 
583  return OK(influences);
584  }
585 
586  Result<std::pair<std::map<u32, Gate*>, std::vector<std::vector<double>>>> get_ff_dependency_matrix(const Netlist* nl, bool with_boolean_influence)
587  {
588  std::map<u32, Gate*> matrix_id_to_gate;
589  std::map<Gate*, u32> gate_to_matrix_id;
590  std::vector<std::vector<double>> matrix;
591 
592  std::unordered_map<const Net*, std::set<Gate*>>* cache;
593 
594  u32 matrix_gates = 0;
595  for (const auto& gate : nl->get_gates())
596  {
597  if (!gate->get_type()->has_property(GateTypeProperty::ff))
598  {
599  continue;
600  }
601  gate_to_matrix_id[gate] = matrix_gates;
602  matrix_id_to_gate[matrix_gates] = gate;
603  matrix_gates++;
604  }
605 
606  u32 status_counter = 0;
607  for (const auto& [id, gate] : matrix_id_to_gate)
608  {
609  if (status_counter % 100 == 0)
610  {
611  log_info("boolean_influence", "status {}/{} processed", status_counter, matrix_id_to_gate.size());
612  }
613  status_counter++;
614  std::vector<double> line_of_matrix;
615 
616  std::set<u32> gates_to_add;
617  const auto next_seq_gates = NetlistTraversalDecorator(*nl).get_next_sequential_gates(gate, false, {}, cache);
618  if (next_seq_gates.is_error())
619  {
620  return ERR_APPEND(next_seq_gates.get_error(),
621  "unable to generate ff dependency matrix: failed to generate Boolean influence for gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id())
622  + ": failed to get next sequential gates.");
623  }
624  for (const auto& pred_gate : next_seq_gates.get())
625  {
626  gates_to_add.insert(gate_to_matrix_id[pred_gate]);
627  }
628  std::map<Net*, double> boolean_influence_for_gate;
629  if (with_boolean_influence)
630  {
631  const auto inf_res = get_boolean_influences_of_gate(gate);
632  if (inf_res.is_error())
633  {
634  return ERR_APPEND(inf_res.get_error(),
635  "unable to generate ff dependency matrix: failed to generate Boolean influence for gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id())
636  + ".");
637  }
638  boolean_influence_for_gate = inf_res.get();
639  }
640 
641  for (u32 i = 0; i < matrix_gates; i++)
642  {
643  if (gates_to_add.find(i) != gates_to_add.end())
644  {
645  if (with_boolean_influence)
646  {
647  double influence = 0.0;
648 
649  Gate* pred_ff = matrix_id_to_gate[i];
650 
651  for (const auto& output_net : pred_ff->get_fan_out_nets())
652  {
653  if (boolean_influence_for_gate.find(output_net) != boolean_influence_for_gate.end())
654  {
655  influence += boolean_influence_for_gate[output_net];
656  }
657  }
658 
659  line_of_matrix.push_back(influence);
660  }
661  else
662  {
663  line_of_matrix.push_back(1.0);
664  }
665  }
666  else
667  {
668  line_of_matrix.push_back(0.0);
669  }
670  }
671  matrix.push_back(line_of_matrix);
672  }
673 
674  return OK(std::make_pair(matrix_id_to_gate, matrix));
675  }
676  } // namespace boolean_influence
677 } // namespace hal
std::set< std::string > get_variable_names() const
Result< Value > evaluate(const std::unordered_map< std::string, Value > &inputs) const
Value
represents the type of the node
static Result< Net * > get_net_from(const Netlist *netlist, const BooleanFunction &var)
Definition: gate.h:58
const std::vector< Net * > & get_fan_out_nets() const
Definition: gate.cpp:735
Definition: net.h:58
const std::vector< Gate * > & get_gates() const
Definition: netlist.cpp:204
Result< std::set< Gate * > > get_next_sequential_gates(const Net *net, bool successors, const std::set< PinType > &forbidden_pins={}, std::unordered_map< const Net *, std::set< Gate * >> *cache=nullptr) const
uint64_t u64
Definition: defines.h:42
uint32_t u32
Definition: defines.h:41
#define UNUSED(expr)
Definition: defines.h:49
#define log_info(channel,...)
Definition: log.h:70
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
#define ERR_APPEND(prev_error, message)
Definition: result.h:64
Result< std::map< Net *, double > > get_boolean_influences_of_subcircuit(const std::vector< Gate * > &gates, const Net *start_net, const u32 num_evaluations=32000)
Result< std::map< Net *, double > > get_boolean_influences_of_gate(const Gate *gate, const u32 num_evaluations=32000)
Result< std::unordered_map< std::string, double > > get_boolean_influence_with_z3_expr(const BooleanFunction &bf, const u32 num_evaluations)
Result< std::map< Net *, double > > get_boolean_influences_of_subcircuit_deterministic(const std::vector< Gate * > &gates, const Net *start_net)
Result< std::unordered_map< std::string, double > > get_boolean_influence_deterministic(const BooleanFunction &bf)
Result< std::unordered_map< std::string, double > > get_boolean_influence(const BooleanFunction &bf, const u32 num_evaluations=32000)
Result< std::map< Net *, double > > get_boolean_influences_of_gate_deterministic(const Gate *gate)
Result< std::pair< std::map< u32, Gate * >, std::vector< std::vector< double > > > > get_ff_dependency_matrix(const Netlist *netlist, bool with_boolean_influence)
Result< std::unordered_map< std::string, double > > get_boolean_influence_with_hal_boolean_function_class(const BooleanFunction &bf, const u32 num_evaluations)
S to(const T &str)
void remove(std::filesystem::path file_path)
T replace(const T &str, const T &search, const T &replace)
Definition: utils.h:384
Result< std::filesystem::path > get_unique_temp_directory(const std::string &prefix="", const u32 max_attempts=5)
Definition: utils.cpp:276
bool starts_with(const T &s, const T &start)
Definition: utils.h:169
std::vector< T > to_vector(const Container< T, Args... > &container)
Definition: utils.h:515
std::set< std::string > get_variable_names(const z3::expr &e)
Extracts all variable names from a z3 expression.
Definition: z3_utils.cpp:481
z3::expr from_bf(const BooleanFunction &bf, z3::context &ctx, const std::map< std::string, z3::expr > &var2expr={})
Definition: z3_utils.cpp:15
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...
std::string to_cpp(const z3::expr &e)
Definition: z3_utils.cpp:463
Definition: defines.h:45
Net * net