src/HOL/Import/import.ML
author wenzelm
Thu, 15 Mar 2012 19:02:34 +0100
changeset 47821 b8c7eb0c2f89
parent 47676 50dbdb9e28ad
child 47836 5c6955f487e5
permissions -rw-r--r--
declare minor keywords via theory header;
haftmann@31723
     1
(*  Title:      HOL/Import/import.ML
skalberg@14620
     2
    Author:     Sebastian Skalberg (TU Muenchen)
skalberg@14620
     3
*)
skalberg@14620
     4
haftmann@31723
     5
signature IMPORT =
skalberg@14516
     6
sig
wenzelm@32740
     7
    val debug      : bool Unsynchronized.ref
wenzelm@31265
     8
    val import_tac : Proof.context -> string * string -> tactic
wenzelm@18708
     9
    val setup      : theory -> theory
skalberg@14516
    10
end
skalberg@14516
    11
wenzelm@33522
    12
structure ImportData = Theory_Data
wenzelm@22846
    13
(
wenzelm@33522
    14
  type T = ProofKernel.thm option array option  (* FIXME mutable array !??!!! *)
wenzelm@22846
    15
  val empty = NONE
wenzelm@22846
    16
  val extend = I
wenzelm@33522
    17
  fun merge _ = NONE
wenzelm@22846
    18
)
skalberg@14620
    19
haftmann@47674
    20
structure Import : IMPORT =
skalberg@14516
    21
struct
skalberg@14516
    22
wenzelm@32740
    23
val debug = Unsynchronized.ref false
skalberg@14516
    24
fun message s = if !debug then writeln s else ()
skalberg@14516
    25
wenzelm@31265
    26
fun import_tac ctxt (thyname, thmname) =
wenzelm@17370
    27
    if ! quick_and_dirty
wenzelm@43232
    28
    then Skip_Proof.cheat_tac (Proof_Context.theory_of ctxt)
skalberg@14516
    29
    else
skalberg@14516
    30
     fn th =>
wenzelm@21590
    31
        let
wenzelm@43232
    32
            val thy = Proof_Context.theory_of ctxt
wenzelm@21590
    33
            val prem = hd (prems_of th)
wenzelm@31265
    34
            val _ = message ("Import_tac: thyname=" ^ thyname ^ ", thmname=" ^ thmname)
wenzelm@31265
    35
            val _ = message ("Import trying to prove " ^ Syntax.string_of_term ctxt prem)
wenzelm@21590
    36
            val int_thms = case ImportData.get thy of
wenzelm@21590
    37
                               NONE => fst (Replay.setup_int_thms thyname thy)
wenzelm@21590
    38
                             | SOME a => a
wenzelm@21590
    39
            val proof = snd (ProofKernel.import_proof thyname thmname thy) thy
haftmann@47671
    40
            val importerthm = snd (Replay.replay_proof int_thms thyname thmname proof thy)
haftmann@47671
    41
            val thm = snd (ProofKernel.to_isa_thm importerthm)
haftmann@47671
    42
            val rew = ProofKernel.rewrite_importer_term (concl_of thm) thy
wenzelm@36945
    43
            val thm = Thm.equal_elim rew thm
haftmann@47671
    44
            val prew = ProofKernel.rewrite_importer_term prem thy
wenzelm@21590
    45
            val prem' = #2 (Logic.dest_equals (prop_of prew))
wenzelm@32111
    46
            val _ = message ("Import proved " ^ Display.string_of_thm ctxt thm)
wenzelm@17657
    47
            val thm = ProofKernel.disambiguate_frees thm
wenzelm@32111
    48
            val _ = message ("Disambiguate: " ^ Display.string_of_thm ctxt thm)
wenzelm@21590
    49
        in
wenzelm@21590
    50
            case Shuffler.set_prop thy prem' [("",thm)] of
wenzelm@21590
    51
                SOME (_,thm) =>
wenzelm@21590
    52
                let
wenzelm@21590
    53
                    val _ = if prem' aconv (prop_of thm)
wenzelm@21590
    54
                            then message "import: Terms match up"
wenzelm@21590
    55
                            else message "import: Terms DO NOT match up"
