Search code examples
prologgrammardcg

Learn Prolog Now! DCG Practice Example


I have been progressing through Learn Prolog Now! as self-study and am now learning about Definite Clause Grammars. I am having some difficulty with one of the Practical Session's tasks. The task reads:

The formal language anb2mc2mdn consists of all strings of the following form: an unbroken block of as followed by an unbroken block of bs followed by an unbroken block of cs followed by an unbroken block of ds, such that the a and d blocks are exactly the same length, and the c and d blocks are also exactly the same length and furthermore consist of an even number of cs and ds respectively. For example, ε, abbccd, and aaabbbbccccddd all belong to anb2mc2mdn. Write a DCG that generates this language.

I am able to write rules that generate andn, b2mc2m, and even anb2m and c2mdn... but I can't seem to join all these rules into anb2mc2mdn. The following are my rules that can generate andn and b2mc2m.

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

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

Is anb2mc2mdn really a CFG, and is it possible to write a DCG using only what was taught in the lesson (no additional arguments or code, etc)? If so, can anyone offer me some guidance how I can join these so that I can solve the given task?


Solution

  • @Timothy, your answer works, but it generates duplicates:

    ?- 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
    

    This can be fixed by removing one clause, leaving the DCG:

    s --> x.
    s --> a,s,d.
    
    x --> [].
    x --> b,b,x,c,c.
    
    % a, b, c, d the same
    

    This generates:

    ?- 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] ;