:- use_module(library(dcg_util)). lowercase(C) --> [C], { between(0'a, 0'z, C) }. :- use_module(library(tap)). % make sure our auxiliary predicate behaves as expected 'lowercase is behaving' :- phrase(lowercase(C), `hello`, Rest), C == 0'h, Rest == `ello`. nothing :- Text = `some text`, once(phrase(generous(lowercase,Matches),Text,Rest)), Matches == [], Rest == Text. backtrack :- Text = `abc`, findall(X,phrase(generous(lowercase,X),Text,_),Matches), Matches == [``, `a`, `ab`, `abc`].