src/HOL/Tools/Quotient/quotient_info.ML
changeset 45280 9fd6fce8a230
parent 45279 89a17197cb98
child 45281 29e88714ffe4
equal deleted inserted replaced
45279:89a17197cb98 45280:9fd6fce8a230
     5 *)
     5 *)
     6 
     6 
     7 signature QUOTIENT_INFO =
     7 signature QUOTIENT_INFO =
     8 sig
     8 sig
     9   type quotmaps = {mapfun: string, relmap: string}
     9   type quotmaps = {mapfun: string, relmap: string}
    10   val lookup_quotmaps: theory -> string -> quotmaps option
    10   val lookup_quotmaps: Proof.context -> string -> quotmaps option
    11   val update_quotmaps_global: string -> quotmaps -> theory -> theory
       
    12   val update_quotmaps: string -> quotmaps -> Proof.context -> Proof.context
       
    13   val print_quotmaps: Proof.context -> unit
    11   val print_quotmaps: Proof.context -> unit
    14 
    12 
    15   type quotients = {qtyp: typ, rtyp: typ, equiv_rel: term, equiv_thm: thm}
    13   type quotients = {qtyp: typ, rtyp: typ, equiv_rel: term, equiv_thm: thm}
    16   val transform_quotients: morphism -> quotients -> quotients
    14   val transform_quotients: morphism -> quotients -> quotients
    17   val lookup_quotients: theory -> string -> quotients option
    15   val lookup_quotients: Proof.context -> string -> quotients option
    18   val update_quotients_global: string -> quotients -> theory -> theory
       
    19   val update_quotients: string -> quotients -> Context.generic -> Context.generic
    16   val update_quotients: string -> quotients -> Context.generic -> Context.generic
    20   val dest_quotients: Proof.context -> quotients list
    17   val dest_quotients: Proof.context -> quotients list
    21   val print_quotients: Proof.context -> unit
    18   val print_quotients: Proof.context -> unit
    22 
    19 
    23   type quotconsts = {qconst: term, rconst: term, def: thm}
    20   type quotconsts = {qconst: term, rconst: term, def: thm}
    24   val transform_quotconsts: morphism -> quotconsts -> quotconsts
    21   val transform_quotconsts: morphism -> quotconsts -> quotconsts
    25   val lookup_quotconsts: theory -> term -> quotconsts option
    22   val lookup_quotconsts: Proof.context -> term -> quotconsts option
    26   val update_quotconsts_global: string -> quotconsts -> theory -> theory
       
    27   val update_quotconsts: string -> quotconsts -> Context.generic -> Context.generic
    23   val update_quotconsts: string -> quotconsts -> Context.generic -> Context.generic
    28   val dest_quotconsts: Proof.context -> quotconsts list
    24   val dest_quotconsts: Proof.context -> quotconsts list
    29   val print_quotconsts: Proof.context -> unit
    25   val print_quotconsts: Proof.context -> unit
    30 
    26 
    31   val equiv_rules: Proof.context -> thm list
    27   val equiv_rules: Proof.context -> thm list
    48 (* FIXME just one data slot (record) per program unit *)
    44 (* FIXME just one data slot (record) per program unit *)
    49 
    45 
    50 (* info about map- and rel-functions for a type *)
    46 (* info about map- and rel-functions for a type *)
    51 type quotmaps = {mapfun: string, relmap: string}
    47 type quotmaps = {mapfun: string, relmap: string}
    52 
    48 
    53 structure Quotmaps = Theory_Data
    49 structure Quotmaps = Generic_Data
    54 (
    50 (
    55   type T = quotmaps Symtab.table
    51   type T = quotmaps Symtab.table
    56   val empty = Symtab.empty
    52   val empty = Symtab.empty
    57   val extend = I
    53   val extend = I
    58   fun merge data = Symtab.merge (K true) data
    54   fun merge data = Symtab.merge (K true) data
    59 )
    55 )
    60 
    56 
    61 val lookup_quotmaps = Symtab.lookup o Quotmaps.get
    57 val lookup_quotmaps = Symtab.lookup o Quotmaps.get o Context.Proof
    62 
    58 
    63 fun update_quotmaps_global k minfo = Quotmaps.map (Symtab.update (k, minfo))
    59 fun quotmaps_attribute (ctxt, (tystr, (mapstr, relstr))) =
    64 fun update_quotmaps k minfo = Proof_Context.background_theory (update_quotmaps_global k minfo)  (* FIXME !? *)
    60   let
    65 
    61     val thy = Proof_Context.theory_of ctxt  (* FIXME proper local context *)
    66 fun maps_attribute_aux s minfo = Thm.declaration_attribute
    62     val tyname = Sign.intern_type thy tystr  (* FIXME pass proper internal names via syntax *)
    67   (fn _ => Context.mapping (update_quotmaps_global s minfo) (update_quotmaps s minfo))
       
    68 
       
    69 (* attribute to be used in declare statements *)
       
    70 fun maps_attribute (ctxt, (tystr, (mapstr, relstr))) =
       
    71   let
       
    72     val thy = Proof_Context.theory_of ctxt
       
    73     val tyname = Sign.intern_type thy tystr  (* FIXME pass proper internal names *)
       
    74     val mapname = Sign.intern_const thy mapstr
    63     val mapname = Sign.intern_const thy mapstr
    75     val relname = Sign.intern_const thy relstr
    64     val relname = Sign.intern_const thy relstr
    76 
    65 
    77     fun sanity_check s = (Const (s, dummyT) |> Syntax.check_term ctxt; ())
    66     fun sanity_check s = (Const (s, dummyT) |> Syntax.check_term ctxt; ())
    78     val _ = List.app sanity_check [mapname, relname]
    67     val _ = List.app sanity_check [mapname, relname]
    79   in
    68     val minfo = {mapfun = mapname, relmap = relname}
    80     maps_attribute_aux tyname {mapfun = mapname, relmap = relname}
    69   in
    81   end
    70     Thm.declaration_attribute (fn _ => Quotmaps.map (Symtab.update (tyname, minfo)))
    82 
    71   end
    83 val maps_attr_parser =
    72 
       
    73 val quotmaps_attr_parser =
    84   Args.context -- Scan.lift
    74   Args.context -- Scan.lift
    85     ((Args.name --| Parse.$$$ "=") --
    75     ((Args.name --| Parse.$$$ "=") --
    86       (Parse.$$$ "(" |-- Args.name --| Parse.$$$ "," --
    76       (Parse.$$$ "(" |-- Args.name --| Parse.$$$ "," --
    87         Args.name --| Parse.$$$ ")"))
    77         Args.name --| Parse.$$$ ")"))
    88 
    78 
    93         (map Pretty.str
    83         (map Pretty.str
    94          ["type:", ty_name,
    84          ["type:", ty_name,
    95           "map:", mapfun,
    85           "map:", mapfun,
    96           "relation map:", relmap]))
    86           "relation map:", relmap]))
    97   in
    87   in
    98     Quotmaps.get (Proof_Context.theory_of ctxt)
    88     map prt_map (Symtab.dest (Quotmaps.get (Context.Proof ctxt)))
    99     |> Symtab.dest
       
   100     |> map (prt_map)
       
   101     |> Pretty.big_list "maps for type constructors:"
    89     |> Pretty.big_list "maps for type constructors:"
   102     |> Pretty.writeln
    90     |> Pretty.writeln
   103   end
    91   end
   104 
    92 
   105 
    93 
   106 (* info about quotient types *)
    94 (* info about quotient types *)
   107 type quotients = {qtyp: typ, rtyp: typ, equiv_rel: term, equiv_thm: thm}
    95 type quotients = {qtyp: typ, rtyp: typ, equiv_rel: term, equiv_thm: thm}
   108 
    96 
   109 structure Quotients = Theory_Data
    97 structure Quotients = Generic_Data
   110 (
    98 (
   111   type T = quotients Symtab.table
    99   type T = quotients Symtab.table
   112   val empty = Symtab.empty
   100   val empty = Symtab.empty
   113   val extend = I
   101   val extend = I
   114   fun merge data = Symtab.merge (K true) data
   102   fun merge data = Symtab.merge (K true) data
   118   {qtyp = Morphism.typ phi qtyp,
   106   {qtyp = Morphism.typ phi qtyp,
   119    rtyp = Morphism.typ phi rtyp,
   107    rtyp = Morphism.typ phi rtyp,
   120    equiv_rel = Morphism.term phi equiv_rel,
   108    equiv_rel = Morphism.term phi equiv_rel,
   121    equiv_thm = Morphism.thm phi equiv_thm}
   109    equiv_thm = Morphism.thm phi equiv_thm}
   122 
   110 
   123 val lookup_quotients = Symtab.lookup o Quotients.get
   111 val lookup_quotients = Symtab.lookup o Quotients.get o Context.Proof
   124 
   112 
   125 fun update_quotients_global str qinfo = Quotients.map (Symtab.update (str, qinfo))
   113 fun update_quotients str qinfo = Quotients.map (Symtab.update (str, qinfo))
   126 fun update_quotients str qinfo = Context.mapping (update_quotients_global str qinfo) I  (* FIXME !? *)
   114 
   127 
   115 fun dest_quotients ctxt =  (* FIXME slightly expensive way to retrieve data *)
   128 fun dest_quotients lthy =  (* FIXME slightly expensive way to retrieve data *)
   116   map snd (Symtab.dest (Quotients.get (Context.Proof ctxt)))
   129   map snd (Symtab.dest (Quotients.get (Proof_Context.theory_of lthy)))  (* FIXME !? *)
       
   130 
   117 
   131 fun print_quotients ctxt =
   118 fun print_quotients ctxt =
   132   let
   119   let
   133     fun prt_quot {qtyp, rtyp, equiv_rel, equiv_thm} =
   120     fun prt_quot {qtyp, rtyp, equiv_rel, equiv_thm} =
   134       Pretty.block (separate (Pretty.brk 2)
   121       Pretty.block (separate (Pretty.brk 2)
   139         Pretty.str "relation:",
   126         Pretty.str "relation:",
   140         Syntax.pretty_term ctxt equiv_rel,
   127         Syntax.pretty_term ctxt equiv_rel,
   141         Pretty.str "equiv. thm:",
   128         Pretty.str "equiv. thm:",
   142         Syntax.pretty_term ctxt (prop_of equiv_thm)])
   129         Syntax.pretty_term ctxt (prop_of equiv_thm)])
   143   in
   130   in
   144     Quotients.get (Proof_Context.theory_of ctxt)
   131     map (prt_quot o snd) (Symtab.dest (Quotients.get (Context.Proof ctxt)))
   145     |> Symtab.dest
       
   146     |> map (prt_quot o snd)
       
   147     |> Pretty.big_list "quotients:"
   132     |> Pretty.big_list "quotients:"
   148     |> Pretty.writeln
   133     |> Pretty.writeln
   149   end
   134   end
   150 
   135 
   151 
   136 
   155 fun eq_quotconsts (x : quotconsts, y : quotconsts) = #qconst x = #qconst y
   140 fun eq_quotconsts (x : quotconsts, y : quotconsts) = #qconst x = #qconst y
   156 
   141 
   157 (* We need to be able to lookup instances of lifted constants,
   142 (* We need to be able to lookup instances of lifted constants,
   158    for example given "nat fset" we need to find "'a fset";
   143    for example given "nat fset" we need to find "'a fset";
   159    but overloaded constants share the same name *)
   144    but overloaded constants share the same name *)
   160 structure Quotconsts = Theory_Data
   145 structure Quotconsts = Generic_Data
   161 (
   146 (
   162   type T = quotconsts list Symtab.table
   147   type T = quotconsts list Symtab.table
   163   val empty = Symtab.empty
   148   val empty = Symtab.empty
   164   val extend = I
   149   val extend = I
   165   val merge = Symtab.merge_list eq_quotconsts
   150   val merge = Symtab.merge_list eq_quotconsts
   168 fun transform_quotconsts phi {qconst, rconst, def} =
   153 fun transform_quotconsts phi {qconst, rconst, def} =
   169   {qconst = Morphism.term phi qconst,
   154   {qconst = Morphism.term phi qconst,
   170    rconst = Morphism.term phi rconst,
   155    rconst = Morphism.term phi rconst,
   171    def = Morphism.thm phi def}
   156    def = Morphism.thm phi def}
   172 
   157 
   173 fun update_quotconsts_global name qcinfo = Quotconsts.map (Symtab.cons_list (name, qcinfo))
   158 fun update_quotconsts name qcinfo = Quotconsts.map (Symtab.cons_list (name, qcinfo))
   174 fun update_quotconsts name qcinfo = Context.mapping (update_quotconsts_global name qcinfo) I  (* FIXME !? *)
   159 
   175 
   160 fun dest_quotconsts ctxt =
   176 fun dest_quotconsts lthy =
   161   flat (map snd (Symtab.dest (Quotconsts.get (Context.Proof ctxt))))
   177   flat (map snd (Symtab.dest (Quotconsts.get (Proof_Context.theory_of lthy))))  (* FIXME !? *)
   162 
   178 
   163 fun lookup_quotconsts ctxt t =
   179 fun lookup_quotconsts thy t =
   164   let
   180   let
   165     val thy = Proof_Context.theory_of ctxt
       
   166 
   181     val (name, qty) = dest_Const t
   167     val (name, qty) = dest_Const t
   182     fun matches (x: quotconsts) =
   168     fun matches (x: quotconsts) =
   183       let
   169       let val (name', qty') = dest_Const (#qconst x);
   184         val (name', qty') = dest_Const (#qconst x);
   170       in name = name' andalso Sign.typ_instance thy (qty, qty') end
   185       in
   171   in
   186         name = name' andalso Sign.typ_instance thy (qty, qty')
   172     (case Symtab.lookup (Quotconsts.get (Context.Proof ctxt)) name of
   187       end
       
   188   in
       
   189     (case Symtab.lookup (Quotconsts.get thy) name of
       
   190       NONE => NONE
   173       NONE => NONE
   191     | SOME l => find_first matches l)
   174     | SOME l => find_first matches l)
   192   end
   175   end
   193 
   176 
   194 fun print_quotconsts ctxt =
   177 fun print_quotconsts ctxt =
   199         Pretty.str ":=",
   182         Pretty.str ":=",
   200         Syntax.pretty_term ctxt rconst,
   183         Syntax.pretty_term ctxt rconst,
   201         Pretty.str "as",
   184         Pretty.str "as",
   202         Syntax.pretty_term ctxt (prop_of def)])
   185         Syntax.pretty_term ctxt (prop_of def)])
   203   in
   186   in
   204     Quotconsts.get (Proof_Context.theory_of ctxt)
   187     map prt_qconst (maps snd (Symtab.dest (Quotconsts.get (Context.Proof ctxt))))
   205     |> Symtab.dest
       
   206     |> map snd
       
   207     |> flat
       
   208     |> map prt_qconst
       
   209     |> Pretty.big_list "quotient constants:"
   188     |> Pretty.big_list "quotient constants:"
   210     |> Pretty.writeln
   189     |> Pretty.writeln
   211   end
   190   end
   212 
   191 
   213 (* equivalence relation theorems *)
   192 (* equivalence relation theorems *)
   261 
   240 
   262 
   241 
   263 (* theory setup *)
   242 (* theory setup *)
   264 
   243 
   265 val setup =
   244 val setup =
   266   Attrib.setup @{binding map} (maps_attr_parser >> maps_attribute)
   245   Attrib.setup @{binding map} (quotmaps_attr_parser >> quotmaps_attribute)
   267     "declaration of map information" #>
   246     "declaration of map information" #>
   268   Equiv_Rules.setup #>
   247   Equiv_Rules.setup #>
   269   Rsp_Rules.setup #>
   248   Rsp_Rules.setup #>
   270   Prs_Rules.setup #>
   249   Prs_Rules.setup #>
   271   Id_Simps.setup #>
   250   Id_Simps.setup #>
   284 
   263 
   285 val _ =
   264 val _ =
   286   Outer_Syntax.improper_command "print_quotconsts" "print quotient constants" Keyword.diag
   265   Outer_Syntax.improper_command "print_quotconsts" "print quotient constants" Keyword.diag
   287     (Scan.succeed (Toplevel.keep (print_quotconsts o Toplevel.context_of)))
   266     (Scan.succeed (Toplevel.keep (print_quotconsts o Toplevel.context_of)))
   288 
   267 
   289 
       
   290 end;
   268 end;