diff -r b82e765ca464 -r df225aa45770 QuotMain.thy --- a/QuotMain.thy Wed Nov 04 09:52:31 2009 +0100 +++ b/QuotMain.thy Wed Nov 04 10:31:20 2009 +0100 @@ -143,12 +143,6 @@ (* the auxiliary data for the quotient types *) use "quotient_info.ML" -ML {* -fun error_msg pre post msg = - msg |> quote - |> enclose (pre ^ " ") (" " ^ post) - |> error -*} declare [[map list = (map, LIST_REL)]] declare [[map * = (prod_fun, prod_rel)]] @@ -175,13 +169,9 @@ section {* lifting of constants *} ML {* -fun lookup_snd _ [] _ = NONE - | lookup_snd eq ((value, key)::xs) key' = - if eq (key', key) then SOME value - else lookup_snd eq xs key'; fun lookup_qenv qenv qty = - (case (AList.lookup (op =) qenv qty) of + (case (AList.lookup (op=) qenv qty) of SOME rty => SOME (qty, rty) | NONE => NONE) *} @@ -210,7 +200,7 @@ in (case (maps_lookup (ProofContext.theory_of lthy) s) of SOME info => (list_comb (Const (#mapfun info, ftys ---> (oty --> nty)), fs), (oty, nty)) - | NONE => raise ERROR ("no map association for type " ^ s)) + | NONE => error ("no map association for type " ^ s)) end fun get_fun_fun fs_tys = @@ -237,7 +227,7 @@ fun mk_identity ty = Abs ("", ty, Bound 0) in - if (AList.defined (op =) qenv ty) + if (AList.defined (op=) qenv ty) then (get_const flag (the (lookup_qenv qenv ty))) else (case ty of TFree _ => (mk_identity ty, (ty, ty)) @@ -250,64 +240,26 @@ end *} -text {* produces the definition for a lifted constant *} - ML {* -fun get_const_def nconst otrm qenv lthy = +fun make_def nconst_bname rhs qty mx qenv lthy = let - val ty = fastype_of nconst - val (arg_tys, res_ty) = strip_type ty + val (arg_tys, res_ty) = strip_type qty val rep_fns = map (fst o get_fun repF qenv lthy) arg_tys val abs_fn = (fst o get_fun absF qenv lthy) res_ty - fun mk_fun_map (t1,t2) = Const (@{const_name "fun_map"}, dummyT) $ t1 $ t2 - - val fns = Library.foldr mk_fun_map (rep_fns, abs_fn) - |> Syntax.check_term lthy -in - fns $ otrm -end -*} - - -ML {* -fun exchange_ty qenv ty = - case (lookup_snd (op =) qenv ty) of - SOME qty => qty - | NONE => - (case ty of - Type (s, tys) => Type (s, map (exchange_ty qenv) tys) - | _ => ty - ) -*} + fun mk_fun_map t s = + Const (@{const_name "fun_map"}, dummyT) $ t $ s -ML {* -fun ppair lthy (ty1, ty2) = - "(" ^ (Syntax.string_of_typ lthy ty1) ^ "," ^ (Syntax.string_of_typ lthy ty2) ^ ")" -*} - -ML {* -fun print_env qenv lthy = - map (ppair lthy) qenv - |> commas - |> tracing -*} - -ML {* -fun make_const_def nconst_bname otrm mx qenv lthy = -let - val otrm_ty = fastype_of otrm - val nconst_ty = exchange_ty qenv otrm_ty - val nconst = Const (Binding.name_of nconst_bname, nconst_ty) - val def_trm = get_const_def nconst otrm qenv lthy + val absrep_fn = fold_rev mk_fun_map rep_fns abs_fn + |> Syntax.check_term lthy in - define (nconst_bname, mx, def_trm) lthy + define (nconst_bname, mx, absrep_fn $ rhs) lthy end *} ML {* -(* difference of two types *) +(* returns all subterms where two types differ *) fun diff (T, S) Ds = case (T, S) of (TVar v, TVar u) => if v = u then Ds else (T, S)::Ds @@ -321,42 +273,73 @@ *} ML {* -fun quotdef_cmd ((bind, qty, mx), (attr, prop)) lthy = -let - val (_, rhs) = Logic.dest_equals prop - val rty = fastype_of rhs - val qenv = distinct (op=) (diff (qty, rty) []) +fun error_msg lthy (qty, rty) = +let + val qtystr = quote (Syntax.string_of_typ lthy qty) + val rtystr = quote (Syntax.string_of_typ lthy rty) in - make_const_def bind rhs mx qenv lthy + error (implode ["Quotient type ", qtystr, " does not match with ", rtystr]) +end + + +fun sanity_chk lthy qenv = +let + val qenv' = Quotient_Info.mk_qenv lthy + val thy = ProofContext.theory_of lthy + + fun is_inst thy (qty, rty) (qty', rty') = + if Sign.typ_instance thy (qty, qty') + then let + val inst = Sign.typ_match thy (qty', qty) Vartab.empty + in + rty = Envir.subst_type inst rty' + end + else false + + fun chk_inst (qty, rty) = + if exists (is_inst thy (qty, rty)) qenv' then true + else error_msg lthy (qty, rty) +in + forall chk_inst qenv end *} ML {* -val constdecl = - OuterParse.binding -- - (OuterParse.$$$ "::" |-- OuterParse.!!! - (OuterParse.typ -- OuterParse.opt_mixfix' --| OuterParse.where_)) - >> OuterParse.triple2; +fun quotdef ((bind, qty, mx), (attr, prop)) lthy = +let + val (_, prop') = PrimitiveDefs.dest_def lthy (K true) (K false) (K false) prop + val (_, rhs) = PrimitiveDefs.abs_def prop' + + val rty = fastype_of rhs + val qenv = distinct (op=) (diff (qty, rty) []) + +in + sanity_chk lthy qenv; + make_def bind rhs qty mx qenv lthy +end *} ML {* -val quotdef_parser = - (constdecl -- (SpecParse.opt_thm_name ":" -- OuterParse.prop)) +val quotdef_parser = + (OuterParse.binding -- + (OuterParse.$$$ "::" |-- OuterParse.!!! (OuterParse.typ -- + OuterParse.opt_mixfix' --| OuterParse.where_)) >> OuterParse.triple2) -- + (SpecParse.opt_thm_name ":" -- OuterParse.prop) *} ML {* -fun quotdef ((bind, qtystr, mx), (attr, propstr)) lthy = +fun quotdef_cmd ((bind, qtystr, mx), (attr, propstr)) lthy = let val qty = (Syntax.check_typ lthy o Syntax.parse_typ lthy) qtystr val prop = (Syntax.check_prop lthy o Syntax.parse_prop lthy) propstr in - quotdef_cmd ((bind, qty, mx), (attr, prop)) lthy |> snd + quotdef ((bind, qty, mx), (attr, prop)) lthy |> snd end *} ML {* val _ = OuterSyntax.local_theory "quotient_def" "lifted definition of constants" - OuterKeyword.thy_decl (quotdef_parser >> quotdef) + OuterKeyword.thy_decl (quotdef_parser >> quotdef_cmd) *} section {* ATOMIZE *} @@ -595,7 +578,7 @@ get_fun flag [(qty, rty)] lthy ty fun old_make_const_def nconst_bname otrm mx rty qty lthy = - make_const_def nconst_bname otrm mx [(qty, rty)] lthy + make_def nconst_bname otrm qty mx [(qty, rty)] lthy *} text {* Does the same as 'subst' in a given prop or theorem *}