/*
 * @(#)$Id: generalise,v 1.4 1996/11/02 13:56:25 img Exp $
 *
 * $Log: generalise,v $
 * Revision 1.4  1996/11/02 13:56:25  img
 * Don't generalize propositions/atomic definitions.
 *
 * Revision 1.3  1996/07/10  09:02:44  img
 * use type_of/3.
 *
 * Revision 1.2  1995/10/03  12:52:40  img
 * remove annotaion from goal in preconditions rather than postconditions.
 *
 * Revision 1.1  1994/09/16  09:33:29  dream
 * Initial revision
 *
 */

	% GENERALISE METHOD:
	% Replace a common subterm in both halves of an
	% - equality, or
	% - implication, or
	% - inequality
	% by a new variable.
	% Disallow generalising over object-level variables, and over 
        % terms containing meta-level variables (too dangerous), and 
        % over constant object-level terms, and over terms containing 
        % wave-fronts.  Remove annotations since we are giving up on
	% the present induction (if any).
method(generalise(Exp,Var:Type),
       H==>GG,
       [strip_meta_annotations(GG,G),
	matrix(Vs,M,G),
        member(M,[(L=R in _),(L=>R),geq(L,R),leq(L,R),greater(L,R),less(L,R)]),
        exp_at(L,_,Exp),
        not atomic(Exp),        % disallow generalising object-level variables
        not constant(Exp,_),    % Exp must not be a constant term.
        not Exp = {_},          % don't generalise atomic definitions
        object_level_term(Exp), % Exp must not contain meta-vars or wave fronts
        exp_at(R,_,Exp),
        type_of(H,Exp,Type),
	\+ Type = u(_),         % don't generalise over propositions
	ground(Type),
        append(Vs,H,VsH),
        hfree([Var],VsH)], 
       [replace_all(Exp,Var,G, NewG)],
       [H==>Var:Type=>NewG],
       generalise(Exp,Var:Type)).
