author  haftmann 
Wed, 20 May 2009 15:35:13 +0200  
changeset 31214  b67179528acd 
parent 31210  d6681ddc046c 
child 31249  d51d2a22a4f9 
permissions  rwrr 
29358  1 
(* Title: Pure/Isar/class_target.ML 
24218  2 
Author: Florian Haftmann, TU Muenchen 
3 

29358  4 
Type classes derived from primitive axclasses and locales  mechanisms. 
24218  5 
*) 
6 

29358  7 
signature CLASS_TARGET = 
24218  8 
sig 
25462  9 
(*classes*) 
29358  10 
val register: class > class list > ((string * typ) * (string * typ)) list 
29526  11 
> sort > morphism > thm option > thm option > thm 
12 
> theory > theory 

29558  13 
val register_subclass: class * class > morphism option > Element.witness option 
14 
> morphism > theory > theory 

25485  15 

29526  16 
val is_class: theory > class > bool 
17 
val base_sort: theory > class > sort 

18 
val rules: theory > class > thm option * thm 

19 
val these_params: theory > sort > (string * (class * (string * typ))) list 

20 
val these_defs: theory > sort > thm list 

29577  21 
val these_operations: theory > sort > (string * (class * (typ * term))) list 
29526  22 
val print_classes: theory > unit 
23 

29358  24 
val begin: class list > sort > Proof.context > Proof.context 
25311  25 
val init: class > theory > Proof.context 
28017  26 
val declare: class > Properties.T 
30344
10a67c5ddddb
more uniform handling of binding in targets and derived elements;
wenzelm
parents:
30280
diff
changeset

27 
> (binding * mixfix) * term > theory > theory 
28017  28 
val abbrev: class > Syntax.mode > Properties.T 
30344
10a67c5ddddb
more uniform handling of binding in targets and derived elements;
wenzelm
parents:
30280
diff
changeset

29 
> (binding * mixfix) * term > theory > theory 
29526  30 
val class_prefix: string > string 
25083  31 
val refresh_syntax: class > Proof.context > Proof.context 
29632
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

32 
val redeclare_operations: theory > sort > Proof.context > Proof.context 
25485  33 

25462  34 
(*instances*) 
26247  35 
val init_instantiation: string list * (string * sort) list * sort 
36 
> theory > local_theory 

37 
val instantiation_instance: (local_theory > local_theory) 

38 
> local_theory > Proof.state 

39 
val prove_instantiation_instance: (Proof.context > tactic) 

40 
> local_theory > local_theory 

28666  41 
val prove_instantiation_exit: (Proof.context > tactic) 
42 
> local_theory > theory 

43 
val prove_instantiation_exit_result: (morphism > 'a > 'b) 

44 
> (Proof.context > 'b > tactic) > 'a > local_theory > 'b * theory 

25485  45 
val conclude_instantiation: local_theory > local_theory 
30519
c05c0199826f
coherent binding policy with primitive target operations
haftmann
parents:
30364
diff
changeset

46 
val instantiation_param: local_theory > binding > string option 
c05c0199826f
coherent binding policy with primitive target operations
haftmann
parents:
30364
diff
changeset

47 
val confirm_declaration: binding > local_theory > local_theory 
25603  48 
val pretty_instantiation: local_theory > Pretty.T 
26259  49 
val type_name: string > string 
25485  50 

29526  51 
val intro_classes_tac: thm list > tactic 
52 
val default_intro_tac: Proof.context > thm list > tactic 

53 

25462  54 
(*old axclass layer*) 
30344
10a67c5ddddb
more uniform handling of binding in targets and derived elements;
wenzelm
parents:
30280
diff
changeset

55 
val axclass_cmd: binding * xstring list 
28084
a05ca48ef263
type Attrib.binding abbreviates Name.binding without attributes;
wenzelm
parents:
28083
diff
changeset

56 
> (Attrib.binding * string list) list 
25462  57 
> theory > class * theory 
58 
val classrel_cmd: xstring * xstring > theory > Proof.state 

25536  59 
val instance_arity: (theory > theory) > arity > theory > Proof.state 
30344
10a67c5ddddb
more uniform handling of binding in targets and derived elements;
wenzelm
parents:
30280
diff
changeset

60 
val instance_arity_cmd: xstring * xstring list * xstring > theory > Proof.state 
24218  61 
end; 
62 

29358  63 
structure Class_Target : CLASS_TARGET = 
24218  64 
struct 
65 

25485  66 
(** primitive axclass and instance commands **) 
24589  67 

24218  68 
fun axclass_cmd (class, raw_superclasses) raw_specs thy = 
69 
let 

70 
val ctxt = ProofContext.init thy; 

71 
val superclasses = map (Sign.read_class thy) raw_superclasses; 

24589  72 
val name_atts = map ((apsnd o map) (Attrib.attribute thy) o fst) 
73 
raw_specs; 

74 
val axiomss = ProofContext.read_propp (ctxt, map (map (rpair []) o snd) 

75 
raw_specs) 

24218  76 
> snd 
77 
> (map o map) fst; 

24589  78 
in 
79 
AxClass.define_class (class, superclasses) [] 

80 
(name_atts ~~ axiomss) thy 

81 
end; 

24218  82 

83 
local 

84 

85 
fun gen_instance mk_prop add_thm after_qed insts thy = 

86 
let 

87 
fun after_qed' results = 

88 
ProofContext.theory ((fold o fold) add_thm results #> after_qed); 

89 
in 

90 
thy 

91 
> ProofContext.init 

24589  92 
> Proof.theorem_i NONE after_qed' ((map (fn t => [(t, [])]) 
25536  93 
o mk_prop thy) insts) 
24218  94 
end; 
95 

