20-CS-4003-001 Organization of Programming Languages Fall 2017
Basic Operations

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures        Code

Check Correctness of Mergesort Output

;; returns #t iff lst contains at least one occurrence of a
(define contains?
  (lambda (lst a)
    (if (null? lst)
        (if (equal? (car lst) a)
            (contains? (cdr lst) a)))))

;; returns lst minus the leftmost occurrence of a, if any
(define remove-first
  (lambda (lst a)
    (if (null? lst)
        (if (equal? (car lst) a)
            (cdr lst)
            (cons (car lst) (remove-first (cdr lst) a))))))

;; returns #t iff lists x and y are permutations
(define perm?
  (lambda (x y)
    (if (null? x)
        (null? y)
        (if (contains? y (car x))
            (perm? (cdr x) (remove-first y (car x)))

;; returns #t iff the elements of lst are in non-decreasing order
(define ordered?
  (lambda (lst)
    (or (null? lst)
        (null? (cdr lst))
        (and (<= (car lst) (car (cdr lst))) (ordered? (cdr lst))))))

;; returns a pair (lst1 lst2) where every element of lst is in lst1 or
;; lst2 but not both and where the length of lst1 is approximately equal
;; to the length of lst2.
;;   lst = (a b c d e f g h ...)
;;   (split lst) = (cons a (car ((c e g ...) (d f h ...))))
;;                 (cons b (cadr ((c e g ...) (d f h ...))))
(define split
  (lambda (lst)
    (if (null? lst)
        (list '() '())
        (if (null? (cdr lst))
            (list lst '())
            (let ((rest (split (cddr lst))))
              (list (cons (car l) (car rest))
                    (cons (car (cdr l)) (car (cdr rest)))))))))

;; merge two lists in non-decreasing order
(define merge
  (lambda (l1 l2)
    (if (null? l1)
        (if (null? l2)
            (if (< (car l1) (car l2))
                (cons (car l1) (merge (cdr l1) l2))
                (cons (car l2) (merge l1 (cdr l2))))))))

;; sort a list of elements
(define mrgsrt
  (lambda (lst)
    (if (null? lst)
        (if (null? (cdr lst))
            (let* ((s (split lst))
                   (a (car s))
                   (b (cadr s)))
              (merge (mrgsrt a) (mrgsrt b)))))))

;; returns true iff the mrgsrt of a lst is a permutation of lst and is
;; ordered
(define checker
  (lambda (lst)
    (let ((res (mrgsrt lst)))
      (and (perm? res lst) (ordered? res)))))