English 中文(简体)
ADT properties in Mercury
原标题:

I wander why Mercury (10.04) can t infer determinism of next snippet:

:- pred load_freqs(int::in, io.res(list(float))::out, io::di, io::uo) is det.
load_freqs(CPU, ResFreqs, !IO):-
    open_input(cpu_fn(CPU, "available_frequencies"), ResStream, !IO),
    (ResStream = io.ok(Stream) ->
        ResFreqs = io.ok([])
    ;ResStream = io.error(Err),
        ResFreqs = io.error(Err)
    ).

It complains:

cpugear.m:075: In `load_freqs (in, out, di, uo):
cpugear.m:075:   error: determinism declaration not satisfied.
cpugear.m:075:   Declared `det , inferred `semidet .
cpugear.m:080:   Unification of `ResStream  and `io.error(Err)  can fail.
cpugear.m:076: In clause for predicate `cpugear.load_freqs /4:
cpugear.m:076:   warning: variable `CPU  occurs only once in this scope.
cpugear.m:078: In clause for predicate `cpugear.load_freqs /4:
cpugear.m:078:   warning: variable `Stream  occurs only once in this scope.

But io.res have only io.ok/1 and io.error/1.
And next snippet of code compiles well:

:- pred read_freqs(io.res(io.input_stream)::in, io.res(list(float))::out, io::di, io::uo) is det.
read_freqs(io.ok(Stream), io.ok([]), IO, IO).
read_freqs(io.error(Err), io.error(Err), IO, IO).

Update #1: It can decide det even for:

:- pred read_freqs(bool::in, io.res(io.input_stream)::in, io.res(list(float))::out, io::di, io::uo) is det.
read_freqs(no, ResStream, io.ok([]), IO, IO):- ResStream = io.ok(_).
read_freqs(F, io.ok(_), io.ok([]), IO, IO):- F = yes.
read_freqs(yes, io.error(Err), io.error(Err), IO, IO).
read_freqs(F, ResStream, io.error(Err), IO, IO):- ResStream = io.error(Err), F = no.
最佳回答

My reading of the Mercury rules for determinism with conditionals (below) is that for this to be considered deterministic, you should replace the -> with a ,

From the Mercury reference manual:

If the condition of an if-then-else cannot fail, the if-then-else is equivalent to the conjunction of the condition and the “then” part, and its determinism is computed accordingly. Otherwise, an if-then-else can fail if either the “then” part or the “else” part can fail.

问题回答

As for Why . lets look at the original code with the if-then-else:

(ResStream = io.ok(Stream) ->
    ResFreqs = io.ok([])
;ResStream = io.error(Err),
    ResFreqs = io.error(Err)
).

If the condition fails, then the first conjunct in the else case is a semidet test. The compiler doesn t know that it must succeed (which can be inferred by the knowledge that this condition failed). In other words, the compiler is not smart enough.

That said, it s vary rare to find this problem, because usually the condition is more complicated and won t allow for this inference to be made, so it s not important that the compiler is not smart enough to determine the correct determinism here.

It is recommended to program using switches whenever possible (such as this example), it prevents the current problem and helps ensure that you ve covered all the possible cases of ResStream. For example, if in the future io.error was re factored and could be io.error_file_not_found or io.error_disk_full etc the compiler would direct the programmer to fix their switch as it would now be incomplete.

Ok, it can infer det for:

:- pred load_freqs(int::in, io.res(list(float))::out, io::di, io::uo) is det.
load_freqs(CPU, ResFreqs, !IO):-
    open_input(cpu_fn(0, "available_frequencies"), ResStream, !IO),
    (ResStream = io.ok(Stream),
        ResFreqs = io.ok([])
    ;ResStream = io.error(Err),
        ResFreqs = io.error(Err)
    ).

But why "if-then-else" construction introduces semidet?





相关问题
Prolog difference routine

I need some help with a routine that I am trying to create. I need to make a routine that will look something like this: difference([(a,b),(a,c),(b,c),(d,e)],[(a,_)],X). X = [(b,c),(d,e)]. I really ...

Python: Analyzing complex statements during execution

I am wondering if there is any way to get some meta information about the interpretation of a python statement during execution. Let s assume this is a complex statement of some single statements ...

Python nested lists and recursion problem

I m trying to process a first order logic formula represented as nested lists and strings in python so that that its in disjunctive normal form, i.e [ & , [ | , a , b ], [ | , c , d ]] ...

prolog - why this strange trace

here is the prolog code (which i sort of follow). len([],0). len([_|T],N) :- len(T,X), N is X+1. and here is the trace for it (im running linux, swi) [trace] ?- len([d,f,w,c],X). Call: (7) ...

prolog cut off in method

I have a question I would like to ask you something about a code snippet: insert_pq(State, [], [State]) :- !. insert_pq(State, [H|Tail], [State, H|Tail]) :- precedes(State, H). insert_pq(State, [...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

how to create a parser for search queries

for example i d need to create something like google search query parser to parse such expressions as: flying hiking or swiming -"**walking in boots **" **author:**hamish **author:**reid or ...

Applications of Unification?

What are the (practical) applications of Unification? Where it is actually being used in real world? I couldn t understand the whole idea of what it is really about and why it s considered as a part ...

热门标签