fn leq_core(
        self, 
        other : Self, 
        diff : isize, 
        ctx : &mut impl IsLiveCtx<'a>
    ) -> bool {
        match (self.read(ctx), other.read(ctx)) {
            (Zero, _) if diff >= 0             => true,
            (_, Zero) if diff < 0              => false,
            (Param(a), Param(x))               => a == x && diff >= 0,
            (Param(..), Zero)                  => false,
            (Zero, Param(..))                  => diff >= 0,

            (Succ(s), _)                       => s.leq_core(other, diff - 1, ctx),
            (_, Succ(s))                       => self.leq_core(s, diff + 1, ctx),

            (Max(a, b), _)                     => a.leq_core(other, diff, ctx) 
                                               && b.leq_core(other, diff, ctx),

            (Param(..), Max(x, y))             => self.leq_core(x, diff, ctx)
                                               || self.leq_core(y, diff, ctx),

            (Zero, Max(x, y))                  => self.leq_core(x, diff, ctx)
                                               || self.leq_core(y, diff, ctx),

            (Imax(a, b), Imax(x, y)) if (a == x) && (b == y) => true,

            (Imax(.., b), _) if b.is_param(ctx)   => b.ensure_imax_leq(self, other, diff, ctx),

            (_, Imax(.., y)) if y.is_param(ctx)   => y.ensure_imax_leq(self, other, diff, ctx),

            (Imax(a, b), _) if b.is_any_max(ctx)  => match b.read(ctx) {
               Imax(x, y) => {

                   let new_lhs = <Self>::new_imax(a, y, ctx); 
                   let new_rhs = <Self>::new_imax(x, y, ctx);
                   let new_max = <Self>::new_max(new_lhs, new_rhs, ctx);
                   new_max.leq_core(other, diff, ctx)
               },
               Max(x, y) => {
                    let new_lhs = <Self>::new_imax(a, x, ctx);
                    let new_rhs = <Self>::new_imax(a, y, ctx);
                    let new_max = <Self>::new_max(new_lhs, new_rhs, ctx).simplify(ctx);
                    new_max.leq_core(other, diff, ctx)
                },
                _ => unreachable!(),
            },

            (_, Imax(x, y)) if y.is_any_max(ctx)  => match y.read(ctx) {
                Imax(j, k) => {
                    let new_lhs = <Self>::new_imax(x, k, ctx);
                    let new_rhs = <Self>::new_imax(j, k, ctx);
                    let new_max = <Self>::new_max(new_lhs, new_rhs, ctx);
                    self.leq_core(new_max, diff, ctx)
                },
                Max(j, k) => {
                    let new_lhs = <Self>::new_imax(x, j, ctx);
                    let new_rhs = <Self>::new_imax(x, k, ctx);
                    let new_max = <Self>::new_max(new_lhs, new_rhs, ctx).simplify(ctx);
                    self.leq_core(new_max, diff, ctx)
                },
                _ => unreachable!(),
            }
            _ => unreachable!()
        }
    }
// Important note about this is that a return value of `false` does NOT
// indicate `greater than`, it just means "L is not less than or equal to R"
// since there are times where we can't say for sure one way or the other.
// An example would be (Param(A), Param(X)). Without some extra information
// (which this function will never receive), there's no way to know whether
// any particular substitution for A and X will produce a pair such that 
// L <= R or R <= L   
Important note about this is that a return value of `false` does NOT
indicate `greater than`, it just means "L is not less than or equal to R"
since there are times where we can't say for sure one way or the other.
Important note about this is that a return value of ` false ` does NOT indicate ` greater than ` it just means " L is not less than or equal to R " since there are times where we can ' t say for sure one way or the other .
fn leq_core(
        self, 
        other : Self, 
        diff : isize, 
        ctx : &mut impl IsLiveCtx<'a>
    ) -> bool {
        match (self.read(ctx), other.read(ctx)) {
            (Zero, _) if diff >= 0             => true,
            (_, Zero) if diff < 0              => false,
            (Param(a), Param(x))               => a == x && diff >= 0,
            (Param(..), Zero)                  => false,
            (Zero, Param(..))                  => diff >= 0,
            (Succ(s), _)                       => s.leq_core(other, diff - 1, ctx),
            (_, Succ(s))                       => self.leq_core(s, diff + 1, ctx),
            (Max(a, b), _)                     => a.leq_core(other, diff, ctx) 
                                               && b.leq_core(other, diff, ctx),
            (Param(..), Max(x, y))             => self.leq_core(x, diff, ctx)
                                               || self.leq_core(y, diff, ctx),
            (Zero, Max(x, y))                  => self.leq_core(x, diff, ctx)
                                               || self.leq_core(y, diff, ctx),
            (Imax(a, b), Imax(x, y)) if (a == x) && (b == y) => true,
            (Imax(.., b), _) if b.is_param(ctx)   => b.ensure_imax_leq(self, other, diff, ctx),
            (_, Imax(.., y)) if y.is_param(ctx)   => y.ensure_imax_leq(self, other, diff, ctx),
            (Imax(a, b), _) if b.is_any_max(ctx)  => match b.read(ctx) {
               Imax(x, y) => {
                   let new_lhs = <Self>::new_imax(a, y, ctx); 
                   let new_rhs = <Self>::new_imax(x, y, ctx);
                   let new_max = <Self>::new_max(new_lhs, new_rhs, ctx);
                   new_max.leq_core(other, diff, ctx)
               },
               Max(x, y) => {
                    let new_lhs = <Self>::new_imax(a, x, ctx);
                    let new_rhs = <Self>::new_imax(a, y, ctx);
                    let new_max = <Self>::new_max(new_lhs, new_rhs, ctx).simplify(ctx);
                    new_max.leq_core(other, diff, ctx)
                },
                _ => unreachable!(),
            },
            (_, Imax(x, y)) if y.is_any_max(ctx)  => match y.read(ctx) {
                Imax(j, k) => {
                    let new_lhs = <Self>::new_imax(x, k, ctx);
                    let new_rhs = <Self>::new_imax(j, k, ctx);
                    let new_max = <Self>::new_max(new_lhs, new_rhs, ctx);
                    self.leq_core(new_max, diff, ctx)
                },
                Max(j, k) => {
                    let new_lhs = <Self>::new_imax(x, j, ctx);
                    let new_rhs = <Self>::new_imax(x, k, ctx);
                    let new_max = <Self>::new_max(new_lhs, new_rhs, ctx).simplify(ctx);
                    self.leq_core(new_max, diff, ctx)
                },
                _ => unreachable!(),
            }
            _ => unreachable!()
        }
    }
