我希望能够使用语法将[int(2), sep(<), int(1), sep(-), id(N)]
之类的数组转换为条件(在本例中为[int(2) < int(1)-id(N)]
)。我的语法如下:
cond(_, A > B) --> expr(_,A), [sep(>)], expr(_,B).
cond(_, A < B) --> expr(_,A), [sep(<)], expr(_,B).
expr(_, int(X)) --> [int(X)].
expr(_, id(X)) --> [id(X)].
expr(_, X + Y) --> expr(_,X), [sep(+)], expr(_,Y).
expr(_, X - Y) --> expr(_,X), [sep(-)], expr(_,Y).
我不明白的事实是,如果我有阵列:[int(2), sep(>), int(1), sep(+), id(N)]
一切都很好,条件正确翻译。然后,我进行了一些更改,将+
替换为-
或>
替换为<
(考虑到我的语法>
中的一行{ {1}},与<
和+
相同,并且不会被翻译,它会陷入无限循环:
-
始终与Call: (18) ? [sep(-), id(N)]=[sep(+)|_G2290032]creep
Fail: (18) ? [sep(-), id(N)]=[sep(+)|_G2290032]creep
的行进行比较。这个语法有什么问题?
- EDIT添加了追踪
sep(+)
答案 0 :(得分:0)
正如@TomasBy所建议的那样,非终端expr // 2中的左递归导致非终止。在SWI-Prolog中有库(tabling),只需导入它并将expr // 2声明为tabled。
:- use_module(library(tabling)).
:- table expr//2.