src/HOL/Tools/Quotient/quotient_info.ML
author wenzelm
Fri, 16 Mar 2012 21:59:19 +0100
changeset 47842 bdec4a6016c2
parent 47836 5c6955f487e5
child 47963 0516a6c1ea59
child 47981 29e92b644d6c
permissions -rw-r--r--
afford strict Args.type_name (cf. 29e88714ffe4);
haftmann@37743
     1
(*  Title:      HOL/Tools/Quotient/quotient_info.ML
kaliszyk@35222
     2
    Author:     Cezary Kaliszyk and Christian Urban
kaliszyk@35222
     3
wenzelm@46150
     4
Context data for the quotient package.
kaliszyk@35222
     5
*)
kaliszyk@35222
     6
kaliszyk@35222
     7
signature QUOTIENT_INFO =
kaliszyk@35222
     8
sig
kuncar@46673
     9
  type quotmaps = {relmap: string}
wenzelm@46151
    10
  val lookup_quotmaps: Proof.context -> string -> quotmaps option
wenzelm@46211
    11
  val lookup_quotmaps_global: theory -> string -> quotmaps option
wenzelm@46150
    12
  val print_quotmaps: Proof.context -> unit
kaliszyk@35222
    13
bulwahn@46405
    14
  type abs_rep = {abs : term, rep : term}
bulwahn@46405
    15
  val transform_abs_rep: morphism -> abs_rep -> abs_rep
bulwahn@46405
    16
  val lookup_abs_rep: Proof.context -> string -> abs_rep option
bulwahn@46405
    17
  val lookup_abs_rep_global: theory -> string -> abs_rep option
bulwahn@46405
    18
  val update_abs_rep: string -> abs_rep -> Context.generic -> Context.generic
bulwahn@46405
    19
  val print_abs_rep: Proof.context -> unit
bulwahn@46405
    20
  
wenzelm@46150
    21
  type quotients = {qtyp: typ, rtyp: typ, equiv_rel: term, equiv_thm: thm}
wenzelm@46150
    22
  val transform_quotients: morphism -> quotients -> quotients
wenzelm@46151
    23
  val lookup_quotients: Proof.context -> string -> quotients option
wenzelm@46211
    24
  val lookup_quotients_global: theory -> string -> quotients option
wenzelm@46150
    25
  val update_quotients: string -> quotients -> Context.generic -> Context.generic
wenzelm@46150
    26
  val dest_quotients: Proof.context -> quotients list
wenzelm@46150
    27
  val print_quotients: Proof.context -> unit
kaliszyk@35222
    28
wenzelm@46150
    29
  type quotconsts = {qconst: term, rconst: term, def: thm}
wenzelm@46150
    30
  val transform_quotconsts: morphism -> quotconsts -> quotconsts
wenzelm@46211
    31
  val lookup_quotconsts_global: theory -> term -> quotconsts option
wenzelm@46150
    32
  val update_quotconsts: string -> quotconsts -> Context.generic -> Context.generic
urbanc@46215
    33
  val dest_quotconsts_global: theory -> quotconsts list
wenzelm@46150
    34
  val dest_quotconsts: Proof.context -> quotconsts list
wenzelm@46150
    35
  val print_quotconsts: Proof.context -> unit
kaliszyk@35222
    36
wenzelm@46150
    37
  val equiv_rules: Proof.context -> thm list
kaliszyk@35222
    38
  val equiv_rules_add: attribute
wenzelm@46150
    39
  val rsp_rules: Proof.context -> thm list
kaliszyk@35314
    40
  val rsp_rules_add: attribute
wenzelm@46150
    41
  val prs_rules: Proof.context -> thm list
kaliszyk@35314
    42
  val prs_rules_add: attribute
wenzelm@46150
    43
  val id_simps: Proof.context -> thm list
wenzelm@46150
    44
  val quotient_rules: Proof.context -> thm list
kaliszyk@35222
    45
  val quotient_rules_add: attribute
wenzelm@41708
    46
  val setup: theory -> theory
kaliszyk@35222
    47
end;
kaliszyk@35222
    48
kaliszyk@35222
    49
structure Quotient_Info: QUOTIENT_INFO =
kaliszyk@35222
    50
