| author | huffman | 
| Wed, 24 Aug 2011 11:56:57 -0700 | |
| changeset 44514 | d02b01e5ab8f | 
| parent 44204 | 3cdc4176638c | 
| child 45278 | 7c6c8e950636 | 
| permissions | -rw-r--r-- | 
| 37744 | 1 | (* Title: HOL/Tools/Quotient/quotient_typ.ML | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 2 | Author: Cezary Kaliszyk and Christian Urban | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 3 | |
| 35806 
a814cccce0b8
rollback of local typedef until problem with type-variables can be sorted out; fixed header
 Christian Urban <urbanc@in.tum.de> parents: 
35790diff
changeset | 4 | Definition of a quotient type. | 
| 35790 
a9507cd84326
removed Local_Theory.theory_result by using local Typedef.add_typedef
 Christian Urban <urbanc@in.tum.de> parents: 
35788diff
changeset | 5 | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 6 | *) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 7 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 8 | signature QUOTIENT_TYPE = | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 9 | sig | 
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 10 | val add_quotient_type: ((string list * binding * mixfix) * (typ * term * bool)) * thm | 
| 37530 
70d03844b2f9
export of proper information in the ML-interface of the quotient package
 Christian Urban <urbanc@in.tum.de> parents: 
37493diff
changeset | 11 | -> Proof.context -> Quotient_Info.quotdata_info * local_theory | 
| 35415 
1810b1ade437
export add_quotient_type.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
35351diff
changeset | 12 | |
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 13 | val quotient_type: ((string list * binding * mixfix) * (typ * term * bool)) list | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 14 | -> Proof.context -> Proof.state | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 15 | |
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 16 | val quotient_type_cmd: ((((string list * binding) * mixfix) * string) * (bool * string)) list | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 17 | -> Proof.context -> Proof.state | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 18 | end; | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 19 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 20 | structure Quotient_Type: QUOTIENT_TYPE = | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 21 | struct | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 22 | |
| 41451 | 23 | (* wrappers for define, note, Attrib.internal and theorem_i *) (* FIXME !? *) | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 24 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 25 | fun define (name, mx, rhs) lthy = | 
| 41444 | 26 | let | 
| 27 | val ((rhs, (_ , thm)), lthy') = | |
| 28 | Local_Theory.define ((name, mx), (Attrib.empty_binding, rhs)) lthy | |
| 29 | in | |
| 30 | ((rhs, thm), lthy') | |
| 31 | end | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 32 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 33 | fun note (name, thm, attrs) lthy = | 
| 37530 
70d03844b2f9
export of proper information in the ML-interface of the quotient package
 Christian Urban <urbanc@in.tum.de> parents: 
37493diff
changeset | 34 | Local_Theory.note ((name, attrs), [thm]) lthy |> snd | 
| 
70d03844b2f9
export of proper information in the ML-interface of the quotient package
 Christian Urban <urbanc@in.tum.de> parents: 
37493diff
changeset | 35 | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 36 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 37 | fun intern_attr at = Attrib.internal (K at) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 38 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 39 | fun theorem after_qed goals ctxt = | 
| 41444 | 40 | let | 
| 41 | val goals' = map (rpair []) goals | |
| 42 | fun after_qed' thms = after_qed (the_single thms) | |
| 43 | in | |
| 44 | Proof.theorem NONE after_qed' [goals'] ctxt | |
| 45 | end | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 46 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 47 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 48 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 49 | (*** definition of quotient types ***) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 50 | |
| 44204 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 51 | val mem_def1 = @{lemma "y : Collect S ==> S y" by simp}
 | 
| 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 52 | val mem_def2 = @{lemma "S y ==> y : Collect S" by simp}
 | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 53 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 54 | (* constructs the term lambda (c::rty => bool). EX (x::rty). c = rel x *) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 55 | fun typedef_term rel rty lthy = | 
| 41444 | 56 | let | 
| 57 | val [x, c] = | |
| 58 |       [("x", rty), ("c", HOLogic.mk_setT rty)]
 | |
| 59 | |> Variable.variant_frees lthy [rel] | |
| 60 | |> map Free | |
| 44204 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 61 | fun mk_collect T = | 
| 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 62 |       Const (@{const_name Collect}, (T --> @{typ bool}) --> HOLogic.mk_setT T)
 | 
| 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 63 | val collect_in = mk_collect rty | 
| 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 64 | val collect_out = mk_collect (HOLogic.mk_setT rty) | 
| 41444 | 65 | in | 
| 44204 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 66 | collect_out $ (lambda c (HOLogic.exists_const rty $ | 
| 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 67 | lambda x (HOLogic.mk_conj (rel $ x $ x, | 
| 
3cdc4176638c
Quotient Package: make quotient_type work with separate set type
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
43547diff
changeset | 68 | HOLogic.mk_eq (c, collect_in $ (rel $ x)))))) | 
| 41444 | 69 | end | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 70 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 71 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 72 | (* makes the new type definitions and proves non-emptyness *) | 
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 73 | fun typedef_make (vs, qty_name, mx, rel, rty) equiv_thm lthy = | 
| 41444 | 74 | let | 
| 75 | val typedef_tac = | |
| 76 |       EVERY1 (map rtac [@{thm part_equivp_typedef}, equiv_thm])
 | |
| 77 | in | |
| 78 | (* FIXME: purely local typedef causes at the moment | |
| 79 | problems with type variables | |
| 80 | ||
| 81 | Typedef.add_typedef false NONE (qty_name, vs, mx) | |
| 82 | (typedef_term rel rty lthy) NONE typedef_tac lthy | |
| 83 | *) | |
| 84 | (* FIXME should really use local typedef here *) | |
| 85 | Local_Theory.background_theory_result | |
| 35806 
a814cccce0b8
rollback of local typedef until problem with type-variables can be sorted out; fixed header
 Christian Urban <urbanc@in.tum.de> parents: 
35790diff
changeset | 86 | (Typedef.add_typedef_global false NONE | 
| 35842 | 87 | (qty_name, map (rpair dummyS) vs, mx) | 
| 35806 
a814cccce0b8
rollback of local typedef until problem with type-variables can be sorted out; fixed header
 Christian Urban <urbanc@in.tum.de> parents: 
35790diff
changeset | 88 | (typedef_term rel rty lthy) | 
| 
a814cccce0b8
rollback of local typedef until problem with type-variables can be sorted out; fixed header
 Christian Urban <urbanc@in.tum.de> parents: 
35790diff
changeset | 89 | NONE typedef_tac) lthy | 
| 41444 | 90 | end | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 91 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 92 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 93 | (* tactic to prove the quot_type theorem for the new type *) | 
| 35994 
9cc3df9a606e
Typedef.info: separate global and local part, only the latter is transformed by morphisms;
 wenzelm parents: 
35842diff
changeset | 94 | fun typedef_quot_type_tac equiv_thm ((_, typedef_info): Typedef.info) = | 
| 41444 | 95 | let | 
| 96 | val rep_thm = #Rep typedef_info RS mem_def1 | |
| 97 | val rep_inv = #Rep_inverse typedef_info | |
| 98 | val abs_inv = #Abs_inverse typedef_info | |
| 99 | val rep_inj = #Rep_inject typedef_info | |
| 100 | in | |
| 101 |     (rtac @{thm quot_type.intro} THEN' RANGE [
 | |
| 102 | rtac equiv_thm, | |
| 103 | rtac rep_thm, | |
| 104 | rtac rep_inv, | |
| 105 | rtac abs_inv THEN' rtac mem_def2 THEN' atac, | |
| 106 | rtac rep_inj]) 1 | |
| 107 | end | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 108 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 109 | (* proves the quot_type theorem for the new type *) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 110 | fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy = | 
| 41444 | 111 | let | 
| 112 |     val quot_type_const = Const (@{const_name "quot_type"}, dummyT)
 | |
