在Prolog中对列表进行分类

时间:2012-09-11 07:00:06

标签: prolog dcg

好吧,我正在编写算术方程的解析器。我在列表中输入输入,例如"10+20" = [49,48,43,50,48]然后我将所有数字转换为相应的数字,例如[49,48,43,50,48] = [1,0,43,2,0]从那里我想要整数> 10回到一起。

从ascii转换 - >数字我使用maplist和number_codes进行转换。

我采用的一种方法是遍历列表,如果它是0-9将其存储在变量中,然后检查下一个数字,0-9将其附加到另一个变量,依此类推,直到我遇到一个运算符。我似乎无法简单地追加数字。这是我目前的代码。

expression(L) :-
    maplist(chars, L, Ls).

chars(C, N) :-
    (
        C >= "0", "9" >= C -> number_codes(N, [C]);
        N is C
    ).

不确定是否有一种简单的方法可以添加到我的代码中(据我所知,maplist只返回一个与传入的列表相同长度的列表,但我可能会弄错)。

感谢任何帮助:)

2 个答案:

答案 0 :(得分:1)

是的,maplist仅'返回'相等长度的列表。而且,maplist仅将谓词应用于一个元素(基本上它是无上下文的)。因此,不可能用maplist做你想要的(将运算符之间的数字组合成一个数字),你必须自己编写递归。

但是,你可以做一些比来回转换更容易的事情:

expression(L, E):-
    string_to_atom(L,A),
    atom_to_term(A,E,[]).

其中的工作原理如下:

2 ?- expression("1+2",E).
E = 1+2.

3 ?- expression("1+2",E), X is E.
E = 1+2, X = 3.

4 ?- expression("1+2",E), X+Y =  E.
E = 1+2, X = 1, Y = 2.

5 ?- expression("1+2+3",E), X+Y =  E.
E = 1+2+3, X = 1+2, Y = 3.

当然,如果你想要一个包含所有数字的列表,你将不得不做一些递归的事情,但这有点琐碎。

如果你仍然想要转换,我建议检查Definite Clause Grammars;它会简化任务。

答案 1 :(得分:1)

我前段时间answered使用表达式解析器。

它将向您展示如何将DCG用于实际任务,我希望您会欣赏这种方法的通用性和简单性。

SWI-Prolog需要一个库谓词,number // 1,可以在Sicstus中轻松实现。如果您需要更多帮助,请告诉我。