use symplex::prelude::*;
#[test]
fn derivatives_with_respect_to_function_values_and_refusals() {
let ctx = Context::new();
let x = ctx.symbol("x");
let f = ctx.apply("f", std::slice::from_ref(&x)).unwrap();
let df = f.formal_diff(&x);
let d2f = df.formal_diff(&x);
let e = f.powi(3) + &x * &f + x.sin().powi(2);
assert_eq!(e.diff(&f), 3 * f.powi(2) + &x);
let lagrangian = &f * &df + df.powi(2) + &d2f * &x;
assert_eq!(lagrangian.diff(&f), df);
assert_eq!(lagrangian.diff(&df), &f + 2 * &df);
for var in [2 * &x, &x + 1, x.sin()] {
let d = x.powi(2).diff(&var);
assert!(d.has_unevaluated(), "d/d({var}) x² = {d}");
assert!(x.powi(2).try_diff(&var).is_err());
}
assert_eq!(x.powi(3).diff(&x), 3 * x.powi(2));
}