anchor.diff:  %% @doc Return a purity score for a module.  Initially the purity
   %% score is the fraction of pure functions.
   
  --spec score(module(), purity_utils:options()) -> dict().
  +-spec score(string(), purity_utils:options()) -> dict().
   score(CodeText, Options) ->
       case compile(CodeText) of
   	{ok, Module, Core} ->
  
positive.code: 
  %% @doc Find the top-most pure functions, i.e. those which are pure
  %% and have an impure caller.  Return the result as a set.
  
  -spec top_funs([module()], dict(), dict()) -> ordsets:ordset(mfa()).
  
  top_funs(Modules, CallArcs, Pureness) ->
      dict:fold(fun(Caller, Contexts, TopSet) ->
  		      add_top_fun(Modules, Caller, Contexts, Pureness, TopSet)
  	      end,
  	      ordsets:new(), CallArcs).
  
  -spec add_top_fun(dict(), mfa(), [context()], dict(), set()) -> set().
  
  add_top_fun(Modules, {_, _, _}=Caller, Contexts, Pureness, TopSet) ->
      Ms = sets:from_list(Modules),
      case is_pure(Caller, Pureness) of
  	true ->
  	    %% Caller is pure, so callees are not top-most
  	    TopSet;
  	false ->
  	    %% Caller is impure, so pure callees are top-most
  	    Callees = if is_list(Contexts) ->
  			      lists:map(fun mfa_from_context/1, Contexts);
  			 true ->
  			      [mfa_from_context(Contexts)]
  		      end,
  	    PureCallees = lists:filter(
  		fun(none) ->
  			false;
  		   ({M, _, _}=Callee) ->
  			sets:is_element(M, Ms) and
  			    is_pure(Callee, Pureness)
  		end, Callees),
  	    lists:foldl(
  	        fun(Elem, SetIn) ->
  			ordsets:add_element(Elem, SetIn)
  		end, TopSet, PureCallees)
      end;
  add_top_fun(_Modules, _Caller, _Contexts, _Pureness, TopSet) ->
      TopSet.
  	    
  
  -spec mfa_from_context(context()) -> mfa().
  
  
negative.code:     none.
  
  
  %% @doc Return a set of topmost pure functions containined in
  %% a string of Erlang code.
  
  -spec top_funs_from_code(string(), purity_utils:options()) ->
        ordsets:ordset(mfa()) | {error, compilation_failure}.
  top_funs_from_code(CodeText, Options) ->
      case compile(CodeText) of
  	{ok, Module, Core} ->
              Plt = load_plt_silent(Options),
              Tab = purity_plt:get_cache(Plt, Options),
  	    Dep = module(Core, Options, Tab),
              Pureness = propagate(Dep, Options),
              top_funs([Module], Dep, Pureness);
  	_ ->
  	    {error, compilation_failure}
      end.
  
  
  %%% Various helpers. %%%
  
  update(Table, KeyVals) ->
  