任务是识别像“abab”这样的单词并拒绝像“aacc”这样的单词。我应该使用DCG来实现这个目的,但我正在阅读的Prolog上的书只解释了如何在原子列表中使用它们,而不是在字符串上。
?- double("abab", []).
true
?- double("xyz", []).
false
这是一个“家庭作业”的问题,如果你觉得不方便给我答案,请随意给我一个提示。我真的不知道谷歌会怎么做。
答案 0 :(得分:4)
Prolog中的字符串是列出字符代码。因此,如果您知道如何将DCG用于列表,那么您已经知道如何将它们用于字符串。我同意@mat的字符列表更具可读性,因此我建议你按照他在评论中的建议设置标志。
话虽这么说,你可以使用DCG seq // 1来描述任意字符串并在DCG double // 0中使用它来描述这样的字符串必须出现两次。我还建议使用短语/ 2或短语/ 3与DCG,而不是使用DCG规则被转换成的谓词(参见@mat的评论)。您可以使用短语/ 2定义谓词double / 1,如下所示:
double(D) :- % the list D as described by
phrase(double,D). % the actual DCG double//0
seq([]) -->
[].
seq([H|T]) -->
[H],
seq(T).
double -->
seq(L),
seq(L).
查询调用谓词double / 1会产生以下结果:
?- double("abab").
yes
?- double("xyz").
no
?- double("aacc").
no
?- double(D).
D = [] ? ;
D = [_A,_A] ? ;
D = [_A,_B,_A,_B] ? ;
D = [_A,_B,_C,_A,_B,_C] ? ;
...
如果你坚持,你也可以使用上面的代码将你的示例查询用于double / 2,但我再次推荐你@ mat的评论为什么这是不可取的。