:- set_prolog_flag(prefer_rationals, true). % Int/Int --> Rational :- set_prolog_flag(rational_syntax, natural). % Write as `1/3`

How to make this code working ?

:- set_prolog_flag(prefer_rationals, true).     % Int/Int --> Rational
:- set_prolog_flag(rational_syntax,  natural).  % Write as `1/3`

I do not succeed to get rational numbers as ‘1/3’.

Thanks .

1 Like

Are you sure? On my install (9.2.9):

?- current_prolog_flag(prefer_rationals,P).
P = true.

?- set_prolog_flag(rational_syntax, compatibility).
true.

?- X is 1/3,rational(X).
X = 1r3.

?- set_prolog_flag(rational_syntax, natural).
true.

?- X is 1/3,rational(X).
X = 1/3.

This code gets around the problem:

:- set_prolog_flag(prefer_rationals, true).
:- set_prolog_flag(rational_syntax, natural).

it_av(A, B, N) :- time(iterative_average(A, B, N)).

iterative_average(A, B, N) :-
    average(A, B, M),
    format('Step 1: Average : ~50f (', [M]),
    rational_to_string(M, S),
    write(S),
    format(')~n', []),
    iterative_average(M, B, N, 2).

iterative_average(_, _, 1, _) :- !.
iterative_average(A, B, N, I) :-
    average(A, B, M),
    format('Step ~w : Average : ~50f (', [I, M]),
    rational_to_string(M, S),
    write(S),
    format(')~n', []),
    succ(I, NewI),
    succ(N0, N),
    iterative_average(M, B, N0, NewI).

average(A, B, M) :- M is (A + B) / 2.

rational_to_string(R, S) :-
    numerator(R, N),
    denominator(R, D),
    atomic_list_concat([N, '/', D], S).

numerator(R, N) :- rational(R, N, _).
numerator(R, N) :- R = N / D, N1 is numerator(N), D1 is denominator(D), gcd(N1, D1, G), N is N1 // G.

denominator(R, D) :- rational(R, _, D).
denominator(R, D) :- R = N / D, N1 is numerator(N), D1 is denominator(D), gcd(N1, D1, G), D is D1 // G.

gcd(A, 0, A).
gcd(A, B, G) :- B > 0, R is A mod B, gcd(B, R, G).

output :

?- it_av(1,2,10).
Step 1: Average : 1.50000000000000000000000000000000000000000000000000 (3/2)
Step 2 : Average : 1.75000000000000000000000000000000000000000000000000 (7/4)
Step 3 : Average : 1.87500000000000000000000000000000000000000000000000 (15/8)
Step 4 : Average : 1.93750000000000000000000000000000000000000000000000 (31/16)
Step 5 : Average : 1.96875000000000000000000000000000000000000000000000 (63/32)
Step 6 : Average : 1.98437500000000000000000000000000000000000000000000 (127/64)
Step 7 : Average : 1.99218750000000000000000000000000000000000000000000 (255/128)
Step 8 : Average : 1.99609375000000000000000000000000000000000000000000 (511/256)
Step 9 : Average : 1.99804687500000000000000000000000000000000000000000 (1023/512)
Step 10 : Average : 1.99902343750000000000000000000000000000000000000000 (2047/1024)
% 137 inferences, 0.001 CPU in 0.001 seconds (99% CPU, 232348 Lips)
true.

More elegant solutions for this program are welcome.

There seems to be a but in write/1. Using write_term/2, all works as expected, so we get

:- set_prolog_flag(prefer_rationals, true).
:- set_prolog_flag(rational_syntax, natural).

it_av(A, B, N) :-
    time(iterative_average(A, B, N)).

iterative_average(A, B, N) :-
    average(A, B, M),
    format('Step~t1~7|: Average: ~50f (~W)~n', [M, M, []]),
    iterative_average(M, B, N, 2).

iterative_average(_, _, 1, _) :- !.
iterative_average(A, B, N, I) :-
    average(A, B, M),
    format('Step~t~w~7|: Average: ~50f (~W)~n', [I, M, M, []]),
    succ(I, NewI),
    succ(N0, N),
    iterative_average(M, B, N0, NewI).

average(A, B, M) :- M is (A + B) / 2.
?- it_av(1,2,10).
Step  1: Average: 1.50000000000000000000000000000000000000000000000000 (3/2)
Step  2: Average: 1.75000000000000000000000000000000000000000000000000 (7/4)
Step  3: Average: 1.87500000000000000000000000000000000000000000000000 (15/8)
Step  4: Average: 1.93750000000000000000000000000000000000000000000000 (31/16)
Step  5: Average: 1.96875000000000000000000000000000000000000000000000 (63/32)
Step  6: Average: 1.98437500000000000000000000000000000000000000000000 (127/64)
Step  7: Average: 1.99218750000000000000000000000000000000000000000000 (255/128)
Step  8: Average: 1.99609375000000000000000000000000000000000000000000 (511/256)
Step  9: Average: 1.99804687500000000000000000000000000000000000000000 (1023/512)
Step 10: Average: 1.99902343750000000000000000000000000000000000000000 (2047/1024)
% 57 inferences, 0.000 CPU in 0.000 seconds (97% CPU, 745556 Lips)
true.

edit fixed with 457b6270d94c662b9af3d57b7537e7576b060ddf

3 Likes

Many thanks Jan !

1 Like