LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/expr - node_traversal.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 5 5 100.0 %
Date: 2024-10-17 11:38:51 Functions: 5 5 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Alex Ozdemir, Andres Noetzli, Aina Niemetz
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2024 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * Iterators for traversing nodes.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "cvc5_private.h"
      17                 :            : 
      18                 :            : #ifndef CVC5__EXPR__NODE_TRAVERSAL_H
      19                 :            : #define CVC5__EXPR__NODE_TRAVERSAL_H
      20                 :            : 
      21                 :            : #include <iterator>
      22                 :            : #include <unordered_map>
      23                 :            : #include <vector>
      24                 :            : 
      25                 :            : #include "expr/node.h"
      26                 :            : 
      27                 :            : namespace cvc5::internal {
      28                 :            : 
      29                 :            : /**
      30                 :            :  * Enum that represents an order in which nodes are visited.
      31                 :            :  */
      32                 :            : enum class VisitOrder
      33                 :            : {
      34                 :            :   PREORDER,
      35                 :            :   POSTORDER
      36                 :            : };
      37                 :            : 
      38                 :            : // Iterator for traversing a node in pre-/post-order
      39                 :            : // It does DAG-traversal, so indentical sub-nodes will be visited once only.
      40                 :            : class NodeDfsIterator
      41                 :            : {
      42                 :            :  public:
      43                 :            :   // STL type definitions for an iterator
      44                 :            :   using value_type = TNode;
      45                 :            :   using pointer = TNode*;
      46                 :            :   using reference = TNode&;
      47                 :            :   using iterator_category = std::forward_iterator_tag;
      48                 :            :   using difference_type = std::ptrdiff_t;
      49                 :            : 
      50                 :            :   // Construct a traversal iterator beginning at `n`
      51                 :            :   NodeDfsIterator(TNode n, VisitOrder order, std::function<bool(TNode)> skipIf);
      52                 :            :   // Construct an end-of-traversal iterator
      53                 :            :   NodeDfsIterator(VisitOrder order);
      54                 :            : 
      55                 :            :   // Move/copy construction and assignment. Destructor.
      56                 :         20 :   NodeDfsIterator(NodeDfsIterator&&) = default;
      57                 :            :   NodeDfsIterator& operator=(NodeDfsIterator&&) = default;
      58                 :         48 :   NodeDfsIterator(const NodeDfsIterator&) = default;
      59                 :            :   NodeDfsIterator& operator=(const NodeDfsIterator&) = default;
      60                 :     386450 :   ~NodeDfsIterator() = default;
      61                 :            : 
      62                 :            :   // Preincrement
      63                 :            :   NodeDfsIterator& operator++();
      64                 :            :   // Postincrement
      65                 :            :   NodeDfsIterator operator++(int);
      66                 :            :   // Dereference
      67                 :            :   reference operator*();
      68                 :            :   // Equals
      69                 :            :   // It is not constant, because an unitilized node must be initialized before
      70                 :            :   // comparison
      71                 :            :   bool operator==(NodeDfsIterator&);
      72                 :            :   // Not equals
      73                 :            :   // It is not constant, because an unitilized node must be initialized before
      74                 :            :   // comparison
      75                 :            :   bool operator!=(NodeDfsIterator&);
      76                 :            : 
      77                 :            :  private:
      78                 :            :   // While we're not at an appropriate visit (see d_postorder), advance.
      79                 :            :   // In each step:
      80                 :            :   //   * enqueue children of a not-yet-pre-visited node (and mark it
      81                 :            :   //     previsited)
      82                 :            :   //   * pop a not-yet-post-visited node (and mark it post-visited)
      83                 :            :   //   * pop an already post-visited node.
      84                 :            :   // After calling this, `d_current` will be changed to the next node, if there
      85                 :            :   // is another node in the traversal.
      86                 :            :   void advanceToNextVisit();
      87                 :            : 
      88                 :            :   // If this iterator hasn't been dereferenced or incremented yet, advance to
      89                 :            :   // first visit.
      90                 :            :   // Necessary because we are lazy and don't find our first visit node at
      91                 :            :   // construction time.
      92                 :            :   void initializeIfUninitialized();
      93                 :            : 
      94                 :            :   // Stack of nodes to visit.
      95                 :            :   std::vector<TNode> d_stack;
      96                 :            : 
      97                 :            :   // Whether (and how) we've visited a node.
      98                 :            :   // Absent if we haven't visited it.
      99                 :            :   // Set to `false` if we've already pre-visited it (enqueued its children).
     100                 :            :   // Set to `true` if we've also already post-visited it.
     101                 :            :   std::unordered_map<TNode, bool> d_visited;
     102                 :            : 
     103                 :            :   // The visit order that this iterator is using
     104                 :            :   VisitOrder d_order;
     105                 :            : 
     106                 :            :   // Current referent node. A valid node to visit if non-null.
     107                 :            :   // Null after construction (but before first access) and at the end.
     108                 :            :   TNode d_current;
     109                 :            : 
     110                 :            :   // When to omit a node and its descendants from the traversal
     111                 :            :   std::function<bool(TNode)> d_skipIf;
     112                 :            : };
     113                 :            : 
     114                 :            : // Node wrapper that is iterable in DAG pre-/post-order
     115                 :            : class NodeDfsIterable
     116                 :            : {
     117                 :            :  public:
     118                 :            :   /**
     119                 :            :    * Creates a new node wrapper that can be used to iterate over the children
     120                 :            :    * of a node in pre-/post-order.
     121                 :            :    *
     122                 :            :    * @param n The node the iterate
     123                 :            :    * @param order The order in which the children are visited.
     124                 :            :    * @param skipIf Function that determines whether a given node and its
     125                 :            :    *               descendants should be skipped or not.
     126                 :            :    */
     127                 :            :   NodeDfsIterable(
     128                 :            :       TNode n,
     129                 :            :       VisitOrder order = VisitOrder::POSTORDER,
     130                 :         45 :       std::function<bool(TNode)> skipIf = [](TNode) { return false; });
     131                 :            : 
     132                 :            :   // Move/copy construction and assignment. Destructor.
     133                 :            :   NodeDfsIterable(NodeDfsIterable&&) = default;
     134                 :            :   NodeDfsIterable& operator=(NodeDfsIterable&&) = default;
     135                 :            :   NodeDfsIterable(const NodeDfsIterable&) = default;
     136                 :            :   NodeDfsIterable& operator=(const NodeDfsIterable&) = default;
     137                 :     193191 :   ~NodeDfsIterable() = default;
     138                 :            : 
     139                 :            :   NodeDfsIterator begin() const;
     140                 :            :   NodeDfsIterator end() const;
     141                 :            : 
     142                 :            :  private:
     143                 :            :   TNode d_node;
     144                 :            :   VisitOrder d_order;
     145                 :            :   std::function<bool(TNode)> d_skipIf;
     146                 :            : };
     147                 :            : 
     148                 :            : }  // namespace cvc5::internal
     149                 :            : 
     150                 :            : #endif  // CVC5__EXPR__NODE_TRAVERSAL_H

Generated by: LCOV version 1.14