问题 - 序言中的形式语言
我正在尝试构建一个 DCG,它可以识别与此形式匹配的所有列表:a^nb^2m c^2m d^n
。
我写下了以下规则:
<代码>s --> [].
<代码>s -->广告。广告 --> a、ad、d。
广告 -->公元前。
<代码>BC --> b、b、bc、c、c。
<代码>BC --> [].一个 --> [一]。
<代码>b --> [b].
<代码>c --> [c].
<代码>d --> [d].
当我尝试使用这些规范评估字符串时,例如列表[a,b,b,c,c,d]
,它可以工作。但是,当我尝试评估查询短语(s,X)以便我可以看到此语法返回的所有可能的字符串时,它会无限循环。
我构建 DCG 的方式有问题吗?
I am trying to build a DCG which recognizes all lists which match this form : a^n b^2m c^2m d^n
.
I have written up the following rules:s --> [].
s --> ad.
ad --> a, ad, d.
ad --> bc.
bc --> b, b, bc, c, c.
bc --> [].
a --> [a].
b --> [b].
c --> [c].
d --> [d].
When I try to evaluate a string with those specifications, like the list [a,b,b,c,c,d]
, it works. But when I try to evaluate the query phrase(s, X)
so that I can see all the possible strings returned by this grammar, it loops to infinity.
Is there something wrong with the way I have build the DCG?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以通过迭代加深来公平地枚举字符串:
You can enumerate the strings fairly with iterative deepening:
@Simon 使用 DGC 的方法是正确的,但您的尝试存在两个问题。
第一个是您在如下子句中保留了递归:
这就是它循环到无穷大的原因之一。
第二个问题是这种形式语言无法构建为上下文无关语法,因此您需要一个额外的变量,例如 count。
然后使用以下目标
s(_, L, []) 进行查询。
我知道这是一个老问题,但也许从现在开始有人会发现正确的答案很有用。
@Simon the approach of using DGCs is correct but there are two issues in your attempt.
The first one is that you have left recursion in clauses like the following:
And this is one of the reasons why it loops to infinity.
The second issue is that this formal language cannot be built as a context free grammar, therefore you need an extra variable such as count.
Then query it using the following goal
s(_, L, []).
I know this is an old question but maybe someone finds the correct answer useful from now on.
我没有看到这个问题的序言部分。答案很大程度上取决于你如何实现这个语法。
我最好的猜测是颠倒规则的顺序,首先应用终止规则。
I don't see the prolog part of this question. The answer highly depends on how you implemented this grammar.
My best guess would be to reverse the order of the rules, to have the terminating rules applied first.
我写这篇文章是为了帮助限制解决方案,即使有无限的解决方案。但我意识到有一种方法可以重新排列规则以首先获得更短的结果。
因为
ad --> a, ad, d.
在ad -->; 之前评估bc.
它试图满足ad --> a, ad, a.
在ad --> 之前公元前。
。我会放ad --> bc. 位于
ad 之前 -->一个,广告,一个。
。bc 也是如此 --> b、b、bc、c、c。
和bc --> [].
规则正如 arian 指出的那样,首先应用终止规则,将确保首先找到较短的解决方案。
我还想指出的是
[]
s 和 s -> 有两种解决方案广告-> BC-> [] 我会消除s --> [].
因为它是多余的。总而言之,我会尝试这个解决方案:
原始帖子:
我必须查找如何进行计数(自从我做序言以来已经有一段时间了)但是数量是无限的,并且由于序言试图找到所有解决方案,它永远不会停止寻找,尽管我确信在此之前您会遇到堆栈溢出或一些错误:)。
限制结果数量的一种方法是限制解的大小
获取恰好具有 4 个值的所有解,将其
增加到 6 将产生:
或使用范围:
I wrote this as a way to help limit solutions even though there are infinite solutions. But I realized there would be a way to rearrange the rules to get shorter results first.
Because
ad --> a, ad, d.
is evaluated beforead --> bc.
it tries to satisfyad --> a, ad, a.
beforead --> bc.
. I would putad --> bc.
beforead --> a, ad, a.
. The same goes for thebc --> b, b, bc, c, c.
andbc --> [].
rulesAs arian pointed out have the terminating rules applied first, would ensure the shorter solutions are found first.
I also want to point out that there are two solutions for
[]
s and s -> ad -> bc -> [] I would eliminates --> [].
as it's redundant.All in all I would try this solution:
ORIGINAL POST:
I had to look up how to do counting (it's been a while since I did prolog) But there are an infinite number and since prolog tries to find all solutions it never stops looking, although I'm sure you'll hit a stack over flow or some error before then :).
One way to limit the number of results is to limit the size of the solution
Gets all solutions with exactly 4 values, which would be
increasing to 6 would yield:
Or use ranges: