src/HOLCF/Tools/Domain/domain_isomorphism.ML
changeset 34149 a0efb4754cb7
parent 33971 9c7fa7f76950
child 35021 c839a4c670c6
equal deleted inserted replaced
34148:5aa816a3f78a 34149:a0efb4754cb7
     5 *)
     5 *)
     6 
     6 
     7 signature DOMAIN_ISOMORPHISM =
     7 signature DOMAIN_ISOMORPHISM =
     8 sig
     8 sig
     9   val domain_isomorphism:
     9   val domain_isomorphism:
    10     (string list * binding * mixfix * typ) list -> theory -> theory
    10     (string list * binding * mixfix * typ * (binding * binding) option) list
       
    11       -> theory -> theory
    11   val domain_isomorphism_cmd:
    12   val domain_isomorphism_cmd:
    12     (string list * binding * mixfix * string) list -> theory -> theory
    13     (string list * binding * mixfix * string * (binding * binding) option) list
       
    14       -> theory -> theory
    13   val add_type_constructor:
    15   val add_type_constructor:
    14     (string * term * string * thm  * thm * thm) -> theory -> theory
    16     (string * term * string * thm  * thm * thm) -> theory -> theory
    15   val get_map_tab:
    17   val get_map_tab:
    16     theory -> string Symtab.table
    18     theory -> string Symtab.table
    17 end;
    19 end;
   314       | dups => error ("Inconsistent sort constraints for " ^ commas dups)
   316       | dups => error ("Inconsistent sort constraints for " ^ commas dups)
   315   in (T, sorts') end;
   317   in (T, sorts') end;
   316 
   318 
   317 fun gen_domain_isomorphism
   319 fun gen_domain_isomorphism
   318     (prep_typ: theory -> 'a -> (string * sort) list -> typ * (string * sort) list)
   320     (prep_typ: theory -> 'a -> (string * sort) list -> typ * (string * sort) list)
   319     (doms_raw: (string list * binding * mixfix * 'a) list)
   321     (doms_raw: (string list * binding * mixfix * 'a * (binding * binding) option) list)
   320     (thy: theory)
   322     (thy: theory)
   321     : theory =
   323     : theory =
   322   let
   324   let
   323     val _ = Theory.requires thy "Representable" "domain isomorphisms";
   325     val _ = Theory.requires thy "Representable" "domain isomorphisms";
   324 
   326 
   325     (* this theory is used just for parsing *)
   327     (* this theory is used just for parsing *)
   326     val tmp_thy = thy |>
   328     val tmp_thy = thy |>
   327       Theory.copy |>
   329       Theory.copy |>
   328       Sign.add_types (map (fn (tvs, tname, mx, _) =>
   330       Sign.add_types (map (fn (tvs, tname, mx, _, morphs) =>
   329         (tname, length tvs, mx)) doms_raw);
   331         (tname, length tvs, mx)) doms_raw);
   330 
   332 
   331     fun prep_dom thy (vs, t, mx, typ_raw) sorts =
   333     fun prep_dom thy (vs, t, mx, typ_raw, morphs) sorts =
   332       let val (typ, sorts') = prep_typ thy typ_raw sorts
   334       let val (typ, sorts') = prep_typ thy typ_raw sorts
   333       in ((vs, t, mx, typ), sorts') end;
   335       in ((vs, t, mx, typ, morphs), sorts') end;
   334 
   336 
   335     val (doms : (string list * binding * mixfix * typ) list,
   337     val (doms : (string list * binding * mixfix * typ * (binding * binding) option) list,
   336          sorts : (string * sort) list) =
   338          sorts : (string * sort) list) =
   337       fold_map (prep_dom tmp_thy) doms_raw [];
   339       fold_map (prep_dom tmp_thy) doms_raw [];
   338 
   340 
   339     (* domain equations *)
   341     (* domain equations *)
   340     fun mk_dom_eqn (vs, tbind, mx, rhs) =
   342     fun mk_dom_eqn (vs, tbind, mx, rhs, morphs) =
   341       let fun arg v = TFree (v, the (AList.lookup (op =) sorts v));
   343       let fun arg v = TFree (v, the (AList.lookup (op =) sorts v));
   342       in (Type (Sign.full_name tmp_thy tbind, map arg vs), rhs) end;
   344       in (Type (Sign.full_name tmp_thy tbind, map arg vs), rhs) end;
   343     val dom_eqns = map mk_dom_eqn doms;
   345     val dom_eqns = map mk_dom_eqn doms;
   344 
   346 
   345     (* check for valid type parameters *)
   347     (* check for valid type parameters *)
   346     val (tyvars, _, _, _)::_ = doms;
   348     val (tyvars, _, _, _, _)::_ = doms;
   347     val new_doms = map (fn (tvs, tname, mx, _) =>
   349     val new_doms = map (fn (tvs, tname, mx, _, _) =>
   348       let val full_tname = Sign.full_name tmp_thy tname
   350       let val full_tname = Sign.full_name tmp_thy tname
   349       in
   351       in
   350         (case duplicates (op =) tvs of
   352         (case duplicates (op =) tvs of
   351           [] =>
   353           [] =>
   352             if eq_set (op =) (tyvars, tvs) then (full_tname, tvs)
   354             if eq_set (op =) (tyvars, tvs) then (full_tname, tvs)
   353             else error ("Mutually recursive domains must have same type parameters")
   355             else error ("Mutually recursive domains must have same type parameters")
   354         | dups => error ("Duplicate parameter(s) for domain " ^ quote (Binding.str_of tname) ^
   356         | dups => error ("Duplicate parameter(s) for domain " ^ quote (Binding.str_of tname) ^
   355             " : " ^ commas dups))
   357             " : " ^ commas dups))
   356       end) doms;
   358       end) doms;
   357     val dom_binds = map (fn (_, tbind, _, _) => tbind) doms;
   359     val dom_binds = map (fn (_, tbind, _, _, _) => tbind) doms;
       
   360     val morphs = map (fn (_, _, _, _, morphs) => morphs) doms;
   358 
   361 
   359     (* declare deflation combinator constants *)
   362     (* declare deflation combinator constants *)
   360     fun declare_defl_const (vs, tbind, mx, rhs) thy =
   363     fun declare_defl_const (vs, tbind, mx, rhs, morphs) thy =
   361       let
   364       let
   362         val defl_type = Library.foldr cfunT (map (K deflT) vs, deflT);
   365         val defl_type = Library.foldr cfunT (map (K deflT) vs, deflT);
   363         val defl_bind = Binding.suffix_name "_defl" tbind;
   366         val defl_bind = Binding.suffix_name "_defl" tbind;
   364       in
   367       in
   365         Sign.declare_const ((defl_bind, defl_type), NoSyn) thy
   368         Sign.declare_const ((defl_bind, defl_type), NoSyn) thy
   381     val defl_binds = map (Binding.suffix_name "_defl") dom_binds;
   384     val defl_binds = map (Binding.suffix_name "_defl") dom_binds;
   382     val ((defl_apply_thms, defl_unfold_thms), thy) =
   385     val ((defl_apply_thms, defl_unfold_thms), thy) =
   383       add_fixdefs (defl_binds ~~ defl_specs) thy;
   386       add_fixdefs (defl_binds ~~ defl_specs) thy;
   384 
   387 
   385     (* define types using deflation combinators *)
   388     (* define types using deflation combinators *)
   386     fun make_repdef ((vs, tbind, mx, _), defl_const) thy =
   389     fun make_repdef ((vs, tbind, mx, _, _), defl_const) thy =
   387       let
   390       let
   388         fun tfree a = TFree (a, the (AList.lookup (op =) sorts a))
   391         fun tfree a = TFree (a, the (AList.lookup (op =) sorts a))
   389         val reps = map (mk_Rep_of o tfree) vs;
   392         val reps = map (mk_Rep_of o tfree) vs;
   390         val defl = Library.foldl mk_capply (defl_const, reps);
   393         val defl = Library.foldl mk_capply (defl_const, reps);
   391         val ((_, _, _, {REP, ...}), thy) =
   394         val ((_, _, _, {REP, ...}), thy) =
   414     val (_, thy) = thy |>
   417     val (_, thy) = thy |>
   415       (PureThy.add_thms o map Thm.no_attributes)
   418       (PureThy.add_thms o map Thm.no_attributes)
   416         (REP_eq_binds ~~ REP_eq_thms);
   419         (REP_eq_binds ~~ REP_eq_thms);
   417 
   420 
   418     (* define rep/abs functions *)
   421     (* define rep/abs functions *)
   419     fun mk_rep_abs (tbind, (lhsT, rhsT)) thy =
   422     fun mk_rep_abs ((tbind, morphs), (lhsT, rhsT)) thy =
   420       let
   423       let
   421         val rep_type = cfunT (lhsT, rhsT);
   424         val rep_type = cfunT (lhsT, rhsT);
   422         val abs_type = cfunT (rhsT, lhsT);
   425         val abs_type = cfunT (rhsT, lhsT);
   423         val rep_bind = Binding.suffix_name "_rep" tbind;
   426         val rep_bind = Binding.suffix_name "_rep" tbind;
   424         val abs_bind = Binding.suffix_name "_abs" tbind;
   427         val abs_bind = Binding.suffix_name "_abs" tbind;
       
   428         val (rep_bind, abs_bind) = the_default (rep_bind, abs_bind) morphs;
   425         val (rep_const, thy) = thy |>
   429         val (rep_const, thy) = thy |>
   426           Sign.declare_const ((rep_bind, rep_type), NoSyn);
   430           Sign.declare_const ((rep_bind, rep_type), NoSyn);
   427         val (abs_const, thy) = thy |>
   431         val (abs_const, thy) = thy |>
   428           Sign.declare_const ((abs_bind, abs_type), NoSyn);
   432           Sign.declare_const ((abs_bind, abs_type), NoSyn);
   429         val rep_eqn = Logic.mk_equals (rep_const, coerce_const rep_type);
   433         val rep_eqn = Logic.mk_equals (rep_const, coerce_const rep_type);
   434              (Binding.suffix_name "_abs_def" tbind, abs_eqn)];
   438              (Binding.suffix_name "_abs_def" tbind, abs_eqn)];
   435       in
   439       in
   436         (((rep_const, abs_const), (rep_def, abs_def)), thy)
   440         (((rep_const, abs_const), (rep_def, abs_def)), thy)
   437       end;
   441       end;
   438     val ((rep_abs_consts, rep_abs_defs), thy) = thy
   442     val ((rep_abs_consts, rep_abs_defs), thy) = thy
   439       |> fold_map mk_rep_abs (dom_binds ~~ dom_eqns)
   443       |> fold_map mk_rep_abs (dom_binds ~~ morphs ~~ dom_eqns)
   440       |>> ListPair.unzip;
   444       |>> ListPair.unzip;
   441 
   445 
   442     (* prove isomorphism and isodefl rules *)
   446     (* prove isomorphism and isodefl rules *)
   443     fun mk_iso_thms ((tbind, REP_eq), (rep_def, abs_def)) thy =
   447     fun mk_iso_thms ((tbind, REP_eq), (rep_def, abs_def)) thy =
   444       let
   448       let
   691 
   695 
   692 local
   696 local
   693 
   697 
   694 structure P = OuterParse and K = OuterKeyword
   698 structure P = OuterParse and K = OuterKeyword
   695 
   699 
   696 val parse_domain_iso : (string list * binding * mixfix * string) parser =
   700 val parse_domain_iso :
   697   (P.type_args -- P.binding -- P.opt_infix -- (P.$$$ "=" |-- P.typ))
   701     (string list * binding * mixfix * string * (binding * binding) option)
   698     >> (fn (((vs, t), mx), rhs) => (vs, t, mx, rhs));
   702       parser =
       
   703   (P.type_args -- P.binding -- P.opt_infix -- (P.$$$ "=" |-- P.typ) --
       
   704     Scan.option (P.$$$ "morphisms" |-- P.!!! (P.binding -- P.binding)))
       
   705     >> (fn ((((vs, t), mx), rhs), morphs) => (vs, t, mx, rhs, morphs));
   699 
   706 
   700 val parse_domain_isos = P.and_list1 parse_domain_iso;
   707 val parse_domain_isos = P.and_list1 parse_domain_iso;
   701 
   708 
   702 in
   709 in
   703 
   710