src/Tools/Code/code_thingol.ML
changeset 48072 ace701efe203
parent 48003 1d11af40b106
child 48074 c6d514717d7b
equal deleted inserted replaced
48071:d7864276bca8 48072:ace701efe203
    16   type vname = string;
    16   type vname = string;
    17   datatype dict =
    17   datatype dict =
    18       Dict of string list * plain_dict
    18       Dict of string list * plain_dict
    19   and plain_dict = 
    19   and plain_dict = 
    20       Dict_Const of string * dict list list
    20       Dict_Const of string * dict list list
    21     | Dict_Var of vname * (int * int)
    21     | Dict_Var of vname * (int * int);
    22   datatype itype =
    22   datatype itype =
    23       `%% of string * itype list
    23       `%% of string * itype list
    24     | ITyVar of vname;
    24     | ITyVar of vname;
    25   type const = string * (((itype list * dict list list) * (itype list * itype)) * bool)
    25   type const = { name: string, typargs: itype list, dicts: dict list list,
    26     (* (f [T1..Tn] {dicts} (_::S1) .. (_::Sm)) :: S =^= (f, ((([T1..Tn], dicts), ([S1..Sm], S)), ambiguous)) *)
    26     dom: itype list, range: itype, annotate: bool };
    27   datatype iterm =
    27   datatype iterm =
    28       IConst of const
    28       IConst of const
    29     | IVar of vname option
    29     | IVar of vname option
    30     | `$ of iterm * iterm
    30     | `$ of iterm * iterm
    31     | `|=> of (vname option * itype) * iterm
    31     | `|=> of (vname option * itype) * iterm
    32     | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
    32     | ICase of { term: iterm, typ: itype, clauses: (iterm * iterm) list, primitive: iterm };
    33         (*((term, type), [(selector pattern, body term )]), primitive term)*)
       
    34   val `$$ : iterm * iterm list -> iterm;
    33   val `$$ : iterm * iterm list -> iterm;
    35   val `|==> : (vname option * itype) list * iterm -> iterm;
    34   val `|==> : (vname option * itype) list * iterm -> iterm;
    36   type typscheme = (vname * sort) list * itype;
    35   type typscheme = (vname * sort) list * itype;
    37 end;
    36 end;
    38 
    37 
    75         ((string * vname list (*type argument wrt. canonical order*)) * itype list) list)
    74         ((string * vname list (*type argument wrt. canonical order*)) * itype list) list)
    76     | Datatypecons of string * string
    75     | Datatypecons of string * string
    77     | Class of class * (vname * ((class * string) list * (string * itype) list))
    76     | Class of class * (vname * ((class * string) list * (string * itype) list))
    78     | Classrel of class * class
    77     | Classrel of class * class
    79     | Classparam of string * class
    78     | Classparam of string * class
    80     | Classinst of (class * (string * (vname * sort) list) (*class and arity*))
    79     | Classinst of { class: string, tyco: string, vs: (vname * sort) list,
    81           * ((class * (string * (string * dict list list))) list (*super instances*)
    80         superinsts: (class * (string * (string * dict list list))) list,
    82         * (((string * const) * (thm * bool)) list (*class parameter instances*)
    81         inst_params: ((string * const) * (thm * bool)) list,
    83           * ((string * const) * (thm * bool)) list (*super class parameter instances*)))
    82         superinst_params: ((string * const) * (thm * bool)) list };
    84   type program = stmt Graph.T
    83   type program = stmt Graph.T
    85   val empty_funs: program -> string list
    84   val empty_funs: program -> string list
    86   val map_terms_bottom_up: (iterm -> iterm) -> iterm -> iterm
    85   val map_terms_bottom_up: (iterm -> iterm) -> iterm -> iterm
    87   val map_terms_stmt: (iterm -> iterm) -> stmt -> stmt
    86   val map_terms_stmt: (iterm -> iterm) -> stmt -> stmt
    88   val is_cons: program -> string -> bool
    87   val is_cons: program -> string -> bool
   124 
   123 
   125 fun unfoldr dest x =
   124 fun unfoldr dest x =
   126   case dest x
   125   case dest x
   127    of NONE => ([], x)
   126    of NONE => ([], x)
   128     | SOME (x1, x2) =>
   127     | SOME (x1, x2) =>
   129         let val (xs', x') = unfoldr dest x2 in (x1::xs', x') end;
   128         let val (xs', x') = unfoldr dest x2 in (x1 :: xs', x') end;
   130 
   129 
   131 
   130 
   132 (** language core - types, terms **)
   131 (** language core - types, terms **)
   133 
   132 
   134 type vname = string;
   133 type vname = string;
   135 
   134 
   136 datatype dict =
   135 datatype dict =
   137     Dict of string list * plain_dict
   136     Dict of string list * plain_dict
   138 and plain_dict = 
   137 and plain_dict = 
   139     Dict_Const of string * dict list list
   138     Dict_Const of string * dict list list
   140   | Dict_Var of vname * (int * int)
   139   | Dict_Var of vname * (int * int);
   141 
   140 
   142 datatype itype =
   141 datatype itype =
   143     `%% of string * itype list
   142     `%% of string * itype list
   144   | ITyVar of vname;
   143   | ITyVar of vname;
   145 
   144 
   146 type const = string * (((itype list * dict list list) *
   145 type const = { name: string, typargs: itype list, dicts: dict list list,
   147   (itype list (*types of arguments*) * itype (*result type*))) * bool (*requires type annotation*))
   146   dom: itype list, range: itype, annotate: bool };
   148 
   147 
   149 datatype iterm =
   148 datatype iterm =
   150     IConst of const
   149     IConst of const
   151   | IVar of vname option
   150   | IVar of vname option
   152   | `$ of iterm * iterm
   151   | `$ of iterm * iterm
   153   | `|=> of (vname option * itype) * iterm
   152   | `|=> of (vname option * itype) * iterm
   154   | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
   153   | ICase of { term: iterm, typ: itype, clauses: (iterm * iterm) list, primitive: iterm };
   155     (*see also signature*)
   154     (*see also signature*)
   156 
   155 
   157 fun is_IVar (IVar _) = true
   156 fun is_IVar (IVar _) = true
   158   | is_IVar _ = false;
   157   | is_IVar _ = false;
   159 
   158 
   170 val unfold_abs = unfoldr
   169 val unfold_abs = unfoldr
   171   (fn op `|=> t => SOME t
   170   (fn op `|=> t => SOME t
   172     | _ => NONE);
   171     | _ => NONE);
   173 
   172 
   174 val split_let = 
   173 val split_let = 
   175   (fn ICase (((td, ty), [(p, t)]), _) => SOME (((p, ty), td), t)
   174   (fn ICase { term = t, typ = ty, clauses = [(p, body)], ... } => SOME (((p, ty), t), body)
   176     | _ => NONE);
   175     | _ => NONE);
   177 
   176 
   178 val unfold_let = unfoldr split_let;
   177 val unfold_let = unfoldr split_let;
   179 
   178 
   180 fun unfold_const_app t =
   179 fun unfold_const_app t =
   186   let
   185   let
   187     fun fold' (IConst c) = f c
   186     fun fold' (IConst c) = f c
   188       | fold' (IVar _) = I
   187       | fold' (IVar _) = I
   189       | fold' (t1 `$ t2) = fold' t1 #> fold' t2
   188       | fold' (t1 `$ t2) = fold' t1 #> fold' t2
   190       | fold' (_ `|=> t) = fold' t
   189       | fold' (_ `|=> t) = fold' t
   191       | fold' (ICase (((t, _), ds), _)) = fold' t
   190       | fold' (ICase { term = t, clauses = clauses, ... }) = fold' t
   192           #> fold (fn (pat, body) => fold' pat #> fold' body) ds
   191           #> fold (fn (p, body) => fold' p #> fold' body) clauses
   193   in fold' end;
   192   in fold' end;
   194 
   193 
   195 val add_constnames = fold_constexprs (fn (c, _) => insert (op =) c);
   194 val add_constnames = fold_constexprs (fn { name = c, ... } => insert (op =) c);
   196 
   195 
   197 fun add_tycos (tyco `%% tys) = insert (op =) tyco #> fold add_tycos tys
   196 fun add_tycos (tyco `%% tys) = insert (op =) tyco #> fold add_tycos tys
   198   | add_tycos (ITyVar _) = I;
   197   | add_tycos (ITyVar _) = I;
   199 
   198 
   200 val add_tyconames = fold_constexprs (fn (_, (((tys, _), _), _)) => fold add_tycos tys);
   199 val add_tyconames = fold_constexprs (fn { typargs = tys, ... } => fold add_tycos tys);
   201 
   200 
   202 fun fold_varnames f =
   201 fun fold_varnames f =
   203   let
   202   let
   204     fun fold_aux add f =
   203     fun fold_aux add f =
   205       let
   204       let
   207           | fold_term vs (IVar (SOME v)) = if member (op =) vs v then I else f v
   206           | fold_term vs (IVar (SOME v)) = if member (op =) vs v then I else f v
   208           | fold_term _ (IVar NONE) = I
   207           | fold_term _ (IVar NONE) = I
   209           | fold_term vs (t1 `$ t2) = fold_term vs t1 #> fold_term vs t2
   208           | fold_term vs (t1 `$ t2) = fold_term vs t1 #> fold_term vs t2
   210           | fold_term vs ((SOME v, _) `|=> t) = fold_term (insert (op =) v vs) t
   209           | fold_term vs ((SOME v, _) `|=> t) = fold_term (insert (op =) v vs) t
   211           | fold_term vs ((NONE, _) `|=> t) = fold_term vs t
   210           | fold_term vs ((NONE, _) `|=> t) = fold_term vs t
   212           | fold_term vs (ICase (((t, _), ds), _)) = fold_term vs t #> fold (fold_case vs) ds
   211           | fold_term vs (ICase { term = t, clauses = clauses, ... }) = fold_term vs t #> fold (fold_case vs) clauses
   213         and fold_case vs (p, t) = fold_term (add p vs) t;
   212         and fold_case vs (p, t) = fold_term (add p vs) t;
   214       in fold_term [] end;
   213       in fold_term [] end;
   215     fun add t = fold_aux add (insert (op =)) t;
   214     fun add t = fold_aux add (insert (op =)) t;
   216   in fold_aux add f end;
   215   in fold_aux add f end;
   217 
   216 
   218 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false;
   217 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false;
   219 
   218 
   220 fun split_pat_abs ((NONE, ty) `|=> t) = SOME ((IVar NONE, ty), t)
   219 fun split_pat_abs ((NONE, ty) `|=> t) = SOME ((IVar NONE, ty), t)
   221   | split_pat_abs ((SOME v, ty) `|=> t) = SOME (case t
   220   | split_pat_abs ((SOME v, ty) `|=> t) = SOME (case t
   222      of ICase (((IVar (SOME w), _), [(p, t')]), _) =>
   221      of ICase { term = IVar (SOME w), clauses = [(p, body)], ... } =>
   223           if v = w andalso (exists_var p v orelse not (exists_var t' v))
   222           if v = w andalso (exists_var p v orelse not (exists_var body v))
   224           then ((p, ty), t')
   223           then ((p, ty), body)
   225           else ((IVar (SOME v), ty), t)
   224           else ((IVar (SOME v), ty), t)
   226       | _ => ((IVar (SOME v), ty), t))
   225       | _ => ((IVar (SOME v), ty), t))
   227   | split_pat_abs _ = NONE;
   226   | split_pat_abs _ = NONE;
   228 
   227 
   229 val unfold_pat_abs = unfoldr split_pat_abs;
   228 val unfold_pat_abs = unfoldr split_pat_abs;
   237       let
   236       let
   238         val ctxt = fold_varnames Name.declare t Name.context;
   237         val ctxt = fold_varnames Name.declare t Name.context;
   239         val vs_tys = (map o apfst) SOME (Name.invent_names ctxt "a" tys);
   238         val vs_tys = (map o apfst) SOME (Name.invent_names ctxt "a" tys);
   240       in (vs_tys, t `$$ map (IVar o fst) vs_tys) end;
   239       in (vs_tys, t `$$ map (IVar o fst) vs_tys) end;
   241 
   240 
   242 fun eta_expand k (c as (name, ((_, (tys, _)), _)), ts) =
   241 fun eta_expand k (const as { name = c, dom = tys, ... }, ts) =
   243   let
   242   let
   244     val j = length ts;
   243     val j = length ts;
   245     val l = k - j;
   244     val l = k - j;
   246     val _ = if l > length tys
   245     val _ = if l > length tys
   247       then error ("Impossible eta-expansion for constant " ^ quote name) else ();
   246       then error ("Impossible eta-expansion for constant " ^ quote c) else ();
   248     val ctxt = (fold o fold_varnames) Name.declare ts Name.context;
   247     val ctxt = (fold o fold_varnames) Name.declare ts Name.context;
   249     val vs_tys = (map o apfst) SOME
   248     val vs_tys = (map o apfst) SOME
   250       (Name.invent_names ctxt "a" ((take l o drop j) tys));
   249       (Name.invent_names ctxt "a" ((take l o drop j) tys));
   251   in vs_tys `|==> IConst c `$$ ts @ map (IVar o fst) vs_tys end;
   250   in vs_tys `|==> IConst const `$$ ts @ map (IVar o fst) vs_tys end;
   252 
   251 
   253 fun contains_dict_var t =
   252 fun contains_dict_var t =
   254   let
   253   let
   255     fun cont_dict (Dict (_, d)) = cont_plain_dict d
   254     fun cont_dict (Dict (_, d)) = cont_plain_dict d
   256     and cont_plain_dict (Dict_Const (_, dss)) = (exists o exists) cont_dict dss
   255     and cont_plain_dict (Dict_Const (_, dss)) = (exists o exists) cont_dict dss
   257       | cont_plain_dict (Dict_Var _) = true;
   256       | cont_plain_dict (Dict_Var _) = true;
   258     fun cont_term (IConst (_, (((_, dss), _), _))) = (exists o exists) cont_dict dss
   257     fun cont_term (IConst { dicts = dss, ... }) = (exists o exists) cont_dict dss
   259       | cont_term (IVar _) = false
   258       | cont_term (IVar _) = false
   260       | cont_term (t1 `$ t2) = cont_term t1 orelse cont_term t2
   259       | cont_term (t1 `$ t2) = cont_term t1 orelse cont_term t2
   261       | cont_term (_ `|=> t) = cont_term t
   260       | cont_term (_ `|=> t) = cont_term t
   262       | cont_term (ICase (_, t)) = cont_term t;
   261       | cont_term (ICase { primitive = t, ... }) = cont_term t;
   263   in cont_term t end;
   262   in cont_term t end;
   264 
   263 
   265 
   264 
   266 (** namings **)
   265 (** namings **)
   267 
   266 
   425   | Datatype of string * (vname list * ((string * vname list) * itype list) list)
   424   | Datatype of string * (vname list * ((string * vname list) * itype list) list)
   426   | Datatypecons of string * string
   425   | Datatypecons of string * string
   427   | Class of class * (vname * ((class * string) list * (string * itype) list))
   426   | Class of class * (vname * ((class * string) list * (string * itype) list))
   428   | Classrel of class * class
   427   | Classrel of class * class
   429   | Classparam of string * class
   428   | Classparam of string * class
   430   | Classinst of (class * (string * (vname * sort) list))
   429   | Classinst of { class: string, tyco: string, vs: (vname * sort) list,
   431         * ((class * (string * (string * dict list list))) list
   430       superinsts: (class * (string * (string * dict list list))) list,
   432       * (((string * const) * (thm * bool)) list
   431       inst_params: ((string * const) * (thm * bool)) list,
   433         * ((string * const) * (thm * bool)) list))
   432       superinst_params: ((string * const) * (thm * bool)) list };
   434       (*see also signature*);
       
   435 
   433 
   436 type program = stmt Graph.T;
   434 type program = stmt Graph.T;
   437 
   435 
   438 fun empty_funs program =
   436 fun empty_funs program =
   439   Graph.fold (fn (_, (Fun (c, ((_, []), _)), _)) => cons c | _ => I) program [];
   437   Graph.fold (fn (_, (Fun (c, ((_, []), _)), _)) => cons c | _ => I) program [];
   442   | map_terms_bottom_up f (t as IVar _) = f t
   440   | map_terms_bottom_up f (t as IVar _) = f t
   443   | map_terms_bottom_up f (t1 `$ t2) = f
   441   | map_terms_bottom_up f (t1 `$ t2) = f
   444       (map_terms_bottom_up f t1 `$ map_terms_bottom_up f t2)
   442       (map_terms_bottom_up f t1 `$ map_terms_bottom_up f t2)
   445   | map_terms_bottom_up f ((v, ty) `|=> t) = f
   443   | map_terms_bottom_up f ((v, ty) `|=> t) = f
   446       ((v, ty) `|=> map_terms_bottom_up f t)
   444       ((v, ty) `|=> map_terms_bottom_up f t)
   447   | map_terms_bottom_up f (ICase (((t, ty), ps), t0)) = f
   445   | map_terms_bottom_up f (ICase { term = t, typ = ty, clauses = clauses, primitive = t0 }) = f
   448       (ICase (((map_terms_bottom_up f t, ty), (map o pairself)
   446       (ICase { term = map_terms_bottom_up f t, typ = ty,
   449         (map_terms_bottom_up f) ps), map_terms_bottom_up f t0));
   447         clauses = (map o pairself) (map_terms_bottom_up f) clauses,
       
   448         primitive = map_terms_bottom_up f t0 });
   450 
   449 
   451 fun map_classparam_instances_as_term f =
   450 fun map_classparam_instances_as_term f =
   452   (map o apfst o apsnd) (fn const => case f (IConst const) of IConst const' => const')
   451   (map o apfst o apsnd) (fn const => case f (IConst const) of IConst const' => const')
   453 
   452 
   454 fun map_terms_stmt f NoStmt = NoStmt
   453 fun map_terms_stmt f NoStmt = NoStmt
   457   | map_terms_stmt f (stmt as Datatype _) = stmt
   456   | map_terms_stmt f (stmt as Datatype _) = stmt
   458   | map_terms_stmt f (stmt as Datatypecons _) = stmt
   457   | map_terms_stmt f (stmt as Datatypecons _) = stmt
   459   | map_terms_stmt f (stmt as Class _) = stmt
   458   | map_terms_stmt f (stmt as Class _) = stmt
   460   | map_terms_stmt f (stmt as Classrel _) = stmt
   459   | map_terms_stmt f (stmt as Classrel _) = stmt
   461   | map_terms_stmt f (stmt as Classparam _) = stmt
   460   | map_terms_stmt f (stmt as Classparam _) = stmt
   462   | map_terms_stmt f (Classinst (arity, (super_instances, classparam_instances))) =
   461   | map_terms_stmt f (Classinst { class, tyco, vs, superinsts,
   463       Classinst (arity, (super_instances, (pairself o map_classparam_instances_as_term) f classparam_instances));
   462       inst_params, superinst_params }) =
       
   463         Classinst { class = class, tyco = tyco, vs = vs, superinsts = superinsts,
       
   464           inst_params = map_classparam_instances_as_term f inst_params,
       
   465           superinst_params = map_classparam_instances_as_term f superinst_params };
   464 
   466 
   465 fun is_cons program name = case Graph.get_node program name
   467 fun is_cons program name = case Graph.get_node program name
   466  of Datatypecons _ => true
   468  of Datatypecons _ => true
   467   | _ => false;
   469   | _ => false;
   468 
   470 
   482           val Class (super, _) = Graph.get_node program super;
   484           val Class (super, _) = Graph.get_node program super;
   483         in
   485         in
   484           quote (Proof_Context.extern_class ctxt sub ^ " < " ^ Proof_Context.extern_class ctxt super)
   486           quote (Proof_Context.extern_class ctxt sub ^ " < " ^ Proof_Context.extern_class ctxt super)
   485         end
   487         end
   486     | Classparam (c, _) => quote (Code.string_of_const thy c)
   488     | Classparam (c, _) => quote (Code.string_of_const thy c)
   487     | Classinst ((class, (tyco, _)), _) =>
   489     | Classinst { class, tyco, ... } =>
   488         let
   490         let
   489           val Class (class, _) = Graph.get_node program class;
   491           val Class (class, _) = Graph.get_node program class;
   490           val Datatype (tyco, _) = Graph.get_node program tyco;
   492           val Datatype (tyco, _) = Graph.get_node program tyco;
   491         in
   493         in
   492           quote (Proof_Context.extern_type ctxt tyco ^ " :: " ^ Proof_Context.extern_class ctxt class)
   494           quote (Proof_Context.extern_type ctxt tyco ^ " :: " ^ Proof_Context.extern_class ctxt class)
   676       #>> Classrel;
   678       #>> Classrel;
   677   in ensure_stmt lookup_classrel (declare_classrel thy) stmt_classrel (sub_class, super_class) end
   679   in ensure_stmt lookup_classrel (declare_classrel thy) stmt_classrel (sub_class, super_class) end
   678 and ensure_inst thy (algbr as (_, algebra)) eqngr permissive (class, tyco) =
   680 and ensure_inst thy (algbr as (_, algebra)) eqngr permissive (class, tyco) =
   679   let
   681   let
   680     val super_classes = (Sorts.minimize_sort algebra o Sorts.super_classes algebra) class;
   682     val super_classes = (Sorts.minimize_sort algebra o Sorts.super_classes algebra) class;
   681     val these_classparams = these o try (#params o AxClass.get_info thy);
   683     val these_class_params = these o try (#params o AxClass.get_info thy);
   682     val classparams = these_classparams class;
   684     val class_params = these_class_params class;
   683     val further_classparams = maps these_classparams
   685     val superclass_params = maps these_class_params
   684       ((Sorts.complete_sort algebra o Sorts.super_classes algebra) class);
   686       ((Sorts.complete_sort algebra o Sorts.super_classes algebra) class);
   685     val vs = Name.invent_names Name.context "'a" (Sorts.mg_domain algebra tyco [class]);
   687     val vs = Name.invent_names Name.context "'a" (Sorts.mg_domain algebra tyco [class]);
   686     val sorts' = Sorts.mg_domain (Sign.classes_of thy) tyco [class];
   688     val sorts' = Sorts.mg_domain (Sign.classes_of thy) tyco [class];
   687     val vs' = map2 (fn (v, sort1) => fn sort2 => (v,
   689     val vs' = map2 (fn (v, sort1) => fn sort2 => (v,
   688       Sorts.inter_sort (Sign.classes_of thy) (sort1, sort2))) vs sorts';
   690       Sorts.inter_sort (Sign.classes_of thy) (sort1, sort2))) vs sorts';
   708     val stmt_inst =
   710     val stmt_inst =
   709       ensure_class thy algbr eqngr permissive class
   711       ensure_class thy algbr eqngr permissive class
   710       ##>> ensure_tyco thy algbr eqngr permissive tyco
   712       ##>> ensure_tyco thy algbr eqngr permissive tyco
   711       ##>> fold_map (translate_tyvar_sort thy algbr eqngr permissive) vs
   713       ##>> fold_map (translate_tyvar_sort thy algbr eqngr permissive) vs
   712       ##>> fold_map translate_super_instance super_classes
   714       ##>> fold_map translate_super_instance super_classes
   713       ##>> fold_map translate_classparam_instance classparams
   715       ##>> fold_map translate_classparam_instance class_params
   714       ##>> fold_map translate_classparam_instance further_classparams
   716       ##>> fold_map translate_classparam_instance superclass_params
   715       #>> (fn (((((class, tyco), arity_args), super_instances),
   717       #>> (fn (((((class, tyco), vs), superinsts), inst_params), superinst_params) =>
   716         classparam_instances), further_classparam_instances) =>
   718           Classinst { class = class, tyco = tyco, vs = vs,
   717           Classinst ((class, (tyco, arity_args)), (super_instances,
   719             superinsts = superinsts, inst_params = inst_params, superinst_params = superinst_params });
   718             (classparam_instances, further_classparam_instances))));
       
   719   in ensure_stmt lookup_instance (declare_instance thy) stmt_inst (class, tyco) end
   720   in ensure_stmt lookup_instance (declare_instance thy) stmt_inst (class, tyco) end
   720 and translate_typ thy algbr eqngr permissive (TFree (v, _)) =
   721 and translate_typ thy algbr eqngr permissive (TFree (v, _)) =
   721       pair (ITyVar (unprefix "'" v))
   722       pair (ITyVar (unprefix "'" v))
   722   | translate_typ thy algbr eqngr permissive (Type (tyco, tys)) =
   723   | translate_typ thy algbr eqngr permissive (Type (tyco, tys)) =
   723       ensure_tyco thy algbr eqngr permissive tyco
   724       ensure_tyco thy algbr eqngr permissive tyco
   757     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   758     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   758         andalso Code.is_abstr thy c
   759         andalso Code.is_abstr thy c
   759         then translation_error thy permissive some_thm
   760         then translation_error thy permissive some_thm
   760           "Abstraction violation" ("constant " ^ Code.string_of_const thy c)
   761           "Abstraction violation" ("constant " ^ Code.string_of_const thy c)
   761       else ()
   762       else ()
   762     val (annotate, ty') = dest_tagged_type ty
   763     val (annotate, ty') = dest_tagged_type ty;
   763     val arg_typs = Sign.const_typargs thy (c, ty');
   764     val typargs = Sign.const_typargs thy (c, ty');
   764     val sorts = Code_Preproc.sortargs eqngr c;
   765     val sorts = Code_Preproc.sortargs eqngr c;
   765     val (function_typs, body_typ) = Term.strip_type ty';
   766     val (dom, range) = Term.strip_type ty';
   766   in
   767   in
   767     ensure_const thy algbr eqngr permissive c
   768     ensure_const thy algbr eqngr permissive c
   768     ##>> fold_map (translate_typ thy algbr eqngr permissive) arg_typs
   769     ##>> fold_map (translate_typ thy algbr eqngr permissive) typargs
   769     ##>> fold_map (translate_dicts thy algbr eqngr permissive some_thm) (arg_typs ~~ sorts)
   770     ##>> fold_map (translate_dicts thy algbr eqngr permissive some_thm) (typargs ~~ sorts)
   770     ##>> fold_map (translate_typ thy algbr eqngr permissive) (body_typ :: function_typs)
   771     ##>> fold_map (translate_typ thy algbr eqngr permissive) (range :: dom)
   771     #>> (fn (((c, arg_typs), dss), body_typ :: function_typs) =>
   772     #>> (fn (((c, typargs), dss), range :: dom) =>
   772       IConst (c, (((arg_typs, dss), (function_typs, body_typ)), annotate)))
   773       IConst { name = c, typargs = typargs, dicts = dss,
       
   774         dom = dom, range = range, annotate = annotate })
   773   end
   775   end
   774 and translate_app_const thy algbr eqngr permissive some_thm ((c_ty, ts), some_abs) =
   776 and translate_app_const thy algbr eqngr permissive some_thm ((c_ty, ts), some_abs) =
   775   translate_const thy algbr eqngr permissive some_thm (c_ty, some_abs)
   777   translate_const thy algbr eqngr permissive some_thm (c_ty, some_abs)
   776   ##>> fold_map (translate_term thy algbr eqngr permissive some_thm o rpair NONE) ts
   778   ##>> fold_map (translate_term thy algbr eqngr permissive some_thm o rpair NONE) ts
   777   #>> (fn (t, ts) => t `$$ ts)
   779   #>> (fn (t, ts) => t `$$ ts)
   786             val n = Code.args_number thy c;
   788             val n = Code.args_number thy c;
   787           in SOME ((c, arg_types n (fastype_of (untag_term t)) ---> ty), n) end;
   789           in SOME ((c, arg_types n (fastype_of (untag_term t)) ---> ty), n) end;
   788     val constrs =
   790     val constrs =
   789       if null case_pats then []
   791       if null case_pats then []
   790       else map_filter I (map2 mk_constr case_pats (nth_drop t_pos ts));
   792       else map_filter I (map2 mk_constr case_pats (nth_drop t_pos ts));
   791     fun casify naming constrs ty ts =
   793     fun casify naming constrs ty t_app ts =
   792       let
   794       let
   793         val undefineds = map_filter (lookup_const naming) (Code.undefineds thy);
   795         val undefineds = map_filter (lookup_const naming) (Code.undefineds thy);
   794         fun collapse_clause vs_map ts body =
   796         fun collapse_clause vs_map ts body =
   795           let
   797           let
   796           in case body
   798           in case body
   797            of IConst (c, _) => if member (op =) undefineds c
   799            of IConst { name = c, ... } => if member (op =) undefineds c
   798                 then []
   800                 then []
   799                 else [(ts, body)]
   801                 else [(ts, body)]
   800             | ICase (((IVar (SOME v), _), subclauses), _) =>
   802             | ICase { term = IVar (SOME v), clauses = clauses, ... } =>
   801                 if forall (fn (pat', body') => exists_var pat' v
   803                 if forall (fn (pat', body') => exists_var pat' v
   802                   orelse not (exists_var body' v)) subclauses
   804                   orelse not (exists_var body' v)) clauses
   803                 then case AList.lookup (op =) vs_map v
   805                 then case AList.lookup (op =) vs_map v
   804                  of SOME i => maps (fn (pat', body') =>
   806                  of SOME i => maps (fn (pat', body') =>
   805                       collapse_clause (AList.delete (op =) v vs_map)
   807                       collapse_clause (AList.delete (op =) v vs_map)
   806                         (nth_map i (K pat') ts) body') subclauses
   808                         (nth_map i (K pat') ts) body') clauses
   807                   | NONE => [(ts, body)]
   809                   | NONE => [(ts, body)]
   808                 else [(ts, body)]
   810                 else [(ts, body)]
   809             | _ => [(ts, body)]
   811             | _ => [(ts, body)]
   810           end;
   812           end;
   811         fun mk_clause mk tys t =
   813         fun mk_clause mk tys t =
   816           in map mk (collapse_clause vs_map ts body) end;
   818           in map mk (collapse_clause vs_map ts body) end;
   817         val t = nth ts t_pos;
   819         val t = nth ts t_pos;
   818         val ts_clause = nth_drop t_pos ts;
   820         val ts_clause = nth_drop t_pos ts;
   819         val clauses = if null case_pats
   821         val clauses = if null case_pats
   820           then mk_clause (fn ([t], body) => (t, body)) [ty] (the_single ts_clause)
   822           then mk_clause (fn ([t], body) => (t, body)) [ty] (the_single ts_clause)
   821           else maps (fn ((constr as IConst (_, ((_, (tys, _)), _)), n), t) =>
   823           else maps (fn ((constr as IConst { dom = tys, ... }, n), t) =>
   822             mk_clause (fn (ts, body) => (constr `$$ ts, body)) (take n tys) t)
   824             mk_clause (fn (ts, body) => (constr `$$ ts, body)) (take n tys) t)
   823               (constrs ~~ (map_filter (fn (NONE, _) => NONE | (SOME _, t) => SOME t)
   825               (constrs ~~ (map_filter (fn (NONE, _) => NONE | (SOME _, t) => SOME t)
   824                 (case_pats ~~ ts_clause)));
   826                 (case_pats ~~ ts_clause)));
   825       in ((t, ty), clauses) end;
   827       in ICase { term = t, typ = ty, clauses = clauses, primitive = t_app `$$ ts } end;
   826   in
   828   in
   827     translate_const thy algbr eqngr permissive some_thm (c_ty, NONE)
   829     translate_const thy algbr eqngr permissive some_thm (c_ty, NONE)
   828     ##>> fold_map (fn (constr, n) => translate_const thy algbr eqngr permissive some_thm (constr, NONE)
   830     ##>> fold_map (fn (constr, n) => translate_const thy algbr eqngr permissive some_thm (constr, NONE)
   829       #>> rpair n) constrs
   831       #>> rpair n) constrs
   830     ##>> translate_typ thy algbr eqngr permissive ty
   832     ##>> translate_typ thy algbr eqngr permissive ty
   831     ##>> fold_map (translate_term thy algbr eqngr permissive some_thm o rpair NONE) ts
   833     ##>> fold_map (translate_term thy algbr eqngr permissive some_thm o rpair NONE) ts
   832     #-> (fn (((t, constrs), ty), ts) =>
   834     #-> (fn (((t, constrs), ty), ts) =>
   833       `(fn (_, (naming, _)) => ICase (casify naming constrs ty ts, t `$$ ts)))
   835       `(fn (_, (naming, _)) => casify naming constrs ty t ts))
   834   end
   836   end
   835 and translate_app_case thy algbr eqngr permissive some_thm (case_scheme as (num_args, _)) ((c, ty), ts) =
   837 and translate_app_case thy algbr eqngr permissive some_thm (case_scheme as (num_args, _)) ((c, ty), ts) =
   836   if length ts < num_args then
   838   if length ts < num_args then
   837     let
   839     let
   838       val k = length ts;
   840       val k = length ts;