pub fn substitute(&self, arg: &Expr, v: &Expr) -> (Expr, usize) {
        if self == arg {(v.clone(), 1)}
        else {
            match self {
                _0 | _1 | I | Var(_) => (self.clone(), 0),
                Type(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (typ(a2), n)
                }
                Un(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (un(a2), n)
                }
                Nu(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (nu(a2), n)
                }
                Ty(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (ty(a2, b2), n + m)
                }
                Ind(p, i) => {
                    let (p2, n) = p.substitute(arg, v);
                    let (i2, m) = i.substitute(arg, v);
                    (ind(p2, i2), n + m)
                }
                Pa(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (pa(a2, b2), n + m)
                }
                Lam(arg2, body) => {
                    if let Ty(a, a_ty) = &**arg2 {
                        let (a_ty2, m) = a_ty.substitute(arg, v);
                        if **a == *arg {(lam(ty((**a).clone(), a_ty2), (**body).clone()), m)}
                        else {
                            let (body2, n) = body.substitute(arg, v);
                            (lam(ty((**a).clone(), a_ty2), body2), m + n)
                        }
                    } else {
                        (self.clone(), 0)
                    }
                }
                All(lam) => {
                    let (lam2, n) = lam.substitute(arg, v);
                    (All(Box::new(lam2)), n)
                }
                Any(lam) => {
                    let (lam2, n) = lam.substitute(arg, v);
                    (Any(Box::new(lam2)), n)
                }
                Tup(tup) => {
                    let mut res = vec![];
                    let mut sum = 0;
                    for t in tup {
                        let (item, n) = t.substitute(arg, v);
                        res.push(item);
                        sum += n;
                    }
                    (Tup(res), sum)
                }
                Lift(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (lift(a2), n)
                }
                App(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (app(a2, b2), n + m)
                }
                Not(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (not(a2), n)
                }
                And(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (and(a2, b2), n + m)
                }
                Or(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (or(a2, b2), n + m)
                }
                Imply(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (imply(a2, b2), n + m)
                }
                Eq(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (eq(a2, b2), n + m)
                }
                Xor(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (xor(a2, b2), n + m)
                }
            }
        }
    }
/// Substitutes some argument with a value.
Substitutes some argument with a value.
Substitutes some argument with a value .
pub fn substitute(&self, arg: &Expr, v: &Expr) -> (Expr, usize) {
        if self == arg {(v.clone(), 1)}
        else {
            match self {
                _0 | _1 | I | Var(_) => (self.clone(), 0),
                Type(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (typ(a2), n)
                }
                Un(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (un(a2), n)
                }
                Nu(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (nu(a2), n)
                }
                Ty(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (ty(a2, b2), n + m)
                }
                Ind(p, i) => {
                    let (p2, n) = p.substitute(arg, v);
                    let (i2, m) = i.substitute(arg, v);
                    (ind(p2, i2), n + m)
                }
                Pa(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (pa(a2, b2), n + m)
                }
                Lam(arg2, body) => {
                    if let Ty(a, a_ty) = &**arg2 {
                        let (a_ty2, m) = a_ty.substitute(arg, v);
                        if **a == *arg {(lam(ty((**a).clone(), a_ty2), (**body).clone()), m)}
                        else {
                            let (body2, n) = body.substitute(arg, v);
                            (lam(ty((**a).clone(), a_ty2), body2), m + n)
                        }
                    } else {
                        (self.clone(), 0)
                    }
                }
                All(lam) => {
                    let (lam2, n) = lam.substitute(arg, v);
                    (All(Box::new(lam2)), n)
                }
                Any(lam) => {
                    let (lam2, n) = lam.substitute(arg, v);
                    (Any(Box::new(lam2)), n)
                }
                Tup(tup) => {
                    let mut res = vec![];
                    let mut sum = 0;
                    for t in tup {
                        let (item, n) = t.substitute(arg, v);
                        res.push(item);
                        sum += n;
                    }
                    (Tup(res), sum)
                }
                Lift(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (lift(a2), n)
                }
                App(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (app(a2, b2), n + m)
                }
                Not(a) => {
                    let (a2, n) = a.substitute(arg, v);
                    (not(a2), n)
                }
                And(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (and(a2, b2), n + m)
                }
                Or(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (or(a2, b2), n + m)
                }
                Imply(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (imply(a2, b2), n + m)
                }
                Eq(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (eq(a2, b2), n + m)
                }
                Xor(a, b) => {
                    let (a2, n) = a.substitute(arg, v);
                    let (b2, m) = b.substitute(arg, v);
                    (xor(a2, b2), n + m)
                }
            }
        }
    }
pub fn substitute ( & self , arg : & Expr , v : & Expr ) -> ( Expr , usize ) { if self == arg { ( v . clone ( ) , 1 ) } else { match self { _0 | _1 | I | Var ( _ ) => ( self . clone ( ) , 0 ) , Type ( a ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; ( typ ( a2 ) , n ) } Un ( a ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; ( un ( a2 ) , n ) } Nu ( a ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; ( nu ( a2 ) , n ) } Ty ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( ty ( a2 , b2 ) , n + m ) } Ind ( p , i ) => { let ( p2 , n ) = p . substitute ( arg , v ) ; let ( i2 , m ) = i . substitute ( arg , v ) ; ( ind ( p2 , i2 ) , n + m ) } Pa ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( pa ( a2 , b2 ) , n + m ) } Lam ( arg2 , body ) => { if let Ty ( a , a_ty ) = & * * arg2 { let ( a_ty2 , m ) = a_ty . substitute ( arg , v ) ; if * * a == * arg { ( lam ( ty ( ( * * a ) . clone ( ) , a_ty2 ) , ( * * body ) . clone ( ) ) , m ) } else { let ( body2 , n ) = body . substitute ( arg , v ) ; ( lam ( ty ( ( * * a ) . clone ( ) , a_ty2 ) , body2 ) , m + n ) } } else { ( self . clone ( ) , 0 ) } } All ( lam ) => { let ( lam2 , n ) = lam . substitute ( arg , v ) ; ( All ( Box :: new ( lam2 ) ) , n ) } Any ( lam ) => { let ( lam2 , n ) = lam . substitute ( arg , v ) ; ( Any ( Box :: new ( lam2 ) ) , n ) } Tup ( tup ) => { let mut res = vec ! [ ] ; let mut sum = 0 ; for t in tup { let ( item , n ) = t . substitute ( arg , v ) ; res . push ( item ) ; sum += n ; } ( Tup ( res ) , sum ) } Lift ( a ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; ( lift ( a2 ) , n ) } App ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( app ( a2 , b2 ) , n + m ) } Not ( a ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; ( not ( a2 ) , n ) } And ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( and ( a2 , b2 ) , n + m ) } Or ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( or ( a2 , b2 ) , n + m ) } Imply ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( imply ( a2 , b2 ) , n + m ) } Eq ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( eq ( a2 , b2 ) , n + m ) } Xor ( a , b ) => { let ( a2 , n ) = a . substitute ( arg , v ) ; let ( b2 , m ) = b . substitute ( arg , v ) ; ( xor ( a2 , b2 ) , n + m ) } } } }
Substitutes some argument with a value.
Substitutes some argument with a value .
&self
arg
&Expr
v
&Expr
&self
arg
&Expr
v
&Expr