Based on the question, I think you have a misconception on what predicates are. Predicates can only result in true or false (well there can of course be an error, or they can loop forever if you see these as "possible outcomes" as well). A predicate can respond with values by unifying variables that are not yet fixed. Typically in Prolog, one makes predicates as generic as possible such that one can call a predicate multidirectional.
You call a predicate like:
FB is fact1(BB,R1),
But fact1 is not a function (a functor for which in the is/2 predicate, the semantics is known).
A predicate can calculate things and passes results through unification, for example:
?- fac1(5, X). X = 120 .
we thus make a call to the fac1/2 predidate with the first parameter fixed to 5, and Prolog will unify X to 120.
We can tus rewrite the predicate to:
main :- current_prolog_flag(argv,[BB_S,CC_S]), atom_number(BB_S,BB), atom_number(CC_S,CC), fact1(BB, FB), ABS is abs(BB - CC), fact1(ABS, FA), fact1(CC, FC), Res is FB / (FA * FC), write(Res).
We can also make fac1 more declarative: right now it only works given the first parameter is fixed (or in case the second parameter is 1). Furthermore it is a bit inefficient since it does not make use of tail call optimization (TCO). We can improve the predicate by using the clpfd library, and implement it like:
:- use_module(library(clpfd)). fac(0, 1). fac(I, F) :- I #> 0, F #= I*F1, I1 #= I-1, fac(I1, F1).
Now we can query the factorial relation in several directions:
?- fac(I, 120). I = 5 ; false. ?- fac(I, 130). false. ?- fac(5, 120). true ; false. ?- fac(7, 120). false. ?- fac(7, Y). Y = 5040 ; false.
We can thus query for which i, i! is equal to 120, etc.
We can also boost performance by implementing a product for a specific range, so:
b ------ | | | | i i=a+1
So a prodrange that is basically:
prodrange(A, B, P) :- fac(A, FA), fac(B, FB), P is FB / FA.
but then more efficient, since this is O(a + b), and we can reduce it to O(b - a), with:
prodrange(A, A, 1). prodrange(A, B, P) :- B > A, B1 is B-1, prodrange(A, B1, P1), P is P1 * B1.
or more declarative:
prodrange(A, A, 1). prodrange(A, B, P) :- B #> A, P #= B*P1, B1 #= B-1, prodrange(A, B1, P1).
then we can implement a comb/3 predicate to calculate the number of combinations:
comb(BB, CC, Res) :- MX is max(BB, CC), MN is min(BB, CC), prodrange(MN, MX, Num), Abs is MX-MN, fac(Abs, Den), Res is Num / Den.
then the main looks like:
main :- current_prolog_flag(argv,[BB_S,CC_S]), atom_number(BB_S,BB), atom_number(CC_S,CC), comb(BB, CC, BF), print('Number of bracelets: '), write(BF), halt.