| 113 | val goal = | |
| 114 | HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep) | |
| 115 | |> Syntax.check_term lthy | |
| 116 | in | |
| 117 | Goal.prove lthy [] [] goal | |
| 118 | (K (typedef_quot_type_tac equiv_thm typedef_info)) | |
| 119 | end | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 120 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 121 | (* main function for constructing a quotient type *) | 
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 122 | fun add_quotient_type (((vs, qty_name, mx), (rty, rel, partial)), equiv_thm) lthy = | 
| 41444 | 123 | let | 
| 124 | val part_equiv = | |
| 125 | if partial | |
| 126 | then equiv_thm | |
| 127 |       else equiv_thm RS @{thm equivp_implies_part_equivp}
 | |
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 128 | |
| 41444 | 129 | (* generates the typedef *) | 
| 130 | val ((qty_full_name, typedef_info), lthy1) = | |
| 131 | typedef_make (vs, qty_name, mx, rel, rty) part_equiv lthy | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 132 | |
| 41444 | 133 | (* abs and rep functions from the typedef *) | 
| 134 | val Abs_ty = #abs_type (#1 typedef_info) | |
| 135 | val Rep_ty = #rep_type (#1 typedef_info) | |
| 136 | val Abs_name = #Abs_name (#1 typedef_info) | |
| 137 | val Rep_name = #Rep_name (#1 typedef_info) | |
| 138 | val Abs_const = Const (Abs_name, Rep_ty --> Abs_ty) | |
| 139 | val Rep_const = Const (Rep_name, Abs_ty --> Rep_ty) | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 140 | |
| 41444 | 141 | (* more useful abs and rep definitions *) | 
| 142 |     val abs_const = Const (@{const_name "quot_type.abs"}, dummyT )
 | |
