2010-06-08 155 views
5

我一直在通过Learn Prolog Now!进行自学,现在我正在学习有关定义语句的文法。我在实际会议的任务中遇到了一些困难。 The task读取:立即学习Prolog! DCG练习示例

正式语言Ñ b 2米Ç2米 d Ñ由下列形式的所有字符串的:依次不间断的块的一个秒的完整块 b的随后的ç秒的完整块,随后的 d秒的完整块, S,从而使所述一个 d块是完全相同的长度,并且Ç d块也完全一样的长度和分别小号还包括一个偶数的Ç S和 d的。例如,ε abbccd,和 aaabbbbccccddd都属于一个Ñ b 2米Ç2米 d Ñ。写一个生成这种语言的DCG。

我能够编写生成ň d ñ规则,B 2米Ç2米,甚至ň b 2米和c 2米 d ñ ...但我似乎无法将所有这些规则加入到n b 2m c 2m d n。以下是我的规则,可以生成n d n和b 2m c 2m

s1 --> []. 
s1 --> a,s1,d. 
a --> [a]. 
d --> [d]. 

s2 --> []. 
s2 --> c,c,s2,d,d. 
c --> [c]. 
d --> [d]. 

是一个ň b 2米Ç2米 d ň真的CFG,并有可能只使用了什么的教训教(没有额外的参数或代码写DCG等)?如果是这样,任何人都可以提供一些指导我如何加入这些,以便我可以解决给定的任务?

回答

5

@Timothy,你的答案的工作,但它会产生重复:

?- length(S,_), s(S,[]). 
S = [] ; 
S = [a, d] ; 
S = [a, d] ;   % XXX 
S = [b, b, c, c] ; 
S = [a, a, d, d] ; 
S = [a, a, d, d] ;  % XXX 

这样就可以消除一个条款是固定的,留下DCG:

s --> x. 
s --> a,s,d. 

x --> []. 
x --> b,b,x,c,c. 

% a, b, c, d the same 

这产生:

?- length(S,_), s(S,[]). 
S = [] ; 
S = [a, d] ; 
S = [b, b, c, c] ; 
S = [a, a, d, d] ; 
S = [a, b, b, c, c, d] ; 
S = [a, a, a, d, d, d] ; 
S = [b, b, b, b, c, c, c, c] ; 
S = [a, a, b, b, c, c, d, d] ; 
S = [a, a, a, a, d, d, d, d] ; 
0

如何像:

n(L,N) --> n(L,N,0). 

n(_,N,N) --> [], !. 
n(L,N,K) --> L, {K1 is K + 1}, n(L, N, K1). 

abbccd(N,M) --> 
    {M1 is 2*M}, 
    n("a",N), 
    n("b",M1), 
    n("c",M1), 
    n("d",N). 

gen :- 
    forall((
      between(1,4,N), 
     between(1,4,M), 
     phrase(abbccd(N,M),S), 
     string_to_atom(S,A) 
      ), 
      writeln(A)). 

执行:

?- gen. 
abbccd 
abbbbccccd 
abbbbbbccccccd 
abbbbbbbbccccccccd 
aabbccdd 
aabbbbccccdd 
aabbbbbbccccccdd 
aabbbbbbbbccccccccdd 
aaabbccddd 
aaabbbbccccddd 
aaabbbbbbccccccddd 
aaabbbbbbbbccccccccddd 
aaaabbccdddd 
aaaabbbbccccdddd 
aaaabbbbbbccccccdddd 
aaaabbbbbbbbccccccccdddd 
true. 
+0

谢谢Xonix。这是有效的,但不幸的是它使用的概念直到后来才被覆盖(代码块,剪切等)。我诚实地认为仅仅使用简单的规则是不可能的,或者如果是这样,这是不值得的,因为在“现实世界”中,人们会利用其他概念,像你在样本中做的那样。 – Timothy 2010-06-08 19:58:10

3

我相信我想通了...

s --> x. 
s --> a,d. 
s --> a,s,d. 

x --> []. 
x --> b,b,x,c,c. 

a --> [a]. 
b --> [b]. 
c --> [c]. 
d --> [d]. 

?- s([],[]). 
Yes 

?- s([a,b,c,c,d],[]). 
No 

?- s([a,a,a,b,b,c,c,d,d,d],[]). 
Yes 

这是一件有趣的事情看的解决方案,并认为,“我绞尽脑汁想了?”但我想这是学习新东西的乐趣的一半,特别是当它像逻辑程序来自命令式编程背景时。

+1

这很难,但是有回报。逻辑编程(和惰性FP)知识esp。在C++,Java和Python中学习迭代器概念时为我服务。 – 2010-07-07 21:54:58