| 0 |      1 | theory QuotMain
 | 
|  |      2 | imports QuotScript QuotList
 | 
|  |      3 | begin
 | 
|  |      4 | 
 | 
|  |      5 | locale QUOT_TYPE =
 | 
|  |      6 |   fixes R :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
 | 
|  |      7 |   and   Abs :: "('a \<Rightarrow> bool) \<Rightarrow> 'b"
 | 
|  |      8 |   and   Rep :: "'b \<Rightarrow> ('a \<Rightarrow> bool)"
 | 
|  |      9 |   assumes equiv: "EQUIV R"
 | 
|  |     10 |   and     rep_prop: "\<And>y. \<exists>x. Rep y = R x"
 | 
|  |     11 |   and     rep_inverse: "\<And>x. Abs (Rep x) = x"
 | 
|  |     12 |   and     abs_inverse: "\<And>x. (Rep (Abs (R x))) = (R x)"
 | 
|  |     13 |   and     rep_inject: "\<And>x y. (Rep x = Rep y) = (x = y)"
 | 
|  |     14 | begin 
 | 
|  |     15 | 
 | 
|  |     16 | definition
 | 
|  |     17 |   "ABS x \<equiv> Abs (R x)"
 | 
|  |     18 | 
 | 
|  |     19 | definition
 | 
|  |     20 |   "REP a = Eps (Rep a)"
 | 
|  |     21 | 
 | 
|  |     22 | lemma lem9: 
 | 
|  |     23 |   shows "R (Eps (R x)) = R x"
 | 
|  |     24 | proof -
 | 
|  |     25 |   have a: "R x x" using equiv by (simp add: EQUIV_REFL_SYM_TRANS REFL_def)
 | 
|  |     26 |   then have "R x (Eps (R x))" by (rule someI)
 | 
|  |     27 |   then show "R (Eps (R x)) = R x" 
 | 
|  |     28 |     using equiv unfolding EQUIV_def by simp
 | 
|  |     29 | qed
 | 
|  |     30 | 
 | 
|  |     31 | theorem thm10:
 | 
|  |     32 |   shows "ABS (REP a) = a"
 | 
|  |     33 | unfolding ABS_def REP_def
 | 
|  |     34 | proof -
 | 
|  |     35 |   from rep_prop 
 | 
|  |     36 |   obtain x where eq: "Rep a = R x" by auto
 | 
|  |     37 |   have "Abs (R (Eps (Rep a))) = Abs (R (Eps (R x)))" using eq by simp
 | 
|  |     38 |   also have "\<dots> = Abs (R x)" using lem9 by simp
 | 
|  |     39 |   also have "\<dots> = Abs (Rep a)" using eq by simp
 | 
|  |     40 |   also have "\<dots> = a" using rep_inverse by simp
 | 
|  |     41 |   finally
 | 
|  |     42 |   show "Abs (R (Eps (Rep a))) = a" by simp
 | 
|  |     43 | qed
 | 
|  |     44 | 
 | 
|  |     45 | lemma REP_refl: 
 | 
|  |     46 |   shows "R (REP a) (REP a)"
 | 
|  |     47 | unfolding REP_def
 | 
|  |     48 | by (simp add: equiv[simplified EQUIV_def])
 | 
|  |     49 | 
 | 
|  |     50 | lemma lem7:
 | 
|  |     51 |   "(R x = R y) = (Abs (R x) = Abs (R y))"
 | 
|  |     52 | apply(rule iffI)
 | 
|  |     53 | apply(simp)
 | 
|  |     54 | apply(drule rep_inject[THEN iffD2])
 | 
|  |     55 | apply(simp add: abs_inverse)
 | 
|  |     56 | done
 | 
|  |     57 |   
 | 
|  |     58 | theorem thm11:
 | 
|  |     59 |   shows "R r r' = (ABS r = ABS r')"
 | 
|  |     60 | unfolding ABS_def
 | 
|  |     61 | by (simp only: equiv[simplified EQUIV_def] lem7)
 | 
|  |     62 | 
 | 
| 4 |     63 | 
 | 
| 2 |     64 | lemma REP_ABS_rsp:
 | 
| 4 |     65 |   shows "R f (REP (ABS g)) = R f g"
 | 
|  |     66 |   and   "R (REP (ABS g)) f = R g f"
 | 
|  |     67 | apply(subst thm11)
 | 
|  |     68 | apply(simp add: thm10 thm11)
 | 
|  |     69 | apply(subst thm11)
 | 
|  |     70 | apply(simp add: thm10 thm11)
 | 
|  |     71 | done
 | 
|  |     72 | 
 | 
| 0 |     73 | lemma QUOTIENT:
 | 
|  |     74 |   "QUOTIENT R ABS REP"
 | 
|  |     75 | apply(unfold QUOTIENT_def)
 | 
|  |     76 | apply(simp add: thm10)
 | 
|  |     77 | apply(simp add: REP_refl)
 | 
|  |     78 | apply(subst thm11[symmetric])
 | 
|  |     79 | apply(simp add: equiv[simplified EQUIV_def])
 | 
