Waysys on the Web

Set

Set

Previous topic Next topic  

Set

Previous topic Next topic  

(*

 

Class:      Set

Package:    com.waysysweb

Author:     W. Shaffer

Date:       27-Oct-2005

Description:

 

    This structure

 

Maintenance:

 

Date        Author  Description

----------- ------  -----------------------------------------------------------

27-Oct-2005 Shaffer File created

 

*)

 

structure SET = struct

 

    (*============  Exceptions ==============================================*)

 

    exception SetException of string;

 

    (*============  Imports     =============================================*)

 

 

 

    (*============  Types       =============================================*)

 

    type ''a Set = ''a list;

 

    (*============  Constants  ==============================================*)

 

    val empty = [];

 

    (*============  Properties ==============================================*)

 

 

 

    (*============  Attributes  =============================================*)

 

 

 

    (*============  Invariant   =============================================*)

 

 

 

    (*============  Initialization ==========================================*)

 

 

 

    (*============  Operations  =============================================*)

 

    (* return true if set is empty                                           *)

    (* Precondition: true                                                    *)

    (* Postcondition: set = empty                                            *)

    fun isEmpty(set : ''a Set) : bool =

        if set = empty then true

        else false;

 

    (* return true if item is in set                                         *)

    (* Precondition: true                                                    *)

    (* Postcondition: if set = empty then false                              *)

    (*                else if item = hd(set) then true                       *)

    (*                else item inset tl(set)                                *)

    infix inset;

    fun ((item : ''a) inset (set : ''a Set) ) : bool  =

        if      isEmpty(set) then false

        else if item = hd(set) then true

        else    item inset tl(set);

 

    (* turn true if an item is not in the set                                *)

    (* Precondition: item : 'a andalso set : 'a Set                          *)

    (* Postcondition: not (item inset set)                                   *)

    infix notinset;

    fun ((item : ''a) notinset (set : ''a Set)) : bool = not (item inset set);

 

    (* return a set with an item added to it                                 *)

    (* Precondition:  not (item inset set)                                   *)

    (* Postcondition: set' = add(set, item) andalso item inset set'          *)

    fun add(set : ''a Set, item : ''a) : ''a Set =

        if item inset set then raise SetException("add: item is already in set")

        else item::set;

 

    (* return a set with an item removed                                     *)

    (* Precondition:  item inset set                                         *)

    (* Postcondition: remove(set, item) = set' andalso                       *)

    (*                not (item inset set)                                   *)

    fun remove(set : ''a Set, item : ''a) : ''a Set =

        if item inset set then

            let

                val first = hd(set)

            in

                if item = first then tl(set)

                else first::remove(set, item)

            end

        else raise SetException("remove: item is not in set");

 

    (* return true if if each element in a set satisfies the predicate       *)

    (* Precondition: true                                                    *)

    (* Postcondition: for all x inset set | pred(x)                          *)

    fun forall(set : ''a Set, pred : ''a -> bool) : bool =

        if set = empty then true

        else pred(hd(set)) andalso forall(tl(set), pred);

 

    (* return true if there exists an element that satisfies the predicate   *)

    (* Precondition: true                                                    *)

    (* Postcondition: there exists x inset set | pred(x)                     *)

    fun exists(set : ''a Set, pred : ''a -> bool) : bool =

        if set = empty then false

        else if pred(hd(set)) then true

        else exists(tl(set), pred);

 

    (* return the cardinality of the set or the number of items in set       *)

    (* Precondition: true                                                    *)

    (* Postcondition: size(empty) andalso                                    *)

    (*                size(add(set, item)) = size(set) + 1                   *)

    fun card(set : '' Set) : int = length(set);

 

    (* return a set of the elements in a list                                *)

    (* Precondition: true                                                    *)

    (* Postcondition: set = toSet(list') andalso                             *)

    (*                forall x in list1 | x inset set andalso                *)

    (*                forall(set, fn x : x in list)                          *)

    fun toSet([]                    ) : ''a Set = empty

    |   toSet(item::list' : ''a list) : ''a Set =

        let

           val set = toSet(list')

        in

            if item inset set then set

            else                   add(set, item)

        end;

 

    (* return one element of a set                                           *)

    (* Precondition: card(set) > 0                                           *)

    (* Postcondition: item = fetch(set) andalso item inset set               *)

    fun fetch(set : ''a Set) : ''a = hd(set);

 

    (* return the union of two sets                                          *)

    (* Precondition: true                                                    *)

    (* Postcondition: set' = union(set1, set2) andalso                       *)

    (*                forall(set1, fn x => x inset set')                     *)

    (*                forall(set2, fn x => x inset set')                     *)

    (*                forall(set',                                           *)

    (*                   fn x => (x inset set1) orelse (x inset set2)        *)

    fun union(set1 : ''a Set, set2 : ''a Set) : ''a Set =

        if set1 = empty then set2

        else

            let

                val item  = fetch(set1);

                val set1' = remove(set1, item);

                val set'  = union(set1', set2)

            in

                if item inset set' then set'

                else                    add(set', item)

            end;

 

    (* return the intersection of two sets                                   *)

    (* Precondition: true                                                    *)

    (* Postcondition: set' = inter(set1, set2) andalso                       *)

    (*                forall(set',                                           *)

    (*                    fn x => (x inset set1) andalso (x inset set2)      *)

    (*                forall(set1, fn x => if x inset set2 then x inset set' *)

    (*                                     else true)                        *)

    fun inter(set1 : ''a Set, set2 : ''a Set) : ''a Set =

        if set1 = empty then empty

        else

            let

                val item  = fetch(set1);

                val set1' = remove(set1, item);

                val set'  = inter(set1', set2)

            in

                if   (item inset set2) andalso (not (item inset set'))

                then add(set', item)

                else set'

            end;

 

    (* return true if sub is a subset of superset                            *)

    (* Precondition: true                                                    *)

    (* Postcondition: forall(sub, fn x => x inset superset)                  *)

    fun subset(sub : ''a Set, superset : ''a Set) : bool =

        forall(sub, fn x => x inset superset);

 

    (* return true if a set equals another set                               *)

    (* Precondition: true                                                    *)

    (* Postcondition: subset(set1, set2) andalso subset(set2, set1)          *)

    fun equals(set1 : ''a Set, set2 : ''a Set) : bool =

        subset(set1, set2) andalso subset(set2, set1);

 

    (* return a set of items that satisfy a predicate                        *)

    (* Precondition: true                                                   *)

    (* Postcondition: set' = select(set, pred) andalso                       *)

    (*                subset(set', set) andalso forall(set', pred)           *)

    fun select(set : ''a Set, pred : ''a -> bool) : ''a Set =

        if isEmpty(set) then empty

        else

            let

                val item = fetch(set);

                val set' = remove(set, item);

                val sel  = select(set', pred)

            in

                if pred(item) then add(sel, item)

                else sel

            end;

 

    (* return the set after applying a function to each element              *)

    (* Precondition: true                                                    *)

    (* Postcondition: set' = project(set, func) andalso                      *)

    (*                forall(set, fn x => func(x) inset set') andalso        *)

    (*                forall(set', fn x => exists(set, fn y => func(y) = x)) *)

    fun project(set : ''a Set, func : ''a -> ''b) : ''b Set =

        toSet(map func set);

 

    (* return a set of sets where each inner set contains item.              *)

    (* Precondition: setofSet : 'a Set Set andalso item : 'a andalso         *)

    (*               forall(setofSet, fn set => item notinset set)           *)

    fun addItem(setofSet : ''a Set Set, item : ''a) : ''a Set Set =

        if isEmpty(setofSet) then empty

        else

            let

                val aSet        = fetch(setofSet);

                val restSet     = remove(setofSet, aSet);

                val newSet      = add(aSet, item);

                val newSetofSet = addItem(restSet, item)

            in

                add(newSetofSet, newSet)

            end;

 

    (* return the powerset of a set                                          *)

    (* Precondition: set : ''a Set andalso                                   *)

    (*               powerset' = powerset(set) andalso                       *)

    (*               POWERSET : ''a Set Set is the powerset of set           *)

    fun powerset(set : ''a Set) : ''a Set Set =

        if isEmpty(set) then add(empty, empty)

        else

            let

                val item = fetch(set);

                val restSet = remove(set, item);

                val restPower = powerset(restSet)

            in

                union(restPower, addItem(restPower, item))

            end;

 

    (* create a set of integers in a range                                   *)

    fun range(first : int, last : int) : int Set =

        if first > last then empty

        else add(range(first + 1, last), first);

 

    (* return the largest integer in a range that satisifies a predicate     *)

    fun max(first : int, last : int, pred : int -> bool) : int =

        if      last < first then raise SetException("max: predicate is never true")

        else if pred(last)   then last

        else                      max(first, last-1, pred);

 

end (* SET *)