2012-11-25 80 views
2

我目前正在編寫一個,它採用[0,1] *形式的列表,並告訴我列表中的0的數量是否大於1的數量3。我似乎無法得到第三部分(dcg//0)的工作。識別DCG中的圖案

sq --> []. 
sq --> num, sq. 

num --> [0]. 
num --> [1]. 

dcg --> sq, dd(Count), Count > 2. 

dd(0) --> []. 
dd(Newcnt) --> [0], dd(Cnt), { Newcnt is Cnt+1 }. 
dd(Newcnt) --> [1], dd(Cnt), { Newcnt is Cnt-1 }. 

回答

0

以下代碼計算給定序列中零和1的個數。你可以用它來應用你想要的任何條件。

sq(0, 0) --> []. 
sq(Zeros, Ones) --> 
    [0], 
    sq(Z, Ones), 
    {Zeros is Z + 1}. 
sq(Zeros, Ones) --> 
    [1], 
    sq(Zeros, O), 
    {Ones is O + 1}. 
1

通過@Little鮑比表答案synthetizes(計數)的元素個數,和「外部」的DCG你需要測試結果

..., phrase(sq(Z,O), S), Z is O*3, ... 

更簡單的方法可能是通過降不平衡

z3o1(B) --> [1], {S is B-3}, z3o1(S). 
z3o1(B) --> [0], {S is B+1}, z3o1(S). 
z3o1(0) --> []. % accept only if balanced 

..., phrase(z3o1(0), S), ... 
1

幾乎沒有......事實上,代碼是存在的,我們把它用!

:- use_module(library(clpfd)). 

運行dd//1phrase/2我們得到:

?- C#>= 3, phrase(dd(C), Xs). 
    C = 3, Xs = [0,0,0] 
; C = 4, Xs = [0,0,0,0] 
; C = 5, Xs = [0,0,0,0,0] 
; C = 6, Xs = [0,0,0,0,0,0] 
; C = 7, Xs = [0,0,0,0,0,0,0] 
; C = 8, Xs = [0,0,0,0,0,0,0,0] 
; C = 9, Xs = [0,0,0,0,0,0,0,0,0] 
... 

在哪裏含1序列?我們知道,他們必須存在 ...

 
?- Xs = [0,0,0,1,0], C#>= 3, phrase(dd(C), Xs). 
Xs = [0,0,0,1,0], C = 3 
; false. 

...但他們出現在上面的回答順序:

 
?- C#>= 3, phrase(dd(C), Xs), Xs = [0,0,0,1,0]. 
**LOOPS** 

要強制解集公平枚舉,我們可以使用目標length/2像這樣:

 
?- C#>= 3, length (Xs, _), phrase(dd(C), Xs). 
    C = 3, Xs = [0,0,0] 
; C = 4, Xs = [0,0,0,0] 
; C = 5, Xs = [0,0,0,0,0] 
; C = 3, Xs = [0,0,0,0,1] 
; C = 3, Xs = [0,0,0,1,0] 
; C = 3, Xs = [0,0,1,0,0] 
; C = 3, Xs = [0,1,0,0,0] 
; C = 3, Xs = [1,0,0,0,0] 
; C = 6, Xs = [0,0,0,0,0,0] 
...