wenzelm@36945
    56
                    val thm' = Thm.equal_elim (Thm.symmetric prew) thm
wenzelm@31945
    57
                    val res = Thm.bicompose true (false,thm',0) 1 th
wenzelm@21590
    58
                in
wenzelm@21590
    59
                    res
wenzelm@21590
    60
                end
wenzelm@21590
    61
              | NONE => (message "import: set_prop didn't succeed"; no_tac th)
wenzelm@21590
    62
        end
wenzelm@21590
    63
wenzelm@31265
    64
val setup = Method.setup @{binding import}
wenzelm@31265
    65
  (Scan.lift (Args.name -- Args.name) >>
wenzelm@31265
    66
    (fn arg => fn ctxt => SIMPLE_METHOD (import_tac ctxt arg)))
haftmann@47670
    67
  "import external theorem"
skalberg@14516
    68
haftmann@47676
    69
(* Parsers *)
haftmann@47676
    70
haftmann@47676
    71
val import_segment = Parse.name >> set_import_segment
haftmann@47676
    72
haftmann@47676
    73
haftmann@47676
    74
val import_theory = (Parse.name -- Parse.name) >> (fn (location, thyname) =>
haftmann@47676
    75
                               fn thy =>
haftmann@47676
    76
                                  thy |> set_generating_thy thyname
haftmann@47676
    77
                                      |> Sign.add_path thyname
haftmann@47676
    78
                                      |> add_dump ("setup_theory " ^ quote location ^ " " ^ thyname))
haftmann@47676
    79
haftmann@47676
    80
fun end_import toks =
haftmann@47676
    81
    Scan.succeed
haftmann@47676
    82
        (fn thy =>
haftmann@47676
    83
            let
haftmann@47676
    84
                val thyname = get_generating_thy thy
haftmann@47676
    85
                val segname = get_import_segment thy
haftmann@47676
    86
                val (int_thms,facts) = Replay.setup_int_thms thyname thy
haftmann@47676
    87
                val thmnames = filter_out (should_ignore thyname thy) facts
haftmann@47676
    88
                fun replay thy = Replay.import_thms thyname int_thms thmnames thy
haftmann@47676
    89
            in
haftmann@47676
    90
                thy |> clear_import_thy
haftmann@47676
    91
                    |> set_segment thyname segname
haftmann@47676
    92
                    |> set_used_names facts
haftmann@47676
    93
                    |> replay 
haftmann@47676
    94
                    |> clear_used_names
haftmann@47676
    95
                    |> export_importer_pending
haftmann@47676
    96
                    |> Sign.parent_path
haftmann@47676
    97
                    |> dump_import_thy thyname
haftmann@47676
    98
                    |> add_dump ";end_setup"
haftmann@47676
    99
            end) toks
haftmann@47676
   100
haftmann@47676
   101
val ignore_thms = Scan.repeat1 Parse.name
haftmann@47676
   102
                               >> (fn ignored =>
haftmann@47676
   103
                                   fn thy =>
haftmann@47676
   104
                                      let
haftmann@47676
   105
                                          val thyname = get_import_thy thy
haftmann@47676
   106
                                      in
haftmann@47676
   107
                                          Library.foldl (fn (thy,thmname) => ignore_importer thyname thmname thy) (thy,ignored)
haftmann@47676
   108
                                      end)
haftmann@47676
   109
haftmann@47676
   110
val thm_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname)
haftmann@47676
   111
                            >> (fn thmmaps =>
haftmann@47676
   112
                                fn thy =>
haftmann@47676
   113
                                   let
haftmann@47676
   114
                                       val thyname = get_import_thy thy
haftmann@47676
   115
                                   in
haftmann@47676
   116
                                       Library.foldl (fn (thy,(hol,isa)) => add_importer_mapping thyname hol isa thy) (thy,thmmaps)
haftmann@47676
   117
                                   end)
haftmann@47676
   118
haftmann@47676
   119