struct
kaliszyk@35222
    51
kaliszyk@35222
    52
(** data containers **)
kaliszyk@35222
    53
wenzelm@41720
    54
(* FIXME just one data slot (record) per program unit *)
wenzelm@41720
    55
kaliszyk@35222
    56
(* info about map- and rel-functions for a type *)
kuncar@46673
    57
type quotmaps = {relmap: string}
kaliszyk@35222
    58
wenzelm@46151
    59
structure Quotmaps = Generic_Data
wenzelm@39034
    60
(
wenzelm@46150
    61
  type T = quotmaps Symtab.table
wenzelm@39034
    62
  val empty = Symtab.empty
wenzelm@39034
    63
  val extend = I
wenzelm@39034
    64
  fun merge data = Symtab.merge (K true) data
wenzelm@39034
    65
)
kaliszyk@35222
    66
wenzelm@46151
    67
val lookup_quotmaps = Symtab.lookup o Quotmaps.get o Context.Proof
wenzelm@46211
    68
val lookup_quotmaps_global = Symtab.lookup o Quotmaps.get o Context.Theory
kaliszyk@35222
    69
wenzelm@46152
    70
(* FIXME export proper internal update operation!? *)
kaliszyk@35222
    71
wenzelm@46152
    72
val quotmaps_attribute_setup =
wenzelm@46152
    73
  Attrib.setup @{binding map}
wenzelm@47842
    74
    ((Args.type_name true --| Scan.lift (@{keyword "="})) -- Args.const_proper true >>
kuncar@46673
    75
      (fn (tyname, relname) =>
kuncar@46673
    76
        let val minfo = {relmap = relname}
wenzelm@46152
    77
        in Thm.declaration_attribute (fn _ => Quotmaps.map (Symtab.update (tyname, minfo))) end))
wenzelm@46152
    78
    "declaration of map information"
kaliszyk@35222
    79
wenzelm@46150
    80
fun print_quotmaps ctxt =
wenzelm@41700
    81
  let
kuncar@46673
    82
    fun prt_map (ty_name, {relmap}) =
wenzelm@41701
    83
      Pretty.block (separate (Pretty.brk 2)
wenzelm@41700
    84
        (map Pretty.str
wenzelm@41701
    85
         ["type:", ty_name,
wenzelm@41700
    86
          "relation map:", relmap]))
wenzelm@41700
    87
  in
wenzelm@46151
    88
    map prt_map (Symtab.dest (Quotmaps.get (Context.Proof ctxt)))
wenzelm@41700
    89
    |> Pretty.big_list "maps for type constructors:"
wenzelm@41700
    90
    |> Pretty.writeln
wenzelm@41700
    91
  end
kaliszyk@35222
    92
bulwahn@46405
    93
(* info about abs/rep terms *)
bulwahn@46405
    94
type abs_rep = {abs : term, rep : term}
bulwahn@46405
    95
bulwahn@46405
    96
structure Abs_Rep = Generic_Data
bulwahn@46405
    97
(
bulwahn@46405
    98
  type T = abs_rep Symtab.table
bulwahn@46405
    99
  val empty = Symtab.empty
bulwahn@46405
   100
  val extend = I
bulwahn@46405
   101
  fun merge data = Symtab.merge (K true) data
bulwahn@46405
   102
)
bulwahn@46405
   103
bulwahn@46405
   104
fun transform_abs_rep phi {abs, rep} = {abs = Morphism.term phi abs, rep = Morphism.term phi rep}
bulwahn@46405
   105
bulwahn@46405
   106
val lookup_abs_rep = Symtab.lookup o Abs_Rep.get o Context.Proof
bulwahn@46405
   107
val lookup_abs_rep_global = Symtab.lookup o Abs_Rep.get o Context.Theory
bulwahn@46405
   108
bulwahn@46405
   109
fun update_abs_rep str data = Abs_Rep.map (Symtab.update (str, data))
bulwahn@46405
   110
bulwahn@46405
   111
fun print_abs_rep ctxt =
bulwahn@46405
   112
  let
bulwahn@46405
   113
    fun prt_abs_rep (s, {abs, rep}) =
