anchor.diff:  union(#hyper{registers = LeftRegisters} = Left,
         #hyper{registers = RightRegisters} = Right)
     when Left#hyper.p =:= Right#hyper.p ->
  -
  -    NewRegisters = array:sparse_foldl(
  -                     fun (Index, LeftValue, Registers) ->
  -                             case array:get(Index, Registers) of
  -                                 Less when Less < LeftValue ->
  -                                     array:set(Index, LeftValue, Registers);
  -                                 _ ->
  -                                     Registers
  -                             end
  -                     end, RightRegisters, LeftRegisters),
  +    %% NewRegisters =
  +    %%     gb_trees:from_orddict(
  +    %%       orddict:merge(fun (_Index, L, R) -> max(L, R) end,
  +    %%                     gb_trees:to_list(LeftRegisters),
  +    %%                     gb_trees:to_list(RightRegisters))),
  +
  +    NewRegisters = gb_fold(fun (Index, L, Registers) ->
  +                                   case gb_trees:lookup(Index, Registers) of
  +                                       {value, R} when R < L ->
  +                                           gb_trees:enter(Index, L, Registers);
  +                                       {value, _} ->
  +                                           Registers;
  +                                       none ->
  +                                           gb_trees:enter(Index, L, Registers)
  +                                   end
  +                           end, RightRegisters, LeftRegisters),
   
       Right#hyper{registers = NewRegisters}.
  +
  +
  +gb_fold(F, A, {_, T}) when is_function(F, 3) ->
  +    gb_fold_1(F, A, T).
  +
  +gb_fold_1(F, Acc0, {Key, Value, Small, Big}) ->
  +    Acc1 = gb_fold_1(F, Acc0, Small),
  +    Acc = F(Key, Value, Acc1),
  +    gb_fold_1(F, Acc, Big);
  +gb_fold_1(_, Acc, _) ->
  +    Acc.
   
   
   %% NOTE: use with caution, no guarantees on accuracy.
  
positive.code: -spec card(filter()) -> float().
  card(#hyper{registers = Registers, p = P}) ->
      M = trunc(pow(2, P)),
      RegisterSum = lists:sum(lists:map(fun (Register) ->
                                                pow(2, -Register)
                                        end, array:to_list(Registers))),
  
      E = alpha(M) * pow(M, 2) / RegisterSum,
      Ep = case E =< 5 * M of
  
negative.code: 
  serialization_test() ->
      Hyper = insert_many(generate_unique(10), new(14)),
  
      L = Hyper#hyper.registers,
      R = (from_json(to_json(Hyper)))#hyper.registers,
  
      ?assertEqual(trunc(card(Hyper)), trunc(card(from_json(to_json(Hyper))))),
      ?assertEqual(Hyper#hyper.p, (from_json(to_json(Hyper)))#hyper.p),
      ?assertEqual(gb_trees:to_list(L), gb_trees:to_list(R)).
  
  encoding_test() ->
      Hyper = insert_many(generate_unique(100000), new(14)),
  