17constexpr const char*
kOperation =
"solve_complex_quadratic";
18using Node = std::shared_ptr<const SymbolicNode>;
49 std::optional<AssumptionFacts>
facts;
53 value->accept(visitor);
57 "quadratic normalization returned null",
kOperation);
65 for (
const auto& coefficient : input) {
70 if (!coefficient || !
node(coefficient)) {
72 "quadratic coefficients must not be null",
kOperation);
76 for (std::size_t i = 0; i < input.size(); ++i) {
81 result[i] = std::move(simplified.value());
87 const AssumptionContext&
facts,
93 if (
node(coefficients[0])->is_zero()) {
95 "quadratic leading coefficient is zero",
kOperation);
98 for (
const auto& coefficient : coefficients) {
105 "quadratic coefficients must be provably real",
kOperation);
108 auto nonzero =
facts.is_nonzero_checked(*coefficients[0],
context);
114 "quadratic leading coefficient is zero",
kOperation);
118 "quadratic leading coefficient is not provably nonzero",
kOperation);
124 const AssumptionContext&
facts,
130 auto nonnegative =
facts.is_nonnegative_checked(delta,
context);
137 auto negative =
facts.is_negative_checked(delta,
context);
145 "quadratic discriminant sign is unknown",
kOperation);
165 const auto minus_b =
negate(
node(coefficients[1]));
208 if (!std::holds_alternative<ProvedZeroResidual>(proof.value())) {
210 "quadratic Cartesian residual could not be proved zero",
kOperation);
243 const auto b =
node(coefficients[1]);
269 const std::shared_ptr<SymbolicExpr>&
a,
270 const std::shared_ptr<SymbolicExpr>&
b,
271 const std::shared_ptr<SymbolicExpr>&
c,
274 auto coefficients = normalize_coefficients({
a,
b,
c},
context);
279 return solve_real_quadratic(coefficients.value(), *
context.assumptions(),
context);
281 const AssumptionContext
facts;
282 return solve_real_quadratic(coefficients.value(),
facts,
context);
285 }
catch (
const std::bad_alloc&) {
287 "quadratic construction allocation failed", kOperation);
288 }
catch (
const std::exception& error) {
290 error.what(), kOperation);
AssumptionContext class with scoped push/pop management.
统一规范化数值幂。 精确操作数保留整数和有理数运算;近似求根要求指数精确等于 1/2。 有限浮点幂直接折叠,省去倒数中间值;非有限结果保留幂表达式。
std::shared_ptr< const SymbolicNode > get_result() const
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
static std::shared_ptr< const SymbolicNode > create_add(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建加法节点,自动扁平化嵌套加法并消除零项.
static std::shared_ptr< const SymbolicNode > create_power(std::shared_ptr< const SymbolicNode > base, std::shared_ptr< const SymbolicNode > exponent)
创建幂运算节点,自动处理指数为 0/1 及底数为 0/1 的情况.
static std::shared_ptr< const SymbolicNode > create_multiply(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建乘法节点,自动扁平化嵌套乘法并消除单位元.
static std::shared_ptr< const SymbolicNode > create_number(const ::LMCAS::BigInt &v)
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
Result< Coefficients > normalize_coefficients(const Coefficients &input, ComputationContext &context)
Node divide(const Node &numerator, const Node &denominator)
std::shared_ptr< const SymbolicNode > Node
Result< CartesianQuadraticRoots > solve_real_quadratic(const Coefficients &coefficients, const AssumptionContext &facts, ComputationContext &context)
Result< CartesianQuadraticRoots > construct_roots(const Coefficients &coefficients, const Node &delta, bool negative, ComputationContext &context)
ExpressionResult normalize(const Node &value, ComputationContext &context)
CartesianNodes cartesian_add(const CartesianNodes &left, const CartesianNodes &right)
Result< bool > negative_discriminant(const SymbolicExpr &delta, const AssumptionContext &facts, ComputationContext &context)
Node multiply(const Node &left, const Node &right)
constexpr const char * kOperation
Result< void > prove_coefficients(const Coefficients &coefficients, const AssumptionContext &facts, ComputationContext &context)
Result< void > prove_zero(const Node &residual, ComputationContext &context)
Result< QuadraticCartesianRoot > normalized_root(const Node &real, const Node &imag, ComputationContext &context)
Node add(const Node &left, const Node &right)
std::array< std::shared_ptr< SymbolicExpr >, 3 > Coefficients
CartesianNodes cartesian_multiply(const CartesianNodes &left, const CartesianNodes &right)
Result< void > verify_root(const Coefficients &coefficients, const QuadraticCartesianRoot &root, ComputationContext &context)
Node negate(const Node &value)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::array< QuadraticCartesianRoot, 2 > CartesianQuadraticRoots
std::shared_ptr< SymbolicExpr > imag
Result< CartesianQuadraticRoots > real_quadratic_roots_checked(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, ComputationContext &context)
const FactsQuery & no_facts() noexcept
RewriteBudget const FactsQuery & facts
Result< Tribool > query_real_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
std::size_t std::size_t ComputationContext & context
std::shared_ptr< SymbolicExpr > real
ExprResult real(const ExprPtr &expression, ComputationContext &context)
const VectorField const VectorField & c
@ True
Property definitely holds
@ False
Property definitely does not hold
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
ResidualCheckResult check_zero_residual(const ExprPtr &residual, ComputationContext &context, const LMCAS::EqvOptions &options)
const std::string const ExprPtr & value
const ExprPtr & denominator