src/ZF/Tools/primrec_package.ML
author wenzelm
Tue, 21 Sep 2021 13:14:18 +0200
changeset 74342 5d411d85da8c
parent 74319 54b2e5f771da
child 79336 032a31db4c6f
permissions -rw-r--r--
clarified antiquotations;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
     1
(*  Title:      ZF/Tools/primrec_package.ML
29266
4a478f9d2847 use regular Term.add_vars, Term.add_frees etc.;
wenzelm
parents: 29006
diff changeset
     2
    Author:     Norbert Voelker, FernUni Hagen
4a478f9d2847 use regular Term.add_vars, Term.add_frees etc.;
wenzelm
parents: 29006
diff changeset
     3
    Author:     Stefan Berghofer, TU Muenchen
4a478f9d2847 use regular Term.add_vars, Term.add_frees etc.;
wenzelm
parents: 29006
diff changeset
     4
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
     5
29266
4a478f9d2847 use regular Term.add_vars, Term.add_frees etc.;
wenzelm
parents: 29006
diff changeset
     6
Package for defining functions on datatypes by primitive recursion.
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
     7
*)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
     8
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
     9
signature PRIMREC_PACKAGE =
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    10
sig
71081
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
    11
  val primrec: ((binding * string) * Token.src list) list -> theory -> thm list * theory
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
    12
  val primrec_i: ((binding * term) * attribute list) list -> theory -> thm list * theory
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    13
end;
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    14
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    15
structure PrimrecPackage : PRIMREC_PACKAGE =
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    16
struct
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    17
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    18
exception RecError of string;
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    19
6141
a6922171b396 removal of the (thm list) argument of mk_cases
paulson
parents: 6092
diff changeset
    20
(*Remove outer Trueprop and equality sign*)
74342
5d411d85da8c clarified antiquotations;
wenzelm
parents: 74319
diff changeset
    21
val dest_eqn = FOLogic.dest_eq o \<^dest_judgment>;
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    22
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    23
fun primrec_err s = error ("Primrec definition error:\n" ^ s);
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    24
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    25
fun primrec_eq_err sign s eq =
26939
1035c89b4c02 moved global pretty/string_of functions from Sign to Syntax;
wenzelm
parents: 26478
diff changeset
    26
  primrec_err (s ^ "\nin equation\n" ^ Syntax.string_of_term_global sign eq);
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    27
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    28
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    29
(* preprocessing of equations *)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    30
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    31
(*rec_fn_opt records equations already noted for this function*)
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    32
fun process_eqn thy (eq, rec_fn_opt) =
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    33
  let
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    34
    val (lhs, rhs) =
29266
4a478f9d2847 use regular Term.add_vars, Term.add_frees etc.;
wenzelm
parents: 29006
diff changeset
    35
        if null (Term.add_vars eq []) then
12203
571d9c288640 avoid handle _;
wenzelm
parents: 12188
diff changeset
    36
            dest_eqn eq handle TERM _ => raise RecError "not a proper equation"
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    37
        else raise RecError "illegal schematic variable(s)";
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    38
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    39
    val (recfun, args) = strip_comb lhs;
12203
571d9c288640 avoid handle _;
wenzelm
parents: 12188
diff changeset
    40
    val (fname, ftype) = dest_Const recfun handle TERM _ =>
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    41
      raise RecError "function is not declared as constant in theory";
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    42
67522
9e712280cc37 clarified take/drop/chop prefix/suffix;
wenzelm
parents: 61466
diff changeset
    43
    val (ls_frees, rest)  = chop_prefix is_Free args;
9e712280cc37 clarified take/drop/chop prefix/suffix;
wenzelm
parents: 61466
diff changeset
    44
    val (middle, rs_frees) = chop_suffix is_Free rest;
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    45
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    46
    val (constr, cargs_frees) =
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    47
      if null middle then raise RecError "constructor missing"
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    48
      else strip_comb (hd middle);
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    49
    val (cname, _) = dest_Const constr
12203
571d9c288640 avoid handle _;
wenzelm
parents: 12188
diff changeset
    50
      handle TERM _ => raise RecError "ill-formed constructor";
