390 {
391 RCP<const Symbol> s;
392 map_basic_basic m, n;
393 bool subs;
394
395 for (const auto &p : subs_dict_) {
396
397
398 if (
eq(*x.get_arg(), *p.first)) {
399 RCP<const Basic> t = p.second;
400 for (auto &sym : x.get_symbols()) {
401 if (not is_a<Symbol>(*sym)) {
402 throw SymEngineException("Error, expected a Symbol.");
403 }
404 t = t->diff(rcp_static_cast<const Symbol>(sym));
405 }
406 result_ = t;
407 return;
408 }
409 }
410 for (const auto &p : subs_dict_) {
411 subs = true;
412 if (
eq(*x.get_arg()->subs({{p.first, p.second}}), *x.get_arg()))
413 continue;
414
415
416
417 if (is_a<Symbol>(*p.first) and is_a<Symbol>(*p.second)
419 *x.get_arg()->diff(rcp_static_cast<const Symbol>(p.second)),
420 *zero)) {
421 insert(n, p.first, p.second);
422 continue;
423 }
424 for (const auto &d : x.get_symbols()) {
425 if (is_a<Symbol>(*d)) {
426 s = rcp_static_cast<const Symbol>(d);
427
428
429 if (
neq(*zero, *(p.first->diff(s)))
430 ||
neq(*zero, *(p.second->diff(s)))) {
431 subs = false;
432 break;
433 }
434 } else {
435 result_
436 = make_rcp<const Subs>(x.rcp_from_this(), subs_dict_);
437 return;
438 }
439 }
440 if (subs) {
441 insert(n, p.first, p.second);
442 } else {
443 insert(m, p.first, p.second);
444 }
445 }
446 auto t = x.get_arg()->subs(n);
447 for (auto &p : x.get_symbols()) {
448 auto t2 = p->subs(n);
449 if (not is_a<Symbol>(*t2)) {
450 throw SymEngineException("Error, expected a Symbol.");
451 }
452 t = t->diff(rcp_static_cast<const Symbol>(t2));
453 }
454 if (m.empty()) {
455 result_ = t;
456 } else {
457 result_ = make_rcp<const Subs>(t, m);
458 }
459 }
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
void insert(T1 &m, const T2 &first, const T3 &second)
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b