2012-11-25 43 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] 
...