#lang racket (require "set-adt.rkt") ;; ---------------------------------------------------------------- ;; See notes below for one limitation and one explanation. ;; ---------------------------------------------------------------- (define (MAKE-PAIR a b) (set (set a) (set a b))) (define (FIRST aPair) (set-one-elem (apply set-intersect aPair))) (define (SECOND aPair) (set-one-elem (set-minus (apply set-union aPair) (apply set-intersect aPair)))) ;; ---------------------------------------------------------------- ;; The same test code using pairs, regardless of implementation. ;; ---------------------------------------------------------------- (require rackunit) (define pair1 (MAKE-PAIR 2 3)) (define pair2 (MAKE-PAIR 1 pair1)) (check-equal? (FIRST pair2) 1) (check-equal? (FIRST (SECOND pair2)) 2) (check-equal? (SECOND (SECOND pair2)) 3) ;; ---------------------------------------------------------------- ;; ;; This implementation has one restriction: the pair cannot contain ;; two items that are equal. It only works if a != b. ;; ;; To allow a == b, we need a slightly more complicated way to ;; access the SECOND item. For details, see this blog post: ;; http://www.cs.uni.edu/~wallingf/blog/archives/monthly/2022-04.html#e2022-04-16T14_32_18.htm ;; ;; ---------------------------------------------------------------- ;; ;; I used apply above to find the unions and intersections because ;; set-union and set-intersect expect exactly two arguments. ;; Without apply, I have to access the items first. ;; ;; FIRST ;; (let ((x (set-one-elem aPair)) ;; (y (set-one-elem (set-rest aPair)))) ;; (set-one-elem (set-intersect x y))))) ;; ;; SECOND ;; (let ((x (set-one-elem aSet)) ;; (y (set-one-elem (set-rest aSet)))) ;; (set-one-elem (set-minus (set-union x y) ;; (set-intersect x y)))))) ;; ;; ----------------------------------------------------------------