Zdroj
% Najděte dvojici čísel, které jsou v dekadickém zápisu
% složeny pouze z jedniček a jejich součin a součet se rovnají
% A*B =:= A+B
reseni(A,B) :- reseni(2, A, B).
reseni(N, U, V) :- rozdel(N, U, V), test(U, V).
reseni(N, U, V) :- M is N + 1, reseni(M, U, V).
test(cislo(A,B), cislo(C,D)) :-
prevod(cislo(A,B), X), prevod(cislo(C,D), Y),
abs(X*Y - (X+Y)) =:= 0.
%prevod(+cislo(DelkaPredTeckou, DelkaZaTeckou), -hodnota)
prevod(cislo(A,B), X) :- leve(A,X1), prave(B,X2), X is X1+X2.
%leve(+PocetJednicek, -hodnota)
leve(0, 0).
%leve(1, 1).
leve(N, X) :- N > 0, N1 is N-1, leve(N1, X1), X is X1*10+1.
%prave(+PocetJednicekZa, -hodnota)
prave(0, 0).
prave(N, X) :-
N > 0, N1 is N-1, prave(N1,X1),
X is (X1 + 1) rdiv 10.
% ^^ nakonec jsme použili nestandardní aritmetiku:
% racionální čísla s neomezenou přesností
%rozdel(+CelkovyPocetJednicek, -Cislo1, -Cislo2)
rozdel(N, C1, C2) :-
N >= 2, rozdelCislo(N, N1, N2),
carka(N1, C1), carka(N2, C2).
%carka(+PocetJednicek, Cislo)
carka(N, cislo(Cela, Desetinna)) :-
N > 0, rozdelCislo(N, Cela, Desetinna).
%rozdelCislo(Soucet, A, B)
rozdelCislo(N, A, B) :- seq(N, A), B is N - A.
%seq(+End, -Current)
seq(End, Current) :- range(End, RNG), member(Current, RNG).
%range(+Count, -RangeList)
range(0, [0]):-!.
range(N, [N|Z]) :- decrement(N, M), range(M, Z).
%decrement(+In, -Out)
decrement(N, M) :- M is N - 1.