First, looking at the rules
num(0).
num(X) :- num(X1), X is X1 + 1.
the predicate num(Y) will be immediately valid for Y = 0.
Thus the rule
fact(X) :- num(Y), fact(Y,X).
can be simplified as
fact(X) :- fact(0,X).
that will find a match for fact(0,1). For X = 6, what happens instead is, as no rule defines a predicate for fact(0,6), a search is started with fact(-1,V1), followed with fact(-2,V2) etc... until a match occurs for a fact(-value, Var) where the local result would be the Var found.
This cannot happen, and an infinite loop consumes the whole stack, until an error is triggered.