title: About building a list until it meets conditions
body: <p>I wanted to solve <a href="https://youtu.be/YeMVoJKn1Tg" rel="nofollow noreferrer">&quot;the giant cat army riddle&quot;</a> by Dan Finkel using Prolog.</p>
  <p>Basically you start with <code>[0]</code>, then you build this list by using one of three operations: adding <code>5</code>, adding <code>7</code>, or taking <code>sqrt</code>. You successfully complete the game when you have managed to build a list such that <code>2</code>,<code>10</code> and <code>14</code> appear on the list, in that order, and there can be other numbers between them.</p>
  <p>The rules also require that all the elements are distinct, they're all <code>&lt;=60</code> and are all only integers.
  For example, starting with <code>[0]</code>, you can apply <code>(add5, add7, add5)</code>, which would result in <code>[0, 5, 12, 17]</code>, but since it doesn't have 2,10,14 in that order it doesn't satisfy the game.</p>
  <p>I think I have successfully managed to write the required facts, but I can't figure out how to actually build the list. I think using <code>dcg</code> is a good option for this, but I don't know how.</p>
  <p>Here's my code:</p>
  <pre><code>:- use_module(library(lists)).
  :- use_module(library(clpz)).
  :- use_module(library(dcgs)).
  
  % integer sqrt
  isqrt(X, Y) :- Y #&gt;= 0, X #= Y*Y.
  
  % makes sure X occurs before Y and Y occurs before Z
  before(X, Y, Z) --&gt; ..., [X], ..., [Y], ..., [Z], ... .
  ... --&gt; [].
  ... --&gt; [_], ... .
  
  % in reverse, since the operations are in reverse too.
  order(Ls) :- phrase(before(14,10,2), Ls).
  
  % rule for all the elements to be less than 60.
  lt60_(X) :- X #=&lt; 60.
  lt60(Ls) :- maplist(lt60_, Ls).
  
  % available operations
  add5([L0|Rs], L) :- X #= L0+5, L = [X, L0|Rs].  
  add7([L0|Rs], L) :- X #= L0+7, L = [X, L0|Rs].
  root([L0|Rs], L) :- isqrt(L0, X), L = [X, L0|Rs].
  
  % base case, the game stops when Ls satisfies all the conditions.
  step(Ls) --&gt; { all_different(Ls), order(Ls), lt60(Ls) }.
  
  % building the list
  step(Ls) --&gt; [add5(Ls, L)], step(L).
  step(Ls) --&gt; [add7(Ls, L)], step(L).
  step(Ls) --&gt; [root(Ls, L)], step(L).
  
  </code></pre>
  <p>The code emits the following error but I haven't tried to trace it or anything because I'm convinced that I'm using DCG incorrectly:</p>
  <pre><code>?- phrase(step(L), X).
  caught: error(type_error(list,_65),sort/2)
  </code></pre>
  <p>I'm using Scryer-Prolog, but I think all the modules are available in <code>swipl</code> too, like <code>clpfd</code> instead of <code>clpz</code>.</p>