I’ve written a very simple optimiser library with a swipl pack structure.
The current version checks to see if all subsequent calls are disjoint from the current predicate call by checking the arguments. There is also code for a constraint based approach which takes into account types and binding status but this code is still not completed and so not exposed in the interface.
Ultimately I hope to slurp up a guard from the clause body defined as the largest initial segment of predicates that fall into a grammar:
X,Y in any N,M in number G,H := G,H | G ; H | \+ G | integer(X) | string(X) | ... | X <= Y | X >= Y | ... | var(X) | ground(X) ...
So far there are some bugs which appear with complicated module loading and pre-existing term transformations. I’d be happy if people tried it out and reported bugs or even better reasons for the bugs.
The advantage of the simple equality based optimiser is that it relies on very little about the host system. It seems to me that the type checking is going to be fairly fragile as one switches prolog systems and would probably have to be specialised for each one. In any event I’ll have a prototype in swipl fairly soon.
In particular the
reify_reflect/2 predicate was informed by Markus Triska’s recent lecture on avoiding ‘defaulty’ representations. The initial version of the code had used the prolog term language for program transformation and it was indeed awkward and required explicit cuts and a bit more thinking than the reflected representation required.