| 143 |     val rep_const = Const (@{const_name "quot_type.rep"}, dummyT )
 | |
| 144 | val abs_trm = Syntax.check_term lthy1 (abs_const $ rel $ Abs_const) | |
| 145 | val rep_trm = Syntax.check_term lthy1 (rep_const $ Rep_const) | |
| 146 | val abs_name = Binding.prefix_name "abs_" qty_name | |
| 147 | val rep_name = Binding.prefix_name "rep_" qty_name | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 148 | |
| 41444 | 149 | val ((_, abs_def), lthy2) = define (abs_name, NoSyn, abs_trm) lthy1 | 
| 150 | val ((_, rep_def), lthy3) = define (rep_name, NoSyn, rep_trm) lthy2 | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 151 | |
| 41444 | 152 | (* quot_type theorem *) | 
| 153 | val quot_thm = typedef_quot_type_thm (rel, Abs_const, Rep_const, part_equiv, typedef_info) lthy3 | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 154 | |
| 41444 | 155 | (* quotient theorem *) | 
| 156 | val quotient_thm_name = Binding.prefix_name "Quotient_" qty_name | |
| 157 | val quotient_thm = | |
| 158 |       (quot_thm RS @{thm quot_type.Quotient})
 | |
| 159 | |> fold_rule [abs_def, rep_def] | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 160 | |
| 41444 | 161 | (* name equivalence theorem *) | 
| 162 | val equiv_thm_name = Binding.suffix_name "_equivp" qty_name | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 163 | |
| 41444 | 164 | (* storing the quotdata *) | 
| 165 |     val quotdata = {qtyp = Abs_ty, rtyp = rty, equiv_rel = rel, equiv_thm = equiv_thm}
 | |
| 37530 
70d03844b2f9
export of proper information in the ML-interface of the quotient package
 Christian Urban <urbanc@in.tum.de> parents: 
37493diff
changeset | 166 | |
| 41451 | 167 | fun qinfo phi = Quotient_Info.transform_quotdata phi quotdata | 
| 37530 
70d03844b2f9
export of proper information in the ML-interface of the quotient package
 Christian Urban <urbanc@in.tum.de> parents: 
