:- use_module(library(dcg/basics)). :- begin_tests(dcg). % Parsing the (unicode) codepoints in "Codes" with the callable % integer(X) which actually resolves to predicate integer/3, taking % itself "Codes" and "Rest" in addition to "X". After the call, leftover % character codes from "Codes" are in "Rest". test(parsing, [true(ResultCmp)] ) :- atom_codes('42 times', Codes), phrase(integer(X), Codes, Rest), atom_codes(RestAtom, Rest), ResultCmp = (result(X,RestAtom) == result(42,' times')). % Generating the (unicode) codepoints in "Codes" based on an integer % passed to the callable integer(X) and a suffix of codepoints in "Rest". % After the call, the "Rest", prefixed with whatever integer(42) as % generated, can be found in "Codes". test(generating, [true(ResultCmp)] ) :- atom_codes(' times', Rest), phrase(integer(42), Codes, Rest), atom_codes(CodesAtom, Codes), ResultCmp = (CodesAtom == '42 times'). :- end_tests(dcg). rt(dcg) :- run_tests(dcg).
How does integer//1 from library(dcg/basics) looks like?
(note the two // to indicate that this a DCG-processing predicate. In the same away as integer/1 is called a "predicate indicator", integer//1 is called a "non-terminal indicator")
It is actually an integer/3 (although one should not rely on what the compiler generates from integer//1)
?- listing(integer//1). integer(I, A, B) :- digit(D0, A, C), digits(D, C, E), number_codes(I, [D0|D]), B=E. true.