[m-users.] Confused my det/multi error message, full disjunction of type in place.

Sean Charles (emacstheviking) objitsu at gmail.com
Sun Dec 4 21:35:46 AEDT 2022


Hi,

I am writing a code formatter, and I created a state object and some formatting instructions:

     24 :- type fi
     25     --->    nl
     26     ;       brace_o; brace_c        % indentation gets updated
     27     ;       s(string)
     28     ;       blk(list(fi))
     29     ;       csv(list(fi))
     30     ;       ssv(list(fi))
     31     ;       seq(fi, list(fi))
     32     .

     42 :- type fstate
     43     --->    fstate(
     44                 indent      :: int,
     45                 tab_size    :: int,
     46                 nl_written  :: bool
     47             ).


I have an aux., predicate that actually performs each instruction, but one of them, shown in bold, is giving me an error that I don't really understand and thus don't know how to get past, here is error message first:

formatter.m:059: In `write_'(in, out, in, di, uo):
formatter.m:059:   error: determinism declaration not satisfied.
formatter.m:059:   Declared `det', inferred `multi'.
formatter.m:059:   The reason for the difference is the following.
formatter.m:061:   Inside the case nl/0 of the switch on HeadVar__3:
formatter.m:061:   disjunction has multiple clauses with solutions.
formatter.m:062: In clause for `write_(in, out, in, di, uo)':
formatter.m:062:   in argument 1 of call to predicate `io.nl'/2:
formatter.m:062:   mode error: variable `STATE_VARIABLE_IO_0' has
formatter.m:062:   instantiatedness `mostly_unique',
formatter.m:062:   expected instantiatedness was `unique'.
formatter.m:062:   This kind of uniqueness mismatch is usually caused by doing
formatter.m:062:   input/output or some other kind of destructive update in a
formatter.m:062:   context where it can be backtracked over, such as the
formatter.m:062:   condition of an if-then-else.
and the full predicate code, I've highlighted the offending clause in bold:


And the code, I just don't understand, as usual, what the compiler is trying to tell me. The io.nl/2 is det, so that can't fail, and presumably the field update can't fail either. And why hasn't this error been raised on all the other cases?


     59 :- pred write_(fstate::in, fstate::out, fi::in, io::di, io::uo) is det.
     60
     61 write_(!S, nl, !IO) :-
     62     io.nl(!IO),
     63     !:S = !.S ^nl_written := yes.
     64
     65 write_(!S, brace_o, !IO) :-
     66     write_(!S, s("{"), !IO),
     67     !:S = !.S ^tab_size := !.S ^tab_size+1.
     68     write_(!S, nl, !IO).
     69
     70 write_(!S, brace_c, !IO) :-
     71     write_(!S, s("}"), !IO),
     72     !:S = !.S ^tab_size := !.S ^tab_size-1.
     73
     74 write_(!S, s(Text), !IO) :-
     75     io.print(Text, !IO).
     76
     77 write_(!S, blk(FIs), !IO) :-
     78     P = (pred(FI::in, !.St::in, !:St::out, !.IO::di, !:IO::uo) is det :-
     79         write_(!St, FI, !IO)
     80     ),
     81     list.foldl2(P, FIs, !S, !IO).
     82
     83 write_(!S, csv(FIs), !IO) :-
     84     write_(!S, seq(s(", "), FIs), !IO).
     85
     86 write_(!S, ssv(FIs), !IO) :-
     87     write_(!S, seq(s(" "), FIs), !IO).
     88
     89 write_(!_, seq(_, []), !IO).
     90 write_(!S, seq(With, [ FI | FIs ]), !IO) :-
     91     write_(!S, FI, !IO),
     92     ( if list.is_empty(FIs) then
     93         true
     94     else
     95         write_(!S, With, !IO),
     96         write_(!S, seq(With, FIs), !IO)
     97     ).


I think will be a good one to learn from!

Thanks,
Sea.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20221204/00f22bff/attachment.html>


More information about the users mailing list