00001 //-*-c++-*- 00002 // ==================================================================== 00003 // ==================================================================== 00004 // 00005 // Module: opt_dfs.h 00006 // $Revision: 1.1.1.1 $ 00007 // $Date: 2005/10/21 19:00:00 $ 00008 // $Author: marcel $ 00009 // $Source: /proj/osprey/CVS/open64/osprey1.0/be/opt/opt_dfs.h,v $ 00010 // 00011 // ==================================================================== 00012 // 00013 // Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00014 // 00015 // This program is free software; you can redistribute it and/or modify 00016 // it under the terms of version 2 of the GNU General Public License as 00017 // published by the Free Software Foundation. 00018 // 00019 // This program is distributed in the hope that it would be useful, but 00020 // WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 // 00023 // Further, this software is distributed without any warranty that it 00024 // is free of the rightful claim of any third person regarding 00025 // infringement or the like. Any license provided herein, whether 00026 // implied or otherwise, applies only to this software file. Patent 00027 // licenses, if any, provided herein do not apply to combinations of 00028 // this program with other software, or any other product whatsoever. 00029 // 00030 // You should have received a copy of the GNU General Public License 00031 // along with this program; if not, write the Free Software Foundation, 00032 // Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00033 // 00034 // Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00035 // Mountain View, CA 94043, or: 00036 // 00037 // http://www.sgi.com 00038 // 00039 // For further information regarding this notice, see: 00040 // 00041 // http://oss.sgi.com/projects/GenInfo/NoticeExplan 00042 // 00043 // ==================================================================== 00044 // 00045 // Description: 00046 // 00047 // The template depth-first search package requires that you define a 00048 // single class that describes the implementation of the search. The 00049 // class must have the following members: 00050 // 00051 // Member typedefs: 00052 // node_type 00053 // adj_list_type 00054 // adj_list_iter_type 00055 // node_iterator 00056 // 00057 // TODO: Document the typedefs. 00058 // 00059 // Member functions: 00060 // constructor(node_type *N) 00061 // Sets the current node in the search to be node *N; N can also 00062 // be NULL for a top-level search descriptor that carries only 00063 // type information for templatization. This hack would not be 00064 // necessary if not for a bug in our C++ front end (see below). 00065 // 00066 // void Set_seen(node_type *N) 00067 // Has the side effect of noting that the search has visited the 00068 // node *N. Also incorporates any other side-effect actions that 00069 // need to be done in preorder (before the search recurses on the 00070 // neighbors of *N). 00071 // 00072 // BOOL Seen(node_type *N) 00073 // Returns TRUE if Set_seen(N) has been called since the start of 00074 // the search, otherwise returns FALSE. 00075 // 00076 // void Reach_from_to(node_type *M, INT tag, node_type *N) 00077 // Performs any side-effect actions that need to be done to any 00078 // neighbor *N of node *M when the search is visiting node 00079 // *M. Note that the search may or may not go on to recurse for 00080 // N. For many search implementations, Reach_from_to() will be an 00081 // empty function that does nothing. 00082 // TODO: Document the parameter list properly. 00083 // 00084 // BOOL Start_from(node_type *N) 00085 // Returns TRUE if the search should begin from node *N, otherwise 00086 // returns FALSE. When Start_from(N) is called, it is guaranteed 00087 // that Seen(N) is FALSE. 00088 // 00089 // BOOL Continue_from_to(node_type *M, INT tag, node_type *N) 00090 // Returns TRUE if the search should recurse from node *M to node 00091 // *N, where *N is a neighbor of *M. When 00092 // Continue_from_to(M, tag, N) is called, 00093 // Reach_from_to(M, tag, N) is guaranteed to have been called 00094 // already, Set_seen(M) has been called, and Seen(N) has just 00095 // returned FALSE. 00096 // TODO: Document the parameter list properly and provide a 00097 // better explanation. 00098 // 00099 // void Postorder_processing(node_type *N) 00100 // Performs any side-effect actions that should be done after the 00101 // recursion on *N's neighbors is complete. 00102 // 00103 // node_type *Current_node(void) 00104 // Returns a pointer to the current node being visited by the 00105 // search. This function exists because of a bug in our C++ front 00106 // end that keeps us from making the current node an argument to 00107 // Df_search with a parameterized type. 00108 // 00109 // adj_list_type *Neighbors(node_type *N) 00110 // Returns a pointer to the list of neighbors of node *N in a form 00111 // acceptable to the function 00112 // adj_list_iter_type::Init(adj_list_type *). 00113 // 00114 // BOOL Tracing(void) 00115 // Returns a flag that tells whether the depth-first search 00116 // template routines should trace their progress to TFile. 00117 // 00118 // The following member is required only if Perform_dfs is used to 00119 // check each node in the graph for starting points of the 00120 // search. If the search is started only "manually" via direct calls 00121 // to the nodewise Df_search routine, this member isn't needed. 00122 // x Nodes(void) 00123 // Returns an entity of type x which, when passed to 00124 // node_iterator::Init(x), initializes *this to iterate over all 00125 // nodes in the universe of interest where the depth-first search 00126 // might originate. The specifics of type x are left up to the 00127 // designer of the search implementation descriptor class. 00128 // 00129 // ==================================================================== 00130 // ==================================================================== 00131 00132 00133 // In the following template function definition, we unfortunately 00134 // have to specify EXP_OCCURS explicitly rather than use 00135 // search_type::node_type. This seems to be a EDG front-end bug. 00136 00137 template <class search_type> void 00138 Df_search(const search_type &srch) 00139 { 00140 Is_Trace(srch.Tracing(), (TFile, "%s: searching ", srch.Search_name())); 00141 Is_Trace_cmd(srch.Tracing(), srch.Current_node()->Print(TFile)); 00142 00143 srch.Set_seen(srch.Current_node()); 00144 00145 typename search_type::adj_list_type *neighbor; 00146 typename search_type::adj_list_iter_type neighbor_iter; 00147 00148 FOR_ALL_NODE(neighbor, 00149 neighbor_iter, 00150 Init(srch.Neighbors(srch.Current_node()))) { 00151 Is_Trace(srch.Tracing(), (TFile, "%s: reaching ", srch.Search_name())); 00152 Is_Trace_cmd(srch.Tracing(), neighbor->Node()->Print(TFile)); 00153 00154 srch.Reach_from_to(srch.Current_node(), 00155 neighbor->Opnd_idx(), 00156 neighbor->Node()); 00157 if (!srch.Seen(neighbor->Node()) && 00158 srch.Continue_from_to(srch.Current_node(), 00159 neighbor->Opnd_idx(), 00160 neighbor->Node())) { 00161 search_type new_srch(neighbor->Node()); 00162 Df_search(new_srch); 00163 } 00164 } 00165 srch.Postorder_processing(srch.Current_node()); 00166 } 00167 00168 template <class search_type> void 00169 Perform_dfs(const search_type &srch) 00170 { 00171 typename search_type::node_iterator nodes; 00172 typename search_type::node_type *node; 00173 00174 FOR_ALL_NODE(node, nodes, Init(srch.Nodes())) { 00175 if (!srch.Seen(node) && srch.Start_from(node)) { 00176 Is_Trace(srch.Tracing(), (TFile, "%s: Beginning from ", srch.Search_name())); 00177 Is_Trace_cmd(srch.Tracing(), node->Print(TFile)); 00178 00179 search_type srch(node); 00180 Df_search(srch); 00181 } 00182 } 00183 }
1.5.6