;; An Atom is one of: ;; - Number ;; - Symbol ;; - String ;; atom? : Any -> Boolean ;; Is a an atom? (define (atom? a) (or (number? a) (symbol? a) (string? a))) ;; Processing 2 complex inputs in parallel ;; Template for atom=? has 9 possibilities ;; atom=? : Atom Atom -> Boolean ;; Is a1 equal to a2? (define (atom=? a1 a2) (cond [(and (number? a1) (number? a2)) (= a1 a2)] [(and (symbol? a1) (symbol? a2)) (symbol=? a1 a2)] [(and (string? a1) (string? a2)) (string=? a1 a2)] [else false])) (check-expect (atom=? 4 "foo") false) (check-expect (atom=? 4 4) true) (check-expect (atom=? 4 13) false) (check-expect (atom=? 'foo "foo") false) (check-expect (atom=? 'foo 'foo) true) (check-expect (atom=? "hi" "hi") true) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; An SExp is one of: ;; - Atom ;; - LOS ;; An LOS (listof SExp) is one of: ;; - empty ;; - (cons SExp LOS) ;; What are SExps good for? Representing BSL/ISL expressions: ;; '(+ (* 4 3) 40) ;; (list '+ (list '* 4 3) 40) ;; Examples (SExp) 3 'red "yellow" empty (define sexp1 (list "banana" 27 'grapefruit)) (define sexp2 (list (list 'red 'yellow (list "banana" 27 'grapefruit)) (list 1 2) "foo")) ;; SExp and LOS are mutually recursive data definitions #;(define (sexp-temp s) (cond [(atom? s) ...] [else ... (los-temp s) ...])) #;(define (los-temp los) (cond [(empty? los) ...] [else ... (sexp-temp (first los)) ... (los-temp (rest los)) ...])) ;; flatten : SExp -> [Listof Atom] ;; flatten the given sexpr (see examples) (define (flatten s) (cond [(atom? s) (list s)] [else (los-flatten s)])) ;; los-flatten : LOS -> [Listof Atom] (define (los-flatten los) (foldr (lambda (s ans) (append (flatten s) ans)) empty los)) ;; los-flatten : LOS -> [Listof Atom] #;(define (los-flatten los) (cond [(empty? los) empty] [else (append (flatten (first los)) (los-flatten (rest los)))])) (check-expect (flatten 4) (list 4)) (check-expect (flatten "red") (list "red")) (check-expect (flatten empty) empty) (check-expect (flatten sexp1) sexp1) (check-expect (flatten sexp2) (list 'red 'yellow "banana" 27 'grapefruit 1 2 "foo")) ;; ****** FINGER EXERCISE ******** ;; Design the function atom-occurs? that takes an SExp and an Atom ;; and returns true if the given atom occurs in the given sexp. ;; ********************************* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Processing 2 complex inputs in parallel #;(define (sexp2d-temp s1 s2) (cond [(and (atom? s1) (atom? s2)) ...] [(and (atom? s1) (list? s2)) ...] [(and (list? s1) (atom? s2)) ...] [else ... (los2d-temp s1 s2) ...])) #;(define (los2d-temp los1 los2) (cond [(and (empty? los1) (empty? los2)) ...] [(and (empty? los1) (cons? los2)) ...] [(and (cons? los1) (empty? los2)) ...] [else ... (sexp2d-temp (first los1) (first los2)) (los2d-temp (rest los1) (rest los2))...])) ;; eqwal? : SExp SExp -> Boolean ;; Is s1 equal to s2? (define (eqwal? s1 s2) (cond [(and (atom? s1) (atom? s2)) (atom=? s1 s2)] [(and (atom? s1) (list? s2)) false] [(and (list? s1) (atom? s2)) false] [else (los-eqwal? s1 s2)])) (define (los-eqwal? los1 los2) (cond [(and (empty? los1) (empty? los2)) true] [(and (empty? los1) (cons? los2)) false] [(and (cons? los1) (empty? los2)) false] [else (and (eqwal? (first los1) (first los2)) (los-eqwal? (rest los1) (rest los2)))])) (check-expect (eqwal? sexp1 sexp1) true) (check-expect (eqwal? sexp2 sexp1) false) (check-expect (eqwal? sexp1 '()) false) (check-expect (eqwal? 13 sexp1) false) (check-expect (eqwal? sexp2 sexp2) true) (check-expect (eqwal? '() sexp2) false)