Mercury Bugs - mercury
View Issue Details
0000316mercuryBugpublic2014-02-05 18:112014-02-05 18:33
Reporterlpimmes 
Assigned Tojuliensf 
PriorityhighSeveritymajorReproducibilityalways
StatusresolvedResolutionno change required 
PlatformOSOSx 10.9.1OS Version
Product Version 
Target VersionFixed in Version 
Summary0000316: Declared `det', inferred `semidet'. --- [H|T] first argument input
DescriptionThis function compiles, except for det error.
In this case, I really need det, not semidet, otherwise callers including main will not work.

:- pred charToStrLst(list(char), list(string), list(string)).
:- mode charToStrLst(in, in, out) is det.
charToStrLst([H | T], Accum, LstStr) :- % [H|T] can fail
    (if list.is_empty([H|T])
    then
    LstStr = Accum
    else
    format("%c", [c(H)], Str),
     charToStrLst(T, [Str | Accum], LstStr)
    ).

All I needed to accomplish is convert, e.g., "foo" to ["f", "o", "o"].

longCommSubseq.m:097: In `charToStrLst'(in, in, out):
longCommSubseq.m:097: error: determinism declaration not satisfied.
longCommSubseq.m:097: Declared `det', inferred `semidet'.
longCommSubseq.m:098: In argument 1 of clause head:
longCommSubseq.m:098: unification of `HeadVar__1' and `list.[H | T]' can
longCommSubseq.m:098: fail.
% Program contains determinism error(s).
Steps To Reproduce mmc --make --fully-strict -E -v -O 0 --use-subdirs longCommSubseq
Additional InformationSee attached file.
Thanks.
TagsNo tags attached.
Attached Files? longCommSubseq.m (4,585) 2014-02-05 18:11
https://bugs.mercurylang.org/file_download.php?file_id=200&type=bug

Notes
(0000639)
juliensf   
2014-02-05 18:32   
The predicate charToStrLst/3 does not have a clause that matches the case where the first
argument is the empty list, which it would need in order to be det.

One way of making the above predicate det is:

charToStrLst([], Accum, Accum).
charToStrLst([H | T], Accum, LastStr) :-
     Str = string.from_char(H),
     charToStrLst(T, [Str | Accum], LastStr)

(Aside: you can use string.from_char/1 to convert characters into strings;
there's no need to use format/3).

Alternatively, you the above predicate could be written as the following function:

    :- func charToStrLst(list(char)) = list(string).

    charToStrLst(Chars) = list.map(string.from_char, Chars).

In short, the error reported by the compiler here is correct and there isn't a bug.

Issue History
2014-02-05 18:11lpimmesNew Issue
2014-02-05 18:11lpimmesFile Added: longCommSubseq.m
2014-02-05 18:32juliensfNote Added: 0000639
2014-02-05 18:33juliensfStatusnew => resolved
2014-02-05 18:33juliensfResolutionopen => no change required
2014-02-05 18:33juliensfAssigned To => juliensf