我无法让Prolog DCG与Atom Concat一起使用

时间:2019-01-25 23:23:05

标签: prolog dcg

我无法使用此Prolog DCG代码:

String1="   ",string_codes(String1,Codes),phrase(spaces(Output),Codes).

spaces(XXs) -->
   [X], {X=32}, spaces(Xs),
   {char_code(Ch,X), atom_concat(Ch,Xs,XXs)}, !. %%Space
spaces([]) --> [].

3 个答案:

答案 0 :(得分:2)

我通过将基本情况下的[]更改为“”解决了此问题。

spaces(XXs) -->
   [X], {X=32}, spaces(Xs),
   {char_code(Ch,X), atom_concat(Ch,Xs,XXs)}, !. %% Space
spaces('') --> [].

String1 = "   ",
Codes = [32, 32, 32],
Output = '   '.

答案 1 :(得分:1)

我觉得改进的解决方案可能是这样的:

spaces(Spaces) --> " ", spaces(S0), { atom_concat(' ', S0, Spaces) }.
spaces('') --> [].

真正不需要询问代码32的字符是什么,您知道这是一个空格。另外,您的答案中的[X], {X=32}优于[32],还是优于" "

答案 2 :(得分:1)

如果您正在执行DCG并使用SWI-Prolog,则dcgbasics中有一个常用谓词和DCG子句库。可以在带有

的代码中使用
:- use_module(library(dcg/basics)).

要列出谓词的代码,请使用listing/1,例如

?- listing(dcg_basics:_). 

该库具有一个DCG子句blanks//0,该子句可以满足您的要求,例如

?- listing(dcg_basics:blanks).
blanks(A, B) :-
    blank(A, C),
    !,
    D=C,
    blanks(D, B).
blanks(A, A).

true.

?- listing(dcg_basics:blank).
blank([C|A], B) :-
    nonvar(C),
    code_type(C, space),
    B=A.

true.

作为DCG的

blank -->
    [C],
    {
        nonvar(C),
        code_type(C,space)
    }.

blanks -->
    blank, !, blanks.

blanks --> [].

NB
库版本使用character codes而不是characters

?- string_codes("",Codes),phrase(blanks,Codes,Rest).
Codes = Rest, Rest = [].

?- string_codes(" ",Codes),phrase(blanks,Codes,Rest).
Codes = [32],
Rest = [].

?- string_codes("  ",Codes),phrase(blanks,Codes,Rest).
Codes = [32, 32],
Rest = [].

?- string_codes("   ",Codes),phrase(blanks,Codes,Rest).
Codes = [32, 32, 32],
Rest = [].