src/HOL/Typerep.thy
author wenzelm
Mon Nov 02 20:34:59 2009 +0100 (2009-11-02)
changeset 33384 1b5ba4e6a953
parent 31723 f5cafe803b55
child 33553 35f2b30593a8
permissions -rw-r--r--
modernized structure Simple_Syntax;
haftmann@31048
     1
(* Author: Florian Haftmann, TU Muenchen *)
haftmann@26168
     2
haftmann@26168
     3
header {* Reflecting Pure types into HOL *}
haftmann@26168
     4
haftmann@28952
     5
theory Typerep
haftmann@31048
     6
imports Plain String
haftmann@26168
     7
begin
haftmann@26168
     8
haftmann@31205
     9
datatype typerep = Typerep String.literal "typerep list"
haftmann@26168
    10
haftmann@28335
    11
class typerep =
haftmann@31031
    12
  fixes typerep :: "'a itself \<Rightarrow> typerep"
haftmann@26168
    13
begin
haftmann@26168
    14
haftmann@29574
    15
definition typerep_of :: "'a \<Rightarrow> typerep" where
haftmann@28335
    16
  [simp]: "typerep_of x = typerep TYPE('a)"
haftmann@26168
    17
haftmann@26168
    18
end
haftmann@26168
    19
haftmann@26168
    20
setup {*
haftmann@26168
    21
let
haftmann@28335
    22
  fun typerep_tr (*"_TYPEREP"*) [ty] =
haftmann@28335
    23
        Lexicon.const @{const_syntax typerep} $ (Lexicon.const "_constrain" $ Lexicon.const "TYPE" $
haftmann@26168
    24
          (Lexicon.const "itself" $ ty))
haftmann@28335
    25
    | typerep_tr (*"_TYPEREP"*) ts = raise TERM ("typerep_tr", ts);
haftmann@28335
    26
  fun typerep_tr' show_sorts (*"typerep"*)
haftmann@26168
    27
          (Type ("fun", [Type ("itself", [T]), _])) (Const (@{const_syntax TYPE}, _) :: ts) =
haftmann@28335
    28
        Term.list_comb (Lexicon.const "_TYPEREP" $ Syntax.term_of_typ show_sorts T, ts)
haftmann@28335
    29
    | typerep_tr' _ T ts = raise Match;
haftmann@26168
    30
in
haftmann@26168
    31
  Sign.add_syntax_i
wenzelm@33384
    32
    [("_TYPEREP", Simple_Syntax.read_typ "type => logic", Delimfix "(1TYPEREP/(1'(_')))")]
haftmann@28335
    33
  #> Sign.add_trfuns ([], [("_TYPEREP", typerep_tr)], [], [])
haftmann@28335
    34
  #> Sign.add_trfunsT [(@{const_syntax typerep}, typerep_tr')]
haftmann@26168
    35
end
haftmann@26168
    36
*}
haftmann@26168
    37
haftmann@31137
    38
setup {*
haftmann@31137
    39
let
haftmann@26168
    40
haftmann@31137
    41
fun add_typerep tyco thy =
haftmann@26168
    42
  let
haftmann@28335
    43
    val sorts = replicate (Sign.arity_number thy tyco) @{sort typerep};
haftmann@26168
    44
    val vs = Name.names Name.context "'a" sorts;
haftmann@26168
    45
    val ty = Type (tyco, map TFree vs);
haftmann@28335
    46
    val lhs = Const (@{const_name typerep}, Term.itselfT ty --> @{typ typerep})
haftmann@26168
    47
      $ Free ("T", Term.itselfT ty);
haftmann@31205
    48
    val rhs = @{term Typerep} $ HOLogic.mk_literal tyco
haftmann@31137
    49
      $ HOLogic.mk_list @{typ typerep} (map (HOLogic.mk_typerep o TFree) vs);
haftmann@26168
    50
    val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));
haftmann@26168
    51
  in
haftmann@26168
    52
    thy
haftmann@28335
    53
    |> TheoryTarget.instantiation ([tyco], vs, @{sort typerep})
haftmann@26168
    54
    |> `(fn lthy => Syntax.check_term lthy eq)
haftmann@28965
    55
    |-> (fn eq => Specification.definition (NONE, (Attrib.empty_binding, eq)))
haftmann@26168
    56
    |> snd
haftmann@31137
    57
    |> Class.prove_instantiation_exit (K (Class.intro_classes_tac []))
haftmann@26168
    58
  end;
haftmann@26168
    59
haftmann@31137
    60
fun ensure_typerep tyco thy = if not (can (Sorts.mg_domain (Sign.classes_of thy) tyco) @{sort typerep})
haftmann@31137
    61
  andalso can (Sorts.mg_domain (Sign.classes_of thy) tyco) @{sort type}
haftmann@31137
    62
  then add_typerep tyco thy else thy;
haftmann@31137
    63
haftmann@31137
    64
in
haftmann@26168
    65
haftmann@31137
    66
add_typerep @{type_name fun}
haftmann@31723
    67
#> Typedef.interpretation ensure_typerep
haftmann@31137
    68
#> Code.type_interpretation (ensure_typerep o fst)
haftmann@26168
    69
haftmann@31137
    70
end
haftmann@26168
    71
*}
haftmann@26168
    72
haftmann@28562
    73
lemma [code]:
haftmann@28346
    74
  "eq_class.eq (Typerep tyco1 tys1) (Typerep tyco2 tys2) \<longleftrightarrow> eq_class.eq tyco1 tyco2
haftmann@28346
    75
     \<and> list_all2 eq_class.eq tys1 tys2"
haftmann@28346
    76
  by (auto simp add: equals_eq [symmetric] list_all2_eq [symmetric])
haftmann@26168
    77
haftmann@28335
    78
code_type typerep
haftmann@31031
    79
  (Eval "Term.typ")
haftmann@26168
    80
haftmann@28335
    81
code_const Typerep
haftmann@31031
    82
  (Eval "Term.Type/ (_, _)")
haftmann@26168
    83
haftmann@31031
    84
code_reserved Eval Term
haftmann@26168
    85
haftmann@28335
    86
hide (open) const typerep Typerep
haftmann@26168
    87
haftmann@26168
    88
end