src/Tools/Code/code_thingol.ML
changeset 75356 fa014f31f208
parent 75355 26206ade1a23
child 75357 9257e7732766
equal deleted inserted replaced
75355:26206ade1a23 75356:fa014f31f208
    60   val contains_dict_var: iterm -> bool
    60   val contains_dict_var: iterm -> bool
    61   val unambiguous_dictss: dict list list -> bool
    61   val unambiguous_dictss: dict list list -> bool
    62   val add_constsyms: iterm -> Code_Symbol.T list -> Code_Symbol.T list
    62   val add_constsyms: iterm -> Code_Symbol.T list -> Code_Symbol.T list
    63   val add_tyconames: iterm -> string list -> string list
    63   val add_tyconames: iterm -> string list -> string list
    64   val fold_varnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a
    64   val fold_varnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a
       
    65   val add_varnames: iterm -> string list -> string list
    65 
    66 
    66   datatype stmt =
    67   datatype stmt =
    67       NoStmt
    68       NoStmt
    68     | Fun of (typscheme * ((iterm list * iterm) * (thm option * bool)) list) * thm option
    69     | Fun of (typscheme * ((iterm list * iterm) * (thm option * bool)) list) * thm option
    69     | Datatype of vname list *
    70     | Datatype of vname list *
   231         and fold_clause vs (p, t) = fold_term (add_vars p vs) t;
   232         and fold_clause vs (p, t) = fold_term (add_vars p vs) t;
   232       in fold_term [] end
   233       in fold_term [] end
   233     fun add_vars t = fold_aux add_vars (insert (op =)) t;
   234     fun add_vars t = fold_aux add_vars (insert (op =)) t;
   234   in fold_aux add_vars f end;
   235   in fold_aux add_vars f end;
   235 
   236 
       
   237 val add_varnames = fold_varnames (insert (op =));
       
   238 
       
   239 val declare_varnames = fold_varnames Name.declare;
       
   240 
   236 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false;
   241 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false;
   237 
   242 
   238 fun split_pat_abs ((NONE, ty) `|=> t) = SOME ((IVar NONE, ty), t)
   243 fun split_pat_abs ((NONE, ty) `|=> t) = SOME ((IVar NONE, ty), t)
   239   | split_pat_abs ((SOME v, ty) `|=> t) = SOME (case t
   244   | split_pat_abs ((SOME v, ty) `|=> t) = SOME (case t
   240      of ICase { term = IVar (SOME w), clauses = [(p, body)], ... } =>
   245      of ICase { term = IVar (SOME w), clauses = [(p, body)], ... } =>
   251       let
   256       let
   252         val (vs_tys, t') = unfold_abs_eta tys t;
   257         val (vs_tys, t') = unfold_abs_eta tys t;
   253       in (v_ty :: vs_tys, t') end
   258       in (v_ty :: vs_tys, t') end
   254   | unfold_abs_eta tys t =
   259   | unfold_abs_eta tys t =
   255       let
   260       let
   256         val ctxt = fold_varnames Name.declare t Name.context;
   261         val ctxt = Name.build_context (declare_varnames t);
   257         val vs_tys = (map o apfst) SOME (Name.invent_names ctxt "a" tys);
   262         val vs_tys = (map o apfst) SOME (Name.invent_names ctxt "a" tys);
   258       in (vs_tys, t `$$ map (IVar o fst) vs_tys) end;
   263       in (vs_tys, t `$$ map (IVar o fst) vs_tys) end;
   259 
   264 
   260 fun eta_expand k (const as { dom = tys, ... }, ts) =
   265 fun eta_expand k (const as { dom = tys, ... }, ts) =
   261   let
   266   let
   262     val j = length ts;
   267     val j = length ts;
   263     val l = k - j;
   268     val l = k - j;
   264     val _ = if l > length tys
   269     val _ = if l > length tys
   265       then error "Impossible eta-expansion" else ();
   270       then error "Impossible eta-expansion" else ();
   266     val vars = (fold o fold_varnames) Name.declare ts Name.context;
   271     val vars = Name.build_context (fold declare_varnames ts);
   267     val vs_tys = (map o apfst) SOME
   272     val vs_tys = (map o apfst) SOME
   268       (Name.invent_names vars "a" ((take l o drop j) tys));
   273       (Name.invent_names vars "a" ((take l o drop j) tys));
   269   in vs_tys `|==> IConst const `$$ ts @ map (IVar o fst) vs_tys end;
   274   in vs_tys `|==> IConst const `$$ ts @ map (IVar o fst) vs_tys end;
   270 
   275 
   271 fun map_terms_bottom_up f (t as IConst _) = f t
   276 fun map_terms_bottom_up f (t as IConst _) = f t
   287           then []
   292           then []
   288           else [(pat_args, body)]
   293           else [(pat_args, body)]
   289       | distill vs_map pat_args
   294       | distill vs_map pat_args
   290         (body as ICase { term = IVar (SOME v), clauses = clauses, ... }) =
   295         (body as ICase { term = IVar (SOME v), clauses = clauses, ... }) =
   291           let
   296           let
   292             val vs = build ((fold o fold_varnames) (insert (op =)) pat_args);
   297             val vs = build (fold add_varnames pat_args);
   293             fun varnames_disjunctive pat =
   298             fun varnames_disjunctive pat =
   294               null (inter (op =) vs (build (fold_varnames (insert (op =)) pat)));
   299               null (inter (op =) vs (build (add_varnames pat)));
   295             fun purge_unused_vars_in t =
   300             fun purge_unused_vars_in t =
   296               let
   301               let
   297                 val vs = build (fold_varnames (insert (op =)) t);
   302                 val vs = build (add_varnames t);
   298               in
   303               in
   299                 map_terms_bottom_up (fn IVar (SOME v) =>
   304                 map_terms_bottom_up (fn IVar (SOME v) =>
   300                   IVar (if member (op =) vs v then SOME v else NONE) | t => t)
   305                   IVar (if member (op =) vs v then SOME v else NONE) | t => t)
   301               end;
   306               end;
   302           in
   307           in