|  |     80 | done
 | 
|  |     81 | 
 | 
|  |     82 | end
 | 
|  |     83 | 
 | 
|  |     84 | section {* type definition for the quotient type *}
 | 
|  |     85 | 
 | 
|  |     86 | ML {*
 | 
| 2 |     87 | Variable.variant_frees
 | 
|  |     88 | *}
 | 
|  |     89 | 
 | 
|  |     90 | 
 | 
|  |     91 | ML {*
 | 
| 1 |     92 | (* constructs the term \<lambda>(c::ty \<Rightarrow> bool). \<exists>x. c = rel x *)
 | 
| 0 |     93 | fun typedef_term rel ty lthy =
 | 
|  |     94 | let 
 | 
|  |     95 |   val [x, c] = [("x", ty), ("c", ty --> @{typ bool})] 
 | 
|  |     96 |                |> Variable.variant_frees lthy [rel]
 | 
|  |     97 |                |> map Free
 | 
|  |     98 | in
 | 
| 1 |     99 |   lambda c 
 | 
|  |    100 |     (HOLogic.mk_exists 
 | 
|  |    101 |        ("x", ty, HOLogic.mk_eq (c, (rel $ x))))
 | 
| 0 |    102 | end
 | 
|  |    103 | *}
 | 
|  |    104 | 
 | 
|  |    105 | ML {*
 | 
| 2 |    106 |  typedef_term @{term R} @{typ "nat"} @{context} 
 | 
|  |    107 |   |> Syntax.string_of_term @{context}
 | 
|  |    108 |   |> writeln
 | 
|  |    109 | *}
 | 
|  |    110 | 
 | 
|  |    111 | ML {*
 | 
| 0 |    112 | val typedef_tac =  
 | 
|  |    113 |   EVERY1 [rewrite_goal_tac @{thms mem_def},
 | 
|  |    114 |           rtac @{thm exI}, rtac @{thm exI}, rtac @{thm refl}]
 | 
|  |    115 | *}
 | 
|  |    116 | 
 | 
|  |    117 | ML {*
 | 
|  |    118 | (* makes the new type definitions *)
 | 
|  |    119 | fun typedef_make (qty_name, rel, ty) lthy =
 | 
|  |    120 |   LocalTheory.theory_result
 | 
| 1 |    121 |   (Typedef.add_typedef false NONE 
 | 
| 0 |    122 |      (qty_name, map fst (Term.add_tfreesT ty []), NoSyn)
 | 
|  |    123 |        (typedef_term rel ty lthy)
 | 
|  |    124 |          NONE typedef_tac) lthy
 | 
|  |    125 | *}
 | 
|  |    126 | 
 | 
| 2 |    127 | text {* proves the QUOT_TYPE theorem for the new type *}
 | 
| 0 |    128 | ML {*
 | 
| 1 |    129 | fun typedef_quot_type_tac equiv_thm (typedef_info: Typedef.info) = 
 | 
| 0 |    130 | let
 | 
|  |    131 |   val rep_thm = #Rep typedef_info
 | 
|  |    132 |   val rep_inv = #Rep_inverse typedef_info
 | 
|  |    133 |   val abs_inv = #Abs_inverse typedef_info
 | 
|  |    134 |   val rep_inj = #Rep_inject typedef_info
 | 
|  |    135 | 
 | 
|  |    136 |   val ss = HOL_basic_ss addsimps @{thms mem_def}
 | 
|  |    137 |   val rep_thm_simpd = Simplifier.asm_full_simplify ss rep_thm
 | 
|  |    138 |   val abs_inv_simpd = Simplifier.asm_full_simplify ss abs_inv
 | 
|  |    139 | in
 | 
|  |    140 |   EVERY1 [rtac @{thm QUOT_TYPE.intro},
 | 
|  |    141 |           rtac equiv_thm, 
 | 
|  |    142 |           rtac rep_thm_simpd, 
 | 
|  |    143 |           rtac rep_inv, 
 | 
|  |    144 |           rtac abs_inv_simpd, rtac @{thm exI}, rtac @{thm refl},
 | 
|  |    145 |           rtac rep_inj]
 | 
|  |    146 | end
 | 
|  |    147 | *}
 | 
|  |    148 | 
 | 
| 2 |    149 | term QUOT_TYPE
 | 
|  |    150 | ML {* HOLogic.mk_Trueprop *}
 | 
|  |    151 | ML {* Goal.prove *}
 | 
|  |    152 | ML {* Syntax.check_term *}
 | 
|  |    153 | 
 | 
| 0 |    154 | ML {* 
 | 
|  |    155 | fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy =
 | 
|  |    156 | let
 | 
|  |    157 |   val quot_type_const = Const (@{const_name "QUOT_TYPE"}, dummyT)
 | 
|  |    158 |   val goal = HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep)
 | 
|  |    159 |              |> Syntax.check_term lthy
 | 
|  |    160 | in
 | 
|  |    161 |   Goal.prove lthy [] [] goal
 | 
