Quotients.thy
author Cezary Kaliszyk <kaliszyk@in.tum.de>
Tue, 24 Nov 2009 08:36:28 +0100
changeset 356 51aafebf4d06
parent 3 672e14609e6e
child 538 bce41bea3de2
permissions -rw-r--r--
Another theorem for which the new regularize differs from old one, so the goal is not proved. But it seems, that the new one is better.

theory Quotients
imports Main
begin

definition
  "REFL E \<equiv> \<forall>x. E x x"

definition 
  "SYM E \<equiv> \<forall>x y. E x y \<longrightarrow> E y x"

definition
  "TRANS E \<equiv> \<forall>x y z. E x y \<and> E y z \<longrightarrow> E x z"

definition
  "NONEMPTY E \<equiv> \<exists>x. E x x"

definition 
  "EQUIV E \<equiv> REFL E \<and> SYM E \<and> TRANS E" 

definition 
  "EQUIV_PROP E \<equiv> (\<forall>x y. E x y = (E x = E y))"

lemma EQUIV_PROP_EQUALITY:
  shows "EQUIV_PROP (op =)"
unfolding EQUIV_PROP_def expand_fun_eq
by (blast)

lemma EQUIV_implies_EQUIV_PROP:
  assumes a: "REFL E"
  and     b: "SYM E"
  and     c: "TRANS E"
  shows "EQUIV_PROP E"
using a b c
unfolding EQUIV_PROP_def REFL_def SYM_def TRANS_def expand_fun_eq
by (metis)

lemma EQUIV_PROP_implies_REFL:
  assumes a: "EQUIV_PROP E"
  shows "REFL E"
using a
unfolding EQUIV_PROP_def REFL_def expand_fun_eq
by (metis)

lemma EQUIV_PROP_implies_SYM:
  assumes a: "EQUIV_PROP E"
  shows "SYM E"
using a
unfolding EQUIV_PROP_def SYM_def expand_fun_eq
by (metis)

lemma EQUIV_PROP_implies_TRANS:
  assumes a: "EQUIV_PROP E"
  shows "TRANS E"
using a
unfolding EQUIV_PROP_def TRANS_def expand_fun_eq
by (blast)

ML {* 
fun equiv_refl thm = thm RS @{thm EQUIV_PROP_implies_REFL} 
fun equiv_sym thm = thm RS @{thm EQUIV_PROP_implies_SYM} 
fun equiv_trans thm = thm RS @{thm EQUIV_PROP_implies_TRANS} 

fun refl_sym_trans_equiv thm1 thm2 thm3 = [thm1,thm2,thm3] MRS @{thm EQUIV_implies_EQUIV_PROP} 
*}


fun
  LIST_REL
where
  "LIST_REL R [] [] = True"
| "LIST_REL R (x#xs) [] = False"
| "LIST_REL R [] (x#xs) = False"
| "LIST_REL R (x#xs) (y#ys) = (R x y \<and> LIST_REL R xs ys)"

fun 
  OPTION_REL 
where
  "OPTION_REL R None None = True"
| "OPTION_REL R (Some x) None = False"
| "OPTION_REL R None (Some x) = False"
| "OPTION_REL R (Some x) (Some y) = R x y"

fun
  option_map
where
  "option_map f None = None"
| "option_map f (Some x) = Some (f x)"

fun 
  PROD_REL
where
  "PROD_REL R1 R2 (a1,a2) (b1,b2) = (R1 a1 b1 \<and> R2 a2 b2)"

fun
  prod_map
where
  "prod_map f1 f2 (a,b) = (f1 a, f2 b)"

fun
  SUM_REL  
where
  "SUM_REL R1 R2 (Inl a1) (Inl b1) = R1 a1 b1"
| "SUM_REL R1 R2 (Inl a1) (Inr b2) = False"
| "SUM_REL R1 R2 (Inr a2) (Inl b1) = False"
| "SUM_REL R1 R2 (Inr a2) (Inr b2) = R2 a2 b2"

fun
  sum_map
where
  "sum_map f1 f2 (Inl a) = Inl (f1 a)"
| "sum_map f1 f2 (Inr a) = Inr (f2 a)"

fun
  FUN_REL 
where
  "FUN_REL R1 R2 f g = (\<forall>x y. R1 x y \<longrightarrow> R2 (f x) (g y))"

fun
  fun_map
where
  "fun_map f g h x = g (h (f x))" 

definition 
  "QUOTIENT_ABS_REP Abs Rep \<equiv> (\<forall>a. Abs (Rep a) = a)"



definition
  "QUOTIENT R Abs Rep \<equiv> (\<forall>a. Abs (Rep a) = a) \<and> 
                        (\<forall>a. R (Rep a) (Rep a)) \<and> 
                        (\<forall>r s. R r s = (R r r \<and> R s s \<and> (Abs r = Abs s)))"

