chakravala / Reduce.jl

Symbolic parser for Julia language term rewriting using REDUCE algebra

Home Page:http://www.reduce-algebra.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wrong result for sum((1-x)^(2*i), i, 0, n)

jbrea opened this issue · comments

commented
julia> rcall(:(sum((1-x)^(2*i), i, 0, n)))
:((-((x - 1) ^ (2n)) * (x - 1) ^ 1) // ((x - 2) * x))

The result should be something like

:((((x - 1) ^ (2n)) * (x - 1) ^ 2 - 1) // ((x - 2) * x))

Thanks for finding this bug. It's an issue with the parser, when translating the RExpr into an Expr. I will investigate the cause of this issue as soon as am able to. The parser has grown much in complexity, although I spent a large amount of time looking for bugs, this is one I didn't come across before yet.

Okay, so I figured out where the problem comes from.

The temporary immediate fix is for you to set

Reduce.SubCall(false)

and then the expression will be correctly translated.

julia> R"(-x+1)**(2*n)*(x-1)**2-1" |> parse
:((-x + 1) ^ (2n) * (x - 1) ^ 2 - 1)

However, I will fully fix the problem so that this option is not required. The expression R"(-x+1)**(2*n)*(x-1)**2-1" is split up by the parser into parts and then RSymReplace is called on each part to substitute some REDUCE words with Julia words. The problem is that if SubCall is enabled, then the substitution is carried out using a call to REDUCE, and something might get simplified incorrectly due to the way the expression is split up.

This can be fixed in the RSymReplace function, it will just need some extra parsing steps to further split the statement up into smaller pieces, so that each term is substituted separately.

Alrighty, this bug is now fixed on master, so everything should work fine now:

julia> rcall(:(sum((1-x)^(2*i), i, 0, n)))
:(((-x + 1) ^ (2n) * (x - 1) ^ 2 - 1) // ((x - 2) * x))

julia> sum(:((1-x)^(2*i)), :i, 0, :n)
:(((-x + 1) ^ (2n) * (x - 1) ^ 2 - 1) // ((x - 2) * x))

Also, I have imported the sum function so that you can use it as sum(::Expr, ...) instead of having to use rcall to evaluate the sum.

It only required a change where a call to _subst is now handled by a new function

function SubReplace(sym::String,str::String)
    a = matchall(r"([^ ()+*\^\/-]+|[()+*\^\/-])",str)
    for s  1:length(a)
        !isinfix(a[s]) && (a[s]  ["(",")"]) && (a[s] = _subst(sym,a[s]))
    end
    return join(a)
end

It is on commit eaa7026, which will be part of the upcoming v0.3.1 release.

Thanks for your bug report, hope everything else works fine for you.

commented

Great. Thanks much for this super quick fix. I was using the package for the first time today. Looks very promising.