问题 - 序言中的形式语言

时间:2011-01-03 23:39:30

标签: prolog grammar dcg

我正在尝试构建一个能够识别与此表单匹配的所有列表的DCG:a^n b^2m c^2m d^n 我写了以下规则:
s --> [].
s --> ad.
ad --> a, ad, d.
ad --> bc.
bc --> b, b, bc, c, c.
bc --> [].
a --> [a].
b --> [b].
c --> [c].
d --> [d].

当我尝试评估具有这些规范的字符串时,例如列表[a,b,b,c,c,d],它可以正常工作。但是当我尝试评估查询phrase(s, X)以便我可以看到这个语法返回的所有可能的字符串时,它会循环到无穷大。

我构建DCG的方式有问题吗?

4 个答案:

答案 0 :(得分:6)

您可以通过迭代深化来公平地枚举字符串:

?- length(Ls, _), phrase(s, Ls).
Ls = [] ;
Ls = [] ;
Ls = [a, d] ;
Ls = [a, a, d, d] ;
Ls = [b, b, c, c] ;
etc.

答案 1 :(得分:0)

我没有看到这个问题的序言部分。答案很大程度上取决于你如何实现这个语法。

我最好的猜测是颠倒规则的顺序,首先应用终止规则。

答案 2 :(得分:0)

我写这篇文章是为了帮助限制解决方案,即使有无限的解决方案。但我意识到有一种方法可以重新安排规则,以便首先获得更短的结果。

因为在ad --> a, ad, d.之前评估了ad --> bc.,它会在ad --> a, ad, a.之前尝试满足ad --> bc.。我会在ad --> bc.之前加ad --> a, ad, a.bc --> b, b, bc, c, c.bc --> [].规则

也是如此

正如arian指出的那样,首先应用终止规则,将确保首先找到更短的解决方案。

我还想指出[]和s - >有两种解决方案。广告 - > bc - > []我会消除s --> [].,因为它是多余的。

总而言之,我会尝试这个解决方案:

s --> ad.
a --> [a].
b --> [b].
c --> [c].
d --> [d].
ad --> bc.
bc --> [].
ad --> a, ad, d.
bc --> b, b, bc, c, c.

原始邮件:

我不得不查看如何进行计数(自从我做了prolog以来已经有一段时间了)但是有一个无限的数字,因为prolog试图找到所有解决方案它永远不会停止寻找,虽然我确定你会打在此之前堆栈过流或一些错误:)。

限制结果数量的一种方法是限制解决方案的大小

 phrase(s, X), length(X, 4).

获取具有4个值的所有解,即

X = [a, a, d, d]
X = [b, b, c, c]

增加到6会产生:

X = [a, a, a, d, d, d]
X = [a, b, b, c, c, d]

或使用范围:

 phrase(s, X), length(X, Y), Y >= 4 , Y < 10, Y != 6.

答案 3 :(得分:0)

@Simon使用DGC的方法是正确的,但是尝试中有两个问题。

第一个是您在以下子句中保留了递归:

ad --> a, ad, d.

这是循环到无穷大的原因之一。

第二个问题是,这种形式语言不能构建为上下文无关的语法,因此您需要一个额外的变量,例如count。

s(Count) --> a(Count),b(Count),c(Count),d(Count).
a(0) --> [].
a(succ(Count)) --> [a],a(Count).
b(0) --> [].
b(succ(Count)) --> [b,b],b(Count).
c(0) --> [].
c(succ(Count)) --> [c,c],c(Count).
d(0) --> [].
d(succ(Count)) --> [d],d(Count).

然后使用以下目标s(_, L, []).

对其进行查询

我知道这是一个古老的问题,但是也许从现在起有人会找到正确的答案。