prolog-dcg限制

prolog-dcg限制,prolog,dcg,failure-slice,Prolog,Dcg,Failure Slice,我想使用DCGs作为发电机。到目前为止,语法是 s-->a,b. a-->[]. a-->a,c. c-->[t1]. c-->[t2]. b-->[t3]. b-->[t4]. 我想生成所有s,其中a的长度是a,…必须更改!事实上,将其改为a-->c,s解决了这个问题 你当初为什么写a-->a,c.?我怀疑你想以公平的方式列举所有的解决方案。新版本没有: ?- phrase(a,X). X = [] ; X = [t1] ; X = [t1, t1]

我想使用DCGs作为发电机。到目前为止,语法是

s-->a,b.
a-->[].
a-->a,c.
c-->[t1].
c-->[t2].
b-->[t3].
b-->[t4].
我想生成所有
s
,其中
a
的长度是

使用
?-短语(a,X),长度(X,Y),Yc,a.

非终结符a//0是左递归的和“epsilon”(生成空序列),短语/2将在空生成后立即循环

您可以解决边界列表长度的问题:

?- between(1,4,Y),length(X,Y),phrase(a,X).

而且,正如您已经做的那样,删除左递归。

进入Prolog的第一步通常有点困难。但你走的是对的:

目前,您的问题是,您得到了一些预期的答案/解决方案,但随后系统暂停;事实上,它是在一个无限循环中。你通过耐心地敲击太空发现了这一点。这可能只适用于一小部分解决方案,但对于一个更大的解决方案,这将是乏味的。想想看所有少于20句的句子

有一个简单的键盘和腕管友好的方式来模拟击球空间:只需在最后添加一个目标,如下所示:

?- phrase(a,X),length(X,Y),Y<4, false. 为了使其更具可读性,我将只使用一个
false
目标并遍历查询的其余部分:

?- phrase(a,X),length(X,Y),false, Y<4. **LOOPS** 这样行吗?只要看看第一个循环的目标:

?- length(X,Y), false, phrase(a,X), Y<4. 您可能会想看看实际的答案:

?- between(1,3,Y), length(X,Y), phrase(a,X). Y = 1, X = [t1] ; Y = 1, X = [t2] ; ERROR: Out of local stack
几乎所有的代码库都属于
false
!因此,你必须解决微小可见的剩余部分。在别的地方改变一些东西是没有意义的。此
a-->a,…
必须更改!事实上,将其改为
a-->c,s
解决了这个问题

你当初为什么写
a-->a,c.
?我怀疑你想以公平的方式列举所有的解决方案。新版本没有:

?- phrase(a,X). X = [] ; X = [t1] ; X = [t1, t1] ; X = [t1, t1, t1] ; X = [t1, t1, t1, t1] ; X = [t1, t1, t1, t1, t1] ; X = [t1, t1, t1, t1, t1, t1] ; X = [t1, t1, t1, t1, t1, t1, t1] ... -短语(a,X)。 X=[]; X=[t1]; X=[t1,t1]; X=[t1,t1,t1]; X=[t1,t1,t1,t1]; X=[t1,t1,t1,t1,t1]; X=[t1,t1,t1,t1,t1,t1,t1]; X=[t1,t1,t1,t1,t1,t1,t1,t1]。。。 那看起来很吓人。事实上,这看起来是错误的。不是吗?但不要让你被这搞糊涂了:我们这里有一组无限的句子。因此,Prolog唯一正确的反应是产生无限多的答案。因为,如果它们是有限的,一些列表就会丢失!当然,你希望看到他们以公平的方式被列举出来。要了解这一点,只需写下:

?- length(X,N), phrase(a,X). X = [], N = 0 ; X = [t1], N = 1 ; X = [t2], N = 1 ; X = [t1, t1], N = 2 ; X = [t1, t2], N = 2 ; X = [t2, t1], N = 2 ; X = [t2, t2], N = 2 ; X = [t1, t1, t1], N = 3 ... -长度(X,N),短语(a,X)。 X=[], N=0; X=[t1], N=1; X=[t2], N=1; X=[t1,t1], N=2; X=[t1,t2], N=2; X=[t2,t1], N=2; X=[t2,t2], N=2; X=[t1,t1,t1], N=3。。。 这是Prolog程序中的一个要点:始终首先选择最佳(可能的)终止属性。不要看Prolog列举答案的精确顺序。因为,如果一个程序具有更好的终止属性,那么使用它以公平的方式枚举所有解决方案几乎是微不足道的。但是:一个以终止为代价以公平方式列举无限多个解的程序不能用于更有趣的情况


精细印刷

我删除了答案,因为答案错了。在我调试时,您自己发现了这个问题……“您的所有代码库都属于false”可能是我在关于StackOverflow的序言回答中读到的最好的语句。谢谢你的微笑 ?- between(1,3,Y), length(X,Y), false, phrase(a,X). false. ?- between(1,3,Y), length(X,Y), phrase(a,X), false. **LOOPS** ?- between(1,3,Y), length(X,Y), phrase(a,X). Y = 1, X = [t1] ; Y = 1, X = [t2] ; ERROR: Out of local stack ?- between(1,3,Y), length(X,Y), phrase(a,X), false s--> {false}, a,b. a-->[], {false}. a-->a,{false}, c. c-->{false}, [t1]. c-->{false}, [t2]. b-->{false}, [t3]. b-->{false}, [t4]. ?- phrase(a,X). X = [] ; X = [t1] ; X = [t1, t1] ; X = [t1, t1, t1] ; X = [t1, t1, t1, t1] ; X = [t1, t1, t1, t1, t1] ; X = [t1, t1, t1, t1, t1, t1] ; X = [t1, t1, t1, t1, t1, t1, t1] ... ?- length(X,N), phrase(a,X). X = [], N = 0 ; X = [t1], N = 1 ; X = [t2], N = 1 ; X = [t1, t1], N = 2 ; X = [t1, t2], N = 2 ; X = [t2, t1], N = 2 ; X = [t2, t2], N = 2 ; X = [t1, t1, t1], N = 3 ...