00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _TREE_ISO_CHECK_H_
00023 #define _TREE_ISO_CHECK_H_
00024
00025 #include <stack>
00026 #include <utility>
00027
00028 #include "typedefs.h"
00029
00030 template<class PP, class MP, class ST, template<class, typename, typename, template <typename> class > class CC,
00031 template<typename> class ALLOC>
00032 class pattern;
00033
00034 class directed;
00035 class acyclic;
00036 class indegree_lte_one;
00037 class ordered;
00038
00039 template<class prop, class next_property>
00040 class proplist;
00041
00042 using namespace std;
00043
00045 template<class PP, class MP, class ST, template<typename, typename, typename, template <typename> class > class CC,
00046 template <typename> class ALLOC >
00047 void update_rmost_path(pattern<TREE_PROP, MP, ST, CC, ALLOC>*const& cand_pat) {
00048
00049 typedef pattern<TREE_PROP, MP, ST, CC, ALLOC> PATTERN;
00050
00051 int new_vid=cand_pat->rmost_vid();
00052 typename PATTERN::RMP_T& rmost_path=cand_pat->_rmost_path;
00053 int pvid=(cand_pat->in_edges(new_vid)).first->first;
00054
00055
00056 typename PATTERN::RMP_T::iterator it=rmost_path.end()-1;
00057 if(rmost_path.end()!=rmost_path.begin())
00058 while(it!=rmost_path.begin()) {
00059 if(*it==pvid)
00060 break;
00061 it=rmost_path.erase(it);
00062 it--;
00063
00064
00065 cand_pat->_canonical_code.backtrack();
00066 }
00067
00068 rmost_path.push_back(new_vid);
00069
00070 cand_pat->_canonical_code.insert_vertex(cand_pat->label(new_vid));
00071
00072 }
00073
00074
00076 template<typename IT>
00077 int eit_diff_one(IT it1, IT it2) {
00078 if(it1==it2)
00079 return true;
00080 it1++;
00081 if(it1==it2)
00082 return true;
00083
00084 return false;
00085 }
00086
00088 template<typename IT>
00089 IT last_eits(IT it1, IT it2) {
00090 IT prev=it1;
00091 it1++;
00092 it1++;
00093
00094 while(it1++!=it2)
00095 prev++;
00096
00097 return prev;
00098 }
00099
00102 template<class PP, class MP, class ST, template<typename, typename, typename, template <typename> class > class CC,
00103 template <typename> class ALLOC>
00104 bool check_isomorphism(pattern<TREE_PROP, MP, ST, CC, ALLOC>*const& cand_pat) {
00105
00106 typedef pattern<TREE_PROP, MP, ST, CC, ALLOC> PATTERN;
00107
00108 typename PATTERN::RMP_T::const_iterator it;
00109 typename PATTERN::CONST_EIT_PAIR eit_pair;
00110
00111 update_rmost_path(cand_pat);
00112 it=cand_pat->_rmost_path.end();
00113 if(cand_pat->_rmost_path.size())
00114 it--;
00115
00116 while(it>=cand_pat->_rmost_path.begin()) {
00117
00118 eit_pair=cand_pat->out_edges(*it);
00119 bool max_one_child=false;
00120
00121
00122 if(eit_pair.first!=eit_pair.second)
00123 eit_pair.second--;
00124 else
00125 max_one_child=true;
00126
00127 if(eit_pair.first==eit_pair.second)
00128 max_one_child=true;
00129 else
00130 eit_pair.second--;
00131
00132 if(!max_one_child && !check_subtree_order(eit_pair.second, cand_pat)) {
00133
00134 cand_pat->_is_canonical=false;
00135 return false;
00136 }
00137 it--;
00138 }
00139
00140
00141 cand_pat->_is_canonical=true;
00142 return true;
00143
00144 }
00145
00148 template<typename EIT, typename PATTERN>
00149 bool check_subtree_order(EIT& edge_it, const PATTERN*const& cand_pat) {
00150
00151
00152
00153
00154 int vid_x=edge_it->first;
00155 edge_it++;
00156 int vid_y=edge_it->first;
00157
00158 typename PATTERN::CONST_EIT_PAIR edges;
00159 typedef pair<int, int> st_pair;
00160
00161 stack<st_pair> stack_x;
00162 stack<st_pair> stack_y;
00163
00164 stack_x.push(make_pair(vid_x, 0));
00165 stack_y.push(make_pair(vid_y, 0));
00166
00167 while(!stack_x.empty() && !stack_y.empty()) {
00168
00169 const st_pair& node_x=stack_x.top();
00170 stack_x.pop();
00171 const st_pair& node_y=stack_y.top();
00172 stack_y.pop();
00173
00175 if(node_x.second<node_y.second) {
00176
00177 return false;
00178 }
00179
00180 if(node_x.second>node_y.second) {
00181
00182 return true;
00183 }
00184
00186 if(cand_pat->label(node_x.first) < cand_pat->label(node_y.first)) {
00187 return true;
00188 }
00189
00190 if(cand_pat->label(node_x.first) > cand_pat->label(node_y.first)) {
00191 return false;
00192 }
00193
00194
00195 edges=cand_pat->out_edges(node_x.first);
00196 if(edges.second!=edges.first) {
00197 edges.second--;
00198 while(edges.second!=edges.first) {
00199 stack_x.push(make_pair(edges.second->first, node_x.second+1));
00200 edges.second--;
00201 }
00202 stack_x.push(make_pair(edges.second->first, node_x.second+1));
00203 }
00204
00205
00206 edges=cand_pat->out_edges(node_y.first);
00207 if(edges.second!=edges.first) {
00208 edges.second--;
00209 while(edges.second!=edges.first) {
00210 stack_y.push(make_pair(edges.second->first, node_y.second+1));
00211 edges.second--;
00212 }
00213 stack_y.push(make_pair(edges.second->first, node_y.second+1));
00214 }
00215
00216 }
00217
00218 if(!stack_x.empty()) {
00219
00220 return true;
00221 }
00222
00223 if(!stack_y.empty()) {
00224
00225 return false;
00226 }
00227
00228
00229 return true;
00230
00231 }
00232
00233
00237 template<class PP, class MP, class ST, template<typename, typename, typename, template <typename> class > class CC,
00238 template <typename> class ALLOC >
00239 bool check_isomorphism(pattern<ORD_TREE_PROP, MP, ST, CC, ALLOC>*const& cand_pat) {
00240 update_rmost_path(cand_pat);
00241 cand_pat->_is_canonical=true;
00242 return true;
00243 }
00244
00245 #endif