bulwahn@46405
   114
      Pretty.block (separate (Pretty.brk 2)
bulwahn@46405
   115
       [Pretty.str "type constructor:",
bulwahn@46405
   116
        Pretty.str s,
bulwahn@46405
   117
        Pretty.str "abs term:",
bulwahn@46405
   118
        Syntax.pretty_term ctxt abs,
bulwahn@46405
   119
        Pretty.str "rep term:",
bulwahn@46405
   120
        Syntax.pretty_term ctxt rep])
bulwahn@46405
   121
  in
bulwahn@46405
   122
    map prt_abs_rep (Symtab.dest (Abs_Rep.get (Context.Proof ctxt)))
bulwahn@46405
   123
    |> Pretty.big_list "abs/rep terms:"
bulwahn@46405
   124
    |> Pretty.writeln
bulwahn@46405
   125
  end
kaliszyk@35222
   126
kaliszyk@35222
   127
(* info about quotient types *)
wenzelm@46150
   128
type quotients = {qtyp: typ, rtyp: typ, equiv_rel: term, equiv_thm: thm}
kaliszyk@35222
   129
wenzelm@46151
   130
structure Quotients = Generic_Data
wenzelm@39034
   131
(
wenzelm@46150
   132
  type T = quotients Symtab.table
wenzelm@39034
   133
  val empty = Symtab.empty
wenzelm@39034
   134
  val extend = I
wenzelm@39034
   135
  fun merge data = Symtab.merge (K true) data
wenzelm@39034
   136
)
kaliszyk@35222
   137
wenzelm@46150
   138
fun transform_quotients phi {qtyp, rtyp, equiv_rel, equiv_thm} =
kaliszyk@35222
   139
  {qtyp = Morphism.typ phi qtyp,
kaliszyk@35222
   140
   rtyp = Morphism.typ phi rtyp,
kaliszyk@35222
   141
   equiv_rel = Morphism.term phi equiv_rel,
kaliszyk@35222
   142
   equiv_thm = Morphism.thm phi equiv_thm}
kaliszyk@35222
   143
wenzelm@46151
   144
val lookup_quotients = Symtab.lookup o Quotients.get o Context.Proof
wenzelm@46211
   145
val lookup_quotients_global = Symtab.lookup o Quotients.get o Context.Theory
kaliszyk@35222
   146
wenzelm@46151
   147
fun update_quotients str qinfo = Quotients.map (Symtab.update (str, qinfo))
kaliszyk@35222
   148
wenzelm@46151
   149
fun dest_quotients ctxt =  (* FIXME slightly expensive way to retrieve data *)
wenzelm@46151
   150
  map snd (Symtab.dest (Quotients.get (Context.Proof ctxt)))
kaliszyk@35222
   151
wenzelm@46150
   152
fun print_quotients ctxt =
wenzelm@41700
   153
  let
wenzelm@41700
   154
    fun prt_quot {qtyp, rtyp, equiv_rel, equiv_thm} =
wenzelm@41701
   155
      Pretty.block (separate (Pretty.brk 2)
wenzelm@41700
   156
       [Pretty.str "quotient type:",
wenzelm@41700
   157
        Syntax.pretty_typ ctxt qtyp,
wenzelm@41700
   158
        Pretty.str "raw type:",
wenzelm@41700
   159
        Syntax.pretty_typ ctxt rtyp,
wenzelm@41700
   160
        Pretty.str "relation:",
wenzelm@41700
   161
        Syntax.pretty_term ctxt equiv_rel,
wenzelm@41700
   162
        Pretty.str "equiv. thm:",
wenzelm@41700
   163
        Syntax.pretty_term ctxt (prop_of equiv_thm)])
wenzelm@41700
   164
  in
wenzelm@46151
   165
    map (prt_quot o snd) (Symtab.dest (Quotients.get (Context.Proof ctxt)))
wenzelm@41700
   166
    |> Pretty.big_list "quotients:"
wenzelm@41700
   167
    |> Pretty.writeln
wenzelm@41700
   168
  end
kaliszyk@35222
   169
kaliszyk@35222
   170
kaliszyk@35222
   171
(* info about quotient constants *)
wenzelm@46150
   172
