anchor.diff:  -include_lib("proper/include/proper.hrl").
   -include_lib("ecapnp/include/ecapnp.hrl").
   
  +-define(TRACE(E),
  +        fun (__V) ->
  +                io:format("TRACE: ~s:~b ~s = ~p~n", [?FILE, ?LINE, ??E, __V]),
  +                __V
  +        end(E)).
  +
  +-define(T(E), ?TRACE(E)).
  +
   %%% ----------------------------------------
   value() -> union(
                [?LET(B, boolean(), {bool, B}),
                 ?LET(I, integer(-128, 127), {int8, I})
                ]).
  +
  +struct_ref() -> ?SUCHTHAT(R, struct_ref1(),
  +                          begin
  +                              #struct_ref{ dsize=D, psize=P } = R,
  +                              D + P > 0
  +                          end).
  +
  +struct_ref1() -> ?SIZED(D, struct_ref1(D)).
  +struct_ref1(D) -> ?SIZED(P, struct_ref1(D, P)).
  +struct_ref1(D, P) -> #struct_ref{ dsize=D, psize=P }.
   
   %% generate struct def with valid offset and size
   struct_data() -> ?SIZED(D, struct_data(D)).
  
positive.code:                          ?LET(S, range(1, (D*64) - O),
                               ?LET(V, bitstring(S),
                                   {D, P, O, S, V}))).
  
  %%% ----------------------------------------
  prop_capnp_value() ->
  
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>>]).
  