Оставив в стороне цель, для которой это необходимо, давайте напишем предикат Prolog, который объединяет список строк в одну строку, помещая двойной символ новой строки между каждой последовательной парой строк (но не в конце выходной строки,судя по примеру, опубликованному Джерри).
Руководство по SWI-Prolog: Обычно я бы публиковал "глубокие" ссылки на документацию , но SWI-PrologСайт использует стиль URL, который вызывает предупреждения межсайтового скриптинга (XSS) со многими комбинациями браузер / плагин.Поэтому вместо этого я буду ссылаться, чем ссылка на соответствующий раздел.
Раздел 4.22. Представление текста в строках говорит (частично), что «Строковые объекты по умолчанию не имеют лексического представления и, следовательно, могут быть созданы только с использованием предикатов нижеили через интерфейс на иностранном языке. "Это может немного сбивать с толку, поскольку SWI-Prolog записывает строки в виде текста в двойных кавычках, но читает текст в двойных кавычках (по умолчанию) как списки кодов символов.
Вот код для предиката, который объединяет строкив списке, вставляя еще один разделитель строк между последовательными парами строк:
strSepCat([ ],_,Empty) :-
string_to_list(Empty,[ ]).
strSepCat([H|T],Separator,StrCat) :-
strSepCat(T,Separator,H,StrCat).
strSepCat([ ],_,StrCat,StrCat).
strSepCat([H|T],Sep,Str,Cat) :-
string_concat(Sep,H,SepH),
string_concat(Str,SepH,StrSepH),
strSepCat(T,Sep,StrSepH,Cat).
Обратите внимание, что мы определили два предиката, strSepCat / 3 и strSepCat / 4 .Первый определяется в терминах второго, типичного шаблона проектирования в Прологе, который вводит дополнительный аргумент в виде аккумулятора , который связывается с выводом после завершения рекурсии.Такая техника часто полезна для получения хвостовой рекурсивной определения.
Чтобы использовать предикат strSepCat / 3 , нам обычно нужно создать строку-разделитель с помощью(escape-последовательность для) двух новых строк:
?- funs(Fs,Lisp,[ ]), string_to_list(Sep,"\n\n"), strSepCat(Fs,Sep,CProg).