Как преобразовать строку, прочитанную из ввода, в список списков в прологе - PullRequest
0 голосов
/ 08 марта 2012

Я пытаюсь написать программу, которая конвертирует из майя в арабские цифры и наоборот в пролог.Хотя я все еще сталкиваюсь с некоторыми проблемами, мне удалось заставить это работать в основном.Мне просто интересно, как, если я читаю, например:

....| 0 .| |||

из пользовательского ввода, как я могу преобразовать его в список, как это:

L = [ ['.','.','.','.','|'], [0], ['.','|'], ['|','|','|'] ]

У меня есть алгоритмнаписано получение от L до арабского значения, но я понятия не имею, как преобразовать эту строку в список.

Ответы [ 2 ]

3 голосов
/ 08 марта 2012

В SWI-Prolog есть встроенная функция, которая почти дает то, что вам нужно:

?- atom_chars('....| 0 .| |||', L).
L = ['.', '.', '.', '.', '|', ' ', '0', ' ', '.'|...].

Разделение на пробелы может быть выполнено с помощью другой встроенной функции, используемой в «обратном» режиме:

?- atomic_list_concat(L, ' ', '....| 0 .| |||').
L = ['....|', '0', '.|', '|||'].

Затем мы можем объединить их, используя maplist:

?- atomic_list_concat(L, ' ', '....| 0 .| |||'), maplist(atom_chars,L,G).
L = ['....|', '0', '.|', '|||'],
G = [['.', '.', '.', '.', '|'], ['0'], ['.', '|'], ['|', '|', '|']].

G это очень похоже на то, что вам нужно, просто обработайте '0' ...

1 голос
/ 08 марта 2012

Взгляните на этот ответ .Код, который я написал там, разбивает строку Пролога на пробелы, чтобы сформировать список атомов.С небольшой модификацией вы можете изменить код для создания строк вместо атомов.Вот соответствующий код из предыдущего поста, с необходимой модификацией для вашего случая:

data([A|As]) --> 
    spaces(_), 
    chars([X|Xs]), 
    {string_to_list(A, [X|Xs])},  %% Using string_to_list/2 instead
    spaces(_), 
    data(As).
data([]) --> [].

chars([X|Xs]) --> char(X), !, chars(Xs).
chars([]) --> [].

spaces([X|Xs]) --> space(X), !, spaces(Xs).
spaces([]) --> [].

space(X) --> [X], {code_type(X, space)}. 
char(X) --> [X], {\+ code_type(X, space)}.

В вашем примере вы взяли бы строку Prolog, содержащую ваш пример, например "....| 0 .| |||", и запустили приведенный выше кодиспользуя встроенный phrase/2, например так:

?- phrase(data(NumeralList), "....| 0 .| |||").
NumeralList = ["....|", "0", ".|", "|||"]

Обратите внимание, что я протестировал это на SWI-Prolog , и он работает, но если вы используете другойВнедрение Prolog может не поддерживать DCG или встроенные модули, которые я использовал.

Если бы вы добились результата, который точно , как вы описали как Lвыше, вы можете изменить код, чтобы он возвращал список [X | Xs] непосредственно в предложении data (удаляя подцель {string_to_list(A, [X|Xs])},), и измените последний предикат char на следующий:

char(C) --> [X], {\+ code_type(X, space), atom_codes(C,[X])}.

Выполнение этого дает:

?- phrase(data(L), "....| 0 .| |||").
L = [['.', '.', '.', '.', '|'], ['0'], ['.', '|'], ['|', '|', '|']]

РЕДАКТИРОВАТЬ: В соответствии с запросом, здесь приведен модифицированный код, который генерирует вышеуказанный результат в полном объеме:

data([[X|Xs]|As]) --> 
    spaces(_), 
    chars([X|Xs]), 
    spaces(_), 
    data(As).
data([]) --> [].

chars([X|Xs]) --> char(X), !, chars(Xs).
chars([]) --> [].

spaces([X|Xs]) --> space(X), !, spaces(Xs).
spaces([]) --> [].

space(X) --> [X], {code_type(X, space)}. 
char(C) --> [X], {\+ code_type(X, space), atom_codes(C,[X])}.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...