erlangquickcheckerlang-shell

Symbolic calls with Quickcheck in erlang


Hi I am trying to learn quickcheck (quviq) in erlang and I have come across an exercise where I have to test a simulated cache with symbolic calls. However I encounter problems because I get an

31> eqc:quickcheck(test_cache:prop_cache()).               
Failed! Reason:
{'EXIT',{{badfun,{call,test_cache,mkt,[set,{0,10}]}},
         [{test_cache,'-prop_cache/0-fun-0-',1,
                       [{file,"test_cache.erl"},{line,79}]}]}}
After 1 tests.
{c,0,10,{call,test_cache,mkt,[set,{0,10}]}}
Shrinking ..(2 times)
Reason:
{'EXIT',{{badfun,{call,test_cache,mkt,[set,{0,2}]}},
         [{test_cache,'-prop_cache/0-fun-0-',1,
                       [{file,"test_cache.erl"},{line,79}]},
          {eqc_lazy_lists,lazy_safe_map,2,
                          [{file,"../src/eqc_lazy_lists.erl"},{line,38}]}]}}
{a,0,2,{call,test_cache,mkt,[set,{0,2}]}}
false

error when trying to call a function that is called symbolically and saved/stored in a variable such that it might be called with different pattern matches as seen in the response to anonymous function and pattern matching.

Edited:

In the below code I get the error when calling the TT1 variable in the prop_cache() with TT1(new) for instance. Which normally would return the {changed_value, Value, Cost} but doesn't do so (with or without the eval(...) ):

mkt(set, {Value, Cost}) ->   
  Val = fun(new) -> {changed_value, Value, Cost};
    ({exst, _Value}) -> {changed_value, Value, Cost}
  end,
  io:format("mkt Gets here ~p~n", [Val]),
  Val.

sym_mkt(Opr, Args) -> {call, ?MODULE, mkt, [Opr, Args]}.

term_transf(KeyGen) ->
  oneof(
    [ ?LET({K, V, C}, {KeyGen, int(), cost()},
              return ({K, V, C, sym_mkt(set,{V,C})}))
      ]). 


prop_cache()->
  ?FORALL({K1, V1, C1, TT1}, 
    term_transf(key()),
    begin
      %% arbitrary high capacity to ensure cache can hold all items
      {ok, F} = cache:new(999999),  
      equals({changed_value, V1,C1}, eval(TT1(new)))
    end
    ).

For reference (although not important to solving my issue): new(C) returns {ok, Pid} with capacity C. Furthermore it is placed in a module called cache and creates the simulated cache.


Solution

  • The error is telling you that you are trying to call a bad function {call,test_cache,mkt,[set,{0,10}]}, which is, indeed, not a function. This happens when trying to invoke it as TT1(new), prior to calling eval/1. Do eval(TT1) first, and then apply the argument new to the returned function to resolve this.