Attic/Quot/quotient_def.ML
branchNominal2-Isabelle2013
changeset 3208 da575186d492
parent 3206 fb201e383f1b
child 3209 2fb0bc0dcbf1
equal deleted inserted replaced
3206:fb201e383f1b 3208:da575186d492
     1 (*  Title:      HOL/Tools/Quotient/quotient_def.thy
       
     2     Author:     Cezary Kaliszyk and Christian Urban
       
     3 
       
     4 Definitions for constants on quotient types.
       
     5 *)
       
     6 
       
     7 signature QUOTIENT_DEF =
       
     8 sig
       
     9   val quotient_def: (binding option * mixfix) * (Attrib.binding * (term * term)) ->
       
    10     local_theory -> (term * thm) * local_theory
       
    11 
       
    12   val quotdef_cmd: (binding option * mixfix) * (Attrib.binding * (string * string)) ->
       
    13     local_theory -> (term * thm) * local_theory
       
    14 
       
    15   val quotient_lift_const: string * term -> local_theory -> (term * thm) * local_theory
       
    16 end;
       
    17 
       
    18 structure Quotient_Def: QUOTIENT_DEF =
       
    19 struct
       
    20 
       
    21 open Quotient_Info;
       
    22 open Quotient_Term;
       
    23 
       
    24 (** Interface and Syntax Setup **)
       
    25 
       
    26 (* The ML-interface for a quotient definition takes
       
    27    as argument:
       
    28 
       
    29     - an optional binding and mixfix annotation
       
    30     - attributes
       
    31     - the new constant as term
       
    32     - the rhs of the definition as term
       
    33 
       
    34    It returns the defined constant and its definition
       
    35    theorem; stores the data in the qconsts data slot.
       
    36 
       
    37    Restriction: At the moment the right-hand side of the
       
    38    definition must be a constant. Similarly the left-hand 
       
    39    side must be a constant.
       
    40 *)
       
    41 fun error_msg bind str = 
       
    42 let 
       
    43   val name = Binding.name_of bind
       
    44   val pos = Position.str_of (Binding.pos_of bind)
       
    45 in
       
    46   error ("Head of quotient_definition " ^ 
       
    47     (quote str) ^ " differs from declaration " ^ name ^ pos)
       
    48 end
       
    49 
       
    50 fun quotient_def ((optbind, mx), (attr, (lhs, rhs))) lthy =
       
    51 let
       
    52   val (lhs_str, lhs_ty) = dest_Free lhs handle TERM _ => error "Constant already defined."
       
    53   val _ = if null (strip_abs_vars rhs) then () else error "The definiens cannot be an abstraction"
       
    54   
       
    55   fun sanity_test NONE _ = true
       
    56     | sanity_test (SOME bind) str =
       
    57         if Name.of_binding bind = str then true
       
    58         else error_msg bind str
       
    59 
       
    60   val _ = sanity_test optbind lhs_str
       
    61 
       
    62   val qconst_bname = Binding.name lhs_str
       
    63   val absrep_trm = absrep_fun AbsF lthy (fastype_of rhs, lhs_ty) $ rhs
       
    64   val prop = Logic.mk_equals (lhs, Syntax.check_term lthy absrep_trm)
       
    65   val (_, prop') = Local_Defs.cert_def lthy prop
       
    66   val (_, newrhs) = Primitive_Defs.abs_def prop'
       
    67 
       
    68   val ((trm, (_ , thm)), lthy') = Local_Theory.define ((qconst_bname, mx), (attr, newrhs)) lthy
       
    69 
       
    70   (* data storage *)
       
    71   fun qcinfo phi = transform_qconsts phi {qconst = trm, rconst = rhs, def = thm}
       
    72   fun trans_name phi = (fst o dest_Const o #qconst) (qcinfo phi)
       
    73   val lthy'' = Local_Theory.declaration true
       
    74                  (fn phi => qconsts_update_gen (trans_name phi) (qcinfo phi)) lthy'
       
    75 in
       
    76   ((trm, thm), lthy'')
       
    77 end
       
    78 
       
    79 fun quotdef_cmd (decl, (attr, (lhs_str, rhs_str))) lthy =
       
    80 let
       
    81   val lhs = Syntax.read_term lthy lhs_str
       
    82   val rhs = Syntax.read_term lthy rhs_str
       
    83   val lthy' = Variable.declare_term lhs lthy
       
    84   val lthy'' = Variable.declare_term rhs lthy'
       
    85 in
       
    86   quotient_def (decl, (attr, (lhs, rhs))) lthy''
       
    87 end
       
    88 
       
    89 fun quotient_lift_const (b, t) ctxt =
       
    90   quotient_def ((NONE, NoSyn), (Attrib.empty_binding,
       
    91     (Quotient_Term.quotient_lift_const (b, t) ctxt, t))) ctxt
       
    92 
       
    93 local
       
    94   structure P = OuterParse;
       
    95 in
       
    96 
       
    97 val quotdef_decl = (P.binding >> SOME) -- P.opt_mixfix' --| P.$$$ "where"
       
    98 
       
    99 val quotdef_parser =
       
   100   Scan.optional quotdef_decl (NONE, NoSyn) -- 
       
   101     P.!!! (SpecParse.opt_thm_name ":" -- (P.term --| P.$$$ "is" -- P.term))
       
   102 end
       
   103 
       
   104 val _ =
       
   105   OuterSyntax.local_theory "quotient_definition"
       
   106     "definition for constants over the quotient type"
       
   107       OuterKeyword.thy_decl (quotdef_parser >> (snd oo quotdef_cmd))
       
   108 
       
   109 end; (* structure *)