Julia, 79 bytes
Try it online!
In Advanced Problems and Solutions, H-187: Fibonacci is a square, the proposer shows that
where Ln denotes the nth Lucas number, and that – conversely – if
then n is a Fibonacci number and m is a Lucas number.
How it works
We define the binary operator
<| for our purposes. It is undefined in recent versions of Julia, but still recognized as an operator by the parser.
When called with only one argument (n),
<| initializes k as 1. While n is positive, it subtracts !k (1 if k is a product of Fibonacci numbers, 0 if not) from n and recursively calls itself, increments k by 1. Once n reaches 0, the desired amount of products have been found, so
<| returns the previous value of k, i.e., ~-k = k - 1.
The unary operator
!, redefined as a test for Fibonacci number products, achieves its task as follows.
If k = 1, k is a product of Fibonacci numbers. In this case, we raise the return value of
any(...) to the power ~-k = k - 1 = 0, so the result will be 1.
If k > 1, the result will be the value of
any(....), which will return true if and only if the predicate
√(5i^2+[4,-4])%1∋k%i<!(k÷i) returns true for some integer i such that 2 ≤ i ≤ k.
The chained conditions in the predicate hold if
k%i belongs to
k%i is less than
√(5i^2+[4,-4])%1 takes the square root of 5i2 + 4 and 5i2 - 4 and computes their residues modulo 1. Each modulus is 0 if the corresponding number is a perfect square, and a positive number less than 1 otherwise.
k%i returns an integer, it can only belong to the array of moduli if k % i = 0 (i.e., k is divisible by i) and at least one among 5i2 + 4 and 5i2 - 4 is a perfect square (i.e., i is a Fibonacci number).
!(k÷i) recursively calls 1 with argument k ÷ i (integer division), which will be greater than 0 if and only if k ÷ i is a product of Fibonacci numbers.
By induction, ! has the desired property.