Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:19:37

0001 /* This software is distributed under the GNU Lesser General Public License */
0002 //==========================================================================
0003 //
0004 //   pq_node.h
0005 //
0006 //==========================================================================
0007 // $Id: pq_node.h,v 1.15 2003/04/03 11:48:26 raitner Exp $
0008 
0009 #ifndef PQ_NODE_H
0010 #define PQ_NODE_H
0011 
0012 #include <GTL/GTL.h>
0013 #include <GTL/symlist.h>
0014 #include <GTL/graph.h>
0015 
0016 #include <list>
0017 #include <iostream>
0018 
0019 __GTL_BEGIN_NAMESPACE
0020 
0021 class pq_tree;
0022 class p_node;
0023 class q_node; 
0024 class pq_leaf;
0025 class direction_indicator;
0026 
0027 /**
0028  * @internal
0029  */
0030 class GTL_EXTERN pq_node 
0031 {
0032 protected:
0033     /**
0034      * @internal
0035      */
0036     typedef symlist<pq_node*>::iterator iterator;
0037 
0038     /**
0039      * @internal
0040      */
0041     enum PQ_KIND {P_NODE, Q_NODE, LEAF, DIR};
0042 
0043     /**
0044      * @internal
0045      */
0046     enum PQ_MARK {UNMARKED, QUEUED, BLOCKED, UNBLOCKED};
0047 
0048     /**
0049      * @internal
0050      */
0051     pq_node (node n_, int id_) :  pert_children(0),
0052                   pert_leaves(0),
0053                   mark (UNMARKED),
0054                   n (n_),
0055                   id (id_)
0056     {
0057     }
0058 
0059     /**
0060      * @internal
0061      */
0062     virtual ~pq_node ();
0063 
0064     /**
0065      * @internal
0066      * Used to identify nodes.
0067      */
0068     virtual PQ_KIND kind() const = 0;
0069 
0070     /**
0071      * @internal
0072      * Called whenever a son is known to be partial during reduction phase.
0073      */
0074     virtual void partial(iterator)
0075     {
0076     }
0077 
0078     /**
0079      * @internal
0080      * Called whenever a son is known to be full during reduction phase.
0081      */
0082     virtual void full(iterator)
0083     {
0084     }
0085 
0086     /**
0087      * @internal
0088      * Used to write a description of this node into a stream.
0089      */
0090     virtual void write(ostream&, int) = 0;
0091 
0092     /**
0093      * @internal
0094      * Reset node for next reduction.
0095      */
0096     virtual void clear()
0097     {
0098     mark = UNMARKED;
0099     pert_leaves = 0;
0100     pert_children = 0;
0101     }
0102 
0103     // type-casts 
0104 
0105     /**
0106      * @internal
0107      * Interface type-cast to P-node.
0108      */
0109     virtual p_node* P() = 0;
0110 
0111     /**
0112      * @internal
0113      * Interface type-cast to Q-node.
0114      */
0115     virtual q_node* Q() = 0;
0116 
0117     /**
0118      * @internal
0119      * Interface type-cast to direction indicator.
0120      */
0121     virtual direction_indicator* D() = 0;
0122 
0123     /**
0124      * @internal
0125      * Interface type-cast to PQ-leaf.
0126      */
0127     virtual pq_leaf* L() = 0;
0128 
0129     //
0130     // Data used in reductions
0131     //
0132 
0133     /**
0134      * @internal
0135      * Number of pertinent children; is calculated during bubble-up phase
0136      * and gets decreased whenever a pertinent child is matched in reduction
0137      * phase, such that it can be assured that this node is matched @em
0138      * after all its pertinent children were correctly matched.
0139      */
0140     int pert_children;
0141 
0142     /**
0143      * @internal
0144      * Number of pertinent leaves in the subtree rooted at this node; is 
0145      * calculated in the reduction phase and is used to determine the root 
0146      * of the pertinent subtree, i.e. the last node for template matchings. 
0147      */
0148     int pert_leaves;
0149 
0150     /**
0151      * @internal
0152      * For Q-nodes it is not acceptable to maintain father pointers for @em 
0153      * all sons (cf. Booth, Luecker); fortunatly this isn't neccessary and 
0154      * the father pointer is only valid if is_endmost is true. For the sons
0155      * of a Q-node is_endmost is only true for the first and the last son.
0156      * For the sons of P-nodes ths flag is always true.
0157      */
0158     bool is_endmost;
0159 
0160     /**
0161      * @internal
0162      * The main operations on PQ-trees are performed bottom up so each node
0163      * should know its father; Because of complexity issuses this isn't
0164      * always possible and  thus father is valid iff is_endmost is true.
0165      */
0166     pq_node* father;
0167 
0168     /**
0169      * @internal
0170      * Describes the role this node plays in the reduction at the moment;
0171      * four states are possible:
0172      * -# @c UNMARKED: node wasn't touched so far
0173      * -# @c BLOCKED: during bubble-up phase this node got queued, but as
0174      *    yet it was not possible to get a valid father pointer
0175      * -# @c UNBLOCKED: node was touched during bubble-up and it either had
0176      *    a valid father pointer or one could be borrowed from one of its
0177      *    siblings
0178      * -# @c QUEUED: node has been put into the queue
0179      */
0180     PQ_MARK mark;
0181 
0182     /**
0183      * @internal
0184      * List of sons.
0185      */
0186     symlist<pq_node*> sons;
0187 
0188     /**
0189      * @internal
0190      * Position in the list of sons of node's father.
0191      */
0192     iterator pos;
0193 
0194     /**
0195      * @internal
0196      * Position in the list of nodes to be cleared in reset. Each node
0197      * touched in #bubble-up phase is stored in the list of nodes to be
0198      * cleared. As they get matched in the reduction phase they are cleared
0199      * and deleted from this list. But even if the reduction is successful
0200      * not all nodes touched in the first phase really get matched.
0201      */
0202     list<pq_node*>::iterator lpos;
0203 
0204     //
0205     // Application specific data (should become template parameter)
0206     //
0207 
0208     /**
0209      * @internal
0210      * Node of the graph which this PQ-node represents.
0211      */
0212     node n;
0213 
0214     /**
0215      * @internal
0216      */
0217     int id;
0218 
0219     /**
0220      * @internal
0221      */
0222     node up;
0223 
0224     /**
0225      * @internal
0226      */
0227     int up_id;
0228 
0229     //
0230     // Friends
0231     //
0232 
0233     /**
0234      * @internal
0235      * Allow q_node private access.
0236      */
0237     friend class q_node;
0238 
0239     /**
0240      * @internal
0241      * Allow p_node private access.
0242      */
0243     friend class p_node;
0244 
0245     /**
0246      * @internal
0247      * Allow my_pq_tree private access.
0248      */
0249     friend class pq_tree;
0250 
0251     /**
0252      * @internal
0253      * Allow planarity private access.
0254      */
0255     friend class planarity;
0256 
0257     /**
0258      * @internal
0259      * Allow operator<< private access.
0260      */
0261     GTL_EXTERN friend ostream& operator<<(ostream&, const pq_tree&);
0262 };
0263 
0264 
0265 /**
0266  * @internal
0267  */
0268 class GTL_EXTERN p_node : public pq_node 
0269 {
0270 private:
0271     /**
0272      * @internal
0273      */
0274     p_node(node, int);
0275 
0276     /**
0277      * @internal
0278      */
0279     p_node(node, int, symlist<pq_node*>&);
0280     
0281     //
0282     // pq_node interface
0283     // 
0284 
0285     /**
0286      * @internal
0287      */
0288     void partial(iterator);
0289 
0290     /**
0291      * @internal
0292      */
0293     void full(iterator);
0294 
0295     /**
0296      * @internal
0297      * Determines kind of this %node.
0298      */
0299     PQ_KIND kind () const 
0300     {
0301     return P_NODE;
0302     }
0303 
0304     /**
0305      * @internal
0306      * Print this %node in gml format.
0307      */
0308     void write (ostream&, int);
0309 
0310     /**
0311      * @internal
0312      */
0313     void clear ();
0314 
0315     // type-casts
0316 
0317     /**
0318      * @internal
0319      * Type-cast to P-node.
0320      */
0321     p_node* P()
0322     {
0323     return this;
0324     }
0325 
0326     /**
0327      * @internal
0328      * Type-cast to Q-node.
0329      */
0330     q_node* Q()
0331     {
0332     assert(false);
0333     return 0;
0334     }
0335 
0336     /**
0337      * @internal
0338      * Type-cast to direction indicator.
0339      */
0340     direction_indicator* D()
0341     {
0342     assert(false);
0343     return 0;
0344     }
0345 
0346     /**
0347      * @internal
0348      * Type-cast to PQ-leaf.
0349      */
0350     pq_leaf* L()
0351     {
0352     assert(false);
0353     return 0;
0354     }
0355 
0356     //
0357     // Additional
0358     //
0359 
0360     /**
0361      * @internal
0362      * Whenever a child is known to be full, it is moved from the list of 
0363      * sons to this list.
0364      */
0365     symlist<pq_node*> full_sons;
0366 
0367     /**
0368      * @internal
0369      * Whenever a child is known to be partial, it is moved from the list of
0370      * sons to this list.
0371      */
0372     symlist<pq_node*> partial_sons;
0373 
0374     /**
0375      * @internal
0376      * Number of children.
0377      */
0378     int child_count;
0379 
0380     /**
0381      * @internal
0382      * Number of partial children.
0383      */
0384     int partial_count;
0385 
0386     /**
0387      * @internal
0388      * Number of full children.
0389      */
0390     int full_count;
0391 
0392     //
0393     // Friends 
0394     //
0395 
0396     /**
0397      * @internal
0398      * Allow planarity private access.
0399      */
0400     friend class planarity;
0401 
0402     /**
0403      * @internal
0404      * Allow pq_tree private access.
0405      */
0406     friend class pq_tree;
0407 
0408     /**
0409      * @internal
0410      * Allow operator<< private access.
0411      */
0412     GTL_EXTERN friend ostream& operator<<(ostream&, const pq_tree&);
0413 };
0414 
0415 
0416 /**
0417  * @internal
0418  */
0419 class GTL_EXTERN q_node : public pq_node 
0420 {
0421 private:
0422     /**
0423      * @internal
0424      */
0425     q_node (node, int);
0426 
0427     //
0428     // pq_node interface
0429     // 
0430 
0431     /**
0432      * @internal
0433      */
0434     void partial(iterator);
0435 
0436     /**
0437      * @internal
0438      */
0439     void full(iterator);
0440 
0441     /**
0442      * @internal
0443      * Determines kind of this %node.
0444      */
0445     PQ_KIND kind() const
0446     {
0447     return Q_NODE;
0448     }
0449 
0450     /**
0451      * @internal
0452      * Print this %node in gml format.
0453      */
0454     void write(ostream&, int);
0455 
0456     /**
0457      * @internal
0458      */
0459     void clear();
0460 
0461     // type-casts
0462 
0463     /**
0464      * @internal
0465      * Type-cast to P-node.
0466      */
0467     p_node* P()
0468     {
0469     assert (false);
0470     return 0;
0471     }
0472 
0473     /**
0474      * @internal
0475      * Type-cast to Q-node.
0476      */
0477     q_node* Q()
0478     {
0479     return this;
0480     }
0481 
0482     /**
0483      * @internal
0484      * Type-cast to direction indicator.
0485      */
0486     direction_indicator* D()
0487     {
0488     assert (false);
0489     return 0;
0490     }
0491 
0492     /**
0493      * @internal
0494      * Type-cast to PQ-leaf.
0495      */
0496     pq_leaf* L()
0497     {
0498     assert (false);
0499     return 0;
0500     }
0501 
0502     //
0503     // Additional
0504     //
0505 
0506     /**
0507      * @internal
0508      * Determines pert_begin and pert_end the first time a full or partial 
0509      * child is found.
0510      */
0511     void pertinent(iterator);
0512     
0513     /**
0514      * @internal
0515      * In #Q2 and #Q3 matchings the sons of partial children have to be
0516      * merged into the list of sons of this node at the partial node's
0517      * position
0518      */
0519     q_node* merge (iterator);
0520     
0521     /**
0522      * @internal
0523      * @em Depreacted.
0524      */
0525     void turn (); 
0526 
0527     /**
0528      * @internal
0529      * First son full or partial viewed from the beginning of the list of
0530      * pq_node::sons.
0531      */
0532     iterator pert_begin;    
0533 
0534     /**
0535      * @internal
0536      * Last son full or partial; usually this is the last son.
0537      */
0538     iterator pert_end;
0539 
0540     /**
0541      * @internal
0542      * Positions of the partial nodes among the sons. Normally only two
0543      * partial sons are allowed, but the third one is needed in planarity
0544      * testing.
0545      */
0546     iterator partial_pos[3];
0547 
0548     /**
0549      * @internal
0550      * True when all the pertinent children are consecutive; íf false
0551      * @a pert_begin lies in one block of pertinent children and @a pert_end
0552      * in another, such that <tt>--pert_end</tt> is empty and between the
0553      * two blocks.
0554      */
0555     bool pert_cons;
0556 
0557     /**
0558      * @internal
0559      * Number of partial children.
0560      */
0561     int partial_count;
0562 
0563     /**
0564      * @internal
0565      * Number of full children.
0566      */
0567     int full_count;
0568     
0569     //
0570     // Friends 
0571     //
0572 
0573     /**
0574      * @internal
0575      * Allow planarity private access.
0576      */
0577     friend class planarity;
0578 
0579     /**
0580      * @internal
0581      * Allow pq_tree private access.
0582      */
0583     friend class pq_tree;
0584 };
0585 
0586 
0587 /**
0588  * @internal
0589  */
0590 class GTL_EXTERN pq_leaf : public pq_node 
0591 {
0592 public:
0593     /**
0594      * @internal
0595      */
0596     pq_leaf (int, int, edge, node);
0597 private:
0598     /**
0599      * @internal
0600      * Determines kind of this %node.
0601      */
0602     PQ_KIND kind() const
0603     {
0604     return LEAF;
0605     }
0606 
0607     /**
0608      * @internal
0609      * Print this %node in gml format.
0610      */
0611     void write (ostream&, int);
0612 
0613     // type-casts
0614 
0615     /**
0616      * @internal
0617      * Type-cast to P-node.
0618      */
0619     p_node* P()
0620     {
0621     assert(false);
0622     return 0;
0623     }
0624 
0625     /**
0626      * @internal
0627      * Type-cast to Q-node.
0628      */
0629     q_node* Q()
0630     {
0631     assert(false);
0632     return 0;
0633     }
0634 
0635     /**
0636      * @internal
0637      * Type-cast to direction indicator.
0638      */
0639     direction_indicator* D()
0640     {
0641     assert(false);
0642     return 0;
0643     }
0644 
0645     /**
0646      * @internal
0647      * Type-cast to PQ-leaf.
0648      */
0649     pq_leaf* L()
0650     {
0651     return this;
0652     }
0653     
0654     //
0655     // Additional
0656     //
0657 
0658     /**
0659      * @internal
0660      */
0661     int other_id;
0662 
0663     /**
0664      * @internal
0665      */
0666     edge e;
0667 
0668     //
0669     // Friends 
0670     //
0671 
0672     /**
0673      * @internal
0674      * Allow planarity private access.
0675      */
0676     friend class planarity;
0677 
0678     /**
0679      * @internal
0680      * Allow pq_tree private access.
0681      */
0682     friend class pq_tree;
0683 };
0684 
0685 
0686 /**
0687  * @internal
0688  */
0689 class GTL_EXTERN direction_indicator : public pq_node 
0690 {
0691 private:
0692     /**
0693      * @internal
0694      */
0695     direction_indicator (node n_, int id_) : pq_node (n_, id_) { };
0696 
0697     //
0698     // pq_node interface
0699     // 
0700     
0701     /**
0702      * @internal
0703      * Determines kind of this %node.
0704      */
0705     PQ_KIND kind() const
0706     {
0707     return DIR;
0708     }
0709 
0710     /**
0711      * @internal
0712      * Print this %node in gml format.
0713      */
0714     void write (ostream& os, int);
0715 
0716     // type-casts 
0717 
0718     /**
0719      * @internal
0720      * Type-cast to P-node.
0721      */
0722     p_node* P()
0723     {
0724     assert(false);
0725     return 0;
0726     }
0727 
0728     /**
0729      * @internal
0730      * Type-cast to Q-node.
0731      */
0732     q_node* Q()
0733     {
0734     assert(false);
0735     return 0;
0736     }
0737 
0738     /**
0739      * @internal
0740      * Type-cast to direction indicator.
0741      */
0742     direction_indicator* D()
0743     {
0744     return this;
0745     }
0746 
0747     /**
0748      * @internal
0749      * Type-cast to PQ-leaf.
0750      */
0751     pq_leaf* L()
0752     {
0753     assert(false);
0754     return 0;
0755     }
0756     
0757     //
0758     // Additional
0759     //
0760 
0761     /**
0762      * @internal
0763      */
0764     bool direction; 
0765 
0766     //
0767     // Friends 
0768     //
0769 
0770     /**
0771      * @internal
0772      * Allow planarity private access.
0773      */
0774     friend class planarity;
0775 
0776     /**
0777      * @internal
0778      * Allow pq_tree private access.
0779      */
0780     friend class pq_tree;
0781 };
0782 
0783 __GTL_END_NAMESPACE
0784 
0785 #endif
0786 
0787 //--------------------------------------------------------------------------
0788 //   end of file
0789 //--------------------------------------------------------------------------