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