/////////////////////////////////////////////////////////////////////// // Math Type Library // $Id: matcher.h,v 1.3 2002/05/07 12:38:55 cparpart Exp $ // (This file contains the expression tree specific template members) // // Copyright (c) 2002 by Christian Parpart // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this library; see the file COPYING.LIB. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. /////////////////////////////////////////////////////////////////////// #ifndef libmath_matcher_h #define libmath_matcher_h #include #include #include #include namespace math { template class TMatchRegistry { public: TMatchRegistry(); TMatchRegistry(const TMatchRegistry&); /// defines given expression node as given id. void define(const std::string& AId, const TNode *ANode); /// checks whether given id is defined or not. bool defined(const std::string& AId) const; /// returns expression node to given id. const TNode *get(const std::string& AId) const; /// marks given node as used void mark(const TNode *ANode); /// returns true when ANode is either marked as used or is defined as any bool contains(const TNode *ANode) const; private: typedef std::map *> TAnyMap; typedef std::list *> TNodeList; TAnyMap FAnyMap; TNodeList FNodeList; }; //////////////////////////////////////////////////////////////////////// // The match template tree template class TMatch { public: virtual ~TMatch() {} virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const = 0; }; template class TNumMatch : public TMatch { public: TNumMatch(const T& ANum); virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const; private: T FNumber; }; template class TAnyMatch : public TMatch { public: TAnyMatch(const std::string& AId); virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const; private: std::string FIdent; }; /** T2Match is the base class for operators where the operands may be equivalent exchaned (+, *) */ template class T2Match : public TMatch { protected: T2Match(TMatch *ALeft, TMatch *ARight); ~T2Match(); // gets additional match methods for share soon typedef std::list *> TList; TList FPatterns; }; template class TPlusMatch : public T2Match { public: TPlusMatch(TMatch *ALeft, TMatch *ARight, ...); virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const; }; template class TMulMatch : public T2Match { public: TMulMatch(TMatch *ALeft, TMatch *ARight, ...); virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const; }; template class TNegMatch : public TMatch { public: TNegMatch(TMatch *ANode); virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const; private: std::auto_ptr > FNode; }; template class TDivMatch : public TMatch { public: TDivMatch(TMatch *ALeft, TMatch *ARight); virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const; private: std::auto_ptr > FLeft; std::auto_ptr > FRight; }; template class TPowMatch : public TMatch { public: TPowMatch(TMatch *ABase, TMatch *AExp); virtual bool match(const TNode *AExpr, TMatchRegistry *AReg) const; private: std::auto_ptr > FBase; std::auto_ptr > FExp; }; /** TMatcher<> is a dynamic matching system for symbolic expressions. * One application for that is simplifying expressions. * * TMatcher<> class is really to be done. But it will rock then. * Example: *
  *   TMatcher::TResult matchResult;
  *   if (TMatcher::match("a+a", expr, machResult))
  *       return transform(expr, machResult, "2*a+$");
  * 
* * the "$" means the remaining part not matched using given template match, * here "a+a". Example: if you've a+b+a and want match a+a, then the remaining * part is b; if you've a^2+b^(sin(2x)+2)+c^2+c*2*a and want to match * a^2+2ab+b^2, then the matched parts is: "a^2+c^2+c*2*a" and the remaining * part will be: "b^(sin(2x)+2)". */ template class TMatcher : public TNodeVisitor { public: typedef std::map > TResult; /** matchExact returns true when the template (AMatch) represents exactly * the test expression (AExpr). */ static bool matchExact(const TMatch *AMatch, const TNode *AExpr, TMatchRegistry *AReg = 0); /** returns true when given pattern (AMatch) was matched in given * expression (AExpr). The result data is stored into the registry * on success only. */ static bool match(const TMatch *AMatch, const TNode *AExpr, TMatchRegistry *AReg = 0); /** match matches a given expression template on expression AExpr and * puts its result into AResult. */ static unsigned match(const std::string& AMatch, const TNode *AExpr, TResult& AResult); private: TMatcher(const TMatch *AMatch, const TNode *ANode, TMatchRegistry *AReg = 0); private: const TMatch *FMatch; const TNode *FExpr; private: virtual void visit(TNumberNode *); virtual void visit(TSymbolNode *); virtual void visit(TParamNode *); virtual void visit(TPlusNode *); virtual void visit(TNegNode *); virtual void visit(TMulNode *); virtual void visit(TDivNode *); virtual void visit(TPowNode *); virtual void visit(TSqrtNode *); virtual void visit(TSinNode *); virtual void visit(TCosNode *); virtual void visit(TTanNode *); virtual void visit(TLnNode *); virtual void visit(TFuncNode *); virtual void visit(TIfNode *); virtual void visit(TEquNode *); virtual void visit(TUnEquNode *); virtual void visit(TGreaterNode *); virtual void visit(TLessNode *); virtual void visit(TGreaterEquNode *); virtual void visit(TLessEquNode *); }; } // namespace math #include #endif