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

"Sean Charles (emacstheviking)" <[email protected]>
Newsgroups gmane.comp.lang.mercury.general
Message-ID <[email protected]>
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.

_______________________________________________
users mailing list
[email protected]
https://lists.mercurylang.org/listinfo/users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.