Boost logo

Boost Users :

Subject: Re: [Boost-users] [Proto] implementing an computer algebra systemwith proto
From: Dave Jenkins (david_at_[hidden])
Date: 2009-01-28 10:38:07


"Kim Kuen Tang" <kuentang_at_[hidden]> wrote in message
news:497F760C.1030408_at_vodafone.de...
> this version of Solve
> has the feature of calling itsel recursively. So writing "Solve()( var_ +
> 1 + 3 = 2 )" is enough to produce "var_ = 2-1-3".
> It takes me about 1 to 2 hour to figure this out. So i would say that
> proto is not difficult to learn and you really will gain more.

Thanks, Kim Tang. I see that your example works.
However, when I tried playing with it I found one mystery.
It seems that any placeholder will match, not just the one you specify in
the grammar.

Below is an example program showing what I mean.
I would expect that only placeholder1 would match,
but both placeholder1 and placeholder2 match and produce the same output.
I even tried using proto::exact to get the program to reject placeholder2,
but that made no difference.

#include <iostream>
#include <boost/proto/proto.hpp>

namespace mpl = boost::mpl;
namespace proto = boost::proto;
namespace fusion = boost::fusion;
using proto::_;

// Work around annoyng msvc compiler bugs ...
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#define _left(x) call<proto::_left(x)>
#define _right(x) call<proto::_right(x)>
#define _make_minus(x,y) call<proto::_make_minus(x,y)>
#define _make_plus(x,y) call<proto::_make_plus(x,y)>
#define _make_assign(x,y) call<proto::_make_assign(x,y)>
#endif

struct placeholder1
{
   friend std::ostream &operator <<(std::ostream &sout, placeholder1)
   {
       return sout << "var1_";
   }
};
struct placeholder2
{
   friend std::ostream &operator <<(std::ostream &sout, placeholder2)
   {
       return sout << "var2_";
   }
};

proto::terminal<placeholder1>::type const var1_ = {{}};
proto::terminal<placeholder2>::type const var2_ = {{}};

struct Solve
    : proto::when<
        // Match "var1_ + x = y"
        proto::assign<
            proto::plus<
                proto::terminal<proto::exact<placeholder1>>
                , _>
            , _ >
        // Rewrite as "var1_ = y - x"
        , proto::_make_assign(
            proto::_left(proto::_left) ,
            proto::_make_minus(
                proto::_right,
                proto::_right(proto::_left)
            )
        )
>
{};

int main()
{
   proto::display_expr( var1_ + 1 = 2 );
   proto::display_expr( Solve()( var1_ + 1 = 2 ) );
   proto::display_expr( var2_ + 1 = 2 );
   proto::display_expr( Solve()( var2_ + 1 = 2 ) );
}

>
> The next step will be to extend the grammar with the feature of
> transforming such expression "1+2+var_+3=4" into
> this "var_=4-1-2-3".

I would be interested in your solution to this also.

Thanks,
Dave Jenkins


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net