Inferno  0.2
agent.hpp
Go to the documentation of this file.
00001 #ifndef AGENT_HPP
00002 #define AGENT_HPP
00003 
00004 #include "common/common.hpp"
00005 #include "common/read_args.hpp"
00006 #include "helpers/walk.hpp"
00007 #include "helpers/transformation.hpp"
00008 #include "coupling.hpp"
00009 #include <set>
00010 
00011 class Conjecture;
00012 class SpecialBase;
00013 class StuffBase;
00014 class StarBase;
00015 class SlaveBase;
00016 class SearchContainerBase;
00017 class SearchReplace;
00018 
00019 class Agent : public Traceable
00020 {
00021 public:
00022     virtual bool DecidedCompare( const TreePtrInterface &x,
00023                   TreePtr<Node> pattern,
00024                   bool can_key,
00025                     Conjecture &conj ) const = 0;
00026     virtual TreePtr<Node> BuildReplace( TreePtr<Node> pattern, 
00027                          TreePtr<Node> keynode=TreePtr<Node>() ) const = 0;
00028     virtual void ConfigureTreePtrThis( TreePtr<Node> tpt ) = 0;                    
00029   virtual void Configure( const CompareReplace *s, CouplingKeys *c ) = 0;
00030 };
00031 
00032 
00033 
00034 class NormalAgent : public Agent
00035 {
00036 public:
00037   NormalAgent() :sr(NULL), coupling_keys(NULL) {}
00038     void ConfigureTreePtrThis( TreePtr<Node> tpt );                    
00039   void Configure( const CompareReplace *s, CouplingKeys *c );
00040 private:
00041   const CompareReplace *sr;
00042   CouplingKeys *coupling_keys;
00043 public:
00044     virtual bool DecidedCompare( const TreePtrInterface &x,
00045                              TreePtr<Node> pattern,
00046                              bool can_key,
00047                              Conjecture &conj ) const;
00048 private:
00049     bool DecidedCompare( SequenceInterface &x,
00050                      SequenceInterface &pattern,
00051                      bool can_key,
00052                      Conjecture &conj ) const;
00053     bool DecidedCompare( CollectionInterface &x,
00054                      CollectionInterface &pattern,
00055                      bool can_key,
00056                      Conjecture &conj ) const;
00057     bool DecidedCompare( const TreePtrInterface &x,
00058                      shared_ptr<SearchContainerBase> pattern,
00059                      bool can_key,
00060                      Conjecture &conj ) const;
00061 public: 
00062     virtual TreePtr<Node> BuildReplace( TreePtr<Node> pattern, 
00063                          TreePtr<Node> keynode=TreePtr<Node>() ) const;
00064 private:  
00065   TreePtr<Node> BuildReplaceOverlay( TreePtr<Node> pattern, 
00066                       TreePtr<Node> keynode ) const; // under substitution if not NULL
00067     TreePtr<Node> BuildReplaceSlave( shared_ptr<SlaveBase> pattern, 
00068                     TreePtr<Node> keynode ) const;    
00069     TreePtr<Node> BuildReplaceNormal( TreePtr<Node> pattern ) const;
00070     TreePtr<Node> BuildReplaceKeyed( TreePtr<Node> pattern, 
00071                     TreePtr<Node> keynode ) const;
00072     TreePtr<Node> BuildReplaceStar( shared_ptr<StarBase> pattern, 
00073                    TreePtr<Node> keynode ) const;
00074                    
00075 private:
00076     Sequence<Node> WalkContainerPattern( ContainerInterface &pattern,
00077                                          bool replacing ) const;
00078   // Internal node classes - NOTE these are not special nodes, and we use them like normal tree nodes
00079   // Note: only needed for Star pattern
00080     struct SubContainer : Node
00081     {
00082         NODE_FUNCTIONS
00083     };
00084     struct SubSequenceRange : SequenceInterface,
00085                               SubContainer
00086     {
00087       NODE_FUNCTIONS_FINAL 
00088 
00089         SubSequenceRange() {}
00090       shared_ptr<iterator_interface> my_begin;
00091       shared_ptr<iterator_interface> my_end;
00092       operator string() const { return GetName() + SSPrintf("@%p", this); }    
00093     public:
00094       SubSequenceRange( iterator &b, iterator &e ) : my_begin(b.Clone()), my_end(e.Clone())
00095       {         
00096       }
00097       virtual const iterator_interface &begin() { return *my_begin; }
00098         virtual const iterator_interface &end()   { return *my_end; }
00099         virtual void erase( iterator )  { ASSERTFAIL("Cannot modify SubSequenceRange"); }
00100         virtual void clear()                                { ASSERTFAIL("Cannot modify SubSequenceRange"); }    
00101         virtual void insert( const TreePtrInterface & )     { ASSERTFAIL("Cannot modify SubSequenceRange"); }
00102         virtual TreePtrInterface &operator[]( int i ) { ASSERTFAIL("TODO"); }  
00103         virtual void push_back( const TreePtrInterface &gx ){ ASSERTFAIL("Cannot modify SubSequenceRange"); }  
00104     };
00105     struct SubSequence : Sequence<Node>,
00106                          SubContainer
00107     {
00108       NODE_FUNCTIONS_FINAL 
00109       operator string() const { return GetName() + SSPrintf("@%p", this); }    
00110     };
00111     struct SubCollection : Collection<Node>,
00112                            SubContainer
00113     {
00114       NODE_FUNCTIONS_FINAL
00115       operator string() const { return GetName() + SSPrintf("@%p", this); } 
00116     };
00117 
00118 };
00119 
00120 
00121 template<typename NODE_TYPE>
00122 class NormalAgentWrapper : public NODE_TYPE,
00123                            public NormalAgent
00124 {
00125 };
00126 
00127 
00128 // Similar to MakeTreePtr<> (see node/specialise_oostd.hpp) but produces a TreePtr to NormalAgentWrapper<NODE_TYPE> rather
00129 // than just NODE_TYPE when NODE_TYPE is not already a kind of Agent. Wrapping case only allowed with zero constructor 
00130 // parameters, which is a requirement for normal nodes anyway.
00131 template<typename NODE_TYPE>
00132 class MakePatternPtr : public TreePtr<NODE_TYPE>
00133 {
00134 private:
00135   bool IsNeedWrapper()
00136   {
00137     return !( NODE_TYPE::GetInterfaces()=="agent" );
00138   }
00139 public: 
00140   MakePatternPtr() : TreePtr<NODE_TYPE>( IsNeedWrapper() ? 
00141                                          new NormalAgentWrapper<NODE_TYPE> : 
00142                                          new NODE_TYPE )
00143   {
00144     Agent *ap = dynamic_cast<Agent *>( TreePtr<NODE_TYPE>::get() );
00145     ASSERT( ap )("Trying to produce non-Agent object, IsNeedWrapper returns %d", IsNeedWrapper());
00146     ap->ConfigureTreePtrThis( (TreePtr<Node>)(*this) );
00147   }
00148   template<typename CP0>
00149   MakePatternPtr(const CP0 &cp0) : TreePtr<NODE_TYPE>( new NODE_TYPE(cp0) ) 
00150   { 
00151     ASSERT( !IsNeedWrapper() )("MakePatternPtr cannot pass constructor params to normal nodes");    
00152   }
00153   template<typename CP0, typename CP1>
00154   MakePatternPtr(const CP0 &cp0, const CP1 &cp1) : TreePtr<NODE_TYPE>( new NODE_TYPE(cp0, cp1) )
00155   { 
00156     ASSERT( !IsNeedWrapper() )("MakePatternPtr cannot pass constructor params to normal nodes");    
00157   }
00158   template<typename CP0, typename CP1, typename CP2>
00159   MakePatternPtr(const CP0 &cp0, const CP1 &cp1, const CP2 &cp2) : TreePtr<NODE_TYPE>( new NODE_TYPE(cp0, cp1, cp2) )
00160   { 
00161     ASSERT( !IsNeedWrapper() )("MakePatternPtr cannot pass constructor params to normal nodes");    
00162   }
00163   // Add more params as needed...
00164 };
00165 
00166 #endif