title: Prolog: DCGS - Converting numbers to English
body: <p>I'm practicing using DCGs in Prolog.  I take an integer like 123, 'explode' it into a list i.e. [1,2,3] and then I want to use DCG rules to get the output one-two-three.  So far I can convert a list of one integer e.g. [1] into one but I don't know what to do when it comes to a list.  I want to use DCGs as much as possible really as this is what I am practicing.  Here's my current code:</p>
  
  <pre><code>tests( 1, [1] ).
  tests( 2, [67] ).
  tests( 3, [183] ).
  tests( 4, [999] ).  
  
  numToEng( N, Res ) :-
      tests( N, W ),
      print( 'test: ' ),print( W ),nl,
      explode( W, Exploded ),
      print( 'exploded: ' ),print( Exploded ),nl,
      phrase( num(Res), Exploded ).
  
  explode( N, Explosion ) :-
      explode( N, [], Explosion ).
  explode( 0, Explosion, Explosion ) :- !.    
  explode( N, Inter, Explosion ) :- 
      Test is N mod 10, 
      NewN0 is  N - Test,
      NewN1 is NewN0//10, 
      explode( NewN1, [Test|Inter], Explosion ).
  
  num( X ) --&gt; digit( X ).    
  
  digit(zero) --&gt; [0].
  digit(one) --&gt; [1].
  digit(two) --&gt; [2].
  digit(three) --&gt; [3].
  digit(four) --&gt; [4].
  digit(five) --&gt; [5].
  digit(six) --&gt; [6].
  digit(seven) --&gt; [7].
  digit(eight) --&gt; [8].
  digit(nine) --&gt; [9].
  </code></pre>
  
  <p>A possible solution WITHOUT using DCGs is what I've written before but I'm wondering how to write it using DCGs.</p>
  
  <pre><code>% test cases, called by numToEng/2
  tests( 1, [1] ).
  tests( 2, [67] ).
  tests( 3, [183] ).
  tests( 4, [999] ).
  
  % dictionary
  digit(0,zero).
  digit(1,one).
  digit(2,two).
  digit(3,three).
  digit(4,four).
  digit(5,five).
  digit(6,six).
  digit(7,seven).
  digit(8,eight).
  digit(9,nine).
  
  % take an integer e.g. 123 and explode it
  % into a list i.e. [1,2,3]
  explode( N, Explosion ) :-
      explode( N, [], Explosion ).
  explode( 0, Explosion, Explosion ) :- !.    
  explode( N, Inter, Explosion ) :- 
      Test is N mod 10, 
      NewN0 is  N - Test,
      NewN1 is NewN0//10, 
      explode( NewN1, [Test|Inter], Explosion ).
  
  % take a number in digits and convert it
  % into english e.g. [1,2,3] would be
  % [one,two,three]   
  numToEng( N, Res ) :-
      tests( N, Test ),
      explode( Test, Exploded ),
      numToEng( N, Exploded, [], Res ).
  numToEng( _, [], Rev, Res ) :-
      reverse( Rev, Res ).
  numToEng( N, [H|T], Inter, Res ) :-
      digit( H, Word ),
      numToEng( N, T, [Word|Inter], Res ).
  </code></pre>