470 (*avoid spurious fixed variables: there is no eigen context for equations*) |
470 (*avoid spurious fixed variables: there is no eigen context for equations*) |
471 in |
471 in |
472 map (apfst (fn (args, (rhs, some_abs)) => (args, |
472 map (apfst (fn (args, (rhs, some_abs)) => (args, |
473 (annotate ctxt' algbr eqngr (c, ty) args rhs, some_abs)))) eqns |
473 (annotate ctxt' algbr eqngr (c, ty) args rhs, some_abs)))) eqns |
474 end; |
474 end; |
|
475 |
|
476 |
|
477 (* preprocessing pattern schemas *) |
|
478 |
|
479 fun preprocess_pattern_schema ctxt (t_pos, case_pats) (c_ty, ts) = |
|
480 let |
|
481 val thy = Proof_Context.theory_of ctxt; |
|
482 val ty = nth (binder_types (snd c_ty)) t_pos; |
|
483 fun select_clauses xs = |
|
484 xs |
|
485 |> nth_drop t_pos |
|
486 |> curry (op ~~) case_pats |
|
487 |> map_filter (fn (NONE, _) => NONE | (SOME _, x) => SOME x); |
|
488 fun mk_constr c t = |
|
489 let |
|
490 val n = Code.args_number thy c; |
|
491 in ((c, (take n o binder_types o fastype_of o untag_term) t ---> ty), n) end; |
|
492 val constrs = |
|
493 if null case_pats then [] |
|
494 else map2 mk_constr (case_pats |> map_filter I) (select_clauses ts); |
|
495 val split_clauses = |
|
496 if null case_pats then (fn ts => (nth ts t_pos, nth_drop t_pos ts)) |
|
497 else (fn ts => (nth ts t_pos, select_clauses ts)); |
|
498 in (ty, constrs, split_clauses) end; |
|
499 |
475 |
500 |
476 (* abstract dictionary construction *) |
501 (* abstract dictionary construction *) |
477 |
502 |
478 datatype typarg_witness = |
503 datatype typarg_witness = |
479 Weakening of (class * class) list * plain_typarg_witness |
504 Weakening of (class * class) list * plain_typarg_witness |
673 translate_const ctxt algbr eqngr permissive some_thm (c_ty, some_abs) |
698 translate_const ctxt algbr eqngr permissive some_thm (c_ty, some_abs) |
674 ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts |
699 ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts |
675 #>> (fn (t, ts) => t `$$ ts) |
700 #>> (fn (t, ts) => t `$$ ts) |
676 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, case_pats) (c_ty, ts) = |
701 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, case_pats) (c_ty, ts) = |
677 let |
702 let |
|
703 val (ty, constrs, split_clauses) = preprocess_pattern_schema ctxt (t_pos, case_pats) (c_ty, ts); |
678 val thy = Proof_Context.theory_of ctxt; |
704 val thy = Proof_Context.theory_of ctxt; |
679 val ty = nth (binder_types (snd c_ty)) t_pos; |
|
680 val is_let = null case_pats; |
|
681 fun select_clauses xs = |
|
682 xs |
|
683 |> nth_drop t_pos |
|
684 |> curry (op ~~) case_pats |
|
685 |> map_filter (fn (NONE, _) => NONE | (SOME _, x) => SOME x); |
|
686 fun mk_constr c t = |
|
687 let |
|
688 val n = Code.args_number thy c; |
|
689 in ((c, (take n o binder_types o fastype_of o untag_term) t ---> ty), n) end; |
|
690 val constrs = |
|
691 if is_let then [] |
|
692 else map2 mk_constr (case_pats |> map_filter I) (select_clauses ts); |
|
693 val split_clauses = |
|
694 if is_let then (fn ts => (nth ts t_pos, nth_drop t_pos ts)) |
|
695 else (fn ts => (nth ts t_pos, select_clauses ts)); |
|
696 fun disjunctive_varnames ts = |
705 fun disjunctive_varnames ts = |
697 let |
706 let |
698 val vs = (fold o fold_varnames) (insert (op =)) ts []; |
707 val vs = (fold o fold_varnames) (insert (op =)) ts []; |
699 in fn pat => null (inter (op =) vs (fold_varnames (insert (op =)) pat [])) end; |
708 in fn pat => null (inter (op =) vs (fold_varnames (insert (op =)) pat [])) end; |
700 fun purge_unused_vars_in t = |
709 fun purge_unused_vars_in t = |
727 val ts = map (IVar o fst) vs; |
736 val ts = map (IVar o fst) vs; |
728 in collapse_clause vs_map ts body end; |
737 in collapse_clause vs_map ts body end; |
729 fun casify constrs ty t_app ts = |
738 fun casify constrs ty t_app ts = |
730 let |
739 let |
731 val (t, ts_clause) = split_clauses ts; |
740 val (t, ts_clause) = split_clauses ts; |
732 val clauses = if null case_pats |
741 val clauses = if null constrs |
733 then map (fn ([t], body) => (t, body)) (mk_clause [ty] (the_single ts_clause)) |
742 then map (fn ([t], body) => (t, body)) (mk_clause [ty] (the_single ts_clause)) |
734 else maps (fn ((constr as IConst { dom = tys, ... }, n), t) => |
743 else maps (fn ((constr as IConst { dom = tys, ... }, n), t) => |
735 map (fn (ts, body) => (constr `$$ ts, body)) (mk_clause (take n tys) t)) |
744 map (fn (ts, body) => (constr `$$ ts, body)) (mk_clause (take n tys) t)) |
736 (constrs ~~ ts_clause); |
745 (constrs ~~ ts_clause); |
737 in ICase { term = t, typ = ty, clauses = clauses, primitive = t_app `$$ ts } end; |
746 in ICase { term = t, typ = ty, clauses = clauses, primitive = t_app `$$ ts } end; |