diff --git a/debug_test.jl b/debug_test.jl new file mode 100644 index 0000000..46100ea --- /dev/null +++ b/debug_test.jl @@ -0,0 +1,23 @@ +#!/usr/bin/env julia + +using Pkg +Pkg.activate(".") + +println("Loading packages...") +using SymbolicIntegration, Symbolics + +println("Creating variable...") +@variables x + +println("Attempting sin(x) integration with debugging...") +try + result = integrate(sin(x), x, RischMethod()) + println("SUCCESS: Result = $result") +catch e + println("ERROR: $e") + println("Stack trace:") + for (exc, bt) in Base.catch_stack() + showerror(stdout, exc, bt) + println() + end +end \ No newline at end of file diff --git a/src/methods/risch/complex_fields.jl b/src/methods/risch/complex_fields.jl index 061ff8a..f277b7f 100644 --- a/src/methods/risch/complex_fields.jl +++ b/src/methods/risch/complex_fields.jl @@ -4,7 +4,28 @@ struct ComplexExtensionDerivation{T<:FieldElement, P<:PolyRingElem{T}} <: Deriva domain::AbstractAlgebra.ResField{P} D::Derivation function ComplexExtensionDerivation(domain::AbstractAlgebra.ResField{P}, D::Derivation) where {T<:FieldElement, P<:PolyRingElem{T}} - base_ring(base_ring(base_ring(domain)))==D.domain || error("base ring of domain must be domain of D") + # The issue is that we need to check the correct nesting level based on the derivation type + # Similar to how ExtensionDerivation handles different nesting levels + + expected_domain = base_ring(base_ring(base_ring(domain))) + actual_domain = D.domain + + # Check compatibility following the same pattern as ExtensionDerivation + domain_compatible = false + + if expected_domain == actual_domain + # Direct match - the expected case for basic derivations + domain_compatible = true + elseif base_ring(base_ring(domain)) == actual_domain + # One level less nesting - derivation on the polynomial ring level + domain_compatible = true + elseif base_ring(domain) == actual_domain + # Two levels less nesting - derivation on the coefficient field level + domain_compatible = true + end + + domain_compatible || error("base ring of domain must be domain of D") + m = modulus(domain) degree(m)==2 && isone(coeff(m, 0)) && iszero(coeff(m, 1)) && isone(coeff(m,2)) || error("domain must be residue field modulo X^2+1.") diff --git a/test/methods/risch/test_trigonometric_functions.jl b/test/methods/risch/test_trigonometric_functions.jl new file mode 100644 index 0000000..9a90350 --- /dev/null +++ b/test/methods/risch/test_trigonometric_functions.jl @@ -0,0 +1,33 @@ +using Test +using SymbolicIntegration +using Symbolics + +@testset "Trigonometric Functions with Risch Method" begin + @variables x + + @testset "Issue #20: Basic trigonometric integration" begin + # Test sin(x) integration + sin_result = integrate(sin(x), x, RischMethod()) + @test sin_result !== nothing + + # Test cos(x) integration + cos_result = integrate(cos(x), x, RischMethod()) + @test cos_result !== nothing + + # Test mathematical correctness by verifying derivatives + # The fundamental theorem of calculus: d/dx[∫f(x)dx] = f(x) + @test isequal(Symbolics.derivative(sin_result, x), sin(x)) + @test isequal(Symbolics.derivative(cos_result, x), cos(x)) + + # Test that results are symbolic expressions + @test sin_result isa Union{Number, SymbolicUtils.BasicSymbolic} + @test cos_result isa Union{Number, SymbolicUtils.BasicSymbolic} + end + + @testset "Additional trigonometric functions" begin + # Test tan(x) integration + tan_result = integrate(tan(x), x, RischMethod()) + @test tan_result !== nothing + @test isequal(Symbolics.derivative(tan_result, x), tan(x)) + end +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 33bd983..731dc40 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,6 +21,7 @@ using Symbolics # Include Risch method test suites include("methods/risch/test_rational_integration.jl") include("methods/risch/test_complex_fields.jl") + include("methods/risch/test_trigonometric_functions.jl") include("methods/risch/test_bronstein_examples.jl") include("methods/risch/test_algorithm_internals.jl")