src/HOL/BNF/Tools/bnf_fp_n2m_sugar.ML
author blanchet
Mon, 04 Nov 2013 15:44:43 +0100
changeset 54245 f91022745c85
parent 54243 a596292be9a8
child 54253 04cd231e2b9e
permissions -rw-r--r--
better error handling
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     1
(*  Title:      HOL/BNF/Tools/bnf_fp_n2m_sugar.ML
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     2
    Author:     Jasmin Blanchette, TU Muenchen
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     3
    Copyright   2013
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     4
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     5
Suggared flattening of nested to mutual (co)recursion.
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     6
*)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     7
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     8
signature BNF_FP_N2M_SUGAR =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     9
sig
54243
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    10
  val unfold_let: term -> term
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    11
  val dest_map: Proof.context -> string -> term -> term * term list
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    12
54009
f138452e8265 got rid of dead feature
blanchet
parents: 54006
diff changeset
    13
  val mutualize_fp_sugars: bool -> BNF_FP_Util.fp_kind -> binding list -> typ list ->
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    14
    (term -> int list) -> term list list list list -> BNF_FP_Def_Sugar.fp_sugar list ->
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
    15
    local_theory ->
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
    16
    (BNF_FP_Def_Sugar.fp_sugar list
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
    17
     * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option))
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
    18
    * local_theory
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    19
  val pad_and_indexify_calls: BNF_FP_Def_Sugar.fp_sugar list -> int ->
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    20
    (term * term list list) list list -> term list list list list
54009
f138452e8265 got rid of dead feature
blanchet
parents: 54006
diff changeset
    21
  val nested_to_mutual_fps: BNF_FP_Util.fp_kind -> binding list -> typ list -> (term -> int list) ->
f138452e8265 got rid of dead feature
blanchet
parents: 54006
diff changeset
    22
    (term * term list list) list list -> local_theory ->
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
    23
    (typ list * int list * BNF_FP_Def_Sugar.fp_sugar list
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
    24
     * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option))
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
    25
    * local_theory
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    26
end;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    27
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    28
structure BNF_FP_N2M_Sugar : BNF_FP_N2M_SUGAR =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    29
struct
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    30
54006
9fe1bd54d437 renamed theory file
blanchet
parents: 53974
diff changeset
    31
