/////////////////////////////////////////////////////////////////////// // Math Type Library // $Id: matcher.tcc,v 1.4 2002/07/02 00:56:12 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 #error You may not include math/matcher.tcc directly; include math/matcher.h instead. #endif #include namespace math { /////////////////////////////////////////////////////////////////////// // TMatchRegistry /////////////////////////////////////////////////////////////////////// template TMatchRegistry::TMatchRegistry() { } template TMatchRegistry::TMatchRegistry(const TMatchRegistry& AProto) : FAnyMap(AProto.FAnyMap), FNodeList(AProto.FNodeList) { } template void TMatchRegistry::define(const std::string& AId, const TNode *ANode) { FAnyMap[AId] = ANode; } template bool TMatchRegistry::defined(const std::string& AId) const { for (typename TAnyMap::const_iterator i = FAnyMap.begin(); i != FAnyMap.end(); ++i) if (i->first == AId) return true; return false; } template const TNode *TMatchRegistry::get(const std::string& AId) const { for (typename TAnyMap::const_iterator i = FAnyMap.begin(); i != FAnyMap.end(); ++i) if (i->first == AId) return i->second; return 0; // should throw ! } template void TMatchRegistry::mark(const TNode *ANode) { FNodeList.push_back(ANode); } template bool TMatchRegistry::contains(const TNode *ANode) const { for (typename TAnyMap::const_iterator i = FAnyMap.begin(); i != FAnyMap.end(); ++i) if (i->second == ANode) return true; for (typename TNodeList::const_iterator i = FNodeList.begin(); i != FNodeList.end(); ++i) if (*i == ANode) return true; return false; } /////////////////////////////////////////////////////////////////////// // Match Template Tree /////////////////////////////////////////////////////////////////////// /* TNumMatch */ template TNumMatch::TNumMatch(const T& ANumber) : FNumber(ANumber) { } template bool TNumMatch::match(const TNode *AExpr, TMatchRegistry *AReg) const { for (typename TNode::const_operand_iterator i = AExpr; i != i.end(); ++i) { // find a number equal to the one we want to match and isn't yet matched // by another one. if (i->nodeType() == TNode::NUMBER_NODE && !AReg->contains(i.get()) && static_cast *>(i.get())->number() == FNumber) { AReg->mark(i.get()); return true; } } return false; } /* TAnyMatch */ template TAnyMatch::TAnyMatch(const std::string& AId) : FIdent(AId) { } template bool TAnyMatch::match(const TNode *AExpr, TMatchRegistry *AReg) const { if (AReg->defined(FIdent)) { // identififier is already defined, look for another, but equal, one const TNode *node = AReg->get(FIdent); for (typename TNode::const_operand_iterator i = AExpr; i != i.end(); ++i) { if (!AReg->contains(i.get()) && *i == *node) { // if operand not yet in registry and equal to given one... AReg->mark(i.get()); // mark as already matched. return true; } } } else { // identifier not defined, search for first free operand for (typename TNode::const_operand_iterator i = AExpr; i != i.end(); ++i) { if (!AReg->contains(i.get())) { // if operand not yet in registry, define and return success AReg->define(FIdent, i.get()); return true; } } } return false; } /* T2Match */ template T2Match::T2Match(TMatch *ALeft, TMatch *ARight) { FPatterns.push_back(ALeft); FPatterns.push_back(ARight); } template T2Match::~T2Match() { for (typename TList::iterator i = FPatterns.begin(); i != FPatterns.end(); ++i) delete *i; } /* TPlusMatch */ template TPlusMatch::TPlusMatch(TMatch *ALeft, TMatch *ARight, ...) : T2Match(ALeft, ARight) { va_list ap; va_start(ap, ARight); while (TMatch *p = va_arg(ap, TMatch *)) this->FPatterns.push_back(p); va_end(ap); } template bool TPlusMatch::match(const TNode *AExpr, TMatchRegistry *AReg) const { // yet a primitive sequencial search for (typename T2Match::TList::const_iterator p = this->FPatterns.begin(); p != this->FPatterns.end(); ++p) if (!TMatcher::match(*p, AExpr, AReg)) return false; return true; } /* TMulMatch */ template TMulMatch::TMulMatch(TMatch *ALeft, TMatch *ARight, ...) : T2Match(ALeft, ARight) { va_list ap; va_start(ap, ARight); while (TMatch *p = va_arg(ap, TMatch *)) this->FPatterns.push_back(p); va_end(ap); } template bool TMulMatch::match(const TNode *AExpr, TMatchRegistry *AReg) const { return false; } /* TPowMatch */ template TPowMatch::TPowMatch(TMatch *ABase, TMatch *AExp) : FBase(ABase), FExp(AExp) { } template bool TPowMatch::match(const TNode *AExpr, TMatchRegistry *AReg) const { for (typename TNode::const_operand_iterator i = AExpr; i != i.end(); ++i) { // look for a power node matching exactly our base and exponent template if (!AReg->contains(i.get()) && i->nodeType() == TNode::POW_NODE) { if (TMatcher::matchExact(FBase.get(), i->left()) && TMatcher::matchExact(FExp.get(), i->right())) { AReg->mark(i.get()); return true; } } } return false; } /////////////////////////////////////////////////////////////////////// // TMatcher /////////////////////////////////////////////////////////////////////// template bool TMatcher::matchExact(const TMatch *AMatch, const TNode *ANode, TMatchRegistry *AReg) { TMatcher matcher(AMatch, ANode, AReg); // TODO + FIXME return false;//!matcher.hasUnused(); } template bool TMatcher::match(const TMatch *AMatch, const TNode *ANode, TMatchRegistry *AReg) { TMatcher matcher(AMatch, ANode, AReg); // TODO + FIXME return false;//matcher.success(); } template TMatcher::TMatcher(const TMatch *AMatch, const TNode *ANode, TMatchRegistry *AReg) : FMatch(AMatch), FExpr(ANode) { } template void TMatcher::visit(TNumberNode *ANode) { } template void TMatcher::visit(TSymbolNode *ANode) { } template void TMatcher::visit(TParamNode *ANode) { } template void TMatcher::visit(TPlusNode *ANode) { } template void TMatcher::visit(TNegNode *ANode) { } template void TMatcher::visit(TMulNode *ANode) { } template void TMatcher::visit(TDivNode *ANode) { } template void TMatcher::visit(TPowNode *ANode) { } template void TMatcher::visit(TSqrtNode *ANode) { } template void TMatcher::visit(TSinNode *ANode) { } template void TMatcher::visit(TCosNode *ANode) { } template void TMatcher::visit(TTanNode *ANode) { } template void TMatcher::visit(TLnNode *ANode) { } template void TMatcher::visit(TFuncNode *ANode) { } template void TMatcher::visit(TIfNode *ANode) { } template void TMatcher::visit(TEquNode *ANode) { } template void TMatcher::visit(TUnEquNode *ANode) { } template void TMatcher::visit(TGreaterNode *ANode) { } template void TMatcher::visit(TLessNode *ANode) { } template void TMatcher::visit(TGreaterEquNode *ANode) { } template void TMatcher::visit(TLessEquNode *ANode) { } } // namespace math