424 (*Check whether the 'banned' bound var indices occur rigidly in t*) |
424 (*Check whether the 'banned' bound var indices occur rigidly in t*) |
425 fun rigid_bound (lev, banned) t = |
425 fun rigid_bound (lev, banned) t = |
426 let val (head,args) = strip_comb t |
426 let val (head,args) = strip_comb t |
427 in |
427 in |
428 case head of |
428 case head of |
429 Bound i => (i-lev) mem_int banned orelse |
429 Bound i => member (op =) banned (i-lev) orelse |
430 exists (rigid_bound (lev, banned)) args |
430 exists (rigid_bound (lev, banned)) args |
431 | Var _ => false (*no rigid occurrences here!*) |
431 | Var _ => false (*no rigid occurrences here!*) |
432 | Abs (_,_,u) => |
432 | Abs (_,_,u) => |
433 rigid_bound(lev+1, banned) u orelse |
433 rigid_bound(lev+1, banned) u orelse |
434 exists (rigid_bound (lev, banned)) args |
434 exists (rigid_bound (lev, banned)) args |
437 |
437 |
438 (*Squash down indices at level >=lev to delete the banned from a term.*) |
438 (*Squash down indices at level >=lev to delete the banned from a term.*) |
439 fun change_bnos banned = |
439 fun change_bnos banned = |
440 let fun change lev (Bound i) = |
440 let fun change lev (Bound i) = |
441 if i<lev then Bound i |
441 if i<lev then Bound i |
442 else if (i-lev) mem_int banned |
442 else if member (op =) banned (i-lev) |
443 then raise CHANGE_FAIL (**flexible occurrence: give up**) |
443 then raise CHANGE_FAIL (**flexible occurrence: give up**) |
444 else Bound (i - length (List.filter (fn j => j < i-lev) banned)) |
444 else Bound (i - length (List.filter (fn j => j < i-lev) banned)) |
445 | change lev (Abs (a,T,t)) = Abs (a, T, change(lev+1) t) |
445 | change lev (Abs (a,T,t)) = Abs (a, T, change(lev+1) t) |
446 | change lev (t$u) = change lev t $ change lev u |
446 | change lev (t$u) = change lev t $ change lev u |
447 | change lev t = t |
447 | change lev t = t |
498 (*Simplify both terms and check for assignments. |
498 (*Simplify both terms and check for assignments. |
499 Bound vars in the binder are "banned" unless used in both t AND u *) |
499 Bound vars in the binder are "banned" unless used in both t AND u *) |
500 fun clean_ffpair thy ((rbinder, t, u), (env,tpairs)) = |
500 fun clean_ffpair thy ((rbinder, t, u), (env,tpairs)) = |
501 let val loot = loose_bnos t and loou = loose_bnos u |
501 let val loot = loose_bnos t and loou = loose_bnos u |
502 fun add_index (((a,T), j), (bnos, newbinder)) = |
502 fun add_index (((a,T), j), (bnos, newbinder)) = |
503 if j mem_int loot andalso j mem_int loou |
503 if member (op =) loot j andalso member (op =) loou j |
504 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
504 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
505 else (j::bnos, newbinder); (*remove*) |
505 else (j::bnos, newbinder); (*remove*) |
506 val indices = 0 upto (length rbinder - 1); |
506 val indices = 0 upto (length rbinder - 1); |
507 val (banned,rbin') = foldr add_index ([],[]) (rbinder~~indices); |
507 val (banned,rbin') = foldr add_index ([],[]) (rbinder~~indices); |
508 val (env', t') = clean_term banned (env, t); |
508 val (env', t') = clean_term banned (env, t); |