[m-users.] Some help with understanding the mode system?
Volker Wysk
post at volker-wysk.de
Sat Jun 29 08:29:13 AEST 2024
Hi, Anders
Let's shrink your program to this:
:- module ground_free_branches_error_1.
:- interface.
:- type t ---> a; b.
:- pred p(t,t).
:- mode p(in,out) is multi.
:- implementation.
p(a, _).
%p(_, b).
I find three errors in this code.
1. The second argument of p is declared to be an output variable. That means
it must be bound. But the above code, it's free.
2. When you add the clause "p(_, b)" to the above, shrinked version, you get
the message which you're mentioned. That's because the instantiatedness of
the variables in a disjunction must match between the branches. (The two
clauses are a disjunction.) I wouldn't make sense to have two branches with
different instantiations, because the mode predefines the one and only mode
of the argument.
3. The compiler doesn't enumerate the constructors of a data type and bind
them to a free variable. You have to explicitly bind all the constructors
when you want that.
Here's an improved version the implementation section:
:- implementation.
:- pred any_of_t(t::out) is multi.
any_of_t(a).
any_of_t(b).
p(a, B) :- any_of_t(B).
p(_, b).
This compiles, except for there not being any main predicate.
Cheers,
Volker
Am Freitag, dem 28.06.2024 um 21:17 +0200 schrieb Anders Lundstedt:
> 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
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/users
More information about the users
mailing list