type quotconsts = {qconst: term, rconst: term, def: thm}
kaliszyk@35222
   173
wenzelm@46150
   174
fun eq_quotconsts (x : quotconsts, y : quotconsts) = #qconst x = #qconst y
kaliszyk@35222
   175
kaliszyk@35222
   176
(* We need to be able to lookup instances of lifted constants,
kaliszyk@35222
   177
   for example given "nat fset" we need to find "'a fset";
kaliszyk@35222
   178
   but overloaded constants share the same name *)
wenzelm@46151
   179
structure Quotconsts = Generic_Data
wenzelm@39034
   180
(
wenzelm@46150
   181
  type T = quotconsts list Symtab.table
wenzelm@39034
   182
  val empty = Symtab.empty
wenzelm@39034
   183
  val extend = I
wenzelm@46150
   184
  val merge = Symtab.merge_list eq_quotconsts
wenzelm@39034
   185
)
kaliszyk@35222
   186
wenzelm@46150
   187
fun transform_quotconsts phi {qconst, rconst, def} =
kaliszyk@35222
   188
  {qconst = Morphism.term phi qconst,
kaliszyk@35222
   189
   rconst = Morphism.term phi rconst,
kaliszyk@35222
   190
   def = Morphism.thm phi def}
kaliszyk@35222
   191
wenzelm@46151
   192
fun update_quotconsts name qcinfo = Quotconsts.map (Symtab.cons_list (name, qcinfo))
kaliszyk@35222
   193
wenzelm@46151
   194
fun dest_quotconsts ctxt =
wenzelm@46151
   195
  flat (map snd (Symtab.dest (Quotconsts.get (Context.Proof ctxt))))
kaliszyk@35222
   196
urbanc@46215
   197
fun dest_quotconsts_global thy =
urbanc@46215
   198
  flat (map snd (Symtab.dest (Quotconsts.get (Context.Theory thy))))
urbanc@46215
   199
urbanc@46215
   200
urbanc@46215
   201
wenzelm@46211
   202
fun lookup_quotconsts_global thy t =
kaliszyk@35222
   203
  let
kaliszyk@35222
   204
    val (name, qty) = dest_Const t
wenzelm@46150
   205
    fun matches (x: quotconsts) =
wenzelm@46151
   206
      let val (name', qty') = dest_Const (#qconst x);
wenzelm@46151
   207
      in name = name' andalso Sign.typ_instance thy (qty, qty') end
kaliszyk@35222
   208
  in
wenzelm@46211
   209
    (case Symtab.lookup (Quotconsts.get (Context.Theory thy)) name of
bulwahn@46145
   210
      NONE => NONE
bulwahn@46145
   211
    | SOME l => find_first matches l)
kaliszyk@35222
   212
  end
kaliszyk@35222
   213
wenzelm@46150
   214
fun print_quotconsts ctxt =
wenzelm@41700
   215
  let
wenzelm@41700
   216
    fun prt_qconst {qconst, rconst, def} =
wenzelm@41700
   217
      Pretty.block (separate (Pretty.brk 1)
wenzelm@41700
   218
       [Syntax.pretty_term ctxt qconst,
wenzelm@41700
   219
        Pretty.str ":=",
wenzelm@41700
   220
        Syntax.pretty_term ctxt rconst,
wenzelm@41700
   221
        Pretty.str "as",
wenzelm@41700
   222
        Syntax.pretty_term ctxt (prop_of def)])
wenzelm@41700
   223
  in
wenzelm@46151
   224
    map prt_qconst (maps snd (Symtab.dest (Quotconsts.get (Context.Proof ctxt))))
wenzelm@41700
   225
    |> Pretty.big_list "quotient constants:"
wenzelm@41700
   226
    |> Pretty.writeln
wenzelm@41700
   227
  end
kaliszyk@35222
   228
kaliszyk@35222
   229
(* equivalence relation theorems *)
wenzelm@46150
   230
structure Equiv_Rules = Named_Thms
wenzelm@39039
   231
(
wenzelm@46165
   232
  val name = @{binding quot_equiv}
wenzelm@39039
   233
  val description = "equivalence relation theorems"
wenzelm@39039
   234
)
kaliszyk@35222
   235
