src/HOL/Eisbach/method_closure.ML
author wenzelm
Sun, 07 Jun 2015 20:03:40 +0200
changeset 60379 51d9dcd71ad7
parent 60287 adde5ce1e0a7
child 60407 53ef7b78e78a
permissions -rw-r--r--
tuned signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
     1
(*  Title:      HOL/Eisbach/method_closure.ML
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     2
    Author:     Daniel Matichuk, NICTA/UNSW
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     3
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     4
Facilities for treating method syntax as a closure, with abstraction
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     5
over terms, facts and other methods.
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     6
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     7
The 'method' command allows to define new proof methods by combining
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     8
existing ones with their usual syntax.
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
     9
*)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    10
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    11
signature METHOD_CLOSURE =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    12
sig
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    13
  val is_dummy: thm -> bool
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    14
  val tag_free_thm: thm -> thm
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    15
  val is_free_thm: thm -> bool
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    16
  val dummy_free_thm: thm
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    17
  val free_aware_rule_attribute: thm list -> (Context.generic -> thm -> thm) -> Thm.attribute
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    18
  val wrap_attribute: {handle_all_errs : bool, declaration : bool} ->
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    19
    Binding.binding -> theory -> theory
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    20
  val read_inner_method: Proof.context -> Token.src -> Method.text
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
    21
  val read_text_closure: Proof.context -> Token.src -> Token.src * Method.text
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
    22
  val read_inner_text_closure: Proof.context -> Input.source -> Token.src * Method.text
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    23
  val parse_method: Method.text context_parser
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    24
  val method_evaluate: Method.text -> Proof.context -> Method.method
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    25
  val get_inner_method: Proof.context -> string * Position.T ->
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    26
    (term list * (string list * string list)) * Method.text
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    27
  val eval_inner_method: Proof.context -> (term list * string list) * Method.text ->
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
    28
    term list -> (string * thm list) list -> (Proof.context -> Method.method) list ->
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    29
    Proof.context -> Method.method
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    30
  val method_definition: binding -> (binding * typ option * mixfix) list ->
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
    31
    binding list -> binding list -> binding list -> Token.src -> local_theory -> local_theory
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    32
  val method_definition_cmd: binding -> (binding * string option * mixfix) list ->
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
    33
    binding list -> binding list -> binding list -> Token.src -> local_theory -> local_theory
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    34
end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    35
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    36
structure Method_Closure: METHOD_CLOSURE =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    37
struct
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    38
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    39
(* context data *)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    40
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    41
structure Data = Generic_Data
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    42
(
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
    43
  type T = ((term list * (string list * string list)) * Method.text) Symtab.table;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    44
  val empty: T = Symtab.empty;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    45
  val extend = I;
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
    46
  fun merge data : T = Symtab.merge (K true) data;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    47
);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    48
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    49
val get_methods = Data.get o Context.Proof;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    50
val map_methods = Data.map;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    51
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    52
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    53
structure Local_Data = Proof_Data
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    54
(
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    55
  type T =
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
    56
    (Proof.context -> Method.method) Symtab.table *  (*dynamic methods*)
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    57
    (term list -> Proof.context -> Method.method)  (*recursive method*);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    58
  fun init _ : T = (Symtab.empty, fn _ => fn _ => Method.fail);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    59
);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    60
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
    61