96 
in 

97 

24589  98 
val instance_arity = 
24218  99 
gen_instance (Logic.mk_arities oo Sign.cert_arity) AxClass.add_arity; 
25502  100 
val instance_arity_cmd = 
101 
gen_instance (Logic.mk_arities oo Sign.read_arity) AxClass.add_arity I; 

24589  102 
val classrel = 
25536  103 
gen_instance (single oo (Logic.mk_classrel oo AxClass.cert_classrel)) AxClass.add_classrel I; 
24589  104 
val classrel_cmd = 
25536  105 
gen_instance (single oo (Logic.mk_classrel oo AxClass.read_classrel)) AxClass.add_classrel I; 
24218  106 

107 
end; (*local*) 

108 

109 

24589  110 
(** class data **) 
24218  111 

112 
datatype class_data = ClassData of { 

28715
238f9966c80e
class morphism stemming from locale interpretation
haftmann
parents:
28674
diff
changeset

113 

238f9966c80e
class morphism stemming from locale interpretation
haftmann
parents:
28674
diff
changeset

114 
(* static part *) 
24218  115 
consts: (string * string) list 
24836  116 
(*locale parameter ~> constant name*), 
25062  117 
base_sort: sort, 
29545  118 
base_morph: morphism 
29439  119 
(*static part of canonical morphism*), 
25618  120 
assm_intro: thm option, 
121 
of_class: thm, 

122 
axiom: thm option, 

28715
238f9966c80e
class morphism stemming from locale interpretation
haftmann
parents:
28674
diff
changeset

123 

238f9966c80e
class morphism stemming from locale interpretation
haftmann
parents:
28674
diff
changeset

124 
(* dynamic part *) 
24657  125 
defs: thm list, 
25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

126 
operations: (string * (class * (typ * term))) list 
28715
238f9966c80e
class morphism stemming from locale interpretation
haftmann
parents:
28674
diff
changeset

127 

24657  128 
}; 
24218  129 

29526  130 
fun rep_class_data (ClassData data) = data; 
131 
fun mk_class_data ((consts, base_sort, base_morph, assm_intro, of_class, axiom), 

25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

132 
(defs, operations)) = 
29526  133 
ClassData { consts = consts, base_sort = base_sort, 
29439  134 
base_morph = base_morph, assm_intro = assm_intro, of_class = of_class, axiom = axiom, 
25618  135 
defs = defs, operations = operations }; 
29526  136 
fun map_class_data f (ClassData { consts, base_sort, base_morph, assm_intro, 
28715
238f9966c80e
class morphism stemming from locale interpretation
haftmann
parents:
28674
diff
changeset

137 
of_class, axiom, defs, operations }) = 
29526  138 
mk_class_data (f ((consts, base_sort, base_morph, assm_intro, of_class, axiom), 
25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

139 
(defs, operations))); 
25038  140 
fun merge_class_data _ (ClassData { consts = consts, 
29526  141 
base_sort = base_sort, base_morph = base_morph, assm_intro = assm_intro, 
25618  142 
of_class = of_class, axiom = axiom, defs = defs1, operations = operations1 }, 
29526  143 
ClassData { consts = _, base_sort = _, base_morph = _, assm_intro = _, 
25618  144 
of_class = _, axiom = _, defs = defs2, operations = operations2 }) = 
29526  145 
mk_class_data ((consts, base_sort, base_morph, assm_intro, of_class, axiom), 
24914
95cda5dd58d5
added proper subclass concept; improved class target
haftmann
parents:
24901
diff
changeset

146 
(Thm.merge_thms (defs1, defs2), 
25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

147 
AList.merge (op =) (K true) (operations1, operations2))); 
24218  148 

149 
structure ClassData = TheoryDataFun 

150 
( 

25038  151 
type T = class_data Graph.T 
152 
val empty = Graph.empty; 

24218  153 
val copy = I; 
154 
val extend = I; 

25038  155 
fun merge _ = Graph.join merge_class_data; 
24218  156 
); 
157 

158 

159 
(* queries *) 

160 

25038  161 
val lookup_class_data = Option.map rep_class_data oo try o Graph.get_node o ClassData.get; 
24218  162 

