$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] [Proto] implementing an computer algebra system with proto
From: Kim Kuen Tang (kuentang_at_[hidden])
Date: 2009-01-30 18:23:48
Dave Jenkins schrieb:
>
> "Kim Kuen Tang" <kuentang_at_[hidden]> wrote in message 
> news:497F760C.1030408_at_vodafone.de...
>
> Hi Kim Tang,
>
> I think the attached program solves that problem.
>
> The problem I've been working on is to use the distributive law to 
> simplify expressions at compile time.
> For example, I'd like to transform "var_ * 2 + var_ * 3 = 4" to "var_ 
> * (2 + 3) = 4".
> Then, you could transform it to "var_ = 4 / (2 + 3)", all at compile 
> time.
> Wouldn't that be cool? I think it's possible using Proto, but I 
> haven't worked out the details yet.
> Any suggestions are welcome.
Hi Dave,
thank you for the code. The grammar looks great. Here is a grammar that 
is able to perform the distributive law. It is not perfect because it 
doesnt cover all expressions.
struct DistributiveLaw
  : proto::or_<
      // Solved:
      proto::multiplies<proto::terminal<placeholder>, _>
      // Rewrite "var_ *3+var_*2  to var_*(3+2)"
      , proto::when<
           proto::plus< proto::multiplies<proto::terminal<placeholder> 
,proto::terminal<_> >
                       ,proto::multiplies<proto::terminal<placeholder> 
,proto::terminal<_> >
           >
           //, proto::_make_multiplies( proto::terminal<placeholder> , 
proto::_make_plus( proto::_right, proto::_left ) )
           ,proto::_make_multiplies(proto::_left(proto::_left), 
proto::_make_plus(proto::_right(proto::_left),proto::_right(proto::_right) 
)  )
      >
  >
{};
>
>
> struct Solve
>   : proto::or_<
>       // Solved:
>       proto::assign<proto::terminal<placeholder>, _>
>       // Rewrite "var_ + x = y" to "var_ = y - x"
>       , proto::when<
>            proto::assign<                proto::plus< 
> proto::terminal<placeholder>, _>, _ >
>            , proto::_make_assign(                
> proto::_left(proto::_left) ,                proto::_make_minus( 
> proto::_right, proto::_right(proto::_left) )            )       > 
I am not sure wheter this line is needed.
>       // Rewrite "x + var_ = y" to "var_ = y - x"
>       , proto::when<
>            proto::assign<                proto::plus< _, 
> proto::terminal<placeholder>>, _ >
>            , proto::_make_assign(                
> proto::_right(proto::_left) ,                proto::_make_minus( 
> proto::_right, proto::_left(proto::_left) )            )       >
>       // Rewrite "x + ? = y" to "Solve(? = y - x)"
>       , proto::when<
>            proto::assign<                proto::plus< 
> proto::terminal<_>, _>, _ >
>            , Solve(
>                proto::_make_assign(                    
> proto::_right(proto::_left) ,                    proto::_make_minus( 
> proto::_right, proto::_left(proto::_left) )                )            )
>       >
>       // Rewrite "? + x = y" to "Solve(? = y - x)"
>      , proto::when<
>            proto::assign<                proto::plus< _, 
> proto::terminal<_> >, _ >
>            , Solve(
>                proto::_make_assign(                    
> proto::_left(proto::_left) ,                    proto::_make_minus( 
> proto::_right, proto::_right(proto::_left) )                ) 
>            )
>       >
>   >
> {};
>
Cheers
Kim