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 |