@@ -445,6 +445,32 @@ impl Term {
445
445
_ => false ,
446
446
}
447
447
}
448
+
449
+ /// Returns `true` if `self` has any free vairables.
450
+ ///
451
+ /// # Example
452
+ /// ```
453
+ /// use lambda_calculus::*;
454
+ ///
455
+ /// let with_freevar = abs(Var(2)); // λ 2
456
+ /// let without_freevar = abs(Var(1)); // λ 1
457
+ ///
458
+ /// assert!(with_freevar.has_free_variables());
459
+ /// assert!(!without_freevar.has_free_variables());
460
+ pub fn has_free_variables ( & self ) -> bool {
461
+ self . has_free_variables_helper ( 0 )
462
+ }
463
+
464
+ fn has_free_variables_helper ( & self , depth : usize ) -> bool {
465
+ match self {
466
+ Var ( x) => * x > depth || * x == 0 ,
467
+ Abs ( p) => p. has_free_variables_helper ( depth + 1 ) ,
468
+ App ( p_boxed) => {
469
+ let ( ref f, ref a) = * * p_boxed;
470
+ f. has_free_variables_helper ( depth) || a. has_free_variables_helper ( depth)
471
+ }
472
+ }
473
+ }
448
474
}
449
475
450
476
/// Wraps a `Term` in an `Abs`traction. Consumes its argument.
@@ -713,4 +739,20 @@ mod tests {
713
739
assert ! ( app( abs( Var ( 1 ) ) , Var ( 1 ) ) . is_isomorphic_to( & app( abs( Var ( 1 ) ) , Var ( 1 ) ) ) ) ;
714
740
assert ! ( !app( abs( Var ( 1 ) ) , Var ( 1 ) ) . is_isomorphic_to( & app( Var ( 2 ) , abs( Var ( 1 ) ) ) ) ) ;
715
741
}
742
+
743
+ #[ test]
744
+ fn has_free_variables ( ) {
745
+ assert ! ( !( abs( Var ( 1 ) ) . has_free_variables( ) ) ) ;
746
+ assert ! ( abs( Var ( 2 ) ) . has_free_variables( ) ) ;
747
+ assert ! ( app( abs( Var ( 2 ) ) , Var ( 1 ) ) . has_free_variables( ) ) ;
748
+ assert ! ( app( abs( Var ( 2 ) ) , abs( Var ( 1 ) ) ) . has_free_variables( ) ) ;
749
+ assert ! ( app( abs( Var ( 1 ) ) , abs( Var ( 2 ) ) ) . has_free_variables( ) ) ;
750
+ assert ! ( !app( abs( Var ( 1 ) ) , abs( Var ( 1 ) ) ) . has_free_variables( ) ) ;
751
+ assert ! ( !( abs( app(
752
+ abs( app( Var ( 2 ) , app( Var ( 1 ) , Var ( 1 ) ) ) ) ,
753
+ abs( app( Var ( 2 ) , app( Var ( 1 ) , Var ( 1 ) ) ) ) ,
754
+ ) ) )
755
+ . has_free_variables( ) ) ;
756
+ assert ! ( ( Var ( 0 ) ) . has_free_variables( ) ) ;
757
+ }
716
758
}
0 commit comments