File ‹Tools/cartprod.ML›
signature FP =
sig
val oper : term
val bnd_mono : term
val bnd_monoI : thm
val subs : thm
val Tarski : thm
val induct : thm
end;
signature SU =
sig
val sum : term
val inl : term
val inr : term
val elim : term
val case_inl : thm
val case_inr : thm
val inl_iff : thm
val inr_iff : thm
val distinct : thm
val distinct' : thm
val free_SEs : thm list
end;
signature PR =
sig
val sigma : term
val pair : term
val split_name : string
val pair_iff : thm
val split_eq : thm
val fsplitI : thm
val fsplitD : thm
val fsplitE : thm
end;
signature CARTPROD =
sig
val ap_split : typ -> typ -> term -> term
val factors : typ -> typ list
val mk_prod : typ * typ -> typ
val mk_tuple : term -> typ -> term list -> term
val pseudo_type : term -> typ
val remove_split : Proof.context -> thm -> thm
val split_const : typ -> term
val split_rule_var : Proof.context -> term * typ * thm -> thm
end;
functor CartProd_Fun (Pr: PR) : CARTPROD =
struct
fun mk_prod (T1,T2) = Type("*", [T1,T2]);
fun pseudo_type (t $ A $ Abs(_,_,B)) =
if t = Pr.sigma
then mk_prod(pseudo_type A, pseudo_type B)
else \<^Type>‹i›
| pseudo_type _ = \<^Type>‹i›;
fun factors (Type("*", [T1, T2])) = factors T1 @ factors T2
| factors T = [T];
fun split_const T = Const(Pr.split_name, [[\<^Type>‹i›, \<^Type>‹i›]--->T, \<^Type>‹i›] ---> T);
fun ap_split (Type("*", [T1,T2])) T3 u =
split_const T3 $
Abs("v", \<^Type>‹i›,
ap_split T2 T3
((ap_split T1 (factors T2 ---> T3) (incr_boundvars 1 u)) $
Bound 0))
| ap_split T T3 u = u;
fun mk_tuple pair (Type("*", [T1,T2])) tms =
pair $ mk_tuple pair T1 tms
$ mk_tuple pair T2 (drop (length (factors T1)) tms)
| mk_tuple pair T (t::_) = t;
fun remove_split ctxt = rewrite_rule ctxt [Pr.split_eq];
fun split_rule_var ctxt (Var(v,_), Type("fun",[T1,T2]), rl) =
let val T' = factors T1 ---> T2
val newt = ap_split T1 T2 (Var(v,T'))
in
remove_split ctxt
(Drule.instantiate_normalize (TVars.empty,
Vars.make1 ((v, \<^Type>‹i› --> T2), Thm.cterm_of ctxt newt)) rl)
end
| split_rule_var _ (t,T,rl) = rl;
end;