anchor.diff:  
   distr_and(And = #and_q{subs = Qs}) ->
       case lists:partition(fun (Q) -> is_record(Q, or_q) end, Qs) of
  -        {[], _Rest} ->
  +        {[],_Rest} ->
               And;
  -        {Ors, Rest} ->
  +        {Ors,Rest} ->
               #or_q{subs = [distr_and(#and_q{subs = Rs})
                             || Rs <- product([Q#or_q.subs || Q <-Ors],
                                              [Rest])]}
  
positive.code: 
  %% convert string to query
  from_str(Str, Lang) ->
      {ok, ParseTree} = dk_q_parser:parse(scan(Str)),
      tree_to_query(ParseTree, Lang).
  
  %% rewrite query to DNF
  
negative.code: 
  denest(#and_q{subs = Qs}) ->
      Rs = lists:flatten(lists:map(fun denest/1, Qs)),
      {Ands,Rest} = lists:partition(fun (R) -> is_record(R, and_q) end, Rs),
      #and_q{subs = lists:flatmap(fun subs/1, Ands) ++ Rest};
  denest(#or_q{subs = Qs}) ->
      Rs = lists:map(fun denest/1, Qs),
      {Ors,Rest} = lists:partition(fun (R) -> is_record(R, or_q) end, Rs),
      #or_q{subs = lists:flatmap(fun subs/1, Ors) ++ Rest};
  denest(#not_q{sub = Q}) ->
      #not_q{sub = denest(Q)};
  