[GiNaC-list] Fw: [sage-support] (5-e^x).substitute(x=log(x)) goes wrong?

Richard B. Kreckel kreckel at ginac.de
Tue Sep 14 10:26:21 CEST 2010


Hi!

Burcin Erocal wrote:
> This looks like a bug in GiNaC, the library we use for the symbolic
> expressions.
> 
> ginsh - GiNaC Interactive Shell (ginac V1.5.7)
>   __,  _______  Copyright (C) 1999-2010 Johannes Gutenberg University
> Mainz, (__) *       | Germany.  This is free software with ABSOLUTELY
> NO WARRANTY. ._) i N a C | You are welcome to redistribute it under
> certain conditions. <-------------' For details type `warranty;'.
> 
> Type ?? for a list of help topics.
>> subs(5-exp(x),x==log(x));
> 5-log(x)

Thank your for the bug report.

The problem is that exprseq::subs(x==log(x)) first recurses into its 
child, resulting in exp(log(x)) and then it invokes 
subs_one_level(x==log(x)) on that result again, but the result has 
meanwhile automagically evaluated to x!

To see this, here is how the call tree for subs(exp(x),x==log(x)) looks 
like:

exprseq::subs([(x,log(x))], pattern_is_not_product) (*this==[x])
     exprseq::subschildren([(x,log(x))], pattern_is_not_product) 
(*this==[x])
         basic::subs_one_level([(x,log(x))], pattern_is_not_product) 
(*this==x)
             exprseq::subs([], no_pattern|pattern_is_not_product) 
(*this==[x])
                 exprseq::subschildren([], 
no_pattern|pattern_is_not_product) (*this==[x])
                     basic::subs_one_level([], 
no_pattern|pattern_is_not_product) (*this==x)
                      -> x
                 basic::subs_one_level([], 
no_pattern|pattern_is_not_product) (*this==log(x))
                  -> log(x)
          -> log(x)
     basic::subs_one_level([(x,log(x))], pattern_is_not_product) (*this==x)
         exprseq::subs([], no_pattern|pattern_is_not_product) (*this==[x])
             exprseq::subschildren([], 
no_pattern|pattern_is_not_product) (*this==[x])
                 basic::subs_one_level([], 
no_pattern|pattern_is_not_product) (*this==x)
                  -> x
             basic::subs_one_level([], 
no_pattern|pattern_is_not_product) (*this==log(x))
              -> log(x)
      -> log(x)

In contrast, the call tree for subs(exp(x),x==log(y)) looks like this:

exprseq::subs([(x,log(y))], pattern_is_not_product) (*this==[x])
     exprseq::subschildren([(x,log(y))], pattern_is_not_product) 
(*this==[x])
         basic::subs_one_level([(x,log(y))], pattern_is_not_product) 
(*this==x)
             exprseq::subs([], no_pattern|pattern_is_not_product) 
(*this==[y])
                 exprseq::subschildren([], 
no_pattern|pattern_is_not_product) (*this==[y])
                     basic::subs_one_level([], 
no_pattern|pattern_is_not_product) (*this==y)
                      -> y
                 basic::subs_one_level([], 
no_pattern|pattern_is_not_product) (*this==log(y))
                  -> log(y)
          -> log(y)
     basic::subs_one_level([(x,log(y))], pattern_is_not_product) (*this==y)
      -> y

I'm not sure how to fix this. Calling subs_one_level([x,log(x)]) is 
certainly necessary. Otherwise, subs(sin(1+sin(x)),sin($1)==cos($1)) 
would return sin(1+cos(x)) instead of cos(1+cos(x)).

Bye!
    -richy.
-- 
Richard B. Kreckel
<http://www.ginac.de/~kreckel/>


More information about the GiNaC-list mailing list