HAL
python_bindings.cpp
Go to the documentation of this file.
2 
5 #include "pybind11/operators.h"
6 #include "pybind11/pybind11.h"
7 #include "pybind11/stl.h"
8 #include "pybind11/stl_bind.h"
10 #include "solve_fsm/solve_fsm.h"
11 
12 #include <map>
13 namespace py = pybind11;
14 
15 namespace hal
16 {
17  // the name in PYBIND11_MODULE/PYBIND11_PLUGIN *MUST* match the filename of the output library (without extension),
18  // otherwise you will get "ImportError: dynamic module does not define module export function" when importing the module
19 
20 #ifdef PYBIND11_MODULE
21  PYBIND11_MODULE(solve_fsm, m)
22  {
23  m.doc() = "Plugin to automatically generate FSM state transition graphs for given FSMs.";
24 #else
26  {
27  py::module m("solve_fsm", "Plugin to automatically generate FSM state transition graphs for given FSMs.");
28 #endif // ifdef PYBIND11_MODULE
29 
30  py::class_<SolveFsmPlugin, RawPtrWrapper<SolveFsmPlugin>, BasePluginInterface> py_solve_fsm(
31  m, "SolveFsmPlugin", R"(This class provides an interface to integrate FSM solving as a plugin within the HAL framework.)");
32  py_solve_fsm.def_property_readonly("name", &SolveFsmPlugin::get_name, R"(
33  The name of the plugin.
34 
35  :type: str
36  )");
37 
38  py_solve_fsm.def("get_name", &SolveFsmPlugin::get_name, R"(
39  Get the name of the plugin.
40 
41  :returns: Plugin name.
42  :rtype: str
43  )");
44 
45  py_solve_fsm.def_property_readonly("version", &SolveFsmPlugin::get_version, R"(
46  The version of the plugin.
47 
48  :type: str
49  )");
50 
51  py_solve_fsm.def("get_version", &SolveFsmPlugin::get_version, R"(
52  Get the version of the plugin.
53 
54  :returns: Plugin version.
55  :rtype: str
56  )");
57 
58  py_solve_fsm.def_property_readonly("description", &SolveFsmPlugin::get_description, R"(
59  The description of the plugin.
60 
61  :type: str
62  )");
63 
64  py_solve_fsm.def("get_description", &SolveFsmPlugin::get_description, R"(
65  Get the description of the plugin.
66 
67  :returns: The description of the plugin.
68  :rtype: str
69  )");
70 
71  m.def(
72  "solve_fsm_brute_force",
73  [](Netlist* nl, const std::vector<Gate*>& state_reg, const std::vector<Gate*>& transition_logic, const std::string& graph_path = "")
74  -> std::optional<std::map<u64, std::map<u64, BooleanFunction>>> {
75  auto res = solve_fsm::solve_fsm_brute_force(nl, state_reg, transition_logic, graph_path);
76  if (res.is_ok())
77  {
78  return res.get();
79  }
80  else
81  {
82  log_error("python_context", "{}", res.get_error().get());
83  return std::nullopt;
84  }
85  },
86  py::arg("nl"),
87  py::arg("state_reg"),
88  py::arg("transition_logic"),
89  py::arg("graph_path") = std::string(""),
90  R"(
91  Generate the state transition graph of a given FSM using brute force.
92  The result is a map from each state of the FSM to all of its transitions.
93  A transition is given as each successor state as well as the Boolean condition that needs to be fulfilled for the transition to take place.
94  Optionally also produces a DOT file representing the state transition graph.
95 
96  :param hal_py.Netlist nl: The netlist to operate on.
97  :param list[hal_py.Gate] state_reg: A list of flip-flop gates that make up the state register of the FSM.
98  :param list[hal_py.Gate] transition_logic: A list of combinational gates that make up the transition logic of the FSM.
99  :param pathlib.Path graph_path: File path at which to store the DOT state transition graph. No file is created if the path is left empty. Defaults to an empty path.
100  :returns: A dict from each state to its successor states as well as the condition for the respective transition to be taken on success, `None` otherwise.
101  :rtype: dict[int,dict[int,hal_py.BooleanFunction]] or None
102  )");
103 
104  m.def(
105  "solve_fsm",
106  [](Netlist* nl,
107  const std::vector<Gate*>& state_reg,
108  const std::vector<Gate*>& transition_logic,
109  const std::map<Gate*, bool>& initial_state = {},
110  const std::filesystem::path& graph_path = "",
111  const u32 timeout = 600000) -> std::optional<std::map<u64, std::map<u64, BooleanFunction>>> {
112  auto res = solve_fsm::solve_fsm(nl, state_reg, transition_logic, initial_state, graph_path, timeout);
113  if (res.is_ok())
114  {
115  return res.get();
116  }
117  else
118  {
119  log_error("python_context", "{}", res.get_error().get());
120  return std::nullopt;
121  }
122  },
123  py::arg("nl"),
124  py::arg("state_reg"),
125  py::arg("transition_logic"),
126  py::arg("initial_state") = std::map<Gate*, bool>(),
127  py::arg("graph_path") = "",
128  py::arg("timeout") = 600000,
129  R"(
130  Generate the state transition graph of a given FSM using SMT solving.
131  The result is a map from each state of the FSM to all of its transitions.
132  A transition is given as each successor state as well as the Boolean condition that needs to be fulfilled for the transition to take place.
133  Optionally also produces a DOT file representing the state transition graph.
134 
135  :param hal_py.Netlist nl: The netlist to operate on.
136  :param list[hal_py.Gate] state_reg: A list of flip-flop gates that make up the state register of the FSM.
137  :param list[hal_py.Gate] transition_logic: A list of combinational gates that make up the transition logic of the FSM.
138  :param dict[hal_py.Gate,bool] initial_state: A dict from the state register flip-flops to their initial (Boolean) value. If an empty dict is provided, the initial state is set to 0. Defaults to an empty dict.
139  :param pathlib.Path graph_path: File path at which to store the DOT state transition graph. No file is created if the path is left empty. Defaults to an empty path.
140  :param int timeout: Timeout for the underlying SAT solvers. Defaults to 600000 ms.
141  :returns: A dict from each state to its successor states as well as the condition for the respective transition to be taken on success, `None` otherwise.
142  :rtype: dict[int,dict[int,hal_py.BooleanFunction]] or None
143  )");
144 
145  m.def(
146  "generate_dot_graph",
147  [](const std::vector<Gate*>& state_reg,
148  const std::map<u64, std::map<u64, BooleanFunction>>& transitions,
149  const std::string& graph_path = "",
150  const u32 max_condition_length = 128,
151  const u32 base = 10) -> std::optional<std::string> {
152  auto res = solve_fsm::generate_dot_graph(state_reg, transitions, graph_path, max_condition_length, base);
153  if (res.is_ok())
154  {
155  return res.get();
156  }
157  else
158  {
159  log_error("python_context", "{}", res.get_error().get());
160  return std::nullopt;
161  }
162  },
163  py::arg("state_reg"),
164  py::arg("transitions"),
165  py::arg("graph_path") = std::string(),
166  py::arg("max_condition_length") = 128,
167  py::arg("base") = 10,
168  R"(
169  Generates the state graph of a finite state machine from the transitions of that fsm.
170 
171  :param list[hal_py.Gate] state_reg: Vector contianing the state registers.
172  :param dict[int, dict[int, hal_py.BooleanFunction]] transitions: Transitions of the fsm given as a map from origin state to all possible successor states and the corresponding condition.
173  :param str graph_path: Path to the location where the state graph is saved in dot format.
174  :param int max_condition_length: The maximum character length that is printed for boolean functions representing the conditions.
175  :param int base: The base with that the states are formatted and printed.
176  :returns: A string representing the dot graph.
177  :rtype: str
178  )");
179 
180 #ifndef PYBIND11_MODULE
181  return m.ptr();
182 #endif // PYBIND11_MODULE
183  }
184 } // namespace hal
std::string get_name() const override
Get the name of the plugin.
std::string get_description() const override
Get a short description of the plugin.
std::string get_version() const override
Get the version of the plugin.
uint64_t u64
Definition: defines.h:42
#define log_error(channel,...)
Definition: log.h:78
const Module * module(const Gate *g, const NodeBoxes &boxes)
Result< std::string > generate_dot_graph(const std::vector< Gate * > &state_reg, const std::map< u64, std::map< u64, BooleanFunction >> &transitions, const std::filesystem::path &graph_path="", const u32 max_condition_length=128, const u32 base=10)
Definition: solve_fsm.cpp:533
Result< std::map< u64, std::map< u64, BooleanFunction > > > solve_fsm(Netlist *nl, const std::vector< Gate * > &state_reg, const std::vector< Gate * > &transition_logic, const std::map< Gate *, bool > &initial_state={}, const std::filesystem::path &graph_path="", const u32 timeout=600000)
Definition: solve_fsm.cpp:381
Result< std::map< u64, std::map< u64, BooleanFunction > > > solve_fsm_brute_force(Netlist *nl, const std::vector< Gate * > &state_reg, const std::vector< Gate * > &transition_logic, const std::filesystem::path &graph_path="")
Definition: solve_fsm.cpp:285
PYBIND11_PLUGIN(hal_py)
string graph_path
Definition: test_plugin.py:29
dictionary initial_state
Definition: test_plugin.py:28
quint32 u32
This file contains functions to generate the state transition graph of a given FSM.