resolveCuts: only create new terms if necessary

This func converts !/0 into '$cut_to'/1  If it doesn't have to do that
work, don't allocate new memory.  Profiling showed this responsible
for some excess memory pressure.
Avoid switching on Indicator()

Although using Indicator makes switch statements a little easier to
read, generating the indicator string is pretty slow.  Instead, switch
on arity followed by functor.  These two values are faster to
calculate and don't require allocating memory.

This improves Append, Maplist and DCGish benchmarks by about 3%
Further avoid Indicator()

In all these cases, Indicator() was being called in performance
critical code.  Migrate to an arity-then-functor comparison pattern
instead.
Optimize small-arity foreign predicate lookup

Most foreign predicates have small arity (0, 1, 2 or 3).  By storing
those predicates in a small array which contains a map by functor, we
can avoid many calls to goal.Indicator(), which is slow.

Foreign predicates with larger arity still invoke Indicator() but that
should be fairly rare.

This change improves performance on a language model benchmark by 10%