Boost logo

Proto :

Subject: Re: [proto] restructuring expression
From: Eric Niebler (eric_at_[hidden])
Date: 2012-05-30 12:25:27


On 5/29/2012 3:29 PM, Karsten Ahnert wrote:
> On 05/29/2012 08:21 PM, Eric Niebler wrote:
>> On 5/29/2012 1:44 AM, Karsten Ahnert wrote:
>>> I have an arithmetic expression template where multiplication is
>>> commutative. Is there an easy way to order a chain of multiplications
>>> such that terminals with values (like proto::terminal< double >) appear
>>> at the beginning? For example that
>>>
>>> arg1 * arg1 * 1.5 * arg1
>>>
>>> will be transformed to
>>>
>>> 1.5 * arg1 * arg1 * arg1
>>>
>>> ?
>>>
>>> I can imagine some complicated algorithms swapping expressions and child
>>> expressions but I wonder if there is a simpler way.
>>
>> There is no clever built-in Proto algorithm for commutative
>> transformations like this, I'm afraid. I was going to suggest flattening
>> to a fusion vector and using fusion sort, but I see there is no fusion
>> sort! :-( Nevertheless, that seems like a promising direction to me.
>> Once you have the sorted vector, you should(?) be able to use
>> fusion::fold to build the correct proto tree from it.
>
> Ok, this looks promising. But I failed to get proto::fold to work. As a
> first step I tried to flatten an expression and reconstruct it with
> proto::fold:
>
> struct back_fold :
> proto::fold<
> proto::_ ,
> proto::_state ,
> proto::functional::make_multiplies( proto::_state , proto::_ )
> > { };
>
> template< class Expr >
> void eval( const Expr &e )
> {
> back_fold b;
> proto::display_expr(
> b( proto::flatten( e ) , proto::_make_terminal()( 1.0 ) )
> );
> }
>
> eval( 2.0 * arg1 * arg1 * arg1 * 1.0 );
>
> Unfortunately this does not compile. Any ideas what is wrong here?

Yes, I know. I said you should use fusion::fold, not proto::fold. Once
you flatten a proto expression, you get a fusion sequence. That means
you have to use a fusion algorithm on it. Proto's transforms expect
their first parameter to be proto expression trees. The result of
proto::flatten is emphatically not.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Proto list run by eric at boostpro.com