@@ -2,67 +2,63 @@ use crate::merkle::common::{MerkleRoot, TypeMerkleRoot};
2
2
use crate :: merkle:: tmr:: Tmr ;
3
3
use std:: { cell:: RefCell , cmp, fmt, rc:: Rc , sync:: Arc } ;
4
4
5
- #[ derive( Clone , Debug ) ]
6
- pub ( crate ) enum Type {
7
- Unit ,
8
- Sum ( RcVar , RcVar ) ,
9
- Product ( RcVar , RcVar ) ,
10
- }
11
-
12
- impl Type {
13
- pub ( crate ) fn into_rcvar ( self ) -> RcVar {
14
- Rc :: new ( RefCell :: new ( UnificationVar :: concrete ( self ) ) )
15
- }
16
- }
17
-
18
- #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
19
- pub enum FinalTypeInner {
20
- Unit ,
21
- Sum ( Arc < FinalType > , Arc < FinalType > ) ,
22
- Product ( Arc < FinalType > , Arc < FinalType > ) ,
23
- }
24
-
5
+ /// Finalized Simplicity type.
6
+ ///
7
+ /// _Unit_ is the base type and is for _unit_ values.
8
+ ///
9
+ /// The _sum_ of types A and B is for values
10
+ /// that are the _left sum_ of a value of type A or the _right sum_ of a value of type B.
11
+ ///
12
+ /// The _product_ of types A and B is for values
13
+ /// that are the _product_ of a value of type A and a value of type B.
14
+ ///
15
+ /// _(see [`crate::core::Value`])_
25
16
#[ derive( Clone , PartialOrd , Ord , Debug ) ]
26
- pub struct FinalType {
27
- pub ty : FinalTypeInner ,
17
+ pub struct Type {
18
+ /// Underlying type with references to sub-types
19
+ pub ty : TypeInner ,
20
+ /// Bit width of the type
28
21
pub bit_width : usize ,
29
- /// The annotated type merkle root of the type
22
+ /// Annotated Type Merkle root of the type
30
23
pub tmr : Tmr ,
31
- /// cached display result in order to avoid repeat computation
24
+ /// Cached display result in order to avoid repeat computation
32
25
pub display : String ,
33
26
}
34
27
35
- impl FinalType {
36
- pub fn unit ( ) -> Self {
37
- let ty = FinalTypeInner :: Unit ;
28
+ impl Type {
29
+ /// Return a unit type.
30
+ pub fn unit ( ) -> Arc < Self > {
31
+ let ty = TypeInner :: Unit ;
38
32
39
- Self {
33
+ Arc :: new ( Self {
40
34
tmr : Tmr :: get_iv ( & ty) ,
41
35
ty,
42
36
bit_width : 0 ,
43
37
display : "1" . to_owned ( ) ,
44
- }
38
+ } )
45
39
}
46
40
47
- pub fn sum ( a : Arc < Self > , b : Arc < Self > ) -> Self {
48
- let ty = FinalTypeInner :: Sum ( a. clone ( ) , b. clone ( ) ) ;
41
+ /// Return the sum of the given two types.
42
+ pub fn sum ( a : Arc < Self > , b : Arc < Self > ) -> Arc < Self > {
43
+ let ty = TypeInner :: Sum ( a. clone ( ) , b. clone ( ) ) ;
49
44
50
- Self {
45
+ Arc :: new ( Self {
51
46
tmr : Tmr :: get_iv ( & ty) . update ( a. tmr , b. tmr ) ,
52
47
ty,
53
48
bit_width : 1 + cmp:: max ( a. bit_width , b. bit_width ) ,
54
- display : if a. ty == FinalTypeInner :: Unit && b. ty == FinalTypeInner :: Unit {
49
+ display : if a. ty == TypeInner :: Unit && b. ty == TypeInner :: Unit {
55
50
"2" . to_owned ( )
56
51
} else {
57
52
format ! ( "({} + {})" , a. display, b. display)
58
53
} ,
59
- }
54
+ } )
60
55
}
61
56
62
- pub fn prod ( a : Arc < Self > , b : Arc < Self > ) -> Self {
63
- let ty = FinalTypeInner :: Product ( a. clone ( ) , b. clone ( ) ) ;
57
+ /// Return the product of the given two types.
58
+ pub fn product ( a : Arc < Self > , b : Arc < Self > ) -> Arc < Self > {
59
+ let ty = TypeInner :: Product ( a. clone ( ) , b. clone ( ) ) ;
64
60
65
- Self {
61
+ Arc :: new ( Self {
66
62
tmr : Tmr :: get_iv ( & ty) . update ( a. tmr , b. tmr ) ,
67
63
ty,
68
64
bit_width : a. bit_width + b. bit_width ,
@@ -81,81 +77,131 @@ impl FinalType {
81
77
} else {
82
78
format ! ( "({} × {})" , a. display, b. display)
83
79
} ,
84
- }
80
+ } )
85
81
}
86
82
}
87
83
88
- impl fmt:: Display for FinalType {
84
+ impl fmt:: Display for Type {
89
85
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
90
- write ! ( f , "{}" , self . display)
86
+ f . write_str ( & self . display )
91
87
}
92
88
}
93
89
94
- impl PartialEq for FinalType {
90
+ impl PartialEq for Type {
95
91
fn eq ( & self , other : & Self ) -> bool {
96
92
self . tmr . eq ( & other. tmr )
97
93
}
98
94
}
99
95
100
- impl Eq for FinalType { }
96
+ impl Eq for Type { }
101
97
102
- impl std:: hash:: Hash for FinalType {
98
+ impl std:: hash:: Hash for Type {
103
99
fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
104
100
self . tmr . hash ( state)
105
101
}
106
102
}
107
103
108
- #[ derive( Clone ) ]
109
- pub ( crate ) enum Variable {
110
- /// Free variable
111
- Free ,
112
- /// Bound to some type (which may itself contain other free variables,
113
- /// or not). Contains a boolean which is only used by the finalization
114
- /// function, for the occurs-check
115
- Bound ( Type , bool ) ,
116
- /// Equal to another variable (the included `RcVar` is the "parent"
117
- /// pointer in union-find terms)
118
- EqualTo ( RcVar ) ,
119
- /// Complete type has been set in place
120
- Finalized ( Arc < FinalType > ) ,
104
+ /// Finalized Simplicity type without metadata (see [`Type`])
105
+ #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
106
+ pub enum TypeInner {
107
+ /// Unit type
108
+ Unit ,
109
+ /// Sum of two types
110
+ Sum ( Arc < Type > , Arc < Type > ) ,
111
+ /// Product of two types
112
+ Product ( Arc < Type > , Arc < Type > ) ,
121
113
}
122
114
123
- impl fmt:: Debug for Variable {
124
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
125
- match * self {
126
- Variable :: Free => f. write_str ( "?" ) ,
127
- Variable :: Bound ( ref ty, b) => write ! ( f, "[{:?}/{}]" , ty, b) ,
128
- Variable :: EqualTo ( ref other) => write ! ( f, "={:?}" , other) ,
129
- Variable :: Finalized ( ..) => unimplemented ! ( ) ,
130
- }
131
- }
115
+ /// Variable Simplicity type.
116
+ ///
117
+ /// In contrast to [`Type`],
118
+ /// a [`VariableType`] contains variables that can be internally mutated.
119
+ #[ derive( Clone , Debug ) ]
120
+ pub ( crate ) enum VariableType {
121
+ /// Unit type
122
+ Unit ,
123
+ /// Sum of two types
124
+ Sum ( RcVar , RcVar ) ,
125
+ /// Product of two types
126
+ Product ( RcVar , RcVar ) ,
132
127
}
133
128
134
- pub ( crate ) struct UnificationVar {
135
- pub var : Variable ,
129
+ /// Variable that can be cheaply cloned and internally mutated
130
+ pub ( crate ) type RcVar = Rc < RefCell < Variable > > ;
131
+
132
+ /// Unification variable
133
+ #[ derive( Clone ) ]
134
+ pub ( crate ) struct Variable {
135
+ /// Underlying variable
136
+ pub inner : VariableInner ,
137
+ /// Rank for union-first algorithm
136
138
pub rank : usize ,
137
139
}
138
140
139
- impl fmt:: Debug for UnificationVar {
140
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
141
- write ! ( f, "[{}]{:?}" , self . rank, self . var)
141
+ impl Variable {
142
+ /// Return a free variable.
143
+ pub fn free ( ) -> RcVar {
144
+ Rc :: new ( RefCell :: new ( Self {
145
+ inner : VariableInner :: Free ,
146
+ rank : 0 ,
147
+ } ) )
142
148
}
143
- }
144
149
145
- pub ( crate ) type RcVar = Rc < RefCell < UnificationVar > > ;
146
-
147
- impl UnificationVar {
148
- pub fn free ( ) -> UnificationVar {
149
- UnificationVar {
150
- var : Variable :: Free ,
150
+ /// Return a variable that is bound to the given type.
151
+ pub fn bound ( ty : VariableType ) -> RcVar {
152
+ Rc :: new ( RefCell :: new ( Self {
153
+ inner : VariableInner :: Bound ( ty, false ) ,
151
154
rank : 0 ,
152
- }
155
+ } ) )
153
156
}
154
157
155
- pub fn concrete ( ty : Type ) -> UnificationVar {
156
- UnificationVar {
157
- var : Variable :: Bound ( ty, false ) ,
158
- rank : 0 ,
158
+ /// Return an array `pow2s` of types such that `pow2s[i] = 2^i` holds for 0 ≤ `i` < 9.
159
+ pub fn powers_of_two ( ) -> [ RcVar ; 9 ] {
160
+ let two_0 = Variable :: bound ( VariableType :: Unit ) ;
161
+ let two_1 = Variable :: bound ( VariableType :: Sum ( two_0. clone ( ) , two_0) ) ;
162
+ let two_2 = Variable :: bound ( VariableType :: Product ( two_1. clone ( ) , two_1. clone ( ) ) ) ;
163
+ let two_4 = Variable :: bound ( VariableType :: Product ( two_2. clone ( ) , two_2. clone ( ) ) ) ;
164
+ let two_8 = Variable :: bound ( VariableType :: Product ( two_4. clone ( ) , two_4. clone ( ) ) ) ;
165
+ let two_16 = Variable :: bound ( VariableType :: Product ( two_8. clone ( ) , two_8. clone ( ) ) ) ;
166
+ let two_32 = Variable :: bound ( VariableType :: Product ( two_16. clone ( ) , two_16. clone ( ) ) ) ;
167
+ let two_64 = Variable :: bound ( VariableType :: Product ( two_32. clone ( ) , two_32. clone ( ) ) ) ;
168
+ let two_128 = Variable :: bound ( VariableType :: Product ( two_64. clone ( ) , two_64. clone ( ) ) ) ;
169
+ let two_256 = Variable :: bound ( VariableType :: Product ( two_128. clone ( ) , two_128. clone ( ) ) ) ;
170
+
171
+ [
172
+ two_1, two_2, two_4, two_8, two_16, two_32, two_64, two_128, two_256,
173
+ ]
174
+ }
175
+ }
176
+
177
+ impl fmt:: Debug for Variable {
178
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
179
+ write ! ( f, "[{}]{:?}" , self . rank, self . inner)
180
+ }
181
+ }
182
+
183
+ /// Unification variable without metadata (see [`Variable`])
184
+ #[ derive( Clone ) ]
185
+ pub ( crate ) enum VariableInner {
186
+ /// Free variable
187
+ Free ,
188
+ /// Variable bound to some variable type.
189
+ /// Contains a Boolean to check if this variable already occurred _(occurs check)_
190
+ Bound ( VariableType , bool ) ,
191
+ /// Variable equal to another variable.
192
+ /// In the union-find algorithm, this is the _parent_
193
+ EqualTo ( RcVar ) ,
194
+ /// Variable bound to some finalized type
195
+ Finalized ( Arc < Type > ) ,
196
+ }
197
+
198
+ impl fmt:: Debug for VariableInner {
199
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
200
+ match self {
201
+ VariableInner :: Free => f. write_str ( "?" ) ,
202
+ VariableInner :: Bound ( ty, b) => write ! ( f, "[{:?}/{}]" , ty, b) ,
203
+ VariableInner :: EqualTo ( parent) => write ! ( f, "={:?}" , parent) ,
204
+ VariableInner :: Finalized ( ty) => fmt:: Debug :: fmt ( ty, f) ,
159
205
}
160
206
}
161
207
}
0 commit comments