Inferno
0.2
|
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