11#include <nlohmann/json.hpp>
34 return {
true,
value,
static_cast<double>(
value)};
39 return {
false, 0,
value};
44 return value.is_int ?
static_cast<double>(
value.int_value)
50 if (!arg.contains(
"_type"))
51 throw std::runtime_error(
"Invalid JSON: missing _type");
53 if (arg[
"_type"] ==
"UnaryOp")
55 if (!arg.contains(
"operand") || !arg[
"operand"].contains(
"value"))
56 throw std::runtime_error(
"Invalid UnaryOp: missing operand/value");
58 auto operand = arg[
"operand"][
"value"];
59 if (operand.is_number_integer())
61 if (operand.is_number_float())
65 if (!arg.contains(
"value"))
66 throw std::runtime_error(
"Invalid JSON: missing value");
68 auto value = arg[
"value"];
69 if (
value.is_boolean())
71 if (
value.is_number_integer())
73 if (
value.is_number_float())
78 if (arg.contains(
"value_nonfinite"))
83 throw std::runtime_error(
"Unknown numeric type in JSON");
97 if (!node.is_object() || !node.contains(
"_type"))
100 const std::string type = node[
"_type"];
102 if (type ==
"UnaryOp")
105 !node.contains(
"operand") || !node[
"operand"].is_object() ||
106 !node[
"operand"].contains(
"value"))
109 const auto &operand = node[
"operand"][
"value"];
110 if (!operand.is_number_integer() && !operand.is_number_float())
113 else if (type ==
"Constant")
115 if (!node.contains(
"value"))
117 const auto &
value = node[
"value"];
119 !
value.is_boolean() && !
value.is_number_integer() &&
120 !
value.is_number_float())
135 return node.is_object() && node.contains(
"_type") &&
136 node[
"_type"] ==
"Constant" && node.contains(
"value") &&
137 node[
"value"].is_null();
146 if (!call.contains(
"keywords"))
148 for (
const auto &kw : call[
"keywords"])
149 if (kw.value(
"arg",
"") !=
"axis")
159 const nlohmann::json &call,
160 const std::set<std::string> &allowed)
162 if (!call.contains(
"keywords"))
164 for (
const auto &kw : call[
"keywords"])
165 if (allowed.count(kw.value(
"arg",
"")) == 0)
176 const nlohmann::json &
value,
177 const std::string &function_name)
182 value.is_object() &&
value.value(
"_type", std::string()) ==
"Constant" &&
183 value.contains(
"value") &&
value[
"value"].is_string())
185 const std::string kind =
value[
"value"].get<std::string>();
186 if (kind ==
"stable" || kind ==
"mergesort")
189 throw std::runtime_error(
190 "TypeError: numpy." + function_name +
191 "() currently supports kind='stable'/'mergesort'/None only");
198 const nlohmann::json &
value,
199 const std::string &function_name)
202 !
value.is_object() ||
value.value(
"_type", std::string()) !=
"Constant" ||
203 !
value.contains(
"value") || !
value[
"value"].is_boolean())
204 throw std::runtime_error(
205 "TypeError: numpy." + function_name +
"() stable must be a literal bool");
210 const std::vector<exprt> &elems,
215 for (std::size_t i = 0; i < elems.size(); ++i)
216 value.operands().at(i) = elems[i];
224 const long long normalized =
225 axis < 0 ? axis + static_cast<long long>(rank) : axis;
226 if (normalized < 0 || normalized >=
static_cast<long long>(rank))
227 throw std::runtime_error(
228 "AxisError: axis " + std::to_string(axis) +
229 " is out of bounds for array of dimension " + std::to_string(rank));
249 for (std::size_t pass = 0; pass + 1 < keys.size(); ++pass)
251 for (std::size_t j = 0; j + pass + 1 < keys.size(); ++j)
259 if (payload !=
nullptr)
261 exprt lo_p =
if_exprt(out_of_order, (*payload)[j + 1], (*payload)[j]);
262 exprt hi_p =
if_exprt(out_of_order, (*payload)[j], (*payload)[j + 1]);
263 (*payload)[j] = lo_p;
264 (*payload)[j + 1] = hi_p;
280 const std::vector<std::size_t> &shape,
281 const std::vector<exprt> &elems,
282 const typet &elem_type,
285 if (shape.size() == 1)
289 for (std::size_t i = 0; i < elems.size(); ++i)
290 value.operands().at(i) = elems[i];
294 const std::size_t cols = shape[1];
298 for (std::size_t row = 0; row < shape[0]; ++row)
299 for (std::size_t col = 0; col < cols; ++col)
300 value.operands().at(row).operands().at(col) = elems[(row * cols) + col];
318 const std::vector<std::size_t> &shape,
319 std::vector<exprt> elems,
323 const typet &elem_type)
325 auto make_index = [&](std::size_t i) {
327 {
"_type",
"Constant"},
328 {
"value",
static_cast<int64_t
>(i)},
333 auto sort_slice = [&](std::vector<exprt> values) -> std::vector<exprt> {
339 std::vector<exprt> indices;
340 indices.reserve(values.size());
341 for (std::size_t i = 0; i < values.size(); ++i)
342 indices.push_back(make_index(i));
351 if (shape.size() == 1)
354 const std::size_t rows = shape[0];
355 const std::size_t cols = shape[1];
356 std::vector<exprt> out(elems.size());
360 for (std::size_t r = 0; r < rows; ++r)
362 std::vector<exprt> row(
363 elems.begin() +
static_cast<std::ptrdiff_t
>(r * cols),
364 elems.begin() +
static_cast<std::ptrdiff_t
>((r + 1) * cols));
365 std::vector<exprt> sorted_row = sort_slice(std::move(row));
369 out.begin() +
static_cast<std::ptrdiff_t
>(r * cols));
374 for (std::size_t c = 0; c < cols; ++c)
376 std::vector<exprt> col;
378 for (std::size_t r = 0; r < rows; ++r)
379 col.push_back(elems[(r * cols) + c]);
380 std::vector<exprt> sorted_col = sort_slice(std::move(col));
381 for (std::size_t r = 0; r < rows; ++r)
382 out[(r * cols) + c] = sorted_col[r];
Definition std_expr.h:157
Definition std_expr.h:833
const irep_idt & size() const
Definition irep.h:302
Main converter for transforming Python AST into ESBMC's intermediate representation.
Definition python_converter.h:76
exprt get_expr(const nlohmann::json &element)
Definition converter_expr.cpp:2402
Definition type_handler.h:113
typet build_array(const typet &sub_type, const size_t size) const
This method creates a typet representing a statically sized array.
Definition type_handler.cpp:439
std::optional< ieee_floatt > nonfinite_float_from_spelling(const std::string &spelling)
The non-finite double spelling names, or empty when it names none.
Definition convert_float_literal.cpp:94
expr2tc gen_zero(const type2tc &type, bool array_as_array_of)
Build the canonical zero value of type.
Definition irep2_utils.cpp:64
constexpr std::size_t max_numpy_sort_elements
Definition numpy_reducer_shared.h:237
bool numpy_reducer_has_unsupported_keywords_besides(const nlohmann::json &call, const std::set< std::string > &allowed)
Definition numpy_reducer_shared.h:158
void bubble_sort_numpy_paired(std::vector< exprt > &keys, std::vector< exprt > *payload)
Definition numpy_reducer_shared.h:247
bool try_extract_numeric_constant(const nlohmann::json &node, numeric_value &out)
Definition numpy_reducer_shared.h:95
exprt build_numpy_shape_array_value(const std::vector< std::size_t > &shape, const std::vector< exprt > &elems, const typet &elem_type, const type_handler &th)
Definition numpy_reducer_shared.h:279
numeric_value make_float_value(double value)
Definition numpy_reducer_shared.h:37
bool numpy_reducer_has_unsupported_keywords_besides_axis(const nlohmann::json &call)
Definition numpy_reducer_shared.h:144
bool is_json_none_literal(const nlohmann::json &node)
Definition numpy_reducer_shared.h:133
double to_double(const numeric_value &value)
Definition numpy_reducer_shared.h:42
long long normalize_reducer_axis(long long axis, std::size_t rank)
Definition numpy_reducer_shared.h:222
void validate_numpy_sort_kind_keyword_value(const nlohmann::json &value, const std::string &function_name)
Definition numpy_reducer_shared.h:175
void validate_numpy_stable_bool_keyword_value(const nlohmann::json &value, const std::string &function_name)
Definition numpy_reducer_shared.h:197
numeric_value make_int_value(int64_t value)
Definition numpy_reducer_shared.h:32
exprt build_1d_numpy_array_value(const std::vector< exprt > &elems, const type_handler &th)
Definition numpy_reducer_shared.h:209
exprt build_numpy_sort_or_argsort_result(python_converter &converter, const type_handler &th, const std::vector< std::size_t > &shape, std::vector< exprt > elems, bool flatten, long long axis, bool want_indices, const typet &elem_type)
Definition numpy_reducer_shared.h:315
numeric_value extract_value(const nlohmann::json &arg)
Definition numpy_reducer_shared.h:48
Definition numpy_reducer_shared.h:26
bool is_int
Definition numpy_reducer_shared.h:27
double double_value
Definition numpy_reducer_shared.h:29
int64_t int_value
Definition numpy_reducer_shared.h:28