fun lookup_dynamic_method ctxt full_name =
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    62
  (case Symtab.lookup (#1 (Local_Data.get ctxt)) full_name of
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    63
    SOME m => m
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    64
  | NONE => error ("Illegal use of internal Eisbach method: " ^ quote full_name));
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    65
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    66
val update_dynamic_method = Local_Data.map o apfst o Symtab.update;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    67
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    68
val get_recursive_method = #2 o Local_Data.get;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    69
val put_recursive_method = Local_Data.map o apsnd o K;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    70
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    71
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    72
(* free thm *)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    73
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    74
fun is_dummy thm =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    75
  (case try Logic.dest_term (Thm.concl_of (perhaps (try Goal.conclude) thm)) of
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    76
    NONE => false
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    77
  | SOME t => Term.is_dummy_pattern t);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    78
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    79
val free_thmN = "Method_Closure.free_thm";
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    80
fun tag_free_thm thm = Thm.tag_rule (free_thmN, "") thm;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    81
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    82
val dummy_free_thm = tag_free_thm Drule.dummy_thm;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    83
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    84
fun is_free_thm thm = Properties.defined (Thm.get_tags thm) free_thmN;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    85
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    86
fun is_free_fact [thm] = is_free_thm thm
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    87
  | is_free_fact _ = false;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    88
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    89
fun free_aware_rule_attribute args f =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    90
  Thm.rule_attribute (fn context => fn thm =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    91
    if exists is_free_thm (thm :: args) then dummy_free_thm
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    92
    else f context thm);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
    93
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    94
fun free_aware_attribute thy {handle_all_errs,declaration} src (context, thm) =
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
    95
  let
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
    96
    val src' = Token.init_assignable_src src;
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
    97
    fun apply_att thm = (Attrib.attribute_global thy src') (context, thm);
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    98
    val _ =
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
    99
      if handle_all_errs then (try apply_att Drule.dummy_thm; ())
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   100
      else (apply_att Drule.dummy_thm; ()) handle THM _ => () | TERM _ => () | TYPE _ => ();
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   101
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   102
    val src'' = Token.closure_src src';
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   103
    val thms =
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   104
      map_filter Token.get_value (Token.args_of_src src'')
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   105
      |> map_filter (fn (Token.Fact (_, f)) => SOME f | _ => NONE)
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   106
      |> flat;
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   107
  in
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   108
    if exists is_free_thm (thm :: thms) then
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   109
      if declaration then (NONE, NONE)
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   110
      else (NONE, SOME dummy_free_thm)
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   111
    else apply_att thm
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   112
  end;
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   113
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   114
fun wrap_attribute args binding thy =
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   115
  let
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   116
    val name = Binding.name_of binding;
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   117
    val name' = Attrib.check_name_generic (Context.Theory thy) (name, Position.none);
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   118
    fun get_src src = Token.src (name', Token.range_of_src src) (Token.args_of_src src);
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   119
  in
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   120
    Attrib.define_global binding (free_aware_attribute thy args o get_src) "" thy
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   121
    |> snd
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   122
  end;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   123
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   124
(* thm semantics for combined methods with internal parser. Simulates outer syntax parsing. *)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   125
(* Creates closures for each combined method while parsing, based on the parse context *)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   126
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   127
fun read_inner_method ctxt src =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   128
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   129
    val toks = Token.args_of_src src;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   130
    val parser = Parse.!!! (Method.parser' ctxt 0 --| Scan.ahead Parse.eof);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   131
  in
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   132
    (case Scan.read Token.stopper parser toks of
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   133
      SOME (method_text, pos) => (Method.report (method_text, pos); method_text)
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   134
    | NONE => error ("Failed to parse method" ^ Position.here (#2 (Token.name_of_src src))))
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   135
  end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   136
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   137
fun read_text_closure ctxt source =
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   138
  let
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   139
    val src = Token.init_assignable_src source;
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   140
    val method_text = read_inner_method ctxt src;
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   141
    val method_text' = Method.map_source (Method.method_closure ctxt) method_text;
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   142
    (*FIXME: Does not markup method parameters. Needs to be done by Method.parser' directly. *)
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   143
    val _ =
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   144
      Method.map_source (fn src => (try (Method.check_name ctxt) (Token.name_of_src src); src))
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   145
        method_text;
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   146
    val src' = Token.closure_src src;
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   147
  in (src', method_text') end;
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   148
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   149
fun read_inner_text_closure ctxt input =
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   150
  let
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   151
    val keywords = Thy_Header.get_keywords' ctxt;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   152
    val toks =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   153
      Input.source_explode input
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   154
      |> Token.read_no_commands keywords (Scan.one Token.not_eof);
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   155
  in read_text_closure ctxt (Token.src ("", Input.pos_of input) toks) end;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   156
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   157
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   158
val parse_method =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   159
  Args.context -- Scan.lift (Parse.token Parse.cartouche) >> (fn (ctxt, tok) =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   160
    (case Token.get_value tok of
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   161
      NONE =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   162
        let
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   163
           val input = Token.input_of tok;
60248
f7e4294216d2 updated Eisbach, using version fb741500f533 of its Bitbucket repository;
wenzelm
parents: 60209
diff changeset
   164
           val (src, text) = read_inner_text_closure ctxt input;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   165
           val _ = Token.assign (SOME (Token.Source src)) tok;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   166
        in text end
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   167
    | SOME (Token.Source src) => read_inner_method ctxt src
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   168
    | SOME _ =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   169
        error ("Unexpected inner token value for method cartouche" ^
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   170
          Position.here (Token.pos_of tok))));
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   171
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   172
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   173
fun parse_term_args args =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   174
  Args.context :|-- (fn ctxt =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   175
    let
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   176
      val ctxt' = Proof_Context.set_mode (Proof_Context.mode_schematic) ctxt;
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   177
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   178
      fun parse T =
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   179
        (if T = propT then Syntax.parse_prop ctxt' else Syntax.parse_term ctxt')
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   180
        #> Type.constraint (Type_Infer.paramify_vars T);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   181
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   182
      fun do_parse' T =
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   183
        Parse_Tools.name_term >> Parse_Tools.parse_val_cases (parse T);
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   184
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   185
      fun do_parse (Var (_, T)) = do_parse' T
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   186
        | do_parse (Free (_, T)) = do_parse' T
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   187
        | do_parse t = error ("Unexpected method parameter: " ^ Syntax.string_of_term ctxt' t);
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   188
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   189
       fun rep [] x = Scan.succeed [] x
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   190
         | rep (t :: ts) x  = (do_parse t -- rep ts >> op ::) x;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   191
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   192
      fun check ts =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   193
        let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   194
          val (ts, fs) = split_list ts;
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   195
          val ts' = Syntax.check_terms ctxt' ts |> Variable.polymorphic ctxt';
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   196
          val _ = ListPair.app (fn (f, t) => f t) (fs, ts');
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   197
        in ts' end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   198
    in Scan.lift (rep args) >> check end);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   199
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   200
fun match_term_args ctxt args ts =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   201
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   202
    val match_types = Sign.typ_match (Proof_Context.theory_of ctxt) o apply2 Term.fastype_of;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   203
    val tyenv = fold match_types (args ~~ ts) Vartab.empty;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   204
    val tenv =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   205
      fold (fn ((xi, T), t) => Vartab.update_new (xi, (T, t)))
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   206
        (map Term.dest_Var args ~~ ts) Vartab.empty;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   207
  in Envir.Envir {maxidx = ~1, tenv = tenv, tyenv = tyenv} end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   208
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   209
fun check_attrib ctxt attrib =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   210
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   211
    val name = Binding.name_of attrib;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   212
    val pos = Binding.pos_of attrib;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   213
    val named_thm = Named_Theorems.check ctxt (name, pos);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   214
    val parser: Method.modifier parser =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   215
      Args.$$$ name -- Args.colon >>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   216
        K {init = I, attribute = Named_Theorems.add named_thm, pos = pos};
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   217
  in (named_thm, parser) end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   218
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   219
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   220
fun instantiate_text env text =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   221
  let val morphism = Morphism.term_morphism "instantiate_text" (Envir.norm_term env);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   222
  in Method.map_source (Token.transform_src morphism) text end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   223
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   224
fun evaluate_dynamic_thm ctxt name =
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   225
  (case try (Named_Theorems.get ctxt) name of
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   226
    SOME thms => thms
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   227
  | NONE => Proof_Context.get_thms ctxt name);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   228
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   229
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   230
fun evaluate_named_theorems ctxt =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   231
  (Method.map_source o Token.map_values)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   232
    (fn Token.Fact (SOME name, _) =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   233
          Token.Fact (SOME name, evaluate_dynamic_thm ctxt name)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   234
      | x => x);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   235
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   236
fun method_evaluate text ctxt : Method.method = fn facts => fn st =>
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   237
  let
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   238
    val ctxt' = Config.put Method.closure false ctxt;
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   239
  in
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   240
    if is_dummy st then Seq.empty
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   241
    else Method.evaluate (evaluate_named_theorems ctxt' text) ctxt' facts st
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   242
  end;
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   243
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   244
fun evaluate_method_def fix_env raw_text ctxt =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   245
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   246
    val text = raw_text
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   247
      |> instantiate_text fix_env;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   248
  in method_evaluate text ctxt end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   249
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   250
fun setup_local_method binding lthy =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   251
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   252
    val full_name = Local_Theory.full_name lthy binding;
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   253
    fun get_method ctxt = lookup_dynamic_method ctxt full_name ctxt;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   254
  in
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   255
    lthy
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   256
    |> update_dynamic_method (full_name, K Method.fail)
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   257
    |> Method.local_setup binding (Scan.succeed get_method) "(internal)"
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   258
  end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   259
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   260
fun setup_local_fact binding = Named_Theorems.declare binding "";
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   261
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   262
(* FIXME: In general we need the ability to override all dynamic facts.
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   263
   This is also slow: we need Named_Theorems.only *)
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   264
fun empty_named_thm named_thm ctxt =
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   265
  let
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   266
    val contents = Named_Theorems.get ctxt named_thm;
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   267
    val attrib = snd oo Thm.proof_attributes [Named_Theorems.del named_thm];
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   268
  in fold attrib contents ctxt end;
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   269
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   270
fun dummy_named_thm named_thm ctxt =
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   271
  let
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   272
    val ctxt' = empty_named_thm named_thm ctxt;
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   273
    val (_,ctxt'') = Thm.proof_attributes [Named_Theorems.add named_thm] dummy_free_thm ctxt';
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   274
  in ctxt'' end;
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   275
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   276
fun parse_method_args method_names =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   277
  let
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   278
    fun bind_method (name, text) ctxt = 
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   279
    let
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   280
      val method = method_evaluate text;
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   281
      val inner_update = method o update_dynamic_method (name,K (method ctxt));
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   282
    in update_dynamic_method (name,inner_update) ctxt end;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   283
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   284
    fun do_parse t = parse_method >> pair t;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   285
    fun rep [] x = Scan.succeed [] x
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   286
      | rep (t :: ts) x  = (do_parse t -- rep ts >> op ::) x;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   287
  in rep method_names >> fold bind_method end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   288
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   289
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   290
(* FIXME redundant!? -- base name of binding is not changed by usual morphisms*)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   291
fun Morphism_name phi name =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   292
  Morphism.binding phi (Binding.make (name, Position.none)) |> Binding.name_of;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   293
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   294
fun add_method binding ((fixes, declares, methods), text) lthy =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   295
  lthy |>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   296
  Local_Theory.declaration {syntax = false, pervasive = true} (fn phi =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   297
    map_methods
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   298
      (Symtab.update (Local_Theory.full_name lthy binding,
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   299
        (((map (Morphism.term phi) fixes),
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   300
          (map (Morphism_name phi) declares, map (Morphism_name phi) methods)),
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   301
          Method.map_source (Token.transform_src phi) text))));
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   302
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   303
fun get_inner_method ctxt (xname, pos) =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   304
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   305
    val name = Method.check_name ctxt (xname, pos);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   306
  in
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   307
    (case Symtab.lookup (get_methods ctxt) name of
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   308
      SOME entry => entry
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   309
    | NONE => error ("Unknown Eisbach method: " ^ quote name ^ Position.here pos))
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   310
  end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   311
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   312
fun eval_inner_method ctxt0 header fixes attribs methods =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   313
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   314
    val ((term_args, hmethods), text) = header;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   315
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   316
    fun match fixes = (* FIXME proper context!? *)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   317
      (case Seq.pull (Unify.matchers (Context.Proof ctxt0) (term_args ~~ fixes)) of
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   318
        SOME (env, _) => env
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   319
      | NONE => error "Couldn't match term arguments");
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   320
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   321
    fun add_thms (name, thms) =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   322
      fold (Context.proof_map o Named_Theorems.add_thm name) thms;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   323
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   324
    val setup_ctxt = fold add_thms attribs
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   325
      #> fold update_dynamic_method (hmethods ~~ methods)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   326
      #> put_recursive_method (fn fixes => evaluate_method_def (match fixes) text);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   327
  in
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   328
    fn ctxt => evaluate_method_def (match fixes) text (setup_ctxt ctxt)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   329
  end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   330
60379
51d9dcd71ad7 tuned signature;
wenzelm
parents: 60287
diff changeset
   331
fun gen_method_definition prep_var name vars uses attribs methods source lthy =
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   332
  let
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   333
    val (uses_nms, lthy1) = lthy
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   334
      |> Proof_Context.concealed
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   335
      |> Local_Theory.open_target |-> Proof_Context.private_scope
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   336
      |> Local_Theory.map_background_naming (Name_Space.add_path (Binding.name_of name))
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   337
      |> Config.put Method.old_section_parser true
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   338
      |> fold setup_local_method methods
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   339
      |> fold_map setup_local_fact uses;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   340
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   341
    val ((xs, Ts), lthy2) = lthy1
60379
51d9dcd71ad7 tuned signature;
wenzelm
parents: 60287
diff changeset
   342
      |> fold_map prep_var vars |-> Proof_Context.add_fixes
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   343
      |-> (fn xs => fold_map Proof_Context.inferred_param xs #>> pair xs);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   344
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   345
    val term_args = map Free (xs ~~ Ts);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   346
    val (named_thms, modifiers) = map (check_attrib lthy2) (attribs @ uses) |> split_list;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   347
    val self_name :: method_names = map (Local_Theory.full_name lthy2) (name :: methods);
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   348
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   349
    fun parser args eval =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   350
      apfst (Config.put_generic Method.old_section_parser true) #>
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   351
      (parse_term_args args --
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   352
        parse_method_args method_names --|
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   353
        (Scan.depend (fn context =>
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   354
              Scan.succeed (Context.map_proof (fold empty_named_thm uses_nms) context,())) --
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   355
         Method.sections modifiers) >> eval);
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   356
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   357
    val lthy3 = lthy2
60285
b4f1a0a701ae updated Eisbach, using version 4863020a8fe9 of its Bitbucket repository;
wenzelm
parents: 60248
diff changeset
   358
      |> fold dummy_named_thm named_thms
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   359
      |> Method.local_setup (Binding.make (Binding.name_of name, Position.none))
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   360
        (parser term_args
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   361
          (fn (fixes, decl) => fn ctxt => get_recursive_method ctxt fixes (decl ctxt))) "(internal)";
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   362
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   363
    val (src, text) = read_text_closure lthy3 source;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   364
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   365
    val morphism =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   366
      Variable.export_morphism lthy3
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   367
        (lthy
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   368
          |> Proof_Context.transfer (Proof_Context.theory_of lthy3)
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   369
          |> Token.declare_maxidx_src src
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   370
          |> Variable.declare_maxidx (Variable.maxidx_of lthy3));
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   371
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   372
    val text' = Method.map_source (Token.transform_src morphism) text;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   373
    val term_args' = map (Morphism.term morphism) term_args;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   374
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   375
    fun real_exec ts ctxt =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   376
      evaluate_method_def (match_term_args ctxt term_args' ts) text' ctxt;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   377
    val real_parser =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   378
      parser term_args' (fn (fixes, decl) => fn ctxt =>
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   379
        real_exec fixes (put_recursive_method real_exec (decl ctxt)));
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   380
  in
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   381
    lthy3
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   382
    |> Local_Theory.close_target
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   383
    |> Proof_Context.restore_naming lthy
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   384
    |> Method.local_setup name real_parser "(defined in Eisbach)"
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   385
    |> add_method name ((term_args', named_thms, method_names), text')
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   386
  end;
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   387
60379
51d9dcd71ad7 tuned signature;
wenzelm
parents: 60287
diff changeset
   388
val method_definition = gen_method_definition Proof_Context.cert_var;
51d9dcd71ad7 tuned signature;
wenzelm
parents: 60287
diff changeset
   389
val method_definition_cmd = gen_method_definition Proof_Context.read_var;
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   390
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   391
val _ =
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   392
  Outer_Syntax.local_theory @{command_keyword method} "Eisbach method definition"
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   393
    (Parse.binding -- Parse.for_fixes --
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   394
      ((Scan.optional (@{keyword "methods"} |-- Parse.!!! (Scan.repeat1 Parse.binding)) []) --
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   395
        (Scan.optional (@{keyword "uses"} |-- Parse.!!! (Scan.repeat1 Parse.binding)) [])) --
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   396
      (Scan.optional (@{keyword "declares"} |-- Parse.!!! (Scan.repeat1 Parse.binding)) []) --
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   397
      Parse.!!! (@{keyword "="}
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   398
        |-- (Parse.position (Parse.args1 (K true)) >> (fn (args, pos) => Token.src ("", pos) args)))
60287
adde5ce1e0a7 updated Eisbach, using version 134bc592909c of its Bitbucket repository;
wenzelm
parents: 60285
diff changeset
   399
      >> (fn ((((name, vars), (methods, uses)), attribs), source) =>
60209
022ca2799c73 updated Eisbach, using version 5df3d8c72403 of its Bitbucket repository;
wenzelm
parents: 60119
diff changeset
   400
        method_definition_cmd name vars uses attribs methods source));
60119
54bea620e54f added Eisbach, using version 3752768caa17 of its Bitbucket repository;
wenzelm
parents:
diff changeset
   401
end;