Search code examples
prologdcg

Match anything except if a negative rule matches


I have a rule that matches bc. When I encounter that in a string, I don't want to parse that string, otherwise parse anything else.

% Prolog

bc(B, C) --> [B, C], {
  B = "b",
  C = "c"
}.

not_bc(O) --> [O], % ?! bc(O, C).

% ?- phrase(not_bc(O), "bcdefg").
% false.
% ?- phrase(not_bc(O), "abcdefg").
% O = "a".
% ?- phrase(not_bc(O), "wxcybgz")
% O = "w".
% ?- phrase(not_bc(O), "wxybgz") 
% O = "w".

Simplified version of my problem, hopefully solutions are isomorphic.

Similar to this question: Translation to DCG Semicontext not working - follow on


Solution

  • An alternative:

    process_bc(_) --> "bc", !, { fail }.
    process_bc(C) --> [C].
    

    This differs from my other solution in accepting:

    ?- time(phrase(process_bc(C), `b`, _)).
    % 8 inferences, 0.000 CPU in 0.000 seconds (83% CPU, 387053 Lips)
    C = 98.