Используйте =..
с проверкой на троичные функторы.
ternary_takes_list(T0, T) :-
(T0 =.. [F, X, Y, Z] ->
T =.. [F, [X, Y, Z]]
; T0 =.. [F, X0] ->
ternary_takes_list(X0, X),
T =.. [F, X]
;
T = T0
).
Это работает на ваших примерах:
?- ternary_takes_list(cat(dog(cow(a,b,c))), X).
X = cat(dog(cow([a, b, c]))).
?- ternary_takes_list(dog(cat(a,b,c)), X).
X = dog(cat([a, b, c])).