open Ctr_Sugar
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    32
open BNF_Util
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    33
open BNF_Def
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    34
open BNF_FP_Util
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    35
open BNF_FP_Def_Sugar
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    36
open BNF_FP_N2M
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    37
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    38
val n2mN = "n2m_"
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    39
54243
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    40
fun unfold_let (Const (@{const_name Let}, _) $ arg1 $ arg2) = unfold_let (betapply (arg2, arg1))
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    41
  | unfold_let (Const (@{const_name prod_case}, _) $ t) =
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    42
    (case unfold_let t of
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    43
      t' as Abs (s1, T1, Abs (s2, T2, _)) =>
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    44
      let
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    45
        val x = (s1 ^ s2, Term.maxidx_of_term t + 1);
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    46
        val v = Var (x, HOLogic.mk_prodT (T1, T2));
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    47
      in
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    48
        lambda v (unfold_let (betapplys (t', [HOLogic.mk_fst v, HOLogic.mk_snd v])))
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    49
      end
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    50
    | _ => t)
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    51
  | unfold_let (t $ u) = betapply (unfold_let t, unfold_let u)
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    52
  | unfold_let (Abs (s, T, t)) = Abs (s, T, unfold_let t)
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    53
  | unfold_let t = t;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    54
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    55
val dummy_var_name = "?f"
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    56
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    57
fun mk_map_pattern ctxt s =
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    58
  let
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    59
    val bnf = the (bnf_of ctxt s);
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    60
    val mapx = map_of_bnf bnf;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    61
    val live = live_of_bnf bnf;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    62
    val (f_Ts, _) = strip_typeN live (fastype_of mapx);
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    63
    val fs = map_index (fn (i, T) => Var ((dummy_var_name, i), T)) f_Ts;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    64
  in
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    65
    (mapx, betapplys (mapx, fs))
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    66
  end;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    67
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    68
fun dest_map ctxt s call =
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    69
  let
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    70
    val (map0, pat) = mk_map_pattern ctxt s;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    71
    val (_, tenv) = fo_match ctxt call pat;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    72
  in
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    73
    (map0, Vartab.fold_rev (fn (_, (_, f)) => cons f) tenv [])
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    74
  end;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    75
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    76
fun dest_abs_or_applied_map_or_ctr _ _ (Abs (_, _, t)) = (Term.dummy, [t])
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    77
  | dest_abs_or_applied_map_or_ctr ctxt s (t as t1 $ _) =
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    78
    (case try (dest_map ctxt s) t1 of
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    79
      SOME res => res
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    80
    | NONE =>
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    81
      let
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    82
        val thy = Proof_Context.theory_of ctxt;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    83
        val map_thms = of_fp_sugar #mapss (the (fp_sugar_of ctxt s))
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    84
        val map_thms' = map (fn thm => thm RS sym RS eq_reflection) map_thms;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    85
        val t' = Raw_Simplifier.rewrite_term thy map_thms' [] t;
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    86
      in
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    87
        if t aconv t' then raise Fail "dest_applied_map_or_ctr"
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    88
        else dest_map ctxt s (fst (dest_comb t'))
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
    89
      end);
54239
9bd91d5d8a7b handle constructor syntax in n2m primcorec
blanchet
parents: 54235
diff changeset
    90
54245
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
    91
fun map_partition f xs =
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
    92
  fold_rev (fn x => fn (ys, (good, bad)) =>
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
    93
      case f x of SOME y => (y :: ys, (x :: good, bad)) | NONE => (ys, (good, x :: bad)))
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
    94
    xs ([], ([], []));
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
    95
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    96
(* TODO: test with sort constraints on As *)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    97
(* TODO: use right sorting order for "fp_sort" w.r.t. original BNFs (?) -- treat new variables
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    98
   as deads? *)
54245
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
    99
fun mutualize_fp_sugars has_nested fp bs fpTs get_indices callssss fp_sugars0 no_defs_lthy0 =
54180
blanchet
parents: 54030
diff changeset
   100
  if has_nested orelse has_duplicates (op =) fpTs then
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   101
    let
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   102
      val thy = Proof_Context.theory_of no_defs_lthy0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   103
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   104
      val qsotm = quote o Syntax.string_of_term no_defs_lthy0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   105
54245
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   106
      fun incompatible_calls t1 t2 =
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   107
        error ("Incompatible " ^ co_prefix fp ^ "recursive calls: " ^ qsotm t1 ^ " vs. " ^
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   108
          qsotm t2);
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   109
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   110
      val b_names = map Binding.name_of bs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   111
      val fp_b_names = map base_name_of_typ fpTs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   112
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   113
      val nn = length fpTs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   114
53974
612505263257 make SML/NJ more happy;
wenzelm
parents: 53808
diff changeset
   115
      fun target_ctr_sugar_of_fp_sugar fpT ({T, index, ctr_sugars, ...} : fp_sugar) =
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   116
        let
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   117
          val rho = Vartab.fold (cons o apsnd snd) (Sign.typ_match thy (T, fpT) Vartab.empty) [];
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   118
          val phi = Morphism.term_morphism (Term.subst_TVars rho);
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   119
        in
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   120
          morph_ctr_sugar phi (nth ctr_sugars index)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   121
        end;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   122
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   123
      val ctr_defss = map (of_fp_sugar #ctr_defss) fp_sugars0;
53476
eb3865c3ee58 include map theorems in datastructure for "primcorec"
blanchet
parents: 53475
diff changeset
   124
      val mapss = map (of_fp_sugar #mapss) fp_sugars0;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   125
      val ctr_sugars0 = map2 target_ctr_sugar_of_fp_sugar fpTs fp_sugars0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   126
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   127
      val ctrss = map #ctrs ctr_sugars0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   128
      val ctr_Tss = map (map fastype_of) ctrss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   129
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   130
      val As' = fold (fold Term.add_tfreesT) ctr_Tss [];
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   131
      val As = map TFree As';
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   132
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   133
      val ((Cs, Xs), no_defs_lthy) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   134
        no_defs_lthy0
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   135
        |> fold Variable.declare_typ As
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   136
        |> mk_TFrees nn
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   137
        ||>> variant_tfrees fp_b_names;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   138
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   139
      fun freeze_fp_default (T as Type (s, Ts)) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   140
          (case find_index (curry (op =) T) fpTs of
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   141
            ~1 => Type (s, map freeze_fp_default Ts)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   142
          | kk => nth Xs kk)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   143
        | freeze_fp_default T = T;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   144
54245
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   145
      fun check_call_dead live_call call =
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   146
        if null (get_indices call) then () else incompatible_calls live_call call;
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   147
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   148
      fun freeze_fp_map (callss, (live_call :: _, dead_calls)) s Ts =
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   149
        (List.app (check_call_dead live_call) dead_calls;
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   150
         Type (s, map2 freeze_fp (flatten_type_args_of_bnf (the (bnf_of no_defs_lthy s)) []
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   151
           (transpose callss)) Ts))
54234
b5310a1b807c make code more robust w.r.t. applied/unapplied map (primrec vs. primcorec)
blanchet
parents: 54180
diff changeset
   152
      and freeze_fp calls (T as Type (s, Ts)) =
54245
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   153
          (case map_partition (try (snd o dest_map no_defs_lthy s)) calls of
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   154
            ([], _) =>
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   155
            (case map_partition (try (snd o dest_abs_or_applied_map_or_ctr no_defs_lthy s)) calls of
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   156
              ([], _) => freeze_fp_default T
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   157
            | callsp => freeze_fp_map callsp s Ts)
f91022745c85 better error handling
blanchet
parents: 54243
diff changeset
   158
          | callsp => freeze_fp_map callsp s Ts)
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   159
        | freeze_fp _ T = T;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   160
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   161
      val ctr_Tsss = map (map binder_types) ctr_Tss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   162
      val ctrXs_Tsss = map2 (map2 (map2 freeze_fp)) callssss ctr_Tsss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   163
      val ctrXs_sum_prod_Ts = map (mk_sumTN_balanced o map HOLogic.mk_tupleT) ctrXs_Tsss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   164
      val Ts = map (body_type o hd) ctr_Tss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   165
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   166
      val ns = map length ctr_Tsss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   167
      val kss = map (fn n => 1 upto n) ns;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   168
      val mss = map (map length) ctr_Tsss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   169
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   170
      val fp_eqs = map dest_TFree Xs ~~ ctrXs_sum_prod_Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   171
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   172
      val base_fp_names = Name.variant_list [] fp_b_names;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   173
      val fp_bs = map2 (fn b_name => fn base_fp_name =>
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   174
          Binding.qualify true b_name (Binding.name (n2mN ^ base_fp_name)))
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   175
        b_names base_fp_names;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   176
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   177
      val (pre_bnfs, (fp_res as {xtor_co_iterss = xtor_co_iterss0, xtor_co_induct,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   178
             dtor_injects, dtor_ctors, xtor_co_iter_thmss, ...}, lthy)) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   179
        fp_bnf (construct_mutualized_fp fp fpTs fp_sugars0) fp_bs As' fp_eqs no_defs_lthy;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   180
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   181
      val nesting_bnfs = nesty_bnfs lthy ctrXs_Tsss As;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   182
      val nested_bnfs = nesty_bnfs lthy ctrXs_Tsss Xs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   183
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   184
      val ((xtor_co_iterss, iters_args_types, coiters_args_types), _) =
53591
b6e2993fd0d3 don't wrongly destroy sum types in coiterators
blanchet
parents: 53476
diff changeset
   185
        mk_co_iters_prelims fp ctr_Tsss fpTs Cs ns mss xtor_co_iterss0 lthy;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   186
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   187
      fun mk_binding b suf = Binding.suffix_name ("_" ^ suf) b;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   188
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   189
      val ((co_iterss, co_iter_defss), lthy) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   190
        fold_map2 (fn b =>
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   191
          (if fp = Least_FP then define_iters [foldN, recN] (the iters_args_types)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   192
           else define_coiters [unfoldN, corecN] (the coiters_args_types))
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   193
            (mk_binding b) fpTs Cs) fp_bs xtor_co_iterss lthy
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   194
        |>> split_list;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   195
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   196
      val rho = tvar_subst thy Ts fpTs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   197
      val ctr_sugar_phi =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   198
        Morphism.compose (Morphism.typ_morphism (Term.typ_subst_TVars rho))
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   199
          (Morphism.term_morphism (Term.subst_TVars rho));
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   200
      val inst_ctr_sugar = morph_ctr_sugar ctr_sugar_phi;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   201
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   202
      val ctr_sugars = map inst_ctr_sugar ctr_sugars0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   203
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   204
      val ((co_inducts, un_fold_thmss, co_rec_thmss, disc_unfold_thmss, disc_corec_thmss,
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   205
            sel_unfold_thmsss, sel_corec_thmsss), fp_sugar_thms) =
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   206
        if fp = Least_FP then
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   207
          derive_induct_iters_thms_for_types pre_bnfs (the iters_args_types) xtor_co_induct
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   208
            xtor_co_iter_thmss nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss ctrss ctr_defss
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   209
            co_iterss co_iter_defss lthy
53808
b3e2022530e3 register codatatypes with Nitpick
blanchet
parents: 53746
diff changeset
   210
          |> `(fn ((_, induct, _), (fold_thmss, rec_thmss, _)) =>
53475
185ad6cf6576 enriched data structure with necessary theorems
blanchet
parents: 53303
diff changeset
   211
            ([induct], fold_thmss, rec_thmss, [], [], [], []))
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   212
          ||> (fn info => (SOME info, NONE))
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   213
        else
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   214
          derive_coinduct_coiters_thms_for_types pre_bnfs (the coiters_args_types) xtor_co_induct
54235
blanchet
parents: 54234
diff changeset
   215
            dtor_injects dtor_ctors xtor_co_iter_thmss nesting_bnfs fpTs Cs Xs ctrXs_Tsss kss mss ns
blanchet
parents: 54234
diff changeset
   216
            ctr_defss ctr_sugars co_iterss co_iter_defss (Proof_Context.export lthy no_defs_lthy)
blanchet
parents: 54234
diff changeset
   217
            lthy
54030
732b53d9b720 don't register equations of the form 'f x = ...' as simp rules, even if they are safe (noncorecursive), because they unfold too aggresively concepts users are likely to want to stay folded
blanchet
parents: 54009
diff changeset
   218
          |> `(fn ((coinduct_thms_pairs, _), (unfold_thmss, corec_thmss, _),
53678
e55bb583342e return right theorems
blanchet
parents: 53591
diff changeset
   219
                  (disc_unfold_thmss, disc_corec_thmss, _), _,
53475
185ad6cf6576 enriched data structure with necessary theorems
blanchet
parents: 53303
diff changeset
   220
                  (sel_unfold_thmsss, sel_corec_thmsss, _)) =>
185ad6cf6576 enriched data structure with necessary theorems
blanchet
parents: 53303
diff changeset
   221
            (map snd coinduct_thms_pairs, unfold_thmss, corec_thmss, disc_unfold_thmss,
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   222
             disc_corec_thmss, sel_unfold_thmsss, sel_corec_thmsss))
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   223
          ||> (fn info => (NONE, SOME info));
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   224
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   225
      val phi = Proof_Context.export_morphism no_defs_lthy no_defs_lthy0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   226
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   227
      fun mk_target_fp_sugar (kk, T) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   228
        {T = T, fp = fp, index = kk, pre_bnfs = pre_bnfs, nested_bnfs = nested_bnfs,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   229
         nesting_bnfs = nesting_bnfs, fp_res = fp_res, ctr_defss = ctr_defss,
53476
eb3865c3ee58 include map theorems in datastructure for "primcorec"
blanchet
parents: 53475
diff changeset
   230
         ctr_sugars = ctr_sugars, co_iterss = co_iterss, mapss = mapss, co_inducts = co_inducts,
53475
185ad6cf6576 enriched data structure with necessary theorems
blanchet
parents: 53303
diff changeset
   231
         co_iter_thmsss = transpose [un_fold_thmss, co_rec_thmss],
185ad6cf6576 enriched data structure with necessary theorems
blanchet
parents: 53303
diff changeset
   232
         disc_co_itersss = transpose [disc_unfold_thmss, disc_corec_thmss],
185ad6cf6576 enriched data structure with necessary theorems
blanchet
parents: 53303
diff changeset
   233
         sel_co_iterssss = transpose [sel_unfold_thmsss, sel_corec_thmsss]}
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   234
        |> morph_fp_sugar phi;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   235
    in
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   236
      ((map_index mk_target_fp_sugar fpTs, fp_sugar_thms), lthy)
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   237
    end
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   238
  else
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   239
    (* TODO: reorder hypotheses and predicates in (co)induction rules? *)
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   240
    ((fp_sugars0, (NONE, NONE)), no_defs_lthy0);
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   241
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   242
fun indexify_callsss fp_sugar callsss =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   243
  let
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   244
    val {ctrs, ...} = of_fp_sugar #ctr_sugars fp_sugar;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   245
    fun do_ctr ctr =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   246
      (case AList.lookup Term.aconv_untyped callsss ctr of
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   247
        NONE => replicate (num_binder_types (fastype_of ctr)) []
54243
a596292be9a8 more robust n2m w.r.t. 'let's
blanchet
parents: 54240
diff changeset
   248
      | SOME callss => map (map (Envir.beta_eta_contract o unfold_let)) callss);
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   249
  in
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   250
    map do_ctr ctrs
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   251
  end;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   252
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   253
fun pad_and_indexify_calls fp_sugars0 = map2 indexify_callsss fp_sugars0 oo pad_list [];
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   254
54009
f138452e8265 got rid of dead feature
blanchet
parents: 54006
diff changeset
   255
fun nested_to_mutual_fps fp actual_bs actual_Ts get_indices actual_callssss0 lthy =
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   256
  let
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   257
    val qsoty = quote o Syntax.string_of_typ lthy;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   258
    val qsotys = space_implode " or " o map qsoty;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   259
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   260
    fun not_co_datatype0 T = error (qsoty T ^ " is not a " ^ co_prefix fp ^ "datatype");
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   261
    fun not_co_datatype (T as Type (s, _)) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   262
        if fp = Least_FP andalso
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   263
           is_some (Datatype_Data.get_info (Proof_Context.theory_of lthy) s) then
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   264
          error (qsoty T ^ " is not a new-style datatype (cf. \"datatype_new\")")
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   265
        else
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   266
          not_co_datatype0 T
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   267
      | not_co_datatype T = not_co_datatype0 T;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   268
    fun not_mutually_nested_rec Ts1 Ts2 =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   269
      error (qsotys Ts1 ^ " is neither mutually recursive with nor nested recursive via " ^
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   270
        qsotys Ts2);
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   271
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   272
    val perm_actual_Ts as Type (_, ty_args0) :: _ =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   273
      sort (int_ord o pairself Term.size_of_typ) actual_Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   274
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   275
    fun check_enrich_with_mutuals _ [] = []
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   276
      | check_enrich_with_mutuals seen ((T as Type (T_name, ty_args)) :: Ts) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   277
        (case fp_sugar_of lthy T_name of
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   278
          SOME ({fp = fp', fp_res = {Ts = Ts', ...}, ...}) =>
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   279
          if fp = fp' then
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   280
            let
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   281
              val mutual_Ts = map (fn Type (s, _) => Type (s, ty_args)) Ts';
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   282
              val _ =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   283
                seen = [] orelse exists (exists_subtype_in seen) mutual_Ts orelse
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   284
                not_mutually_nested_rec mutual_Ts seen;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   285
              val (seen', Ts') = List.partition (member (op =) mutual_Ts) Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   286
            in
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   287
              mutual_Ts @ check_enrich_with_mutuals (seen @ T :: seen') Ts'
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   288
            end
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   289
          else
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   290
            not_co_datatype T
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   291
        | NONE => not_co_datatype T)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   292
      | check_enrich_with_mutuals _ (T :: _) = not_co_datatype T;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   293
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   294
    val perm_Ts = check_enrich_with_mutuals [] perm_actual_Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   295
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   296
    val missing_Ts = perm_Ts |> subtract (op =) actual_Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   297
    val Ts = actual_Ts @ missing_Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   298
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   299
    val nn = length Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   300
    val kks = 0 upto nn - 1;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   301
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   302
    val common_name = mk_common_name (map Binding.name_of actual_bs);
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   303
    val bs = pad_list (Binding.name common_name) nn actual_bs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   304
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   305
    fun permute xs = permute_like (op =) Ts perm_Ts xs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   306
    fun unpermute perm_xs = permute_like (op =) perm_Ts Ts perm_xs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   307
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   308
    val perm_bs = permute bs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   309
    val perm_kks = permute kks;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   310
    val perm_fp_sugars0 = map (the o fp_sugar_of lthy o fst o dest_Type) perm_Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   311
54180
blanchet
parents: 54030
diff changeset
   312
    val has_nested = exists (fn Type (_, ty_args) => ty_args <> ty_args0) Ts;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   313
    val perm_callssss = pad_and_indexify_calls perm_fp_sugars0 nn actual_callssss0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   314
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   315
    val get_perm_indices = map (fn kk => find_index (curry (op =) kk) perm_kks) o get_indices;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   316
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   317
    val ((perm_fp_sugars, fp_sugar_thms), lthy) =
54180
blanchet
parents: 54030
diff changeset
   318
      mutualize_fp_sugars has_nested fp perm_bs perm_Ts get_perm_indices perm_callssss
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   319
        perm_fp_sugars0 lthy;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   320
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   321
    val fp_sugars = unpermute perm_fp_sugars;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   322
  in
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53678
diff changeset
   323
    ((missing_Ts, perm_kks, fp_sugars, fp_sugar_thms), lthy)
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   324
  end;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   325
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   326
end;