anchor.diff:      X.
   
   unfold_record_types_in_type({app_t, Ann, Id = {id, _, RecName}, Args}) ->
  -    case ets:lookup(record_types, RecName) of
  -        [{RecName, Formals, Fields}] when length(Formals) == length(Args) ->
  +    case lookup_type(RecName) of
  +        {Formals, {record_t, Fields}} when length(Formals) == length(Args) ->
               {record_t,
                unfold_record_types_in_type(
                  subst_tvars(lists:zip(Formals, Args), Fields))};
  
positive.code:     FieldNames = [ Name || {id, _, Name} <- Fields ],
      UniqueFields = lists:usort(FieldNames),
      Candidates = [RecName || {_, _, {app_t, _, {id, _, RecName}, _}} <- ets:lookup(record_fields, hd(FieldNames))],
      TypesAndFields = [case ets:lookup(record_types, RecName) of
                            [{RecName, _, RecFields}] ->
                                {RecName, [Field || {field_t, _, {id, _, Field}, _} <- RecFields]};
                            [] ->
                                error({no_definition_for, RecName, in, Candidates})
                        end
                        || RecName <- Candidates],
  
negative.code:     ets:new(record_types, [public, named_table, set]),
      %% A relation from field names to types
      ets:new(record_fields, [public, named_table, bag]),
      [ insert_typedef(Id, Args, Typedef)
       || {type_def, _Attrs, Id, Args, Typedef} <- Defs].
  
  destroy_record_types() ->
      ets:delete(record_types),
      ets:delete(record_fields).
  
  -spec insert_typedef(aeso_syntax:id(), [aeso_syntax:tvar()], aeso_syntax:typedef()) -> ok.
  insert_typedef(Id = {id, Attrs, Name}, Args, Typedef) ->
      case Typedef of
          {record_t, Fields} ->
              ets:insert(record_types, {Name, Args, Fields}),
              [ets:insert(record_fields, {FieldName, FieldType, {app_t, Attrs, Id, Args}})
               || {field_t, _, {id, _, FieldName}, FieldType} <- Fields];
          {variant_t, _} -> ok;
          {alias_t, _} -> ok
      end,
      ok.
  
  -spec lookup_type(string()) -> false | {[aeso_syntax:tvar()], aeso_syntax:typedef()}.
  lookup_type(Name) ->
      case ets:lookup(record_types, Name) of
          []                       -> false;
          [{Name, Params, Fields}] -> {Params, {record_t, Fields}}
      end.
  
  create_field_constraints() ->
      %% A relation from uvars to constraints
  