diff -r 95bfef18da83 -r 4de06a8f67ef src/Pure/pattern.ML --- a/src/Pure/pattern.ML Thu Jan 17 20:59:46 2002 +0100 +++ b/src/Pure/pattern.ML Thu Jan 17 21:00:38 2002 +0100 @@ -228,15 +228,26 @@ (*Eta-contract a term (fully)*) -(* copying: *) -fun eta_contract (Abs(a,T,body)) = - (case eta_contract body of - body' as (f $ Bound 0) => - if loose_bvar1(f,0) then Abs(a,T,body') - else incr_boundvars ~1 f - | body' => Abs(a,T,body')) - | eta_contract(f$t) = eta_contract f $ eta_contract t - | eta_contract t = t; +fun eta_contract t = + let + exception SAME; + fun eta (Abs (a, T, body)) = + ((case eta body of + body' as (f $ Bound 0) => + if loose_bvar1 (f, 0) then Abs(a, T, body') + else incr_boundvars ~1 f + | body' => Abs (a, T, body')) handle SAME => + (case body of + (f $ Bound 0) => + if loose_bvar1 (f, 0) then raise SAME + else incr_boundvars ~1 f + | _ => raise SAME)) + | eta (f $ t) = + (let val f' = eta f + in f' $ etah t end handle SAME => f $ eta t) + | eta _ = raise SAME + and etah t = (eta t handle SAME => t) + in etah t end; val beta_eta_contract = eta_contract o Envir.beta_norm; @@ -400,9 +411,16 @@ fun rewrite_term tsig rules tm = let + val rhs_names = + foldr (fn ((_, rhs), names) => add_term_free_names (rhs, names)) (rules, []); + fun variant_absfree (x, T, t) = + let + val x' = variant (add_term_free_names (t, rhs_names)) x; + val t' = subst_bound (Free (x', T), t); + in (fn u => Abs (x, T, abstract_over (Free (x', T), u)), t') end; + fun match_rew tm (tm1, tm2) = Some (subst_vars (match tsig (tm1, tm)) tm2) handle MATCH => None; - fun rew (Abs (_, _, body) $ t) = Some (subst_bound (t, body)) | rew tm = get_first (match_rew tm) rules; @@ -432,11 +450,14 @@ | None => (case rew1 tm2 of Some tm2' => Some (tm1 $ tm2') | None => None))) - | rew2 (Abs (x, T, tm)) = (case rew1 tm of - Some tm' => Some (Abs (x, T, tm')) - | None => None) + | rew2 (Abs (x, T, tm)) = + let val (abs, tm') = variant_absfree (x, T, tm) in + (case rew1 tm' of + Some tm'' => Some (abs tm'') + | None => None) + end | rew2 _ = None - in if_none (rew1 tm) tm end; + in if_none (timeap_msg "FIXME: rewrite_term" rew1 tm) tm end; end;