>>450
まず最初に、コードの解説から
これは>>449で書いた最初のケースの具体例で、手続き的な2重ループ処理だね
述語between/3はバックトラックで再呼び出しされるたびに別の解を返すから、
その between(1, MX, I), between(1, MY, J), ...., fail. という部分は、
以下のCコードの処理と似ている
 for (i = 1; i <= mx; i++) {
   for (j = 1; j <= my; j++)
     ....
 }
バックトラックは、initCells :- ... の最後のfail呼び出しを契機に発生し、
between x2が返す全ての解を探索し終えると(=二重ループ処理を抜けると)否定を返す
でも、(>>450で書いたように)initCells全体の処理は肯定で終わらせたいから、
最後にbody部が空な(=常に真を返す) initCells. が置かれてる
Prologでしばしば見かける手続き的なコーディング技法だね(自分は好まないけど....)

次に、質問について答えよう
>・initCells :- hogehoge.のあとinitCells.と書いているので
> goの中でinitCellsを改めて呼び出す必要はないのでは?

initCells定義のbody内でinitCellsが(再帰的に)呼ばれているのは、ループ処理を実現するため
だから、そのループを開始するきっかけとしてgoからinitCellsの呼び出しが必要になる

>・initCellsは常に否定で終わるのに、goの中の以降の処理が実行されているのはなぜ?

最後に置かれた(body部が空の)initCells定義が、常に肯定(真)を返すから