fn leq_core ( self , other : Self , diff : isize , ctx : & mut impl IsLiveCtx < ' a > ) -> bool { match ( self . read ( ctx ) , other . read ( ctx ) ) { ( Zero , _ ) if diff >= 0 => true , ( _ , Zero ) if diff < 0 => false , ( Param ( a ) , Param ( x ) ) => a == x && diff >= 0 , ( Param ( .. ) , Zero ) => false , ( Zero , Param ( .. ) ) => diff >= 0 , ( Succ ( s ) , _ ) => s . leq_core ( other , diff - 1 , ctx ) , ( _ , Succ ( s ) ) => self . leq_core ( s , diff + 1 , ctx ) , ( Max ( a , b ) , _ ) => a . leq_core ( other , diff , ctx ) && b . leq_core ( other , diff , ctx ) , ( Param ( .. ) , Max ( x , y ) ) => self . leq_core ( x , diff , ctx ) || self . leq_core ( y , diff , ctx ) , ( Zero , Max ( x , y ) ) => self . leq_core ( x , diff , ctx ) || self . leq_core ( y , diff , ctx ) , ( Imax ( a , b ) , Imax ( x , y ) ) if ( a == x ) && ( b == y ) => true , ( Imax ( .. , b ) , _ ) if b . is_param ( ctx ) => b . ensure_imax_leq ( self , other , diff , ctx ) , ( _ , Imax ( .. , y ) ) if y . is_param ( ctx ) => y . ensure_imax_leq ( self , other , diff , ctx ) , ( Imax ( a , b ) , _ ) if b . is_any_max ( ctx ) => match b . read ( ctx ) { Imax ( x , y ) => { let new_lhs = < Self > :: new_imax ( a , y , ctx ) ; let new_rhs = < Self > :: new_imax ( x , y , ctx ) ; let new_max = < Self > :: new_max ( new_lhs , new_rhs , ctx ) ; new_max . leq_core ( other , diff , ctx ) } , Max ( x , y ) => { let new_lhs = < Self > :: new_imax ( a , x , ctx ) ; let new_rhs = < Self > :: new_imax ( a , y , ctx ) ; let new_max = < Self > :: new_max ( new_lhs , new_rhs , ctx ) . simplify ( ctx ) ; new_max . leq_core ( other , diff , ctx ) } , _ => unreachable ! ( ) , } , ( _ , Imax ( x , y ) ) if y . is_any_max ( ctx ) => match y . read ( ctx ) { Imax ( j , k ) => { let new_lhs = < Self > :: new_imax ( x , k , ctx ) ; let new_rhs = < Self > :: new_imax ( j , k , ctx ) ; let new_max = < Self > :: new_max ( new_lhs , new_rhs , ctx ) ; self . leq_core ( new_max , diff , ctx ) } , Max ( j , k ) => { let new_lhs = < Self > :: new_imax ( x , j , ctx ) ; let new_rhs = < Self > :: new_imax ( x , k , ctx ) ; let new_max = < Self > :: new_max ( new_lhs , new_rhs , ctx ) . simplify ( ctx ) ; self . leq_core ( new_max , diff , ctx ) } , _ => unreachable ! ( ) , } _ => unreachable ! ( ) } }
Important note about this is that a return value of `false` does NOT
indicate `greater than`, it just means "L is not less than or equal to R"
since there are times where we can't say for sure one way or the other.
Important note about this is that a return value of ` false ` does NOT indicate ` greater than ` it just means " L is not less than or equal to R " since there are times where we can ' t say for sure one way or the other .
self
other
Self
diff
isize
ctx
&mut impl IsLiveCtx<'a>
self
other
Self
diff
isize
ctx
&mut impl IsLiveCtx<'a>