I think i am going a step further, to say, that when mode and type declaration are provided, then a compiler can do some additional checks, increasing the quality of the code.
I my mind, it kind of self-evident, that if, you can omit creating choice points for declared determinstic goal predicate encountered, and you can skip such goals during backtracking, then this provides a key performance gain.
Also, when thinking about types:
could perhaps be resolved during compile time using polymorphic types, rather than a rule
programmer(X) :- person(X), saving runtime compute as well.
The few cycles wasted are likely not much of a problem in a domain where one can program, say, in Java as well – with its VM overhead (as well).
However, in domains were processor cycles are counted to ensure optimization, and where C and C++ are the preferred language choices – these omitted choice points and backracking steps, are significant.
The other area, i (intuitively) feel there is an overhead in Prolog is not support for pointers. to traverse structures – at each step there is a hash lookup which is much more costly than a “next” pointer – not sure if Mercury has an answer to that though.
But, perhaps, system level programming its just not the right domain to work with Prolog (or Mercury) and moving to C / C++ for those performance critical areas is the better choice.