# HG changeset patch # User wenzelm # Date 1540503847 -7200 # Node ID 278b09a92ed6f05a559beb1493bd76284c49f83f # Parent 91fd09f2b86e8c814885a08b054c15fceeefb1fb# Parent f714114b05713e0ef909ce87f9119631eb46df2b merged diff -r f714114b0571 -r 278b09a92ed6 src/HOL/Library/Comparator.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Library/Comparator.thy Thu Oct 25 23:44:07 2018 +0200 @@ -0,0 +1,207 @@ +(* Title: HOL/Library/Comparator.thy + Author: Florian Haftmann, TU Muenchen +*) + +theory Comparator + imports Main +begin + +section \Comparators on linear quasi-orders\ + +datatype comp = Less | Equiv | Greater + +locale comparator = + fixes cmp :: "'a \ 'a \ comp" + assumes refl [simp]: "\a. cmp a a = Equiv" + and trans_equiv: "\a b c. cmp a b = Equiv \ cmp b c = Equiv \ cmp a c = Equiv" + assumes trans_less: "cmp a b = Less \ cmp b c = Less \ cmp a c = Less" + and greater_iff_sym_less: "\b a. cmp b a = Greater \ cmp a b = Less" +begin + +text \Dual properties\ + +lemma trans_greater: + "cmp a c = Greater" if "cmp a b = Greater" "cmp b c = Greater" + using that greater_iff_sym_less trans_less by blast + +lemma less_iff_sym_greater: + "cmp b a = Less \ cmp a b = Greater" + by (simp add: greater_iff_sym_less) + +text \The equivalence part\ + +lemma sym: + "cmp b a = Equiv \ cmp a b = Equiv" + by (metis (full_types) comp.exhaust greater_iff_sym_less) + +lemma reflp: + "reflp (\a b. cmp a b = Equiv)" + by (rule reflpI) simp + +lemma symp: + "symp (\a b. cmp a b = Equiv)" + by (rule sympI) (simp add: sym) + +lemma transp: + "transp (\a b. cmp a b = Equiv)" + by (rule transpI) (fact trans_equiv) + +lemma equivp: + "equivp (\a b. cmp a b = Equiv)" + using reflp symp transp by (rule equivpI) + +text \The strict part\ + +lemma irreflp_less: + "irreflp (\a b. cmp a b = Less)" + by (rule irreflpI) simp + +lemma irreflp_greater: + "irreflp (\a b. cmp a b = Greater)" + by (rule irreflpI) simp + +lemma asym_less: + "cmp b a \ Less" if "cmp a b = Less" + using that greater_iff_sym_less by force + +lemma asym_greater: + "cmp b a \ Greater" if "cmp a b = Greater" + using that greater_iff_sym_less by force + +lemma asymp_less: + "asymp (\a b. cmp a b = Less)" + using irreflp_less by (auto intro: asympI dest: asym_less) + +lemma asymp_greater: + "asymp (\a b. cmp a b = Greater)" + using irreflp_greater by (auto intro!: asympI dest: asym_greater) + +lemma transp_less: + "transp (\a b. cmp a b = Less)" + by (rule transpI) (fact trans_less) + +lemma transp_greater: + "transp (\a b. cmp a b = Greater)" + by (rule transpI) (fact trans_greater) + +text \The reflexive part\ + +lemma reflp_not_less: + "reflp (\a b. cmp a b \ Less)" + by (rule reflpI) simp + +lemma reflp_not_greater: + "reflp (\a b. cmp a b \ Greater)" + by (rule reflpI) simp + +lemma quasisym_not_less: + "cmp a b = Equiv" if "cmp a b \ Less" and "cmp b a \ Less" + using that comp.exhaust greater_iff_sym_less by auto + +lemma quasisym_not_greater: + "cmp a b = Equiv" if "cmp a b \ Greater" and "cmp b a \ Greater" + using that comp.exhaust greater_iff_sym_less by auto + +lemma trans_not_less: + "cmp a c \ Less" if "cmp a b \ Less" "cmp b c \ Less" + using that by (metis comp.exhaust greater_iff_sym_less trans_equiv trans_less) + +lemma trans_not_greater: + "cmp a c \ Greater" if "cmp a b \ Greater" "cmp b c \ Greater" + using that greater_iff_sym_less trans_not_less by blast + +lemma transp_not_less: + "transp (\a b. cmp a b \ Less)" + by (rule transpI) (fact trans_not_less) + +lemma transp_not_greater: + "transp (\a b. cmp a b \ Greater)" + by (rule transpI) (fact trans_not_greater) + +end + +typedef 'a comparator = "{cmp :: 'a \ 'a \ comp. comparator cmp}" + morphisms compare Abs_comparator +proof - + have "comparator (\_ _. Equiv)" + by standard simp_all + then show ?thesis + by auto +qed + +setup_lifting type_definition_comparator + +global_interpretation compare: comparator "compare cmp" + using compare [of cmp] by simp + +lift_definition flat :: "'a comparator" + is "\_ _. Equiv" by standard simp_all + +instantiation comparator :: (linorder) default +begin + +lift_definition default_comparator :: "'a comparator" + is "\x y. if x < y then Less else if x > y then Greater else Equiv" + by standard (auto split: if_splits) + +instance .. + +end + +text \A rudimentary quickcheck setup\ + +instantiation comparator :: (enum) equal +begin + +lift_definition equal_comparator :: "'a comparator \ 'a comparator \ bool" + is "\f g. \x \ set Enum.enum. f x = g x" . + +instance + by (standard; transfer) (auto simp add: enum_UNIV) + +end + +lemma [code]: + "HOL.equal cmp1 cmp2 \ Enum.enum_all (\x. compare cmp1 x = compare cmp2 x)" + by transfer (simp add: enum_UNIV) + +lemma [code nbe]: + "HOL.equal (cmp :: 'a::enum comparator) cmp \ True" + by (fact equal_refl) + +instantiation comparator :: ("{linorder, typerep}") full_exhaustive +begin + +definition full_exhaustive_comparator :: + "('a comparator \ (unit \ term) \ (bool \ term list) option) + \ natural \ (bool \ term list) option" + where "full_exhaustive_comparator f s = + Quickcheck_Exhaustive.orelse + (f (flat, (\u. Code_Evaluation.Const (STR ''Comparator.flat'') TYPEREP('a comparator)))) + (f (default, (\u. Code_Evaluation.Const (STR ''HOL.default_class.default'') TYPEREP('a comparator))))" + +instance .. + +end + +lift_definition reversed :: "'a comparator \ 'a comparator" + is "\cmp a b. cmp b a" +proof - + fix cmp :: "'a \ 'a \ comp" + assume "comparator cmp" + then interpret comparator cmp . + show "comparator (\a b. cmp b a)" + by standard (auto intro: trans_equiv trans_less simp: greater_iff_sym_less) +qed + +lift_definition key :: "('b \ 'a) \ 'a comparator \ 'b comparator" + is "\f cmp a b. cmp (f a) (f b)" +proof - + fix cmp :: "'a \ 'a \ comp" and f :: "'b \ 'a" + assume "comparator cmp" + then interpret comparator cmp . + show "comparator (\a b. cmp (f a) (f b))" + by standard (auto intro: trans_equiv trans_less simp: greater_iff_sym_less) +qed + +end diff -r f714114b0571 -r 278b09a92ed6 src/HOL/Library/Library.thy --- a/src/HOL/Library/Library.thy Thu Oct 25 23:33:07 2018 +0200 +++ b/src/HOL/Library/Library.thy Thu Oct 25 23:44:07 2018 +0200 @@ -13,6 +13,7 @@ Code_Lazy Code_Test Combine_PER + Comparator Complete_Partial_Order2 Conditional_Parametricity Countable