src/Pure/unify.ML
changeset 37720 50a9e2fa4f6b
parent 37637 ade245a81481
child 39116 f14735a88886
equal deleted inserted replaced
37681:6ec40bc934e1 37720:50a9e2fa4f6b
   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