14
14
15
15
//! Iterators over DAGs
16
16
17
- use crate :: core:: Term ;
18
- use crate :: jet:: Application ;
19
17
use std:: collections:: HashSet ;
20
18
use std:: hash:: Hash ;
21
19
22
20
/// Structure that can be iterated like a DAG _(directed acyclic graph)_.
23
- pub trait DagIterable : Sized {
24
- /// Node in the DAG
25
- type Node : Copy + Eq + Hash ;
26
-
21
+ pub trait DagIterable : Copy + Eq + Hash {
27
22
/// Return the DAG root, if the DAG is nonempty.
28
- fn root ( & self ) -> Option < Self :: Node > ;
23
+ fn root ( self ) -> Option < Self > ;
29
24
30
25
/// Return the left child of the given `node`.
31
- fn left_of ( & self , node : Self :: Node ) -> Option < Self :: Node > ;
26
+ fn get_left ( self ) -> Option < Self > ;
32
27
33
28
/// Return the right child of the given `node`.
34
- fn right_of ( & self , node : Self :: Node ) -> Option < Self :: Node > ;
29
+ fn get_right ( self ) -> Option < Self > ;
35
30
36
31
/// Return a post-order iterator over the DAG.
37
32
fn iter_post_order ( & self ) -> PostOrderIter < Self > {
@@ -43,34 +38,32 @@ pub trait DagIterable: Sized {
43
38
/// That means, left children appear before right ones, and children appear before their parent.
44
39
/// Shared nodes appear only once at their leftmost position.
45
40
#[ derive( Clone , Debug ) ]
46
- pub struct PostOrderIter < ' a , D : DagIterable > {
47
- dag : & ' a D ,
48
- stack : Vec < D :: Node > ,
49
- maybe_current : Option < D :: Node > ,
50
- visited : HashSet < D :: Node > ,
41
+ pub struct PostOrderIter < D : DagIterable > {
42
+ stack : Vec < D > ,
43
+ maybe_current : Option < D > ,
44
+ visited : HashSet < D > ,
51
45
}
52
46
53
- impl < ' a , D : DagIterable > PostOrderIter < ' a , D > {
47
+ impl < D : DagIterable > PostOrderIter < D > {
54
48
/// Create a new iterator from the given `dag`.
55
- pub fn new ( dag : & ' a D ) -> Self {
49
+ pub fn new ( dag : & D ) -> Self {
56
50
PostOrderIter {
57
- dag,
58
51
stack : Vec :: new ( ) ,
59
52
maybe_current : dag. root ( ) ,
60
53
visited : HashSet :: new ( ) ,
61
54
}
62
55
}
63
56
}
64
57
65
- impl < ' a , D : DagIterable > Iterator for PostOrderIter < ' a , D > {
66
- type Item = D :: Node ;
58
+ impl < D : DagIterable > Iterator for PostOrderIter < D > {
59
+ type Item = D ;
67
60
68
61
fn next ( & mut self ) -> Option < Self :: Item > {
69
62
loop {
70
63
if let Some ( current) = self . maybe_current {
71
64
self . stack . push ( current) ;
72
65
73
- if let Some ( left) = self . dag . left_of ( current ) {
66
+ if let Some ( left) = current . get_left ( ) {
74
67
if !self . visited . contains ( & left) {
75
68
self . maybe_current = Some ( left) ;
76
69
continue ;
@@ -79,7 +72,7 @@ impl<'a, D: DagIterable> Iterator for PostOrderIter<'a, D> {
79
72
// else
80
73
self . maybe_current = None ;
81
74
} else if let Some ( top) = self . stack . last ( ) {
82
- if let Some ( right) = self . dag . right_of ( * top ) {
75
+ if let Some ( right) = top . get_right ( ) {
83
76
if !self . visited . contains ( & right) {
84
77
self . maybe_current = Some ( right) ;
85
78
continue ;
@@ -97,6 +90,55 @@ impl<'a, D: DagIterable> Iterator for PostOrderIter<'a, D> {
97
90
}
98
91
}
99
92
93
+ /// Convenience macro for wrappers of references to structures over
94
+ /// `<Witness, App: Application>`.
95
+ ///
96
+ /// Implements `Clone`, `Copy`, `Eq` and `Hash` using pointers.
97
+ /// Implements [`DagIterable`] using `self.0.get_left()` and `self.0.get_right()`.
98
+ #[ macro_export]
99
+ macro_rules! impl_ref_wrapper {
100
+ ( $wrapper: ident) => {
101
+ impl <' a, Witness , App : Application > Clone for $wrapper<' a, Witness , App > {
102
+ fn clone( & self ) -> Self {
103
+ $wrapper( & ( self . 0 ) . clone( ) )
104
+ }
105
+ }
106
+
107
+ impl <' a, Witness , App : Application > Copy for $wrapper<' a, Witness , App > { }
108
+
109
+ impl <' a, Witness , App : Application > PartialEq for $wrapper<' a, Witness , App > {
110
+ fn eq( & self , other: & Self ) -> bool {
111
+ std:: ptr:: eq( self . 0 , other. 0 )
112
+ }
113
+ }
114
+
115
+ impl <' a, Witness , App : Application > Eq for $wrapper<' a, Witness , App > { }
116
+
117
+ impl <' a, Witness , App : Application > std:: hash:: Hash for $wrapper<' a, Witness , App > {
118
+ fn hash<H : std:: hash:: Hasher >( & self , state: & mut H ) {
119
+ std:: ptr:: hash( self . 0 , state)
120
+ }
121
+ }
122
+
123
+ impl <' a, Witness , App : Application > $crate:: core:: iter:: DagIterable
124
+ for $wrapper<' a, Witness , App >
125
+ {
126
+ fn root( self ) -> Option <Self > {
127
+ Some ( self )
128
+ }
129
+
130
+ fn get_left( self ) -> Option <Self > {
131
+ self . 0 . get_left( ) . map( |x| RefWrapper ( x) )
132
+ }
133
+
134
+ fn get_right( self ) -> Option <Self > {
135
+ self . 0 . get_right( ) . map( |x| RefWrapper ( x) )
136
+ }
137
+ }
138
+ } ;
139
+ }
140
+
141
+ /*
100
142
/// Convert the given iterator over [`Term`]s into an iterator over the contained `Witness` values.
101
143
pub fn into_witness<'a, Witness, App: Application, I>(
102
144
iter: I,
@@ -113,3 +155,4 @@ where
113
155
}
114
156
})
115
157
}
158
+ */
0 commit comments