val type_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname)
haftmann@47676
   120
                             >> (fn typmaps =>
haftmann@47676
   121
                                 fn thy =>
haftmann@47676
   122
                                    let
haftmann@47676
   123
                                        val thyname = get_import_thy thy
haftmann@47676
   124
                                    in
haftmann@47676
   125
                                        Library.foldl (fn (thy,(hol,isa)) => add_importer_type_mapping thyname hol false isa thy) (thy,typmaps)
haftmann@47676
   126
                                    end)
haftmann@47676
   127
haftmann@47676
   128
val def_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname)
haftmann@47676
   129
                            >> (fn defmaps =>
haftmann@47676
   130
                                fn thy =>
haftmann@47676
   131
                                   let
haftmann@47676
   132
                                       val thyname = get_import_thy thy
haftmann@47676
   133
                                   in
haftmann@47676
   134
                                       Library.foldl (fn (thy,(hol,isa)) => add_defmap thyname hol isa thy) (thy,defmaps)
haftmann@47676
   135
                                   end)
haftmann@47676
   136
haftmann@47676
   137
val const_renames = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.name)
haftmann@47676
   138
                                 >> (fn renames =>
haftmann@47676
   139
                                     fn thy =>
haftmann@47676
   140
                                        let
haftmann@47676
   141
                                            val thyname = get_import_thy thy
haftmann@47676
   142
                                        in
haftmann@47676
   143
                                            Library.foldl (fn (thy,(hol,isa)) => add_importer_const_renaming thyname hol isa thy) (thy,renames)
haftmann@47676
   144
                                        end)
haftmann@47676
   145
                                                                                                                                      
haftmann@47676
   146
val const_maps = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname -- Scan.option (Parse.$$$ "::" |-- Parse.typ))
haftmann@47676
   147
                              >> (fn constmaps =>
haftmann@47676
   148
                                  fn thy =>
haftmann@47676
   149
                                     let
haftmann@47676
   150
                                         val thyname = get_import_thy thy
haftmann@47676
   151
                                     in
haftmann@47676
   152
                                         Library.foldl (fn (thy,((hol,isa),NONE)) => add_importer_const_mapping thyname hol false isa thy
haftmann@47676
   153
                                                 | (thy,((hol,isa),SOME ty)) => add_importer_const_wt_mapping thyname hol false isa (Syntax.read_typ_global thy ty) thy) (thy,constmaps)
haftmann@47676
   154
                                     end)
haftmann@47676
   155
haftmann@47676
   156
val const_moves = Scan.repeat1 (Parse.name --| Parse.$$$ ">" -- Parse.xname -- Scan.option (Parse.$$$ "::" |-- Parse.typ))
haftmann@47676
   157
                               >> (fn constmaps =>
haftmann@47676
   158
                                   fn thy =>
haftmann@47676
   159
                                      let
haftmann@47676
   160
                                          val thyname = get_import_thy thy
haftmann@47676
   161
                                      in
haftmann@47676
   162
                                          Library.foldl (fn (thy,((hol,isa),NONE)) => add_importer_const_mapping thyname hol true isa thy
haftmann@47676
   163
                                                  | (thy,((hol,isa),SOME ty)) => add_importer_const_wt_mapping thyname hol true isa (Syntax.read_typ_global thy ty) thy) (thy,constmaps)
haftmann@47676
   164
                                      end)
haftmann@47676
   165
haftmann@47676
   166
fun import_thy location s =
haftmann@47676
   167
    let
haftmann@47676
   168
        val src_location = Path.append (Path.explode location) (Path.basic (s ^ ".imp"))
haftmann@47676
   169
        val is = TextIO.openIn (File.platform_path src_location)
haftmann@47676
   170
        val inp = TextIO.inputAll is
haftmann@47676
   171
        val _ = TextIO.closeIn is
haftmann@47676
   172
        val orig_source = Source.of_string inp
haftmann@47676
   173
        val symb_source = Symbol.source orig_source
haftmann@47676
   174
        val lexes =
haftmann@47676
   175
          (Scan.make_lexicon
haftmann@47676
   176
            (map Symbol.explode ["import_segment","ignore_thms","import","end",">","::","const_maps","const_moves","thm_maps","const_renames","type_maps","def_maps"]),
haftmann@47676
   177
                  Scan.empty_lexicon)
