FACTORIAL RELATION - PROLOG
  1. % Reversible factorial relation
  2. % fact(N, F) is true when F = N!
  3. % Works when N is given, when F is given, or when both are variables.
  4.  
  5. % public entry
  6. fact(N, F) :-
  7. ( nonvar(N) -> % N is known: compute F directly
  8. integer(N), N >= 0,
  9. fact_from_n(N, F)
  10. ; nonvar(F) -> % F is known: search N by growing factorial
  11. integer(F), F >= 0,
  12. fact_from_f(F, N)
  13. ; % both variables: enumerate N = 0,1,2,...
  14. nat(N),
  15. fact_from_n(N, F)
  16. ).
  17.  
  18. % compute factorial when N is known
  19. fact_from_n(0, 1) :- !.
  20. fact_from_n(N, F) :-
  21. N > 0,
  22. N1 is N - 1,
  23. fact_from_n(N1, F1),
  24. F is F1 * N.
  25.  
  26. % find N given F by iterative search
  27. % handles F = 0 only if you want to treat 0 specially (0! = 1), so we require F >= 0
  28. fact_from_f(F, N) :-
  29. % start search from 0 with accumulator 1
  30. fact_search(0, 1, F, N).
  31.  
  32. % fact_search(CurrentN, Acc, TargetF, ResultN)
  33. fact_search(N, Acc, F, N) :-
  34. Acc =:= F, !.
  35. fact_search(N, Acc, F, Res) :-
  36. Acc < F,
  37. N1 is N + 1,
  38. Acc1 is Acc * N1,
  39. fact_search(N1, Acc1, F, Res).
  40. % If Acc > F the search fails (no integer N with N! = F).
  41. % nat/1 enumerates natural numbers 0,1,2,...
  42. nat(0).
  43. nat(N) :- nat(M), N is M + 1.
Pasted 2026-03-29 15:32:21

Short link: