<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <font face="Courier New, Courier, monospace">In the current ROTD
      Reference manual, chapter 8.3.1 on 'Building higher-order insts
      and modes', the inst/mode of higher-order predicates is defined as
      follows:<br>
    </font>
    <blockquote>
      <p><font size="-1" face="Courier New, Courier, monospace">"If you
          want to define a predicate which returns a higher-order
          predicate term,</font></p>
      <font size="-1" face="Courier New, Courier, monospace"> you would
        use a mode such as ‘<samp>free >> pred(…) is …</samp>’,
        or ‘<samp>out(pred(…) is … )</samp>’.
        For example:
      </font><font size="-1" face="Courier New, Courier, monospace"><br>
      </font>
      <div class="example">
        <font size="-1" face="Courier New, Courier, monospace"><br>
           :- pred foo(pred(int)). <br>
        </font></div>
      <div class="example"><font size="-1" face="Courier New, Courier,
          monospace"> :- mode foo(free >> pred(out) is det) is
          det. <br>
        </font></div>
      <div class="example"><font size="-1" face="Courier New, Courier,
          monospace"><br>
        </font></div>
      <div class="example"><font size="-1" face="Courier New, Courier,
          monospace"> foo(sum([1,2,3]))."</font></div>
      <div class="example"><font face="Courier New, Courier, monospace"><br>
        </font></div>
    </blockquote>
    <div class="example"><font face="Courier New, Courier, monospace">Apparently
        though, at least from 20.06 on (not checked before), the 'free
        >>' part of of higher-order inst/mode declaration is
        outdated and causes compiler errors. The following Mercury chunk
        code compiles and runs OK:</font></div>
    <div class="example"><font face="Courier New, Courier, monospace"><br>
      </font></div>
    <blockquote>
      <div class="example">
        <pre><font size="-1" face="Courier New, Courier, monospace">:- module new. </font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">:- interface.      </font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">:- import_module io.  </font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">:- pred main(io::di, io::uo) is det.</font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">
:- implementation.</font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">:- import_module string, int.

</font></pre>
      </div>
      <div class="example">
        <pre><font size="-1" face="Courier New, Courier, monospace">:- pred check_10(pred(string, int), string).</font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">:- mode check_10(pred(in, out) is det, in) is semidet.  
                                                                                                                                     </font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">check_10(Predicate, S) :- call(Predicate, S, L), L < 10. </font></pre>
        <pre><font size="-1" face="Courier New, Courier, monospace">main(!IO) :- ( if check_10((pred(S::in, L::out) is det :- length(S, L)), "test_str")</font></pre>
      </div>
      <div class="example">
        <pre><font size="-1" face="Courier New, Courier, monospace">             then  write_string("OK!", !IO) else<font size="-1"> write_string("NO!", !IO)).  </font></font></pre>
      </div>
    </blockquote>
    <div class="example"><font face="Courier New, Courier, monospace"><br>
      </font></div>
    <div class="example"><font face="Courier New, Courier, monospace">Replacing
        'pred(in, out)' with 'free >> pred(in, out)'  in the above
        mode declaration for 'check_10' causes a compiler (20.06 or DEV)
        error msg:</font></div>
    <blockquote>
      <div class="example"><br>
      </div>
      <div class="example"><font size="-1" face="Courier New, Courier,
          monospace">Error: no mode declaration for predicate
          `check_10'/2.<br>
             (Use `--infer-modes' to enable mode inference.) <br>
           Inferred :- mode check_10(di(/* unique */(pred(in, out) is
          det)),  
di).                                                                                                                                                                             
          <br>
          In the mode declaration of the predicate `check_10': error: a<br>
           higher-order mode should have one of the following forms:<br>
            `pred(<mode1>, ...) is <detism>'<br>
             `any_pred(<mode1>, ...) is <detism>' <br>
             `func(<mode1>, ...) = <return_mode> is
          <detism>' <br>
             `any_func(<mode1>, ...) = <return_mode> is
          <detism>'<br>
        </font></div>
      <div class="example"><font size="-1" face="Courier New, Courier,
          monospace"><br>
        </font></div>
    </blockquote>
    <div class="example"><font face="Courier New, Courier, monospace">Also,
        for independent reasons, the example given in the manual
        (foo(sum[1,2,3])) does not compile. It triggers a "higher-order
        predicate unification error", but this is more understandable
        and can be fixed by changing the example. <br>
      </font></div>
    <div class="example"><font face="Courier New, Courier, monospace">Unless
        I am mistaken or doing something wrong, a reference manual
        update would perhaps be appropriate.</font></div>
    <div class="example"><font face="Courier New, Courier, monospace"><br>
      </font></div>
    <div class="example"><font face="Courier New, Courier, monospace">F.
        Nicol<br>
      </font></div>
    <blockquote>
      <div class="example"><font size="-1" face="Courier New, Courier,
          monospace"><br>
        </font></div>
      <div class="example"><font size="-1" face="Courier New, Courier,
          monospace"><br>
        </font></div>
    </blockquote>
  </body>
</html>