2010-06-08 147 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