|  |    162 |     (fn _ => typedef_quot_type_tac equiv_thm typedef_info)
 | 
|  |    163 | end
 | 
|  |    164 | *}
 | 
|  |    165 | 
 | 
|  |    166 | ML {*
 | 
|  |    167 | fun typedef_quotient_thm_tac defs quot_type_thm =
 | 
|  |    168 |   EVERY1 [K (rewrite_goals_tac defs), 
 | 
|  |    169 |           rtac @{thm QUOT_TYPE.QUOTIENT}, 
 | 
|  |    170 |           rtac quot_type_thm]
 | 
|  |    171 | *}
 | 
|  |    172 | 
 | 
|  |    173 | ML {* 
 | 
|  |    174 | fun typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_type_thm) lthy =
 | 
|  |    175 | let
 | 
|  |    176 |   val quotient_const = Const (@{const_name "QUOTIENT"}, dummyT)
 | 
|  |    177 |   val goal = HOLogic.mk_Trueprop (quotient_const $ rel $ abs $ rep)
 | 
|  |    178 |              |> Syntax.check_term lthy
 | 
|  |    179 | in
 | 
|  |    180 |   Goal.prove lthy [] [] goal
 | 
|  |    181 |     (fn _ => typedef_quotient_thm_tac [abs_def, rep_def] quot_type_thm)
 | 
|  |    182 | end
 | 
|  |    183 | *}
 | 
|  |    184 | 
 | 
|  |    185 | text {* two wrappers for define and note *}
 | 
