11 const std::string& operation) {
15 normalized.error().code, normalized.error().message, operation);
17 if (normalized.value().empty()) {
20 "property declaration interval must not be empty",
27 if (left.is_open !=
right.is_open ||
28 left.is_neg_infinity !=
right.is_neg_infinity ||
29 left.is_pos_infinity !=
right.is_pos_infinity) {
32 if (!left.value || !
right.value) {
33 return left.value ==
right.value;
54 auto left = IntervalUnion::from_intervals_checked({
a},
context);
56 auto right = IntervalUnion::from_intervals_checked({
b},
context);
58 auto intersection = left.value().intersect_checked(
right.value(),
context);
69 const Interval& outer,
70 const Interval& inner,
72 auto normalized_outer = IntervalUnion::from_intervals_checked({outer},
context);
73 if (!normalized_outer) {
76 auto normalized_inner = IntervalUnion::from_intervals_checked({inner},
context);
77 if (!normalized_inner) {
83 auto intersection = normalized_outer.value().intersect_checked(
84 normalized_inner.value(),
context);
88 const auto& intersection_intervals = intersection.value().intervals();
89 const auto& inner_intervals = normalized_inner.value().intervals();
90 if (intersection_intervals.size() != inner_intervals.size()) {
93 for (std::size_t i = 0; i < inner_intervals.size(); ++i) {
102Result<bool> PropertyStore::check_continuous_declarations(
103 const std::vector<SymbolProperties::ContinuityDecl>& declarations,
104 const std::string& symbol,
const Interval&
interval,
106 constexpr const char* operation =
"declare_continuous";
107 for (
const auto& declaration : declarations) {
108 if (!declaration.is_differentiable &&
116 overlap.error().code, overlap.error().message, operation);
118 if (overlap.value() && declaration.is_differentiable) {
121 "Contradiction for symbol '" + symbol +
122 "': continuous-only declaration overlaps an existing "
123 "differentiable declaration",
130bool PropertyStore::has_differentiable_declaration(
131 const std::vector<SymbolProperties::ContinuityDecl>& declarations,
133 for (
const auto& declaration : declarations) {
134 if (declaration.is_differentiable &&
143 const std::string& symbol,
const Interval&
interval) {
144 return declare_continuous_checked(symbol,
interval);
148 const std::string& symbol,
151 constexpr const char*
operation =
"declare_continuous";
154 if (!valid)
return valid;
157 PropertyStore candidate = *
this;
158 auto& declarations = candidate.properties_[symbol].continuity_decls;
159 auto checked = check_continuous_declarations(declarations, symbol,
interval,
context);
162 declarations.push_back({
interval,
false});
163 *
this = std::move(candidate);
164 }
catch (
const std::bad_alloc&) {
167 }
catch (
const std::exception& ex) {
175 const std::string& symbol,
182 const std::string& symbol,
const Interval&
interval) {
183 return declare_differentiable_checked(symbol,
interval);
187 const std::string& symbol,
190 constexpr const char*
operation =
"declare_differentiable";
193 if (!valid)
return valid;
196 PropertyStore candidate = *
this;
197 auto& declarations = candidate.properties_[symbol].continuity_decls;
198 if (has_differentiable_declaration(declarations,
interval)) {
201 declarations.push_back({
interval,
true});
202 *
this = std::move(candidate);
203 }
catch (
const std::bad_alloc&) {
206 }
catch (
const std::exception& ex) {
214 const std::string& symbol,
221 const std::string& symbol,
const Interval&
interval)
const {
222 return is_continuous_checked(symbol,
interval);
226 const std::string& symbol,
229 constexpr const char*
operation =
"is_continuous";
230 if (symbol.empty()) {
237 auto it = properties_.find(symbol);
238 if (it == properties_.end()) {
242 for (
const auto& decl : it->second.continuity_decls) {
246 covers.error().code, covers.error().message, operation);
254 const std::string& symbol,
261 const std::string& symbol,
const Interval&
interval)
const {
262 return is_differentiable_checked(symbol,
interval);
266 const std::string& symbol,
269 constexpr const char*
operation =
"is_differentiable";
270 if (symbol.empty()) {
277 auto it = properties_.find(symbol);
278 if (it == properties_.end()) {
282 for (
const auto& decl : it->second.continuity_decls) {
283 if (!decl.is_differentiable)
continue;
287 covers.error().code, covers.error().message, operation);
295 const std::string& symbol,
303 const std::string& symbol,
311 const std::string& symbol,
316 constexpr const char*
operation =
"declare_monotonicity";
323 if (!valid)
return valid;
326 PropertyStore candidate = *
this;
327 auto& declarations = candidate.properties_[symbol].monotonicity_decls;
328 for (
const auto& declaration : declarations) {
329 if (declaration.variable ==
variable && declaration.type == mono &&
335 *
this = std::move(candidate);
336 }
catch (
const std::bad_alloc&) {
339 }
catch (
const std::exception& ex) {
347 const std::string& symbol,
356 const std::string& symbol,
363 const std::string& symbol,
367 constexpr const char*
operation =
"get_monotonicity";
368 if (symbol.empty() ||
variable.empty()) {
371 symbol.empty() ?
"symbol name must not be empty" :
"variable name must not be empty",
377 auto it = properties_.find(symbol);
378 if (it == properties_.end()) {
382 for (
const auto& decl : it->second.monotonicity_decls) {
383 if (decl.variable !=
variable)
continue;
387 covers.error().code, covers.error().message, operation);
395 const std::string& symbol,
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
int compare(const SymbolicNode &other) const
与另一个节点进行全序比较.
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
ComputationContext const std::string & operation
PropertyStoreResult invalid_empty_symbol(const std::string &operation)
const std::string & variable
static Result< bool > interval_covers_checked_impl(const Interval &outer, const Interval &inner, ComputationContext &context)
判断 outer 是否完全包含 inner。 包含条件为 outer.lower <= inner.lower 且 inner.upper <= outer.upper, 并结合端点的开闭属性判断边界。
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
Result< void > PropertyStoreResult
static Result< bool > intervals_overlap_checked_impl(const Interval &a, const Interval &b, ComputationContext &context)
判断两个区间是否存在已证明的交集。 端点排序采用受检区间运算;超出支持域时,交集判定仍为未决。
static bool endpoints_equivalent(const Endpoint &left, const Endpoint &right)
Monotonicity
Monotonicity classification for functions over intervals.
@ Unknown
Monotonicity not determined
Result< std::vector< Interval > > normalize_intervals_checked(std::vector< Interval > intervals, ComputationContext &context)
__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
static bool intervals_equivalent(const Interval &left, const Interval &right)
PropertyStoreResult validate_property_interval(const Interval &interval, ComputationContext &context, const std::string &operation)