17412
e26cb20ef0cc TableFun/Symtab: curried lookup and update;
wenzelm
parents: 17314
diff changeset
    51
    val con_info = the (Symtab.lookup (ConstructorsData.get thy) cname)
51930
52fd62618631 prefer explicitly qualified exceptions, which is particular important for robust handlers;
wenzelm
parents: 47815
diff changeset
    52
      handle Option.Option =>
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    53
      raise RecError "cannot determine datatype associated with function"
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    54
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    55
    val (ls, cargs, rs) = (map dest_Free ls_frees,
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    56
                           map dest_Free cargs_frees,
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    57
                           map dest_Free rs_frees)
12203
571d9c288640 avoid handle _;
wenzelm
parents: 12188
diff changeset
    58
      handle TERM _ => raise RecError "illegal argument in pattern";
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    59
    val lfrees = ls @ rs @ cargs;
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    60
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    61
    (*Constructor, frees to left of pattern, pattern variables,
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    62
      frees to right of pattern, rhs of equation, full original equation. *)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    63
    val new_eqn = (cname, (rhs, cargs, eq))
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    64
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    65
  in
18973
f88976608aad has_duplicates;
wenzelm
parents: 18928
diff changeset
    66
    if has_duplicates (op =) lfrees then
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    67
      raise RecError "repeated variable name in pattern"
33038
8f9594c31de4 dropped redundant gen_ prefix
haftmann
parents: 33037
diff changeset
    68
    else if not (subset (op =) (Term.add_frees rhs [], lfrees)) then
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    69
      raise RecError "extra variables on rhs"
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    70
    else if length middle > 1 then
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    71
      raise RecError "more than one non-variable in pattern"
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    72
    else case rec_fn_opt of
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 12876
diff changeset
    73
        NONE => SOME (fname, ftype, ls, rs, con_info, [new_eqn])
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 12876
diff changeset
    74
      | SOME (fname', _, ls', rs', con_info': constructor_info, eqns) =>
