src/HOL/Data_Structures/Define_Time_Function.ML
author haftmann
Thu, 19 Jun 2025 17:15:40 +0200
changeset 82734 89347c0cc6a3
parent 82081 50dd4fc40fcb
permissions -rw-r--r--
treat map_filter similar to list_all, list_ex, list_ex1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
     1
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
     2
signature TIMING_FUNCTIONS =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
     3
sig
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
     4
type 'a wctxt = {
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
     5
  ctxt: local_theory,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
     6
  origins: term list,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
     7
  f: term -> 'a
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
     8
}
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
     9
type 'a converter = {
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    10
  constc : 'a wctxt -> term -> 'a,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    11
  funcc : 'a wctxt -> term -> term list -> 'a,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    12
  ifc : 'a wctxt -> typ -> term -> term -> term -> 'a,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    13
  casec : 'a wctxt -> term -> term list -> 'a,
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    14
  letc : 'a wctxt -> typ -> term -> (string * typ) list -> term -> 'a
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    15
}
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    16
val walk : local_theory -> term list -> 'a converter -> term -> 'a
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    17
val Iconst : term wctxt -> term -> term
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    18
val Ifunc : term wctxt -> term -> term list -> term
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    19
val Iif : term wctxt -> typ -> term -> term -> term -> term
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    20
val Icase : term wctxt -> term -> term list -> term
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    21
val Ilet : term wctxt -> typ -> term -> (string * typ) list -> term -> term
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    22
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    23
type pfunc = { names : string list, terms : term list, typs : typ list }
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    24
val fun_pretty':  Proof.context -> pfunc -> Pretty.T
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    25
val fun_pretty:  Proof.context -> Function.info -> Pretty.T
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    26
val print_timing':  Proof.context -> pfunc -> pfunc -> unit
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    27
val print_timing:  Proof.context -> Function.info -> Function.info -> unit
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    28
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    29
type time_config = {
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    30
  print: bool,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    31
  simp: bool,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    32
  partial: bool
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    33
}
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    34
datatype result = Function of Function.info | PartialFunction of thm
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    35
val reg_and_proove_time_func: local_theory -> term list -> term list
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    36
      -> time_config -> result * local_theory
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    37
val reg_time_func: local_theory -> term list -> term list
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    38
      -> time_config -> result * local_theory
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    39
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    40
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    41
val time_dom_tac: Proof.context -> thm -> thm list -> int -> tactic
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    42
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
    43
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    44
end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    45
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    46
structure Timing_Functions : TIMING_FUNCTIONS =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    47
struct
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    48
(* Configure config variable to adjust the prefix *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    49
val bprefix = Attrib.setup_config_string @{binding "time_prefix"} (K "T_")
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    50
val bprefix_snd = Attrib.setup_config_string @{binding "time_prefix_snd"} (K "T2_")
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    51
(* Configure config variable to adjust the suffix *)
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    52
val bsuffix = Attrib.setup_config_string @{binding "time_suffix"} (K "")
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    53
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    54
(* Extracts terms from function info *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    55
fun terms_of_info (info: Function.info) =
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    56
  map Thm.prop_of (case #simps info of SOME s => s
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    57
                                     | NONE => error "No terms of function found in info")
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    58
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    59
type pfunc = {
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    60
  names : string list,
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    61
  terms : term list,
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    62
  typs : typ list
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    63
}
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    64
fun info_pfunc (info: Function.info): pfunc =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    65
let
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    66
  val {defname, fs, ...} = info;
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    67
  val T = case hd fs of (Const (_,T)) => T
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    68
                      | (Free (_,T)) => T
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
    69
                      | _ => error "Internal error: Invalid info to print"
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    70
in
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    71
  { names=[Binding.name_of defname], terms=terms_of_info info, typs=[T] }
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    72
end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    73
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    74
(* Auxiliary functions for printing functions *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    75
fun fun_pretty' ctxt (pfunc: pfunc) =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    76
let
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    77
  val {names, terms, typs} = pfunc;
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    78
  val header_beg = Pretty.str "fun ";
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    79
  fun prepHeadCont (nm,T) = [Pretty.str (nm ^ " :: "), (Pretty.quote (Syntax.pretty_typ ctxt T))]
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    80
  val header_content =
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    81
     List.concat (prepHeadCont (hd names,hd typs) :: map ((fn l => Pretty.str "\nand " :: l) o prepHeadCont) (ListPair.zip (tl names, tl typs)));
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    82
  val header_end = Pretty.str " where\n  ";
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    83
  val header = [header_beg] @ header_content @ [header_end];
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    84
  fun separate sep prts =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    85
    flat (Library.separate [Pretty.str sep] (map single prts));
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    86
  val ptrms = (separate "\n| " (map (Syntax.pretty_term ctxt) terms));
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    87
in
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    88
  Pretty.text_fold (header @ ptrms)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    89
end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    90
fun fun_pretty ctxt = fun_pretty' ctxt o info_pfunc
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    91
fun print_timing' ctxt (opfunc: pfunc) (tpfunc: pfunc) =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    92
let
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
    93
  val {names, ...} = opfunc;
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    94
  val poriginal = Pretty.item [Pretty.str "Original function:\n", fun_pretty' ctxt opfunc]
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    95
  val ptiming = Pretty.item [Pretty.str ("Running time function:\n"), fun_pretty' ctxt tpfunc]
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
    96
in
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    97
  Pretty.writeln (Pretty.text_fold [
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    98
      Pretty.str ("Converting " ^ (hd names) ^ (String.concat (map (fn nm => ", " ^ nm) (tl names))) ^ "\n"),
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
    99
      poriginal, Pretty.str "\n", ptiming])
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   100
end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   101
fun print_timing ctxt (oinfo: Function.info) (tinfo: Function.info) =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   102
  print_timing' ctxt (info_pfunc oinfo) (info_pfunc tinfo)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   103
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   104
fun print_lemma ctxt defs (T_terms: term list) =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   105
let
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   106
  val names =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   107
    defs
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   108
    |> map snd
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   109
    |> map (fn s => "_" ^ s)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   110
    |> List.foldr (op ^) ""
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   111
  val begin = "lemma T" ^ names ^ "_simps [simp,code]:\n"
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   112
  fun convLine T_term =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   113
    "  \"" ^ Syntax.string_of_term ctxt T_term ^ "\"\n"
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   114
  val lines = map convLine T_terms
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   115
  fun convDefs def = " " ^ (fst def)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   116
  val proof = "  by (simp_all add:" :: (map convDefs defs) @ [")"]
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   117
  val _ = Pretty.writeln (Pretty.str "Characteristic recursion equations can be derived:")
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   118
in
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   119
  (begin :: lines @ proof)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   120
  |> String.concat
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   121
  (* |> Active.sendback_markup_properties [Markup.padding_fun] *)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   122
  |> Pretty.str
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   123
  |> Pretty.writeln
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   124
end
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   125
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   126
fun contains l e = exists (fn e' => e' = e) l
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   127
fun contains' comp l e = exists (comp e) l
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   128
(* Split name by . *)
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   129
val split_name = String.fields (fn s => s = #".")
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   130
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   131
(* returns true if it's an if term *)
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   132
fun is_if (Const (@{const_name "HOL.If"},_)) = true
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   133
  | is_if _ = false
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   134
(* returns true if it's a case term *)
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   135
fun is_case (Const (n,_)) = n |> split_name |> List.last |> String.isPrefix "case_"
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   136
  | is_case _ = false
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   137
(* returns true if it's a let term *)
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   138
fun is_let (Const (@{const_name "HOL.Let"},_)) = true
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   139
  | is_let _ = false
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   140
(* Convert string name of function to its timing equivalent *)
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   141
fun fun_name_to_time' ctxt s second name =
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   142
let
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   143
  val prefix = Config.get ctxt (if second then bprefix_snd else bprefix)
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   144
  val suffix = (if s then Config.get ctxt bsuffix else "")
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   145
  fun replace_last_name [n] = [prefix ^ n ^ suffix]
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   146
    | replace_last_name (n::ns) = n :: (replace_last_name ns)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   147
    | replace_last_name _ = error "Internal error: Invalid function name to convert"
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   148
  val parts = split_name name
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   149
in
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   150
  String.concatWith "." (replace_last_name parts)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   151
end
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   152
fun fun_name_to_time ctxt s name = fun_name_to_time' ctxt s false name
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   153
(* Count number of arguments of a function *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   154
fun count_args (Type (n, [_,res])) = (if n = "fun" then 1 + count_args res else 0)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   155
  | count_args _ = 0
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   156
(* Check if number of arguments matches function *)
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   157
fun check_args s (t, args) =
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   158
    (if length args = count_args (type_of t) then ()
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   159
     else error ("Partial applications/Lambdas not allowed (" ^ s ^ ")"))
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   160
(* Removes Abs *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   161
fun rem_abs f (Abs (_,_,t)) = rem_abs f t
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   162
  | rem_abs f t = f t
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   163
(* Map right side of equation *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   164
fun map_r f (pT $ (eq $ l $ r)) = (pT $ (eq $ l $ f r))
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   165
  | map_r _ _ = error "Internal error: No right side of equation found"
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   166
(* Get left side of equation *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   167
fun get_l (_ $ (_ $ l $ _)) = l
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   168
  | get_l _ = error "Internal error: No left side of equation found"
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   169
(* Get right side of equation *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   170
fun get_r (_ $ (_ $ _ $ r)) = r
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   171
  | get_r _ = error "Internal error: No right side of equation found"
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   172
(* Return name of Const *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   173
fun Const_name (Const (nm,_)) = SOME nm
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   174
  | Const_name _ = NONE
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   175
fun is_Used (Type ("Product_Type.prod", _)) = true
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   176
  | is_Used _ = false
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   177
(* Custom compare function for types ignoring variable names *)
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   178
fun typ_comp (Type (A,a)) (Type (B,b)) = (A = B) andalso List.foldl (fn ((c,i),s) => typ_comp c i andalso s) true (ListPair.zip (a, b))
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   179
  | typ_comp (Type _) _ = false
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   180
  | typ_comp _ (Type _) = false
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   181
  | typ_comp _ _ = true
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   182
fun const_comp (Const (nm,T)) (Const (nm',T')) = nm = nm' andalso typ_comp T T'
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   183
  | const_comp _ _ = false
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   184
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   185
type 'a wctxt = {
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   186
  ctxt: local_theory,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   187
  origins: term list,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   188
  f: term -> 'a
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   189
}
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   190
type 'a converter = {
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   191
  constc : 'a wctxt -> term -> 'a,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   192
  funcc : 'a wctxt -> term -> term list -> 'a,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   193
  ifc : 'a wctxt -> typ -> term -> term -> term -> 'a,
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   194
  casec : 'a wctxt -> term -> term list -> 'a,
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   195
  letc : 'a wctxt -> typ -> term -> (string * typ) list -> term -> 'a
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   196
}
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   197
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   198
(* Walks over term and calls given converter *)
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   199
fun list_abs ([], t) = t
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   200
  | list_abs (a::abs,t) = list_abs (abs,t) |> absfree a
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   201
fun walk ctxt (origin: term list) (conv as {ifc, casec, funcc, letc, ...} : 'a converter) (t as _ $ _) =
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   202
  let
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   203
    val (f, args) = strip_comb t
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   204
    val this = (walk ctxt origin conv)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   205
    val _ = (case f of Abs _ => error "Lambdas not supported" | _ => ())
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   206
    val wctxt = {ctxt = ctxt, origins = origin, f = this}
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   207
  in
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   208
    (if is_if f then
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   209
      (case f of (Const (_,T)) =>
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   210
        (case args of [cond, t, f] => ifc wctxt T cond t f
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   211
                   | _ => error "Partial applications not supported (if)")
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   212
               | _ => error "Internal error: invalid if term")
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   213
      else if is_case f then casec wctxt f args
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   214
      else if is_let f then
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   215
      (case f of (Const (_,lT)) =>
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   216
         (case args of [exp, t] =>
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   217
            let val (abs,t) = Term.strip_abs_eta 1 t in letc wctxt lT exp abs t end
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   218
                     | _ => error "Partial applications not allowed (let)")
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   219
               | _ => error "Internal error: invalid let term")
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   220
      else funcc wctxt f args)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   221
  end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   222
  | walk ctxt origin (conv as {constc, ...}) c = 
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   223
      constc {ctxt = ctxt, origins = origin, f = walk ctxt origin conv} c
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   224
fun Ifunc (wctxt: term wctxt) t args = list_comb (#f wctxt t,map (#f wctxt) args)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   225
val Iconst = K I
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   226
fun Iif (wctxt: term wctxt) T cond tt tf =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   227
  Const (@{const_name "HOL.If"}, T) $ (#f wctxt cond) $ (#f wctxt tt) $ (#f wctxt tf)
81358
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   228
fun Icase (wctxt: term wctxt) t cs = list_comb
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   229
  (#f wctxt t,map (fn c => c |> Term.strip_abs_eta (c |> fastype_of |> strip_type |> fst |> length) ||> #f wctxt |> list_abs) cs)
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   230
fun Ilet (wctxt: term wctxt) lT exp abs t =
81358
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   231
  Const (@{const_name "HOL.Let"}, lT) $ (#f wctxt exp) $ list_abs (abs, #f wctxt t)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   232
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   233
(* 1. Fix all terms *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   234
(* Exchange Var in types and terms to Free *)
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   235
fun freeTerms (Var(ixn,T)) = Free (fst ixn, T)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   236
  | freeTerms t = t
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   237
fun freeTypes (TVar ((t, _), T)) = TFree (t, T)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   238
  | freeTypes t = t
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   239
fun fix_definition (Const ("Pure.eq", _) $ l $ r) = HOLogic.mk_Trueprop (HOLogic.mk_eq (l,r))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   240
  | fix_definition t = t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   241
fun check_definition [t] = [t]
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   242
  | check_definition _ = error "Only a single definition is allowed"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   243
fun get_terms theory (term: term) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   244
let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   245
  val equations = Spec_Rules.retrieve theory term
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   246
      |> map #rules
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   247
      |> map (map Thm.prop_of)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   248
   handle Empty => error "Function or terms of function not found"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   249
in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   250
  equations
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   251
    |> map (map fix_definition)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   252
    |> filter (List.exists
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   253
        (fn t => typ_comp (t |> get_l |> strip_comb |> fst |> dest_Const |> snd) (term |> strip_comb |> fst |> dest_Const |> snd)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   254
    |> hd
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   255
end
79542
b941924a407d define_time_function: avoid unused let's
nipkow
parents: 79494
diff changeset
   256
81289
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   257
fun fixCasecCases _ [t] = [t]
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   258
  | fixCasecCases wctxt (t::ts) =
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   259
    let
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   260
      val num = fastype_of t |> strip_type |> fst |> length
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   261
      val c' = Term.strip_abs_eta num t |> list_abs
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   262
    in
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   263
      c' :: fixCasecCases wctxt ts
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   264
    end
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   265
  | fixCasecCases _ _ = error "Internal error: invalid case types/terms"
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   266
fun fixCasec wctxt t args =
1eddc169baea better time_functions (let)
nipkow
parents: 81255
diff changeset
   267
      (check_args "cases" (t,args); list_comb (t,fixCasecCases wctxt args))
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   268
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   269
fun shortFunc fixedNum (Const (nm,T)) = 
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   270
    Const (nm,T |> strip_type |>> drop fixedNum |> (op --->))
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   271
  | shortFunc _ _ = error "Internal error: Invalid term"
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   272
fun shortApp fixedNum (c, args) =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   273
  (shortFunc fixedNum c, drop fixedNum args)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   274
fun shortOriginFunc (term: term list) fixedNum (f as (c as Const (_,_), _))  =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   275
  if contains' const_comp term c then shortApp fixedNum f else f
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   276
  | shortOriginFunc _ _ t = t
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   277
fun map_abs f (t as Abs _) = t |> strip_abs ||> f |> list_abs
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   278
  | map_abs _ t = t
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   279
fun fixTerms ctxt (term: term list) (fixedNum: int) (t as pT $ (eq $ l $ r)) =
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   280
  let
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   281
    val _ = check_args "args" (strip_comb (get_l t))
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   282
    val l' = shortApp fixedNum (strip_comb l) |> list_comb
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   283
    val shortOriginFunc' = shortOriginFunc (term |> map (fst o strip_comb)) fixedNum
81358
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   284
    val consts = Proof_Context.consts_of ctxt
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   285
    val net = Consts.revert_abbrevs consts ["internal"] |> hd |> Item_Net.content
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   286
                (* filter out consts *)
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   287
              |> filter (is_Const o fst o strip_comb o fst)
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   288
                (* filter out abbreviations for locales *)
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   289
              |> filter (fn n => "local"
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   290
                  = (n |> snd |> strip_comb |> fst |> dest_Const_name |> split_name |> hd))
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   291
              |> filter (fn n => (n |> fst |> strip_comb |> fst |> dest_Const_name |> split_name |> List.last) =
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   292
                (n |> snd |> strip_comb |> fst |> dest_Const_name |> split_name |> List.last))
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   293
              |> map (fst #> strip_comb #>> dest_Const_name ##> length)
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   294
    fun n_abbrev (Const (nm,_)) =
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   295
    let
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   296
      val f = filter (fn n => fst n = nm) net
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   297
    in
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   298
      if length f >= 1 then f |> hd |> snd else 0
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   299
    end
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   300
      | n_abbrev _ = 0
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   301
    val r' = walk ctxt term {
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   302
          funcc = (fn wctxt => fn t => fn args =>
81358
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   303
            let
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   304
              val n_abb = n_abbrev t
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   305
              val t = case t of Const (nm,T) => Const (nm, T |> strip_type |>> drop n_abb |> (op --->))
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   306
                              | t => t
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   307
              val args = drop n_abb args           
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   308
            in
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   309
              (check_args "func" (t,args);
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   310
               (#f wctxt t, map (#f wctxt) args) |> shortOriginFunc' |> list_comb)
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   311
            end),
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   312
          constc = fn wctxt => map_abs (#f wctxt),
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   313
          ifc = Iif,
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   314
          casec = fixCasec,
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   315
          letc = (fn wctxt => fn expT => fn exp => fn abs => fn t =>
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   316
              (Const (@{const_name "HOL.Let"},expT) $ (#f wctxt exp) $ list_abs (abs, #f wctxt t)))
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   317
      } r
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   318
  in
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   319
    pT $ (eq $ l' $ r')
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   320
  end
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   321
  | fixTerms _ _ _ _ = error "Internal error: invalid term"
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   322
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   323
(* 2. Check for properties about the function *)
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   324
(* 2.1 Check if function is recursive *)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   325
fun or f (a,b) = f a orelse b
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   326
fun find_rec ctxt term = (walk ctxt term {
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   327
          funcc = (fn wctxt => fn t => fn args =>
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   328
            List.exists (fn term => (Const_name t) = (Const_name term)) term
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   329
             orelse List.foldr (or (#f wctxt)) false args),
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   330
          constc = fn wctxt => fn t => case t of
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   331
                Abs _ => t |> strip_abs |> snd |> (#f wctxt)
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   332
              | _ => false,
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   333
          ifc = (fn wctxt => fn _ => fn cond => fn tt => fn tf =>
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   334
            (#f wctxt) cond orelse (#f wctxt) tt orelse (#f wctxt) tf),
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   335
          casec = (fn wctxt => fn t => fn cs =>
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   336
            (#f wctxt) t orelse List.foldr (or (rem_abs (#f wctxt))) false cs),
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   337
          letc = (fn wctxt => fn _ => fn exp => fn _ => fn t =>
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   338
            (#f wctxt) exp orelse (#f wctxt) t)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   339
      }) o get_r
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   340
fun is_rec ctxt (term: term list) = List.foldr (or (find_rec ctxt term)) false
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   341
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   342
(* 4. Tactic to prove "f_dom n" *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   343
fun time_dom_tac ctxt induct_rule domintros =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   344
  (Induction.induction_tac ctxt true [] [[]] [] (SOME [induct_rule]) []
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   345
    THEN_ALL_NEW ((K (auto_tac ctxt)) THEN' (fn i => FIRST' (
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   346
    (if i <= length domintros then [Metis_Tactic.metis_tac [] ATP_Problem_Generate.combsN ctxt [List.nth (domintros, i-1)]] else []) @
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   347
    [Metis_Tactic.metis_tac [] ATP_Problem_Generate.combsN ctxt domintros]) i)))
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   348
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   349
(* Register timing function of a given function *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   350
type time_config = {
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   351
  print: bool,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   352
  simp: bool,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   353
  partial: bool
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   354
}
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   355
datatype result = Function of Function.info | PartialFunction of thm
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   356
fun reg_time_func (lthy: local_theory) (term: term list) (terms: term list) (config: time_config) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   357
  let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   358
    (* some default values to build terms easier *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   359
    (* Const (@{const_name "Groups.zero"}, HOLogic.natT) *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   360
    val zero = if #partial config then @{term "Some (0::nat)"} else HOLogic.zero
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   361
    val one = Const (@{const_name "Groups.one"}, HOLogic.natT)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   362
    val natOptT = @{typ "nat option"}
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   363
    val finT = if #partial config then natOptT else HOLogic.natT
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   364
    val some = @{term "Some::nat \<Rightarrow> nat option"}
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   365
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   366
    (* change type of original function to new type (_ \<Rightarrow> ... \<Rightarrow> _ to _ \<Rightarrow> ... \<Rightarrow> nat)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   367
        and replace all function arguments f with (t*T_f) if used *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   368
    fun change_typ' used (Type ("fun", [T1, T2])) = 
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   369
          Type ("fun", [check_for_fun' (used 0) T1, change_typ' (fn i => used (i+1)) T2])
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   370
      | change_typ' _ _ = finT
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   371
    and check_for_fun' true (f as Type ("fun", [_,_])) = HOLogic.mk_prodT (f, change_typ' (K false) f)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   372
      | check_for_fun' false (f as Type ("fun", [_,_])) = change_typ' (K true) f
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   373
      | check_for_fun' _ t = t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   374
    val change_typ = change_typ' (K true)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   375
    fun time_term ctxt s (Const (nm,T)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   376
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   377
      val T_nm = fun_name_to_time ctxt s nm
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   378
      val T_T = change_typ T
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   379
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   380
    (SOME (Syntax.check_term ctxt (Const (T_nm,T_T))))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   381
      handle (ERROR _) =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   382
        case Syntax.read_term ctxt (Long_Name.base_name T_nm)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   383
          of (Const (T_nm,T_T)) =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   384
            let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   385
              fun col_Used i (Type ("fun", [Type ("fun", _), Ts])) (Type ("fun", [T', Ts'])) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   386
                (if is_Used T' then [i] else []) @ col_Used (i+1) Ts Ts'
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   387
                | col_Used i (Type ("fun", [_, Ts])) (Type ("fun", [_, Ts'])) = col_Used (i+1) Ts Ts'
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   388
                | col_Used _ _ _ = []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   389
              val binderT = change_typ' (contains (col_Used 0 T T_T)) T |> Term.binder_types
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   390
              val finT = Term.body_type T_T
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   391
            in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   392
              SOME (Const (T_nm, binderT ---> finT))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   393
            end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   394
           | _ => error ("Timing function of " ^ nm ^ " is not defined")
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   395
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   396
      | time_term _ _ _ = error "Internal error: No valid function given"
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   397
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   398
    fun opt_term NONE = zero
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   399
      | opt_term (SOME t) = t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   400
    fun use_origin (Free (nm, T as Type ("fun",_))) = HOLogic.mk_fst (Free (nm,HOLogic.mk_prodT (T, change_typ T)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   401
      | use_origin t = t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   402
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   403
    (* Conversion of function term *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   404
    fun fun_to_time' ctxt (origin: term list) second (func as Const (nm,T)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   405
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   406
      val origin' = map (fst o strip_comb) origin
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   407
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   408
      if contains' const_comp origin' func then SOME (Free (func |> Term.term_name |> fun_name_to_time' ctxt true second, change_typ T)) else
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   409
      if Zero_Funcs.is_zero (Proof_Context.theory_of ctxt) (nm,T) then NONE else
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   410
        time_term ctxt false func
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   411
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   412
      | fun_to_time' _ _ _ (Free (nm,T)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   413
          SOME (HOLogic.mk_snd (Free (nm,HOLogic.mk_prodT (T,change_typ' (K true) T))))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   414
      | fun_to_time' _ _ _ _ = error "Internal error: invalid function to convert"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   415
    fun fun_to_time context origin func = fun_to_time' context origin false func
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   416
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   417
    (* Convert arguments of left side of a term *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   418
    fun conv_arg _ (Free (nm,T as Type("fun",_))) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   419
        Free (nm, HOLogic.mk_prodT (T, change_typ' (K false) T))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   420
      | conv_arg _ x = x
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   421
    fun conv_args ctxt = map (conv_arg ctxt)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   422
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   423
    (* 3. Convert equations *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   424
    (* Some Helper *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   425
    val plusTyp = @{typ "nat => nat => nat"}
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   426
    fun plus (SOME a) (SOME b) = SOME ((if #partial config then @{term part_add} else Const (@{const_name "Groups.plus"}, plusTyp)) $ a $ b)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   427
      | plus (SOME a) NONE = SOME a
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   428
      | plus NONE (SOME b) = SOME b
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   429
      | plus NONE NONE = NONE
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   430
    (* Partial helper *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   431
    val OPTION_BIND = @{term "Option.bind::nat option \<Rightarrow> (nat \<Rightarrow> nat option) \<Rightarrow> nat option"}
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   432
    fun OPTION_ABS_SUC args = Term.absfree ("_uu", @{typ nat})
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   433
      (List.foldr (uncurry plus)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   434
        (SOME (some $ HOLogic.mk_Suc (Free ("_uu", @{typ nat})))) args |> Option.valOf)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   435
    fun build_option_bind term args =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   436
      OPTION_BIND $ term $ OPTION_ABS_SUC args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   437
    fun WRAP_FUNCTION t =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   438
      if (Term.head_of t |> Term.fastype_of |> Term.body_type) = finT
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   439
      then t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   440
      else if #partial config
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   441
            then some $ t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   442
            else @{term "the::nat option \<Rightarrow> nat"} $ t
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   443
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   444
    (* Handle function calls *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   445
    fun build_zero (Type ("fun", [T, R])) = Abs ("uu", T, build_zero R)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   446
      | build_zero _ = zero
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   447
    fun funcc_use_origin (Free (nm, T as Type ("fun",_))) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   448
        HOLogic.mk_fst (Free (nm,HOLogic.mk_prodT (T, change_typ T)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   449
      | funcc_use_origin t = t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   450
    fun funcc_conv_arg _ _ (t as (_ $ _)) = map_aterms funcc_use_origin t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   451
      | funcc_conv_arg _ u (Free (nm, T as Type ("fun",_))) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   452
          if u then Free (nm, HOLogic.mk_prodT (T, change_typ T))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   453
          else HOLogic.mk_snd (Free (nm,HOLogic.mk_prodT (T,change_typ T)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   454
      | funcc_conv_arg wctxt true (f as Const (_,Type ("fun",_))) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   455
          HOLogic.mk_prod (f, funcc_conv_arg wctxt false f)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   456
      | funcc_conv_arg wctxt false (f as Const (_,T as Type ("fun",_))) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   457
          Option.getOpt (fun_to_time (#ctxt wctxt) (#origins wctxt) f, build_zero T)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   458
      | funcc_conv_arg wctxt false (f as Abs _) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   459
           f
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   460
           |> Term.strip_abs_eta ((length o fst o strip_type o type_of) f)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   461
           ||> #f wctxt ||> opt_term
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   462
           |> list_abs
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   463
      | funcc_conv_arg wctxt true (f as Abs _) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   464
        let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   465
          val f' = f
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   466
           |> Term.strip_abs_eta ((length o fst o strip_type o type_of) f)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   467
           ||> map_aterms funcc_use_origin
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   468
           |> list_abs
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   469
        in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   470
          HOLogic.mk_prod (f', funcc_conv_arg wctxt false f)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   471
        end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   472
      | funcc_conv_arg _ _ t = t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   473
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   474
    fun funcc_conv_args _ _ [] = []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   475
      | funcc_conv_args wctxt (Type ("fun", [t, ts])) (a::args) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   476
          funcc_conv_arg wctxt (is_Used t) a :: funcc_conv_args wctxt ts args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   477
      | funcc_conv_args _ _ _ = error "Internal error: Non matching type"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   478
    fun funcc wctxt func args =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   479
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   480
      fun get_T (Free (_,T)) = T
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   481
        | get_T (Const (_,T)) = T
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   482
        | get_T (_ $ (Free (_,Type (_, [_, T])))) = T (* Case of snd was constructed *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   483
        | get_T _ = error "Internal error: Forgotten type"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   484
      val func = (case fun_to_time (#ctxt wctxt) (#origins wctxt) func
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   485
        of SOME t => SOME (WRAP_FUNCTION (list_comb (t, funcc_conv_args wctxt (get_T t) args)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   486
         | NONE => NONE)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   487
      val args = (map (#f wctxt) args)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   488
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   489
      (if not (#partial config) orelse func = NONE
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   490
      then List.foldr (uncurry plus) func args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   491
      else build_option_bind (Option.valOf func) args |> SOME)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   492
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   493
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   494
    (* Handle case terms *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   495
    fun casecIsCase (Type (n1, [_,Type (n2, _)])) = (n1 = "fun" andalso n2 = "fun")
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   496
      | casecIsCase _ = false
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   497
    fun casecLastTyp (Type (n, [T1,T2])) = Type (n, [T1, change_typ T2])
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   498
      | casecLastTyp _ = error "Internal error: Invalid case type"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   499
    fun casecTyp (Type (n, [T1, T2])) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   500
          Type (n, [change_typ T1, (if casecIsCase T2 then casecTyp else casecLastTyp) T2])
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   501
      | casecTyp _ = error "Internal error: Invalid case type"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   502
    fun casecAbs f (Abs (v,Ta,t)) = (case casecAbs f (subst_bound (Free (v,Ta), t))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   503
                                      of (nconst,t) => (nconst,absfree (v,Ta) t))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   504
      | casecAbs f t = (case f t of NONE => (false, opt_term NONE) | SOME t => (true,t))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   505
    fun casecArgs _ [t] = (false, [map_aterms use_origin t])
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   506
      | casecArgs f (t::ar) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   507
        (case casecAbs f t of (nconst, tt) =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   508
          casecArgs f ar ||> (fn ar => tt :: ar) |>> (if nconst then K true else I))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   509
      | casecArgs _ _ = error "Internal error: Invalid case term"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   510
    fun casec wctxt (Const (t,T)) args =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   511
      if not (casecIsCase T) then error "Internal error: Invalid case type" else
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   512
        let val (nconst, args') = casecArgs (#f wctxt) args in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   513
          plus
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   514
            ((#f wctxt) (List.last args))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   515
            (if nconst then
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   516
              SOME (list_comb (Const (t,casecTyp T), args'))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   517
             else NONE)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   518
        end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   519
      | casec _ _ _ = error "Internal error: Invalid case term"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   520
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   521
    (* Handle if terms -> drop the term if true and false terms are zero *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   522
    fun ifc wctxt _ cond tt ft =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   523
      let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   524
        val f = #f wctxt
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   525
        val rcond = map_aterms use_origin cond
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   526
        val tt = f tt
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   527
        val ft = f ft
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   528
      in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   529
        plus (f cond) (case (tt,ft) of (NONE, NONE) => NONE | _ =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   530
           if tt = ft then tt else
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   531
           (SOME ((Const (@{const_name "HOL.If"}, @{typ "bool"} --> finT --> finT --> finT)) $ rcond
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   532
              $ (opt_term tt) $ (opt_term ft))))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   533
      end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   534
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   535
    fun letc_lambda wctxt T (t as Abs _) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   536
          HOLogic.mk_prod (map_aterms use_origin t, 
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   537
           Term.strip_abs_eta (strip_type T |> fst |> length) t ||> #f wctxt ||> opt_term ||> map_types change_typ |> list_abs)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   538
      | letc_lambda _ _ t = map_aterms use_origin t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   539
    fun letc wctxt expT exp ([(nm,_)]) t =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   540
          plus (#f wctxt exp)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   541
          (case #f wctxt t of SOME t' =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   542
            (if Term.used_free nm t'
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   543
             then
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   544
              let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   545
                val exp' = letc_lambda wctxt expT exp
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   546
                val t' = list_abs ([(nm,fastype_of exp')], t')
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   547
              in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   548
                Const (@{const_name "HOL.Let"}, [fastype_of exp', fastype_of t'] ---> finT) $ exp' $ t'
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   549
              end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   550
             else t') |> SOME
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   551
          | NONE => NONE)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   552
      | letc _ _ _ _ _ = error "Unknown let state"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   553
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   554
    fun constc _ (Const ("HOL.undefined", _)) = SOME (Const ("HOL.undefined", finT))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   555
      | constc _ _ = NONE
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   556
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   557
    (* The converter for timing functions given to the walker *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   558
    val converter : term option converter = {
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   559
            constc = constc,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   560
            funcc = funcc,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   561
            ifc = ifc,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   562
            casec = casec,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   563
            letc = letc
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   564
        }
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   565
    fun top_converter is_rec _ _ =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   566
      if #partial config
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   567
      then (fn t => Option.getOpt (t, zero))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   568
      else (opt_term o (fn exp => plus exp (if is_rec then SOME one else NONE)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   569
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   570
    (* Use converter to convert right side of a term *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   571
    fun to_time ctxt origin is_rec term =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   572
      top_converter is_rec ctxt origin (walk ctxt origin converter term)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   573
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   574
    (* Converts a term to its running time version *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   575
    fun convert_term ctxt (origin: term list) is_rec (pT $ (Const (eqN, _) $ l $ r)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   576
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   577
      val (l_const, l_params) = strip_comb l
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   578
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   579
        pT
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   580
        $ (Const (eqN, finT --> finT --> @{typ "bool"})
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   581
          $ (list_comb (l_const |> fun_to_time ctxt origin |> Option.valOf, l_params |> conv_args ctxt))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   582
          $ (to_time ctxt origin is_rec r))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   583
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   584
      | convert_term _ _ _ _ = error "Internal error: invalid term to convert"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   585
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   586
    (* 3.5 Support for locales *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   587
    fun replaceFstSndFree ctxt (origin: term list) (rfst: term -> term) (rsnd: term -> term) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   588
      (walk ctxt origin {
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   589
              funcc = fn wctxt => fn t => fn args =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   590
                case args of
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   591
                     (f as Free _)::args =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   592
                       (case t of
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   593
                           Const ("Product_Type.prod.fst", _) =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   594
                            list_comb (rfst (t $ f), map (#f wctxt) args)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   595
                         | Const ("Product_Type.prod.snd", _) =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   596
                            list_comb (rsnd (t $ f), map (#f wctxt) args)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   597
                         | t => list_comb (t, map (#f wctxt) (f :: args)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   598
                   | args => list_comb (t, map (#f wctxt) args),
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   599
              constc = Iconst,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   600
              ifc = Iif,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   601
              casec = Icase,
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   602
              letc = Ilet
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   603
          })
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   604
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   605
    (* 5. Check for higher-order function if original function is used \<rightarrow> find simplifications *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   606
    fun find_used' T_t =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   607
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   608
      val (T_ident, T_args) = strip_comb (get_l T_t)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   609
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   610
      fun filter_passed [] = []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   611
        | filter_passed ((f as Free (_, Type ("Product_Type.prod",[Type ("fun",_), Type ("fun", _)])))::args) = 
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   612
            f :: filter_passed args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   613
        | filter_passed (_::args) = filter_passed args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   614
      val frees = (walk lthy [] {
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   615
              funcc = (fn wctxt => fn t => fn args =>
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   616
                  (case t of (Const ("Product_Type.prod.snd", _)) => []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   617
                      | _ => (if t = T_ident then [] else filter_passed args)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   618
                        @ List.foldr (fn (l,r) => (#f wctxt) l @ r) [] args)),
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   619
              constc = (K o K) [],
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   620
              ifc = (fn wctxt => fn _ => fn cond => fn tt => fn tf => (#f wctxt) cond @ (#f wctxt) tt @ (#f wctxt) tf),
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   621
              casec = (fn wctxt => fn _ => fn cs => List.foldr (fn (l,r) => (#f wctxt) l @ r) [] cs),
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   622
              letc = (fn wctxt => fn _ => fn exp => fn _ => fn t => (#f wctxt) exp @ (#f wctxt) t)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   623
          }) (get_r T_t)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   624
      fun build _ [] = []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   625
        | build i (a::args) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   626
            (if contains frees a then [(T_ident,i)] else []) @ build (i+1) args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   627
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   628
      build 0 T_args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   629
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   630
    fun find_simplifyble ctxt term terms =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   631
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   632
      val used =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   633
        terms
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   634
        |> List.map find_used'
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   635
        |> List.foldr (op @) []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   636
      val change =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   637
        Option.valOf o fun_to_time ctxt term
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   638
      fun detect t i (Type ("fun",_)::args) = 
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   639
        (if contains used (change t,i) then [] else [i]) @ detect t (i+1) args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   640
        | detect t i (_::args) = detect t (i+1) args
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   641
        | detect _ _ [] = []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   642
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   643
      map (fn t => t |> type_of |> strip_type |> fst |> detect t 0) term
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   644
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   645
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   646
    fun define_simp' term simplifyable ctxt =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   647
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   648
      val base_name = case Named_Target.locale_of ctxt of
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   649
              NONE => ctxt |> Proof_Context.theory_of |> Context.theory_base_name
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   650
            | SOME nm => nm
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   651
      
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   652
      val orig_name = term |> dest_Const_name |> split_name |> List.last
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   653
      val red_name = fun_name_to_time ctxt false orig_name
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   654
      val name = fun_name_to_time' ctxt true true orig_name
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   655
      val full_name = base_name ^ "." ^ name
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   656
      val def_name = red_name ^ "_def"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   657
      val def = Binding.name def_name
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   658
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   659
      val canon = Syntax.read_term (Local_Theory.exit ctxt) name |> strip_comb
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   660
      val canonFrees = canon |> snd
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   661
      val canonType = canon |> fst |> dest_Const_type |> strip_type |> fst |> take (length canonFrees)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   662
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   663
      val types = term |> dest_Const_type |> strip_type |> fst
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   664
      val vars = Variable.variant_fixes (map (K "") types) ctxt |> fst
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   665
      fun l_typs' i ((T as (Type ("fun",_)))::types) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   666
        (if contains simplifyable i
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   667
         then change_typ T
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   668
         else HOLogic.mk_prodT (T,change_typ T))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   669
        :: l_typs' (i+1) types
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   670
        | l_typs' i (T::types) = T :: l_typs' (i+1) types
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   671
        | l_typs' _ [] = []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   672
      val l_typs = l_typs' 0 types
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   673
      val lhs =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   674
        List.foldl (fn ((v,T),t) => t $ Free (v,T)) (Free (red_name,l_typs ---> HOLogic.natT)) (ListPair.zip (vars,l_typs))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   675
      fun fixType (TFree _) = HOLogic.natT
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   676
        | fixType T = T
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   677
      fun fixUnspecified T = T |> strip_type ||> fixType |> (op --->)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   678
      fun r_terms' i (v::vars) ((T as (Type ("fun",_)))::types) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   679
        (if contains simplifyable i
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   680
        then HOLogic.mk_prod (Const ("HOL.undefined", fixUnspecified T), Free (v,change_typ T))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   681
        else Free (v,HOLogic.mk_prodT (T,change_typ T)))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   682
        :: r_terms' (i+1) vars types
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   683
        | r_terms' i (v::vars) (T::types) = Free (v,T) :: r_terms' (i+1) vars types
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   684
        | r_terms' _ _ _ = []
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   685
      val r_terms = r_terms' 0 vars types
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   686
      val full_type = (r_terms |> map (type_of) ---> HOLogic.natT)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   687
      val full = list_comb (Const (full_name,canonType ---> full_type), canonFrees)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   688
      val rhs = list_comb (full, r_terms)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   689
      val eq = (lhs, rhs) |> HOLogic.mk_eq |> HOLogic.mk_Trueprop
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   690
      val _ = Pretty.writeln (Pretty.block [Pretty.str "Defining simplified version:\n",
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   691
                                            Syntax.pretty_term ctxt eq])
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   692
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   693
      val (_, ctxt') = Specification.definition NONE [] [] ((def, []), eq) ctxt
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   694
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   695
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   696
      ((def_name, orig_name), ctxt')
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   697
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   698
    fun define_simp simpables ctxt =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   699
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   700
      fun cond ((term,simplifyable),(defs,ctxt)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   701
        define_simp' term simplifyable ctxt |>> (fn def => def :: defs)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   702
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   703
      List.foldr cond ([], ctxt) simpables
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   704
    end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   705
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   706
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   707
    fun replace from to =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   708
      map (map_aterms (fn t => if t = from then to else t))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   709
    fun replaceAll [] = I
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   710
      | replaceAll ((from,to)::xs) = replaceAll xs o replace from to
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   711
    fun calculateSimplifications ctxt T_terms term simpables =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   712
    let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   713
      (* Show where a simplification can take place *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   714
        fun reportReductions (t,(i::is)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   715
        (Pretty.writeln (Pretty.str
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   716
          ((Term.term_name t |> fun_name_to_time ctxt true)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   717
            ^ " can be simplified because only the time-function component of parameter "
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   718
            ^ (Int.toString (i + 1)) ^ " is used. "));
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   719
            reportReductions (t,is))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   720
          | reportReductions (_,[]) = ()
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   721
        val _ = simpables
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   722
          |> map reportReductions
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   723
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   724
        (* Register definitions for simplified function *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   725
        val (reds, ctxt) = define_simp simpables ctxt
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   726
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   727
        fun genRetype (Const (nm,T),is) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   728
        let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   729
          val T_name = fun_name_to_time ctxt true nm |> split_name |> List.last
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   730
          val from = Free (T_name,change_typ T)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   731
          val to = Free (T_name,change_typ' (not o contains is) T)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   732
        in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   733
          (from,to)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   734
        end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   735
          | genRetype _ = error "Internal error: invalid term"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   736
        val retyping = map genRetype simpables
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   737
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   738
        fun replaceArgs (pT $ (eq $ l $ r)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   739
        let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   740
          val (t,params) = strip_comb l
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   741
          fun match (Const (f_nm,_),_) = 
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   742
                (fun_name_to_time ctxt true f_nm |> Long_Name.base_name) = (dest_Free t |> fst)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   743
            | match _ = false
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   744
          val simps = List.find match simpables |> Option.valOf |> snd
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   745
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   746
          fun dest_Prod_snd (Free (nm, Type (_, [_, T2]))) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   747
                Free (fun_name_to_time ctxt false nm, T2)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   748
            | dest_Prod_snd _ = error "Internal error: Argument is not a pair"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   749
          fun rep _ [] = ([],[])
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   750
            | rep i (x::xs) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   751
          let 
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   752
            val (rs,args) = rep (i+1) xs
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   753
          in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   754
            if contains simps i
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   755
              then (x::rs,dest_Prod_snd x::args)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   756
              else (rs,x::args)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   757
          end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   758
          val (rs,params) = rep 0 params
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   759
          fun fFst _ = error "Internal error: Invalid term to simplify"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   760
          fun fSnd (t as (Const _ $ f)) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   761
            (if contains rs f
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   762
              then dest_Prod_snd f
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   763
              else t)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   764
            | fSnd t = t
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   765
        in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   766
          (pT $ (eq
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   767
              $ (list_comb (t,params))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   768
              $ (replaceFstSndFree ctxt term fFst fSnd r
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   769
                  |> (fn t => replaceAll (map (fn t => (t,dest_Prod_snd t)) rs) [t])
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   770
                  |> hd
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   771
                )
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   772
          ))
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   773
        end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   774
        | replaceArgs _ = error "Internal error: Invalid term"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   775
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   776
        (* Calculate reduced terms *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   777
        val T_terms_red = T_terms
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   778
          |> replaceAll retyping
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   779
          |> map replaceArgs
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   780
    
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   781
        val _ = print_lemma ctxt reds T_terms_red
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   782
        val _ = 
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   783
            Pretty.writeln (Pretty.str "If you do not want the simplified T function, use \"time_fun [no_simp]\"")
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   784
    in
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   785
      ctxt
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   786
    end
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   787
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   788
    val _ =
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   789
      case time_term lthy true (hd term)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   790
            handle (ERROR _) => NONE
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   791
        of SOME _ => error ("Timing function already declared: " ^ (Term.term_name (hd term)))
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   792
         | NONE => ()
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   793
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   794
    (* Number of terms fixed by locale *)
81358
91b008474f1b better termination behaviour
nipkow
parents: 81289
diff changeset
   795
    val fixedNum = term |> hd
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   796
      |> strip_comb |> snd
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   797
      |> length
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   798
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   799
    (********************* BEGIN OF CONVERSION *********************)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   800
    (* 1. Fix all terms *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   801
    (* Exchange Var in types and terms to Free and check constraints *)
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
   802
    val terms = map
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   803
      (map_aterms freeTerms
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   804
        #> map_types (map_atyps freeTypes)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   805
        #> fixTerms lthy term fixedNum)
79542
b941924a407d define_time_function: avoid unused let's
nipkow
parents: 79494
diff changeset
   806
      terms
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   807
    val fixedFrees = (hd term) |> strip_comb |> snd |> take fixedNum 
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   808
    val fixedFreesNames = map (fst o dest_Free) fixedFrees
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   809
    val term = map (shortFunc fixedNum o fst o strip_comb) term
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   810
    fun correctTerm term =
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   811
    let
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   812
      val get_f = fst o strip_comb o get_l
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   813
    in
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   814
      List.find (fn t => (dest_Const_name o get_f) t = dest_Const_name term) terms
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   815
        |> Option.valOf |> get_f
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   816
    end
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
   817
    val term = map correctTerm term
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   818
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   819
    (* 2. Find properties about the function *)
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   820
    (* 2.1 Check if function is recursive *)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   821
    val is_rec = is_rec lthy term terms
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   822
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   823
    (* 3. Convert every equation
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   824
      - Change type of toplevel equation from _ \<Rightarrow> _ \<Rightarrow> bool to nat \<Rightarrow> nat \<Rightarrow> bool
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   825
      - On left side change name of function to timing function
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   826
      - Convert right side of equation with conversion schema
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   827
    *)
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   828
    fun fFst (t as (Const (_,T) $ Free (nm,_))) =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   829
      (if contains fixedFreesNames nm
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   830
        then Free (nm,strip_type T |>> tl |> (op --->))
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   831
        else t)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   832
      | fFst t = t
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   833
    fun fSnd (t as (Const (_,T) $ Free (nm,_))) =
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   834
      (if contains fixedFreesNames nm
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   835
        then Free (fun_name_to_time lthy false nm,strip_type T |>> tl |> (op --->))
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   836
        else t)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   837
      | fSnd t = t
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   838
    val T_terms = map (convert_term lthy term is_rec) terms
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   839
      |> map (map_r (replaceFstSndFree lthy term fFst fSnd))
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   840
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   841
    val simpables = (if #simp config
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   842
      then find_simplifyble lthy term T_terms
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   843
      else map (K []) term)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   844
      |> (fn s => ListPair.zip (term,s))
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   845
    (* Determine if something is simpable, if so rename everything *)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   846
    val simpable = simpables |> map snd |> exists (not o null)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   847
    (* Rename to secondary if simpable *)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   848
    fun genRename (t,_) =
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   849
      let
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   850
        val old = fun_to_time' lthy term false t |> Option.valOf
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   851
        val new = fun_to_time' lthy term true t |> Option.valOf
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   852
      in
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   853
        (old,new)
80624
9f8034d29365 time_function T_map can now be generated automatically.
nipkow
parents: 80036
diff changeset
   854
      end
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   855
    val can_T_terms = if simpable 
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   856
      then replaceAll (map genRename simpables) T_terms
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   857
      else T_terms
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   858
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   859
    (* 4. Register function and prove completeness *)
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   860
    val names = map Term.term_name term
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   861
    val timing_names = map (fun_name_to_time' lthy true simpable) names
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   862
    val bindings = map (fn nm => (Binding.name nm, NONE, NoSyn)) timing_names
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   863
    fun pat_completeness_auto ctxt =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   864
      Pat_Completeness.pat_completeness_tac ctxt 1 THEN auto_tac ctxt
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   865
    val specs = map (fn eq => (((Binding.empty, []), eq), [], [])) can_T_terms
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   866
    val part_specs = (Binding.empty_atts, hd can_T_terms)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   867
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   868
    (* Context for printing without showing question marks *)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   869
    val print_ctxt = lthy
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   870
      |> Config.put show_question_marks false
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   871
      |> Config.put show_sorts false (* Change it for debugging *)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   872
    val print_ctxt = List.foldl (fn (term, ctxt) => Variable.add_fixes_implicit term ctxt) print_ctxt (term @ T_terms)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   873
    (* Print result if print *)
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   874
    val _ = if not (#print config) then () else
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   875
        let
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   876
          val nms = map (dest_Const_name) term
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   877
          val typs = map (dest_Const_type) term
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   878
        in
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   879
          print_timing' print_ctxt { names=nms, terms=terms, typs=typs }
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   880
            { names=timing_names, terms=can_T_terms, typs=map change_typ typs  }
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   881
        end
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   882
    
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   883
    (* For partial functions sequential=true is needed in order to support them
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   884
       We need sequential=false to support the automatic proof of termination over dom
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   885
    *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   886
    fun register seq =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   887
      let
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   888
        val _ = (if seq then warning "Falling back on sequential function..." else ())
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   889
        val fun_config = Function_Common.FunctionConfig
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   890
          {sequential=seq, default=NONE, domintros=true, partials=false}
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   891
      in
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   892
        if #partial config
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   893
        then Partial_Function.add_partial_function "option" bindings part_specs lthy |>> PartialFunction o snd
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   894
        else Function.add_function bindings specs fun_config pat_completeness_auto lthy |>> Function
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   895
      end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   896
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   897
    val (info,ctxt) = 
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   898
      register false
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   899
        handle (ERROR _) =>
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   900
          register true
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   901
             | Match =>
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   902
          register true
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   903
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   904
    val ctxt = if simpable then calculateSimplifications ctxt T_terms term simpables else ctxt
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   905
  in
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   906
    (info, ctxt)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   907
  end
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   908
fun proove_termination (term: term list) terms (T_info: Function.info, lthy: local_theory) =
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   909
  let
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   910
    (* Start proving the termination *)  
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   911
    val infos = SOME (map (Function.get_info lthy) term) handle Empty => NONE
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   912
    val timing_names = map (fun_name_to_time lthy true o Term.term_name) term
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   913
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   914
    (* Proof by lexicographic_order_tac *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   915
    val (time_info, lthy') =
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   916
      (Function.prove_termination NONE
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   917
        (Lexicographic_Order.lexicographic_order_tac false lthy) lthy)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   918
        handle (ERROR _) =>
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   919
        let
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   920
          val _ = warning "Falling back on proof over dom..."
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   921
          val _ = (if length term > 1 then error "Proof over dom not supported for mutual recursive functions" else ())
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   922
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   923
          fun args (a$(Var ((nm,_),T))) = args a |> (fn ar => (nm,T)::ar)
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   924
            | args (a$(Const (_,T))) = args a |> (fn ar => ("uu",T)::ar)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   925
            | args _ = []
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   926
          val dom_vars =
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   927
            terms |> hd |> get_l |> map_types (map_atyps freeTypes)
81519
cdc43c0fdbfc clarified signature;
wenzelm
parents: 81358
diff changeset
   928
            |> args |> Variable.variant_names lthy
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   929
          val dom_args = 
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   930
            List.foldl (fn (t,p) => HOLogic.mk_prod ((Free t),p)) (Free (hd dom_vars)) (tl dom_vars)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   931
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   932
          val {inducts, ...} = case infos of SOME [i] => i | _ => error "Proof over dom failed as no induct rule was found"
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   933
          val induct = (Option.valOf inducts |> hd)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   934
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   935
          val domintros = Proof_Context.get_fact lthy (Facts.named (hd timing_names ^ ".domintros"))
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   936
          val prop = HOLogic.mk_Trueprop (#dom T_info $ dom_args)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   937
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   938
          (* Prove a helper lemma *)
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   939
          val dom_lemma = Goal.prove lthy (map fst dom_vars) [] prop
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   940
            (fn {context, ...} => HEADGOAL (time_dom_tac context induct domintros))
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   941
          (* Add dom_lemma to simplification set *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   942
          val simp_lthy = Simplifier.add_simp dom_lemma lthy
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   943
        in
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   944
          (* Use lemma to prove termination *)
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   945
          Function.prove_termination NONE
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   946
            (auto_tac simp_lthy) lthy
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   947
        end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   948
  in
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   949
    (Function time_info, lthy')
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   950
  end
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   951
fun reg_and_proove_time_func (lthy: local_theory) (term: term list) (terms: term list) (config: time_config) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   952
  case reg_time_func lthy term terms config
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   953
    of (Function info, lthy') => proove_termination term terms (info, lthy')
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   954
     | r => r
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   955
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   956
fun isTypeClass' (Const (nm,_)) =
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   957
  (case split_name nm |> rev
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   958
    of (_::nm::_) => String.isSuffix "_class" nm
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   959
     | _ => false)
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   960
  | isTypeClass' _ = false
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   961
val isTypeClass =
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   962
  (List.foldr (fn (a,b) => a orelse b) false) o (map isTypeClass')
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   963
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   964
fun detect_typ (ctxt: local_theory) (term: term) =
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   965
let
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   966
  val class_term =  (case term of Const (nm,_) => Syntax.read_term ctxt nm
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   967
      | _ => error "Could not find term of class")
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   968
  fun find_free (Type (_,class)) (Type (_,inst)) =
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   969
        List.foldl (fn ((c,i),s) => (case s of NONE => find_free c i | t => t)) (NONE) (ListPair.zip (class, inst))
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   970
    | find_free (TFree _) (TFree _) = NONE
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   971
    | find_free (TFree _) (Type (nm,_)) = SOME nm
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   972
    | find_free  _ _ = error "Unhandled case in detecting type"
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   973
in
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   974
  find_free (type_of class_term) (type_of term)
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   975
    |> Option.map (hd o rev o split_name)
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   976
end
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   977
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   978
fun set_suffix (fterms: term list) ctxt =
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   979
let
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   980
  val isTypeClass = isTypeClass fterms
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   981
  val _ = (if length fterms > 1 andalso isTypeClass then error "No mutual recursion inside instantiation allowed" else ())
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   982
  val suffix = (if isTypeClass then detect_typ ctxt (hd fterms) else NONE)
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   983
in
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   984
  (case suffix of NONE => I | SOME s => Config.put bsuffix ("_" ^ s)) ctxt
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   985
end
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
   986
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   987
fun check_opts [] = false
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   988
  | check_opts ["no_simp"] = true
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   989
  | check_opts (a::_) = error ("Option " ^ a ^ " is not defined")
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   990
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   991
(* Converts a function into its timing function using fun *)
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   992
fun reg_time_fun_cmd ((opts, funcs), thms) (ctxt: local_theory) =
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
   993
let
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
   994
  val no_simp = check_opts opts
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
   995
  val fterms = map (Syntax.read_term ctxt) funcs
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   996
  val ctxt = set_suffix fterms ctxt
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
   997
  val config = { print = true, simp = not no_simp, partial = false }
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   998
  val (_, ctxt') = reg_and_proove_time_func ctxt fterms
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
   999
    (case thms of NONE => get_terms ctxt (hd fterms)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1000
                | SOME thms => thms |> Attrib.eval_thms ctxt |> List.map Thm.prop_of)
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1001
    config
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1002
in ctxt'
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1003
end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1004
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1005
(* Converts a function into its timing function using function with termination proof provided by user*)
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1006
fun reg_time_function_cmd ((opts, funcs), thms) (ctxt: local_theory) =
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1007
let
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1008
  val no_simp = check_opts opts
79494
c7536609bb9b translation to time functions now with canonical let.
nipkow
parents: 79490
diff changeset
  1009
  val fterms = map (Syntax.read_term ctxt) funcs
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1010
  val ctxt = set_suffix fterms ctxt
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1011
  val config = { print = true, simp = not no_simp, partial = false }
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1012
  val ctxt' = reg_time_func ctxt fterms
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1013
    (case thms of NONE => get_terms ctxt (hd fterms)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1014
                | SOME thms => thms |> Attrib.eval_thms ctxt |> List.map Thm.prop_of)
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1015
    config
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1016
    |> snd
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1017
in ctxt'
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1018
end
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1019
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1020
(* Converts a function definition into its timing function using definition *)
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1021
fun reg_time_definition_cmd ((opts, funcs), thms) (ctxt: local_theory) =
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
  1022
let
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1023
  val no_simp = check_opts opts
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
  1024
  val fterms = map (Syntax.read_term ctxt) funcs
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1025
  val ctxt = set_suffix fterms ctxt
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1026
  val config = { print = true, simp = not no_simp, partial = false }
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1027
  val (_, ctxt') = reg_and_proove_time_func ctxt fterms
81255
47530e9a7c33 time_fun: lambdas and lets work now
nipkow
parents: 81147
diff changeset
  1028
    (case thms of NONE => get_terms ctxt (hd fterms) |> check_definition
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
  1029
                | SOME thms => thms |> Attrib.eval_thms ctxt |> List.map Thm.prop_of)
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1030
    config
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1031
in ctxt'
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1032
end
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1033
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1034
(* Converts a a partial function into its timing function using partial_function *)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1035
fun reg_time_partial_function_cmd ((opts, funcs), thms) (ctxt: local_theory) =
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1036
let
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1037
  val no_simp = check_opts opts
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1038
  val fterms = map (Syntax.read_term ctxt) funcs
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1039
  val ctxt = set_suffix fterms ctxt
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1040
  val config = { print = true, simp = not no_simp, partial = true }
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1041
  val (_, ctxt') = reg_and_proove_time_func ctxt fterms
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1042
    (case thms of NONE => get_terms ctxt (hd fterms) |> check_definition
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1043
                | SOME thms => thms |> Attrib.eval_thms ctxt |> List.map Thm.prop_of)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1044
    config
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1045
in ctxt'
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
  1046
end
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
  1047
81147
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1048
val parser = (Parse.opt_attribs >> map (fst o Token.name_of_src))
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1049
             -- Scan.repeat1 Parse.prop
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1050
             -- Scan.option (Parse.keyword_improper "equations" -- Parse.thms1 >> snd)
503e5280ba72 new HO time functions
nipkow
parents: 80734
diff changeset
  1051
val _ = Toplevel.local_theory
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1052
val _ = Outer_Syntax.local_theory @{command_keyword "time_fun"}
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1053
  "Defines runtime function of a function"
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1054
  (parser >> reg_time_fun_cmd)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1055
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1056
val _ = Outer_Syntax.local_theory @{command_keyword "time_function"}
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1057
  "Defines runtime function of a function"
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1058
  (parser >> reg_time_function_cmd)
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
  1059
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1060
val _ = Outer_Syntax.local_theory @{command_keyword "time_definition"}
79969
4aeb25ba90f3 more uniform command names
nipkow
parents: 79714
diff changeset
  1061
  "Defines runtime function of a definition"
80734
7054a1bc8347 new version of time_fun that works for classes; define T_length automatically now
nipkow
parents: 80657
diff changeset
  1062
  (parser >> reg_time_definition_cmd)
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1063
82081
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1064
val _ = Outer_Syntax.local_theory @{command_keyword "time_partial_function"}
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1065
  "Defines runtime function of a definition"
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1066
  (parser >> reg_time_partial_function_cmd)
50dd4fc40fcb added time_partial_function command
nipkow
parents: 81519
diff changeset
  1067
79490
b287510a4202 Added time function automation
nipkow
parents:
diff changeset
  1068
end