323 |
323 |
324 (* class target *) |
324 (* class target *) |
325 |
325 |
326 val class_prefix = Logic.const_of_class o Long_Name.base_name; |
326 val class_prefix = Logic.const_of_class o Long_Name.base_name; |
327 |
327 |
328 local |
|
329 |
|
330 fun guess_morphism_identity (b, rhs) phi1 phi2 = |
328 fun guess_morphism_identity (b, rhs) phi1 phi2 = |
331 let |
329 let |
332 (*FIXME proper concept to identify morphism instead of educated guess*) |
330 (*FIXME proper concept to identify morphism instead of educated guess*) |
333 val name_of_binding = Name_Space.full_name Name_Space.global_naming; |
331 val name_of_binding = Name_Space.full_name Name_Space.global_naming; |
334 val n1 = (name_of_binding o Morphism.binding phi1) b; |
332 val n1 = (name_of_binding o Morphism.binding phi1) b; |
335 val n2 = (name_of_binding o Morphism.binding phi2) b; |
333 val n2 = (name_of_binding o Morphism.binding phi2) b; |
336 val rhs1 = Morphism.term phi1 rhs; |
334 val rhs1 = Morphism.term phi1 rhs; |
337 val rhs2 = Morphism.term phi2 rhs; |
335 val rhs2 = Morphism.term phi2 rhs; |
338 in n1 = n2 andalso Term.aconv_untyped (rhs1, rhs2) end; |
336 in n1 = n2 andalso Term.aconv_untyped (rhs1, rhs2) end; |
339 |
337 |
340 fun target_const class phi0 prmode (b, rhs) = |
338 fun target_const class phi0 prmode (b, rhs) lthy = |
341 let |
339 let |
342 val guess_identity = guess_morphism_identity (b, rhs) Morphism.identity; |
340 val export = Variable.export_morphism lthy (Local_Theory.target_of lthy); |
343 val guess_canonical = guess_morphism_identity (b, rhs) phi0; |
341 val guess_identity = guess_morphism_identity (b, rhs) export; |
344 in |
342 val guess_canonical = guess_morphism_identity (b, rhs) (export $> phi0); |
345 Generic_Target.locale_target_const class |
343 in |
|
344 lthy |
|
345 |> Generic_Target.locale_target_const class |
346 (not o (guess_identity orf guess_canonical)) prmode ((b, NoSyn), rhs) |
346 (not o (guess_identity orf guess_canonical)) prmode ((b, NoSyn), rhs) |
347 end; |
347 end; |
|
348 |
|
349 local |
348 |
350 |
349 fun dangling_params_for lthy class (type_params, term_params) = |
351 fun dangling_params_for lthy class (type_params, term_params) = |
350 let |
352 let |
351 val class_param_names = |
353 val class_param_names = |
352 map fst (these_params (Proof_Context.theory_of lthy) [class]); |
354 map fst (these_params (Proof_Context.theory_of lthy) [class]); |
377 |-> (fn def_thm => register_def class def_thm) |
379 |-> (fn def_thm => register_def class def_thm) |
378 |> null dangling_params ? register_operation class (c, rhs) |
380 |> null dangling_params ? register_operation class (c, rhs) |
379 |> Sign.add_const_constraint (c, SOME ty) |
381 |> Sign.add_const_constraint (c, SOME ty) |
380 end; |
382 end; |
381 |
383 |
382 fun canonical_abbrev class phi prmode dangling_term_params ((b, mx), rhs) thy = |
|
383 let |
|
384 val unchecks = these_unchecks thy [class]; |
|
385 val rhs' = Pattern.rewrite_term thy unchecks [] rhs; |
|
386 val c' = Sign.full_name thy b; |
|
387 val ty' = map Term.fastype_of dangling_term_params ---> Term.fastype_of rhs'; |
|
388 val ty'' = Morphism.typ phi ty'; |
|
389 val rhs'' = map_types (Morphism.typ phi) (fold lambda dangling_term_params rhs'); |
|
390 in |
|
391 thy |
|
392 |> Sign.add_abbrev (#1 prmode) (b, Logic.varify_types_global rhs'') |
|
393 |> snd |
|
394 |> Sign.notation true prmode [(Const (c', ty''), mx)] |
|
395 |> (null dangling_term_params andalso not (#1 prmode = Print_Mode.input)) |
|
396 ? register_operation class (c', rhs') |
|
397 |> Sign.add_const_constraint (c', SOME ty') |
|
398 end; |
|
399 |
|
400 in |
384 in |
401 |
385 |
402 fun const class ((b, mx), lhs) params lthy = |
386 fun const class ((b, mx), lhs) params lthy = |
403 let |
387 let |
404 val phi = morphism (Proof_Context.theory_of lthy) class; |
388 val phi = morphism (Proof_Context.theory_of lthy) class; |
411 |> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other) |
395 |> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other) |
412 Syntax.mode_default ((b, if null dangling_params then NoSyn else mx), lhs) |
396 Syntax.mode_default ((b, if null dangling_params then NoSyn else mx), lhs) |
413 |> synchronize_class_syntax_target class |
397 |> synchronize_class_syntax_target class |
414 end; |
398 end; |
415 |
399 |
416 fun target_abbrev class prmode ((b, mx), lhs) rhs' params lthy = |
400 end; |
417 let |
401 |
418 val phi = morphism (Proof_Context.theory_of lthy) class; |
402 local |
419 val dangling_term_params = map (Morphism.term phi) (snd (dangling_params_for lthy class params)); |
403 |
|
404 fun canonical_abbrev class phi prmode with_syntax ((b, mx), rhs) thy = |
|
405 let |
|
406 val c = Sign.full_name thy b; |
|
407 val constrain = map_atyps (fn T as TFree (v, _) => |
|
408 if v = Name.aT then TFree (v, [class]) else T | T => T); |
|
409 val rhs' = map_types constrain rhs; |
|
410 in |
|
411 thy |
|
412 |> Sign.add_abbrev (#1 prmode) (b, Logic.varify_types_global rhs') |
|
413 |> snd |
|
414 |> with_syntax ? Sign.notation true prmode [(Const (c, fastype_of rhs), mx)] |
|
415 |> with_syntax ? register_operation class (c, rhs) |
|
416 (*FIXME input syntax!?*) |
|
417 |> Sign.add_const_constraint (c, SOME (fastype_of rhs')) |
|
418 end; |
|
419 |
|
420 fun canonical_abbrev_target class phi prmode ((b, mx), rhs) lthy = |
|
421 let |
|
422 val thy = Proof_Context.theory_of lthy; |
|
423 val preprocess = perhaps (try (Pattern.rewrite_term thy (these_unchecks thy [class]) [])); |
|
424 val (global_rhs, (extra_tfrees, (type_params, term_params))) = |
|
425 Generic_Target.export_abbrev lthy preprocess rhs; |
|
426 val mx' = Generic_Target.check_mixfix_global (b, null term_params) mx; |
420 in |
427 in |
421 lthy |
428 lthy |
422 |> target_const class phi prmode (b, lhs) |
429 |> Local_Theory.raw_theory (canonical_abbrev class phi prmode (null term_params) |
423 |> Local_Theory.raw_theory (canonical_abbrev class phi prmode dangling_term_params |
430 ((Morphism.binding phi b, mx'), Logic.unvarify_types_global global_rhs)) |
424 ((Morphism.binding phi b, if null dangling_term_params then mx else NoSyn), rhs')) |
431 end; |
425 |> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other) |
432 |
426 prmode ((b, if null dangling_term_params then NoSyn else mx), lhs) |
433 fun further_abbrev_target class phi prmode (b, mx) rhs params = |
427 |> synchronize_class_syntax_target class |
434 Generic_Target.background_abbrev (b, rhs) (snd params) |
428 end; |
435 #-> (fn (lhs, _) => target_const class phi prmode (b, lhs) |
429 |
436 #> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other) prmode ((b, mx), lhs)) |
430 fun abbrev class = Generic_Target.abbrev (fn prmode => fn (b, mx) => fn global_rhs => fn params => |
437 |
431 Generic_Target.background_abbrev (b, global_rhs) (snd params) |
438 in |
432 #-> (fn (lhs, rhs) => target_abbrev class prmode ((b, mx), lhs) rhs params)); |
439 |
|
440 fun abbrev class prmode ((b, mx), rhs) lthy = |
|
441 let |
|
442 val thy = Proof_Context.theory_of lthy; |
|
443 val phi = morphism thy class; |
|
444 val rhs_generic = |
|
445 perhaps (try (Pattern.rewrite_term thy (map swap (these_unchecks thy [class])) [])) rhs; |
|
446 in |
|
447 lthy |
|
448 |> canonical_abbrev_target class phi prmode ((b, mx), rhs) |
|
449 |> Generic_Target.abbrev (further_abbrev_target class phi) prmode ((b, mx), rhs_generic) |
|
450 ||> synchronize_class_syntax_target class |
|
451 end; |
433 |
452 |
434 end; |
453 end; |
435 |
454 |
436 |
455 |
437 (* subclasses *) |
456 (* subclasses *) |