haftmann@47676
   178
        val token_source = Token.source {do_recover = NONE} (K lexes) Position.start symb_source
haftmann@47676
   179
        val token_list = filter_out (Token.is_kind Token.Space) (Source.exhaust token_source)
haftmann@47676
   180
        val import_segmentP = Parse.$$$ "import_segment" |-- import_segment
haftmann@47676
   181
        val type_mapsP = Parse.$$$ "type_maps" |-- type_maps
haftmann@47676
   182
        val def_mapsP = Parse.$$$ "def_maps" |-- def_maps
haftmann@47676
   183
        val const_mapsP = Parse.$$$ "const_maps" |-- const_maps
haftmann@47676
   184
        val const_movesP = Parse.$$$ "const_moves" |-- const_moves
haftmann@47676
   185
        val const_renamesP = Parse.$$$ "const_renames" |-- const_renames
haftmann@47676
   186
        val ignore_thmsP = Parse.$$$ "ignore_thms" |-- ignore_thms
haftmann@47676
   187
        val thm_mapsP = Parse.$$$ "thm_maps" |-- thm_maps
haftmann@47676
   188
        val parser = type_mapsP || def_mapsP || const_mapsP || const_movesP || const_renamesP || thm_mapsP || ignore_thmsP || import_segmentP
haftmann@47676
   189
        val importP = Parse.$$$ "import" |-- Scan.repeat parser --| Parse.$$$ "end"
haftmann@47676
   190
        fun apply [] thy = thy
haftmann@47676
   191
          | apply (f::fs) thy = apply fs (f thy)
haftmann@47676
   192
    in
haftmann@47676
   193
        apply (set_replaying_thy s :: Sign.add_path s :: fst (importP token_list))
haftmann@47676
   194
    end
haftmann@47676
   195
haftmann@47676
   196
fun create_int_thms thyname thy =
haftmann@47676
   197
    if ! quick_and_dirty
haftmann@47676
   198
    then thy
haftmann@47676
   199
    else
haftmann@47676
   200
        case ImportData.get thy of
haftmann@47676
   201
            NONE => ImportData.put (SOME (fst (Replay.setup_int_thms thyname thy))) thy
haftmann@47676
   202
          | SOME _ => error "Import data not closed - forgotten an end_setup, mayhap?"
haftmann@47676
   203
haftmann@47676
   204
fun clear_int_thms thy =
haftmann@47676
   205
    if ! quick_and_dirty
haftmann@47676
   206
    then thy
haftmann@47676
   207
    else
haftmann@47676
   208
        case ImportData.get thy of
haftmann@47676
   209
            NONE => error "Import data already cleared - forgotten a setup_theory?"
haftmann@47676
   210
          | SOME _ => ImportData.put NONE thy
haftmann@47676
   211
haftmann@47676
   212
val setup_theory = (Parse.name -- Parse.name)
haftmann@47676
   213
                       >>
haftmann@47676
   214
                       (fn (location, thyname) =>
haftmann@47676
   215
                        fn thy =>
haftmann@47676
   216
                           (case Importer_DefThy.get thy of
haftmann@47676
   217
                                NoImport => thy
haftmann@47676
   218
                              | Generating _ => error "Currently generating a theory!"
haftmann@47676
   219
                              | Replaying _ => thy |> clear_import_thy)
haftmann@47676
   220
                               |> import_thy location thyname
haftmann@47676
   221
                               |> create_int_thms thyname)
haftmann@47676
   222
haftmann@47676
   223
fun end_setup toks =
haftmann@47676
   224
    Scan.succeed
haftmann@47676
   225
        (fn thy =>
haftmann@47676
   226
            let
haftmann@47676
   227
                val thyname = get_import_thy thy
haftmann@47676
   228
                val segname = get_import_segment thy
haftmann@47676
   229
            in
haftmann@47676
   230
                thy |> set_segment thyname segname
haftmann@47676
   231
                    |> clear_import_thy
haftmann@47676
   232
                    |> clear_int_thms
haftmann@47676
   233
                    |> Sign.parent_path
haftmann@47676
   234
            end) toks
