src/HOL/Enum.thy
changeset 57922 dc78785427d0
parent 57818 51aa30c9ee4e
child 58101 e7ebe5554281
equal deleted inserted replaced
57921:9225b2761126 57922:dc78785427d0
   535 apply (metis finite_1.exhaust)
   535 apply (metis finite_1.exhaust)
   536 done
   536 done
   537 
   537 
   538 end
   538 end
   539 
   539 
       
   540 instance finite_1 :: "{dense_linorder, wellorder}"
       
   541 by intro_classes (simp_all add: less_finite_1_def)
       
   542 
   540 instantiation finite_1 :: complete_lattice
   543 instantiation finite_1 :: complete_lattice
   541 begin
   544 begin
   542 
   545 
   543 definition [simp]: "Inf = (\<lambda>_. a\<^sub>1)"
   546 definition [simp]: "Inf = (\<lambda>_. a\<^sub>1)"
   544 definition [simp]: "Sup = (\<lambda>_. a\<^sub>1)"
   547 definition [simp]: "Sup = (\<lambda>_. a\<^sub>1)"
   553 instance finite_1 :: complete_distrib_lattice
   556 instance finite_1 :: complete_distrib_lattice
   554 by intro_classes(simp_all add: INF_def SUP_def)
   557 by intro_classes(simp_all add: INF_def SUP_def)
   555 
   558 
   556 instance finite_1 :: complete_linorder ..
   559 instance finite_1 :: complete_linorder ..
   557 
   560 
       
   561 lemma finite_1_eq: "x = a\<^sub>1"
       
   562 by(cases x) simp
       
   563 
       
   564 simproc_setup finite_1_eq ("x::finite_1") = {*
       
   565   fn _ => fn _ => fn ct => case term_of ct of
       
   566     Const (@{const_name a\<^sub>1}, _) => NONE
       
   567   | _ => SOME (mk_meta_eq @{thm finite_1_eq})
       
   568 *}
       
   569 
       
   570 instantiation finite_1 :: complete_boolean_algebra begin
       
   571 definition [simp]: "op - = (\<lambda>_ _. a\<^sub>1)"
       
   572 definition [simp]: "uminus = (\<lambda>_. a\<^sub>1)"
       
   573 instance by intro_classes simp_all
       
   574 end
       
   575 
       
   576 instantiation finite_1 :: 
       
   577   "{linordered_ring_strict, linordered_comm_semiring_strict, ordered_comm_ring,
       
   578     ordered_cancel_comm_monoid_diff, comm_monoid_mult, ordered_ring_abs,
       
   579     one, Divides.div, sgn_if, inverse}"
       
   580 begin
       
   581 definition [simp]: "Groups.zero = a\<^sub>1"
       
   582 definition [simp]: "Groups.one = a\<^sub>1"
       
   583 definition [simp]: "op + = (\<lambda>_ _. a\<^sub>1)"
       
   584 definition [simp]: "op * = (\<lambda>_ _. a\<^sub>1)"
       
   585 definition [simp]: "op div = (\<lambda>_ _. a\<^sub>1)" 
       
   586 definition [simp]: "op mod = (\<lambda>_ _. a\<^sub>1)" 
       
   587 definition [simp]: "abs = (\<lambda>_. a\<^sub>1)"
       
   588 definition [simp]: "sgn = (\<lambda>_. a\<^sub>1)"
       
   589 definition [simp]: "inverse = (\<lambda>_. a\<^sub>1)"
       
   590 definition [simp]: "op / = (\<lambda>_ _. a\<^sub>1)"
       
   591 
       
   592 instance by intro_classes(simp_all add: less_finite_1_def)
       
   593 end
       
   594 
       
   595 declare [[simproc del: finite_1_eq]]
   558 hide_const (open) a\<^sub>1
   596 hide_const (open) a\<^sub>1
   559 
   597 
   560 datatype finite_2 = a\<^sub>1 | a\<^sub>2
   598 datatype finite_2 = a\<^sub>1 | a\<^sub>2
   561 
   599 
   562 notation (output) a\<^sub>1  ("a\<^sub>1")
   600 notation (output) a\<^sub>1  ("a\<^sub>1")
   599 apply (auto simp add: less_finite_2_def less_eq_finite_2_def)
   637 apply (auto simp add: less_finite_2_def less_eq_finite_2_def)
   600 apply (metis finite_2.nchotomy)+
   638 apply (metis finite_2.nchotomy)+
   601 done
   639 done
   602 
   640 
   603 end
   641 end
       
   642 
       
   643 instance finite_2 :: wellorder
       
   644 by(rule wf_wellorderI)(simp add: less_finite_2_def, intro_classes)
   604 
   645 
   605 instantiation finite_2 :: complete_lattice
   646 instantiation finite_2 :: complete_lattice
   606 begin
   647 begin
   607 
   648 
   608 definition "\<Sqinter>A = (if a\<^sub>1 \<in> A then a\<^sub>1 else a\<^sub>2)"
   649 definition "\<Sqinter>A = (if a\<^sub>1 \<in> A then a\<^sub>1 else a\<^sub>2)"
   636 instance finite_2 :: complete_distrib_lattice
   677 instance finite_2 :: complete_distrib_lattice
   637 by(intro_classes)(auto simp add: INF_def SUP_def sup_finite_2_def inf_finite_2_def Inf_finite_2_def Sup_finite_2_def)
   678 by(intro_classes)(auto simp add: INF_def SUP_def sup_finite_2_def inf_finite_2_def Inf_finite_2_def Sup_finite_2_def)
   638 
   679 
   639 instance finite_2 :: complete_linorder ..
   680 instance finite_2 :: complete_linorder ..
   640 
   681 
       
   682 instantiation finite_2 :: "{field_inverse_zero, abs_if, ring_div, semiring_div_parity, sgn_if}" begin
       
   683 definition [simp]: "0 = a\<^sub>1"
       
   684 definition [simp]: "1 = a\<^sub>2"
       
   685 definition "x + y = (case (x, y) of (a\<^sub>1, a\<^sub>1) \<Rightarrow> a\<^sub>1 | (a\<^sub>2, a\<^sub>2) \<Rightarrow> a\<^sub>1 | _ \<Rightarrow> a\<^sub>2)"
       
   686 definition "uminus = (\<lambda>x :: finite_2. x)"
       
   687 definition "op - = (op + :: finite_2 \<Rightarrow> _)"
       
   688 definition "x * y = (case (x, y) of (a\<^sub>2, a\<^sub>2) \<Rightarrow> a\<^sub>2 | _ \<Rightarrow> a\<^sub>1)"
       
   689 definition "inverse = (\<lambda>x :: finite_2. x)"
       
   690 definition "op / = (op * :: finite_2 \<Rightarrow> _)"
       
   691 definition "abs = (\<lambda>x :: finite_2. x)"
       
   692 definition "op div = (op / :: finite_2 \<Rightarrow> _)"
       
   693 definition "x mod y = (case (x, y) of (a\<^sub>2, a\<^sub>1) \<Rightarrow> a\<^sub>2 | _ \<Rightarrow> a\<^sub>1)"
       
   694 definition "sgn = (\<lambda>x :: finite_2. x)"
       
   695 instance
       
   696 by intro_classes
       
   697   (simp_all add: plus_finite_2_def uminus_finite_2_def minus_finite_2_def times_finite_2_def
       
   698        inverse_finite_2_def divide_finite_2_def abs_finite_2_def div_finite_2_def mod_finite_2_def sgn_finite_2_def
       
   699      split: finite_2.splits)
       
   700 end
       
   701 
   641 hide_const (open) a\<^sub>1 a\<^sub>2
   702 hide_const (open) a\<^sub>1 a\<^sub>2
   642 
   703 
   643 datatype finite_3 = a\<^sub>1 | a\<^sub>2 | a\<^sub>3
   704 datatype finite_3 = a\<^sub>1 | a\<^sub>2 | a\<^sub>3
   644 
   705 
   645 notation (output) a\<^sub>1  ("a\<^sub>1")
   706 notation (output) a\<^sub>1  ("a\<^sub>1")
   680 
   741 
   681 instance proof (intro_classes)
   742 instance proof (intro_classes)
   682 qed (auto simp add: less_finite_3_def less_eq_finite_3_def split: finite_3.split_asm)
   743 qed (auto simp add: less_finite_3_def less_eq_finite_3_def split: finite_3.split_asm)
   683 
   744 
   684 end
   745 end
       
   746 
       
   747 instance finite_3 :: wellorder
       
   748 proof(rule wf_wellorderI)
       
   749   have "inv_image less_than (case_finite_3 0 1 2) = {(x, y). x < y}"
       
   750     by(auto simp add: less_finite_3_def split: finite_3.splits)
       
   751   from this[symmetric] show "wf \<dots>" by simp
       
   752 qed intro_classes
   685 
   753 
   686 instantiation finite_3 :: complete_lattice
   754 instantiation finite_3 :: complete_lattice
   687 begin
   755 begin
   688 
   756 
   689 definition "\<Sqinter>A = (if a\<^sub>1 \<in> A then a\<^sub>1 else if a\<^sub>2 \<in> A then a\<^sub>2 else a\<^sub>3)"
   757 definition "\<Sqinter>A = (if a\<^sub>1 \<in> A then a\<^sub>1 else if a\<^sub>2 \<in> A then a\<^sub>2 else a\<^sub>3)"
   728       (auto simp add: SUP_def Sup_finite_3_def min_def less_finite_3_def less_eq_finite_3_def split: split_if_asm)
   796       (auto simp add: SUP_def Sup_finite_3_def min_def less_finite_3_def less_eq_finite_3_def split: split_if_asm)
   729 qed
   797 qed
   730 
   798 
   731 instance finite_3 :: complete_linorder ..
   799 instance finite_3 :: complete_linorder ..
   732 
   800 
       
   801 instantiation finite_3 :: "{field_inverse_zero, abs_if, ring_div, semiring_div, sgn_if}" begin
       
   802 definition [simp]: "0 = a\<^sub>1"
       
   803 definition [simp]: "1 = a\<^sub>2"
       
   804 definition
       
   805   "x + y = (case (x, y) of
       
   806      (a\<^sub>1, a\<^sub>1) \<Rightarrow> a\<^sub>1 | (a\<^sub>2, a\<^sub>3) \<Rightarrow> a\<^sub>1 | (a\<^sub>3, a\<^sub>2) \<Rightarrow> a\<^sub>1
       
   807    | (a\<^sub>1, a\<^sub>2) \<Rightarrow> a\<^sub>2 | (a\<^sub>2, a\<^sub>1) \<Rightarrow> a\<^sub>2 | (a\<^sub>3, a\<^sub>3) \<Rightarrow> a\<^sub>2
       
   808    | _ \<Rightarrow> a\<^sub>3)"
       
   809 definition "- x = (case x of a\<^sub>1 \<Rightarrow> a\<^sub>1 | a\<^sub>2 \<Rightarrow> a\<^sub>3 | a\<^sub>3 \<Rightarrow> a\<^sub>2)"
       
   810 definition "x - y = x + (- y :: finite_3)"
       
   811 definition "x * y = (case (x, y) of (a\<^sub>2, a\<^sub>2) \<Rightarrow> a\<^sub>2 | (a\<^sub>3, a\<^sub>3) \<Rightarrow> a\<^sub>2 | (a\<^sub>2, a\<^sub>3) \<Rightarrow> a\<^sub>3 | (a\<^sub>3, a\<^sub>2) \<Rightarrow> a\<^sub>3 | _ \<Rightarrow> a\<^sub>1)"
       
   812 definition "inverse = (\<lambda>x :: finite_3. x)" 
       
   813 definition "x / y = x * inverse (y :: finite_3)"
       
   814 definition "abs = (\<lambda>x :: finite_3. x)"
       
   815 definition "op div = (op / :: finite_3 \<Rightarrow> _)"
       
   816 definition "x mod y = (case (x, y) of (a\<^sub>2, a\<^sub>1) \<Rightarrow> a\<^sub>2 | (a\<^sub>3, a\<^sub>1) \<Rightarrow> a\<^sub>3 | _ \<Rightarrow> a\<^sub>1)"
       
   817 definition "sgn = (\<lambda>x. case x of a\<^sub>1 \<Rightarrow> a\<^sub>1 | _ \<Rightarrow> a\<^sub>2)"
       
   818 instance
       
   819 by intro_classes
       
   820   (simp_all add: plus_finite_3_def uminus_finite_3_def minus_finite_3_def times_finite_3_def
       
   821        inverse_finite_3_def divide_finite_3_def abs_finite_3_def div_finite_3_def mod_finite_3_def sgn_finite_3_def
       
   822        less_finite_3_def
       
   823      split: finite_3.splits)
       
   824 end
       
   825 
   733 hide_const (open) a\<^sub>1 a\<^sub>2 a\<^sub>3
   826 hide_const (open) a\<^sub>1 a\<^sub>2 a\<^sub>3
   734 
   827 
   735 datatype finite_4 = a\<^sub>1 | a\<^sub>2 | a\<^sub>3 | a\<^sub>4
   828 datatype finite_4 = a\<^sub>1 | a\<^sub>2 | a\<^sub>3 | a\<^sub>4
   736 
   829 
   737 notation (output) a\<^sub>1  ("a\<^sub>1")
   830 notation (output) a\<^sub>1  ("a\<^sub>1")
   821   show "a \<sqinter> \<Squnion>B = (\<Squnion>b\<in>B. a \<sqinter> b)"
   914   show "a \<sqinter> \<Squnion>B = (\<Squnion>b\<in>B. a \<sqinter> b)"
   822     by(cases a "\<Squnion>B" rule: finite_4.exhaust[case_product finite_4.exhaust])
   915     by(cases a "\<Squnion>B" rule: finite_4.exhaust[case_product finite_4.exhaust])
   823       (auto simp add: inf_finite_4_def Sup_finite_4_def SUP_def split: finite_4.splits split_if_asm)
   916       (auto simp add: inf_finite_4_def Sup_finite_4_def SUP_def split: finite_4.splits split_if_asm)
   824 qed
   917 qed
   825 
   918 
       
   919 instantiation finite_4 :: complete_boolean_algebra begin
       
   920 definition "- x = (case x of a\<^sub>1 \<Rightarrow> a\<^sub>4 | a\<^sub>2 \<Rightarrow> a\<^sub>3 | a\<^sub>3 \<Rightarrow> a\<^sub>2 | a\<^sub>4 \<Rightarrow> a\<^sub>1)"
       
   921 definition "x - y = x \<sqinter> - (y :: finite_4)"
       
   922 instance
       
   923 by intro_classes
       
   924   (simp_all add: inf_finite_4_def sup_finite_4_def uminus_finite_4_def minus_finite_4_def split: finite_4.splits)
       
   925 end
       
   926 
   826 hide_const (open) a\<^sub>1 a\<^sub>2 a\<^sub>3 a\<^sub>4
   927 hide_const (open) a\<^sub>1 a\<^sub>2 a\<^sub>3 a\<^sub>4
   827 
   928 
   828 
   929 
   829 datatype finite_5 = a\<^sub>1 | a\<^sub>2 | a\<^sub>3 | a\<^sub>4 | a\<^sub>5
   930 datatype finite_5 = a\<^sub>1 | a\<^sub>2 | a\<^sub>3 | a\<^sub>4 | a\<^sub>5
   830 
   931