[GiNaC-devel] printing of class power

Richard B. Kreckel kreckel at in.terlu.de
Mon Jan 6 23:03:06 CET 2025


Hi,

On 1/3/25 3:41 PM, Stefan Weinzierl wrote:
>    ex g = pow(x,5);
[...]
>    g.print(GiNaC::print_context(std::cout));
>    std::cout << std::endl;
> 
> will print
[...]
> [power object]
> 
> Is that really intentional? The behaviour is the same in GiNaC 1.8.7 and 1.8.8.

Well....

Class 'print_context' is the common base class for 'print_dflt', 
'print_latex', 'print_csrc', etc.

I am not sure if it makes sense to use it. After all, there are ostream 
manipulator 'dflt', 'latex', and 'csrc' (operators.h), but none for 
'print_context'. On the other hand, 'print_context' is totally public.

What happens is: The lookup implemented in basic::print_dispatch() 
doesn't find a method in the print dispatch table for print_default for 
class 'power'. So it proceeds to class 'basic', the base class of 
'power' to look for a dispatch function and this is the one printing 
"[power object]".

The fine user manual cares to elaborate (in section 6.3 "GiNaC's 
expression output system"):

   The method table contains one slot for each possible ‘print_context’
   type, indexed by the (internally assigned) serial number of the type.
   Slots may be empty, in which case GiNaC will retry the method lookup
   with the ‘print_context’ object's parent class, possibly repeating the
   process until it reaches the ‘print_context’ base class.  If there's
   still no method defined, the method table of the algebraic object's
   parent class is consulted, and so on, until a matching method is found
   (eventually it will reach the combination ‘basic/print_context’, which
   prints the object's class name enclosed in square brackets).

   You can think of the print methods of all the different classes and
   output formats as being arranged in a two-dimensional matrix with one
   axis listing the algebraic classes and the other axis listing the
   ‘print_context’ classes.

And it turns out that class 'power' has all kinds of output methods 
except 'print_tree' and 'print_context'! If we change the existing 
method for 'print_dflt' to be the one for 'print_context', your code 
will work as you expected: The lookup for 'print_dflt' will find the 
base method for 'print_context'. One last piece to do would be to add a 
method for 'print_tree' because our new method for 'print_context' will 
match this one while before we were using the one from class 'basic'. 
The attached patch does that.

I'm unsure if this is patch is right. I guess it depends on whether your 
code using 'print_context' directly is right or not.

Comments welcome!

   -richy.

PS: The patch breaks the ABI, but that ain't grave. I think that the 
alternative of making 'print_context' abstract would break the API and 
that would be worse.
-- 
Richard B. Kreckel
<https://in.terlu.de/~kreckel/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: GiNaC-power-print.diff
Type: text/x-patch
Size: 2272 bytes
Desc: not available
URL: <http://www.ginac.de/pipermail/ginac-devel/attachments/20250106/b55e590f/attachment.bin>


More information about the GiNaC-devel mailing list