[m-users.] Returning a predicate from a function

Sean Charles (emacstheviking) objitsu at gmail.com
Fri Dec 23 01:32:06 AEDT 2022


Changing f_ln to:

:- func f_ln(pred(float)::(pred(out) is nondet)) = (pred(float)::(pred(out) is nondet)).
f_ln(Pred) = (pred(Y::out) is nondet :- Pred(X), Y = math.ln(X)).    %<====== you have 'is' here, not equals, possibly a Prolog relapse! :)

gives me this compiler output:

➜  tmp mmc -E tests.m
tests.m:025: In clause for `test2(di, uo)':
tests.m:025:   mode error in conjunction. The next 2 error messages indicate
tests.m:025:   possible causes of this error.
tests.m:025:
tests.m:024:   In clause for `test2(di, uo)':
tests.m:024:   in the return value of call to function `tests.f_ln'/1:
tests.m:024:   mode error: variable `LnData' has instantiatedness `free',
tests.m:024:   expected instantiatedness was `(pred(out) is nondet)'.
tests.m:025:
tests.m:025:   In clause for `test2(di, uo)':
tests.m:025:   in call to predicate `solutions.aggregate'/4:
tests.m:025:   mode error: arguments
tests.m:025:   `LnData, V_14, STATE_VARIABLE_IO_0, STATE_VARIABLE_IO' have the
tests.m:025:   following insts:
tests.m:025:     free,
tests.m:025:     /* unique */ (pred(in, di, uo) is det),
tests.m:025:     unique,
tests.m:025:     free
tests.m:025:   which does not match any of the modes for predicate
tests.m:025:   `solutions.aggregate'/4.
tests.m:025:   The first argument `LnData' has inst `free', which does not
tests.m:025:   match any of those modes.
tests.m:028: In clause for `f_ln((pred(out) is nondet)) = (pred(out) is
tests.m:028:   nondet)':
tests.m:028:   In unification of `HeadVar__2' with
tests.m:028:   `lambda([Pred::(pred(out) is nondet)] ... )':
tests.m:028:   mode error: attempt at higher-order unification.
tests.m:028:   Cannot unify two terms of type `(pred float)'.
tests.m:028:   Your code is trying to test whether two predicates are equal, by
tests.m:028:   unifying them. In the general case, testing equivalence of
tests.m:028:   predicates is an undecidable problem, and so this is not allowed
tests.m:028:   by the Mercury mode system. In some cases, you can achieve the
tests.m:028:   same effect by writing an explicit universal quantification,
tests.m:028:   e.g. `all [X] call(PredA, X) <=> call(PredB, X)', instead of
tests.m:028:   `PredA = PredB'.


Hopefully somebody else can help you resolve it, as I am sure that it can be done.



> On 22 Dec 2022, at 11:52, Mark Clements <mark.clements at ki.se> wrote:
> 
> Dear Mercury users,
> 
> Is there any way to write a function that takes a predicate and returns a transformed predicate without (a) naming a new predicate or (b) using a lambda? In practice, I would like to move the lambda to a function. However, the following code gives an error: "Cannot unify two terms of type `(pred float)'". Can I assume that this is outside of Mercury's mode system?
> 
> Sincerely, Mark.
> 
> -----
> 
> :- module tests.
> 
> :- interface.
> :- import_module io.
> :- pred main(io::di, io::uo) is det.
> 
> :- implementation.
> :- import_module float, ranges, solutions.
> :- use_module math.
> 
> main(!IO) :-
>     test1(!IO), % OK
>     test2(!IO). % Does not compile
> 
> :- pred test1(io::di, io::uo) is det.
> test1(!IO) :- 
>     Data = (pred(Y::out) is nondet :- nondet_member(I,range(1,5)), Y = float(I)), % some data
>     LnData = (pred(Y::out) is nondet :- Data(X), Y = math.ln(X)), % a transformation
>     aggregate(LnData, print_line, !IO).
> 
> :- pred test2(io::di, io::uo) is det.
> test2(!IO) :- 
>     Data = (pred(Y::out) is nondet :- nondet_member(I,range(1,5)), Y = float(I)), % some data
>     LnData = f_ln(Data), %% This transformation does not compile:(
>     aggregate(LnData, print_line, !IO).
> 
> :- func f_ln(pred(float)::(pred(out) is nondet)) = (pred(float)::(pred(out) is nondet)).
> f_ln(Pred) = (pred(Y::out) is nondet :- Pred(X), Y is math.ln(X)).
> 
> 
> 
> När du skickar e-post till Karolinska Institutet (KI) innebär detta att KI kommer att behandla dina personuppgifter. Här finns information om hur KI behandlar personuppgifter <https://ki.se/medarbetare/integritetsskyddspolicy>. 
> 
> Sending email to Karolinska Institutet (KI) will result in KI processing your personal data. You can read more about KI’s processing of personal data here <https://ki.se/en/staff/data-protection-policy>. 
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org <mailto:users at lists.mercurylang.org>
> https://lists.mercurylang.org/listinfo/users


> On 22 Dec 2022, at 11:52, Mark Clements <mark.clements at ki.se> wrote:
> 
> Dear Mercury users,
> 
> Is there any way to write a function that takes a predicate and returns a transformed predicate without (a) naming a new predicate or (b) using a lambda? In practice, I would like to move the lambda to a function. However, the following code gives an error: "Cannot unify two terms of type `(pred float)'". Can I assume that this is outside of Mercury's mode system?
> 
> Sincerely, Mark.
> 
> -----
> 
> :- module tests.
> 
> :- interface.
> :- import_module io.
> :- pred main(io::di, io::uo) is det.
> 
> :- implementation.
> :- import_module float, ranges, solutions.
> :- use_module math.
> 
> main(!IO) :-
>     test1(!IO), % OK
>     test2(!IO). % Does not compile
> 
> :- pred test1(io::di, io::uo) is det.
> test1(!IO) :- 
>     Data = (pred(Y::out) is nondet :- nondet_member(I,range(1,5)), Y = float(I)), % some data
>     LnData = (pred(Y::out) is nondet :- Data(X), Y = math.ln(X)), % a transformation
>     aggregate(LnData, print_line, !IO).
> 
> :- pred test2(io::di, io::uo) is det.
> test2(!IO) :- 
>     Data = (pred(Y::out) is nondet :- nondet_member(I,range(1,5)), Y = float(I)), % some data
>     LnData = f_ln(Data), %% This transformation does not compile:(
>     aggregate(LnData, print_line, !IO).
> 
> :- func f_ln(pred(float)::(pred(out) is nondet)) = (pred(float)::(pred(out) is nondet)).
> f_ln(Pred) = (pred(Y::out) is nondet :- Pred(X), Y is math.ln(X)).
> 
> 
> 
> När du skickar e-post till Karolinska Institutet (KI) innebär detta att KI kommer att behandla dina personuppgifter. Här finns information om hur KI behandlar personuppgifter <https://ki.se/medarbetare/integritetsskyddspolicy>. 
> 
> Sending email to Karolinska Institutet (KI) will result in KI processing your personal data. You can read more about KI’s processing of personal data here <https://ki.se/en/staff/data-protection-policy>. 
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org <mailto:users at lists.mercurylang.org>
> https://lists.mercurylang.org/listinfo/users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20221222/671f8555/attachment-0001.html>


More information about the users mailing list