improved treatment of Element.Obtains via Expression.prepare_stmt;
discontinued pointless all_types ctxt: prep_var is always sequential;
--- a/NEWS Sun Jun 14 20:10:21 2015 +0200
+++ b/NEWS Sun Jun 14 23:22:08 2015 +0200
@@ -12,6 +12,9 @@
* Command 'obtain' binds term abbreviations (via 'is' patterns) in the
proof body as well, abstracted over relevant parameters.
+* Improved type-inference for theorem statement 'obtains': separate
+parameter scope for of each clause.
+
* Term abbreviations via 'is' patterns also work for schematic
statements: result is abstracted over unknowns.
--- a/src/Pure/Isar/expression.ML Sun Jun 14 20:10:21 2015 +0200
+++ b/src/Pure/Isar/expression.ML Sun Jun 14 23:22:08 2015 +0200
@@ -13,10 +13,10 @@
type expression = (xstring * Position.T, string) expr * (binding * string option * mixfix) list
(* Processing of context statements *)
- val cert_statement: Element.context_i list -> (term * term list) list list ->
- Proof.context -> (term * term list) list list * Proof.context
- val read_statement: Element.context list -> (string * string list) list list ->
- Proof.context -> (term * term list) list list * Proof.context
+ val cert_statement: Element.context_i list -> Element.statement_i ->
+ Proof.context -> (Attrib.binding * (term * term list) list) list * Proof.context
+ val read_statement: Element.context list -> Element.statement ->
+ Proof.context -> (Attrib.binding * (term * term list) list) list * Proof.context
(* Declaring locales *)
val cert_declaration: expression_i -> (Proof.context -> Proof.context) ->
@@ -217,13 +217,20 @@
fact = I,
attrib = I};
-fun parse_concl prep_term ctxt concl =
- (map o map) (fn (t, ps) =>
- (prep_term (Proof_Context.set_mode Proof_Context.mode_schematic ctxt) t,
- map (prep_term (Proof_Context.set_mode Proof_Context.mode_pattern ctxt)) ps)) concl;
+fun prepare_stmt prep_prop prep_obtains ctxt stmt =
+ (case stmt of
+ Element.Shows raw_shows =>
+ raw_shows |> (map o apsnd o map) (fn (t, ps) =>
+ (prep_prop (Proof_Context.set_mode Proof_Context.mode_schematic ctxt) t,
+ map (prep_prop (Proof_Context.set_mode Proof_Context.mode_pattern ctxt)) ps))
+ | Element.Obtains raw_obtains =>
+ let
+ val ((_, thesis), thesis_ctxt) = Obtain.obtain_thesis ctxt;
+ val obtains = prep_obtains thesis_ctxt thesis raw_obtains;
+ in map (fn (b, t) => ((b, []), [(t, [])])) obtains end);
-(** Simultaneous type inference: instantiations + elements + conclusion **)
+(** Simultaneous type inference: instantiations + elements + statement **)
local
@@ -275,7 +282,7 @@
let
val inst_cs = map extract_inst insts;
val elem_css = map extract_elem elems;
- val concl_cs = (map o map) mk_propp concl;
+ val concl_cs = (map o map) mk_propp (map snd concl);
(* Type inference *)
val (inst_cs' :: css', ctxt') =
(fold_burrow o fold_burrow) check (inst_cs :: elem_css @ [concl_cs]) ctxt;
@@ -283,7 +290,7 @@
in
((map restore_inst (insts ~~ inst_cs'),
map restore_elem (elems ~~ elem_css'),
- concl_cs'), ctxt')
+ map fst concl ~~ concl_cs'), ctxt')
end;
end;
@@ -351,15 +358,15 @@
end;
-(** Process full context statement: instantiations + elements + conclusion **)
+(** Process full context statement: instantiations + elements + statement **)
(* Interleave incremental parsing and type inference over entire parsed stretch. *)
local
fun prep_full_context_statement
- parse_typ parse_prop prep_var_elem prep_inst prep_var_inst prep_expr
- {strict, do_close, fixed_frees} raw_import init_body raw_elems raw_concl ctxt1 =
+ parse_typ parse_prop prep_obtains prep_var_elem prep_inst prep_var_inst prep_expr
+ {strict, do_close, fixed_frees} raw_import init_body raw_elems raw_stmt ctxt1 =
let
val thy = Proof_Context.theory_of ctxt1;
@@ -393,8 +400,8 @@
val ctxt2 = ctxt1 |> Proof_Context.add_fixes fors |> snd;
val (_, insts', ctxt3) = fold prep_insts_cumulative raw_insts (0, [], ctxt2);
- fun prep_concl elems ctxt =
- check_autofix insts' elems (parse_concl parse_prop ctxt raw_concl) ctxt;
+ fun prep_stmt elems ctxt =
+ check_autofix insts' elems (prepare_stmt parse_prop prep_obtains ctxt raw_stmt) ctxt;
val _ =
if fixed_frees then ()
@@ -407,7 +414,7 @@
val ((insts, elems', concl), ctxt4) = ctxt3
|> init_body
|> fold_map prep_elem raw_elems
- |-> prep_concl;
+ |-> prep_stmt;
(* parameters from expression and elements *)
@@ -426,29 +433,29 @@
in
fun cert_full_context_statement x =
- prep_full_context_statement (K I) (K I) Proof_Context.cert_var
- make_inst Proof_Context.cert_var (K I) x;
+ prep_full_context_statement (K I) (K I) Obtain.cert_obtains
+ Proof_Context.cert_var make_inst Proof_Context.cert_var (K I) x;
fun cert_read_full_context_statement x =
- prep_full_context_statement Syntax.parse_typ Syntax.parse_prop Proof_Context.read_var
- make_inst Proof_Context.cert_var (K I) x;
+ prep_full_context_statement Syntax.parse_typ Syntax.parse_prop Obtain.parse_obtains
+ Proof_Context.read_var make_inst Proof_Context.cert_var (K I) x;
fun read_full_context_statement x =
- prep_full_context_statement Syntax.parse_typ Syntax.parse_prop Proof_Context.read_var
- parse_inst Proof_Context.read_var check_expr x;
+ prep_full_context_statement Syntax.parse_typ Syntax.parse_prop Obtain.parse_obtains
+ Proof_Context.read_var parse_inst Proof_Context.read_var check_expr x;
end;
-(* Context statement: elements + conclusion *)
+(* Context statement: elements + statement *)
local
-fun prep_statement prep activate raw_elems raw_concl context =
+fun prep_statement prep activate raw_elems raw_stmt context =
let
val ((_, _, elems, concl), _) =
prep {strict = true, do_close = false, fixed_frees = true}
- ([], []) I raw_elems raw_concl context;
+ ([], []) I raw_elems raw_stmt context;
val (_, context') = context
|> Proof_Context.set_stmt true
|> fold_map activate elems;
@@ -473,7 +480,7 @@
let
val ((fixed, deps, elems, _), (parms, ctxt')) =
prep {strict = false, do_close = true, fixed_frees = false}
- raw_import init_body raw_elems [] context;
+ raw_import init_body raw_elems (Element.Shows []) context;
(* Declare parameters and imported facts *)
val context' = context |>
fix_params fixed |>
@@ -509,7 +516,8 @@
val thy = Proof_Context.theory_of context;
val ((fixed, deps, _, _), _) =
- prep {strict = true, do_close = true, fixed_frees = true} expression I [] [] context;
+ prep {strict = true, do_close = true, fixed_frees = true} expression I []
+ (Element.Shows []) context;
(* proof obligations *)
val propss = map (props_of thy) deps;
--- a/src/Pure/Isar/obtain.ML Sun Jun 14 20:10:21 2015 +0200
+++ b/src/Pure/Isar/obtain.ML Sun Jun 14 23:22:08 2015 +0200
@@ -6,11 +6,11 @@
signature OBTAIN =
sig
+ val obtain_thesis: Proof.context -> ((string * typ) * term) * Proof.context
val obtains_attributes: ('typ, 'term) Element.obtain list -> attribute list
- val parse_clause: Proof.context -> term ->
- (binding * typ option * mixfix) list -> string list -> term
val read_obtains: Proof.context -> term -> Element.obtains -> (binding * term) list
val cert_obtains: Proof.context -> term -> Element.obtains_i -> (binding * term) list
+ val parse_obtains: Proof.context -> term -> Element.obtains -> (binding * term) list
val consider: Element.obtains_i -> bool -> Proof.state -> Proof.state
val consider_cmd: Element.obtains -> bool -> Proof.state -> Proof.state
val obtain: binding -> (binding * typ option * mixfix) list ->
@@ -92,38 +92,38 @@
local
-fun prepare_clause parse_prop ctxt thesis vars raw_props =
+val mk_all_external = Logic.all_constraint o Variable.default_type;
+fun mk_all_internal _ (y, z) t =
+ let val T = the (AList.lookup (op =) (Term.add_frees t []) z);
+ in Logic.all_const T $ Term.lambda_name (y, Free (z, T)) t end;
+
+fun prepare_clause prep_var parse_prop mk_all ctxt thesis raw_vars raw_props =
let
- val (xs', ctxt') = ctxt |> Proof_Context.add_fixes vars;
+ val ((xs', vars), ctxt') = ctxt
+ |> fold_map prep_var raw_vars
+ |-> (fn vars => Proof_Context.add_fixes vars ##>> pair vars);
val xs = map (Variable.check_name o #1) vars;
in
Logic.list_implies (map (parse_prop ctxt') raw_props, thesis)
- |> fold_rev (Logic.all_constraint (Variable.default_type ctxt')) (xs ~~ xs')
+ |> fold_rev (mk_all ctxt') (xs ~~ xs')
end;
-fun prepare_obtains prep_var parse_prop ctxt thesis raw_obtains =
+fun prepare_obtains prep_clause check_terms
+ ctxt thesis (raw_obtains: ('typ, 'term) Element.obtain list) =
let
- val all_types =
- fold_map prep_var (maps (fn (_, (vs, _)) => vs) raw_obtains)
- (ctxt |> Context_Position.set_visible false)
- |> #1 |> map_filter (fn (_, opt_T, _) => opt_T);
- val types_ctxt = fold Variable.declare_typ all_types ctxt;
+ val clauses = raw_obtains
+ |> map (fn (_, (raw_vars, raw_props)) => prep_clause ctxt thesis raw_vars raw_props)
+ |> check_terms ctxt;
+ in map fst raw_obtains ~~ clauses end;
- val clauses =
- raw_obtains |> map (fn (_, (raw_vars, raw_props)) =>
- let
- val (vars, vars_ctxt) = fold_map prep_var raw_vars types_ctxt;
- val clause = prepare_clause parse_prop vars_ctxt thesis vars raw_props;
- in clause end)
- |> Syntax.check_terms ctxt;
- in map fst raw_obtains ~~ clauses end;
+val parse_clause = prepare_clause Proof_Context.read_var Syntax.parse_prop mk_all_external;
+val cert_clause = prepare_clause Proof_Context.cert_var (K I) mk_all_internal;
in
-val parse_clause = prepare_clause Syntax.parse_prop;
-
-val read_obtains = prepare_obtains Proof_Context.read_var Syntax.parse_prop;
-val cert_obtains = prepare_obtains Proof_Context.cert_var (K I);
+val read_obtains = prepare_obtains parse_clause Syntax.check_terms;
+val cert_obtains = prepare_obtains cert_clause (K I);
+val parse_obtains = prepare_obtains parse_clause (K I);
end;
--- a/src/Pure/Isar/specification.ML Sun Jun 14 20:10:21 2015 +0200
+++ b/src/Pure/Isar/specification.ML Sun Jun 14 23:22:08 2015 +0200
@@ -318,56 +318,30 @@
local
-fun prep_statement prep_att prep_stmt elems concl ctxt =
- (case concl of
- Element.Shows shows =>
- let
- val (propp, elems_ctxt) = prep_stmt elems (map snd shows) ctxt;
- val prems = Assumption.local_prems_of elems_ctxt ctxt;
- val stmt = Attrib.map_specs (map prep_att) (map fst shows ~~ propp);
- val goal_ctxt = (fold o fold) (Variable.auto_fixes o fst) propp elems_ctxt;
- in (([], prems, stmt, NONE), goal_ctxt) end
- | Element.Obtains obtains =>
- let
- val constraints = obtains |> map (fn (_, (vars, _)) =>
- Element.Constrains
- (vars |> map_filter (fn (x, SOME T, _) => SOME (Variable.check_name x, T) | _ => NONE)));
-
- val raw_propp = obtains |> map (fn (_, (_, props)) => map (rpair []) props);
- val (propp, elems_ctxt) = prep_stmt (elems @ constraints) raw_propp ctxt;
-
- val thesis = Object_Logic.fixed_judgment ctxt Auto_Bind.thesisN;
+fun prep_statement prep_att prep_stmt raw_elems raw_stmt ctxt =
+ let
+ val (stmt, elems_ctxt) = prep_stmt raw_elems raw_stmt ctxt;
+ val prems = Assumption.local_prems_of elems_ctxt ctxt;
+ val stmt_ctxt = fold (fold (Variable.auto_fixes o fst) o snd) stmt elems_ctxt;
+ in
+ (case raw_stmt of
+ Element.Shows _ =>
+ let val stmt' = Attrib.map_specs (map prep_att) stmt
+ in (([], prems, stmt', NONE), stmt_ctxt) end
+ | Element.Obtains raw_obtains =>
+ let
+ val asms_ctxt = stmt_ctxt
+ |> fold (fn ((name, _), asm) =>
+ snd o Proof_Context.add_assms Assumption.assume_export
+ [((name, [Context_Rules.intro_query NONE]), asm)]) stmt;
+ val that = Assumption.local_prems_of asms_ctxt stmt_ctxt;
+ val ([(_, that')], that_ctxt) = asms_ctxt
+ |> Proof_Context.note_thmss "" [((Binding.name Auto_Bind.thatN, []), [(that, [])])];
- fun assume_case ((name, (vars, _)), asms) ctxt' =
- let
- val bs = map (fn (b, _, _) => b) vars;
- val xs = map Variable.check_name bs;
- val props = map fst asms;
- val (params, _) = ctxt'
- |> fold Variable.declare_term props
- |> fold_map Proof_Context.inferred_param xs
- |>> map Free;
- val asm = fold_rev Logic.all params (Logic.list_implies (props, thesis));
- val _ = ctxt' |> Proof_Context.add_fixes (map (fn b => (b, NONE, NoSyn)) bs);
- in
- ctxt'
- |> Variable.auto_fixes asm
- |> Proof_Context.add_assms Assumption.assume_export
- [((name, [Context_Rules.intro_query NONE]), [(asm, [])])]
- |>> (fn [(_, [th])] => th)
- end;
-
- val more_atts = map (Attrib.internal o K) (Obtain.obtains_attributes obtains);
- val prems = Assumption.local_prems_of elems_ctxt ctxt;
- val stmt = [((Binding.empty, []), [(thesis, [])])];
-
- val (facts, goal_ctxt) = elems_ctxt
- |> (snd o Proof_Context.add_fixes [(Binding.name Auto_Bind.thesisN, NONE, NoSyn)])
- |> fold_map assume_case (obtains ~~ propp)
- |-> (fn ths =>
- Proof_Context.note_thmss "" [((Binding.name Auto_Bind.thatN, []), [(ths, [])])] #>
- #2 #> pair ths);
- in ((more_atts, prems, stmt, SOME facts), goal_ctxt) end);
+ val more_atts = map (Attrib.internal o K) (Obtain.obtains_attributes raw_obtains);
+ val stmt' = [((Binding.empty, []), [(#2 (#1 (Obtain.obtain_thesis ctxt)), [])])];
+ in ((more_atts, prems, stmt', SOME that'), that_ctxt) end)
+ end;
fun gen_theorem schematic bundle_includes prep_att prep_stmt
kind before_qed after_qed (name, raw_atts) raw_includes raw_elems raw_concl int lthy =