QuotMain.thy
changeset 274 df225aa45770
parent 273 b82e765ca464
child 275 34ad627ac5d5
equal deleted inserted replaced
273:b82e765ca464 274:df225aa45770
   141 section {* type definition for the quotient type *}
   141 section {* type definition for the quotient type *}
   142 
   142 
   143 (* the auxiliary data for the quotient types *)
   143 (* the auxiliary data for the quotient types *)
   144 use "quotient_info.ML"
   144 use "quotient_info.ML"
   145 
   145 
   146 ML {*
       
   147 fun error_msg pre post msg = 
       
   148   msg |> quote
       
   149       |> enclose (pre ^ " ") (" " ^ post) 
       
   150       |> error  
       
   151 *}
       
   152 
   146 
   153 declare [[map list = (map, LIST_REL)]]
   147 declare [[map list = (map, LIST_REL)]]
   154 declare [[map * = (prod_fun, prod_rel)]]
   148 declare [[map * = (prod_fun, prod_rel)]]
   155 declare [[map "fun" = (fun_map, FUN_REL)]]
   149 declare [[map "fun" = (fun_map, FUN_REL)]]
   156 
   150 
   173 *}
   167 *}
   174 
   168 
   175 section {* lifting of constants *}
   169 section {* lifting of constants *}
   176 
   170 
   177 ML {*
   171 ML {*
   178 fun lookup_snd _ [] _ = NONE
       
   179   | lookup_snd eq ((value, key)::xs) key' =
       
   180       if eq (key', key) then SOME value
       
   181       else lookup_snd eq xs key';
       
   182 
   172 
   183 fun lookup_qenv qenv qty =
   173 fun lookup_qenv qenv qty =
   184   (case (AList.lookup (op =) qenv qty) of
   174   (case (AList.lookup (op=) qenv qty) of
   185     SOME rty => SOME (qty, rty)
   175     SOME rty => SOME (qty, rty)
   186   | NONE => NONE)
   176   | NONE => NONE)
   187 *}
   177 *}
   188 
   178 
   189 ML {*
   179 ML {*
   208     val nty = Type (s, ntys)
   198     val nty = Type (s, ntys)
   209     val ftys = map (op -->) tys
   199     val ftys = map (op -->) tys
   210   in
   200   in
   211    (case (maps_lookup (ProofContext.theory_of lthy) s) of
   201    (case (maps_lookup (ProofContext.theory_of lthy) s) of
   212       SOME info => (list_comb (Const (#mapfun info, ftys ---> (oty --> nty)), fs), (oty, nty))
   202       SOME info => (list_comb (Const (#mapfun info, ftys ---> (oty --> nty)), fs), (oty, nty))
   213     | NONE      => raise ERROR ("no map association for type " ^ s))
   203     | NONE      => error ("no map association for type " ^ s))
   214   end
   204   end
   215 
   205 
   216   fun get_fun_fun fs_tys =
   206   fun get_fun_fun fs_tys =
   217   let
   207   let
   218     val (fs, tys) = split_list fs_tys
   208     val (fs, tys) = split_list fs_tys
   235   end
   225   end
   236 
   226 
   237   fun mk_identity ty = Abs ("", ty, Bound 0)
   227   fun mk_identity ty = Abs ("", ty, Bound 0)
   238 
   228 
   239 in
   229 in
   240   if (AList.defined (op =) qenv ty)
   230   if (AList.defined (op=) qenv ty)
   241   then (get_const flag (the (lookup_qenv qenv ty)))
   231   then (get_const flag (the (lookup_qenv qenv ty)))
   242   else (case ty of
   232   else (case ty of
   243           TFree _ => (mk_identity ty, (ty, ty))
   233           TFree _ => (mk_identity ty, (ty, ty))
   244         | Type (_, []) => (mk_identity ty, (ty, ty)) 
   234         | Type (_, []) => (mk_identity ty, (ty, ty)) 
   245         | Type ("fun" , [ty1, ty2]) => 
   235         | Type ("fun" , [ty1, ty2]) => 
   248         | _ => raise ERROR ("no type variables")
   238         | _ => raise ERROR ("no type variables")
   249        )
   239        )
   250 end
   240 end
   251 *}
   241 *}
   252 
   242 
   253 text {* produces the definition for a lifted constant *}
   243 ML {*
   254 
   244 fun make_def nconst_bname rhs qty mx qenv lthy =
   255 ML {*
       
   256 fun get_const_def nconst otrm qenv lthy =
       
   257 let
   245 let
   258   val ty = fastype_of nconst
   246   val (arg_tys, res_ty) = strip_type qty
   259   val (arg_tys, res_ty) = strip_type ty
       
   260 
   247 
   261   val rep_fns = map (fst o get_fun repF qenv lthy) arg_tys
   248   val rep_fns = map (fst o get_fun repF qenv lthy) arg_tys
   262   val abs_fn  = (fst o get_fun absF qenv lthy) res_ty
   249   val abs_fn  = (fst o get_fun absF qenv lthy) res_ty
   263 
   250 
   264   fun mk_fun_map (t1,t2) = Const (@{const_name "fun_map"}, dummyT) $ t1 $ t2
   251   fun mk_fun_map t s = 
   265 
   252         Const (@{const_name "fun_map"}, dummyT) $ t $ s
   266   val fns = Library.foldr mk_fun_map (rep_fns, abs_fn)
   253 
   267             |> Syntax.check_term lthy
   254   val absrep_fn = fold_rev mk_fun_map rep_fns abs_fn
       
   255                   |> Syntax.check_term lthy 
   268 in
   256 in
   269   fns $ otrm
   257   define (nconst_bname, mx, absrep_fn $ rhs) lthy
   270 end
   258 end
   271 *}
   259 *}
   272 
   260 
   273 
   261 ML {*
   274 ML {*
   262 (* returns all subterms where two types differ *)
   275 fun exchange_ty qenv ty =
       
   276   case (lookup_snd (op =) qenv ty) of
       
   277     SOME qty => qty
       
   278   | NONE =>
       
   279     (case ty of
       
   280        Type (s, tys) => Type (s, map (exchange_ty qenv) tys)
       
   281       | _ => ty
       
   282     )
       
   283 *}
       
   284 
       
   285 ML {* 
       
   286 fun ppair lthy (ty1, ty2) =
       
   287   "(" ^ (Syntax.string_of_typ lthy ty1) ^ "," ^ (Syntax.string_of_typ lthy ty2) ^ ")"
       
   288 *}
       
   289 
       
   290 ML {*
       
   291 fun print_env qenv lthy =
       
   292   map (ppair lthy) qenv
       
   293   |> commas
       
   294   |> tracing
       
   295 *}
       
   296 
       
   297 ML {*
       
   298 fun make_const_def nconst_bname otrm mx qenv lthy =
       
   299 let
       
   300   val otrm_ty = fastype_of otrm
       
   301   val nconst_ty = exchange_ty qenv otrm_ty
       
   302   val nconst = Const (Binding.name_of nconst_bname, nconst_ty)
       
   303   val def_trm = get_const_def nconst otrm qenv lthy
       
   304 in
       
   305   define (nconst_bname, mx, def_trm) lthy
       
   306 end
       
   307 *}
       
   308 
       
   309 ML {*
       
   310 (* difference of two types *)
       
   311 fun diff (T, S) Ds =
   263 fun diff (T, S) Ds =
   312   case (T, S) of
   264   case (T, S) of
   313     (TVar v, TVar u) => if v = u then Ds else (T, S)::Ds 
   265     (TVar v, TVar u) => if v = u then Ds else (T, S)::Ds 
   314   | (TFree x, TFree y) => if x = y then Ds else (T, S)::Ds
   266   | (TFree x, TFree y) => if x = y then Ds else (T, S)::Ds
   315   | (Type (a, Ts), Type (b, Us)) => 
   267   | (Type (a, Ts), Type (b, Us)) => 
   319   | diffs ([], []) Ds = Ds
   271   | diffs ([], []) Ds = Ds
   320   | diffs _ _ = error "Unequal length of type arguments"
   272   | diffs _ _ = error "Unequal length of type arguments"
   321 *}
   273 *}
   322 
   274 
   323 ML {*
   275 ML {*
   324 fun quotdef_cmd ((bind, qty, mx), (attr, prop)) lthy =
   276 fun error_msg lthy (qty, rty) =
   325 let    
   277 let 
   326   val (_, rhs) = Logic.dest_equals prop
   278   val qtystr = quote (Syntax.string_of_typ lthy qty)
       
   279   val rtystr = quote (Syntax.string_of_typ lthy rty)
       
   280 in
       
   281   error (implode ["Quotient type ", qtystr, " does not match with ", rtystr])
       
   282 end
       
   283 
       
   284 
       
   285 fun sanity_chk lthy qenv =
       
   286 let
       
   287    val qenv' = Quotient_Info.mk_qenv lthy
       
   288    val thy = ProofContext.theory_of lthy
       
   289 
       
   290    fun is_inst thy (qty, rty) (qty', rty') =
       
   291    if Sign.typ_instance thy (qty, qty')
       
   292    then let
       
   293           val inst = Sign.typ_match thy (qty', qty) Vartab.empty
       
   294         in
       
   295           rty = Envir.subst_type inst rty'
       
   296         end
       
   297    else false
       
   298 
       
   299    fun chk_inst (qty, rty) = 
       
   300      if exists (is_inst thy (qty, rty)) qenv' then true
       
   301      else error_msg lthy (qty, rty)
       
   302 in
       
   303   forall chk_inst qenv
       
   304 end
       
   305 *}
       
   306 
       
   307 ML {*
       
   308 fun quotdef ((bind, qty, mx), (attr, prop)) lthy =
       
   309 let   
       
   310   val (_, prop') = PrimitiveDefs.dest_def lthy (K true) (K false) (K false) prop
       
   311   val (_, rhs) = PrimitiveDefs.abs_def prop'
       
   312 
   327   val rty = fastype_of rhs
   313   val rty = fastype_of rhs
   328   val qenv = distinct (op=) (diff (qty, rty) [])
   314   val qenv = distinct (op=) (diff (qty, rty) [])
       
   315  
   329 in
   316 in
   330   make_const_def bind rhs mx qenv lthy
   317   sanity_chk lthy qenv;
   331 end
   318   make_def bind rhs qty mx qenv lthy 
   332 *}
   319 end
   333 
   320 *}
   334 ML {*
   321 
   335 val constdecl =
   322 ML {*
   336   OuterParse.binding --
   323 val quotdef_parser =
   337     (OuterParse.$$$ "::" |-- OuterParse.!!! 
   324   (OuterParse.binding --
   338       (OuterParse.typ -- OuterParse.opt_mixfix' --| OuterParse.where_))
   325     (OuterParse.$$$ "::" |-- OuterParse.!!! (OuterParse.typ -- 
   339   >> OuterParse.triple2;
   326       OuterParse.opt_mixfix' --| OuterParse.where_)) >> OuterParse.triple2) -- 
   340 *}
   327        (SpecParse.opt_thm_name ":" -- OuterParse.prop)
   341 
   328 *}
   342 ML {*
   329 
   343 val quotdef_parser = 
   330 ML {*
   344   (constdecl -- (SpecParse.opt_thm_name ":" -- OuterParse.prop)) 
   331 fun quotdef_cmd ((bind, qtystr, mx), (attr, propstr)) lthy = 
   345 *}
       
   346 
       
   347 ML {*
       
   348 fun quotdef ((bind, qtystr, mx), (attr, propstr)) lthy = 
       
   349 let
   332 let
   350   val qty  = (Syntax.check_typ lthy o Syntax.parse_typ lthy) qtystr
   333   val qty  = (Syntax.check_typ lthy o Syntax.parse_typ lthy) qtystr
   351   val prop = (Syntax.check_prop lthy o Syntax.parse_prop lthy) propstr
   334   val prop = (Syntax.check_prop lthy o Syntax.parse_prop lthy) propstr
   352 in
   335 in
   353   quotdef_cmd ((bind, qty, mx), (attr, prop)) lthy |> snd
   336   quotdef ((bind, qty, mx), (attr, prop)) lthy |> snd
   354 end
   337 end
   355 *}
   338 *}
   356 
   339 
   357 ML {*
   340 ML {*
   358 val _ = OuterSyntax.local_theory "quotient_def" "lifted definition of constants"
   341 val _ = OuterSyntax.local_theory "quotient_def" "lifted definition of constants"
   359   OuterKeyword.thy_decl (quotdef_parser >> quotdef)
   342   OuterKeyword.thy_decl (quotdef_parser >> quotdef_cmd)
   360 *}
   343 *}
   361 
   344 
   362 section {* ATOMIZE *}
   345 section {* ATOMIZE *}
   363 
   346 
   364 text {*
   347 text {*
   593 ML {*
   576 ML {*
   594 fun old_get_fun flag rty qty lthy ty =
   577 fun old_get_fun flag rty qty lthy ty =
   595   get_fun flag [(qty, rty)] lthy ty 
   578   get_fun flag [(qty, rty)] lthy ty 
   596 
   579 
   597 fun old_make_const_def nconst_bname otrm mx rty qty lthy =
   580 fun old_make_const_def nconst_bname otrm mx rty qty lthy =
   598   make_const_def nconst_bname otrm mx [(qty, rty)] lthy
   581   make_def nconst_bname otrm qty mx [(qty, rty)] lthy
   599 *}
   582 *}
   600 
   583 
   601 text {* Does the same as 'subst' in a given prop or theorem *}
   584 text {* Does the same as 'subst' in a given prop or theorem *}
   602 ML {*
   585 ML {*
   603 fun eqsubst_prop ctxt thms t =
   586 fun eqsubst_prop ctxt thms t =