anchor.diff:                           ?LET(S, range(1, (D*64) - O),
                                ?LET(V, bitstring(S),
                                    {D, P, O, S, V}))).
  +
  +struct_ptr() -> ?SIZED(D, struct_ptr(D)).
  +struct_ptr(D) -> ?SIZED(P, struct_ptr(D, P)).
  +struct_ptr(D, 0) -> struct_ptr(D, 1); %% we need at least 1 ptr to work with
  +struct_ptr(D, P) -> ?LET(I, range(0, P - 1),
  +                         ?LET(K, ref_kind(), {D, P, I, K})).
  +
  +ref_kind() -> union(
  +                [?LET(R, struct_ref(), R)
  +                ]).
   
   %%% ----------------------------------------
   prop_capnp_value() ->
  
positive.code: -include_lib("proper/include/proper.hrl").
  -include_lib("ecapnp/include/ecapnp.hrl").
  
  %%% ----------------------------------------
  value() -> union(
               [?LET(B, boolean(), {bool, B}),
                ?LET(I, integer(-128, 127), {int8, I})
               ]).
  
  %% generate struct def with valid offset and size
  struct_data() -> ?SIZED(D, struct_data(D)).
  
negative.code:     ?FORALL(
         {Data, Ptr, Off, Size, Value}, struct_data(),
         begin
             D = data(Data, Ptr),
             Ref = ecapnp_ref:get(0, 0, D),
             ok = ecapnp_ref:write_struct_data(Off, Size, Value, Ref),
             Value =:= ecapnp_ref:read_struct_data(Off, Size, Ref)
         end).
  
  %%% ----------------------------------------
  prop_struct_ptr() ->
      ?FORALL(
         {Data, Ptr, Idx, Kind}, struct_ptr(),
         begin
             D = data(Data, Ptr),
             Root = ecapnp_ref:get(0, 0, D),
             #ref{ kind=null }=Ref = ecapnp_ref:read_struct_ptr(Idx, Root),
             ok = ecapnp_ref:write_struct_ptr(Ref#ref{ kind=Kind }, Root),
             #ref{ kind=Kind } = ecapnp_ref:read_struct_ptr(Idx, Root),
             true
         end).
  
  
  %% ----------------------------------------
  data(Data) ->
      ecapnp_data:new(#msg{ data=Data, %%schema=test_schema(),
                            alloc=[size(S) || S <- Data] }).
  
  data(Data, Ptr) ->
      data([<<0:32, Data:16/integer-little, Ptr:16/integer-little,
              0:Data/integer-unit:64, 0:Ptr/integer-unit:64>>]).
  