src/HOL/Typerep.thy
author wenzelm
Sun Nov 02 18:21:45 2014 +0100 (2014-11-02)
changeset 58889 5b7a9633cfa8
parent 58662 5963cdbad926
child 59498 50b60f501b05
permissions -rw-r--r--
modernized header uniformly as section;
haftmann@31048
     1
(* Author: Florian Haftmann, TU Muenchen *)
haftmann@26168
     2
wenzelm@58889
     3
section {* Reflecting Pure types into HOL *}
haftmann@26168
     4
haftmann@28952
     5
theory Typerep
haftmann@51112
     6
imports String
haftmann@26168
     7
begin
haftmann@26168
     8
blanchet@58310
     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
wenzelm@35115
    20
syntax
wenzelm@35115
    21
  "_TYPEREP" :: "type => logic"  ("(1TYPEREP/(1'(_')))")
wenzelm@35115
    22
wenzelm@35115
    23
parse_translation {*
wenzelm@52143
    24
  let
wenzelm@52143
    25
    fun typerep_tr (*"_TYPEREP"*) [ty] =
wenzelm@52143
    26
          Syntax.const @{const_syntax typerep} $
wenzelm@56243
    27
            (Syntax.const @{syntax_const "_constrain"} $ Syntax.const @{const_syntax Pure.type} $
wenzelm@52143
    28
              (Syntax.const @{type_syntax itself} $ ty))
wenzelm@52143
    29
      | typerep_tr (*"_TYPEREP"*) ts = raise TERM ("typerep_tr", ts);
wenzelm@52143
    30
  in [(@{syntax_const "_TYPEREP"}, K typerep_tr)] end
wenzelm@35115
    31
*}
wenzelm@35115
    32
wenzelm@52143
    33
typed_print_translation {*
wenzelm@52143
    34
  let
wenzelm@52143
    35
    fun typerep_tr' ctxt (*"typerep"*)
wenzelm@52143
    36
            (Type (@{type_name fun}, [Type (@{type_name itself}, [T]), _]))
wenzelm@56243
    37
            (Const (@{const_syntax Pure.type}, _) :: ts) =
wenzelm@52143
    38
          Term.list_comb
wenzelm@52143
    39
            (Syntax.const @{syntax_const "_TYPEREP"} $ Syntax_Phases.term_of_typ ctxt T, ts)
wenzelm@52143
    40
      | typerep_tr' _ T ts = raise Match;
wenzelm@52143
    41
  in [(@{const_syntax typerep}, typerep_tr')] end
haftmann@26168
    42
*}
haftmann@26168
    43
haftmann@31137
    44
setup {*
haftmann@31137
    45
let
haftmann@26168
    46
haftmann@31137
    47
fun add_typerep tyco thy =
haftmann@26168
    48
  let
haftmann@28335
    49
    val sorts = replicate (Sign.arity_number thy tyco) @{sort typerep};
wenzelm@43329
    50
    val vs = Name.invent_names Name.context "'a" sorts;
haftmann@26168
    51
    val ty = Type (tyco, map TFree vs);
haftmann@28335
    52
    val lhs = Const (@{const_name typerep}, Term.itselfT ty --> @{typ typerep})
haftmann@26168
    53
      $ Free ("T", Term.itselfT ty);
haftmann@31205
    54
    val rhs = @{term Typerep} $ HOLogic.mk_literal tyco
haftmann@31137
    55
      $ HOLogic.mk_list @{typ typerep} (map (HOLogic.mk_typerep o TFree) vs);
haftmann@26168
    56
    val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));
haftmann@26168
    57
  in
haftmann@26168
    58
    thy
haftmann@38348
    59
    |> Class.instantiation ([tyco], vs, @{sort typerep})
haftmann@26168
    60
    |> `(fn lthy => Syntax.check_term lthy eq)
haftmann@28965
    61
    |-> (fn eq => Specification.definition (NONE, (Attrib.empty_binding, eq)))
haftmann@26168
    62
    |> snd
haftmann@31137
    63
    |> Class.prove_instantiation_exit (K (Class.intro_classes_tac []))
haftmann@26168
    64
  end;
haftmann@26168
    65
wenzelm@45693
    66
fun ensure_typerep tyco thy =
wenzelm@48272
    67
  if not (Sorts.has_instance (Sign.classes_of thy) tyco @{sort typerep})
wenzelm@48272
    68
    andalso Sorts.has_instance (Sign.classes_of thy) tyco @{sort type}
haftmann@31137
    69
  then add_typerep tyco thy else thy;
haftmann@31137
    70
haftmann@31137
    71
in
haftmann@26168
    72
haftmann@31137
    73
add_typerep @{type_name fun}
wenzelm@58662
    74
#> Typedef.interpretation (Local_Theory.background_theory o ensure_typerep)
haftmann@35299
    75
#> Code.datatype_interpretation (ensure_typerep o fst)
haftmann@35299
    76
#> Code.abstype_interpretation (ensure_typerep o fst)
haftmann@26168
    77
haftmann@31137
    78
end
haftmann@26168
    79
*}
haftmann@26168
    80
haftmann@28562
    81
lemma [code]:
haftmann@38857
    82
  "HOL.equal (Typerep tyco1 tys1) (Typerep tyco2 tys2) \<longleftrightarrow> HOL.equal tyco1 tyco2
haftmann@38857
    83
     \<and> list_all2 HOL.equal tys1 tys2"
haftmann@38857
    84
  by (auto simp add: eq_equal [symmetric] list_all2_eq [symmetric])
haftmann@38857
    85
haftmann@38857
    86
lemma [code nbe]:
haftmann@38857
    87
  "HOL.equal (x :: typerep) x \<longleftrightarrow> True"
haftmann@38857
    88
  by (fact equal_refl)
haftmann@26168
    89
haftmann@52435
    90
code_printing
haftmann@52435
    91
  type_constructor typerep \<rightharpoonup> (Eval) "Term.typ"
haftmann@52435
    92
| constant Typerep \<rightharpoonup> (Eval) "Term.Type/ (_, _)"
haftmann@26168
    93
haftmann@31031
    94
code_reserved Eval Term
haftmann@26168
    95
wenzelm@36176
    96
hide_const (open) typerep Typerep
haftmann@26168
    97
haftmann@26168
    98
end