如何将从输入读取的字符串转换为prolog中的列表列表

时间:2012-03-08 00:10:35

标签: string list prolog

我正在尝试编写一个程序,将玛雅语转换为阿拉伯数字,反之亦然。虽然我仍然遇到一些麻烦,但我已经设法让它主要起作用了。我只是想知道如何阅读例如:

....| 0 .| |||
从用户输入

,如何将其转换为如下列表:

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

我有一个编写从L到阿拉伯语值的算法,但我不知道如何将该字符串转换为列表。

2 个答案:

答案 0 :(得分:3)

在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'], ['.', '|'], ['|', '|', '|']].

这与你需要的非常相似,只需处理'0'......

答案 1 :(得分:1)

看看this answer。我在那里写的代码在空格上分割Prolog字符串以生成原子列表。通过一个小的修改,您可以更改代码以创建字符串而不是原子。以下是上一篇文章中的相关代码,并对您的案例进行了必要的修改:

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)}.

在您的示例中,您将使用包含"....| 0 .| |||"示例的Prolog字符串,并使用内置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])}.