识别DCG中的模式

时间:2012-11-25 11:51:31

标签: list prolog dcg

我目前正在撰写,其中包含表单[0,1] *的列表,并告诉我列表中0的数量是否大于3 1的数量。我似乎无法使第三部分(dcg//0)起作用。

 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 }.

3 个答案:

答案 0 :(得分:1)

@Little Bobby Tables的答案合成(计数)元素数量,以及测试结果所需的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 :(得分:1)

几乎就在那里......事实上,代码就在那里,让我们来使用它!

:- use_module(library(clpfd)).

dd//1一起运行phrase/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]
...

答案 2 :(得分: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}.