Quot/quotient_typ.ML
changeset 1128 17ca92ab4660
parent 1124 4a4c714ff795
child 1152 fbaebf08c1bd
equal deleted inserted replaced
1127:243a5ceaa088 1128:17ca92ab4660
     5 
     5 
     6 *)
     6 *)
     7 
     7 
     8 signature QUOTIENT_TYPE =
     8 signature QUOTIENT_TYPE =
     9 sig
     9 sig
    10   val quotient_type: ((string list * binding * mixfix) * (typ * term)) list 
    10   val quotient_type: ((string list * binding * mixfix) * (typ * term)) list
    11     -> Proof.context -> Proof.state
    11     -> Proof.context -> Proof.state
    12 
    12 
    13   val quotient_type_cmd: ((((string list * binding) * mixfix) * string) * string) list 
    13   val quotient_type_cmd: ((((string list * binding) * mixfix) * string) * string) list
    14     -> Proof.context -> Proof.state
    14     -> Proof.context -> Proof.state
    15 end;
    15 end;
    16 
    16 
    17 structure Quotient_Type: QUOTIENT_TYPE =
    17 structure Quotient_Type: QUOTIENT_TYPE =
    18 struct
    18 struct
    39 
    39 
    40 fun theorem after_qed goals ctxt =
    40 fun theorem after_qed goals ctxt =
    41 let
    41 let
    42   val goals' = map (rpair []) goals
    42   val goals' = map (rpair []) goals
    43   fun after_qed' thms = after_qed (the_single thms)
    43   fun after_qed' thms = after_qed (the_single thms)
    44 in 
    44 in
    45   Proof.theorem_i NONE after_qed' [goals'] ctxt
    45   Proof.theorem_i NONE after_qed' [goals'] ctxt
    46 end
    46 end
    47 
    47 
    48 
    48 
    49 
    49 
   153   val ((rep, rep_def), lthy3) = define (rep_name, NoSyn, rep_trm) lthy2
   153   val ((rep, rep_def), lthy3) = define (rep_name, NoSyn, rep_trm) lthy2
   154 
   154 
   155   (* quot_type theorem *)
   155   (* quot_type theorem *)
   156   val quot_thm = typedef_quot_type_thm (rel, Abs_const, Rep_const, equiv_thm, typedef_info) lthy3
   156   val quot_thm = typedef_quot_type_thm (rel, Abs_const, Rep_const, equiv_thm, typedef_info) lthy3
   157 
   157 
   158   (* quotient theorem *)  
   158   (* quotient theorem *)
   159   val quotient_thm = typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_thm) lthy3
   159   val quotient_thm = typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_thm) lthy3
   160   val quotient_thm_name = Binding.prefix_name "Quotient_" qty_name
   160   val quotient_thm_name = Binding.prefix_name "Quotient_" qty_name
   161 
   161 
   162   (* name equivalence theorem *)
   162   (* name equivalence theorem *)
   163   val equiv_thm_name = Binding.suffix_name "_equivp" qty_name
   163   val equiv_thm_name = Binding.suffix_name "_equivp" qty_name
   187   val illegal_rel_vars =
   187   val illegal_rel_vars =
   188     if null rel_vars andalso null rel_tvars then []
   188     if null rel_vars andalso null rel_tvars then []
   189     else [qty_str ^ "illegal schematic variable(s) in the relation."]
   189     else [qty_str ^ "illegal schematic variable(s) in the relation."]
   190 
   190 
   191   val dup_vs =
   191   val dup_vs =
   192     (case duplicates (op =) vs of 
   192     (case duplicates (op =) vs of
   193        [] => []
   193        [] => []
   194      | dups => [qty_str ^ "duplicate type variable(s) on the lhs: " ^ commas_quote dups])
   194      | dups => [qty_str ^ "duplicate type variable(s) on the lhs: " ^ commas_quote dups])
   195 
   195 
   196   val extra_rty_tfrees =
   196   val extra_rty_tfrees =
   197     (case subtract (op =) vs rty_tfreesT of 
   197     (case subtract (op =) vs rty_tfreesT of
   198        [] => []
   198        [] => []
   199      | extras => [qty_str ^ "extra type variable(s) on the lhs: " ^ commas_quote extras])
   199      | extras => [qty_str ^ "extra type variable(s) on the lhs: " ^ commas_quote extras])
   200 
   200 
   201   val extra_rel_tfrees =
   201   val extra_rel_tfrees =
   202     (case subtract (op =) vs rel_tfrees of 
   202     (case subtract (op =) vs rel_tfrees of
   203        [] => []
   203        [] => []
   204      | extras => [qty_str ^ "extra type variable(s) in the relation: " ^ commas_quote extras])
   204      | extras => [qty_str ^ "extra type variable(s) in the relation: " ^ commas_quote extras])
   205  
   205 
   206   val illegal_rel_frees =
   206   val illegal_rel_frees =
   207     (case rel_frees of 
   207     (case rel_frees of
   208       [] => []
   208       [] => []
   209     | xs => [qty_str ^ "illegal variable(s) in the relation: " ^ commas_quote xs])
   209     | xs => [qty_str ^ "illegal variable(s) in the relation: " ^ commas_quote xs])
   210 
   210 
   211   val errs = illegal_rel_vars @ dup_vs @ extra_rty_tfrees @ extra_rel_tfrees @ illegal_rel_frees
   211   val errs = illegal_rel_vars @ dup_vs @ extra_rty_tfrees @ extra_rel_tfrees @ illegal_rel_frees
   212 in
   212 in
   246 
   246 
   247  it opens a proof-state in which one has to show that the
   247  it opens a proof-state in which one has to show that the
   248  relations are equivalence relations
   248  relations are equivalence relations
   249 *)
   249 *)
   250 
   250 
   251 fun quotient_type quot_list lthy = 
   251 fun quotient_type quot_list lthy =
   252 let
   252 let
   253   (* sanity check *)  
   253   (* sanity check *)
   254   val _ = List.app sanity_check quot_list 
   254   val _ = List.app sanity_check quot_list
   255   val _ = List.app (map_check lthy) quot_list
   255   val _ = List.app (map_check lthy) quot_list
   256 
   256 
   257   fun mk_goal (rty, rel) =
   257   fun mk_goal (rty, rel) =
   258   let
   258   let
   259     val equivp_ty = ([rty, rty] ---> @{typ bool}) --> @{typ bool}
   259     val equivp_ty = ([rty, rty] ---> @{typ bool}) --> @{typ bool}
   260   in 
   260   in
   261     HOLogic.mk_Trueprop (Const (@{const_name equivp}, equivp_ty) $ rel)
   261     HOLogic.mk_Trueprop (Const (@{const_name equivp}, equivp_ty) $ rel)
   262   end
   262   end
   263 
   263 
   264   val goals = map (mk_goal o snd) quot_list
   264   val goals = map (mk_goal o snd) quot_list
   265               
   265 
   266   fun after_qed thms lthy =
   266   fun after_qed thms lthy =
   267     fold_map mk_quotient_type (quot_list ~~ thms) lthy |> snd
   267     fold_map mk_quotient_type (quot_list ~~ thms) lthy |> snd
   268 in
   268 in
   269   theorem after_qed goals lthy
   269   theorem after_qed goals lthy
   270 end
   270 end
   271            
   271 
   272 fun quotient_type_cmd specs lthy = 
   272 fun quotient_type_cmd specs lthy =
   273 let
   273 let
   274   fun parse_spec ((((vs, qty_name), mx), rty_str), rel_str) lthy =
   274   fun parse_spec ((((vs, qty_name), mx), rty_str), rel_str) lthy =
   275   let
   275   let
   276     (* new parsing with proper declaration *)
   276     (* new parsing with proper declaration *)
   277     val rty = Syntax.read_typ lthy rty_str
   277     val rty = Syntax.read_typ lthy rty_str
   278     val lthy1 = Variable.declare_typ rty lthy
   278     val lthy1 = Variable.declare_typ rty lthy
   279     val pre_rel = Syntax.parse_term lthy1 rel_str
   279     val pre_rel = Syntax.parse_term lthy1 rel_str
   280     val pre_rel' = Syntax.type_constraint (rty --> rty --> @{typ bool}) pre_rel
   280     val pre_rel' = Syntax.type_constraint (rty --> rty --> @{typ bool}) pre_rel
   281     val rel = Syntax.check_term lthy1 pre_rel'   
   281     val rel = Syntax.check_term lthy1 pre_rel'
   282     val lthy2 = Variable.declare_term rel lthy1
   282     val lthy2 = Variable.declare_term rel lthy1
   283    
   283 
   284     (* old parsing *)
   284     (* old parsing *)
   285     (* val rty = Syntax.read_typ lthy rty_str
   285     (* val rty = Syntax.read_typ lthy rty_str
   286        val rel = Syntax.read_term lthy rel_str *) 
   286        val rel = Syntax.read_term lthy rel_str *)
   287   in
   287   in
   288     (((vs, qty_name, mx), (rty, rel)), lthy2)
   288     (((vs, qty_name, mx), (rty, rel)), lthy2)
   289   end
   289   end
   290 
   290 
   291   val (spec', lthy') = fold_map parse_spec specs lthy
   291   val (spec', lthy') = fold_map parse_spec specs lthy
   292 in
   292 in
   293   quotient_type spec' lthy'
   293   quotient_type spec' lthy'
   294 end
   294 end
   295 
   295 
   296 val quotspec_parser = 
   296 val quotspec_parser =
   297     OuterParse.and_list1
   297     OuterParse.and_list1
   298      ((OuterParse.type_args -- OuterParse.binding) -- 
   298      ((OuterParse.type_args -- OuterParse.binding) --
   299         OuterParse.opt_infix -- (OuterParse.$$$ "=" |-- OuterParse.typ) -- 
   299         OuterParse.opt_infix -- (OuterParse.$$$ "=" |-- OuterParse.typ) --
   300          (OuterParse.$$$ "/" |-- OuterParse.term))
   300          (OuterParse.$$$ "/" |-- OuterParse.term))
   301 
   301 
   302 val _ = OuterKeyword.keyword "/"
   302 val _ = OuterKeyword.keyword "/"
   303 
   303 
   304 val _ = 
   304 val _ =
   305     OuterSyntax.local_theory_to_proof "quotient_type" 
   305     OuterSyntax.local_theory_to_proof "quotient_type"
   306       "quotient type definitions (require equivalence proofs)"
   306       "quotient type definitions (require equivalence proofs)"
   307          OuterKeyword.thy_goal (quotspec_parser >> quotient_type_cmd)
   307          OuterKeyword.thy_goal (quotspec_parser >> quotient_type_cmd)
   308 
   308 
   309 end; (* structure *)
   309 end; (* structure *)