src/Pure/pattern.ML
changeset 52131 366fa32ee2a3
parent 52130 86f7d8bc2a5f
child 52133 f8cd46077224
equal deleted inserted replaced
52130:86f7d8bc2a5f 52131:366fa32ee2a3
     8 In Proceedings of the 8th IEEE Symposium Logic in Computer Science, 1993.
     8 In Proceedings of the 8th IEEE Symposium Logic in Computer Science, 1993.
     9 
     9 
    10 TODO: optimize red by special-casing it
    10 TODO: optimize red by special-casing it
    11 *)
    11 *)
    12 
    12 
    13 infix aeconv;
       
    14 
       
    15 signature PATTERN =
    13 signature PATTERN =
    16 sig
    14 sig
    17   val trace_unify_fail: bool Unsynchronized.ref
    15   val trace_unify_fail: bool Unsynchronized.ref
    18   val aeconv: term * term -> bool
       
    19   val eta_long: typ list -> term -> term
       
    20   val match: theory -> term * term -> Type.tyenv * Envir.tenv -> Type.tyenv * Envir.tenv
    16   val match: theory -> term * term -> Type.tyenv * Envir.tenv -> Type.tyenv * Envir.tenv
    21   val first_order_match: theory -> term * term
    17   val first_order_match: theory -> term * term
    22     -> Type.tyenv * Envir.tenv -> Type.tyenv * Envir.tenv
    18     -> Type.tyenv * Envir.tenv -> Type.tyenv * Envir.tenv
    23   val matches: theory -> term * term -> bool
    19   val matches: theory -> term * term -> bool
    24   val matchess: theory -> term list * term list -> bool
    20   val matchess: theory -> term list * term list -> bool
   278             handle Unif => (proj_fail thy params; raise Unif));
   274             handle Unif => (proj_fail thy params; raise Unif));
   279 
   275 
   280 fun unify thy = unif thy [];
   276 fun unify thy = unif thy [];
   281 
   277 
   282 
   278 
   283 (* put a term into eta long beta normal form *)
       
   284 fun eta_long Ts (Abs (s, T, t)) = Abs (s, T, eta_long (T :: Ts) t)
       
   285   | eta_long Ts t =
       
   286       (case strip_comb t of
       
   287         (Abs _, _) => eta_long Ts (Envir.beta_norm t)
       
   288       | (u, ts) =>
       
   289           let
       
   290             val Us = binder_types (fastype_of1 (Ts, t));
       
   291             val i = length Us;
       
   292           in
       
   293             fold_rev (Term.abs o pair "x") Us
       
   294               (list_comb (incr_boundvars i u, map (eta_long (rev Us @ Ts))
       
   295                 (map (incr_boundvars i) ts @ map Bound (i - 1 downto 0))))
       
   296           end);
       
   297 
       
   298 
       
   299 (*Tests whether 2 terms are alpha/eta-convertible and have same type.
       
   300   Note that Consts and Vars may have more than one type.*)
       
   301 fun t aeconv u = t aconv u orelse
       
   302   Envir.eta_contract t aconv Envir.eta_contract u;
       
   303 
       
   304 
   279 
   305 (*** Matching ***)
   280 (*** Matching ***)
   306 
   281 
   307 exception MATCH;
   282 exception MATCH;
   308 
   283 
   321         (Var(ixn,T), t)  =>
   296         (Var(ixn,T), t)  =>
   322           if k > 0 andalso Term.is_open t then raise MATCH
   297           if k > 0 andalso Term.is_open t then raise MATCH
   323           else (case Envir.lookup1 insts (ixn, T) of
   298           else (case Envir.lookup1 insts (ixn, T) of
   324                   NONE => (typ_match thy (T, fastype_of t) tyinsts,
   299                   NONE => (typ_match thy (T, fastype_of t) tyinsts,
   325                            Vartab.update_new (ixn, (T, t)) insts)
   300                            Vartab.update_new (ixn, (T, t)) insts)
   326                 | SOME u => if t aeconv u then instsp else raise MATCH)
   301                 | SOME u => if Envir.aeconv (t, u) then instsp else raise MATCH)
   327       | (Free (a,T), Free (b,U)) =>
   302       | (Free (a,T), Free (b,U)) =>
   328           if a=b then (typ_match thy (T,U) tyinsts, insts) else raise MATCH
   303           if a=b then (typ_match thy (T,U) tyinsts, insts) else raise MATCH
   329       | (Const (a,T), Const (b,U))  =>
   304       | (Const (a,T), Const (b,U))  =>
   330           if a=b then (typ_match thy (T,U) tyinsts, insts) else raise MATCH
   305           if a=b then (typ_match thy (T,U) tyinsts, insts) else raise MATCH
   331       | (Bound i, Bound j)  =>  if  i=j  then  instsp  else raise MATCH
   306       | (Bound i, Bound j)  =>  if  i=j  then  instsp  else raise MATCH
   375     in case ph of
   350     in case ph of
   376          Var(ixn,T) =>
   351          Var(ixn,T) =>
   377            let val is = ints_of pargs
   352            let val is = ints_of pargs
   378            in case Envir.lookup1 itms (ixn, T) of
   353            in case Envir.lookup1 itms (ixn, T) of
   379                 NONE => (iTs,match_bind(itms,binders,ixn,T,is,obj))
   354                 NONE => (iTs,match_bind(itms,binders,ixn,T,is,obj))
   380               | SOME u => if obj aeconv (red u is []) then env
   355               | SOME u => if Envir.aeconv (obj, red u is []) then env
   381                           else raise MATCH
   356                           else raise MATCH
   382            end
   357            end
   383        | _ =>
   358        | _ =>
   384            let val (oh,oargs) = strip_comb obj
   359            let val (oh,oargs) = strip_comb obj
   385            in case (ph,oh) of
   360            in case (ph,oh) of