37493diff
changeset | 168 | |
| 41444 | 169 | val lthy4 = lthy3 | 
| 41451 | 170 | |> Local_Theory.declaration true | 
| 171 | (fn phi => Quotient_Info.quotdata_update_gen qty_full_name (qinfo phi)) | |
| 172 | |> note | |
| 173 | (equiv_thm_name, equiv_thm, | |
| 174 | if partial then [] else [intern_attr Quotient_Info.equiv_rules_add]) | |
| 175 | |> note (quotient_thm_name, quotient_thm, [intern_attr Quotient_Info.quotient_rules_add]) | |
| 41444 | 176 | in | 
| 177 | (quotdata, lthy4) | |
| 178 | end | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 179 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 180 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 181 | (* sanity checks for the quotient type specifications *) | 
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 182 | fun sanity_check ((vs, qty_name, _), (rty, rel, _)) = | 
| 41444 | 183 | let | 
| 184 | val rty_tfreesT = map fst (Term.add_tfreesT rty []) | |
| 185 | val rel_tfrees = map fst (Term.add_tfrees rel []) | |
| 186 | val rel_frees = map fst (Term.add_frees rel []) | |
| 187 | val rel_vars = Term.add_vars rel [] | |
| 188 | val rel_tvars = Term.add_tvars rel [] | |
| 43547 
f3a8476285c6
clarified Binding.pretty/print: no quotes, only markup -- Binding.str_of is rendered obsolete;
 wenzelm parents: 
42361diff
changeset | 189 | val qty_str = Binding.print qty_name ^ ": " | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 190 | |
| 41444 | 191 | val illegal_rel_vars = | 
| 192 | if null rel_vars andalso null rel_tvars then [] | |
| 193 | else [qty_str ^ "illegal schematic variable(s) in the relation."] | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 194 | |
| 41444 | 195 | val dup_vs = | 
| 196 | (case duplicates (op =) vs of | |
| 197 | [] => [] | |
| 198 | | dups => [qty_str ^ "duplicate type variable(s) on the lhs: " ^ commas_quote dups]) | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 199 | |
| 41444 | 200 | val extra_rty_tfrees = | 
| 201 | (case subtract (op =) vs rty_tfreesT of | |
| 202 | [] => [] | |
| 203 | | extras => [qty_str ^ "extra type variable(s) on the lhs: " ^ commas_quote extras]) | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 204 | |
| 41444 | 205 | val extra_rel_tfrees = | 
| 206 | (case subtract (op =) vs rel_tfrees of | |
| 207 | [] => [] | |
| 208 | | extras => [qty_str ^ "extra type variable(s) in the relation: " ^ commas_quote extras]) | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 209 | |
| 41444 | 210 | val illegal_rel_frees = | 
| 211 | (case rel_frees of | |
| 212 | [] => [] | |
| 213 | | xs => [qty_str ^ "illegal variable(s) in the relation: " ^ commas_quote xs]) | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 214 | |
| 41444 | 215 | val errs = illegal_rel_vars @ dup_vs @ extra_rty_tfrees @ extra_rel_tfrees @ illegal_rel_frees | 
| 216 | in | |
| 217 | if null errs then () else error (cat_lines errs) | |
| 218 | end | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 219 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 220 | (* check for existence of map functions *) | 
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 221 | fun map_check ctxt (_, (rty, _, _)) = | 
| 41444 | 222 | let | 
| 42361 | 223 | val thy = Proof_Context.theory_of ctxt | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 224 | |
| 41444 | 225 | fun map_check_aux rty warns = | 
| 226 | case rty of | |
| 227 | Type (_, []) => warns | |
| 41451 | 228 | | Type (s, _) => if Quotient_Info.maps_defined thy s then warns else s::warns | 
| 41444 | 229 | | _ => warns | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 230 | |
| 41444 | 231 | val warns = map_check_aux rty [] | 
| 232 | in | |
| 233 | if null warns then () | |
| 234 |     else warning ("No map function defined for " ^ commas warns ^
 | |
| 235 | ". This will cause problems later on.") | |
| 236 | end | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 237 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 238 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 239 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 240 | (*** interface and syntax setup ***) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 241 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 242 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 243 | (* the ML-interface takes a list of 5-tuples consisting of: | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 244 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 245 | - the name of the quotient type | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 246 | - its free type variables (first argument) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 247 | - its mixfix annotation | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 248 | - the type to be quotient | 
| 37530 
70d03844b2f9
export of proper information in the ML-interface of the quotient package
 Christian Urban <urbanc@in.tum.de> parents: 
37493diff
changeset | 249 | - the partial flag (a boolean) | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 250 | - the relation according to which the type is quotient | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 251 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 252 | it opens a proof-state in which one has to show that the | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 253 | relations are equivalence relations | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 254 | *) | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 255 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 256 | fun quotient_type quot_list lthy = | 
| 41444 | 257 | let | 
| 258 | (* sanity check *) | |
| 259 | val _ = List.app sanity_check quot_list | |
| 260 | val _ = List.app (map_check lthy) quot_list | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 261 | |
| 41444 | 262 | fun mk_goal (rty, rel, partial) = | 
| 263 | let | |
| 264 |         val equivp_ty = ([rty, rty] ---> @{typ bool}) --> @{typ bool}
 | |
