Думайте декларативно: DCG всегда описывает список. В теле DCG запятая (",") читается как "и затем". Так, например, xml // 1 описывает (по своему первому правилу) либо отдельный элемент, либо (по второму правилу) элемент , а затем что-то, что снова описывается с помощью xml // 1. элемент // 1 является начальным тегом, затем элементами, затем конечным тегом и т. д. Аргументы, используемые в заголовках DCG, позволяют связать последовательность, описываемую телами DCG, с другой информацией, например, с подпоследовательностью, которая вас особенно интересует. Пример begintag // 1 - вы можете спросить:
?- phrase(begintag(T), [<, test, >]).
T = test.
, а также в другом направлении:
?- phrase(begintag(test), Ls).
Ls = [<, test, >].
В случае begintag // 1 имя тега кажется вам важным, поэтому вы ввели для него аргумент, который, с одной стороны, позволяет генерировать открывающий тег с заданным именем, и, с другой стороны, позволяет анализировать тег и извлекать его имя, а с третьей стороны задавать даже самый общий запрос:
?- phrase(begintag(T), Ls).
Ls = [<, T, >].
, который абстрактно связывает открывающий тег XML с его именем.