src/HOL/Algebra/Congruence.thy
changeset 67999 1b05f74f2e5f
parent 67091 1393c2340eec
child 68072 493b818e8e10
equal deleted inserted replaced
67998:73a5a33486ee 67999:1b05f74f2e5f
     1 (*  Title:      HOL/Algebra/Congruence.thy
     1 (*  Title:      HOL/Algebra/Congruence.thy
     2     Author:     Clemens Ballarin, started 3 January 2008
     2     Author:     Clemens Ballarin, started 3 January 2008
     3     Copyright:  Clemens Ballarin
     3     with thanks to Paulo Emílio de Vilhena
     4 *)
     4 *)
     5 
     5 
     6 theory Congruence
     6 theory Congruence
     7 imports 
     7 imports 
     8   Main
     8   Main
   117   shows "a .\<in> B"
   117   shows "a .\<in> B"
   118 using assms
   118 using assms
   119 by (fast intro: elemI elim: elemE dest: subsetD)
   119 by (fast intro: elemI elim: elemE dest: subsetD)
   120 
   120 
   121 lemma (in equivalence) mem_imp_elem [simp, intro]:
   121 lemma (in equivalence) mem_imp_elem [simp, intro]:
   122   "[| x \<in> A; x \<in> carrier S |] ==> x .\<in> A"
   122   "\<lbrakk> x \<in> A; x \<in> carrier S \<rbrakk> \<Longrightarrow> x .\<in> A"
   123   unfolding elem_def by blast
   123   unfolding elem_def by blast
   124 
   124 
   125 lemma set_eqI:
   125 lemma set_eqI:
   126   fixes R (structure)
   126   fixes R (structure)
   127   assumes ltr: "\<And>a. a \<in> A \<Longrightarrow> a .\<in> B"
   127   assumes ltr: "\<And>a. a \<in> A \<Longrightarrow> a .\<in> B"
   213        show "a .\<in> A'" by simp
   213        show "a .\<in> A'" by simp
   214 qed
   214 qed
   215 
   215 
   216 lemma (in equivalence) set_eq_sym [sym]:
   216 lemma (in equivalence) set_eq_sym [sym]:
   217   assumes "A {.=} B"
   217   assumes "A {.=} B"
   218     and "A \<subseteq> carrier S" "B \<subseteq> carrier S"
       
   219   shows "B {.=} A"
   218   shows "B {.=} A"
   220 using assms
   219 using assms
   221 unfolding set_eq_def elem_def
   220 unfolding set_eq_def elem_def
   222 by fast
   221 by fast
   223 
       
   224 (* FIXME: the following two required in Isabelle 2008, not Isabelle 2007 *)
       
   225 (* alternatively, could declare lemmas [trans] = ssubst [where 'a = "'a set"] *)
       
   226 
   222 
   227 lemma (in equivalence) equal_set_eq_trans [trans]:
   223 lemma (in equivalence) equal_set_eq_trans [trans]:
   228   assumes AB: "A = B" and BC: "B {.=} C"
   224   assumes AB: "A = B" and BC: "B {.=} C"
   229   shows "A {.=} C"
   225   shows "A {.=} C"
   230   using AB BC by simp
   226   using AB BC by simp
   231 
   227 
   232 lemma (in equivalence) set_eq_equal_trans [trans]:
   228 lemma (in equivalence) set_eq_equal_trans [trans]:
   233   assumes AB: "A {.=} B" and BC: "B = C"
   229   assumes AB: "A {.=} B" and BC: "B = C"
   234   shows "A {.=} C"
   230   shows "A {.=} C"
   235   using AB BC by simp
   231   using AB BC by simp
   236 
       
   237 
   232 
   238 lemma (in equivalence) set_eq_trans [trans]:
   233 lemma (in equivalence) set_eq_trans [trans]:
   239   assumes AB: "A {.=} B" and BC: "B {.=} C"
   234   assumes AB: "A {.=} B" and BC: "B {.=} C"
   240     and carr: "A \<subseteq> carrier S"  "B \<subseteq> carrier S"  "C \<subseteq> carrier S"
   235     and carr: "A \<subseteq> carrier S"  "B \<subseteq> carrier S"  "C \<subseteq> carrier S"
   241   shows "A {.=} C"
   236   shows "A {.=} C"
   263   also note AB[symmetric]
   258   also note AB[symmetric]
   264   finally
   259   finally
   265        show "c .\<in> A" by simp
   260        show "c .\<in> A" by simp
   266 qed
   261 qed
   267 
   262 
   268 (* FIXME: generalise for insert *)
   263 lemma (in equivalence) set_eq_insert_aux:
   269 
   264   assumes x: "x .= x'"
   270 (*
   265       and carr: "x \<in> carrier S" "x' \<in> carrier S" "A \<subseteq> carrier S"
       
   266     shows "\<forall>a \<in> (insert x A). a .\<in> (insert x' A)"
       
   267 proof
       
   268   fix a
       
   269   show "a \<in> insert x A \<Longrightarrow> a .\<in> insert x' A"
       
   270   proof cases
       
   271     assume "a \<in> A"
       
   272     thus "a .\<in> insert x' A"
       
   273       using carr(3) by blast
       
   274   next
       
   275     assume "a \<in> insert x A" "a \<notin> A"
       
   276     hence "a = x"
       
   277       by blast
       
   278     thus "a .\<in> insert x' A"
       
   279       by (meson x elemI insertI1)
       
   280   qed
       
   281 qed
       
   282 
   271 lemma (in equivalence) set_eq_insert:
   283 lemma (in equivalence) set_eq_insert:
   272   assumes x: "x .= x'"
   284   assumes x: "x .= x'"
   273     and carr: "x \<in> carrier S" "x' \<in> carrier S" "A \<subseteq> carrier S"
   285       and carr: "x \<in> carrier S" "x' \<in> carrier S" "A \<subseteq> carrier S"
   274   shows "insert x A {.=} insert x' A"
   286     shows "insert x A {.=} insert x' A"
   275   unfolding set_eq_def elem_def
   287 proof-
   276 apply rule
   288   have "(\<forall>a \<in> (insert x  A). a .\<in> (insert x' A)) \<and>
   277 apply rule
   289         (\<forall>a \<in> (insert x' A). a .\<in> (insert x  A))"
   278 apply (case_tac "xa = x")
   290     using set_eq_insert_aux carr x sym by blast
   279 using x apply fast
   291   thus "insert x A {.=} insert x' A"
   280 apply (subgoal_tac "xa \<in> A") prefer 2 apply fast
   292     using set_eq_def by blast
   281 apply (rule_tac x=xa in bexI)
   293 qed  
   282 using carr apply (rule_tac refl) apply auto [1]
       
   283 apply safe
       
   284 *)
       
   285 
   294 
   286 lemma (in equivalence) set_eq_pairI:
   295 lemma (in equivalence) set_eq_pairI:
   287   assumes xx': "x .= x'"
   296   assumes xx': "x .= x'"
   288     and carr: "x \<in> carrier S" "x' \<in> carrier S" "y \<in> carrier S"
   297     and carr: "x \<in> carrier S" "x' \<in> carrier S" "y \<in> carrier S"
   289   shows "{x, y} {.=} {x', y}"
   298   shows "{x, y} {.=} {x', y}"
   290 unfolding set_eq_def elem_def
   299   using assms set_eq_insert by simp
   291 proof safe
       
   292   have "x' \<in> {x', y}" by fast
       
   293   with xx' show "\<exists>b\<in>{x', y}. x .= b" by fast
       
   294 next
       
   295   have "y \<in> {x', y}" by fast
       
   296   with carr show "\<exists>b\<in>{x', y}. y .= b" by fast
       
   297 next
       
   298   have "x \<in> {x, y}" by fast
       
   299   with xx'[symmetric] carr
       
   300   show "\<exists>a\<in>{x, y}. x' .= a" by fast
       
   301 next
       
   302   have "y \<in> {x, y}" by fast
       
   303   with carr show "\<exists>a\<in>{x, y}. y .= a" by fast
       
   304 qed
       
   305 
   300 
   306 lemma (in equivalence) is_closedI:
   301 lemma (in equivalence) is_closedI:
   307   assumes closed: "!!x y. [| x .= y; x \<in> A; y \<in> carrier S |] ==> y \<in> A"
   302   assumes closed: "\<And>x y. \<lbrakk>x .= y; x \<in> A; y \<in> carrier S\<rbrakk> \<Longrightarrow> y \<in> A"
   308     and S: "A \<subseteq> carrier S"
   303     and S: "A \<subseteq> carrier S"
   309   shows "is_closed A"
   304   shows "is_closed A"
   310   unfolding eq_is_closed_def eq_closure_of_def elem_def
   305   unfolding eq_is_closed_def eq_closure_of_def elem_def
   311   using S
   306   using S
   312   by (blast dest: closed sym)
   307   by (blast dest: closed sym)
   313 
   308 
   314 lemma (in equivalence) closure_of_eq:
   309 lemma (in equivalence) closure_of_eq:
   315   "[| x .= x'; A \<subseteq> carrier S; x \<in> closure_of A; x \<in> carrier S; x' \<in> carrier S |] ==> x' \<in> closure_of A"
   310   "\<lbrakk>x .= x'; A \<subseteq> carrier S; x \<in> closure_of A; x' \<in> carrier S\<rbrakk> \<Longrightarrow> x' \<in> closure_of A"
   316   unfolding eq_closure_of_def elem_def
   311   unfolding eq_closure_of_def elem_def
   317   by (blast intro: trans sym)
   312   by (blast intro: trans sym)
   318 
   313 
   319 lemma (in equivalence) is_closed_eq [dest]:
   314 lemma (in equivalence) is_closed_eq [dest]:
   320   "[| x .= x'; x \<in> A; is_closed A; x \<in> carrier S; x' \<in> carrier S |] ==> x' \<in> A"
   315   "\<lbrakk>x .= x'; x \<in> A; is_closed A; x \<in> carrier S; x' \<in> carrier S\<rbrakk> \<Longrightarrow> x' \<in> A"
   321   unfolding eq_is_closed_def
   316   unfolding eq_is_closed_def
   322   using closure_of_eq [where A = A]
   317   using closure_of_eq [where A = A]
   323   by simp
   318   by simp
   324 
   319 
   325 lemma (in equivalence) is_closed_eq_rev [dest]:
   320 lemma (in equivalence) is_closed_eq_rev [dest]:
   326   "[| x .= x'; x' \<in> A; is_closed A; x \<in> carrier S; x' \<in> carrier S |] ==> x \<in> A"
   321   "\<lbrakk>x .= x'; x' \<in> A; is_closed A; x \<in> carrier S; x' \<in> carrier S\<rbrakk> \<Longrightarrow> x \<in> A"
   327   by (drule sym) (simp_all add: is_closed_eq)
   322   by (meson subsetD eq_is_closed_def is_closed_eq sym)
   328 
   323 
   329 lemma closure_of_closed [simp, intro]:
   324 lemma closure_of_closed [simp, intro]:
   330   fixes S (structure)
   325   fixes S (structure)
   331   shows "closure_of A \<subseteq> carrier S"
   326   shows "closure_of A \<subseteq> carrier S"
   332 unfolding eq_closure_of_def
   327 unfolding eq_closure_of_def
   333 by fast
   328 by fast
   334 
   329 
   335 lemma closure_of_memI:
   330 lemma closure_of_memI:
   336   fixes S (structure)
   331   fixes S (structure)
   337   assumes "a .\<in> A"
   332   assumes "a .\<in> A" and "a \<in> carrier S"
   338     and "a \<in> carrier S"
       
   339   shows "a \<in> closure_of A"
   333   shows "a \<in> closure_of A"
   340 unfolding eq_closure_of_def
   334   by (simp add: assms eq_closure_of_def)
   341 using assms
       
   342 by fast
       
   343 
   335 
   344 lemma closure_ofI2:
   336 lemma closure_ofI2:
   345   fixes S (structure)
   337   fixes S (structure)
   346   assumes "a .= a'"
   338   assumes "a .= a'" and "a' \<in> A" and "a \<in> carrier S"
   347     and "a' \<in> A"
       
   348     and "a \<in> carrier S"
       
   349   shows "a \<in> closure_of A"
   339   shows "a \<in> closure_of A"
   350 unfolding eq_closure_of_def elem_def
   340   by (meson assms closure_of_memI elem_def)
   351 using assms
       
   352 by fast
       
   353 
   341 
   354 lemma closure_of_memE:
   342 lemma closure_of_memE:
   355   fixes S (structure)
   343   fixes S (structure)
   356   assumes p: "a \<in> closure_of A"
   344   assumes "a \<in> closure_of A"
   357     and r: "\<lbrakk>a \<in> carrier S; a .\<in> A\<rbrakk> \<Longrightarrow> P"
   345     and "\<lbrakk>a \<in> carrier S; a .\<in> A\<rbrakk> \<Longrightarrow> P"
   358   shows "P"
   346   shows "P"
   359 proof -
   347   using eq_closure_of_def assms by fastforce
   360   from p
       
   361       have acarr: "a \<in> carrier S"
       
   362       and "a .\<in> A"
       
   363       by (simp add: eq_closure_of_def)+
       
   364   thus "P" by (rule r)
       
   365 qed
       
   366 
   348 
   367 lemma closure_ofE2:
   349 lemma closure_ofE2:
   368   fixes S (structure)
   350   fixes S (structure)
   369   assumes p: "a \<in> closure_of A"
   351   assumes "a \<in> closure_of A"
   370     and r: "\<And>a'. \<lbrakk>a \<in> carrier S; a' \<in> A; a .= a'\<rbrakk> \<Longrightarrow> P"
   352     and "\<And>a'. \<lbrakk>a \<in> carrier S; a' \<in> A; a .= a'\<rbrakk> \<Longrightarrow> P"
   371   shows "P"
   353   shows "P"
   372 proof -
   354   by (meson closure_of_memE elemE assms)
   373   from p have acarr: "a \<in> carrier S" by (simp add: eq_closure_of_def)
   355 
   374 
   356 lemma (in equivalence) closure_inclusion:
   375   from p have "\<exists>a'\<in>A. a .= a'" by (simp add: eq_closure_of_def elem_def)
   357   assumes "A \<subseteq> B"
   376   from this obtain a'
   358   shows "closure_of A \<subseteq> closure_of B"
   377       where "a' \<in> A" and "a .= a'" by auto
   359   unfolding eq_closure_of_def
   378 
   360 proof
   379   from acarr and this
   361   fix x
   380       show "P" by (rule r)
   362   assume "x \<in> {y \<in> carrier S. y .\<in> A}"
   381 qed
   363   hence "x \<in> carrier S \<and> x .\<in> A"
   382 
   364     by blast
   383 (*
   365   hence "x \<in> carrier S \<and> x .\<in> B"
   384 lemma (in equivalence) classes_consistent:
   366     using assms elem_subsetD by blast
   385   assumes Acarr: "A \<subseteq> carrier S"
   367   thus "x \<in> {y \<in> carrier S. y .\<in> B}"
   386   shows "is_closed (closure_of A)"
   368     by simp
   387 apply (blast intro: elemI elim elemE)
   369 qed
   388 using assms
   370 
   389 apply (intro is_closedI closure_of_memI, simp)
       
   390  apply (elim elemE closure_of_memE)
       
   391 proof -
       
   392   fix x a' a''
       
   393   assume carr: "x \<in> carrier S" "a' \<in> carrier S"
       
   394   assume a''A: "a'' \<in> A"
       
   395   with Acarr have "a'' \<in> carrier S" by fast
       
   396   note [simp] = carr this Acarr
       
   397 
       
   398   assume "x .= a'"
       
   399   also assume "a' .= a''"
       
   400   also from a''A
       
   401        have "a'' .\<in> A" by (simp add: elem_exact)
       
   402   finally show "x .\<in> A" by simp
       
   403 qed
       
   404 *)
       
   405 (*
       
   406 lemma (in equivalence) classes_small:
   371 lemma (in equivalence) classes_small:
   407   assumes "is_closed B"
   372   assumes "is_closed B"
   408     and "A \<subseteq> B"
   373     and "A \<subseteq> B"
   409   shows "closure_of A \<subseteq> B"
   374   shows "closure_of A \<subseteq> B"
   410 using assms
   375 proof-
   411 by (blast dest: is_closedD2 elem_subsetD elim: closure_of_memE)
   376   have "closure_of A \<subseteq> closure_of B"
       
   377     using closure_inclusion assms by simp
       
   378   thus "closure_of A \<subseteq> B"
       
   379     using assms(1) eq_is_closed_def by fastforce
       
   380 qed
   412 
   381 
   413 lemma (in equivalence) classes_eq:
   382 lemma (in equivalence) classes_eq:
   414   assumes "A \<subseteq> carrier S"
   383   assumes "A \<subseteq> carrier S"
   415   shows "A {.=} closure_of A"
   384   shows "A {.=} closure_of A"
   416 using assms
   385 using assms
   417 by (blast intro: set_eqI elem_exact closure_of_memI elim: closure_of_memE)
   386 by (blast intro: set_eqI elem_exact closure_of_memI elim: closure_of_memE)
   418 
   387 
   419 lemma (in equivalence) complete_classes:
   388 lemma (in equivalence) complete_classes:
   420   assumes c: "is_closed A"
   389   assumes c: "is_closed A"
   421   shows "A = closure_of A"
   390   shows "A = closure_of A"
   422 using assms
   391   using assms by (simp add: eq_is_closed_def)
   423 by (blast intro: closure_of_memI elem_exact dest: is_closedD1 is_closedD2 closure_of_memE)
   392 
   424 *)
   393 lemma (in equivalence) closure_idemp_weak:
       
   394   "closure_of (closure_of A) {.=} closure_of A"
       
   395   by (simp add: classes_eq set_eq_sym)
       
   396 
       
   397 lemma (in equivalence) closure_idemp_strong:
       
   398   assumes "A \<subseteq> carrier S"
       
   399   shows "closure_of (closure_of A) = closure_of A"
       
   400   using assms closure_of_eq complete_classes is_closedI by auto
       
   401 
       
   402 lemma (in equivalence) complete_classes2:
       
   403   assumes "A \<subseteq> carrier S"
       
   404   shows "is_closed (closure_of A)"
       
   405   using closure_idemp_strong by (simp add: assms eq_is_closed_def)
   425 
   406 
   426 lemma equivalence_subset:
   407 lemma equivalence_subset:
   427   assumes "equivalence L" "A \<subseteq> carrier L"
   408   assumes "equivalence L" "A \<subseteq> carrier L"
   428   shows "equivalence (L\<lparr> carrier := A \<rparr>)"
   409   shows "equivalence (L\<lparr> carrier := A \<rparr>)"
   429 proof -
   410 proof -