10constexpr const char*
kDepthMessage =
"equivalence rewrite depth budget exhausted";
11constexpr const char*
kGrowthMessage =
"equivalence node growth budget exhausted";
12constexpr const char*
kStepMessage =
"equivalence rewrite step budget exhausted";
19 if (!entered) {
throw entered.error(); }
38 if (
const auto*
integer = std::get_if<BigInt>(&number.
value())) {
51 if (measured.height == std::numeric_limits<std::size_t>::max()) {
61 if (!checked) {
throw checked.error(); }
78 std::size_t max_depth, std::size_t
max_nodes,
86 if (!access) {
throw access.error(); }
94 if (!step) {
throw step.error(); }
109 if (!entered) {
throw entered.error(); }
121 if (!access) {
throw access.error(); }
128 std::size_t active_depth)
const {
134 context_depth > context_limit || shape.
height > context_limit - context_depth) {
143 if (!step) {
throw step.error(); }
144 if (!
node) {
return {}; }
148 const auto owner = found->second.owner.lock();
149 if (owner && owner.get() ==
node.get()) {
150 const auto shape = found->second.shape;
163 Measurement measurement(*
this, path_depth, active_depth);
164 node->accept(measurement);
165 shape = measurement.
shape;
171 if (!cleared) {
throw cleared.error(); }
190 if (!access) {
throw access.error(); }
191 if (child != 0 && current == 0) {
consume(); }
195 return current + child;
199 const std::shared_ptr<const SymbolicNode>& lhs,
200 const std::shared_ptr<const SymbolicNode>&
rhs,
205 if (
right > std::numeric_limits<std::size_t>::max() - left) {
void leave_recursion() noexcept
Result< void > consume_steps(std::size_t amount=1, const std::string &operation={})
Result< void > enter_recursion(const std::string &operation={})
Result< void > require_ast_nodes(std::size_t amount, const std::string &operation={}) const
std::size_t recursion_depth() const noexcept
Result< void > require_integer_bits(std::size_t amount, const std::string &operation={}) const
const ResourceLimits & limits() const noexcept
const std::variant< BigInt, Rational > & value() const noexcept
Measurement(RewriteBudget &budget, std::size_t path_depth, std::size_t active_depth)
void visit(const NumberNode &number) override
void visit_child(const SymbolicNodePtr &child) override
const std::size_t active_depth_
const std::size_t path_depth_
void require_bits(const BigInt &integer)
const std::string operation_
std::unordered_map< const SymbolicNode *, Entry > shapes_
ComputationContext & context() const noexcept
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
void require_nodes(std::size_t nodes) const
std::size_t append_size(std::size_t current, std::size_t child)
RewriteBudget(ComputationContext &context, std::size_t max_depth, std::size_t max_nodes, const char *operation)
std::size_t measure_result(const std::shared_ptr< const SymbolicNode > &node)
ComputationContext & context_
std::size_t max_nodes() const noexcept
Shape measure_shape(const std::shared_ptr< const SymbolicNode > &node, std::size_t path_depth, std::size_t active_depth)
std::size_t remaining_steps_
static std::size_t input_nodes(const std::shared_ptr< const SymbolicNode > &lhs, const std::shared_ptr< const SymbolicNode > &rhs, ComputationContext &context, std::size_t max_depth, const char *operation)
void require_shape(const Shape &shape, std::size_t path_depth, std::size_t active_depth) const
void check_step_access() const
MeasurementRecursion(ComputationContext &context, const std::string &operation)
MeasurementRecursion & operator=(const MeasurementRecursion &)=delete
MeasurementRecursion(const MeasurementRecursion &)=delete
ComputationContext & context_
constexpr const char * kDepthMessage
constexpr const char * kStepMessage
constexpr const char * kGrowthMessage
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const SymbolicNode > SymbolicNodePtr
ComputationContext const std::string & operation
std::size_t std::size_t ComputationContext & context
ExprResult integer(Integer)=delete
std::size_t max_recursion_depth
Simultaneous checked depth.
ExprResult rational(const Rational &value)