anchor.diff:  %% Internal functions
   %%----------------------------------------------------------------------------
   
  +%% @doc Converts a UTF-8 string to a query. Returns a query record plus the
  +%% depth of the corresponding tree.
  +-spec from_str(utf8_str()) -> {q(),pos_integer()}.
   from_str(Str) ->
       {ok,ParseTree} = dk_q_parser:parse(scan(Str)),
       tree_to_query(ParseTree).
  
positive.code: tree_to_query({term_q,{string,Keyword,_}}) ->
      {#term_q{keyword = Keyword},0}.
  
  dnf({Q,0}) ->
      Q;
  dnf({Q,D}) ->
  
negative.code: mv_and(Q) ->
      Q.
  
  %% @doc Converts a query in DNF to a lists of AND queries.
  clauses({or_q,L,R}) ->
      clauses(L) ++ clauses(R);
  clauses(Q) ->
      [Q].
  
  %% @doc Converts an AND clause to  a list of TERM and NOT queries.
  flatten({and_q,L,R}) ->
      lists:flatten([flatten(L),flatten(R)]);
  flatten(Q) ->
      [Q].
  
  %% @doc Partitions a list of TERM and NOT queries into two lists, where the
  %% first lists contains all terms in TERM queries and the second list contains
  %% all terms in NOT queries.
  partition(Qs) ->
      {Pos,Neg} = lists:partition(fun (Q) -> is_record(Q, term_q) end, Qs),
      {terms(Pos),terms(Neg)}.
  