; ycombinator - Apply this fn to this pair in the list
; ------------------------------
; The Little Lisper 3rd Edition
; Chapter 9
; Exercise 2
; Common Lisp
; http://t...content-available-to-author-only...r.com/thelittlelisper
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper-chapter-9-lamdba-ultimate.html
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper.html
; ------------------------------
(defun first_ (l)
(cond
((null l) '())
(t (car l))))
(defun second_ (l)
(cond
((null l) '())
(t (car (cdr l)))))
(defun third_ (l)
(cond
((null l) '())
(t (car (cdr (cdr l))))))
(defun pair? (lat)
(cond
((null lat) NIL)
((atom lat) NIL)
((and (and (not (eq (first_ lat) NIL))
(not (eq (second_ lat) NIL))))
(eq (third_ lat) NIL))
(t NIL)))
(defun eq-pair-first (pair-a-first pair-b)
(cond
((null pair-a-first) NIL)
((null pair-b) NIL)
((not(atom pair-a-first)) NIL)
((atom pair-b) NIL)
((not (pair? pair-b)) NIL)
((eq pair-a-first
(first_ pair-b)))
(t NIL)))
(print (eq-pair-first 'a '(a b)))
;T
(print (eq-pair-first 'a '(b a)))
;NIL false
(defun rel? (rel)
(cond
((null rel) t)
((atom rel) NIL)
((pair? (car rel))
(rel? (cdr rel)))
(t NIL)))
(print (rel? '((a b)(a c)(a a))))
;T
(defun exists? (first rel)
(cond
((null first) t)
((null rel) NIL)
((not(rel? rel)) NIL)
((eq-pair-first first (car rel)) t)
(t (exists? first (cdr rel)))))
(print (exists? 'a '((a b)(a c)(a a))))
;T
(print (exists? 'd '((a b)(a c)(a a))))
;NIL false
(defun find-match (a l)
(cond
((null a) '())
((null l) NIL)
((not(rel? l)) NIL)
((eq-pair-first a (car l) ) (car l))
(t (find-match a (cdr l)))))
(print (find-match 'a '((a b)(a c)(a a))))
;(A B)
(defun assq-sf (a l sk fk)
(cond
((exists? a l)
(funcall sk (find-match a l)))
(t (funcall fk a))))
(defun build (a b)
(cons a (cons b '())))
(defun add1 (n)
(+ 1 n))
(setf a 'apple)
(setf b1 '())
(setf b2 '((apple 1)(plum 2)))
(setf b3 '((peach 3)))
(setf sk (lambda (p)(build (first p) (add1 (second p)))))
(setf fk (lambda (name) (cons name (quote (not-in-list)))))
(print (assq-sf a b1 sk fk))
;(APPLE NOT-IN-LIST)
(print (assq-sf a b2 sk fk))
;(APPLE 2)
(print (assq-sf a b3 sk fk))
;(APPLE NOT-IN-LIST)