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; |