| 265 | val const = | |
| 266 |           if partial then @{const_name part_equivp} else @{const_name equivp}
 | |
| 267 | in | |
| 268 | HOLogic.mk_Trueprop (Const (const, equivp_ty) $ rel) | |
| 269 | end | |
| 270 | ||
| 271 | val goals = map (mk_goal o snd) quot_list | |
| 272 | ||
| 273 | fun after_qed thms lthy = | |
| 274 | fold_map add_quotient_type (quot_list ~~ thms) lthy |> snd | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 275 | in | 
| 41444 | 276 | theorem after_qed goals lthy | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 277 | end | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 278 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 279 | fun quotient_type_cmd specs lthy = | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 280 | let | 
| 41444 | 281 | fun parse_spec ((((vs, qty_name), mx), rty_str), (partial, rel_str)) lthy = | 
| 282 | let | |
| 283 | val rty = Syntax.read_typ lthy rty_str | |
| 284 | val lthy1 = Variable.declare_typ rty lthy | |
| 285 | val rel = | |
| 286 | Syntax.parse_term lthy1 rel_str | |
| 287 |           |> Type.constraint (rty --> rty --> @{typ bool})
 | |
| 288 | |> Syntax.check_term lthy1 | |
| 289 | val lthy2 = Variable.declare_term rel lthy1 | |
| 290 | in | |
| 291 | (((vs, qty_name, mx), (rty, rel, partial)), lthy2) | |
| 292 | end | |
| 293 | ||
| 294 | val (spec', lthy') = fold_map parse_spec specs lthy | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 295 | in | 
| 41444 | 296 | quotient_type spec' lthy' | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 297 | end | 
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 298 | |
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 299 | val partial = Scan.optional (Parse.reserved "partial" -- Parse.$$$ ":" >> K true) false | 
| 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 300 | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 301 | val quotspec_parser = | 
| 37493 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 302 | Parse.and_list1 | 
| 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 303 | ((Parse.type_args -- Parse.binding) -- | 
| 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 304 | Parse.opt_mixfix -- (Parse.$$$ "=" |-- Parse.typ) -- | 
| 
2377d246a631
Quotient package now uses Partial Equivalence instead place of equivalence
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: 
36960diff
changeset | 305 | (Parse.$$$ "/" |-- (partial -- Parse.term))) | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 306 | |
| 36960 
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
 wenzelm parents: 
36323diff
changeset | 307 | val _ = Keyword.keyword "/" | 
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 308 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 309 | val _ = | 
| 41444 | 310 | Outer_Syntax.local_theory_to_proof "quotient_type" | 
| 311 | "quotient type definitions (require equivalence proofs)" | |
| 312 | Keyword.thy_goal (quotspec_parser >> quotient_type_cmd) | |
| 35222 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 313 | |
| 
4f1fba00f66d
Initial version of HOL quotient package.
 Cezary Kaliszyk <kaliszyk@in.tum.de> parents: diff
changeset | 314 | end; (* structure *) |