author | haftmann |
Fri, 12 Oct 2007 14:42:30 +0200 | |
changeset 25002 | c3d9cb390471 |
parent 24934 | 9f5d60fe9086 |
child 25011 | 633afd909ff2 |
permissions | -rw-r--r-- |
24914 | 1 |
(* Title: Pure/Isar/subclass.ML |
2 |
ID: $Id$ |
|
3 |
Author: Florian Haftmann, TU Muenchen |
|
4 |
||
25002 | 5 |
Prove subclass relationship between type classes. |
24914 | 6 |
*) |
7 |
||
8 |
signature SUBCLASS = |
|
9 |
sig |
|
10 |
val subclass: class -> local_theory -> Proof.state |
|
11 |
val subclass_cmd: xstring -> local_theory -> Proof.state |
|
25002 | 12 |
val prove_subclass: tactic -> class -> local_theory -> local_theory |
24914 | 13 |
end; |
14 |
||
15 |
structure Subclass : SUBCLASS = |
|
16 |
struct |
|
17 |
||
18 |
(** auxiliary **) |
|
19 |
||
20 |
fun prove_interpretation_in tac after_qed (name, expr) = |
|
21 |
Locale.interpretation_in_locale |
|
22 |
(ProofContext.theory after_qed) (name, expr) |
|
23 |
#> Proof.global_terminal_proof |
|
24 |
(Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE) |
|
25 |
#> ProofContext.theory_of; |
|
26 |
||
27 |
fun OF_LAST thm1 thm2 = |
|
28 |
let |
|
29 |
val n = (length o Logic.strip_imp_prems o prop_of) thm2; |
|
30 |
in (thm1 RSN (n, thm2)) end; |
|
31 |
||
32 |
fun strip_all_ofclass thy sort = |
|
33 |
let |
|
34 |
val typ = TVar ((Name.aT, 0), sort); |
|
35 |
fun prem_inclass t = |
|
36 |
case Logic.strip_imp_prems t |
|
37 |
of ofcls :: _ => try Logic.dest_inclass ofcls |
|
38 |
| [] => NONE; |
|
39 |
fun strip_ofclass class thm = |
|
40 |
thm OF (fst o AxClass.of_sort thy (typ, [class])) AxClass.cache; |
|
41 |
fun strip thm = case (prem_inclass o Thm.prop_of) thm |
|
42 |
of SOME (_, class) => thm |> strip_ofclass class |> strip |
|
43 |
| NONE => thm; |
|
44 |
in strip end; |
|
45 |
||
46 |
||
47 |
(** subclassing **) |
|
48 |
||
49 |
local |
|
50 |
||
25002 | 51 |
fun gen_subclass prep_class do_proof raw_sup lthy = |
24914 | 52 |
let |
53 |
val ctxt = LocalTheory.target_of lthy; |
|
54 |
val thy = ProofContext.theory_of ctxt; |
|
55 |
val ctxt_thy = ProofContext.init thy; |
|
56 |
val sup = prep_class thy raw_sup; |
|
25002 | 57 |
val sub = case Option.mapPartial (Class.class_of_locale thy) (TheoryTarget.peek lthy) |
24914 | 58 |
of NONE => error "not in class context" |
59 |
| SOME sub => sub; |
|
25002 | 60 |
val sub_params = map fst (Class.these_params thy [sub]); |
61 |
val sup_params = map fst (Class.these_params thy [sup]); |
|
62 |
val err_params = subtract (op =) sub_params sup_params; |
|
63 |
val _ = if null err_params then [] else |
|
64 |
error ("Class " ^ Sign.string_of_sort thy [sub] ^ " lacks parameter(s) " ^ |
|
65 |
commas_quote err_params ^ " of " ^ Sign.string_of_sort thy [sup]); |
|
66 |
val sublocale_prop = |
|
67 |
Locale.global_asms_of thy (Class.locale_of_class thy sup) |
|
68 |
|> maps snd |
|
69 |
|> map (ObjectLogic.ensure_propT thy); |
|
70 |
val supclasses = Sign.complete_sort thy [sup] |
|
71 |
|> filter_out (fn class => Sign.subsort thy ([sub], [class])); |
|
72 |
val supclasses' = remove (op =) sup supclasses; |
|
73 |
val _ = if null supclasses' then () else |
|
74 |
error ("The following superclasses of " ^ sup |
|
75 |
^ " are no superclass of " ^ sub ^ ": " |
|
76 |
^ commas supclasses'); |
|
77 |
(*FIXME*) |
|
78 |
val sub_ax = #axioms (AxClass.get_info thy sub); |
|
79 |
val sub_inst = Thm.ctyp_of thy (TVar ((Name.aT, 0), [sub])); |
|
24914 | 80 |
val loc_name = Class.locale_of_class thy sub; |
81 |
val loc_expr = Locale.Locale (Class.locale_of_class thy sup); |
|
25002 | 82 |
fun prove_classrel subclass_rule = |
24914 | 83 |
let |
25002 | 84 |
fun add_classrel sup' thy = |
24914 | 85 |
let |
25002 | 86 |
val classrel = |
87 |
#intro (AxClass.get_info thy sup') |
|
88 |
|> Drule.instantiate' [SOME sub_inst] [] |
|
89 |
|> OF_LAST (subclass_rule OF sub_ax) |
|
90 |
|> strip_all_ofclass thy (Sign.super_classes thy sup'); |
|
24914 | 91 |
in |
25002 | 92 |
AxClass.add_classrel classrel thy |
24914 | 93 |
end; |
94 |
in |
|
25002 | 95 |
fold_rev add_classrel supclasses |
24914 | 96 |
end; |
25002 | 97 |
fun prove_interpretation sublocale_rule = |
98 |
prove_interpretation_in (ProofContext.fact_tac [sublocale_rule] 1) |
|
99 |
I (loc_name, loc_expr) |
|
100 |
fun after_qed thms = |
|
24914 | 101 |
let |
25002 | 102 |
val sublocale_rule = Conjunction.intr_balanced thms; |
103 |
val subclass_rule = sublocale_rule |
|
104 |
|> Assumption.export false ctxt ctxt_thy |
|
105 |
|> singleton (Variable.export ctxt ctxt_thy); |
|
24914 | 106 |
in |
25002 | 107 |
LocalTheory.theory (prove_classrel subclass_rule |
108 |
#> prove_interpretation sublocale_rule) |
|
24914 | 109 |
(*#> (fn lthy => LocalTheory.reinit lthy thy) FIXME does not work as expected*) |
110 |
end; |
|
25002 | 111 |
in |
112 |
do_proof after_qed sublocale_prop lthy |
|
113 |
end; |
|
24934
9f5d60fe9086
renamed AxClass.get_definition to AxClass.get_info (again);
wenzelm
parents:
24914
diff
changeset
|
114 |
|
25002 | 115 |
fun user_proof after_qed props = |
116 |
Proof.theorem_i NONE (after_qed o the_single) [map (rpair []) props]; |
|
117 |
||
118 |
fun tactic_proof tac after_qed props lthy = |
|
119 |
after_qed (Goal.prove_multi (LocalTheory.target_of lthy) [] [] props |
|
120 |
(K tac)) lthy; |
|
24914 | 121 |
|
122 |
in |
|
123 |
||
25002 | 124 |
val subclass = gen_subclass (K I) user_proof; |
125 |
val subclass_cmd = gen_subclass Sign.read_class user_proof; |
|
126 |
fun prove_subclass tac = gen_subclass (K I) (tactic_proof tac); |
|
24914 | 127 |
|
128 |
end; (*local*) |
|
129 |
||
130 |
end; |