439 |> Overloading.map_improvable_syntax |
439 |> Overloading.map_improvable_syntax |
440 (fn (((primary_constraints, _), (((improve, _), _), _)), _) => |
440 (fn (((primary_constraints, _), (((improve, _), _), _)), _) => |
441 (((primary_constraints, []), (((improve, subst), false), unchecks)), false)) |
441 (((primary_constraints, []), (((improve, subst), false), unchecks)), false)) |
442 end; |
442 end; |
443 |
443 |
444 |
|
445 (* target *) |
|
446 |
|
447 val sanitize_name = (*necessary as long as "dirty" type identifiers are permitted*) |
|
448 let |
|
449 fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s |
|
450 orelse s = "'" orelse s = "_"; |
|
451 val is_junk = not o is_valid andf Symbol.is_regular; |
|
452 val junk = Scan.many is_junk; |
|
453 val scan_valids = Symbol.scanner "Malformed input" |
|
454 ((junk |-- |
|
455 (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode) |
|
456 --| junk)) |
|
457 ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk)); |
|
458 in |
|
459 explode #> scan_valids #> implode |
|
460 end; |
|
461 |
|
462 val type_name = sanitize_name o Long_Name.base_name; |
|
463 |
|
464 fun resort_terms pp algebra consts constraints ts = |
444 fun resort_terms pp algebra consts constraints ts = |
465 let |
445 let |
466 fun matchings (Const (c_ty as (c, _))) = (case constraints c |
446 fun matchings (Const (c_ty as (c, _))) = (case constraints c |
467 of NONE => I |
447 of NONE => I |
468 | SOME sorts => fold2 (curry (Sorts.meet_sort algebra)) |
448 | SOME sorts => fold2 (curry (Sorts.meet_sort algebra)) |
472 handle Sorts.CLASS_ERROR e => error (Sorts.class_error pp e); |
452 handle Sorts.CLASS_ERROR e => error (Sorts.class_error pp e); |
473 val inst = map_type_tvar |
453 val inst = map_type_tvar |
474 (fn (vi, sort) => TVar (vi, the_default sort (Vartab.lookup tvartab vi))); |
454 (fn (vi, sort) => TVar (vi, the_default sort (Vartab.lookup tvartab vi))); |
475 in if Vartab.is_empty tvartab then NONE else SOME ((map o map_types) inst ts) end; |
455 in if Vartab.is_empty tvartab then NONE else SOME ((map o map_types) inst ts) end; |
476 |
456 |
477 fun init_instantiation (tycos, vs, sort) thy = |
457 |
|
458 (* target *) |
|
459 |
|
460 val sanitize_name = (*necessary as long as "dirty" type identifiers are permitted*) |
|
461 let |
|
462 fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s |
|
463 orelse s = "'" orelse s = "_"; |
|
464 val is_junk = not o is_valid andf Symbol.is_regular; |
|
465 val junk = Scan.many is_junk; |
|
466 val scan_valids = Symbol.scanner "Malformed input" |
|
467 ((junk |-- |
|
468 (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode) |
|
469 --| junk)) |
|
470 ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk)); |
|
471 in |
|
472 explode #> scan_valids #> implode |
|
473 end; |
|
474 |
|
475 val type_name = sanitize_name o Long_Name.base_name; |
|
476 |
|
477 fun define_overloaded (c, U) v (b_def, rhs) = Local_Theory.theory_result |
|
478 (AxClass.declare_overloaded (c, U) ##>> AxClass.define_overloaded b_def (c, rhs)) |
|
479 ##> (map_instantiation o apsnd) (filter_out (fn (_, (v', _)) => v' = v)) |
|
480 ##> Local_Theory.target synchronize_inst_syntax; |
|
481 |
|
482 fun foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy = |
|
483 case instantiation_param lthy b |
|
484 of SOME c => if mx <> NoSyn then error ("Illegal mixfix syntax for overloaded constant " ^ quote c) |
|
485 else lthy |> define_overloaded (c, U) (Binding.name_of b) (b_def, rhs) |
|
486 | NONE => lthy |> |
|
487 Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params); |
|
488 |
|
489 fun pretty lthy = |
|
490 let |
|
491 val { arities = (tycos, vs, sort), params } = the_instantiation lthy; |
|
492 val thy = ProofContext.theory_of lthy; |
|
493 fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort); |
|
494 fun pr_param ((c, _), (v, ty)) = |
|
495 (Pretty.block o Pretty.breaks) [Pretty.str v, Pretty.str "==", |
|
496 (Pretty.str o Sign.extern_const thy) c, Pretty.str "::", Syntax.pretty_typ_global thy ty]; |
|
497 in Pretty.str "instantiation" :: map pr_arity tycos @ map pr_param params end; |
|
498 |
|
499 fun conclude lthy = |
|
500 let |
|
501 val (tycos, vs, sort) = (#arities o the_instantiation) lthy; |
|
502 val thy = ProofContext.theory_of lthy; |
|
503 val _ = map (fn tyco => if Sign.of_sort thy |
|
504 (Type (tyco, map TFree vs), sort) |
|
505 then () else error ("Missing instance proof for type " ^ quote (Sign.extern_type thy tyco))) |
|
506 tycos; |
|
507 in lthy end; |
|
508 |
|
509 fun instantiation (tycos, vs, sort) thy = |
478 let |
510 let |
479 val _ = if null tycos then error "At least one arity must be given" else (); |
511 val _ = if null tycos then error "At least one arity must be given" else (); |
480 val class_params = these_params thy (filter (can (AxClass.get_info thy)) sort); |
512 val class_params = these_params thy (filter (can (AxClass.get_info thy)) sort); |
481 fun get_param tyco (param, (_, (c, ty))) = |
513 fun get_param tyco (param, (_, (c, ty))) = |
482 if can (AxClass.param_of_inst thy) (c, tyco) |
514 if can (AxClass.param_of_inst thy) (c, tyco) |
510 |> (Overloading.map_improvable_syntax o apfst) |
542 |> (Overloading.map_improvable_syntax o apfst) |
511 (K ((primary_constraints, []), (((improve, K NONE), false), []))) |
543 (K ((primary_constraints, []), (((improve, K NONE), false), []))) |
512 |> Overloading.add_improvable_syntax |
544 |> Overloading.add_improvable_syntax |
513 |> Context.proof_map (Syntax.add_term_check 0 "resorting" resort_check) |
545 |> Context.proof_map (Syntax.add_term_check 0 "resorting" resort_check) |
514 |> synchronize_inst_syntax |
546 |> synchronize_inst_syntax |
515 end; |
547 |> Local_Theory.init NONE "" |
516 |
548 {define = Generic_Target.define foundation, |
517 fun confirm_declaration b = (map_instantiation o apsnd) |
549 notes = Generic_Target.notes |
518 (filter_out (fn (_, (c', _)) => c' = Binding.name_of b)) |
550 (fn kind => fn global_facts => fn _ => Generic_Target.theory_notes kind global_facts), |
519 #> Local_Theory.target synchronize_inst_syntax |
551 abbrev = Generic_Target.abbrev |
|
552 (fn prmode => fn (b, mx) => fn (t, _) => fn _ => Generic_Target.theory_abbrev prmode ((b, mx), t)), |
|
553 declaration = K Generic_Target.theory_declaration, |
|
554 syntax_declaration = K Generic_Target.theory_declaration, |
|
555 pretty = pretty, |
|
556 exit = Local_Theory.target_of o conclude} |
|
557 end; |
|
558 |
|
559 fun instantiation_cmd arities thy = |
|
560 instantiation (read_multi_arity thy arities) thy; |
520 |
561 |
521 fun gen_instantiation_instance do_proof after_qed lthy = |
562 fun gen_instantiation_instance do_proof after_qed lthy = |
522 let |
563 let |
523 val (tycos, vs, sort) = (#arities o the_instantiation) lthy; |
564 val (tycos, vs, sort) = (#arities o the_instantiation) lthy; |
524 val arities_proof = maps (fn tyco => Logic.mk_arities (tyco, map snd vs, sort)) tycos; |
565 val arities_proof = maps (fn tyco => Logic.mk_arities (tyco, map snd vs, sort)) tycos; |
549 lthy |
590 lthy |
550 |> prove_instantiation_exit (fn ctxt => tac ctxt y) |
591 |> prove_instantiation_exit (fn ctxt => tac ctxt y) |
551 |> pair y |
592 |> pair y |
552 end; |
593 end; |
553 |
594 |
554 fun conclude_instantiation lthy = |
|
555 let |
|
556 val (tycos, vs, sort) = (#arities o the_instantiation) lthy; |
|
557 val thy = ProofContext.theory_of lthy; |
|
558 val _ = map (fn tyco => if Sign.of_sort thy |
|
559 (Type (tyco, map TFree vs), sort) |
|
560 then () else error ("Missing instance proof for type " ^ quote (Sign.extern_type thy tyco))) |
|
561 tycos; |
|
562 in lthy end; |
|
563 |
|
564 fun pretty_instantiation lthy = |
|
565 let |
|
566 val { arities = (tycos, vs, sort), params } = the_instantiation lthy; |
|
567 val thy = ProofContext.theory_of lthy; |
|
568 fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort); |
|
569 fun pr_param ((c, _), (v, ty)) = |
|
570 (Pretty.block o Pretty.breaks) [Pretty.str v, Pretty.str "==", |
|
571 (Pretty.str o Sign.extern_const thy) c, Pretty.str "::", Syntax.pretty_typ_global thy ty]; |
|
572 in |
|
573 (Pretty.block o Pretty.fbreaks) |
|
574 (Pretty.str "instantiation" :: map pr_arity tycos @ map pr_param params) |
|
575 end; |
|
576 |
|
577 fun syntax_error c = error ("Illegal mixfix syntax for overloaded constant " ^ quote c); |
|
578 |
|
579 fun instantiation_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy = |
|
580 case instantiation_param lthy b |
|
581 of SOME c => if mx <> NoSyn then syntax_error c |
|
582 else lthy |> Local_Theory.theory_result (AxClass.declare_overloaded (c, U) |
|
583 ##>> AxClass.define_overloaded b_def (c, rhs)) |
|
584 ||> confirm_declaration b |
|
585 | NONE => lthy |> |
|
586 Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params); |
|
587 |
|
588 fun instantiation arities thy = |
|
589 thy |
|
590 |> init_instantiation arities |
|
591 |> Local_Theory.init NONE "" |
|
592 {define = Generic_Target.define instantiation_foundation, |
|
593 notes = Generic_Target.notes |
|
594 (fn kind => fn global_facts => fn _ => Generic_Target.theory_notes kind global_facts), |
|
595 abbrev = Generic_Target.abbrev |
|
596 (fn prmode => fn (b, mx) => fn (t, _) => fn _ => Generic_Target.theory_abbrev prmode ((b, mx), t)), |
|
597 declaration = K Generic_Target.theory_declaration, |
|
598 syntax_declaration = K Generic_Target.theory_declaration, |
|
599 pretty = single o pretty_instantiation, |
|
600 exit = Local_Theory.target_of o conclude_instantiation}; |
|
601 |
|
602 fun instantiation_cmd arities thy = |
|
603 instantiation (read_multi_arity thy arities) thy; |
|
604 |
|
605 |
595 |
606 (* simplified instantiation interface with no class parameter *) |
596 (* simplified instantiation interface with no class parameter *) |
607 |
597 |
608 fun instance_arity_cmd raw_arities thy = |
598 fun instance_arity_cmd raw_arities thy = |
609 let |
599 let |