24589  163 
fun the_class_data thy class = case lookup_class_data thy class 
25020  164 
of NONE => error ("Undeclared class " ^ quote class) 
24589  165 
 SOME data => data; 
24218  166 

25038  167 
val is_class = is_some oo lookup_class_data; 
168 

169 
val ancestry = Graph.all_succs o ClassData.get; 

29509
1ff0f3f08a7b
migrated class package to new locale implementation
haftmann
parents:
29439
diff
changeset

170 
val heritage = Graph.all_preds o ClassData.get; 
1ff0f3f08a7b
migrated class package to new locale implementation
haftmann
parents:
29439
diff
changeset

171 

25002  172 
fun these_params thy = 
24218  173 
let 
174 
fun params class = 

175 
let 

24930
cc2e0e8c81af
renamed AxClass.get_definition to AxClass.get_info (again);
wenzelm
parents:
24920
diff
changeset

176 
val const_typs = (#params o AxClass.get_info thy) class; 
24657  177 
val const_names = (#consts o the_class_data thy) class; 
24218  178 
in 
26518  179 
(map o apsnd) 
180 
(fn c => (class, (c, (the o AList.lookup (op =) const_typs) c))) const_names 

24218  181 
end; 
182 
in maps params o ancestry thy end; 

183 

29526  184 
val base_sort = #base_sort oo the_class_data; 
185 

186 
fun rules thy class = 

187 
let val { axiom, of_class, ... } = the_class_data thy class 

188 
in (axiom, of_class) end; 

189 

190 
fun all_assm_intros thy = 

25618  191 
Graph.fold (fn (_, (data, _)) => fold (insert Thm.eq_thm) 
192 
((the_list o #assm_intro o rep_class_data) data)) (ClassData.get thy) []; 

24218  193 

29526  194 
fun these_defs thy = maps (#defs o the_class_data thy) o ancestry thy; 
195 
fun these_operations thy = maps (#operations o the_class_data thy) o ancestry thy; 

29358  196 

29526  197 
val base_morphism = #base_morph oo the_class_data; 
198 
fun morphism thy class = base_morphism thy class 

199 
$> Element.eq_morphism thy (these_defs thy [class]); 

28715
238f9966c80e
class morphism stemming from locale interpretation
haftmann
parents:
28674
diff
changeset

200 

24218  201 
fun print_classes thy = 
202 
let 

24920  203 
val ctxt = ProofContext.init thy; 
24218  204 
val algebra = Sign.classes_of thy; 
205 
val arities = 

206 
Symtab.empty 

207 
> Symtab.fold (fn (tyco, arities) => fold (fn (class, _) => 

208 
Symtab.map_default (class, []) (insert (op =) tyco)) arities) 

209 
((#arities o Sorts.rep_algebra) algebra); 

210 
val the_arities = these o Symtab.lookup arities; 

211 
fun mk_arity class tyco = 

212 
let 

213 
val Ss = Sorts.mg_domain algebra tyco [class]; 

24920  214 
in Syntax.pretty_arity ctxt (tyco, Ss, [class]) end; 
24218  215 
fun mk_param (c, ty) = Pretty.str (Sign.extern_const thy c ^ " :: " 
24920  216 
^ setmp show_sorts false (Syntax.string_of_typ ctxt o Type.strip_sorts) ty); 
24218  217 
fun mk_entry class = (Pretty.block o Pretty.fbreaks o map_filter I) [ 
25062  218 
(SOME o Pretty.str) ("class " ^ Sign.extern_class thy class ^ ":"), 
24218  219 
(SOME o Pretty.block) [Pretty.str "supersort: ", 
24920  220 
(Syntax.pretty_sort ctxt o Sign.minimize_sort thy o Sign.super_classes thy) class], 
25062  221 
((fn [] => NONE  ps => (SOME o Pretty.block o Pretty.fbreaks) 
222 
(Pretty.str "parameters:" :: ps)) o map mk_param 

24930
cc2e0e8c81af
renamed AxClass.get_definition to AxClass.get_info (again);
wenzelm
parents:
24920
diff
changeset

223 
o these o Option.map #params o try (AxClass.get_info thy)) class, 
24218  224 
(SOME o Pretty.block o Pretty.breaks) [ 
225 
Pretty.str "instances:", 

226 
Pretty.list "" "" (map (mk_arity class) (the_arities class)) 

227 
] 

228 
] 

229 
in 

24589  230 
(Pretty.writeln o Pretty.chunks o separate (Pretty.str "") 
231 
o map mk_entry o Sorts.all_classes) algebra 

24218  232 
end; 
233 

234 

235 
(* updaters *) 

236 

29526  237 
fun register class sups params base_sort morph 
29358  238 
axiom assm_intro of_class thy = 
25002  239 
let 
25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

240 
val operations = map (fn (v_ty as (_, ty), (c, _)) => 
25683  241 
(c, (class, (ty, Free v_ty)))) params; 
25038  242 
val add_class = Graph.new_node (class, 
25683  243 
mk_class_data (((map o pairself) fst params, base_sort, 
29526  244 
morph, assm_intro, of_class, axiom), ([], operations))) 
245 
#> fold (curry Graph.add_edge class) sups; 

25618  246 
in ClassData.map add_class thy end; 
24218  247 

29526  248 
fun activate_defs class thms thy = 
249 
let 

250 
val eq_morph = Element.eq_morphism thy thms; 

251 
fun amend cls thy = Locale.amend_registration eq_morph 

252 
(cls, morphism thy cls) thy; 

253 
in fold amend (heritage thy [class]) thy end; 

254 

25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

255 
fun register_operation class (c, (t, some_def)) thy = 
25062  256 
let 
29358  257 
val base_sort = base_sort thy class; 
29439  258 
val prep_typ = map_type_tfree 
259 
(fn (v, sort) => if Name.aT = v 

260 
then TFree (v, base_sort) else TVar ((v, 0), sort)); 

25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

261 
val t' = map_types prep_typ t; 
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

262 
val ty' = Term.fastype_of t'; 
25062  263 
in 
264 
thy 

265 
> (ClassData.map o Graph.map_node class o map_class_data o apsnd) 

25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

266 
(fn (defs, operations) => 
25096  267 
(fold cons (the_list some_def) defs, 
25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

268 
(c, (class, (ty', t'))) :: operations)) 
29526  269 
> is_some some_def ? activate_defs class (the_list some_def) 
25062  270 
end; 
24218  271 

29558  272 
fun register_subclass (sub, sup) some_dep_morph some_wit export thy = 
25618  273 
let 
29558  274 
val intros = (snd o rules thy) sup :: map_filter I 
275 
[Option.map (Drule.standard' o Element.conclude_witness) some_wit, 

276 
(fst o rules thy) sub]; 

29610  277 
val tac = EVERY (map (TRYALL o Tactic.rtac) intros); 
29558  278 
val classrel = Goal.prove_global thy [] [] (Logic.mk_classrel (sub, sup)) 
279 
(K tac); 

29509
1ff0f3f08a7b
migrated class package to new locale implementation
haftmann
parents:
29439
diff
changeset

280 
val diff_sort = Sign.complete_sort thy [sup] 
31012  281 
> subtract (op =) (Sign.complete_sort thy [sub]) 
282 
> filter (is_class thy); 

25618  283 
in 
284 
thy 

285 
> AxClass.add_classrel classrel 

286 
> ClassData.map (Graph.add_edge (sub, sup)) 

29526  287 
> activate_defs sub (these_defs thy diff_sort) 
29610  288 
> fold (fn dep_morph => Locale.add_dependency sub (sup, 
289 
dep_morph $> Element.satisfy_morphism (the_list some_wit) $> export)) 

290 
(the_list some_dep_morph) 

30764
3e3e7aa0cc7a
simplified Locale.activate operations, using generic context;
wenzelm
parents:
30521
diff
changeset

291 
> (fn thy => fold_rev (Context.theory_map o Locale.activate_facts) 
3e3e7aa0cc7a
simplified Locale.activate operations, using generic context;
wenzelm
parents:
30521
diff
changeset

292 
(Locale.get_registrations thy) thy) 
24218  293 
end; 
294 

295 

24589  296 
(** classes and class target **) 
24218  297 

25002  298 
(* class context syntax *) 
24748  299 

29577  300 
fun these_unchecks thy = 
301 
map (fn (c, (_, (ty, t))) => (t, Const (c, ty))) o these_operations thy; 

302 

29632
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

303 
fun redeclare_const thy c = 
30364
577edc39b501
moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents:
30344
diff
changeset

304 
let val b = Long_Name.base_name c 
29632
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

305 
in Sign.intern_const thy b = c ? Variable.declare_const (b, c) end; 
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

306 

29577  307 
fun synchronize_class_syntax sort base_sort ctxt = 
24914
95cda5dd58d5
added proper subclass concept; improved class target
haftmann
parents:
24901
diff
changeset

308 
let 
25344
00c2179db769
synchronize_syntax: improved declare_const (still inactive);
wenzelm
parents:
25326
diff
changeset

309 
val thy = ProofContext.theory_of ctxt; 
26596  310 
val algebra = Sign.classes_of thy; 
29577  311 
val operations = these_operations thy sort; 
26518  312 
fun subst_class_typ sort = map_type_tfree (K (TVar ((Name.aT, 0), sort))); 
313 
val primary_constraints = 

25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

314 
(map o apsnd) (subst_class_typ base_sort o fst o snd) operations; 
26518  315 
val secondary_constraints = 
25368
f12613fda79d
proper implementation of check phase; nonqualified names for class operations
haftmann
parents:
25344
diff
changeset

316 
(map o apsnd) (fn (class, (ty, _)) => subst_class_typ [class] ty) operations; 
26518  317 
fun improve (c, ty) = (case AList.lookup (op =) primary_constraints c 
26238  318 
of SOME ty' => (case try (Type.raw_match (ty', ty)) Vartab.empty 
319 
of SOME tyenv => (case Vartab.lookup tyenv (Name.aT, 0) 

26596  320 
of SOME (_, ty' as TVar (tvar as (vi, sort))) => 
26238  321 
if TypeInfer.is_param vi 
26596  322 
andalso Sorts.sort_le algebra (base_sort, sort) 
323 
then SOME (ty', TFree (Name.aT, base_sort)) 

324 
else NONE 

26238  325 
 _ => NONE) 
326 
 NONE => NONE) 

327 
 NONE => NONE) 

328 
fun subst (c, ty) = Option.map snd (AList.lookup (op =) operations c); 

29577  329 
val unchecks = these_unchecks thy sort; 
25083  330 
in 
331 
ctxt 

29632
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

332 
> fold (redeclare_const thy o fst) primary_constraints 
26518  333 
> Overloading.map_improvable_syntax (K (((primary_constraints, secondary_constraints), 
26730  334 
(((improve, subst), true), unchecks)), false)) 
26518  335 
> Overloading.set_primary_constraints 
25083  336 
end; 
337 

338 
fun refresh_syntax class ctxt = 

25002  339 
let 
340 
val thy = ProofContext.theory_of ctxt; 

29358  341 
val base_sort = base_sort thy class; 
26238  342 
in synchronize_class_syntax [class] base_sort ctxt end; 
25002  343 

29632
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

344 
fun redeclare_operations thy sort = 
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

345 
fold (redeclare_const thy o fst) (these_operations thy sort); 
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

346 

29577  347 
fun begin sort base_sort ctxt = 
25083  348 
ctxt 
349 
> Variable.declare_term 

350 
(Logic.mk_type (TFree (Name.aT, base_sort))) 

29577  351 
> synchronize_class_syntax sort base_sort 
26238  352 
> Overloading.add_improvable_syntax; 
24901
d3cbf79769b9
added first version of userspace type system for class target
haftmann
parents:
24847
diff
changeset

353 

25311  354 
fun init class thy = 
355 
thy 

29509
1ff0f3f08a7b
migrated class package to new locale implementation
haftmann
parents:
29439
diff
changeset

356 
> Locale.init class 
29358  357 
> begin [class] (base_sort thy class); 
24914
95cda5dd58d5
added proper subclass concept; improved class target
haftmann
parents:
24901
diff
changeset

358 

24748  359 

27690
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

360 
(* class target *) 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

361 

30364
577edc39b501
moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents:
30344
diff
changeset

362 
val class_prefix = Logic.const_of_class o Long_Name.base_name; 
29526  363 

27690
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

364 
fun declare class pos ((c, mx), dict) thy = 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

365 
let 
29577  366 
val morph = morphism thy class; 
30344
10a67c5ddddb
more uniform handling of binding in targets and derived elements;
wenzelm
parents:
30280
diff
changeset

367 
val b = Morphism.binding morph c; 
10a67c5ddddb
more uniform handling of binding in targets and derived elements;
wenzelm
parents:
30280
diff
changeset

368 
val b_def = Morphism.binding morph (Binding.suffix_name "_dict" b); 
29577  369 
val c' = Sign.full_name thy b; 
29439  370 
val dict' = Morphism.term morph dict; 
371 
val ty' = Term.fastype_of dict'; 

29577  372 
val def_eq = Logic.mk_equals (Const (c', ty'), dict') 
373 
> map_types Type.strip_sorts; 

27690
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

374 
in 
29577  375 
thy 
376 
> Sign.declare_const pos ((b, Type.strip_sorts ty'), mx) 

377 
> snd 

378 
> Thm.add_def false false (b_def, def_eq) 

379 
>> Thm.varifyT 

380 
> (fn def_thm => PureThy.store_thm (b_def, def_thm) 

381 
#> snd 

382 
#> register_operation class (c', (dict', SOME (Thm.symmetric def_thm)))) 

27690
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

383 
> Sign.add_const_constraint (c', SOME ty') 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

384 
end; 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

385 

24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

386 
fun abbrev class prmode pos ((c, mx), rhs) thy = 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

387 
let 
29577  388 
val morph = morphism thy class; 
389 
val unchecks = these_unchecks thy [class]; 

30344
10a67c5ddddb
more uniform handling of binding in targets and derived elements;
wenzelm
parents:
30280
diff
changeset

390 
val b = Morphism.binding morph c; 
29577  391 
val c' = Sign.full_name thy b; 
27690
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

392 
val rhs' = Pattern.rewrite_term thy unchecks [] rhs; 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

393 
val ty' = Term.fastype_of rhs'; 
29577  394 
val rhs'' = map_types ((*Type.strip_sorts o *)Logic.varifyT) rhs'; 
27690
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

395 
in 
29577  396 
thy 
397 
> Sign.add_abbrev (#1 prmode) pos (b, rhs'') 

398 
> snd 

27690
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

399 
> Sign.add_const_constraint (c', SOME ty') 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

400 
> Sign.notation true prmode [(Const (c', ty'), mx)] 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

401 
> not (#1 prmode = PrintMode.input) ? register_operation class (c', (rhs', NONE)) 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

402 
end; 
24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

403 

24738db98d34
some steps towards explicit class target for canonical interpretation
haftmann
parents:
27684
diff
changeset

404 

25462  405 
(** instantiation target **) 
406 

407 
(* bookkeeping *) 

408 

409 
datatype instantiation = Instantiation of { 

25864  410 
arities: string list * (string * sort) list * sort, 
25462  411 
params: ((string * string) * (string * typ)) list 
25603  412 
(*(instantiation parameter, type constructor), (local instantiation parameter, typ)*) 
25462  413 
} 
414 

415 
structure Instantiation = ProofDataFun 

416 
( 

417 
type T = instantiation 

25536  418 
fun init _ = Instantiation { arities = ([], [], []), params = [] }; 
25462  419 
); 
420 

25485  421 
fun mk_instantiation (arities, params) = 
422 
Instantiation { arities = arities, params = params }; 

25514  423 
fun get_instantiation lthy = case Instantiation.get (LocalTheory.target_of lthy) 
25485  424 
of Instantiation data => data; 
25514  425 
fun map_instantiation f = (LocalTheory.target o Instantiation.map) 
426 
(fn Instantiation { arities, params } => mk_instantiation (f (arities, params))); 

25462  427 

25514  428 
fun the_instantiation lthy = case get_instantiation lthy 
25536  429 
of { arities = ([], [], []), ... } => error "No instantiation target" 
25485  430 
 data => data; 
25462  431 

25485  432 
val instantiation_params = #params o get_instantiation; 
25462  433 

30519
c05c0199826f
coherent binding policy with primitive target operations
haftmann
parents:
30364
diff
changeset

434 
fun instantiation_param lthy b = instantiation_params lthy 
c05c0199826f
coherent binding policy with primitive target operations
haftmann
parents:
30364
diff
changeset

435 
> find_first (fn (_, (v, _)) => Binding.name_of b = v) 
25462  436 
> Option.map (fst o fst); 
437 

438 

439 
(* syntax *) 

440 

26238  441 
fun synchronize_inst_syntax ctxt = 
25462  442 
let 
26259  443 
val Instantiation { arities = (_, _, sort), params = params } = Instantiation.get ctxt; 
31210  444 
val inst_tyco_of = AxClass.inst_tyco_of (Sign.consts_of (ProofContext.theory_of ctxt)); 
445 
fun subst (c, ty) = case inst_tyco_of (c, ty) 

26238  446 
of SOME tyco => (case AList.lookup (op =) params (c, tyco) 
447 
of SOME (v_ty as (_, ty)) => SOME (ty, Free v_ty) 

448 
 NONE => NONE) 

449 
 NONE => NONE; 

450 
val unchecks = 

451 
map (fn ((c, _), v_ty as (_, ty)) => (Free v_ty, Const (c, ty))) params; 

452 
in 

453 
ctxt 

26259  454 
> Overloading.map_improvable_syntax 
26730  455 
(fn (((primary_constraints, _), (((improve, _), _), _)), _) => 
456 
(((primary_constraints, []), (((improve, subst), false), unchecks)), false)) 

26238  457 
end; 
25462  458 

459 

460 
(* target *) 

461 

25485  462 
val sanatize_name = (*FIXME*) 
463 
let 

25574  464 
fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s 
465 
orelse s = "'" orelse s = "_"; 

25485  466 
val is_junk = not o is_valid andf Symbol.is_regular; 
467 
val junk = Scan.many is_junk; 

468 
val scan_valids = Symbol.scanner "Malformed input" 

469 
((junk  

470 
(Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode) 

471 
 junk)) 

25999  472 
::: Scan.repeat ((Scan.many1 is_valid >> implode)  junk)); 
25485  473 
in 
474 
explode #> scan_valids #> implode 

475 
end; 

476 

26259  477 
fun type_name "*" = "prod" 
478 
 type_name "+" = "sum" 

30364
577edc39b501
moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents:
30344
diff
changeset

479 
 type_name s = sanatize_name (Long_Name.base_name s); 
26259  480 

26518  481 
fun resort_terms pp algebra consts constraints ts = 
482 
let 

483 
fun matchings (Const (c_ty as (c, _))) = (case constraints c 

484 
of NONE => I 

485 
 SOME sorts => fold2 (curry (Sorts.meet_sort algebra)) 

486 
(Consts.typargs consts c_ty) sorts) 

487 
 matchings _ = I 

488 
val tvartab = (fold o fold_aterms) matchings ts Vartab.empty 

26642
454d11701fa4
Sorts.class_error: produce message only (formerly msg_class_error);
wenzelm
parents:
26628
diff
changeset

489 
handle Sorts.CLASS_ERROR e => error (Sorts.class_error pp e); 
27089
480f19078b65
fixed wrong treatment of type variables in instantiation target
haftmann
parents:
26995
diff
changeset

490 
val inst = map_type_tvar 
480f19078b65
fixed wrong treatment of type variables in instantiation target
haftmann
parents:
26995
diff
changeset

491 
(fn (vi, sort) => TVar (vi, the_default sort (Vartab.lookup tvartab vi))); 
26518  492 
in if Vartab.is_empty tvartab then NONE else SOME ((map o map_types) inst ts) end; 
493 

25864  494 
fun init_instantiation (tycos, vs, sort) thy = 
25462  495 
let 
25536  496 
val _ = if null tycos then error "At least one arity must be given" else (); 
29969
9dbb046136d0
more precise improvement in instantiation user space type system
haftmann
parents:
29632
diff
changeset

497 
val params = these_params thy (filter (can (AxClass.get_info thy)) sort); 
29632
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

498 
fun get_param tyco (param, (_, (c, ty))) = 
c3d576157244
fixed reading of class specs: declare class operations in context
haftmann
parents:
29610
diff
changeset

499 
if can (AxClass.param_of_inst thy) (c, tyco) 
25603  500 
then NONE else SOME ((c, tyco), 
25864  501 
(param ^ "_" ^ type_name tyco, map_atyps (K (Type (tyco, map TFree vs))) ty)); 
26518  502 
val inst_params = map_product get_param tycos params > map_filter I; 
503 
val primary_constraints = map (apsnd 

504 
(map_atyps (K (TVar ((Name.aT, 0), [])))) o snd o snd) params; 

26939
1035c89b4c02
moved global pretty/string_of functions from Sign to Syntax;
wenzelm
parents:
26761
diff
changeset

505 
val pp = Syntax.pp_global thy; 
26518  506 
val algebra = Sign.classes_of thy 
507 
> fold (fn tyco => Sorts.add_arities pp 

508 
(tyco, map (fn class => (class, map snd vs)) sort)) tycos; 

509 
val consts = Sign.consts_of thy; 

510 
val improve_constraints = AList.lookup (op =) 

511 
(map (fn (_, (class, (c, _))) => (c, [[class]])) params); 

512 
fun resort_check ts ctxt = case resort_terms pp algebra consts improve_constraints ts 

513 
of NONE => NONE 

514 
 SOME ts' => SOME (ts', ctxt); 

31214  515 
val inst_tyco_of = AxClass.inst_tyco_of consts; 
31210  516 
val typ_instance = Type.typ_instance (Sign.tsig_of thy); 
517 
fun improve (c, ty) = case inst_tyco_of (c, ty) 

26329
3e58e4c67a2a
instantiation less liberal with dangling constraints
haftmann
parents:
26259
diff
changeset

518 
of SOME tyco => (case AList.lookup (op =) inst_params (c, tyco) 
31210  519 
of SOME (_, ty') => if typ_instance (ty', ty) 
29969
9dbb046136d0
more precise improvement in instantiation user space type system
haftmann
parents:
29632
diff
changeset

520 
then SOME (ty, ty') else NONE 
26259  521 
 NONE => NONE) 
522 
 NONE => NONE; 

25485  523 
in 
524 
thy 

525 
> ProofContext.init 

26329
3e58e4c67a2a
instantiation less liberal with dangling constraints
haftmann
parents:
26259
diff
changeset

526 
> Instantiation.put (mk_instantiation ((tycos, vs, sort), inst_params)) 
27281  527 
> fold (Variable.declare_typ o TFree) vs 
26329
3e58e4c67a2a
instantiation less liberal with dangling constraints
haftmann
parents:
26259
diff
changeset

528 
> fold (Variable.declare_names o Free o snd) inst_params 
26259  529 
> (Overloading.map_improvable_syntax o apfst) 
29969
9dbb046136d0
more precise improvement in instantiation user space type system
haftmann
parents:
29632
diff
changeset

530 
(K ((primary_constraints, []), (((improve, K NONE), false), []))) 
26259  531 
> Overloading.add_improvable_syntax 
26518  532 
> Context.proof_map (Syntax.add_term_check 0 "resorting" resort_check) 
26238  533 
> synchronize_inst_syntax 
25485  534 
end; 
535 

30519
c05c0199826f
coherent binding policy with primitive target operations
haftmann
parents:
30364
diff
changeset

536 
fun confirm_declaration b = (map_instantiation o apsnd) 
c05c0199826f
coherent binding policy with primitive target operations
haftmann
parents:
30364
diff
changeset

537 
(filter_out (fn (_, (c', _)) => c' = Binding.name_of b)) 
26238  538 
#> LocalTheory.target synchronize_inst_syntax 
539 

25485  540 
fun gen_instantiation_instance do_proof after_qed lthy = 
541 
let 

25864  542 
val (tycos, vs, sort) = (#arities o the_instantiation) lthy; 
543 
val arities_proof = maps (fn tyco => Logic.mk_arities (tyco, map snd vs, sort)) tycos; 

25462  544 
fun after_qed' results = 
545 
LocalTheory.theory (fold (AxClass.add_arity o Thm.varifyT) results) 

546 
#> after_qed; 

547 
in 

548 
lthy 

549 
> do_proof after_qed' arities_proof 

550 
end; 

551 

25485  552 
val instantiation_instance = gen_instantiation_instance (fn after_qed => fn ts => 
25462  553 
Proof.theorem_i NONE (after_qed o map the_single) (map (fn t => [(t, [])]) ts)); 
554 

25485  555 
fun prove_instantiation_instance tac = gen_instantiation_instance (fn after_qed => 
25502  556 
fn ts => fn lthy => after_qed (map (fn t => Goal.prove lthy [] [] t 
557 
(fn {context, ...} => tac context)) ts) lthy) I; 

25462  558 

28666  559 
fun prove_instantiation_exit tac = prove_instantiation_instance tac 
560 
#> LocalTheory.exit_global; 

561 

562 
fun prove_instantiation_exit_result f tac x lthy = 

563 
let 

29439  564 
val morph = ProofContext.export_morphism lthy 
28666  565 
(ProofContext.init (ProofContext.theory_of lthy)); 
29439  566 
val y = f morph x; 
28666  567 
in 
568 
lthy 

569 
> prove_instantiation_exit (fn ctxt => tac ctxt y) 

570 
> pair y 

571 
end; 

572 

25462  573 
fun conclude_instantiation lthy = 
574 
let 

25485  575 
val { arities, params } = the_instantiation lthy; 
25864  576 
val (tycos, vs, sort) = arities; 
25462  577 
val thy = ProofContext.theory_of lthy; 
25597
34860182b250
moved instance parameter management from class.ML to axclass.ML
haftmann
parents:
25574
diff
changeset

578 
val _ = map (fn tyco => if Sign.of_sort thy 
25864  579 
(Type (tyco, map TFree vs), sort) 
25462  580 
then () else error ("Missing instance proof for type " ^ quote (Sign.extern_type thy tyco))) 
25597
34860182b250
moved instance parameter management from class.ML to axclass.ML
haftmann
parents:
25574
diff
changeset

581 
tycos; 
34860182b250
moved instance parameter management from class.ML to axclass.ML
haftmann
parents:
25574
diff
changeset

582 
in lthy end; 
25462  583 

25603  584 
fun pretty_instantiation lthy = 
585 
let 

586 
val { arities, params } = the_instantiation lthy; 

25864  587 
val (tycos, vs, sort) = arities; 
25603  588 
val thy = ProofContext.theory_of lthy; 
25864  589 
fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort); 
25603  590 
fun pr_param ((c, _), (v, ty)) = 
25864  591 
(Pretty.block o Pretty.breaks) [Pretty.str v, Pretty.str "==", 
26939
1035c89b4c02
moved global pretty/string_of functions from Sign to Syntax;
wenzelm
parents:
26761
diff
changeset

592 
(Pretty.str o Sign.extern_const thy) c, Pretty.str "::", Syntax.pretty_typ_global thy ty]; 
25603  593 
in 
594 
(Pretty.block o Pretty.fbreaks) 

595 
(Pretty.str "instantiation" :: map pr_arity tycos @ map pr_param params) 

596 
end; 

597 

29526  598 

599 
(** tactics and methods **) 

600 

601 
fun intro_classes_tac facts st = 

602 
let 

603 
val thy = Thm.theory_of_thm st; 

604 
val classes = Sign.all_classes thy; 

605 
val class_trivs = map (Thm.class_triv thy) classes; 

606 
val class_intros = map_filter (try (#intro o AxClass.get_info thy)) classes; 

607 
val assm_intros = all_assm_intros thy; 

608 
in 

609 
Method.intros_tac (class_trivs @ class_intros @ assm_intros) facts st 

610 
end; 

611 

612 
fun default_intro_tac ctxt [] = 

29577  613 
intro_classes_tac [] ORELSE Locale.intro_locales_tac true ctxt [] 
29526  614 
 default_intro_tac _ _ = no_tac; 
615 

616 
fun default_tac rules ctxt facts = 

617 
HEADGOAL (Method.some_rule_tac rules ctxt facts) ORELSE 

618 
default_intro_tac ctxt facts; 

619 

620 
val _ = Context.>> (Context.map_theory 

30515  621 
(Method.setup (Binding.name "intro_classes") (Scan.succeed (K (METHOD intro_classes_tac))) 
622 
"backchain introduction rules of classes" #> 

623 
Method.setup (Binding.name "default") (Attrib.thms >> (METHOD oo default_tac)) 

624 
"apply some intro/elim rule")); 

29526  625 

24218  626 
end; 
25683  627 