src/Pure/Isar/proof_context.ML
changeset 8616 90d2fed59be1
parent 8462 7f4e4e875c13
child 8637 e86e49aa1631
equal deleted inserted replaced
8615:419166fa66d0 8616:90d2fed59be1
    20   val print_cases: context -> unit
    20   val print_cases: context -> unit
    21   val pretty_prems: context -> Pretty.T list
    21   val pretty_prems: context -> Pretty.T list
    22   val pretty_context: context -> Pretty.T list
    22   val pretty_context: context -> Pretty.T list
    23   val print_proof_data: theory -> unit
    23   val print_proof_data: theory -> unit
    24   val init: theory -> context
    24   val init: theory -> context
       
    25   val assumptions: context -> (cterm * ((int -> tactic) * (int -> tactic))) list
       
    26   val fixed_names: context -> string list
    25   val read_typ: context -> string -> typ
    27   val read_typ: context -> string -> typ
    26   val cert_typ: context -> typ -> typ
    28   val cert_typ: context -> typ -> typ
    27   val cert_skolem: context -> string -> string
    29   val cert_skolem: context -> string -> string
    28   val read_termTs: context -> (string * typ) list -> term list * (indexname * typ) list
    30   val read_termTs: context -> (string * typ) list -> term list * (indexname * typ) list
    29   val read_term: context -> string -> term
    31   val read_term: context -> string -> term
    36   val cert_term_pats: typ -> context -> term list -> term list
    38   val cert_term_pats: typ -> context -> term list -> term list
    37   val cert_prop_pats: context -> term list -> term list
    39   val cert_prop_pats: context -> term list -> term list
    38   val declare_term: term -> context -> context
    40   val declare_term: term -> context -> context
    39   val declare_terms: term list -> context -> context
    41   val declare_terms: term list -> context -> context
    40   val warn_extra_tfrees: context -> context -> context
    42   val warn_extra_tfrees: context -> context -> context
    41   val add_binds: (indexname * string option) list -> context -> context
    43   val generalizeT: context -> context -> typ -> typ
    42   val add_binds_i: (indexname * term option) list -> context -> context
    44   val generalize: context -> context -> term -> term
       
    45   val find_free: term -> string -> term option 
       
    46   val export_wrt: context -> context option
       
    47     -> (thm -> thm) * ((int -> tactic) * (int -> tactic)) list
    43   val auto_bind_goal: term -> context -> context
    48   val auto_bind_goal: term -> context -> context
    44   val auto_bind_facts: string -> term list -> context -> context
    49   val auto_bind_facts: string -> term list -> context -> context
    45   val match_bind: (string list * string) list -> context -> context
    50   val match_bind: bool -> (string list * string) list -> context -> context
    46   val match_bind_i: (term list * term) list -> context -> context
    51   val match_bind_i: bool -> (term list * term) list -> context -> context
    47   val read_propp: context * (string * (string list * string list))
    52   val read_propp: context * (string * (string list * string list))
    48     -> context * (term * (term list * term list))
    53     -> context * (term * (term list * term list))
    49   val cert_propp: context * (term * (term list * term list))
    54   val cert_propp: context * (term * (term list * term list))
    50     -> context * (term * (term list * term list))
    55     -> context * (term * (term list * term list))
    51   val bind_propp: context * (string * (string list * string list)) -> context * term
    56   val bind_propp: context * (string * (string list * string list))
    52   val bind_propp_i: context * (term * (term list * term list)) -> context * term
    57     -> context * (term * (context -> context))
       
    58   val bind_propp_i: context * (term * (term list * term list))
       
    59     -> context * (term * (context -> context))
    53   val get_thm: context -> string -> thm
    60   val get_thm: context -> string -> thm
    54   val get_thms: context -> string -> thm list
    61   val get_thms: context -> string -> thm list
    55   val get_thmss: context -> string list -> thm list
    62   val get_thmss: context -> string list -> thm list
    56   val put_thm: string * thm -> context -> context
    63   val put_thm: string * thm -> context -> context
    57   val put_thms: string * thm list -> context -> context
    64   val put_thms: string * thm list -> context -> context
    58   val put_thmss: (string * thm list) list -> context -> context
    65   val put_thmss: (string * thm list) list -> context -> context
    59   val reset_thms: string -> context -> context
    66   val reset_thms: string -> context -> context
    60   val have_thmss: thm list -> string -> context attribute list
    67   val have_thmss: thm list -> string -> context attribute list
    61     -> (thm list * context attribute list) list -> context -> context * (string * thm list)
    68     -> (thm list * context attribute list) list -> context -> context * (string * thm list)
    62   val assumptions: context -> (cterm * ((int -> tactic) * (int -> tactic))) list
       
    63   val fixed_names: context -> string list
       
    64   val most_general_varify_tfrees: thm -> thm
       
    65   val assume: ((int -> tactic) * (int -> tactic))
    69   val assume: ((int -> tactic) * (int -> tactic))
    66     -> (string * context attribute list * (string * (string list * string list)) list) list
    70     -> (string * context attribute list * (string * (string list * string list)) list) list
    67     -> context -> context * ((string * thm list) list * thm list)
    71     -> context -> context * ((string * thm list) list * thm list)
    68   val assume_i: ((int -> tactic) * (int -> tactic))
    72   val assume_i: ((int -> tactic) * (int -> tactic))
    69     -> (string * context attribute list * (term * (term list * term list)) list) list
    73     -> (string * context attribute list * (term * (term list * term list)) list) list
   105     thms: thm list option Symtab.table,                                 (*local thms*)
   109     thms: thm list option Symtab.table,                                 (*local thms*)
   106     cases: (string * RuleCases.T) list,                                 (*local contexts*)
   110     cases: (string * RuleCases.T) list,                                 (*local contexts*)
   107     defs:
   111     defs:
   108       typ Vartab.table *                                                (*type constraints*)
   112       typ Vartab.table *                                                (*type constraints*)
   109       sort Vartab.table *                                               (*default sorts*)
   113       sort Vartab.table *                                               (*default sorts*)
   110       string list};                                                     (*used type var names*)
   114       (string list * term list Symtab.table)};                          (*used type variables*)
   111 
   115 
   112 exception CONTEXT of string * context;
   116 exception CONTEXT of string * context;
   113 
   117 
   114 
   118 
   115 fun make_context (thy, data, asms, binds, thms, cases, defs) =
   119 fun make_context (thy, data, asms, binds, thms, cases, defs) =
   202   (case prems_of ctxt of
   206   (case prems_of ctxt of
   203     [] => []
   207     [] => []
   204   | prems => [Pretty.big_list "prems:" (map pretty_thm prems)]);
   208   | prems => [Pretty.big_list "prems:" (map pretty_thm prems)]);
   205 
   209 
   206 fun pretty_context (ctxt as Context {asms = (_, (fixes, _)), cases,
   210 fun pretty_context (ctxt as Context {asms = (_, (fixes, _)), cases,
   207     defs = (types, sorts, used), ...}) =
   211     defs = (types, sorts, (used, _)), ...}) =
   208   let
   212   let
   209     val sign = sign_of ctxt;
   213     val sign = sign_of ctxt;
   210 
   214 
   211     val prt_term = Sign.pretty_term sign;
   215     val prt_term = Sign.pretty_term sign;
   212     val prt_typ = Sign.pretty_typ sign;
   216     val prt_typ = Sign.pretty_typ sign;
   335 (* init context *)
   339 (* init context *)
   336 
   340 
   337 fun init thy =
   341 fun init thy =
   338   let val data = Symtab.map (fn (_, (f, _)) => f thy) (ProofDataData.get thy) in
   342   let val data = Symtab.map (fn (_, (f, _)) => f thy) (ProofDataData.get thy) in
   339     make_context (thy, data, (([], []), ([], [])), Vartab.empty, Symtab.empty, [],
   343     make_context (thy, data, (([], []), ([], [])), Vartab.empty, Symtab.empty, [],
   340       (Vartab.empty, Vartab.empty, []))
   344       (Vartab.empty, Vartab.empty, ([], Symtab.empty)))
   341   end;
   345   end;
       
   346 
       
   347 
       
   348 (* get assumptions *)
       
   349 
       
   350 fun assumptions (Context {asms = ((asms, _), _), ...}) = asms;
       
   351 fun fixed_names (Context {asms = (_, (fixes, _)), ...}) = map #2 fixes;
       
   352 fun used_table (Context {defs = (_, _, (_, tab)), ...}) = tab;
   342 
   353 
   343 
   354 
   344 
   355 
   345 (** default sorts and types **)
   356 (** default sorts and types **)
   346 
   357 
   347 fun def_sort (Context {defs = (_, sorts, _), ...}) xi = Vartab.lookup (sorts, xi);
   358 fun def_sort (Context {defs = (_, sorts, _), ...}) xi = Vartab.lookup (sorts, xi);
   348 
   359 
   349 fun def_type (Context {binds, defs = (types, _, _), ...}) is_pat xi =
   360 fun def_type (Context {binds, defs = (types, _, _), ...}) is_pat xi =
   350   (case Vartab.lookup (types, xi) of
   361   (case Vartab.lookup (types, xi) of
   351     None =>
   362     None =>
   352       if is_pat then None
   363       if is_pat then None else
   353       else (case Vartab.lookup (binds, xi) of Some (Some (_, T)) => Some T | _ => None)
   364         (case Vartab.lookup (binds, xi) of
       
   365           Some (Some (_, T)) => Some (TypeInfer.polymorphicT T)
       
   366         | _ => None)
   354   | some => some);
   367   | some => some);
   355 
   368 
   356 
   369 
   357 
   370 
   358 (** prepare types **)
   371 (** prepare types **)
   403 
   416 
   404 
   417 
   405 (* read / certify wrt. signature *)     (*exception ERROR*) (*exception TERM*)
   418 (* read / certify wrt. signature *)     (*exception ERROR*) (*exception TERM*)
   406 
   419 
   407 fun read_def_termTs freeze sg (types, sorts, used) sTs =
   420 fun read_def_termTs freeze sg (types, sorts, used) sTs =
   408   let val (cts, env) = Thm.read_def_cterms (sg, types, sorts) used freeze sTs
   421   Sign.read_def_terms (sg, types, sorts) used freeze sTs;
   409   in (map Thm.term_of cts, env) end;
       
   410 
   422 
   411 fun read_def_termT freeze sg defs sT = apfst hd (read_def_termTs freeze sg defs [sT]);
   423 fun read_def_termT freeze sg defs sT = apfst hd (read_def_termTs freeze sg defs [sT]);
   412 
   424 
   413 fun read_term_sg freeze sg defs s = #1 (read_def_termT freeze sg defs (s, TypeInfer.logicT));
   425 fun read_term_sg freeze sg defs s = #1 (read_def_termT freeze sg defs (s, TypeInfer.logicT));
   414 fun read_prop_sg freeze sg defs s = #1 (read_def_termT freeze sg defs (s, propT));
   426 fun read_prop_sg freeze sg defs s = #1 (read_def_termT freeze sg defs (s, propT));
   429 (* norm_term *)
   441 (* norm_term *)
   430 
   442 
   431 (*beta normal form for terms (not eta normal form), chase variables in
   443 (*beta normal form for terms (not eta normal form), chase variables in
   432   bindings environment (code taken from Pure/envir.ML)*)
   444   bindings environment (code taken from Pure/envir.ML)*)
   433 
   445 
       
   446 fun unifyT ctxt (T, U) =
       
   447   let val maxidx = Int.max (Term.maxidx_of_typ T, Term.maxidx_of_typ U)
       
   448   in #1 (Type.unify (Sign.tsig_of (sign_of ctxt)) maxidx Vartab.empty (T, U)) end;
       
   449 
   434 fun norm_term (ctxt as Context {binds, ...}) =
   450 fun norm_term (ctxt as Context {binds, ...}) =
   435   let
   451   let
   436     (*raised when norm has no effect on a term, to do sharing instead of copying*)
   452     (*raised when norm has no effect on a term, to do sharing instead of copying*)
   437     exception SAME;
   453     exception SAME;
   438 
   454 
   439     fun norm (t as Var (xi, T)) =
   455     fun norm (t as Var (xi, T)) =
   440           (case Vartab.lookup (binds, xi) of
   456           (case Vartab.lookup (binds, xi) of
   441             Some (Some (u, U)) =>
   457             Some (Some (u, U)) =>
   442               if T = U then (norm u handle SAME => u)
   458               let
   443               else raise TYPE ("norm_term: ill-typed variable assigment", [T, U], [t, u])
   459                 val env = unifyT ctxt (T, U) handle Type.TUNIFY =>
       
   460                   raise TYPE ("norm_term: ill-typed variable assigment", [T, U], [t, u]);
       
   461                 val u' = Term.subst_TVars_Vartab env u;
       
   462               in norm u' handle SAME => u' end
   444           | _ => raise CONTEXT ("Unbound schematic variable: " ^ Syntax.string_of_vname xi, ctxt))
   463           | _ => raise CONTEXT ("Unbound schematic variable: " ^ Syntax.string_of_vname xi, ctxt))
   445       | norm (Abs (a, T, body)) =  Abs (a, T, norm body)
   464       | norm (Abs (a, T, body)) =  Abs (a, T, norm body)
   446       | norm (Abs (_, _, body) $ t) = normh (subst_bound (t, body))
   465       | norm (Abs (_, _, body) $ t) = normh (subst_bound (t, body))
   447       | norm (f $ t) =
   466       | norm (f $ t) =
   448           ((case norm f of
   467           ((case norm f of
   474 end;
   493 end;
   475 
   494 
   476 
   495 
   477 (* read terms *)
   496 (* read terms *)
   478 
   497 
   479 fun gen_read read app is_pat (ctxt as Context {defs = (_, _, used), ...}) s =
   498 fun gen_read read app is_pat (ctxt as Context {defs = (_, _, (used, _)), ...}) s =
   480   (transform_error (read (sign_of ctxt) (def_type ctxt is_pat, def_sort ctxt, used)) s
   499   (transform_error (read (sign_of ctxt) (def_type ctxt is_pat, def_sort ctxt, used)) s
   481     handle TERM (msg, _) => raise CONTEXT (msg, ctxt)
   500     handle TERM (msg, _) => raise CONTEXT (msg, ctxt)
   482     | ERROR_MESSAGE msg => raise CONTEXT (msg, ctxt))
   501     | ERROR_MESSAGE msg => raise CONTEXT (msg, ctxt))
   483   |> app (intern_skolem ctxt true)
   502   |> app (intern_skolem ctxt true)
   484   |> app (if is_pat then I else norm_term ctxt)
   503   |> app (if is_pat then I else norm_term ctxt)
   494 val read_prop = gen_read (read_prop_sg true) I false;
   513 val read_prop = gen_read (read_prop_sg true) I false;
   495 
   514 
   496 
   515 
   497 (* certify terms *)
   516 (* certify terms *)
   498 
   517 
   499 fun gen_cert cert is_pat ctxt t =
   518 fun gen_cert cert is_pat ctxt t = t
   500   (cert (sign_of ctxt) t handle TERM (msg, _) => raise CONTEXT (msg, ctxt))
       
   501   |> intern_skolem ctxt false
   519   |> intern_skolem ctxt false
   502   |> (if is_pat then I else norm_term ctxt);
   520   |> (if is_pat then I else norm_term ctxt)
       
   521   |> (fn t' => cert (sign_of ctxt) t' handle TERM (msg, _) => raise CONTEXT (msg, ctxt));
   503 
   522 
   504 val cert_term = gen_cert cert_term_sg false;
   523 val cert_term = gen_cert cert_term_sg false;
   505 val cert_prop = gen_cert cert_prop_sg false;
   524 val cert_prop = gen_cert cert_prop_sg false;
   506 
   525 
   507 fun cert_term_pats _ = map o gen_cert cert_term_sg true;
   526 fun cert_term_pats _ = map o gen_cert cert_term_sg true;
   518 val ins_sorts = foldl_types (foldl_atyps
   537 val ins_sorts = foldl_types (foldl_atyps
   519   (fn (sorts, TFree (x, S)) => Vartab.update (((x, ~1), S), sorts)
   538   (fn (sorts, TFree (x, S)) => Vartab.update (((x, ~1), S), sorts)
   520     | (sorts, TVar v) => Vartab.update (v, sorts)
   539     | (sorts, TVar v) => Vartab.update (v, sorts)
   521     | (sorts, _) => sorts));
   540     | (sorts, _) => sorts));
   522 
   541 
   523 val ins_used = foldl_types (foldl_atyps
   542 val ins_used = foldl_term_types (fn t => foldl_atyps
   524   (fn (used, TFree (x, _)) => x ins used
   543   (fn ((used, tab), TFree (x, _)) => (x ins used, Symtab.update_multi ((x, t), tab))
   525     | (used, TVar ((x, _), _)) => x ins used
       
   526     | (used, _) => used));
   544     | (used, _) => used));
   527 
   545 
   528 fun ins_skolem def_ty = foldr
   546 fun ins_skolem def_ty = foldr
   529   (fn ((x, x'), types) =>
   547   (fn ((x, x'), types) =>
   530     (case def_ty x' of
   548     (case def_ty x' of
   545 
   563 
   546 fun declare_term t ctxt = declare (ctxt, t);
   564 fun declare_term t ctxt = declare (ctxt, t);
   547 fun declare_terms ts ctxt = foldl declare (ctxt, ts);
   565 fun declare_terms ts ctxt = foldl declare (ctxt, ts);
   548 
   566 
   549 
   567 
       
   568 
       
   569 (** Hindley-Milner polymorphism **)
       
   570 
       
   571 
   550 (* warn_extra_tfrees *)
   572 (* warn_extra_tfrees *)
   551 
   573 
   552 fun warn_extra used1 used2 =
   574 local
   553   if used1 = used2 then ()
   575 
       
   576 fun used_free (a, ts) =
       
   577   (case mapfilter (fn Free (x, _) => Some x | _ => None) ts of
       
   578     [] => None
       
   579   | xs => Some (a, xs));
       
   580 
       
   581 fun warn_extra (names1: string list, tab1) (names2, tab2) =
       
   582   if names1 = names2 then ()
   554   else
   583   else
   555     (case Library.gen_rems (op =) (used2, used1) of
   584     let
   556       [] => ()
   585       val extra =
   557     | extras => warning ("DANGER!! Just introduced free type variable(s): " ^ commas (rev extras)));
   586         Library.gen_rems Library.eq_fst (Symtab.dest tab2, Symtab.dest tab1)
       
   587         |> mapfilter used_free;
       
   588       val tfrees = map #1 extra;
       
   589       val frees = Library.sort_strings (Library.distinct (flat (map #2 extra)));
       
   590     in
       
   591       if null extra then ()
       
   592       else warning ("Danger! Just introduced free type variable(s): " ^ commas tfrees ^ " in " ^
       
   593           space_implode " or " frees)
       
   594     end;
       
   595 
       
   596 in
   558 
   597 
   559 fun warn_extra_tfrees (ctxt1 as Context {defs = (_, _, used1), ...})
   598 fun warn_extra_tfrees (ctxt1 as Context {defs = (_, _, used1), ...})
   560     (ctxt2 as Context {defs = (_, _, used2), ...}) = (warn_extra used1 used2; ctxt2);
   599     (ctxt2 as Context {defs = (_, _, used2), ...}) = (warn_extra used1 used2; ctxt2);
       
   600 
       
   601 end;
       
   602 
       
   603 
       
   604 (* generalize type variables *)
       
   605 
       
   606 fun gen_tfrees inner opt_outer =
       
   607   let
       
   608     val inner_used = used_table inner;
       
   609     val inner_fixes = fixed_names inner;
       
   610     val (outer_used, outer_fixes) =
       
   611       (case opt_outer of
       
   612         None => (Symtab.empty, [])
       
   613       | Some ctxt => (used_table ctxt, fixed_names ctxt));
       
   614 
       
   615     val extra_fixes = inner_fixes \\ outer_fixes;
       
   616     fun still_fixed (Free (x, _)) = not (x mem_string extra_fixes)
       
   617       | still_fixed _ = false;
       
   618 
       
   619     fun add (gen, (a, xs)) =
       
   620       if is_some (Symtab.lookup (outer_used, a)) orelse exists still_fixed xs
       
   621       then gen else a :: gen;
       
   622   in Symtab.foldl add ([], inner_used) end;
       
   623 
       
   624 fun generalizeT inner outer =
       
   625   let
       
   626     val tfrees = gen_tfrees inner (Some outer);
       
   627     fun gen (x, S) = if x mem_string tfrees then TVar ((x, 0), S) else TFree (x, S);
       
   628   in Term.map_type_tfree gen end;
       
   629 
       
   630 val generalize = Term.map_term_types oo generalizeT;
       
   631 
       
   632 
       
   633 (* export theorems *)
       
   634 
       
   635 fun get_free x (None, t as Free (y, _)) = if x = y then Some t else None
       
   636   | get_free _ (opt, _) = opt;
       
   637 
       
   638 fun find_free t x = foldl_aterms (get_free x) (None, t);
       
   639 
       
   640 
       
   641 local
       
   642 
       
   643 fun export tfrees fixes casms thm =
       
   644   let
       
   645     val rule =
       
   646       thm
       
   647       |> Drule.forall_elim_vars 0
       
   648       |> Drule.implies_intr_list casms;
       
   649     val {sign, prop, ...} = Thm.rep_thm rule;
       
   650     val frees = map (Thm.cterm_of sign) (mapfilter (find_free prop) fixes);
       
   651   in
       
   652     rule
       
   653     |> Drule.forall_intr_list frees
       
   654     |> Drule.forall_elim_vars 0
       
   655     |> Drule.tvars_intr_list tfrees
       
   656   end;
       
   657 
       
   658 fun diff_context inner None = (gen_tfrees inner None, fixed_names inner, assumptions inner)
       
   659   | diff_context inner (Some outer) =
       
   660       (gen_tfrees inner (Some outer),
       
   661         fixed_names inner \\ fixed_names outer,
       
   662         Library.drop (length (assumptions outer), assumptions inner));
       
   663 
       
   664 in
       
   665 
       
   666 fun export_wrt inner opt_outer =
       
   667   let
       
   668     val (tfrees, fixes, asms) = diff_context inner opt_outer;
       
   669     val casms = map (Drule.mk_cgoal o #1) asms;
       
   670     val tacs = map #2 asms;
       
   671   in (export tfrees fixes casms, tacs) end;
       
   672 
       
   673 end;
   561 
   674 
   562 
   675 
   563 
   676 
   564 (** bindings **)
   677 (** bindings **)
   565 
   678 
   568 fun del_bind (ctxt, xi) =
   681 fun del_bind (ctxt, xi) =
   569   ctxt
   682   ctxt
   570   |> map_context (fn (thy, data, asms, binds, thms, cases, defs) =>
   683   |> map_context (fn (thy, data, asms, binds, thms, cases, defs) =>
   571       (thy, data, asms, Vartab.update ((xi, None), binds), thms, cases, defs));
   684       (thy, data, asms, Vartab.update ((xi, None), binds), thms, cases, defs));
   572 
   685 
   573 fun upd_bind (ctxt, (xi, t)) =
   686 fun upd_bind (ctxt, ((x, i), t)) =
   574   let val T = fastype_of t in
   687   let
       
   688     val T = Term.fastype_of t;
       
   689     val t' =
       
   690       if null (Term.term_tvars t \\ Term.typ_tvars T) then t
       
   691       else Var ((x ^ "_has_extra_type_vars_on_rhs_", i), T);
       
   692   in
   575     ctxt
   693     ctxt
   576     |> declare_term t
   694     |> declare_term t'
   577     |> map_context (fn (thy, data, asms, binds, thms, cases, defs) =>
   695     |> map_context (fn (thy, data, asms, binds, thms, cases, defs) =>
   578         (thy, data, asms, Vartab.update ((xi, Some (t, T)), binds), thms, cases, defs))
   696         (thy, data, asms, Vartab.update (((x, i), Some (t', T)), binds), thms, cases, defs))
   579   end;
   697   end;
   580 
   698 
   581 fun del_upd_bind (ctxt, (xi, None)) = del_bind (ctxt, xi)
   699 fun del_upd_bind (ctxt, (xi, None)) = del_bind (ctxt, xi)
   582   | del_upd_bind (ctxt, (xi, Some t)) = upd_bind (ctxt, (xi, t));
   700   | del_upd_bind (ctxt, (xi, Some t)) = upd_bind (ctxt, (xi, t));
   583 
   701 
   584 fun update_binds bs ctxt = foldl upd_bind (ctxt, bs);
   702 fun update_binds bs ctxt = foldl upd_bind (ctxt, bs);
   585 fun update_binds_env env =      (*Note: Envir.norm_term ensures proper type instantiation*)
       
   586   update_binds (map (apsnd (Envir.norm_term env)) (Envir.alist_of env));
       
   587 
       
   588 fun delete_update_binds bs ctxt = foldl del_upd_bind (ctxt, bs);
   703 fun delete_update_binds bs ctxt = foldl del_upd_bind (ctxt, bs);
   589 
   704 
   590 
   705 
   591 (* simult_matches *)
   706 (* simult_matches *)
   592 
   707 
   593 fun simult_matches [] ctxt = ctxt
   708 fun simult_matches ctxt [] = []
   594   | simult_matches pairs ctxt =
   709   | simult_matches ctxt pairs =
   595       let
   710       let
   596         val maxidx = foldl (fn (i, (t1, t2)) =>
   711         val maxidx = foldl (fn (i, (t1, t2)) =>
   597           Int.max (i, Int.max (Term.maxidx_of_term t1, Term.maxidx_of_term t2))) (~1, pairs);
   712           Int.max (i, Int.max (Term.maxidx_of_term t1, Term.maxidx_of_term t2))) (~1, pairs);
   598         val envs = Unify.smash_unifiers (sign_of ctxt, Envir.empty maxidx, pairs);
   713         val envs = Unify.smash_unifiers (sign_of ctxt, Envir.empty maxidx, pairs);
   599         val env =
   714         val env =
   600           (case Seq.pull envs of
   715           (case Seq.pull envs of
   601             None => raise CONTEXT ("Pattern match failed!", ctxt)      (* FIXME improve msg (!?) *)
   716             None => raise CONTEXT ("Pattern match failed!", ctxt)      (* FIXME improve msg (!?) *)
   602           | Some (env, _) => env);
   717           | Some (env, _) => env);
   603       in ctxt |> update_binds_env env end;
   718         val binds =
       
   719           (*Note: Envir.norm_term ensures proper type instantiation*)
       
   720           map (apsnd (Envir.norm_term env)) (Envir.alist_of env);
       
   721       in binds end;
   604 
   722 
   605 
   723 
   606 (* add_binds(_i) *)
   724 (* add_binds(_i) *)
   607 
   725 
   608 local
   726 local
   609 
   727 
   610 fun gen_bind prep (ctxt, (xi as (x, _), raw_t)) =
   728 fun gen_bind prep (ctxt, (xi as (x, _), raw_t)) =
   611   ctxt |> delete_update_binds [(xi, apsome (prep ctxt) raw_t)];
   729   ctxt |> delete_update_binds [(xi, apsome (prep ctxt) raw_t)];
   612 
   730 
   613 fun gen_binds prep binds ctxt =
   731 fun gen_binds prep binds ctxt = foldl (gen_bind prep) (ctxt, binds);
   614   warn_extra_tfrees ctxt (foldl (gen_bind prep) (ctxt, binds));
       
   615 
   732 
   616 in
   733 in
   617 
   734 
   618 val add_binds = gen_binds read_term;
   735 val add_binds = gen_binds read_term;
   619 val add_binds_i = gen_binds cert_term;
   736 val add_binds_i = gen_binds cert_term;
       
   737 
   620 val auto_bind_goal = add_binds_i o AutoBind.goal;
   738 val auto_bind_goal = add_binds_i o AutoBind.goal;
   621 val auto_bind_facts = add_binds_i oo AutoBind.facts;
   739 val auto_bind_facts = add_binds_i oo AutoBind.facts;
   622 
   740 
   623 end;
   741 end;
   624 
   742 
   625 
   743 
   626 (* match_bind(_i) *)
   744 (* match_bind(_i) *)
   627 
   745 
   628 local
   746 local
   629 
   747 
   630 fun gen_bind (prep, prep_pats) (ctxt, (raw_pats, raw_t)) =
   748 fun prep_bind (prep, prep_pats) (ctxt, (raw_pats, raw_t)) =
   631   let
   749   let
   632     val t = prep ctxt raw_t;
   750     val t = prep ctxt raw_t;
   633     val ctxt' = declare_term t ctxt;
   751     val ctxt' = declare_term t ctxt;
   634     val pats = prep_pats (fastype_of t) ctxt' raw_pats;
   752     val pats = prep_pats (fastype_of t) ctxt' raw_pats;
   635     val ctxt'' = ctxt' |> simult_matches (map (rpair t) pats);
   753     val binds = simult_matches ctxt' (map (rpair t) pats);
   636   in ctxt'' end;
   754   in (ctxt', binds) end;
   637 
   755 
   638 fun gen_binds prepp binds ctxt =
   756 fun gen_binds prepp gen raw_binds ctxt =
   639   warn_extra_tfrees ctxt (foldl (gen_bind prepp) (ctxt, binds));
   757   let
       
   758     val (ctxt', binds) = apsnd flat (foldl_map (prep_bind prepp) (ctxt, raw_binds));
       
   759     val binds' =
       
   760       if gen then map (apsnd (generalize ctxt' ctxt)) binds
       
   761       else binds;
       
   762     val binds'' = map (apsnd Some) binds';
       
   763   in
       
   764     warn_extra_tfrees ctxt
       
   765      (if gen then ctxt (*sic!*) |> declare_terms (map #2 binds') |> add_binds_i binds''
       
   766       else ctxt' |> add_binds_i binds'')
       
   767   end;
   640 
   768 
   641 in
   769 in
   642 
   770 
   643 val match_bind = gen_binds (read_term, read_term_pats);
   771 val match_bind = gen_binds (read_term, read_term_pats);
   644 val match_bind_i = gen_binds (cert_term, cert_term_pats);
   772 val match_bind_i = gen_binds (cert_term, cert_term_pats);
   662 
   790 
   663 
   791 
   664 fun gen_bind_propp prepp (ctxt, propp) =
   792 fun gen_bind_propp prepp (ctxt, propp) =
   665   let
   793   let
   666     val (ctxt', (prop, (pats1, pats2))) = prepp (ctxt, propp);
   794     val (ctxt', (prop, (pats1, pats2))) = prepp (ctxt, propp);
   667     val pairs = map (rpair prop) pats1 @ map (rpair (Logic.strip_imp_concl prop)) pats2;
   795     val pairs =
   668   in (ctxt' |> simult_matches pairs, prop) end;
   796       map (rpair prop) pats1 @
       
   797       map (rpair (Logic.strip_imp_concl prop)) pats2;   (* FIXME handle params!? *)
       
   798     val binds = simult_matches ctxt' pairs;
       
   799 
       
   800     (*note: context evaluated now, binds added later (lazy)*)
       
   801     val gen = generalize ctxt' ctxt;
       
   802     fun gen_binds ct = ct |> add_binds_i (map (apsnd (Some o gen)) binds);
       
   803   in (ctxt' |> add_binds_i (map (apsnd Some) binds), (prop, gen_binds)) end;
   669 
   804 
   670 val bind_propp = gen_bind_propp read_propp;
   805 val bind_propp = gen_bind_propp read_propp;
   671 val bind_propp_i = gen_bind_propp cert_propp;
   806 val bind_propp_i = gen_bind_propp cert_propp;
   672 
   807 
   673 
   808 
   722 
   857 
   723 
   858 
   724 
   859 
   725 (** assumptions **)
   860 (** assumptions **)
   726 
   861 
   727 (* get assumptions *)
       
   728 
       
   729 fun assumptions (Context {asms = ((asms, _), _), ...}) = asms;
       
   730 fun fixed_names (Context {asms = (_, (fixes, _)), ...}) = map #2 fixes;
       
   731 
       
   732 
       
   733 (* assume *)
   862 (* assume *)
   734 
       
   735 fun most_general_varify_tfrees thm =
       
   736   let
       
   737     val {hyps, prop, ...} = Thm.rep_thm thm;
       
   738     val frees = foldr Term.add_term_frees (prop :: hyps, []);
       
   739     val leave_tfrees = foldr Term.add_term_tfree_names (frees, []);
       
   740   in thm |> Thm.varifyT' leave_tfrees end;
       
   741 
       
   742 
   863 
   743 local
   864 local
   744 
   865 
   745 fun gen_assm prepp tac (ctxt, (name, attrs, raw_prop_pats)) =
   866 fun gen_assm prepp tac (ctxt, (name, attrs, raw_prop_pats)) =
   746   let
   867   let
   747     val (ctxt', props) = foldl_map prepp (ctxt, raw_prop_pats);
   868     val (ctxt', props) = foldl_map prepp (ctxt, raw_prop_pats);
   748 
   869 
   749     val cprops = map (Thm.cterm_of (sign_of ctxt')) props;
   870     val cprops = map (Thm.cterm_of (sign_of ctxt')) props;
   750     val cprops_tac = map (rpair tac) cprops;
   871     val cprops_tac = map (rpair tac) cprops;
   751     val asms =
   872     val asms = map (Drule.forall_elim_vars 0 o Drule.assume_goal) cprops;
   752       map (most_general_varify_tfrees o Drule.forall_elim_vars 0 o Drule.assume_goal) cprops;
       
   753 
   873 
   754     val ths = map (fn th => ([th], [])) asms;
   874     val ths = map (fn th => ([th], [])) asms;
   755     val (ctxt'', (_, thms)) =
   875     val (ctxt'', (_, thms)) =
   756       ctxt'
   876       ctxt'
   757       |> auto_bind_facts name props
   877       |> auto_bind_facts name props
   768   let val (ctxt', thmss) = foldl_map (gen_assm prepp tac) (ctxt, args)
   888   let val (ctxt', thmss) = foldl_map (gen_assm prepp tac) (ctxt, args)
   769   in (warn_extra_tfrees ctxt ctxt', (thmss, prems_of ctxt')) end;
   889   in (warn_extra_tfrees ctxt ctxt', (thmss, prems_of ctxt')) end;
   770 
   890 
   771 in
   891 in
   772 
   892 
   773 val assume = gen_assms bind_propp;
   893 val assume = gen_assms (apsnd #1 o bind_propp);
   774 val assume_i = gen_assms bind_propp_i;
   894 val assume_i = gen_assms (apsnd #1 o bind_propp_i);
   775 
   895 
   776 end;
   896 end;
   777 
   897 
   778 
   898 
   779 (* variables *)
   899 (* variables *)