anchor.diff:  %% Types
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   
  --record(bloom, {
  -                size          = ?required(bloom, size):: pos_integer(),%bit-length of the bloom filter - requirement: size rem 8 = 0
  -                filter        = <<>>                  :: binary(),         %length = size div 8
  +-record(bloom, {filter        = <<>>                  :: binary(),         %length = size div 8
                   hfs           = ?required(bloom, hfs) :: ?REP_HFS:hfs(),   %HashFunctionSet
                   items_count   = 0                     :: non_neg_integer() %number of inserted items
                  }).
  
positive.code: 
  %% @doc Return bloom filter debug information.
  -spec print(bloom_filter()) -> [{atom(), any()}].
  print(#bloom{size = Size, hfs = Hfs, items_count = NumItems} = Bloom) ->
      HCount = ?REP_HFS:size(Hfs),
      [{filter_bit_size, Size},
       {struct_byte_size, byte_size(term_to_binary(Bloom))},
  
negative.code: 
  %% @doc joins two bloom filter, returned bloom filter represents their union
  -spec join(bloom_filter(), bloom_filter()) -> bloom_filter().
  join(#bloom{items_count = Items1, filter = F1, hfs = Hfs},
       #bloom{items_count = Items2, filter = F2}) ->
      Size = erlang:bit_size(F1),
      ?ASSERT2(Size =:= erlang:bit_size(F2), bf_not_equal_sizes),
      <<F1Val : Size>> = F1,
      <<F2Val : Size>> = F2,
      NewFVal = F1Val bor F2Val,
      #bloom{filter = <<NewFVal:Size>>, hfs = Hfs,
             items_count = Items1 + Items2 %approximation
             }.
  
  