lemma QUOTIENT_ID:
  shows "QUOTIENT (op =) id id"
unfolding QUOTIENT_def id_def
by (blast)

lemma QUOTIENT_PROD:
  assumes a: "QUOTIENT E1 Abs1 Rep1"
  and     b: "QUOTIENT E2 Abs2 Rep2"
  shows "QUOTIENT (PROD_REL E1 E2) (prod_map Abs1 Abs2) (prod_map Rep1 Rep2)"
using a b unfolding QUOTIENT_def
oops

lemma QUOTIENT_ABS_REP_LIST:
  assumes a: "QUOTIENT_ABS_REP Abs Rep"
  shows "QUOTIENT_ABS_REP (map Abs) (map Rep)"
using a
unfolding QUOTIENT_ABS_REP_def
apply(rule_tac allI)
apply(induct_tac a rule: list.induct)
apply(auto)
done

definition
  eqclass ("[_]_")
where
  "[x]E \<equiv> E x"

definition
 QUOTIENT_SET :: "'a set \<Rightarrow> ('a \<Rightarrow>'a\<Rightarrow>bool) \<Rightarrow> ('a set) set" ("_'/#'/_")
where
 "S/#/E = {[x]E | x. x\<in>S}"

definition
 QUOTIENT_UNIV
where
 "QUOTIENT_UNIV TYPE('a) E \<equiv> (UNIV::'a set)/#/E"

consts MY::"'a\<Rightarrow>'a\<Rightarrow>bool"
axioms my1: "REFL MY"
axioms my2: "SYM MY"
axioms my3: "TRANS MY"

term "QUOTIENT_UNIV TYPE('a) MY"
term "\<lambda>f. \<exists>x. f = [x]MY"

typedef 'a quot = "\<lambda>f::'a\<Rightarrow>bool. \<exists>x. f = [x]MY"
by (auto simp add: mem_def)

thm Abs_quot_inverse Rep_quot_inverse Abs_quot_inject Rep_quot_inject Rep_quot
thm Abs_quot_cases Rep_quot_cases Abs_quot_induct Rep_quot_induct

lemma lem2:
  shows "([x]MY = [y]MY) = MY x y"
apply(rule iffI)
apply(simp add: eqclass_def)
using my1
apply(auto simp add: REFL_def)[1]
apply(simp add: eqclass_def expand_fun_eq)
apply(rule allI)
apply(rule iffI)
apply(subgoal_tac "MY y x")
using my3
apply(simp add: TRANS_def)[1]
apply(drule_tac x="y" in spec)
apply(drule_tac x="x" in spec)
apply(drule_tac x="xa" in spec)
apply(simp)
using my2
apply(simp add: SYM_def)[1]
oops

lemma lem6:
  "\<forall>a. \<exists>r. Rep_quot a = [r]MY"
apply(rule allI)
apply(subgoal_tac "Rep_quot a \<in> quot")
apply(simp add: quot_def mem_def)
apply(rule Rep_quot)
done

lemma lem7:
  "\<forall>x y. (Abs_quot ([x]MY) = Abs_quot ([y]MY)) = ([x]MY = [y]MY)"
apply(subst Abs_quot_inject)
apply(unfold quot_def mem_def)
apply(auto)
done

definition
  "Abs x = Abs_quot ([x]MY)"

definition
  "Rep a = Eps (Rep_quot a)"

lemma lem9:
  "\<forall>r. [(Eps [r]MY)]MY = [r]MY"
apply(rule allI)
apply(subgoal_tac "MY r r \<Longrightarrow> MY r (Eps (MY r))")
apply(drule meta_mp)
apply(rule eq1[THEN spec])


apply(rule_tac x="MY r" in someI)

lemma 
  "(f \<in> UNIV/#/MY) = (Rep_quot (Abs_quot f) = f)"
apply(simp add: QUOTIENT_SET_def)
apply(auto)
apply(subgoal_tac "[x]MY \<in> quot")
apply(simp add: Abs_quot_inverse)
apply(simp add: quot_def)
apply(simp add: QUOTIENT_UNIV_def QUOTIENT_SET_def)
apply(auto)[1]
apply(subgoal_tac "[x]MY \<in> quot")
apply(simp add: Abs_quot_inverse)
apply(simp add: quot_def)
apply(simp add: QUOTIENT_UNIV_def QUOTIENT_SET_def)
apply(auto)[1]
apply(subst expand_set_eq)
thm Abs_quot_inverse Rep_quot_inverse Abs_quot_inject Rep_quot_inject Rep_quot

lemma
  "\<forall>a. \<exists>r. Rep_quot a = [r]MY"
