Skip to content

Commit 1dc113a

Browse files
committed
Fix Integrate returning unevaluated when integrand is constant w.r.t. variable
Add a general is_constant_wrt check at the top of integrate() so that expressions like Integrate[x*x, y] correctly return x^2*y instead of the unevaluated Integrate[x^2, y].
1 parent 4356bcb commit 1dc113a

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

src/functions/calculus_ast.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,6 +1841,16 @@ fn gcd_i128_local(a: i128, b: i128) -> i128 {
18411841

18421842
/// Integrate an expression with respect to a variable
18431843
fn integrate(expr: &Expr, var: &str) -> Option<Expr> {
1844+
// General constant check: ∫ c dy = c*y for any expression c independent of y
1845+
// (handles compound expressions like x^2, Sin[x], etc. when integrating w.r.t. a different variable)
1846+
if is_constant_wrt(expr, var) {
1847+
return Some(Expr::BinaryOp {
1848+
op: crate::syntax::BinaryOperator::Times,
1849+
left: Box::new(expr.clone()),
1850+
right: Box::new(Expr::Identifier(var.to_string())),
1851+
});
1852+
}
1853+
18441854
match expr {
18451855
// Constant: ∫ c dx = c*x
18461856
Expr::Integer(n) => Some(Expr::BinaryOp {

tests/interpreter_tests/calculus.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ use super::*;
33
mod integrate_with_sum {
44
use super::*;
55

6+
#[test]
7+
fn integrate_constant_wrt_other_var() {
8+
assert_eq!(interpret("Integrate[x*x, y]").unwrap(), "x^2*y");
9+
assert_eq!(interpret("Integrate[Sin[x], y]").unwrap(), "y*Sin[x]");
10+
assert_eq!(interpret("Integrate[Log[x], y]").unwrap(), "y*Log[x]");
11+
assert_eq!(interpret("Integrate[x^2 + y, y]").unwrap(), "x^2*y + y^2/2");
12+
}
13+
614
#[test]
715
fn integrate_polynomial() {
816
assert_eq!(interpret("Integrate[x^2, x]").unwrap(), "x^3/3");

0 commit comments

Comments
 (0)