你如何将DCG翻译成PROLOG中的正常明确条款?

时间:2011-12-04 16:34:11

标签: prolog dcg

您如何将以下DCG转换为PROLOG的正常明确条款?

expr_regular --> cor_ini,numero,guion,numero,cor_fin.
cor_ini --> ['['].
numero --> ['0'];['1'];['2'];['3'];['4'];['5'];['6'];['7'];['8'];['9'].
cor_fin --> [']'].
guion --> ['-'].
编辑:我想将DCG转换为普通的PROLOG子句,因为我不能在同一代码中使用DCG和普通子句(在我的例子中)。我有这两段代码:

Piece1:

traducir(Xs, Ys) :- maplist(traduccion, Xs, Ys).
traduccion('^',comeza_por).
traduccion('[',inicio_rango).
traduccion('0',cero).
traduccion('-',a).
traduccion('9',nove).
traduccion(']',fin_rango).

如何使用它的一个例子是:

?- traducir(['[','0','-','9',']'],[]).
true .

和Piece2:

 traducir--> cor_ini,numero,guion,numero,cor_fin.
 cor_ini --> ['['].
 numero --> ['0'];['1'];['2'];['3'];['4'];['5'];['6'];['7'];['8'];['9'].
 cor_fin --> [']'].
 guion --> ['-'].

如何使用它的一个例子是:

traducir(['^','[','0','-','9',']'],X).
X = [comeza_por, inicio_rango, cero, a, nove, fin_rango].

我想将两个代码加入到一个代码中以测试traducir是否编写良好(如果它遵循DCG)并将您输入的内容翻译成文本,因此最终程序应该能够执行以下操作:

?- traducir(['^','[','0','-','9',']'],X).
X = [comeza_por, inicio_rango, cero, a, nove, fin_rango].
?- traducir(['[','0','-','9',']'],[]).
true .

3 个答案:

答案 0 :(得分:2)

在SWI-Prolog中,您可以直接在上使用listing/1

?- forall(member(NT,[expr_regular//0,cor_ini//0,numero//0,cor_fin//0,guion//0]),
          listing(NT)).
expr_regular(A, F) :-
    cor_ini(A, B),
    numero(B, C),
    guion(C, D),
    numero(D, E),
    cor_fin(E, F).

cor_ini(['['|A], A).

numero(A, B) :-
    (   A=['0'|B]
    ;   A=['1'|B]
    ;   A=['2'|B]
    ;   A=['3'|B]
    ;   A=['4'|B]
    ;   A=['5'|B]
    ;   A=['6'|B]
    ;   A=['7'|B]
    ;   A=['8'|B]
    ;   A=['9'|B]
    ).

cor_fin([']'|A], A).

guion([-|A], A).

true.

那就是它!你可以从查看相关问题的答案中获益[&3;} Is there a way or an algorithm to convert DCG into normal definite clauses in Prolog?"。

答案 1 :(得分:1)

嗯,我真的不明白你的问题。无论如何,如果由于某种原因你不想使用漂亮的DCG语法,你仍然可以使用wildcard_match/2之类的东西,或者重新发明轮子并自己使用差异列表来重新实现DCG,或者追加。对于wildcard_match/2部分:

expr_regular(R) :- wildcard_match('[[][0-9]-[0-9]]', R).

答案 2 :(得分:1)

你的语法非常简单:只是终端。所以我们可以转换为一个非常具体的模式(注意:不允许泛化)。

expr_regular(S, G) :-
    S = [0'[, N1, 0'-, N2, 0']|G], numero(N1), numero(N2).
numero(N) :-
    memberchk(N, "0123456789").

唯一值得注意的是它是ISO标准字符符号......