let rec cmp x y =
  match x, y with
    | Slack(i, sl1), Slack(j, sl2) ->
        (match sl1, sl2 with
           | ZeroZero -> 
               Pervasives.compare i j
           | ZeroNonneg _ -> -1
           | Nonneg _, Zero -> 1
           | Nonneg(d), Nonneg(e) ->
               let c1 = Dom.cmp d e in
                 if c1 != 0 then c1 else
                   Pervasives.compare i j)
    | Slack _, _ ->  -1
    | _, Slack _ -> 1 
    | Const(n, i, d), Const(m, j, e) ->
        let c1 = domcmp d e in
          if c1 != 0 then c1 else 
            let c2 = Pervasives.compare i j in
              if c2 != 0 then c2 else Pervasives.compare n m
    | Const _, _ -> -1
    | _, Const _ -> 1
    | Fresh(n, i, d), Fresh(m, j, e) ->
        let c1 = domcmp d e in
          if c1 != 0 then c1 else 
            let c2 = Pervasives.compare i j in
              if c2 != 0 then c2 else Pervasives.compare n m
    | Fresh _, _ -> -1
    | _, Fresh _ -> 1
    | External(n, d), External(m, e) -> 
        let c1 = domcmp d e in
          if c1 != 0 then c1 else Name.compare n m
    | External _, _ -> -1
    | _, External _ -> 1
    | Rename(n, i, d), Rename(m, j, e) -> 
        let c1 = domcmp d e in
          if c1 != 0 then c1 else 
            let c2 = Pervasives.compare i j in
              if c2 != 0 then c2 else Name.compare n m