wenzelm@46150
   236
val equiv_rules = Equiv_Rules.get
wenzelm@46150
   237
val equiv_rules_add = Equiv_Rules.add
kaliszyk@35222
   238
kaliszyk@35222
   239
(* respectfulness theorems *)
wenzelm@46150
   240
structure Rsp_Rules = Named_Thms
wenzelm@39039
   241
(
wenzelm@46165
   242
  val name = @{binding quot_respect}
wenzelm@39039
   243
  val description = "respectfulness theorems"
wenzelm@39039
   244
)
kaliszyk@35222
   245
wenzelm@46150
   246
val rsp_rules = Rsp_Rules.get
wenzelm@46150
   247
val rsp_rules_add = Rsp_Rules.add
kaliszyk@35222
   248
kaliszyk@35222
   249
(* preservation theorems *)
wenzelm@46150
   250
structure Prs_Rules = Named_Thms
wenzelm@39039
   251
(
wenzelm@46165
   252
  val name = @{binding quot_preserve}
wenzelm@39039
   253
  val description = "preservation theorems"
wenzelm@39039
   254
)
kaliszyk@35222
   255
wenzelm@46150
   256
val prs_rules = Prs_Rules.get
wenzelm@46150
   257
val prs_rules_add = Prs_Rules.add
kaliszyk@35222
   258
kaliszyk@35222
   259
(* id simplification theorems *)
wenzelm@46150
   260
structure Id_Simps = Named_Thms
wenzelm@39039
   261
(
wenzelm@46165
   262
  val name = @{binding id_simps}
wenzelm@39039
   263
  val description = "identity simp rules for maps"
wenzelm@39039
   264
)
kaliszyk@35222
   265
wenzelm@46150
   266
val id_simps = Id_Simps.get
kaliszyk@35222
   267
kaliszyk@35222
   268
(* quotient theorems *)
wenzelm@46150
   269
structure Quotient_Rules = Named_Thms
wenzelm@39039
   270
(
wenzelm@46165
   271
  val name = @{binding quot_thm}
wenzelm@39039
   272
  val description = "quotient theorems"
wenzelm@39039
   273
)
kaliszyk@35222
   274
wenzelm@46150
   275
val quotient_rules = Quotient_Rules.get
wenzelm@46150
   276
val quotient_rules_add = Quotient_Rules.add
kaliszyk@35222
   277
kaliszyk@35222
   278
wenzelm@41708
   279
(* theory setup *)
kaliszyk@35222
   280
wenzelm@41708
   281
val setup =
wenzelm@46152
   282
  quotmaps_attribute_setup #>
wenzelm@46150
   283
  Equiv_Rules.setup #>
wenzelm@46150
   284
  Rsp_Rules.setup #>
wenzelm@46150
   285
  Prs_Rules.setup #>
wenzelm@46150
   286
  Id_Simps.setup #>
wenzelm@46150
   287
  Quotient_Rules.setup
kaliszyk@35222
   288
kaliszyk@35222
   289
wenzelm@41708
   290
(* outer syntax commands *)
wenzelm@41708
   291
wenzelm@41708
   292
val _ =
wenzelm@47836
   293
  Outer_Syntax.improper_command @{command_spec "print_quotmaps"} "print quotient map functions"
wenzelm@46150
   294
    (Scan.succeed (Toplevel.keep (print_quotmaps o Toplevel.context_of)))
wenzelm@41708
   295
wenzelm@41708
   296
val _ =
wenzelm@47836
   297
  Outer_Syntax.improper_command @{command_spec "print_quotients"} "print quotients"
wenzelm@46150
   298
    (Scan.succeed (Toplevel.keep (print_quotients o Toplevel.context_of)))
wenzelm@41708
   299
wenzelm@41708
   300
val _ =
wenzelm@47836
   301
  Outer_Syntax.improper_command @{command_spec "print_quotconsts"} "print quotient constants"
wenzelm@46150
   302
    (Scan.succeed (Toplevel.keep (print_quotconsts o Toplevel.context_of)))
kaliszyk@35222
   303
wenzelm@46150
   304
end;