[m-users.] Reference manual 8.3.1, higher-order inst
Julien Fischer
jfischer at opturion.com
Sat Apr 17 03:43:36 AEST 2021
Hi,
On Fri, 16 Apr 2021, fabrice nicol wrote:
> 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:
>
> "If you want to define a predicate which returns a higher-order predicate term,
>
> you would use a mode such as ‘free >> pred(…) is …’, or ‘out(pred(…) is … )’. For example:
>
> :- pred foo(pred(int)).
> :- mode foo(free >> pred(out) is det) is det.
>
> foo(sum([1,2,3]))."
>
> 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 mode declaration in the example is missing some parentheses.
It should be:
:- mode foo(free >> (pred(out) is det)) is det.
(The parentheses are required because >> binds more strongly than is.)
However, it would be more usual to write the above as:
:- mode foo(out(pred(out) is det)) is det.
> The following Mercury chunk code compiles and runs OK:
>
> :- module new.
>
> :- interface.
>
> :- import_module io.
>
> :- pred main(io::di, io::uo) is det.
>
> :- implementation.
>
> :- import_module string, int.
>
> :- pred check_10(pred(string, int), string).
>
> :- mode check_10(pred(in, out) is det, in) is semidet.
>
>
> check_10(Predicate, S) :- call(Predicate, S, L), L < 10.
>
> main(!IO) :- ( if check_10((pred(S::in, L::out) is det :- length(S, L)), "test_str")
>
> then write_string("OK!", !IO) else write_string("NO!", !IO)).
>
>
> 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:
>
> Error: no mode declaration for predicate `check_10'/2.
> (Use `--infer-modes' to enable mode inference.)
> Inferred :- mode check_10(di(/* unique */(pred(in, out) is det)), di).
>
> In the mode declaration of the predicate `check_10': error: a
> higher-order mode should have one of the following forms:
> `pred(<mode1>, ...) is <detism>'
> `any_pred(<mode1>, ...) is <detism>'
> `func(<mode1>, ...) = <return_mode> is <detism>'
> `any_func(<mode1>, ...) = <return_mode> is <detism>'
Same issue. You'll obviously still get an error once you add
the parentheses since the resulting predicate is not mode correct.
> 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.a
The above definitely won't compile since it should be sum([1, 2, 3]) not
sum[1, 2, 3]. With the parentheses added to the mode declaration and
an appropriate definition of sum/2, the verison in the reference manual
compiles,
I'm not quite sure how you arrived at the higher-order unification
error, possibly by changing the mode of the first argument to be an input?
> Unless I am mistaken or doing something wrong, a reference manual
> update would perhaps be appropriate.
Indeed, we'll correct it.
Julien.
More information about the users
mailing list