我正在尝试使用DCG创建语言a ^ n b ^ n-1 c ^ n-2,但无法使succ(0)处理n

时间:2018-12-03 06:34:37

标签: prolog dcg successor-arithmetics

s(Count) --> a(Count), b(Count), c(Count).

a(0) --> [].
a(succ(Count)) --> [a], a(Count).

b(0) --> [].
b(succ(succ(Count))) --> [b], b(Count).

c(0) --> [].
c(succ(succ(succ(Count)))) --> [c], c(Count).

很容易为每个规则使用succ(0)创建像a ^ nb ^ nc ^ n这样的语言,但是当要改变a和c的每个块的n时,这是行不通的。

3 个答案:

答案 0 :(得分:4)

查看您的子句,例如:

c(0) --> [].
c(succ(succ(succ(Count)))) --> [c], c(Count).

请注意,您只匹配两种情况-零或三个字符,但是一两个呢?修改c以解决每个可接受的长度似乎是一个死胡同,相对于ca的数量,指定要多少b个要容易得多在您控制它们的所有位置,即s

s(succ(succ(Count))) --> a(succ(succ(Count))), b(succ(Count)), c(Count).

这自然会转化为您的规范:对于至少两个的N,请接受N a s,N-1 b s和{{1} } N-2

现在其余的就很容易就位了:

c

当然,您可以将它们替换为通用子句a(0) --> []. a(succ(Count)) --> [a], a(Count). b(0) --> []. b(succ(Count)) --> [b], b(Count). c(0) --> []. c(succ(Count)) --> [c], c(Count). (作为练习)。

char(Char, Count)

答案 1 :(得分:3)

除了@firefrorefiddle的回答外,我还要注意三件事。首先,在使用Peano数字时,更习惯使用functor s / 1表示后继,并使用单个字母(如X)表示变量,从而获得较小的项:

s(X)            succ(Count)
s(s(X))         succ(succ(Count))
s(s(s(X)))      succ(succ(succ(Count)))
s(s(s(s(X))))   succ(succ(succ(succ(Count))))
.               .
.               .
.               .

第二,为了进一步提高可读性,那么为DCG选择一个不同的名称可能是有利的,可能是诸如language // 1而不是s // 1之类的名称。第三,您可以定义一个更通用的DCG,以便您可以在abc中编写相同的DCG规则,而无需指定相同的DCG规则。清单。综合所有这些,您的DCG可能看起来像这样:

language(s(s(X))) -->
   element_frequency(a,s(s(X))),
   element_frequency(b,s(X)),
   element_frequency(c,X).

element_frequency(_E,0) -->
   [].
element_frequency(E,s(X)) -->
   [E],
   element_frequency(E,X).

在上面的代码中,语言// 1与代码中的s // 1相对应,element_frequency // 2替代了a // 1,b // 1和c // 1。如果您查询此DCG,您会发现它仍然产生与@firefrorefiddle帖子中相同的答案,例如:

   ?- phrase(language(s(s(s(0)))),L).
L = [a,a,a,b,b,c]

答案 2 :(得分:-2)

DCG的

[]随时匹配。 让我们颠倒a,b,c规则。

s(Count) --> a(Count), b(Count), c(Count).

a(succ(Count)) --> [a], a(Count).
a(0) --> [].

b(succ(succ(Count))) --> [b], b(Count).
b(0) --> [].

c(succ(succ(succ(Count)))) --> [c], c(Count).
c(0) --> [].

:- s(N,[a,a,a,a,a,a,b,b,b,c,c],[]),writeln(N).
:- halt.