我正在尝试构建一个能够识别与此表单匹配的所有列表的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的方式有问题吗?
答案 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, []).
我知道这是一个古老的问题,但是也许从现在起有人会找到正确的答案。