7 const std::shared_ptr<const SymbolicNode>& base,
8 const std::shared_ptr<const SymbolicNode>&
exponent) {
24 if (base->is_zero()) {
43 for (
const auto& operand : base.
operands()) {
44 const auto* power =
dynamic_cast<const PowerNode*
>(operand.get());
45 if (
dynamic_cast<const MatrixNode*
>(operand.get()) ||
46 (power &&
dynamic_cast<const MatrixNode*
>(power->base().get()))) {
56 for (
const auto& operand : base.
operands()) {
72 std::vector<std::shared_ptr<const SymbolicNode>> operands;
73 std::size_t nodes = 0;
75 for (
const auto& operand : base.
operands()) {
78 if (
const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(
result)) {
79 for (
const auto& child : multiply->operands()) {
95 const auto inner_base = std::dynamic_pointer_cast<const NumberNode>(base.
base());
96 if (!inner_base || !inner_base->is_negative_one()) {
99 const auto inner_exponent = std::dynamic_pointer_cast<const NumberNode>(base.
exponent());
100 if (!inner_exponent) {
103 const auto*
rational = std::get_if<Rational>(&inner_exponent->value());
113 const auto numeric = std::dynamic_pointer_cast<const NumberNode>(
exponent);
127 std::shared_ptr<const SymbolicNode> base;
132 node.base()->accept(*
this);
135 node.exponent()->accept(*
this);
140 const auto base_number = std::dynamic_pointer_cast<const NumberNode>(base);
141 const auto exponent_number = std::dynamic_pointer_cast<const NumberNode>(
exponent);
142 if (base_number && exponent_number &&
149 if (
const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(base)) {
154 if (
const auto power = std::dynamic_pointer_cast<const PowerNode>(base)) {
169 const std::shared_ptr<const NumberNode>& outer_exponent)
const {
173 auto exponent = std::dynamic_pointer_cast<const NumberNode>(inner.
exponent());
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
bool can_combine_nested_power(const PowerNode &inner, const std::shared_ptr< const NumberNode > &outer_exponent) const
bool try_normalize_squared_norm(const SymbolicNode &node, std::shared_ptr< const SymbolicNode > &argument)
bool normalize_nested_imaginary_power(const PowerNode &base, const std::shared_ptr< const NumberNode > &exponent)
void visit(const NumberNode &node) override
bool normalize_nested_power(const PowerNode &base, const std::shared_ptr< const SymbolicNode > &exponent)
void set_result(std::shared_ptr< const SymbolicNode > candidate)
const FactsQuery & facts_
std::shared_ptr< const SymbolicNode > result
ComputationContext & context_
bool normalize_product_power(const MultiplyNode &base, const std::shared_ptr< const SymbolicNode > &exponent)
void distribute_power(const MultiplyNode &base, const std::shared_ptr< const SymbolicNode > &exponent)
static bool is_positive_integer_number(const std::shared_ptr< const NumberNode > &node)
bool normalize_power_identity(const std::shared_ptr< const SymbolicNode > &base, const std::shared_ptr< const SymbolicNode > &exponent)
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
RewriteBudget * rewrite_budget() const noexcept
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
std::shared_ptr< const Node > make_node(Args &&... args)
Result< Tribool > query_real_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
Result< Tribool > query_nonnegative_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
Result< Tribool > query_positive_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
ExprResult integer(Integer)=delete
bool try_get_integer_value(const std::shared_ptr< const NumberNode > &node, BigInt &value)
bool normalization_can_discard(const std::shared_ptr< const SymbolicNode > &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
@ Complex
Complex numbers (default, least specific)
std::shared_ptr< const SymbolicNode > normalization_imaginary_power(const BigInt &exponent, detail::RewriteBudget *budget=nullptr)
std::size_t normalization_check_count(detail::RewriteBudget *budget, std::size_t rows, std::size_t cols=1, bool wrapped=true)
void normalization_check_children(detail::RewriteBudget *budget, std::size_t roots, const std::shared_ptr< const Nodes > &... children)
std::shared_ptr< const SymbolicNode > normalization_numeric_power(const std::shared_ptr< const NumberNode > &base, const std::shared_ptr< const NumberNode > &exponent, detail::RewriteBudget *budget=nullptr)
const std::string const ExprPtr & value
bool normalization_proved(const Result< Tribool > &result)
std::shared_ptr< const SymbolicNode > make_normalized_multiply_node(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, detail::RewriteBudget *budget=nullptr)
ExprResult rational(const Rational &value)
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)