20 val eta_contract : term -> term |
20 val eta_contract : term -> term |
21 val eta_long : typ list -> term -> term |
21 val eta_long : typ list -> term -> term |
22 val beta_eta_contract : term -> term |
22 val beta_eta_contract : term -> term |
23 val eta_contract_atom : term -> term |
23 val eta_contract_atom : term -> term |
24 val match : Type.tsig -> term * term |
24 val match : Type.tsig -> term * term |
25 -> (indexname*typ)list * (indexname*term)list |
25 -> Type.tyenv * Envir.tenv |
26 val first_order_match : Type.tsig -> term * term |
26 val first_order_match : Type.tsig -> term * term |
27 -> (indexname*typ)list * (indexname*term)list |
27 -> Type.tyenv * Envir.tenv |
28 val matches : Type.tsig -> term * term -> bool |
28 val matches : Type.tsig -> term * term -> bool |
29 val matches_subterm : Type.tsig -> term * term -> bool |
29 val matches_subterm : Type.tsig -> term * term -> bool |
30 val unify : Sign.sg * Envir.env * (term * term)list -> Envir.env |
30 val unify : Sign.sg * Envir.env * (term * term)list -> Envir.env |
31 val first_order : term -> bool |
31 val first_order : term -> bool |
32 val pattern : term -> bool |
32 val pattern : term -> bool |
70 |
70 |
71 fun clashB binders i s = |
71 fun clashB binders i s = |
72 if !trace_unify_fail then clash (boundVar binders i) s |
72 if !trace_unify_fail then clash (boundVar binders i) s |
73 else () |
73 else () |
74 |
74 |
75 fun proj_fail sg (env,binders,F,is,t) = |
75 fun proj_fail sg (env,binders,F,_,is,t) = |
76 if !trace_unify_fail |
76 if !trace_unify_fail |
77 then let val f = Syntax.string_of_vname F |
77 then let val f = Syntax.string_of_vname F |
78 val xs = bnames binders is |
78 val xs = bnames binders is |
79 val u = string_of_term sg env binders t |
79 val u = string_of_term sg env binders t |
80 val ys = bnames binders (loose_bnos t \\ is) |
80 val ys = bnames binders (loose_bnos t \\ is) |
151 |
151 |
152 fun mkhnf (binders,is,G,js) = mkabs (binders, is, app(G,js)); |
152 fun mkhnf (binders,is,G,js) = mkabs (binders, is, app(G,js)); |
153 |
153 |
154 fun mknewhnf(env,binders,is,F as (a,_),T,js) = |
154 fun mknewhnf(env,binders,is,F as (a,_),T,js) = |
155 let val (env',G) = Envir.genvar a (env,type_of_G env (T,length is,js)) |
155 let val (env',G) = Envir.genvar a (env,type_of_G env (T,length is,js)) |
156 in Envir.update((F,mkhnf(binders,is,G,js)),env') end; |
156 in Envir.update (((F, T), mkhnf (binders, is, G, js)), env') end; |
157 |
157 |
158 |
158 |
159 (* mk_proj_list(is) = [ |is| - k | 1 <= k <= |is| and is[k] >= 0 ] *) |
159 (* mk_proj_list(is) = [ |is| - k | 1 <= k <= |is| and is[k] >= 0 ] *) |
160 fun mk_proj_list is = |
160 fun mk_proj_list is = |
161 let fun mk(i::is,j) = if isSome i then j :: mk(is,j-1) else mk(is,j-1) |
161 let fun mk(i::is,j) = if isSome i then j :: mk(is,j-1) else mk(is,j-1) |
184 val ks = mk_proj_list js'; |
184 val ks = mk_proj_list js'; |
185 val ls = List.mapPartial I js' |
185 val ls = List.mapPartial I js' |
186 val Hty = type_of_G env (Fty,length js,ks) |
186 val Hty = type_of_G env (Fty,length js,ks) |
187 val (env',H) = Envir.genvar a (env,Hty) |
187 val (env',H) = Envir.genvar a (env,Hty) |
188 val env'' = |
188 val env'' = |
189 Envir.update((F,mkhnf(binders,js,H,ks)),env') |
189 Envir.update (((F, Fty), mkhnf (binders, js, H, ks)), env') |
190 in (app(H,ls),env'') end |
190 in (app(H,ls),env'') end |
191 | _ => raise Pattern)) |
191 | _ => raise Pattern)) |
192 and prs(s::ss,env,d,binders) = |
192 and prs(s::ss,env,d,binders) = |
193 let val (s',env1) = pr(s,env,d,binders) |
193 let val (s',env1) = pr(s,env,d,binders) |
194 val (ss',env2) = prs(ss,env1,d,binders) |
194 val (ss',env2) = prs(ss,env1,d,binders) |
214 |
214 |
215 fun flexflex2(env,binders,F,Fty,is,G,Gty,js) = |
215 fun flexflex2(env,binders,F,Fty,is,G,Gty,js) = |
216 let fun ff(F,Fty,is,G as (a,_),Gty,js) = |
216 let fun ff(F,Fty,is,G as (a,_),Gty,js) = |
217 if js subset_int is |
217 if js subset_int is |
218 then let val t= mkabs(binders,is,app(Var(G,Gty),map (idx is) js)) |
218 then let val t= mkabs(binders,is,app(Var(G,Gty),map (idx is) js)) |
219 in Envir.update((F,t),env) end |
219 in Envir.update (((F, Fty), t), env) end |
220 else let val ks = is inter_int js |
220 else let val ks = is inter_int js |
221 val Hty = type_of_G env (Fty,length is,map (idx is) ks) |
221 val Hty = type_of_G env (Fty,length is,map (idx is) ks) |
222 val (env',H) = Envir.genvar a (env,Hty) |
222 val (env',H) = Envir.genvar a (env,Hty) |
223 fun lam(is) = mkabs(binders,is,app(H,map (idx is) ks)); |
223 fun lam(is) = mkabs(binders,is,app(H,map (idx is) ks)); |
224 in Envir.update((G,lam js), Envir.update((F,lam is),env')) |
224 in Envir.update (((G, Gty), lam js), Envir.update (((F, Fty), lam is), env')) |
225 end; |
225 end; |
226 in if xless(G,F) then ff(F,Fty,is,G,Gty,js) else ff(G,Gty,js,F,Fty,is) end |
226 in if xless(G,F) then ff(F,Fty,is,G,Gty,js) else ff(G,Gty,js,F,Fty,is) end |
227 |
227 |
228 fun unify_types sg (T,U, env as Envir.Envir{asol,iTs,maxidx}) = |
228 fun unify_types sg (T,U, env as Envir.Envir{asol,iTs,maxidx}) = |
229 if T=U then env |
229 if T=U then env |
241 |
241 |
242 and cases sg (binders,env,(s,t)) = case (strip_comb s,strip_comb t) of |
242 and cases sg (binders,env,(s,t)) = case (strip_comb s,strip_comb t) of |
243 ((Var(F,Fty),ss),(Var(G,Gty),ts)) => |
243 ((Var(F,Fty),ss),(Var(G,Gty),ts)) => |
244 if F = G then flexflex1(env,binders,F,Fty,ints_of' env ss,ints_of' env ts) |
244 if F = G then flexflex1(env,binders,F,Fty,ints_of' env ss,ints_of' env ts) |
245 else flexflex2(env,binders,F,Fty,ints_of' env ss,G,Gty,ints_of' env ts) |
245 else flexflex2(env,binders,F,Fty,ints_of' env ss,G,Gty,ints_of' env ts) |
246 | ((Var(F,_),ss),_) => flexrigid sg (env,binders,F,ints_of' env ss,t) |
246 | ((Var(F,Fty),ss),_) => flexrigid sg (env,binders,F,Fty,ints_of' env ss,t) |
247 | (_,(Var(F,_),ts)) => flexrigid sg (env,binders,F,ints_of' env ts,s) |
247 | (_,(Var(F,Fty),ts)) => flexrigid sg (env,binders,F,Fty,ints_of' env ts,s) |
248 | ((Const c,ss),(Const d,ts)) => rigidrigid sg (env,binders,c,d,ss,ts) |
248 | ((Const c,ss),(Const d,ts)) => rigidrigid sg (env,binders,c,d,ss,ts) |
249 | ((Free(f),ss),(Free(g),ts)) => rigidrigid sg (env,binders,f,g,ss,ts) |
249 | ((Free(f),ss),(Free(g),ts)) => rigidrigid sg (env,binders,f,g,ss,ts) |
250 | ((Bound(i),ss),(Bound(j),ts)) => rigidrigidB sg (env,binders,i,j,ss,ts) |
250 | ((Bound(i),ss),(Bound(j),ts)) => rigidrigidB sg (env,binders,i,j,ss,ts) |
251 | ((Abs(_),_),_) => raise Pattern |
251 | ((Abs(_),_),_) => raise Pattern |
252 | (_,(Abs(_),_)) => raise Pattern |
252 | (_,(Abs(_),_)) => raise Pattern |
264 |
264 |
265 and rigidrigidB sg (env,binders,i,j,ss,ts) = |
265 and rigidrigidB sg (env,binders,i,j,ss,ts) = |
266 if i <> j then (clashBB binders i j; raise Unif) |
266 if i <> j then (clashBB binders i j; raise Unif) |
267 else Library.foldl (unif sg binders) (env ,ss~~ts) |
267 else Library.foldl (unif sg binders) (env ,ss~~ts) |
268 |
268 |
269 and flexrigid sg (params as (env,binders,F,is,t)) = |
269 and flexrigid sg (params as (env,binders,F,Fty,is,t)) = |
270 if occurs(F,t,env) then (ocheck_fail sg (F,t,binders,env); raise Unif) |
270 if occurs(F,t,env) then (ocheck_fail sg (F,t,binders,env); raise Unif) |
271 else (let val (u,env') = proj(t,env,binders,is) |
271 else (let val (u,env') = proj(t,env,binders,is) |
272 in Envir.update((F,mkabs(binders,is,u)),env') end |
272 in Envir.update (((F, Fty), mkabs (binders, is, u)), env') end |
273 handle Unif => (proj_fail sg params; raise Unif)); |
273 handle Unif => (proj_fail sg params; raise Unif)); |
274 |
274 |
275 fun unify(sg,env,tus) = Library.foldl (unif sg []) (env,tus); |
275 fun unify(sg,env,tus) = Library.foldl (unif sg []) (env,tus); |
276 |
276 |
277 |
277 |
356 fun fomatch tsig = |
356 fun fomatch tsig = |
357 let |
357 let |
358 fun mtch (instsp as (tyinsts,insts)) = fn |
358 fun mtch (instsp as (tyinsts,insts)) = fn |
359 (Var(ixn,T), t) => |
359 (Var(ixn,T), t) => |
360 if loose_bvar(t,0) then raise MATCH |
360 if loose_bvar(t,0) then raise MATCH |
361 else (case assoc_string_int(insts,ixn) of |
361 else (case Envir.lookup' (instsp, (ixn, T)) of |
362 NONE => (typ_match tsig (tyinsts, (T, fastype_of t)), |
362 NONE => (typ_match tsig (tyinsts, (T, fastype_of t)), |
363 (ixn,t)::insts) |
363 Vartab.update_new ((ixn, (T, t)), insts)) |
364 | SOME u => if t aeconv u then instsp else raise MATCH) |
364 | SOME u => if t aeconv u then instsp else raise MATCH) |
365 | (Free (a,T), Free (b,U)) => |
365 | (Free (a,T), Free (b,U)) => |
366 if a=b then (typ_match tsig (tyinsts,(T,U)), insts) else raise MATCH |
366 if a=b then (typ_match tsig (tyinsts,(T,U)), insts) else raise MATCH |
367 | (Const (a,T), Const (b,U)) => |
367 | (Const (a,T), Const (b,U)) => |
368 if a=b then (typ_match tsig (tyinsts,(T,U)), insts) else raise MATCH |
368 if a=b then (typ_match tsig (tyinsts,(T,U)), insts) else raise MATCH |
372 | (f$t, g$u) => mtch (mtch instsp (f,g)) (t, u) |
372 | (f$t, g$u) => mtch (mtch instsp (f,g)) (t, u) |
373 | (t, Abs(_,U,u)) => mtch instsp ((incr t)$(Bound 0), u) |
373 | (t, Abs(_,U,u)) => mtch instsp ((incr t)$(Bound 0), u) |
374 | _ => raise MATCH |
374 | _ => raise MATCH |
375 in mtch end; |
375 in mtch end; |
376 |
376 |
377 fun first_order_match tsig = apfst Vartab.dest o fomatch tsig (Vartab.empty, []); |
377 fun first_order_match tsig = fomatch tsig (Vartab.empty, Vartab.empty); |
378 |
378 |
379 (* Matching of higher-order patterns *) |
379 (* Matching of higher-order patterns *) |
380 |
380 |
381 fun match_bind(itms,binders,ixn,is,t) = |
381 fun match_bind(itms,binders,ixn,T,is,t) = |
382 let val js = loose_bnos t |
382 let val js = loose_bnos t |
383 in if null is |
383 in if null is |
384 then if null js then (ixn,t)::itms else raise MATCH |
384 then if null js then Vartab.update_new ((ixn, (T, t)), itms) else raise MATCH |
385 else if js subset_int is |
385 else if js subset_int is |
386 then let val t' = if downto0(is,length binders - 1) then t |
386 then let val t' = if downto0(is,length binders - 1) then t |
387 else mapbnd (idx is) t |
387 else mapbnd (idx is) t |
388 in (ixn, mkabs(binders,is,t')) :: itms end |
388 in Vartab.update_new ((ixn, (T, mkabs (binders, is, t'))), itms) end |
389 else raise MATCH |
389 else raise MATCH |
390 end; |
390 end; |
391 |
391 |
392 fun match tsg (po as (pat,obj)) = |
392 fun match tsg (po as (pat,obj)) = |
393 let |
393 let |
395 fun mtch binders (env as (iTs,itms),(pat,obj)) = |
395 fun mtch binders (env as (iTs,itms),(pat,obj)) = |
396 case pat of |
396 case pat of |
397 Abs(ns,Ts,ts) => |
397 Abs(ns,Ts,ts) => |
398 (case obj of |
398 (case obj of |
399 Abs(nt,Tt,tt) => mtch ((nt,Tt)::binders) (env,(ts,tt)) |
399 Abs(nt,Tt,tt) => mtch ((nt,Tt)::binders) (env,(ts,tt)) |
400 | _ => let val Tt = typ_subst_TVars_Vartab iTs Ts |
400 | _ => let val Tt = Envir.typ_subst_TVars iTs Ts |
401 in mtch((ns,Tt)::binders)(env,(ts,(incr obj)$Bound(0))) end) |
401 in mtch((ns,Tt)::binders)(env,(ts,(incr obj)$Bound(0))) end) |
402 | _ => (case obj of |
402 | _ => (case obj of |
403 Abs(nt,Tt,tt) => |
403 Abs(nt,Tt,tt) => |
404 mtch((nt,Tt)::binders)(env,((incr pat)$Bound(0),tt)) |
404 mtch((nt,Tt)::binders)(env,((incr pat)$Bound(0),tt)) |
405 | _ => cases(binders,env,pat,obj)) |
405 | _ => cases(binders,env,pat,obj)) |
410 Library.foldl (mtch binders) ((iTs,itms), pargs~~oargs) |
410 Library.foldl (mtch binders) ((iTs,itms), pargs~~oargs) |
411 fun rigrig2((a,Ta),(b,Tb),oargs) = |
411 fun rigrig2((a,Ta),(b,Tb),oargs) = |
412 if a<> b then raise MATCH |
412 if a<> b then raise MATCH |
413 else rigrig1(typ_match tsg (iTs,(Ta,Tb)), oargs) |
413 else rigrig1(typ_match tsg (iTs,(Ta,Tb)), oargs) |
414 in case ph of |
414 in case ph of |
415 Var(ixn,_) => |
415 Var(ixn,T) => |
416 let val is = ints_of pargs |
416 let val is = ints_of pargs |
417 in case assoc_string_int(itms,ixn) of |
417 in case Envir.lookup' (env, (ixn, T)) of |
418 NONE => (iTs,match_bind(itms,binders,ixn,is,obj)) |
418 NONE => (iTs,match_bind(itms,binders,ixn,T,is,obj)) |
419 | SOME u => if obj aeconv (red u is []) then env |
419 | SOME u => if obj aeconv (red u is []) then env |
420 else raise MATCH |
420 else raise MATCH |
421 end |
421 end |
422 | _ => |
422 | _ => |
423 let val (oh,oargs) = strip_comb obj |
423 let val (oh,oargs) = strip_comb obj |
433 end; |
433 end; |
434 |
434 |
435 val pT = fastype_of pat |
435 val pT = fastype_of pat |
436 and oT = fastype_of obj |
436 and oT = fastype_of obj |
437 val iTs = typ_match tsg (Vartab.empty, (pT,oT)) |
437 val iTs = typ_match tsg (Vartab.empty, (pT,oT)) |
438 val insts2 = (iTs,[]) |
438 val insts2 = (iTs, Vartab.empty) |
439 |
439 |
440 in apfst Vartab.dest (mtch [] (insts2, po) |
440 in mtch [] (insts2, po) |
441 handle Pattern => fomatch tsg insts2 po) |
441 handle Pattern => fomatch tsg insts2 po |
442 end; |
442 end; |
443 |
443 |
444 (*Predicate: does the pattern match the object?*) |
444 (*Predicate: does the pattern match the object?*) |
445 fun matches tsig po = (match tsig po; true) handle MATCH => false; |
445 fun matches tsig po = (match tsig po; true) handle MATCH => false; |
446 |
446 |
484 val t' = subst_bound (Free (x', T), t); |
484 val t' = subst_bound (Free (x', T), t); |
485 in (fn u => Abs (x, T, abstract_over (Free (x', T), u)), t') end; |
485 in (fn u => Abs (x, T, abstract_over (Free (x', T), u)), t') end; |
486 |
486 |
487 fun match_rew tm (tm1, tm2) = |
487 fun match_rew tm (tm1, tm2) = |
488 let val rtm = getOpt (Term.rename_abs tm1 tm tm2, tm2) |
488 let val rtm = getOpt (Term.rename_abs tm1 tm tm2, tm2) |
489 in SOME (subst_vars (match tsig (tm1, tm)) rtm, rtm) |
489 in SOME (Envir.subst_vars (match tsig (tm1, tm)) rtm, rtm) |
490 handle MATCH => NONE |
490 handle MATCH => NONE |
491 end; |
491 end; |
492 |
492 |
493 fun rew (Abs (_, _, body) $ t) = SOME (subst_bound (t, body), skel0) |
493 fun rew (Abs (_, _, body) $ t) = SOME (subst_bound (t, body), skel0) |
494 | rew tm = (case get_first (match_rew tm) rules of |
494 | rew tm = (case get_first (match_rew tm) rules of |