chapter ‹Generated by Lem from ‹set_extra.lem›.› theory "Lem_set_extra" imports Main "Lem_bool" "Lem_basic_classes" "Lem_maybe" "Lem_function" "Lem_num" "Lem_list" "Lem_sorting" "Lem_set" begin ― ‹‹****************************************************************************›› ― ‹‹ A library for sets ›› ― ‹‹ ›› ― ‹‹ It mainly follows the Haskell Set-library ›› ― ‹‹****************************************************************************›› ― ‹‹ ========================================================================== ›› ― ‹‹ Header ›› ― ‹‹ ========================================================================== ›› ― ‹‹open import Bool Basic_classes Maybe Function Num List Sorting Set›› ― ‹‹ ----------------------------›› ― ‹‹ set choose (be careful !) ›› ― ‹‹ --------------------------- ›› ― ‹‹val choose : forall 'a. SetType 'a => set 'a -> 'a›› ― ‹‹ ------------------------ ›› ― ‹‹ chooseAndSplit ›› ― ‹‹ ------------------------ ›› ― ‹‹ The idea here is to provide a simple primitive that Lem code can use * to perform its own custom searches within the set -- likely using a * search criterion related to the element ordering, but not necessarily). * For example, sometimes we don't necessarily want to search for a specific * element, but want to search for elements greater than or less than some other. * Someties we'd like to use "split" but don't know a good value to "split" at. * This function lets the set implementation decide that value. * * The contract of chooseAndSplit is simply to select an element nondeterministically * and return that element, together with the subsets of elements less than and * greater than it. In this way, we can recursively traverse the set with any * search criterion, and we avoid baking in the tree representation (although that * is the obvious choice). ›› ― ‹‹val chooseAndSplit : forall 'a. SetType 'a, Ord 'a => set 'a -> maybe (set 'a * 'a * set 'a)›› definition chooseAndSplit :: " 'a Ord_class ⇒ 'a set ⇒('a set*'a*'a set)option " where " chooseAndSplit dict_Basic_classes_Ord_a s = ( if s = {} then None else (let element = (set_choose s) in (let (lt, gt) = (Lem_set.split dict_Basic_classes_Ord_a element s) in Some (lt, element, gt))))" ― ‹‹ ----------------------------›› ― ‹‹ universal set ›› ― ‹‹ --------------------------- ›› ― ‹‹val universal : forall 'a. SetType 'a => set 'a›› ― ‹‹ ----------------------------›› ― ‹‹ toList ›› ― ‹‹ --------------------------- ›› ― ‹‹val toList : forall 'a. SetType 'a => set 'a -> list 'a›› ― ‹‹ ----------------------------›› ― ‹‹ toOrderedList ›› ― ‹‹ --------------------------- ›› ― ‹‹ "toOrderedList" returns a sorted list. Therefore the result is (given a suitable order) deterministic. Therefore, it is much preferred to "toList". However, it still is only defined for finite sets. So, please use carefully and consider using set-operations instead of translating sets to lists, performing list manipulations and then transforming back to sets. ›› ― ‹‹val toOrderedListBy : forall 'a. ('a -> 'a -> bool) -> set 'a -> list 'a›› ― ‹‹val toOrderedList : forall 'a. SetType 'a, Ord 'a => set 'a -> list 'a›› ― ‹‹ ----------------------- ›› ― ‹‹ compare ›› ― ‹‹ ----------------------- ›› ― ‹‹val setCompareBy: forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> ordering›› definition setCompareBy :: "('a ⇒ 'a ⇒ ordering)⇒ 'a set ⇒ 'a set ⇒ ordering " where " setCompareBy cmp ss ts = ( (let ss' = (ordered_list_of_set (λ x y . cmp x y = LT) ss) in (let ts' = (ordered_list_of_set (λ x y . cmp x y = LT) ts) in lexicographicCompareBy cmp ss' ts')))" ― ‹‹val setCompare : forall 'a. SetType 'a, Ord 'a => set 'a -> set 'a -> ordering›› definition setCompare :: " 'a Ord_class ⇒ 'a set ⇒ 'a set ⇒ ordering " where " setCompare dict_Basic_classes_Ord_a = ( setCompareBy (compare_method dict_Basic_classes_Ord_a) )" ― ‹‹ ----------------------------›› ― ‹‹ unbounded fixed point ›› ― ‹‹ --------------------------- ›› ― ‹‹ Is NOT supported by the coq backend! ›› ― ‹‹val leastFixedPointUnbounded : forall 'a. SetType 'a => (set 'a -> set 'a) -> set 'a -> set 'a›› ― ‹‹let rec leastFixedPointUnbounded f x= let fx = f x in if fx subset x then x else leastFixedPointUnbounded f (fx union x)›› end