% faster.pl

% an optimizer using a meta-interpreter.
% things that can be reduced, are
% reduced.

:- [lib], -[demos,reduce,tidyTrue].
:- op(999,xfx,`), op(998,fx,`).

demof :- demos(faster1).
demo1 :- listing([twoPi, area, volume,
	   myVolume,combine, myCombine ]).

% potentinal of prolog- write the interpreter
% and AUTOMATICALLY generate the compiler

% PE= partial evaluation: perform as much of
% the calculation as allowed by the inputs.
% residual = pe(program, inputs)
% where residual is a new program specialized
% by the inputs from the old program.

% general computation is just a special case
% of pe where the residual is (e.g.) a single
% number.

% logical optimization = hook term_expansion
% into a partial evaluator

term_expansion((`X:-Y),Z) :-
	faster(X,Y,Z).

faster(X,Y0,Z) :-
	pe(Y0,Y1),
	tidy((X :- Y1),Z).

% standard top-down parser.
% once(X) :- X,!.
% only have 1 solution.
pe(X,Y) :-
	once(pe1(X,Y)).

% standard base cases
%   1) don't let vars fall into the
%      rest of stuff 
pe1(X,          X) :- var(X).
%   2) true- just end.
pe1(true,    true).

% pe on all parts of an "or"
pe1((A0;B0),(A;B)) :-
	pe(A0,A),
	pe(B0,B).

% pe on all parts of an "and"
pe1((A0,B0),(A,B)) :-
	pe(A0,A),
	pe(B0,B).

% if not inside an "and" or an "or",
% try reducing it
pe1(X, Y) :-
	% if reduce works, pe the
	% reduced stuff. note:
	% these means that our pe
	% chase multiple nested
	% definitions.
	reduce(X,Z),
	pe(Z,Y).

% if none of the above- do nothing
pe1(X, X).

:- [fastereg1].