2016-05-09 03:27:15 +00:00
|
|
|
(*
|
|
|
|
* Copyright 2016, NICTA
|
|
|
|
*
|
|
|
|
* This software may be distributed and modified according to the terms of
|
|
|
|
* the BSD 2-Clause license. Note that NO WARRANTY is provided.
|
|
|
|
* See "LICENSE_BSD2.txt" for details.
|
|
|
|
*
|
|
|
|
* @TAG(NICTA_BSD)
|
|
|
|
*)
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
(*
|
2016-05-05 04:05:33 +00:00
|
|
|
* Extend a locale by seamlessly generating sublocales.
|
|
|
|
*)
|
|
|
|
|
|
|
|
theory Extend_Locale
|
|
|
|
imports Main Defs
|
|
|
|
keywords "extend_locale" :: thy_decl
|
|
|
|
begin
|
|
|
|
|
2016-06-01 07:08:23 +00:00
|
|
|
ML \<open>
|
|
|
|
fun note_new_facts prev_lthy (lthy : local_theory) =
|
|
|
|
let
|
|
|
|
val facts = Proof_Context.facts_of lthy;
|
|
|
|
|
|
|
|
val local_facts = Facts.dest_static false [Proof_Context.facts_of prev_lthy] facts;
|
|
|
|
|
|
|
|
val space = Facts.space_of (Proof_Context.facts_of lthy);
|
|
|
|
|
2016-06-02 01:56:25 +00:00
|
|
|
fun make_binding (long_name, pos) =
|
|
|
|
let val (qualifier, name) = split_last (Long_Name.explode long_name)
|
|
|
|
in fold (Binding.qualify true) qualifier (Binding.make (name, pos)) end;
|
|
|
|
|
2016-06-01 07:08:23 +00:00
|
|
|
fun add_entry (nm, thms) lthy =
|
|
|
|
let
|
2016-06-02 01:56:25 +00:00
|
|
|
val extern_nm = Name_Space.extern_shortest lthy space nm;
|
2016-06-01 07:08:23 +00:00
|
|
|
val {pos, ...} = Name_Space.the_entry space nm;
|
2016-06-02 01:56:25 +00:00
|
|
|
val b = make_binding (extern_nm, pos);
|
2016-06-01 07:08:23 +00:00
|
|
|
val (_, lthy') = Local_Theory.note ((b,[]),thms) lthy;
|
|
|
|
in lthy' end
|
2017-07-12 05:13:51 +00:00
|
|
|
|
2016-06-01 07:08:23 +00:00
|
|
|
in fold add_entry local_facts lthy end;
|
|
|
|
\<close>
|
|
|
|
|
2016-05-05 04:05:33 +00:00
|
|
|
ML \<open>
|
|
|
|
|
|
|
|
val _ =
|
|
|
|
Outer_Syntax.command @{command_keyword extend_locale} "extend current locale"
|
2017-07-12 05:13:51 +00:00
|
|
|
(Parse.opt_target -- (Scan.repeat1 Parse_Spec.context_element) >> (fn (target, (elems)) =>
|
2016-05-05 04:05:33 +00:00
|
|
|
(Toplevel.local_theory NONE target (fn lthy =>
|
|
|
|
let
|
|
|
|
val locale_name = case Named_Target.locale_of lthy of SOME x => x | NONE => error "Not in a locale!"
|
|
|
|
val binding = Binding.make (Long_Name.base_name locale_name, Position.none)
|
|
|
|
|
|
|
|
val chunkN = "extchunk_"
|
2017-07-12 05:13:51 +00:00
|
|
|
|
|
|
|
val last_chunk =
|
|
|
|
case Long_Name.explode locale_name of
|
2016-05-05 04:05:33 +00:00
|
|
|
[_, chunk, _] => (unprefix chunkN chunk |> Int.fromString |> the)
|
|
|
|
| [_, _] => 0
|
|
|
|
| _ => raise Fail ("Unexpected locale naming scheme:" ^ locale_name)
|
|
|
|
|
|
|
|
val chunk = Int.toString (last_chunk + 1)
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
|
2016-05-05 04:05:33 +00:00
|
|
|
val (next_locale_name, lthy') = lthy
|
2017-07-12 05:13:51 +00:00
|
|
|
|> Local_Theory.map_background_naming
|
2016-05-05 04:05:33 +00:00
|
|
|
(Name_Space.parent_path #> Name_Space.add_path (chunkN ^ chunk))
|
2017-07-12 05:13:51 +00:00
|
|
|
|> Local_Theory.background_theory_result
|
|
|
|
(Expression.add_locale_cmd binding binding
|
2016-05-05 04:05:33 +00:00
|
|
|
([((locale_name,Position.none), (("#",false), Expression.Positional []))], []) elems
|
|
|
|
##> Local_Theory.exit_global)
|
|
|
|
||> Local_Theory.restore_background_naming lthy
|
|
|
|
|
|
|
|
|
|
|
|
val lthy'' = lthy'
|
|
|
|
|> Local_Theory.exit_global
|
2017-08-25 06:32:37 +00:00
|
|
|
|> Named_Target.init next_locale_name
|
2016-05-05 04:05:33 +00:00
|
|
|
|
|
|
|
in lthy'' end)
|
|
|
|
)));
|
|
|
|
|
|
|
|
\<close>
|
|
|
|
|
|
|
|
locale Internal begin
|
|
|
|
definition "internal_const1 = True"
|
|
|
|
definition "internal_const2 = False"
|
|
|
|
end
|
|
|
|
|
|
|
|
locale Generic
|
|
|
|
begin
|
|
|
|
|
|
|
|
definition "generic_const = ((\<forall>x :: nat. x \<noteq> x))"
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
extend_locale
|
2016-05-05 04:05:33 +00:00
|
|
|
assumes asm_1: "Internal.internal_const1 = (\<forall>x :: nat. x = x)"
|
|
|
|
|
|
|
|
lemma generic_lemma_1: "Internal.internal_const1"
|
|
|
|
apply (insert asm_1)
|
|
|
|
apply simp
|
|
|
|
done
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
extend_locale
|
2016-05-05 04:05:33 +00:00
|
|
|
assumes asm_2: "\<not> Internal.internal_const2"
|
|
|
|
|
|
|
|
lemma generic_lemma_2: "generic_const = Internal.internal_const2"
|
|
|
|
by (simp add: asm_2 generic_const_def)
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
extend_locale
|
2016-05-05 04:05:33 +00:00
|
|
|
fixes param_const_1 :: nat
|
|
|
|
assumes asm_3: "param_const_1 > 0"
|
|
|
|
|
|
|
|
lemma generic_lemma_3: "param_const_1 \<noteq> 0"
|
|
|
|
by (simp add: asm_3)
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
extend_locale
|
2016-05-05 04:05:33 +00:00
|
|
|
assumes asm_4: "\<not> generic_const"
|
|
|
|
|
|
|
|
lemma generic_lemma_4: "generic_const = Internal.internal_const2"
|
|
|
|
by (simp add: asm_4 asm_2 generic_lemma_2)
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
extend_locale
|
2016-05-05 04:05:33 +00:00
|
|
|
assumes asm_4: "x = param_const_1 \<Longrightarrow> y > x \<Longrightarrow> y > 1"
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
context Internal begin
|
|
|
|
|
|
|
|
lemma internal_lemma1: "internal_const1 = (\<forall>x :: nat. x = x)" by (simp add: internal_const1_def)
|
|
|
|
|
|
|
|
lemma internal_lemma2: "\<not> internal_const2" by (simp add: internal_const2_def)
|
|
|
|
|
|
|
|
lemma internal_lemma3: "\<not> Generic.generic_const" by (simp add: Generic.generic_const_def)
|
|
|
|
|
|
|
|
definition "internal_const3 = (1 :: nat)"
|
|
|
|
|
|
|
|
lemma internal_lemma4: "internal_const3 > 0" by (simp add: internal_const3_def)
|
|
|
|
|
|
|
|
lemma asm_4: "x = internal_const3 \<Longrightarrow> y > x \<Longrightarrow> y > 1"
|
|
|
|
by (simp add: internal_const3_def)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-07-12 05:13:51 +00:00
|
|
|
interpretation Generic
|
2016-05-05 04:05:33 +00:00
|
|
|
where param_const_1 = Internal.internal_const3
|
|
|
|
subgoal
|
2017-07-12 05:13:51 +00:00
|
|
|
proof -
|
2016-05-05 04:05:33 +00:00
|
|
|
interpret Internal .
|
|
|
|
show ?thesis by (intro_locales; (unfold_locales, fact)?)
|
|
|
|
qed
|
|
|
|
done
|
|
|
|
|
|
|
|
context Internal begin
|
|
|
|
|
|
|
|
lemma internal_lemma5:
|
|
|
|
"internal_const3 \<noteq> 0"
|
|
|
|
by (rule generic_lemma_3)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end
|