|  |    186 | ML {* 
 | 
|  |    187 | fun make_def (name, mx, trm) lthy =
 | 
|  |    188 | let   
 | 
|  |    189 |   val ((trm, (_ , thm)), lthy') = 
 | 
|  |    190 |      LocalTheory.define Thm.internalK ((name, mx), (Attrib.empty_binding, trm)) lthy
 | 
|  |    191 | in
 | 
|  |    192 |   ((trm, thm), lthy')
 | 
|  |    193 | end
 | 
|  |    194 | *}
 | 
|  |    195 | 
 | 
|  |    196 | ML {*
 | 
|  |    197 | fun reg_thm (name, thm) lthy = 
 | 
|  |    198 | let
 | 
|  |    199 |   val ((_,[thm']), lthy') = LocalTheory.note Thm.theoremK ((name, []), [thm]) lthy 
 | 
|  |    200 | in
 | 
|  |    201 |   (thm',lthy')
 | 
|  |    202 | end
 | 
|  |    203 | *}
 | 
|  |    204 | 
 | 
|  |    205 | ML {* 
 | 
|  |    206 | fun typedef_main (qty_name, rel, ty, equiv_thm) lthy =
 | 
|  |    207 | let 
 | 
|  |    208 |   (* generates typedef *)
 | 
|  |    209 |   val ((_,typedef_info), lthy') = typedef_make (qty_name, rel, ty) lthy
 | 
|  |    210 | 
 | 
|  |    211 |   (* abs and rep functions *)
 | 
|  |    212 |   val abs_ty = #abs_type typedef_info
 | 
|  |    213 |   val rep_ty = #rep_type typedef_info
 | 
|  |    214 |   val abs_name = #Abs_name typedef_info
 | 
|  |    215 |   val rep_name = #Rep_name typedef_info
 | 
|  |    216 |   val abs = Const (abs_name, rep_ty --> abs_ty)
 | 
|  |    217 |   val rep = Const (rep_name, abs_ty --> rep_ty)
 | 
|  |    218 | 
 | 
|  |    219 |   (* ABS and REP definitions *)
 | 
|  |    220 |   val ABS_const = Const (@{const_name "QUOT_TYPE.ABS"}, dummyT )
 | 
|  |    221 |   val REP_const = Const (@{const_name "QUOT_TYPE.REP"}, dummyT )
 | 
|  |    222 |   val ABS_trm = Syntax.check_term lthy' (ABS_const $ rel $ abs) 
 | 
|  |    223 |   val REP_trm = Syntax.check_term lthy' (REP_const $ rep) 
 | 
|  |    224 |   val ABS_name = Binding.prefix_name "ABS_" qty_name
 | 
|  |    225 |   val REP_name = Binding.prefix_name "REP_" qty_name  
 | 
|  |    226 |   val (((ABS, ABS_def), (REP, REP_def)), lthy'') = 
 | 
|  |    227 |          lthy' |> make_def (ABS_name, NoSyn, ABS_trm)
 | 
|  |    228 |                ||>> make_def (REP_name, NoSyn, REP_trm)
 | 
|  |    229 | 
 | 
|  |    230 |   (* quot_type theorem *)
 | 
|  |    231 |   val quot_thm = typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy''
 | 
|  |    232 |   val quot_thm_name = Binding.prefix_name "QUOT_TYPE_" qty_name
 | 
|  |    233 | 
 | 
|  |    234 |   (* quotient theorem *)
 | 
|  |    235 |   val quotient_thm = typedef_quotient_thm (rel, ABS, REP, ABS_def, REP_def, quot_thm) lthy''
 | 
|  |    236 |   val quotient_thm_name = Binding.prefix_name "QUOTIENT_" qty_name
 | 
|  |    237 | 
 | 
|  |    238 | in
 | 
|  |    239 |   lthy'' 
 | 
|  |    240 |   |> reg_thm (quot_thm_name, quot_thm)  
 | 
|  |    241 |   ||>> reg_thm (quotient_thm_name, quotient_thm)
 | 
|  |    242 | end
 | 
|  |    243 | *}
 | 
|  |    244 | 
 | 
|  |    245 | section {* various tests for quotient types*}
 | 
|  |    246 | datatype trm =
 | 
|  |    247 |   var  "nat" 
 | 
|  |    248 | | app  "trm" "trm"
 | 
|  |    249 | | lam  "nat" "trm"
 | 
|  |    250 |   
 | 
|  |    251 | consts R :: "trm \<Rightarrow> trm \<Rightarrow> bool"
 | 
|  |    252 | axioms r_eq: "EQUIV R"
 | 
|  |    253 | 
 | 
| 2 |    254 | ML {*
 | 
|  |    255 |   typedef_main 
 | 
|  |    256 | *}
 | 
|  |    257 | 
 | 
| 0 |    258 | local_setup {*
 | 
|  |    259 |   typedef_main (@{binding "qtrm"}, @{term "R"}, @{typ trm}, @{thm r_eq}) #> snd
 | 
|  |    260 | *}
 | 
|  |    261 | 
 | 
|  |    262 | term Rep_qtrm
 | 
| 2 |    263 | term REP_qtrm
 | 
| 0 |    264 | term Abs_qtrm
 | 
|  |    265 | term ABS_qtrm
 | 
|  |    266 | thm QUOT_TYPE_qtrm
 | 
|  |    267 | thm QUOTIENT_qtrm
 | 
| 2 |    268 | 
 | 
| 0 |    269 | thm Rep_qtrm
 | 
|  |    270 | 
 | 
|  |    271 | text {* another test *}
 | 
|  |    272 | datatype 'a my = foo
 | 
|  |    273 | consts Rmy :: "'a my \<Rightarrow> 'a my \<Rightarrow> bool"
 | 
|  |    274 | axioms rmy_eq: "EQUIV Rmy"
 | 
|  |    275 | 
 | 
|  |    276 | term "\<lambda>(c::'a my\<Rightarrow>bool). \<exists>x. c = Rmy x"
 | 
|  |    277 | 
 | 
|  |    278 | datatype 'a trm' =
 | 
|  |    279 |   var'  "'a" 
 | 
|  |    280 | | app'  "'a trm'" "'a trm'"
 | 
|  |    281 | | lam'  "'a" "'a trm'"
 | 
|  |    282 |   
 | 
|  |    283 | consts R' :: "'a trm' \<Rightarrow> 'a trm' \<Rightarrow> bool"
 | 
|  |    284 | axioms r_eq': "EQUIV R'"
 | 
|  |    285 | 
 | 
|  |    286 | local_setup {*
 | 
|  |    287 |   typedef_main (@{binding "qtrm'"}, @{term "R'"}, @{typ "'a trm'"}, @{thm r_eq'}) #> snd
 | 
|  |    288 | *}
 | 
|  |    289 | 
 | 
|  |    290 | term ABS_qtrm'
 | 
|  |    291 | term REP_qtrm'
 | 
|  |    292 | thm QUOT_TYPE_qtrm'
 | 
|  |    293 | thm QUOTIENT_qtrm'
 | 
|  |    294 | thm Rep_qtrm'
 | 
|  |    295 | 
 | 
|  |    296 | text {* a test with lists of terms *}
 | 
|  |    297 | datatype t =
 | 
|  |    298 |   vr "string"
 | 
|  |    299 | | ap "t list"
 | 
|  |    300 | | lm "string" "t"
 | 
|  |    301 | 
 | 
|  |    302 | consts Rt :: "t \<Rightarrow> t \<Rightarrow> bool"
 | 
|  |    303 | axioms t_eq: "EQUIV Rt"
 | 
|  |    304 | 
 | 
|  |    305 | local_setup {*
 | 
|  |    306 |   typedef_main (@{binding "qt"}, @{term "Rt"}, @{typ "t"}, @{thm t_eq}) #> snd
 | 
|  |    307 | *}
 | 
|  |    308 | 
 | 
|  |    309 | section {* lifting of constants *}
 | 
|  |    310 | 
 | 
|  |    311 | text {* information about map-functions for type-constructor *}
 | 
|  |    312 | ML {*
 | 
|  |    313 | type typ_info = {mapfun: string}
 | 
|  |    314 | 
 | 
|  |    315 | local
 | 
|  |    316 |   structure Data = GenericDataFun
 | 
|  |    317 |   (type T = typ_info Symtab.table
 | 
|  |    318 |    val empty = Symtab.empty
 | 
|  |    319 |    val extend = I
 | 
|  |    320 |    fun merge _ = Symtab.merge (K true))
 | 
|  |    321 | in
 | 
|  |    322 |  val lookup = Symtab.lookup o Data.get
 | 
|  |    323 |  fun update k v = Data.map (Symtab.update (k, v)) 
 | 
|  |    324 | end
 | 
|  |    325 | *}
 | 
|  |    326 | 
 | 
|  |    327 | (* mapfuns for some standard types *)
 | 
|  |    328 | setup {*
 | 
|  |    329 |     Context.theory_map (update @{type_name "list"} {mapfun = @{const_name "map"}})
 | 
|  |    330 |  #> Context.theory_map (update @{type_name "*"} {mapfun = @{const_name "prod_fun"}})
 | 
|  |    331 |  #> Context.theory_map (update @{type_name "fun"}  {mapfun = @{const_name "fun_map"}})
 | 
|  |    332 | *}
 | 
|  |    333 | 
 | 
| 2 |    334 | 
 | 
| 0 |    335 | ML {* lookup (Context.Proof @{context}) @{type_name list} *}
 | 
|  |    336 | 
 | 
|  |    337 | ML {*
 | 
|  |    338 | datatype abs_or_rep = abs | rep
 | 
|  |    339 | 
 | 
|  |    340 | fun get_fun abs_or_rep rty qty lthy ty = 
 | 
|  |    341 | let
 | 
|  |    342 |   val qty_name = Long_Name.base_name (fst (dest_Type qty))
 | 
|  |    343 |   
 | 
|  |    344 |   fun get_fun_aux s fs_tys =
 | 
|  |    345 |   let
 | 
|  |    346 |     val (fs, tys) = split_list fs_tys
 | 
|  |    347 |     val (otys, ntys) = split_list tys 
 | 
|  |    348 |     val oty = Type (s, otys)
 | 
|  |    349 |     val nty = Type (s, ntys)
 | 
|  |    350 |     val ftys = map (op -->) tys
 | 
|  |    351 |   in
 | 
|  |    352 |    (case (lookup (Context.Proof lthy) s) of 
 | 
|  |    353 |       SOME info => (list_comb (Const (#mapfun info, ftys ---> oty --> nty), fs), (oty, nty))
 | 
|  |    354 |     | NONE => raise ERROR ("no map association for type " ^ s))
 | 
|  |    355 |   end
 | 
|  |    356 | 
 | 
|  |    357 |   fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty))
 | 
|  |    358 |     | get_const rep = (Const ("QuotMain.REP_" ^ qty_name, qty --> rty), (qty, rty))
 | 
|  |    359 | in
 | 
|  |    360 |   if ty = qty
 | 
|  |    361 |   then (get_const abs_or_rep)
 | 
|  |    362 |   else (case ty of
 | 
|  |    363 |           TFree _ => (Abs ("x", ty, Bound 0), (ty, ty))
 | 
|  |    364 |         | Type (_, []) => (Abs ("x", ty, Bound 0), (ty, ty))
 | 
|  |    365 |         | Type (s, tys) => get_fun_aux s (map (get_fun abs_or_rep rty qty lthy) tys)  
 | 
|  |    366 |         | _ => raise ERROR ("no variables")
 | 
|  |    367 |        )
 | 
|  |    368 | end
 | 
|  |    369 | *}
 | 
|  |    370 | 
 | 
|  |    371 | ML {*
 | 
| 2 |    372 |   get_fun rep @{typ t} @{typ qt} @{context} @{typ "t * nat"}
 | 
|  |    373 |   |> fst
 | 
|  |    374 |   |> Syntax.string_of_term @{context}
 | 
|  |    375 |   |> writeln
 | 
|  |    376 | *}
 | 
|  |    377 | 
 | 
|  |    378 | 
 | 
|  |    379 | ML {*
 | 
| 0 |    380 | fun get_const_def nconst oconst rty qty lthy =
 | 
|  |    381 | let
 | 
|  |    382 |   val ty = fastype_of nconst
 | 
|  |    383 |   val (arg_tys, res_ty) = strip_type ty
 | 
|  |    384 |  
 | 
|  |    385 |   val fresh_args = arg_tys |> map (pair "x")
 | 
|  |    386 |                            |> Variable.variant_frees lthy [nconst, oconst] 
 | 
|  |    387 |                            |> map Free
 | 
|  |    388 | 
 | 
|  |    389 |   val rep_fns = map (fst o get_fun rep rty qty lthy) arg_tys
 | 
|  |    390 |   val abs_fn  = (fst o get_fun abs rty qty lthy) res_ty
 | 
|  |    391 | 
 | 
|  |    392 | in
 | 
|  |    393 |   map (op $) (rep_fns ~~ fresh_args)
 | 
|  |    394 |   |> curry list_comb oconst
 | 
|  |    395 |   |> curry (op $) abs_fn
 | 
|  |    396 |   |> fold_rev lambda fresh_args
 | 
|  |    397 | end
 | 
|  |    398 | *}
 | 
|  |    399 | 
 | 
|  |    400 | ML {*
 | 
|  |    401 | fun exchange_ty rty qty ty = 
 | 
|  |    402 |   if ty = rty then qty
 | 
|  |    403 |   else 
 | 
|  |    404 |     (case ty of
 | 
|  |    405 |        Type (s, tys) => Type (s, map (exchange_ty rty qty) tys)
 | 
|  |    406 |       | _ => ty)
 | 
|  |    407 | *}
 | 
|  |    408 | 
 | 
|  |    409 | ML {*
 | 
|  |    410 | fun make_const_def nconst_name oconst mx rty qty lthy = 
 | 
|  |    411 | let
 | 
|  |    412 |   val oconst_ty = fastype_of oconst
 | 
|  |    413 |   val nconst_ty = exchange_ty rty qty oconst_ty
 | 
|  |    414 |   val nconst = Const (nconst_name, nconst_ty)
 | 
|  |    415 |   val def_trm = get_const_def nconst oconst rty qty lthy
 | 
|  |    416 | in
 | 
|  |    417 |   make_def (Binding.name nconst_name, mx, def_trm) lthy
 | 
|  |    418 | end  
 | 
|  |    419 | *}
 | 
|  |    420 | 
 | 
| 2 |    421 | local_setup {*
 | 
|  |    422 |   make_const_def "VR" @{term "vr"} NoSyn @{typ "t"} @{typ "qt"} #> snd
 | 
|  |    423 | *}
 | 
|  |    424 | 
 | 
|  |    425 | local_setup {*
 | 
|  |    426 |   make_const_def "AP" @{term "ap"} NoSyn @{typ "t"} @{typ "qt"} #> snd
 | 
|  |    427 | *}
 | 
|  |    428 | 
 | 
|  |    429 | local_setup {*
 | 
|  |    430 |   make_const_def "LM" @{term "lm"} NoSyn @{typ "t"} @{typ "qt"} #> snd
 | 
|  |    431 | *}
 | 
|  |    432 | 
 | 
|  |    433 | thm VR_def
 | 
|  |    434 | thm AP_def
 | 
|  |    435 | thm LM_def
 | 
|  |    436 | term LM 
 | 
|  |    437 | term VR
 | 
|  |    438 | term AP
 | 
|  |    439 | 
 | 
|  |    440 | 
 | 
| 0 |    441 | text {* a test with functions *}
 | 
|  |    442 | datatype 'a t' =
 | 
|  |    443 |   vr' "string"
 | 
|  |    444 | | ap' "('a t') * ('a t')"
 | 
|  |    445 | | lm' "'a" "string \<Rightarrow> ('a t')"
 | 
|  |    446 | 
 | 
|  |    447 | consts Rt' :: "('a t') \<Rightarrow> ('a t') \<Rightarrow> bool"
 | 
|  |    448 | axioms t_eq': "EQUIV Rt'"
 | 
|  |    449 | 
 | 
|  |    450 | local_setup {*
 | 
|  |    451 |   typedef_main (@{binding "qt'"}, @{term "Rt'"}, @{typ "'a t'"}, @{thm t_eq'}) #> snd
 | 
|  |    452 | *}
 | 
|  |    453 | 
 | 
| 2 |    454 | 
 | 
| 0 |    455 | local_setup {*
 | 
|  |    456 |   make_const_def "VR'" @{term "vr'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd
 | 
|  |    457 | *}
 | 
|  |    458 | 
 | 
|  |    459 | local_setup {*
 | 
|  |    460 |   make_const_def "AP'" @{term "ap'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd
 | 
|  |    461 | *}
 | 
|  |    462 | 
 | 
|  |    463 | local_setup {*
 | 
|  |    464 |   make_const_def "LM'" @{term "lm'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd
 | 
|  |    465 | *}
 | 
|  |    466 | 
 | 
|  |    467 | thm VR'_def
 | 
|  |    468 | thm AP'_def
 | 
|  |    469 | thm LM'_def
 | 
|  |    470 | term LM' 
 | 
|  |    471 | term VR'
 | 
|  |    472 | term AP'
 | 
|  |    473 | 
 | 
|  |    474 | text {* finite set example *}
 | 
|  |    475 | 
 | 
|  |    476 | inductive 
 | 
|  |    477 |   list_eq ("_ \<approx> _")
 | 
|  |    478 | where
 | 
|  |    479 |   "a#b#xs \<approx> b#a#xs"
 | 
|  |    480 | | "[] \<approx> []"
 | 
|  |    481 | | "xs \<approx> ys \<Longrightarrow> ys \<approx> xs"
 | 
|  |    482 | | "a#a#xs \<approx> a#xs"
 | 
|  |    483 | | "xs \<approx> ys \<Longrightarrow> a#xs \<approx> a#ys"
 | 
|  |    484 | | "\<lbrakk>xs1 \<approx> xs2; xs2 \<approx> xs3\<rbrakk> \<Longrightarrow> xs1 \<approx> xs3"
 | 
|  |    485 | 
 | 
|  |    486 | lemma list_eq_sym:
 | 
|  |    487 |   shows "xs \<approx> xs"
 | 
|  |    488 | apply(induct xs)
 | 
|  |    489 | apply(auto intro: list_eq.intros)
 | 
|  |    490 | done
 | 
|  |    491 | 
 | 
|  |    492 | lemma equiv_list_eq:
 | 
|  |    493 |   shows "EQUIV list_eq"
 | 
|  |    494 | unfolding EQUIV_REFL_SYM_TRANS REFL_def SYM_def TRANS_def
 | 
|  |    495 | apply(auto intro: list_eq.intros list_eq_sym)
 | 
|  |    496 | done
 | 
|  |    497 | 
 | 
|  |    498 | local_setup {*
 | 
|  |    499 |   typedef_main (@{binding "fset"}, @{term "list_eq"}, @{typ "'a list"}, @{thm "equiv_list_eq"}) #> snd
 | 
|  |    500 | *}
 | 
|  |    501 | 
 | 
|  |    502 | typ "'a fset"
 | 
|  |    503 | thm "Rep_fset"
 | 
|  |    504 | 
 | 
|  |    505 | local_setup {*
 | 
|  |    506 |   make_const_def "EMPTY" @{term "[]"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
 | 
|  |    507 | *}
 | 
|  |    508 | 
 | 
|  |    509 | term Nil 
 | 
|  |    510 | term EMPTY
 | 
| 2 |    511 | thm EMPTY_def
 | 
|  |    512 | 
 | 
| 0 |    513 | 
 | 
|  |    514 | local_setup {*
 | 
|  |    515 |   make_const_def "INSERT" @{term "op #"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
 | 
|  |    516 | *}
 | 
|  |    517 | 
 | 
|  |    518 | term Cons 
 | 
|  |    519 | term INSERT
 | 
| 2 |    520 | thm INSERT_def
 | 
| 0 |    521 | 
 | 
|  |    522 | local_setup {*
 | 
|  |    523 |   make_const_def "UNION" @{term "op @"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
 | 
|  |    524 | *}
 | 
|  |    525 | 
 | 
|  |    526 | term append 
 | 
|  |    527 | term UNION
 | 
| 2 |    528 | thm UNION_def
 | 
|  |    529 | 
 | 
| 0 |    530 | thm QUOTIENT_fset
 | 
|  |    531 | 
 | 
|  |    532 | fun 
 | 
|  |    533 |   membship :: "'a \<Rightarrow> 'a list \<Rightarrow> bool" ("_ memb _")
 | 
|  |    534 | where
 | 
|  |    535 |   m1: "(x memb []) = False"
 | 
|  |    536 | | m2: "(x memb (y#xs)) = ((x=y) \<or> (x memb xs))"
 | 
|  |    537 | 
 | 
| 2 |    538 | lemma mem_respects:
 | 
|  |    539 |   fixes z::"nat"
 | 
|  |    540 |   assumes a: "list_eq x y"
 | 
|  |    541 |   shows "z memb x = z memb y"
 | 
|  |    542 | using a
 | 
|  |    543 | apply(induct)
 | 
|  |    544 | apply(auto)
 | 
|  |    545 | done
 | 
|  |    546 | 
 | 
| 0 |    547 | 
 | 
|  |    548 | local_setup {*
 | 
|  |    549 |   make_const_def "IN" @{term "membship"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
 | 
|  |    550 | *}
 | 
|  |    551 | 
 | 
|  |    552 | term membship
 | 
|  |    553 | term IN
 | 
| 2 |    554 | thm IN_def
 | 
| 0 |    555 | 
 | 
| 2 |    556 | lemmas a = QUOT_TYPE.ABS_def[OF QUOT_TYPE_fset]
 | 
|  |    557 | thm QUOT_TYPE.thm11[OF QUOT_TYPE_fset, THEN iffD1, simplified a]
 | 
| 0 |    558 | 
 | 
| 2 |    559 | lemma yy:
 | 
|  |    560 |   shows "(False = x memb []) = (False = IN (x::nat) EMPTY)"
 | 
|  |    561 | unfolding IN_def EMPTY_def
 | 
|  |    562 | apply(rule_tac f="(op =) False" in arg_cong)
 | 
|  |    563 | apply(rule mem_respects)
 | 
| 5 |    564 | apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset, 
 | 
| 4 |    565 |         simplified REP_fset_def[symmetric] ABS_fset_def[symmetric]])
 | 
| 2 |    566 | apply(rule list_eq.intros)
 | 
| 0 |    567 | done
 | 
|  |    568 | 
 | 
| 2 |    569 | lemma
 | 
|  |    570 |   shows "IN (x::nat) EMPTY = False"
 | 
|  |    571 | using m1
 | 
|  |    572 | apply -
 | 
|  |    573 | apply(rule yy[THEN iffD1, symmetric])
 | 
|  |    574 | apply(simp)
 | 
| 0 |    575 | done
 | 
|  |    576 | 
 | 
| 2 |    577 | lemma
 | 
|  |    578 |   shows "((x=y) \<or> (IN x xs) = (IN (x::nat) (INSERT y xs))) =
 | 
|  |    579 |          ((x = y) \<or> x memb REP_fset xs = x memb (y # REP_fset xs))"
 | 
|  |    580 | unfolding IN_def INSERT_def
 | 
|  |    581 | apply(rule_tac f="(op \<or>) (x=y)" in arg_cong)
 | 
|  |    582 | apply(rule_tac f="(op =) (x memb REP_fset xs)" in arg_cong)
 | 
|  |    583 | apply(rule mem_respects)
 | 
|  |    584 | apply(rule list_eq.intros(3))
 | 
|  |    585 | apply(unfold REP_fset_def ABS_fset_def)
 | 
| 5 |    586 | apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset])
 | 
| 2 |    587 | apply(rule list_eq_sym)
 | 
|  |    588 | done
 | 
| 0 |    589 | 
 | 
| 3 |    590 | lemma helper:
 | 
| 4 |    591 |   assumes a : "list_eq l1 l2"  
 | 
|  |    592 |   shows "list_eq (l1 @ s) (l2 @ s)"
 | 
| 3 |    593 |   using a
 | 
|  |    594 |   apply(induct)
 | 
| 4 |    595 |   apply(auto intro: list_eq.intros)
 | 
|  |    596 |   apply(simp add: list_eq_sym)
 | 
| 3 |    597 | done
 | 
|  |    598 | 
 | 
|  |    599 | lemma yyy :
 | 
|  |    600 |   shows "
 | 
|  |    601 |     (
 | 
|  |    602 |      (UNION EMPTY s = s) &
 | 
|  |    603 |      ((UNION (INSERT e s1) s2) = (INSERT e (UNION s1 s2)))
 | 
|  |    604 |     ) = (
 | 
|  |    605 |      ((ABS_fset ([] @ REP_fset s)) = s) &
 | 
|  |    606 |      ((ABS_fset ((e # (REP_fset s1)) @ REP_fset s2)) = ABS_fset (e # (REP_fset s1 @ REP_fset s2)))
 | 
|  |    607 |     )"
 | 
|  |    608 |   unfolding UNION_def EMPTY_def INSERT_def
 | 
|  |    609 |   apply(rule_tac f="(op &)" in arg_cong2)
 | 
|  |    610 |   apply(rule_tac f="(op =)" in arg_cong2)
 | 
| 4 |    611 |   apply(simp only: QUOT_TYPE.thm11[OF QUOT_TYPE_fset,
 | 
|  |    612 |                    simplified REP_fset_def[symmetric] ABS_fset_def[symmetric], symmetric])
 | 
| 3 |    613 |   apply(rule helper)
 | 
|  |    614 |   apply(rule list_eq.intros(3))
 | 
| 5 |    615 |   apply(simp only:QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset, 
 | 
| 4 |    616 |                     simplified REP_fset_def[symmetric] ABS_fset_def[symmetric]])
 | 
| 3 |    617 |   apply(rule list_eq_sym)
 | 
|  |    618 |   apply(simp)
 | 
|  |    619 |   apply(rule_tac f="(op =)" in arg_cong2)
 | 
| 4 |    620 |   apply(simp only: QUOT_TYPE.thm11[OF QUOT_TYPE_fset, 
 | 
|  |    621 |                   simplified REP_fset_def[symmetric] ABS_fset_def[symmetric], symmetric])
 | 
| 3 |    622 |   apply(rule helper)
 | 
|  |    623 |   apply(rule list_eq.intros(3))
 | 
| 5 |    624 |   apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset,
 | 
| 4 |    625 |                    simplified REP_fset_def[symmetric] ABS_fset_def[symmetric]])
 | 
| 3 |    626 |   apply(rule list_eq_sym)
 | 
| 4 |    627 |   apply(simp only: QUOT_TYPE.thm11[OF QUOT_TYPE_fset, 
 | 
|  |    628 |                      simplified REP_fset_def[symmetric] ABS_fset_def[symmetric], symmetric])
 | 
| 3 |    629 |   apply(rule list_eq.intros(5))
 | 
|  |    630 |   apply(rule list_eq.intros(3))
 | 
| 5 |    631 |   apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset, 
 | 
| 4 |    632 |                  simplified REP_fset_def[symmetric] ABS_fset_def[symmetric]])
 | 
| 3 |    633 |   apply(rule list_eq_sym)
 | 
|  |    634 | done
 | 
|  |    635 | 
 | 
|  |    636 | lemma
 | 
|  |    637 |   shows "
 | 
|  |    638 |     (
 | 
|  |    639 |      (UNION EMPTY s = s) &
 | 
|  |    640 |      ((UNION (INSERT e s1) s2) = (INSERT e (UNION s1 s2)))
 | 
|  |    641 |     )"
 | 
|  |    642 |   apply(simp add:yyy)
 | 
|  |    643 |   apply (unfold REP_fset_def ABS_fset_def)
 | 
|  |    644 |   apply (rule QUOT_TYPE.thm10[OF QUOT_TYPE_fset])
 | 
|  |    645 | done
 | 
|  |    646 | 
 |