I'm trying to learn myself Prolog and need a little help.
Could someone solve and explain this problem:
Define a p(A, M/N, K/L), which generates all possible rational fractions M/N and K/L, where:
N>M>0, K>L>0, (M/N)*(K/L) = 2 and (M+K)<A
Your description is not that clear to me, I am rather guessing which values should be known and which are asked. So I will rather use library(clpfd)
where I do not have to make such considerations myself.
N>M>0, K>L>0, (M/N)*(K/L) = 2 and (M+K)<A
p(A, M/N, K/L) :-
N #> M, M #> 0,
K #> L, L #> 0,
M+K #< A,
(M/N) * (K/L) #= 2.
?- 3/2 #= F.
F = 1.
?- (3/2)*2 #= F.
F = 2.
Oh, clpfd is on the integers so fractions are truncated. I need some algebra first, multiplying both sides with (N*L)
(they are both not 0...):
p(A, M/N, K/L) :-
N #> M, M #> 0,
K #> L, L #> 0,
M+K #< A,
M*K #= 2*N*L.
?- p(A, M/N, K/L).
A in 4..sup, M+K+ -1*A#=< -1, M in 1..sup,
M#=<N+ -1, M*K#=_A, N in 2..sup, 2*N#=_B,
_B in 4..sup, _B*L#=_A, L in 1..sup, L#=<K+ -1,
K in 2..sup, _A in 4..sup.
So Prolog says: Yes! That is true provided all this very fine print is true. The first line is the most interesting A in 4..sup
which means that there is no upper bound for A
. To get concrete solutions, A
must be known:
?- A #= 10, p(A, M/N, K/L).
A = 10, M in 1..7, M+K#=_A, M#=<N+ -1,
M*K#=_B, K in 2..8, L#=<K+ -1, L in 1..7,
_C*L#=_B, _C in 4..56, 2*N#=_C, N in 2..28,
_B in 4..56, _A in 3..9.
Not enough! But now K, L, M, N
have all finite domains, so we can enumerate them using labeling([], [K,L,M,N])
.
?- A = 10, p(A,M/N,K/L),labeling([],[M,N,K,L]).
A = 10, M = L, L = 1, N = 2, K = 4
; A = 10, M = 1, N = L, L = 2, K = 8
; A = 10, M = L, L = 1, N = 3, K = 6
; ... .