anchor.diff:  subtype(I, pos_integer) when I =< 16#10ffff -> char;
   subtype(I, char) when I =< 255 -> byte;
   
  -subtype(I, IntType) when IntType =:= pos_integer;
  -                         IntType =:= non_neg_integer;
  -                         IntType =:= neg_integer ->
  -    case ds_opts:getopt(mag) of
  -        0 -> '$null';
  -        N -> {IntType, {mag, mag(I, N)}}
  -    end;
  -
  -subtype(F, float) ->
  -    case ds_opts:getopt(mag) of
  -        0 -> '$null';
  -        N -> {float, {mag, mag(F, N)}}
  -    end;
  -
   subtype(L, list) ->
       case is_improper(L) of
           false -> nonempty_list;
  
positive.code:         false -> false
      end;
  dyn_record(_V) -> false.
  
  %% string classifier functions
  is_str_integer(S) -> string_in_ranges(S, [{$0, $9}]).
  is_str_alpha(S) -> string_in_ranges(S, [{$A, $Z}, {$a, $z}]).
  is_str_alnum(S) -> string_in_ranges(S, [{$0, $9}, {$A, $Z}, {$a, $z}]).
  is_str_printable(S) -> string_in_ranges(S, [$\r, $\n, $\t, {32, 126}, {160, 255}]).
  
  %% check that string consists of chars that fit in the given ranges
  string_in_ranges([],_Ranges)   -> true;
  string_in_ranges([C|L], Ranges) ->
      case char_in_ranges(C, Ranges) of
          false -> false;
          true  -> string_in_ranges(L, Ranges)
      end.
  
  %% check that char C is in one of the ranges spec'd as [{Min, Max}|Char].
  char_in_ranges(_C, []) -> false;
  char_in_ranges(C, [{Min, Max} | _]) when C >= Min, C =< Max -> true;
  char_in_ranges(C, [{_Min,_Max} | Rest]) -> char_in_ranges(C, Rest);
  char_in_ranges(C, [C | _]) -> true;
  char_in_ranges(C, [_Char | Rest]) -> char_in_ranges(C, Rest).
  
  %% order of magnitude for integers and floats
  mag(X, N) -> trunc(math:log10(abs(X))) div N * N.
  
  
  %% class-specific extra data
  
negative.code:     Attribute.
  
  %% This should be auto-generated by a 'decision tree compiler'
  %% that creates compiled Erlang code from a declarative type
  %% hierarchy specification.
  %% Compilation should also optimize away the getopt/1 calls,
  %% taking a concrete options configuration into account.
  subtype([], 'T') -> [];
  