/* -*- Prolog -*-
 * @(#)$Id: reduction,v 1.2 1997/10/09 17:18:48 img Exp $
 *
 * $Log: reduction,v $
 * Revision 1.2  1997/10/09 17:18:48  img
 * trivia
 *
 * Revision 1.1  1996/12/11 14:08:47  img
 * Merge mthd and smth libraries.
 *
 * Revision 1.3  1996/05/23  11:20:39  img
 * incorrect argument order in reduction_rule/6
 *
 * Revision 1.2  1996/05/14  14:50:43  img
 * Updated in line with revisions to the reduction rule mechanism.  This
 * version allows the registry to be extended on the fly, providing
 * extending_registry/0 succeeds.
 *
 * Revision 1.1  1994/09/16  09:34:27  dream
 * Initial revision
 */

/* Normalize the goal by exhaustive application of rewrite rules from
   a terminating rewrite system.  Rules are applied in an order 
   determined by exp_at (outermost-rightmost at the time of writing).

   (In fact, this method only applies a single rule, so it normalizes
   only when used inside an iterator: we call this one-step relation
   "reduction".)

   Rewrite rules come from the recorded database of reduction rules.
   These rules are known to be terminating under Clam's global EPOS
   registry.  There two clauses: the first attempts to apply an
   existing rule and the second will extend the registry (and the
   reduction rule database) if a rewrite rule can be oriented.

   NB: this method does not attempt to clear the rewrite system nor
   does it initialize the registry.  Such things are left to other
   parts of the plan (perhaps in a calling method).  */

/* First try to use a known reduction rule, otherwise (if enabled)
   attempt to extend the registry with an arbitrary rewrite rule.  */
method(reduction(Pos,[Thm,Dir]),
	  H==>G,
          [matrix(Vars,Matrix,G),
 	   exp_at(Matrix,Pos,LHSground),
	   \+ Pos = [0|_],
	   not metavar(LHSground),
	   ((reduction_rule(LHSground,RHSground,Cground,Dir,Thm,_),
	     polarity_compatible(Matrix, Pos, Dir))
	     -> true
	     ;  (extending_registry,		%do we want to do this?
		 rewrite_rule_speedy(LHSground,RHSground,Cground,Thm,Dir,RuleRef),
		 polarity_compatible(Matrix, Pos, Dir),
		 %% fetch the same rule, uninstantiated and make it
		 %% into a reduction rule, if possible
		 rewrite_rule(LHS,RHS,C,Thm,Dir,RuleRef),
		 registry(Tau,Prec,RegistryRef),
		 (extend_registry_prove(Tau-Prec,TauExt-PrecExt,LHS,RHS),
		  (Tau-Prec == TauExt-PrecExt
		       -> true			% no extension required
		       ;  (erase(RegistryRef),	% delete the old
			   recorda(registry,registry(TauExt,PrecExt),_),
			   numbervars(C-LHS-RHS,1,_),
			   clam_info('Registry extended to %t\n',
				     [C=>LHS:=>RHS])))))),
	   elementary( H==>Cground, _ )],
          [replace(Pos,RHSground,Matrix,NewMatrix),
           matrix(Vars,NewMatrix,NewG)],
          [H==>NewG],
          reduction(Pos,[Thm,Dir])).

/* cancellation rules are used during post-fertilization rippling, but
   this is not yet fully implemented in this version.  */
/* method(reduction(Pos,Rule),
          H==>G,
          [matrix(Vars,Matrix,G),
           cancel_rule(Exp,Rule:PC=>Exp:=>NewExp),
           exp_at(Matrix,Pos,Exp),
           object_level_term(Exp),
           elementary( H ==> PC, _ ) ],
          [replace(Pos,NewExp,Matrix,NewMatrix),
           matrix(Vars,NewMatrix,NewG) ],
          [H==>NewG],
          reduction(Pos,[Rule,imp(left)]) ).
*/

