2012-09-11 100 views
0

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

从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还给长度相等的列表中传递的列表,但我可能是错误的)。

任何帮助表示赞赏:)

回答

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. 

当然,如果你想与所有的数字列表涉及到你将不得不做一些递归的事情,但这是微不足道的。

如果你仍然想要转换,我建议检查确定子句语法;它会大大简化任务。

+0

string_to_atom不存在于sicstus? – WhaleFanny

+0

@WhaleFanny我没有与sicstus合作;也许你需要包括一个库或检查类似的谓词 –

+0

['atom_codes/2'](http://www.swi-prolog.org/pldoc/doc_for?object=atom_codes/2)是ISO Prolog,似乎按照'string_to_atom/2'的要求来做 – m09

1

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

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

只需从SWI-Prolog获得库谓词number // 1即可在Sicstus中轻松实现。让我知道你是否需要更多的帮助。