haftmann@47676
   235
haftmann@47676
   236
val set_dump  = Parse.string -- Parse.string   >> setup_dump
haftmann@47676
   237
fun fl_dump toks  = Scan.succeed flush_dump toks
haftmann@47676
   238
val append_dump = (Parse.verbatim || Parse.string) >> add_dump
haftmann@47676
   239
haftmann@47676
   240
val _ =
wenzelm@47821
   241
  (Outer_Syntax.command "import_segment"
haftmann@47676
   242
                       "Set import segment name"
haftmann@47676
   243
                       Keyword.thy_decl (import_segment >> Toplevel.theory);
haftmann@47676
   244
   Outer_Syntax.command "import_theory"
haftmann@47676
   245
                       "Set default external theory name"
haftmann@47676
   246
                       Keyword.thy_decl (import_theory >> Toplevel.theory);
haftmann@47676
   247
   Outer_Syntax.command "end_import"
haftmann@47676
   248
                       "End external import"
haftmann@47676
   249
                       Keyword.thy_decl (end_import >> Toplevel.theory);
haftmann@47676
   250
   Outer_Syntax.command "setup_theory"
haftmann@47676
   251
                       "Setup external theory replaying"
haftmann@47676
   252
                       Keyword.thy_decl (setup_theory >> Toplevel.theory);
haftmann@47676
   253
   Outer_Syntax.command "end_setup"
haftmann@47676
   254
                       "End external setup"
haftmann@47676
   255
                       Keyword.thy_decl (end_setup >> Toplevel.theory);
haftmann@47676
   256
   Outer_Syntax.command "setup_dump"
haftmann@47676
   257
                       "Setup the dump file name"
haftmann@47676
   258
                       Keyword.thy_decl (set_dump >> Toplevel.theory);
haftmann@47676
   259
   Outer_Syntax.command "append_dump"
haftmann@47676
   260
                       "Add text to dump file"
haftmann@47676
   261
                       Keyword.thy_decl (append_dump >> Toplevel.theory);
haftmann@47676
   262
   Outer_Syntax.command "flush_dump"
haftmann@47676
   263
                       "Write the dump to file"
haftmann@47676
   264
                       Keyword.thy_decl (fl_dump >> Toplevel.theory);
haftmann@47676
   265
   Outer_Syntax.command "ignore_thms"
haftmann@47676
   266
                       "Theorems to ignore in next external theory import"
haftmann@47676
   267
                       Keyword.thy_decl (ignore_thms >> Toplevel.theory);
haftmann@47676
   268
   Outer_Syntax.command "type_maps"
haftmann@47676
   269
                       "Map external type names to existing Isabelle/HOL type names"
haftmann@47676
   270
                       Keyword.thy_decl (type_maps >> Toplevel.theory);
haftmann@47676
   271
   Outer_Syntax.command "def_maps"
haftmann@47676
   272
                       "Map external constant names to their primitive definitions"
haftmann@47676
   273
                       Keyword.thy_decl (def_maps >> Toplevel.theory);
haftmann@47676
   274
   Outer_Syntax.command "thm_maps"
haftmann@47676
   275
                       "Map external theorem names to existing Isabelle/HOL theorem names"
haftmann@47676
   276
                       Keyword.thy_decl (thm_maps >> Toplevel.theory);
haftmann@47676
   277
   Outer_Syntax.command "const_renames"
haftmann@47676
   278
                       "Rename external const names"
haftmann@47676
   279
                       Keyword.thy_decl (const_renames >> Toplevel.theory);
haftmann@47676
   280
   Outer_Syntax.command "const_moves"
haftmann@47676
   281
                       "Rename external const names to other external constants"
haftmann@47676
   282
                       Keyword.thy_decl (const_moves >> Toplevel.theory);
haftmann@47676
   283
   Outer_Syntax.command "const_maps"
haftmann@47676
   284
                       "Map external const names to existing Isabelle/HOL const names"
haftmann@47676
   285
                       Keyword.thy_decl (const_maps >> Toplevel.theory));
haftmann@47676
   286
skalberg@14516
   287
end
wenzelm@15707
   288