449 let val env = unify_types thy (body_type env T, fastype env (rbinder, u), env) |
449 let val env = unify_types thy (body_type env T, fastype env (rbinder, u), env) |
450 in Envir.vupdate ((vT, Logic.rlist_abs (rbinder, u)), env) end |
450 in Envir.vupdate ((vT, Logic.rlist_abs (rbinder, u)), env) end |
451 end; |
451 end; |
452 |
452 |
453 |
453 |
|
454 (*If an argument contains a banned Bound, then it should be deleted. |
|
455 But if the only path is flexible, this is difficult; the code gives up! |
|
456 In %x y.?a(x) =?= %x y.?b(?c(y)) should we instantiate ?b or ?c *) |
|
457 exception CHANGE_FAIL; (*flexible occurrence of banned variable, or other reason to quit*) |
|
458 |
|
459 |
454 (*Flex argument: a term, its type, and the index that refers to it.*) |
460 (*Flex argument: a term, its type, and the index that refers to it.*) |
455 type flarg = {t: term, T: typ, j: int}; |
461 type flarg = {t: term, T: typ, j: int}; |
456 |
462 |
457 (*Form the arguments into records for deletion/sorting.*) |
463 (*Form the arguments into records for deletion/sorting.*) |
458 fun flexargs ([], [], []) = [] : flarg list |
464 fun flexargs ([], [], []) = [] : flarg list |
459 | flexargs (j :: js, t :: ts, T :: Ts) = {j = j, t = t, T = T} :: flexargs (js, ts, Ts) |
465 | flexargs (j :: js, t :: ts, T :: Ts) = {j = j, t = t, T = T} :: flexargs (js, ts, Ts) |
460 | flexargs _ = raise Fail "flexargs"; |
466 | flexargs _ = raise CHANGE_FAIL; |
461 |
467 (*We give up if we see a variable of function type not applied to a full list of |
462 |
468 arguments (remember, this code assumes that terms are fully eta-expanded). This situation |
463 (*If an argument contains a banned Bound, then it should be deleted. |
469 can occur if a type variable is instantiated with a function type. |
464 But if the only path is flexible, this is difficult; the code gives up! |
470 *) |
465 In %x y.?a(x) =?= %x y.?b(?c(y)) should we instantiate ?b or ?c *) |
|
466 exception CHANGE_FAIL; (*flexible occurrence of banned variable*) |
|
467 |
|
468 |
471 |
469 (*Check whether the 'banned' bound var indices occur rigidly in t*) |
472 (*Check whether the 'banned' bound var indices occur rigidly in t*) |
470 fun rigid_bound (lev, banned) t = |
473 fun rigid_bound (lev, banned) t = |
471 let val (head,args) = strip_comb t in |
474 let val (head,args) = strip_comb t in |
472 (case head of |
475 (case head of |
514 fun clean_term banned (env,t) = |
517 fun clean_term banned (env,t) = |
515 let |
518 let |
516 val (Var (v, T), ts) = strip_comb t; |
519 val (Var (v, T), ts) = strip_comb t; |
517 val (Ts, U) = strip_type env T |
520 val (Ts, U) = strip_type env T |
518 and js = length ts - 1 downto 0; |
521 and js = length ts - 1 downto 0; |
519 val args = sort (make_ord arg_less) (List.foldr (change_arg banned) [] (flexargs (js, ts, Ts))) |
522 val args = sort (make_ord arg_less) (List.foldr (change_arg banned) [] (flexargs (js, ts, Ts))) |
520 val ts' = map #t args; |
523 val ts' = map #t args; |
521 in |
524 in |
522 if decreasing (length Ts) args then (env, (list_comb (Var (v, T), ts'))) |
525 if decreasing (length Ts) args then (env, (list_comb (Var (v, T), ts'))) |
523 else |
526 else |
524 let |
527 let |