[m-users.] How do you go about logging?

Left Right olegsivokon at gmail.com
Tue Apr 8 06:15:48 AEST 2014


For posterity's sake:

:- pred none_divides(int::in, list(int)::in, int::out) is semidet.
none_divides(Test, [Divider | Dividers], Result):-
    (if Test mod Divider = 0
    then Result = Divider
    else none_divides(Test, Dividers, Result)).

:- pred prime_factors(int::in, int::in, list(int)::in, list(int)::out) is det.
prime_factors(Test, UpperBound, Factors, Result):-
     trace [io(!IO), compile_time(flag("debug"))]
     (io.format("Test: %d, UpperBound: %d\n", [i(Test),
i(UpperBound)], !IO) ; true),
    (if Test >= UpperBound then Result = Factors
    else
    (if Divider \= 0, none_divides(Test, Factors, Divider)
    then prime_factors(Test + 2, UpperBound // Test, [Test | Factors], Result)
    else prime_factors(Test + 2, UpperBound, Factors, Result))).

% 2310, 600851475143
% main(!IO):-
%     (if none_divides(42, [5, 4, 8], Result), Result \= 0
%     then io.format("Answer: %d\n", [i(Result)], !IO)
%     else io.format("Nothing divides\n", [], !IO)).

main(!IO):-
    Number = 2310,
    prime_factors(2, floor_to_int(sqrt(float(Number))), [], Primes),
    (if Primes = []
    then io.format("Answer: %d\n", [i(0)], !IO)
    else io.write_list(Primes, ", ", io.write_int, !IO), io.nl(!IO)).

I finally figured it out :) It could be a very bad solution style-wise
or efficiency-wise, you name it, but at least it did what I wanted
(w/r to printing), oh joy! :)

Thanks again!

On Mon, Apr 7, 2014 at 9:39 PM, Left Right <olegsivokon at gmail.com> wrote:
> Thank you for answers!
> I'll keep on reading and advancing in small steps; it's ok :)
>
> Best,
>
> Oleg
>
> On Mon, Apr 7, 2014 at 8:05 AM, Paul Bone <paul at bone.id.au> wrote:
>> On Sun, Apr 06, 2014 at 09:20:54AM +0300, Left Right wrote:
>>> Thanks for reply! But wouldn't you mind elaborating a bit? Here's what
>>> I've tried, with the error message that resulted:
>>>
>>> % e3.m:011: Error: trailed mutable in non-trailing grade.
>>> % e3.m:018: In clause for `nonedivides(in, out)':
>>> % e3.m:018:   in argument 2 of call to predicate `io.write_string'/3:
>>> % e3.m:018:   unique-mode error: the called procedure would clobber
>>> its argument,
>>> % e3.m:018:   but variable `STATE_VARIABLE_IO_9' is still live.
>>> % e3.m:020:   The goal could not be reordered, because it was followed by an
>>> % e3.m:020:   impure goal.
>>> % e3.m:016:   This is the location of the impure goal.
>>>
>>> :- mutable(logging_level, int, 0, ground, []).
>>>
>>> :- pred nonedivides(int::in, list(int)::out) is semidet.
>>> nonedivides(_, []).
>>> nonedivides(Test, [Factor | Factors]):-
>>>     trace [io(!IO), state(logging_level, !LoggingLevel)]
>>>     (!.LoggingLevel > 1 ->
>>>      io.write_string("Factor = ", !IO),
>>>      io.write(Factor, !IO),
>>>      io.nl(!IO) ; true),
>>>     Factor mod Test \= 0, nonedivides(Test, Factors).
>>>
>>
>> it might be simplier to avoid module local mutables for now.
>>
>> Try making the trace goal conditional on either a runtime or compile time
>> flag instead.  For example:
>>
>> :- pred nonedivides(int::in, list(int)::out) is semidet.
>>
>> nonedivides(_, []).
>> nonedivides(Test, [Factor | Factors]) :-
>>     trace [io(!IO), compile_time(flag("debug"))] (
>>         ( !.LoggingLevel > 1 ->
>>             io.write_string("Factor = ", !IO),
>>             io.write(Factor, !IO),
>>             io.nl(!IO)
>>         ;
>>             true
>>         )
>>     ),
>>     Factor mod Test \= 0, nonedivides(Test, Factors).
>>
>> Then add --trace-flag debug to the mmc command line to enable this trace
>> goal.  One of the benifits of trace goals (rather than unchecked impurity)
>> is that they 1) cannot bind variables 2) Can eaisly be turned off.  Combined
>> this means that they're less likely to affect the program's semantics,
>> unlike conditional compilation in languages like C.
>>
>> Note that this clearer syntax also makes the control flow of your
>> if-then-else goal clearer to the reader (future you).
>>
>> Also your 3 calls to write out the status can be replaced with a single
>> call:
>>     io.format("Factor = %d\n", [i(Factor)], !IO)
>>
>> Thanks.
>>
>>
>> --
>> Paul Bone
>> _______________________________________________
>> users mailing list
>> users at lists.mercurylang.org
>> https://www.mercurylang.org/lists/listinfo/users



More information about the users mailing list