<html><head><meta http-equiv="content-type" content="text/html; charset=us-ascii"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hi,<div><br></div><div>I am writing a code formatter, and I created a state object and some formatting instructions:</div><div><br></div><div><div>     24 :- type fi</div><div>     25     --->    nl</div><div>     26     ;       brace_o; brace_c        % indentation gets updated</div><div>     27     ;       s(string)</div><div>     28     ;       blk(list(fi))</div><div>     29     ;       csv(list(fi))</div><div>     30     ;       ssv(list(fi))</div><div>     31     ;       seq(fi, list(fi))</div><div>     32     .</div></div><div><br></div><div><div>     42 :- type fstate</div><div>     43     --->    fstate(</div><div>     44                 indent      :: int,</div><div>     45                 tab_size    :: int,</div><div>     46                 nl_written  :: bool</div><div>     47             ).</div></div><div><br></div><div><br></div><div>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:</div><div><br></div><div><div>formatter.m:059: In `write_'(in, out, in, di, uo):</div><div>formatter.m:059:   error: determinism declaration not satisfied.</div><div>formatter.m:059:   Declared `det', inferred `multi'.</div><div>formatter.m:059:   The reason for the difference is the following.</div><div>formatter.m:061:   Inside the case nl/0 of the switch on HeadVar__3:</div><div>formatter.m:061:   disjunction has multiple clauses with solutions.</div><div>formatter.m:062: In clause for `write_(in, out, in, di, uo)':</div><div>formatter.m:062:   in argument 1 of call to predicate `io.nl'/2:</div><div>formatter.m:062:   mode error: variable `STATE_VARIABLE_IO_0' has</div><div>formatter.m:062:   instantiatedness `mostly_unique',</div><div>formatter.m:062:   expected instantiatedness was `unique'.</div><div>formatter.m:062:   This kind of uniqueness mismatch is usually caused by doing</div><div>formatter.m:062:   input/output or some other kind of destructive update in a</div><div>formatter.m:062:   context where it can be backtracked over, such as the</div><div>formatter.m:062:   condition of an if-then-else.</div></div><div>and the full predicate code, I've highlighted the offending clause in bold:</div><div><br></div><div><br></div><div>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?</div><div><br></div><div><br></div><div><div>     59 :- pred write_(fstate::in, fstate::out, fi::in, io::di, io::uo) is det.</div><div>     60</div><div><b>     61 write_(!S, nl, !IO) :-</b></div><div><b>     62     io.nl(!IO),</b></div><div><b>     63     !:S = !.S ^nl_written := yes.</b></div><div>     64</div><div>     65 write_(!S, brace_o, !IO) :-</div><div>     66     write_(!S, s("{"), !IO),</div><div>     67     !:S = !.S ^tab_size := !.S ^tab_size+1.</div><div>     68     write_(!S, nl, !IO).</div><div>     69</div><div>     70 write_(!S, brace_c, !IO) :-</div><div>     71     write_(!S, s("}"), !IO),</div><div>     72     !:S = !.S ^tab_size := !.S ^tab_size-1.</div><div>     73</div><div>     74 write_(!S, s(Text), !IO) :-</div><div>     75     io.print(Text, !IO).</div><div>     76</div><div>     77 write_(!S, blk(FIs), !IO) :-</div><div>     78     P = (pred(FI::in, !.St::in, !:St::out, !.IO::di, !:IO::uo) is det :-</div><div>     79         write_(!St, FI, !IO)</div><div>     80     ),</div><div>     81     list.foldl2(P, FIs, !S, !IO).</div><div>     82</div><div>     83 write_(!S, csv(FIs), !IO) :-</div><div>     84     write_(!S, seq(s(", "), FIs), !IO).</div><div>     85</div><div>     86 write_(!S, ssv(FIs), !IO) :-</div><div>     87     write_(!S, seq(s(" "), FIs), !IO).</div><div>     88</div><div>     89 write_(!_, seq(_, []), !IO).</div><div>     90 write_(!S, seq(With, [ FI | FIs ]), !IO) :-</div><div>     91     write_(!S, FI, !IO),</div><div>     92     ( if list.is_empty(FIs) then</div><div>     93         true</div><div>     94     else</div><div>     95         write_(!S, With, !IO),</div><div>     96         write_(!S, seq(With, FIs), !IO)</div><div>     97     ).</div></div><div><br></div><div><br></div><div>I think will be a good one to learn from!</div><div><br></div><div>Thanks,</div><div>Sea.</div><div><br></div></body></html>