@@ -9,27 +9,28 @@ use crate::{
9
9
cast:: { Downcast , DowncastFrom , DowncastTo , To , Upcast , UpcastFrom } ,
10
10
fold:: Fold ,
11
11
fold:: SubstitutionFn ,
12
- grammar:: VarIndex ,
12
+ language:: { HasKind , Kind , Language , Parameter } ,
13
+ substitution:: Substitution ,
14
+ variable:: { BoundVar , DebruijnIndex , VarIndex , Variable } ,
13
15
visit:: Visit ,
16
+ Fallible ,
14
17
} ;
15
18
16
- use super :: { BoundVar , DebruijnIndex , Fallible , Parameter , ParameterKind , Substitution , Variable } ;
17
-
18
19
#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Default ) ]
19
- pub struct Binder < T > {
20
- kinds : Vec < ParameterKind > ,
20
+ pub struct Binder < L : Language , T > {
21
+ kinds : Vec < Kind < L > > ,
21
22
term : T ,
22
23
}
23
24
24
- impl < T : Fold > Binder < T > {
25
+ impl < L : Language , T : Fold < L > > Binder < L , T > {
25
26
/// Accesses the contents of the binder.
26
27
///
27
28
/// The variables inside will be renamed to fresh var indices
28
29
/// that do not alias any other indices seen during this computation.
29
30
///
30
31
/// The expectation is that you will create a term and use `Binder::new`.
31
- pub fn open ( & self ) -> ( Vec < BoundVar > , T ) {
32
- let ( bound_vars, substitution) : ( Vec < BoundVar > , Substitution ) = self
32
+ pub fn open ( & self ) -> ( Vec < BoundVar < L > > , T ) {
33
+ let ( bound_vars, substitution) : ( Vec < BoundVar < L > > , Substitution < L > ) = self
33
34
. kinds
34
35
. iter ( )
35
36
. zip ( 0 ..)
@@ -48,21 +49,21 @@ impl<T: Fold> Binder<T> {
48
49
}
49
50
50
51
pub fn dummy ( term : T ) -> Self {
51
- let v: Vec < Variable > = vec ! [ ] ;
52
+ let v: Vec < Variable < L > > = vec ! [ ] ;
52
53
Self :: new ( v, term)
53
54
}
54
55
55
56
/// Given a set of variables (X, Y, Z) and a term referecing some subset of them,
56
57
/// create a binder where exactly those variables are bound (even the ones not used).
57
- pub fn new ( variables : impl Upcast < Vec < Variable > > , term : T ) -> Self {
58
- let variables: Vec < Variable > = variables. upcast ( ) ;
59
- let ( kinds, substitution) : ( Vec < ParameterKind > , Substitution ) = variables
58
+ pub fn new ( variables : impl Upcast < Vec < Variable < L > > > , term : T ) -> Self {
59
+ let variables: Vec < Variable < L > > = variables. upcast ( ) ;
60
+ let ( kinds, substitution) : ( Vec < Kind < L > > , Substitution < L > ) = variables
60
61
. iter ( )
61
62
. zip ( 0 ..)
62
63
. map ( |( old_bound_var, index) | {
63
- let old_bound_var: Variable = old_bound_var. upcast ( ) ;
64
+ let old_bound_var: Variable < L > = old_bound_var. upcast ( ) ;
64
65
assert ! ( old_bound_var. is_free( ) ) ;
65
- let new_bound_var: Parameter = BoundVar {
66
+ let new_bound_var: Parameter < L > = BoundVar {
66
67
debruijn : Some ( DebruijnIndex :: INNERMOST ) ,
67
68
var_index : VarIndex { index } ,
68
69
kind : old_bound_var. kind ( ) ,
@@ -78,15 +79,15 @@ impl<T: Fold> Binder<T> {
78
79
79
80
/// Given a set of variables (X, Y, Z) and a term referecing some subset of them,
80
81
/// create a binder for just those variables that are mentioned.
81
- pub fn mentioned ( variables : impl Upcast < Vec < Variable > > , term : T ) -> Self {
82
- let mut variables: Vec < Variable > = variables. upcast ( ) ;
82
+ pub fn mentioned ( variables : impl Upcast < Vec < Variable < L > > > , term : T ) -> Self {
83
+ let mut variables: Vec < Variable < L > > = variables. upcast ( ) ;
83
84
let fv = term. free_variables ( ) ;
84
85
variables. retain ( |v| fv. contains ( v) ) ;
85
- let variables: Vec < Variable > = variables. into_iter ( ) . collect ( ) ;
86
+ let variables: Vec < Variable < L > > = variables. into_iter ( ) . collect ( ) ;
86
87
Binder :: new ( variables, term)
87
88
}
88
89
89
- pub fn into < U > ( self ) -> Binder < U >
90
+ pub fn into < U > ( self ) -> Binder < L , U >
90
91
where
91
92
T : Into < U > ,
92
93
{
@@ -107,13 +108,13 @@ impl<T: Fold> Binder<T> {
107
108
108
109
/// Instantiate the binder with the given parameters, returning an err if the parameters
109
110
/// are the wrong number or ill-kinded.
110
- pub fn instantiate_with ( & self , parameters : & [ impl Upcast < Parameter > ] ) -> Fallible < T > {
111
+ pub fn instantiate_with ( & self , parameters : & [ impl Upcast < Parameter < L > > ] ) -> Fallible < T > {
111
112
if parameters. len ( ) != self . kinds . len ( ) {
112
113
bail ! ( "wrong number of parameters" ) ;
113
114
}
114
115
115
116
for ( ( p, k) , i) in parameters. iter ( ) . zip ( & self . kinds ) . zip ( 0 ..) {
116
- let p: Parameter = p. upcast ( ) ;
117
+ let p: Parameter < L > = p. upcast ( ) ;
117
118
if p. kind ( ) != * k {
118
119
bail ! (
119
120
"parameter {i} has kind {:?} but should have kind {:?}" ,
@@ -127,8 +128,8 @@ impl<T: Fold> Binder<T> {
127
128
}
128
129
129
130
/// Instantiate the term, replacing each bound variable with `op(i)`.
130
- pub fn instantiate ( & self , mut op : impl FnMut ( ParameterKind , VarIndex ) -> Parameter ) -> T {
131
- let substitution: Vec < Parameter > = self
131
+ pub fn instantiate ( & self , mut op : impl FnMut ( Kind < L > , VarIndex ) -> Parameter < L > ) -> T {
132
+ let substitution: Vec < Parameter < L > > = self
132
133
. kinds
133
134
. iter ( )
134
135
. zip ( 0 ..)
@@ -153,11 +154,11 @@ impl<T: Fold> Binder<T> {
153
154
}
154
155
155
156
/// Returns the kinds of each variable bound by this binder
156
- pub fn kinds ( & self ) -> & [ ParameterKind ] {
157
+ pub fn kinds ( & self ) -> & [ Kind < L > ] {
157
158
& self . kinds
158
159
}
159
160
160
- pub fn map < U : Fold > ( & self , op : impl FnOnce ( T ) -> U ) -> Binder < U > {
161
+ pub fn map < U : Fold < L > > ( & self , op : impl FnOnce ( T ) -> U ) -> Binder < L , U > {
161
162
let ( vars, t) = self . open ( ) ;
162
163
let u = op ( t) ;
163
164
Binder :: new ( vars, u)
@@ -166,7 +167,7 @@ impl<T: Fold> Binder<T> {
166
167
167
168
/// Creates a fresh bound var of the given kind that is not yet part of a binder.
168
169
/// You can put this into a term and then use `Binder::new`.
169
- pub fn fresh_bound_var ( kind : ParameterKind ) -> BoundVar {
170
+ pub fn fresh_bound_var < L : Language > ( kind : Kind < L > ) -> BoundVar < L > {
170
171
lazy_static ! {
171
172
static ref COUNTER : AtomicUsize = AtomicUsize :: new( 0 ) ;
172
173
}
@@ -180,8 +181,8 @@ pub fn fresh_bound_var(kind: ParameterKind) -> BoundVar {
180
181
}
181
182
}
182
183
183
- impl < T : Visit > Visit for Binder < T > {
184
- fn free_variables ( & self ) -> Vec < Variable > {
184
+ impl < L : Language , T : Visit < L > > Visit < L > for Binder < L , T > {
185
+ fn free_variables ( & self ) -> Vec < Variable < L > > {
185
186
self . term . free_variables ( )
186
187
}
187
188
@@ -194,8 +195,8 @@ impl<T: Visit> Visit for Binder<T> {
194
195
}
195
196
}
196
197
197
- impl < T : Fold > Fold for Binder < T > {
198
- fn substitute ( & self , substitution_fn : SubstitutionFn < ' _ > ) -> Self {
198
+ impl < L : Language , T : Fold < L > > Fold < L > for Binder < L , T > {
199
+ fn substitute ( & self , substitution_fn : SubstitutionFn < ' _ , L > ) -> Self {
199
200
let term = self . term . substitute ( & mut |v| {
200
201
// Shift this variable out through the binder. If that fails,
201
202
// it's a variable bound by this binder, so the substitution can't
@@ -224,13 +225,13 @@ impl<T: Fold> Fold for Binder<T> {
224
225
}
225
226
}
226
227
227
- impl < T , U > UpcastFrom < Binder < T > > for Binder < U >
228
+ impl < L : Language , T , U > UpcastFrom < Binder < L , T > > for Binder < L , U >
228
229
where
229
230
T : Clone ,
230
231
U : Clone ,
231
232
T : Upcast < U > ,
232
233
{
233
- fn upcast_from ( term : Binder < T > ) -> Self {
234
+ fn upcast_from ( term : Binder < L , T > ) -> Self {
234
235
let Binder { kinds, term } = term;
235
236
Binder {
236
237
kinds,
@@ -239,11 +240,11 @@ where
239
240
}
240
241
}
241
242
242
- impl < T , U > DowncastTo < Binder < T > > for Binder < U >
243
+ impl < L : Language , T , U > DowncastTo < Binder < L , T > > for Binder < L , U >
243
244
where
244
245
T : DowncastFrom < U > ,
245
246
{
246
- fn downcast_to ( & self ) -> Option < Binder < T > > {
247
+ fn downcast_to ( & self ) -> Option < Binder < L , T > > {
247
248
let Binder { kinds, term } = self ;
248
249
let term = term. downcast ( ) ?;
249
250
Some ( Binder {
@@ -253,7 +254,7 @@ where
253
254
}
254
255
}
255
256
256
- impl < T > std:: fmt:: Debug for Binder < T >
257
+ impl < L : Language , T > std:: fmt:: Debug for Binder < L , T >
257
258
where
258
259
T : std:: fmt:: Debug ,
259
260
{
0 commit comments