23 | Dict_Var of { var: vname, index: int, length: int, class: class, unique: bool }; |
23 | Dict_Var of { var: vname, index: int, length: int, class: class, unique: bool }; |
24 datatype itype = |
24 datatype itype = |
25 `%% of string * itype list |
25 `%% of string * itype list |
26 | ITyVar of vname; |
26 | ITyVar of vname; |
27 type const = { sym: Code_Symbol.T, typargs: itype list, dicts: dict list list, |
27 type const = { sym: Code_Symbol.T, typargs: itype list, dicts: dict list list, |
28 dom: itype list, annotation: itype option }; |
28 dom: itype list, range: itype, annotation: itype option }; |
29 datatype iterm = |
29 datatype iterm = |
30 IConst of const |
30 IConst of const |
31 | IVar of vname option |
31 | IVar of vname option |
32 | `$ of iterm * iterm |
32 | `$ of iterm * iterm |
33 | `|=> of (vname option * itype) * iterm |
33 | `|=> of (vname option * itype) * (iterm * itype) |
34 | ICase of { term: iterm, typ: itype, clauses: (iterm * iterm) list, primitive: iterm }; |
34 | ICase of { term: iterm, typ: itype, clauses: (iterm * iterm) list, primitive: iterm }; |
35 val `-> : itype * itype -> itype; |
35 val `-> : itype * itype -> itype; |
36 val `--> : itype list * itype -> itype; |
36 val `--> : itype list * itype -> itype; |
37 val `$$ : iterm * iterm list -> iterm; |
37 val `$$ : iterm * iterm list -> iterm; |
38 val `|==> : (vname option * itype) list * iterm -> iterm; |
38 val `|==> : (vname option * itype) list * (iterm * itype) -> iterm; |
39 type typscheme = (vname * sort) list * itype; |
39 type typscheme = (vname * sort) list * itype; |
40 end; |
40 end; |
41 |
41 |
42 signature CODE_THINGOL = |
42 signature CODE_THINGOL = |
43 sig |
43 sig |
46 val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a |
46 val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a |
47 val unfold_fun: itype -> itype list * itype |
47 val unfold_fun: itype -> itype list * itype |
48 val unfold_fun_n: int -> itype -> itype list * itype |
48 val unfold_fun_n: int -> itype -> itype list * itype |
49 val unfold_app: iterm -> iterm * iterm list |
49 val unfold_app: iterm -> iterm * iterm list |
50 val unfold_abs: iterm -> (vname option * itype) list * iterm |
50 val unfold_abs: iterm -> (vname option * itype) list * iterm |
|
51 val unfold_abs_typed: iterm -> ((vname option * itype) list * (iterm * itype)) option |
51 val split_let: iterm -> (((iterm * itype) * iterm) * iterm) option |
52 val split_let: iterm -> (((iterm * itype) * iterm) * iterm) option |
52 val split_let_no_pat: iterm -> (((string option * itype) * iterm) * iterm) option |
53 val split_let_no_pat: iterm -> (((string option * itype) * iterm) * iterm) option |
53 val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm |
54 val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm |
54 val unfold_let_no_pat: iterm -> ((string option * itype) * iterm) list * iterm |
55 val unfold_let_no_pat: iterm -> ((string option * itype) * iterm) list * iterm |
55 val split_pat_abs: iterm -> ((iterm * itype) * iterm) option |
56 val split_pat_abs: iterm -> ((iterm * itype) * iterm) option |
156 val (tys1, ty1) = unfold_fun ty; |
157 val (tys1, ty1) = unfold_fun ty; |
157 val (tys3, tys2) = chop n tys1; |
158 val (tys3, tys2) = chop n tys1; |
158 in (tys3, tys2 `--> ty1) end; |
159 in (tys3, tys2 `--> ty1) end; |
159 |
160 |
160 type const = { sym: Code_Symbol.T, typargs: itype list, dicts: dict list list, |
161 type const = { sym: Code_Symbol.T, typargs: itype list, dicts: dict list list, |
161 dom: itype list, annotation: itype option }; |
162 dom: itype list, range: itype, annotation: itype option }; |
162 |
163 |
163 datatype iterm = |
164 datatype iterm = |
164 IConst of const |
165 IConst of const |
165 | IVar of vname option |
166 | IVar of vname option |
166 | `$ of iterm * iterm |
167 | `$ of iterm * iterm |
167 | `|=> of (vname option * itype) * iterm |
168 | `|=> of (vname option * itype) * (iterm * itype) |
168 | ICase of { term: iterm, typ: itype, clauses: (iterm * iterm) list, primitive: iterm }; |
169 | ICase of { term: iterm, typ: itype, clauses: (iterm * iterm) list, primitive: iterm }; |
169 (*see also signature*) |
170 (*see also signature*) |
170 |
171 |
171 fun is_IVar (IVar _) = true |
172 fun is_IVar (IVar _) = true |
172 | is_IVar _ = false; |
173 | is_IVar _ = false; |
173 |
174 |
174 fun is_IAbs (_ `|=> _) = true |
175 fun is_IAbs (_ `|=> _) = true |
175 | is_IAbs _ = false; |
176 | is_IAbs _ = false; |
176 |
177 |
177 val op `$$ = Library.foldl (op `$); |
178 val op `$$ = Library.foldl (op `$); |
178 val op `|==> = Library.foldr (op `|=>); |
179 fun vs_tys `|==> body = Library.foldr |
|
180 (fn (v_ty as (_, ty), body as (_, rty)) => (v_ty `|=> body, ty `-> rty)) (vs_tys, body) |
|
181 |> fst; |
179 |
182 |
180 val unfold_app = unfoldl |
183 val unfold_app = unfoldl |
181 (fn op `$ t_t => SOME t_t |
184 (fn op `$ t_t => SOME t_t |
182 | _ => NONE); |
185 | _ => NONE); |
183 |
186 |
184 val unfold_abs = unfoldr |
187 val unfold_abs = unfoldr |
185 (fn op `|=> v_t => SOME v_t |
188 (fn (v `|=> (t, _)) => SOME (v, t) |
186 | _ => NONE); |
189 | _ => NONE); |
|
190 |
|
191 fun unfold_abs_typed (v_ty `|=> body) = |
|
192 unfoldr |
|
193 (fn (v_ty `|=> body, _) => SOME (v_ty, body) |
|
194 | _ => NONE) body |
|
195 |> apfst (cons v_ty) |
|
196 |> SOME |
|
197 | unfold_abs_typed _ = NONE |
187 |
198 |
188 fun split_let (ICase { term = t, typ = ty, clauses = [(p, body)], ... }) = |
199 fun split_let (ICase { term = t, typ = ty, clauses = [(p, body)], ... }) = |
189 SOME (((p, ty), t), body) |
200 SOME (((p, ty), t), body) |
190 | split_let _ = NONE; |
201 | split_let _ = NONE; |
191 |
202 |
225 let |
236 let |
226 fun fold_term _ (IConst _) = I |
237 fun fold_term _ (IConst _) = I |
227 | fold_term vs (IVar (SOME v)) = if member (op =) vs v then I else f v |
238 | fold_term vs (IVar (SOME v)) = if member (op =) vs v then I else f v |
228 | fold_term _ (IVar NONE) = I |
239 | fold_term _ (IVar NONE) = I |
229 | fold_term vs (t1 `$ t2) = fold_term vs t1 #> fold_term vs t2 |
240 | fold_term vs (t1 `$ t2) = fold_term vs t1 #> fold_term vs t2 |
230 | fold_term vs ((SOME v, _) `|=> t) = fold_term (insert (op =) v vs) t |
241 | fold_term vs ((SOME v, _) `|=> (t, _)) = fold_term (insert (op =) v vs) t |
231 | fold_term vs ((NONE, _) `|=> t) = fold_term vs t |
242 | fold_term vs ((NONE, _) `|=> (t, _)) = fold_term vs t |
232 | fold_term vs (ICase { term = t, clauses = clauses, ... }) = |
243 | fold_term vs (ICase { term = t, clauses = clauses, ... }) = |
233 fold_term vs t #> fold (fold_clause vs) clauses |
244 fold_term vs t #> fold (fold_clause vs) clauses |
234 and fold_clause vs (p, t) = fold_term (add_vars p vs) t; |
245 and fold_clause vs (p, t) = fold_term (add_vars p vs) t; |
235 in fold_term [] end |
246 in fold_term [] end |
236 fun add_vars t = fold_aux add_vars (insert (op =)) t; |
247 fun add_vars t = fold_aux add_vars (insert (op =)) t; |
243 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false; |
254 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false; |
244 |
255 |
245 fun invent_params used tys = |
256 fun invent_params used tys = |
246 (map o apfst) SOME (Name.invent_names (Name.build_context used) "a" tys); |
257 (map o apfst) SOME (Name.invent_names (Name.build_context used) "a" tys); |
247 |
258 |
248 fun split_pat_abs ((NONE, ty) `|=> t) = SOME ((IVar NONE, ty), t) |
259 fun split_pat_abs ((NONE, ty) `|=> (t, _)) = SOME ((IVar NONE, ty), t) |
249 | split_pat_abs ((SOME v, ty) `|=> t) = SOME (case t |
260 | split_pat_abs ((SOME v, ty) `|=> (t, _)) = SOME (case t |
250 of ICase { term = IVar (SOME w), clauses = [(p, body)], ... } => |
261 of ICase { term = IVar (SOME w), clauses = [(p, body)], ... } => |
251 if v = w andalso (exists_var p v orelse not (exists_var body v)) |
262 if v = w andalso (exists_var p v orelse not (exists_var body v)) |
252 then ((p, ty), body) |
263 then ((p, ty), body) |
253 else ((IVar (SOME v), ty), t) |
264 else ((IVar (SOME v), ty), t) |
254 | _ => ((IVar (SOME v), ty), t)) |
265 | _ => ((IVar (SOME v), ty), t)) |
255 | split_pat_abs _ = NONE; |
266 | split_pat_abs _ = NONE; |
256 |
267 |
257 val unfold_pat_abs = unfoldr split_pat_abs; |
268 val unfold_pat_abs = unfoldr split_pat_abs; |
258 |
269 |
259 fun unfold_abs_eta [] t = ([], t) |
270 fun unfold_abs_eta [] t = ([], t) |
260 | unfold_abs_eta (_ :: tys) ((v, _) `|=> t) = |
271 | unfold_abs_eta (_ :: tys) ((v, _) `|=> (t, _)) = |
261 let |
272 let |
262 val (vs, t') = unfold_abs_eta tys t; |
273 val (vs, t') = unfold_abs_eta tys t; |
263 in (v :: vs, t') end |
274 in (v :: vs, t') end |
264 | unfold_abs_eta tys t = |
275 | unfold_abs_eta tys t = |
265 let |
276 let |
266 val vs = map fst (invent_params (declare_varnames t) tys); |
277 val vs = map fst (invent_params (declare_varnames t) tys); |
267 in (vs, t `$$ map IVar vs) end; |
278 in (vs, t `$$ map IVar vs) end; |
268 |
279 |
269 fun satisfied_application wanted (const as { dom = tys, ... }, ts) = |
280 fun satisfied_application wanted (const as { dom, range, ... }, ts) = |
270 let |
281 let |
271 val given = length ts; |
282 val given = length ts; |
272 val delta = wanted - given; |
283 val delta = wanted - given; |
273 val vs_tys = invent_params (fold declare_varnames ts) |
284 val vs_tys = invent_params (fold declare_varnames ts) |
274 (((take delta o drop given) tys)); |
285 (((take delta o drop given) dom)); |
275 in vs_tys `|==> IConst const `$$ ts @ map (IVar o fst) vs_tys end; |
286 val (_, rty) = unfold_fun_n wanted range; |
|
287 in vs_tys `|==> (IConst const `$$ ts @ map (IVar o fst) vs_tys, rty) end; |
276 |
288 |
277 fun map_terms_bottom_up f (t as IConst _) = f t |
289 fun map_terms_bottom_up f (t as IConst _) = f t |
278 | map_terms_bottom_up f (t as IVar _) = f t |
290 | map_terms_bottom_up f (t as IVar _) = f t |
279 | map_terms_bottom_up f (t1 `$ t2) = f |
291 | map_terms_bottom_up f (t1 `$ t2) = f |
280 (map_terms_bottom_up f t1 `$ map_terms_bottom_up f t2) |
292 (map_terms_bottom_up f t1 `$ map_terms_bottom_up f t2) |
281 | map_terms_bottom_up f ((v, ty) `|=> t) = f |
293 | map_terms_bottom_up f ((v, ty) `|=> (t, rty)) = f |
282 ((v, ty) `|=> map_terms_bottom_up f t) |
294 ((v, ty) `|=> (map_terms_bottom_up f t, rty)) |
283 | map_terms_bottom_up f (ICase { term = t, typ = ty, clauses = clauses, primitive = t0 }) = f |
295 | map_terms_bottom_up f (ICase { term = t, typ = ty, clauses = clauses, primitive = t0 }) = f |
284 (ICase { term = map_terms_bottom_up f t, typ = ty, |
296 (ICase { term = map_terms_bottom_up f t, typ = ty, |
285 clauses = (map o apply2) (map_terms_bottom_up f) clauses, |
297 clauses = (map o apply2) (map_terms_bottom_up f) clauses, |
286 primitive = map_terms_bottom_up f t0 }); |
298 primitive = map_terms_bottom_up f t0 }); |
287 |
299 |
328 and exists_dictss_var f dss = (exists o exists) (exists_dict_var f) dss; |
340 and exists_dictss_var f dss = (exists o exists) (exists_dict_var f) dss; |
329 |
341 |
330 fun contains_dict_var (IConst { dicts = dss, ... }) = exists_dictss_var (K true) dss |
342 fun contains_dict_var (IConst { dicts = dss, ... }) = exists_dictss_var (K true) dss |
331 | contains_dict_var (IVar _) = false |
343 | contains_dict_var (IVar _) = false |
332 | contains_dict_var (t1 `$ t2) = contains_dict_var t1 orelse contains_dict_var t2 |
344 | contains_dict_var (t1 `$ t2) = contains_dict_var t1 orelse contains_dict_var t2 |
333 | contains_dict_var (_ `|=> t) = contains_dict_var t |
345 | contains_dict_var (_ `|=> (t, _)) = contains_dict_var t |
334 | contains_dict_var (ICase { primitive = t, ... }) = contains_dict_var t; |
346 | contains_dict_var (ICase { primitive = t, ... }) = contains_dict_var t; |
335 |
347 |
336 val unambiguous_dictss = not o exists_dictss_var (fn { unique, ... } => not unique); |
348 val unambiguous_dictss = not o exists_dictss_var (fn { unique, ... } => not unique); |
337 |
349 |
338 |
350 |
671 pair (IVar (SOME v)) |
683 pair (IVar (SOME v)) |
672 | translate_term ctxt algbr eqngr permissive some_thm (Abs (v, ty, t), some_abs) = |
684 | translate_term ctxt algbr eqngr permissive some_thm (Abs (v, ty, t), some_abs) = |
673 let |
685 let |
674 val ((v', _), t') = Term.dest_abs_global (Abs (Name.desymbolize (SOME false) v, ty, t)); |
686 val ((v', _), t') = Term.dest_abs_global (Abs (Name.desymbolize (SOME false) v, ty, t)); |
675 val v'' = if Term.used_free v' t' then SOME v' else NONE |
687 val v'' = if Term.used_free v' t' then SOME v' else NONE |
|
688 val rty = fastype_of_tagged_term t' |
676 in |
689 in |
677 translate_typ ctxt algbr eqngr permissive ty |
690 translate_typ ctxt algbr eqngr permissive ty |
|
691 ##>> translate_typ ctxt algbr eqngr permissive rty |
678 ##>> translate_term ctxt algbr eqngr permissive some_thm (t', some_abs) |
692 ##>> translate_term ctxt algbr eqngr permissive some_thm (t', some_abs) |
679 #>> (fn (ty, t) => (v'', ty) `|=> t) |
693 #>> (fn ((ty, rty), t) => (v'', ty) `|=> (t, rty)) |
680 end |
694 end |
681 | translate_term ctxt algbr eqngr permissive some_thm (t as _ $ _, some_abs) = |
695 | translate_term ctxt algbr eqngr permissive some_thm (t as _ $ _, some_abs) = |
682 case strip_comb t |
696 case strip_comb t |
683 of (Const (c, ty), ts) => |
697 of (Const (c, ty), ts) => |
684 translate_app ctxt algbr eqngr permissive some_thm (((c, ty), ts), some_abs) |
698 translate_app ctxt algbr eqngr permissive some_thm (((c, ty), ts), some_abs) |
710 val (dom, range) = Term.strip_type ty'; |
724 val (dom, range) = Term.strip_type ty'; |
711 in |
725 in |
712 ensure_const ctxt algbr eqngr permissive c |
726 ensure_const ctxt algbr eqngr permissive c |
713 ##>> fold_map (translate_typ ctxt algbr eqngr permissive) typargs |
727 ##>> fold_map (translate_typ ctxt algbr eqngr permissive) typargs |
714 ##>> fold_map (translate_dicts ctxt algbr eqngr permissive some_thm) (typargs ~~ sorts) |
728 ##>> fold_map (translate_dicts ctxt algbr eqngr permissive some_thm) (typargs ~~ sorts) |
715 ##>> fold_map (translate_typ ctxt algbr eqngr permissive) (ty' :: dom) |
729 ##>> fold_map (translate_typ ctxt algbr eqngr permissive) (range :: dom) |
716 #>> (fn (((c, typargs), dss), annotation :: dom) => |
730 #>> (fn (((c, typargs), dss), range :: dom) => |
717 IConst { sym = Constant c, typargs = typargs, dicts = dss, |
731 IConst { sym = Constant c, typargs = typargs, dicts = dss, |
718 dom = dom, annotation = |
732 dom = dom, range = range, annotation = |
719 if annotate then SOME annotation else NONE }) |
733 if annotate then SOME (dom `--> range) else NONE }) |
720 end |
734 end |
721 and translate_app_const ctxt algbr eqngr permissive some_thm ((c_ty, ts), some_abs) = |
735 and translate_app_const ctxt algbr eqngr permissive some_thm ((c_ty, ts), some_abs) = |
722 translate_const ctxt algbr eqngr permissive some_thm (c_ty, some_abs) |
736 translate_const ctxt algbr eqngr permissive some_thm (c_ty, some_abs) |
723 ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts |
737 ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts |
724 #>> (fn (t, ts) => t `$$ ts) |
738 #>> (fn (t, ts) => t `$$ ts) |
772 val given = length ts; |
786 val given = length ts; |
773 val delta = wanted - given; |
787 val delta = wanted - given; |
774 val tys = (take delta o drop given o binder_types) ty; |
788 val tys = (take delta o drop given o binder_types) ty; |
775 val used = Name.build_context ((fold o fold_aterms) Term.declare_term_frees ts); |
789 val used = Name.build_context ((fold o fold_aterms) Term.declare_term_frees ts); |
776 val vs_tys = Name.invent_names used "a" tys; |
790 val vs_tys = Name.invent_names used "a" tys; |
|
791 val rty = (drop delta o binder_types) ty ---> body_type ty; |
777 in |
792 in |
778 fold_map (translate_typ ctxt algbr eqngr permissive) tys |
793 fold_map (translate_typ ctxt algbr eqngr permissive) tys |
779 ##>> translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), ts @ map Free vs_tys) |
794 ##>> translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), ts @ map Free vs_tys) |
780 #>> (fn (tys, t) => map2 (fn (v, _) => pair (SOME v)) vs_tys tys `|==> t) |
795 ##>> translate_typ ctxt algbr eqngr permissive rty |
|
796 #>> (fn ((tys, t), rty) => map2 (fn (v, _) => pair (SOME v)) vs_tys tys `|==> (t, rty)) |
781 end |
797 end |
782 else if length ts > wanted then |
798 else if length ts > wanted then |
783 translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), take wanted ts) |
799 translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), take wanted ts) |
784 ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) (drop wanted ts) |
800 ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) (drop wanted ts) |
785 #>> (fn (t, ts) => t `$$ ts) |
801 #>> (fn (t, ts) => t `$$ ts) |