[m-users.] Some help with understanding the mode system?

Anders Lundstedt mercury-users at anderslundstedt.se
Sat Jun 29 05:17:02 AEST 2024


Dear all,


I am struggling to understand the mode system. A MWE illustrating my problems
is below. Any help would be much appreciated! In particular, I would appreciate
pointers to relevant documentation, tutorials, et cetera. (I am new to Mercury
but have some experience with Prolog.)


MWE, with comments explaining my reasoning:

:- module ground_free_branches_error.

:- interface.

:- type t ---> a; b.

% implemented such that p(t₁,t₂) succeeds iff at least one of t₁ and t₂ unifies
% with a
:- pred p(t,t).

% for ground t₁ and t₂, p(t₂,t₂) succeeds iff a∈{t₁,t₂}
% thus p(in,in) ought to be semidet:
:- mode p(in,in) is semidet.

% for ground t₁ and free t₂, p(t₁,t₂) succeeds iff t₁ = a or t₂ unifies with a
% thus p(in,out) ought to be multi:
:- mode p(in,out) is multi.

% for reasons similar to the previous case, p(out,in) ought to be multi:
:- mode p(out,in) is multi.

% for free t₁ and t₂, p(t₁,t₂) always succeeds, with solutions:
% t₁ = a, t₂ = a
% t₁ = a, t₂ = b
% t₁ = b, t₂ = a
% thus p(out,out) ought to be multi:
:- mode p(out, out) is multi.

:- implementation.

p(a, _).
p(_, b).

% everything works if I change the implementation to:
%
% p(a,a).
% p(a,b).
% p(b,a).
%
% in this case this is doable, but:
% - if t had more constructors such a solution could become impractical
% - it might be the case that if t is extended with more constructors:
%   - the above working implementation might need to be updated, which is easy
%     to forget; while
%   - the implementation with wild cards might always work as intended when t
%     is extended


Compilation errors below. The compiler complains for all modes except p(in,in).
I understand the error messages, but I cannot square them with my conclusions
in the comments above.

ground_free_branches_error.m:032: In clause for `p(in, out)':
ground_free_branches_error.m:032:   mode mismatch in disjunction.
ground_free_branches_error.m:032:   The variable `HeadVar__2' is ground in some
ground_free_branches_error.m:032:   branches but not others.
ground_free_branches_error.m:031:     In this branch, `HeadVar__2' is free.
ground_free_branches_error.m:032:     In this branch, `HeadVar__2' is ground.
ground_free_branches_error.m:032: In clause for `p(out, in)':
ground_free_branches_error.m:032:   mode mismatch in disjunction.
ground_free_branches_error.m:032:   The variable `HeadVar__1' is ground in some
ground_free_branches_error.m:032:   branches but not others.
ground_free_branches_error.m:031:     In this branch, `HeadVar__1' is ground.
ground_free_branches_error.m:032:     In this branch, `HeadVar__1' is free.
ground_free_branches_error.m:032: In clause for `p(out, out)':
ground_free_branches_error.m:032:   mode mismatch in disjunction.
ground_free_branches_error.m:032:   The variable `HeadVar__1' is ground in some
ground_free_branches_error.m:032:   branches but not others.
ground_free_branches_error.m:031:     In this branch, `HeadVar__1' is ground.
ground_free_branches_error.m:032:     In this branch, `HeadVar__1' is free.
ground_free_branches_error.m:032:   The variable `HeadVar__2' is ground in some
ground_free_branches_error.m:032:   branches but not others.
ground_free_branches_error.m:031:     In this branch, `HeadVar__2' is free.
ground_free_branches_error.m:032:     In this branch, `HeadVar__2' is ground.



Best,

Anders Lundstedt


More information about the users mailing list