17314
04e21a27c0ad introduces some modern-style AList operations
haftmann
parents: 17224
diff changeset
    75
          if AList.defined (op =) eqns cname then
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    76
            raise RecError "constructor already occurred as pattern"
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    77
          else if (ls <> ls') orelse (rs <> rs') then
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    78
            raise RecError "non-recursive arguments are inconsistent"
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    79
          else if #big_rec_name con_info <> #big_rec_name con_info' then
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    80
             raise RecError ("Mixed datatypes for function " ^ fname)
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    81
          else if fname <> fname' then
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    82
             raise RecError ("inconsistent functions for datatype " ^
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    83
                             #big_rec_name con_info)
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 12876
diff changeset
    84
          else SOME (fname, ftype, ls, rs, con_info, new_eqn::eqns)
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    85
  end
20342
wenzelm
parents: 20071
diff changeset
    86
  handle RecError s => primrec_eq_err thy s eq;
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    87
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    88
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    89
(*Instantiates a recursor equation with constructor arguments*)
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
    90
fun inst_recursor ((_ $ constr, rhs), cargs') =
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    91
    subst_atomic (#2 (strip_comb constr) ~~ map Free cargs') rhs;
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    92
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    93
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    94
(*Convert a list of recursion equations into a recursor call*)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    95
fun process_fun thy (fname, ftype, ls, rs, con_info: constructor_info, eqns) =
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    96
  let
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    97
    val fconst = Const(fname, ftype)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    98
    val fabs = list_comb (fconst, map Free ls @ [Bound 0] @ map Free rs)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
    99
    and {big_rec_name, constructors, rec_rewrites, ...} = con_info
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   100
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   101
    (*Replace X_rec(args,t) by fname(ls,t,rs) *)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   102
    fun use_fabs (_ $ t) = subst_bound (t, fabs)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   103
      | use_fabs t       = t
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   104
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   105
    val cnames         = map (#1 o dest_Const) constructors
59582
0fbed69ff081 tuned signature -- prefer qualified names;
wenzelm
parents: 59498
diff changeset
   106
    and recursor_pairs = map (dest_eqn o Thm.concl_of) rec_rewrites
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   107
44241
7943b69f0188 modernized signature of Term.absfree/absdummy;
wenzelm
parents: 43324
diff changeset
   108
    fun absterm (Free x, body) = absfree x body
74319
54b2e5f771da clarified signature -- prefer antiquotations (with subtle change of exception content);
wenzelm
parents: 74294
diff changeset
   109
      | absterm (t, body) = Abs("rec", \<^Type>\<open>i\<close>, abstract_over (t, body))
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   110
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   111
    (*Translate rec equations into function arguments suitable for recursor.
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   112
      Missing cases are replaced by 0 and all cases are put into order.*)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   113
    fun add_case ((cname, recursor_pair), cases) =
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   114
      let val (rhs, recursor_rhs, eq) =
17314
04e21a27c0ad introduces some modern-style AList operations
haftmann
parents: 17224
diff changeset
   115
            case AList.lookup (op =) eqns cname of
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 12876
diff changeset
   116
                NONE => (warning ("no equation for constructor " ^ cname ^
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   117
                                  "\nin definition of function " ^ fname);
74294
ee04dc00bf0a more antiquotations;
wenzelm
parents: 71081
diff changeset
   118
                         (\<^Const>\<open>zero\<close>, #2 recursor_pair, \<^Const>\<open>zero\<close>))
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 12876
diff changeset
   119
              | SOME (rhs, cargs', eq) =>
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   120
                    (rhs, inst_recursor (recursor_pair, cargs'), eq)
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   121
          val allowed_terms = map use_fabs (#2 (strip_comb recursor_rhs))
30190
479806475f3c use long names for old-style fold combinators;
wenzelm
parents: 29579
diff changeset
   122
          val abs = List.foldr absterm rhs allowed_terms
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   123
      in
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   124
          if !Ind_Syntax.trace then
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   125
              writeln ("recursor_rhs = " ^
26939
1035c89b4c02 moved global pretty/string_of functions from Sign to Syntax;
wenzelm
parents: 26478
diff changeset
   126
                       Syntax.string_of_term_global thy recursor_rhs ^
1035c89b4c02 moved global pretty/string_of functions from Sign to Syntax;
wenzelm
parents: 26478
diff changeset
   127
                       "\nabs = " ^ Syntax.string_of_term_global thy abs)
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   128
          else();
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   129
          if Logic.occs (fconst, abs) then
20342
wenzelm
parents: 20071
diff changeset
   130
              primrec_eq_err thy
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   131
                   ("illegal recursive occurrences of " ^ fname)
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   132
                   eq
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   133
          else abs :: cases
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   134
      end
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   135
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   136
    val recursor = head_of (#1 (hd recursor_pairs))
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   137
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   138
    (** make definition **)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   139
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   140
    (*the recursive argument*)
43324
2b47822868e4 discontinued Name.variant to emphasize that this is old-style / indirect;
wenzelm
parents: 41310
diff changeset
   141
    val rec_arg =
2b47822868e4 discontinued Name.variant to emphasize that this is old-style / indirect;
wenzelm
parents: 41310
diff changeset
   142
      Free (singleton (Name.variant_list (map #1 (ls@rs))) (Long_Name.base_name big_rec_name),
74319
54b2e5f771da clarified signature -- prefer antiquotations (with subtle change of exception content);
wenzelm
parents: 74294
diff changeset
   143
        \<^Type>\<open>i\<close>)
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   144
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   145
    val def_tm = Logic.mk_equals
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   146
                    (subst_bound (rec_arg, fabs),
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   147
                     list_comb (recursor,
30190
479806475f3c use long names for old-style fold combinators;
wenzelm
parents: 29579
diff changeset
   148
                                List.foldr add_case [] (cnames ~~ recursor_pairs))
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   149
                     $ rec_arg)
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   150
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   151
  in
6065
3b4a29166f26 induct_tac and exhaust_tac
paulson
parents: 6050
diff changeset
   152
      if !Ind_Syntax.trace then
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   153
            writeln ("primrec def:\n" ^
26939
1035c89b4c02 moved global pretty/string_of functions from Sign to Syntax;
wenzelm
parents: 26478
diff changeset
   154
                     Syntax.string_of_term_global thy def_tm)
6065
3b4a29166f26 induct_tac and exhaust_tac
paulson
parents: 6050
diff changeset
   155
      else();
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30280
diff changeset
   156
      (Long_Name.base_name fname ^ "_" ^ Long_Name.base_name big_rec_name ^ "_def",
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   157
       def_tm)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   158
  end;
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   159
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   160
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   161
(* prepare functions needed for definitions *)
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   162
60003
ba8fa0c38d66 renamed ML funs
blanchet
parents: 59936
diff changeset
   163
fun primrec_i args thy =
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   164
  let
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   165
    val ((eqn_names, eqn_terms), eqn_atts) = apfst split_list (split_list args);
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 12876
diff changeset
   166
    val SOME (fname, ftype, ls, rs, con_info, eqns) =
30190
479806475f3c use long names for old-style fold combinators;
wenzelm
parents: 29579
diff changeset
   167
      List.foldr (process_eqn thy) NONE eqn_terms;
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   168
    val def = process_fun thy (fname, ftype, ls, rs, con_info, eqns);
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   169
18358
0a733e11021a re-oriented some result tuples in PureThy
haftmann
parents: 17985
diff changeset
   170
    val ([def_thm], thy1) = thy
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30280
diff changeset
   171
      |> Sign.add_path (Long_Name.base_name fname)
39557
fe5722fce758 renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
wenzelm
parents: 38514
diff changeset
   172
      |> Global_Theory.add_defs false [Thm.no_attributes (apfst Binding.name def)];
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   173
70474
235396695401 more careful treatment of implicit context;
wenzelm
parents: 69593
diff changeset
   174
    val rewrites = def_thm :: map (mk_meta_eq o Thm.transfer thy1) (#rec_rewrites con_info)
71081
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   175
    val eqn_thms0 =
17985
d5d576b72371 avoid legacy goals;
wenzelm
parents: 17959
diff changeset
   176
      eqn_terms |> map (fn t =>
20046
9c8909fc5865 Goal.prove_global;
wenzelm
parents: 18973
diff changeset
   177
        Goal.prove_global thy1 [] [] (Ind_Syntax.traceIt "next primrec equation = " thy1 t)
58838
59203adfc33f eliminated aliases;
wenzelm
parents: 58011
diff changeset
   178
          (fn {context = ctxt, ...} =>
59498
50b60f501b05 proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
wenzelm
parents: 58838
diff changeset
   179
            EVERY [rewrite_goals_tac ctxt rewrites, resolve_tac ctxt @{thms refl} 1]));
71081
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   180
  in
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   181
    thy1
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   182
    |> Global_Theory.add_thms ((eqn_names ~~ eqn_thms0) ~~ eqn_atts)
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   183
    |-> (fn eqn_thms =>
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   184
      Global_Theory.add_thmss [((Binding.name "simps", eqn_thms), [Simplifier.simp_add])])
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   185
    |>> the_single
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   186
    ||> Sign.parent_path
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   187
  end;
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   188
60003
ba8fa0c38d66 renamed ML funs
blanchet
parents: 59936
diff changeset
   189
fun primrec args thy =
ba8fa0c38d66 renamed ML funs
blanchet
parents: 59936
diff changeset
   190
  primrec_i (map (fn ((name, s), srcs) =>
47815
43f677b3ae91 clarified signature;
wenzelm
parents: 46961
diff changeset
   191
    ((name, Syntax.read_prop_global thy s), map (Attrib.attribute_cmd_global thy) srcs))
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   192
    args) thy;
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   193
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   194
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   195
(* outer syntax *)
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   196
24867
e5b55d7be9bb simplified interfaces for outer syntax;
wenzelm
parents: 24712
diff changeset
   197
val _ =
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 67522
diff changeset
   198
  Outer_Syntax.command \<^command_keyword>\<open>primrec\<close> "define primitive recursive functions on datatypes"
36960
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36954
diff changeset
   199
    (Scan.repeat1 (Parse_Spec.opt_thm_name ":" -- Parse.prop)
71081
45a1fcee14a0 prefer named facts;
wenzelm
parents: 70474
diff changeset
   200
      >> (Toplevel.theory o (#2 oo (primrec o map (fn ((x, y), z) => ((x, z), y))))));
6050
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   201
b3eb3de3a288 new primrec package
paulson
parents:
diff changeset
   202
end;
12183
c10cea75dd56 adapted primrec/datatype to Isar;
wenzelm
parents: 9329
diff changeset
   203