apply(rule allI)
apply(subst Abs_quot_inject[symmetric])
apply(rule Rep_quot)
apply(simp add: quot_def)
apply(simp add: QUOTIENT_UNIV_def QUOTIENT_SET_def)
apply(auto)[1]
apply(simp add: Rep_quot_inverse)
thm Abs_quot_inverse Rep_quot_inverse Abs_quot_inject Rep_quot_inject Rep_quot
apply(subst Abs_quot_inject[symmetric])
proof -
  have "[r]MY \<in> quot"
    apply(simp add: quot_def)
    apply(simp add: QUOTIENT_UNIV_def QUOTIENT_SET_def)
    apply(auto)

thm Abs_quot_inverse


thm Abs_quot_inverse
apply(simp add: Rep_quot_inverse)


thm Rep_quot_inverse

term ""

lemma
  assumes a: "EQUIV2 E"
  shows "([x]E = [y]E) = E x y"
using a
by (simp add: eqclass_def EQUIV2_def)





lemma 
  shows "QUOTIENT (op =) (\<lambda>x. x) (\<lambda>x. x)"
apply(unfold QUOTIENT_def)
apply(blast)
done

definition
  fun_app ("_ ---> _")
where
  "f ---> g \<equiv> \<lambda>h x. g (h (f x))"

lemma helper:
  assumes q: "QUOTIENT R ab re"
  and     a: "R z z"
  shows "R (re (ab z)) z"
using q a
apply(unfold QUOTIENT_def)[1]
apply(blast)
done


lemma
  assumes q1: "QUOTIENT R1 abs1 rep1"
  and     q2: "QUOTIENT R2 abs2 rep2"
  shows "QUOTIENT (R1 ===> R2) (rep1 ---> abs2) (abs1 ---> rep2)"
proof -
  have "\<forall>a. (rep1 ---> abs2) ((abs1 ---> rep2) a) = a"
    apply(simp add: expand_fun_eq)
    apply(simp add: fun_app_def)
    using q1 q2
    apply(simp add: QUOTIENT_def)
    done
  moreover
  have "\<forall>a. (R1 ===> R2) ((abs1 ---> rep2) a) ((abs1 ---> rep2) a)"
    apply(simp add: FUN_REL_def)
    apply(auto)
    apply(simp add: fun_app_def)
    using q1 q2
    apply(unfold QUOTIENT_def)
    apply(metis)
    done
  moreover
  have "\<forall>r s. (R1 ===> R2) r s = ((R1 ===> R2) r r \<and> (R1 ===> R2) s s \<and> 
        (rep1 ---> abs2) r  = (rep1 ---> abs2) s)"
    apply(simp add: expand_fun_eq)
    apply(rule allI)+
    apply(rule iffI)
    using q1 q2
    apply(unfold QUOTIENT_def)[1]
    apply(unfold fun_app_def)[1]
    apply(unfold FUN_REL_def)[1]
    apply(rule conjI)
    apply(metis)
    apply(rule conjI)
    apply(metis)
    apply(metis)
    apply(erule conjE)
    apply(simp (no_asm) add: FUN_REL_def)
    apply(rule allI impI)+
    apply(subgoal_tac "R1 x x \<and> R1 y y \<and> abs1 x = abs1 y")(*A*)
    using q2
    apply(unfold QUOTIENT_def)[1]
    apply(unfold fun_app_def)[1]
    apply(unfold FUN_REL_def)[1]
    apply(subgoal_tac "R2 (r x) (r x)")(*B*)
    apply(subgoal_tac "R2 (s y) (s y)")(*C*)
    apply(subgoal_tac "abs2 (r x) = abs2 (s y)")(*D*)
    apply(blast)
    (*D*)
    apply(metis helper q1)
    (*C*)
    apply(blast)
    (*B*)
    apply(blast)
    (*A*)
    using q1
    apply(unfold QUOTIENT_def)[1]
    apply(unfold fun_app_def)[1]
    apply(unfold FUN_REL_def)[1]
    apply(metis)
    done
  ultimately
  show "QUOTIENT (R1 ===> R2) (rep1 ---> abs2) (abs1 ---> rep2)"
    apply(unfold QUOTIENT_def)[1]
    apply(blast)
    done
qed
    
    
    
    



definition 
  "USER R \<equiv> NONEMPTY R \<and> 



typedecl tau
consts R::"tau \<Rightarrow> tau \<Rightarrow> bool"



definition
  FACTOR :: "'a set \<Rightarrow> ('a \<times>'a \<Rightarrow> bool) \<Rightarrow> ('a set) set" ("_ '/'/'/ _")
where
  "A /// r \<equiv> \<Union>x\<in>A. {r``{x}}"

typedef qtau = "\<lambda>c::tau\<Rightarrow>bool. (\<exists>x. R x x \<and> (c = R x))"
apply(rule exI)

apply(rule_tac x="R x" in exI)
apply(auto)

definition  
 "QUOT TYPE('a) R \<equiv> \<lambda>c::'a\<Rightarrow>bool. (\<exists>x. R x x \<and> (c = R x))"