From 571161ff8491dcac1831042e927aaae8fa975365 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Wed, 19 May 2021 22:37:09 -0500 Subject: [PATCH] Initial commit --- README.md | 9 +++ package.lisp | 4 ++ paip.asd | 10 +++ paip.fasl | Bin 0 -> 9773 bytes paip.lisp | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 200 insertions(+) create mode 100644 README.md create mode 100644 package.lisp create mode 100644 paip.asd create mode 100644 paip.fasl create mode 100644 paip.lisp diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d41eb5 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# paip +### _Your Name _ + +This is a project to do ... something. + +## License + +Specify license here + diff --git a/package.lisp b/package.lisp new file mode 100644 index 0000000..7a395ad --- /dev/null +++ b/package.lisp @@ -0,0 +1,4 @@ +;;;; package.lisp + +(defpackage #:paip + (:use #:cl)) diff --git a/paip.asd b/paip.asd new file mode 100644 index 0000000..56407d4 --- /dev/null +++ b/paip.asd @@ -0,0 +1,10 @@ +;;;; paip.asd + +(asdf:defsystem #:paip + :description "Me learning from the PAIP book" + :author "Case Duckworth" + :license "WTFPL" + :version "0.0.1" + :serial t + :components ((:file "package") + (:file "paip"))) diff --git a/paip.fasl b/paip.fasl new file mode 100644 index 0000000000000000000000000000000000000000..6d6ae9e353f97813ac46f50399a0e4f5e4e1f15f GIT binary patch literal 9773 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 Z-xOh8-$L4NrcCx3bE|xR+n3Di{||+Tm$d)@ literal 0 HcmV?d00001 diff --git a/paip.lisp b/paip.lisp new file mode 100644 index 0000000..903df9e --- /dev/null +++ b/paip.lisp @@ -0,0 +1,177 @@ +;;;; paip.lisp + +(in-package #:paip) + + +;;; Chapter 1 + +;; 1.1 define a version of `last-name' that handles "Rex Morgan MD," "Morton +;; Downey, Jr.," etc. +(defparameter *titles* '(MD Sr. Jr. Sir) + "Titles aren't part of names.") + +(defun first-name (name) + "Select the first name from a NAME represented as a list." + (if (member (first name) *titles*) + (first-name (rest name)) + (first name))) + +(defun last-name (name) + "Select the last name from a NAME represented as a list." + (first-name (reverse name))) + +;; 1.2 Write a function to exponentiate, or raise a number to an integer +;; power. For example: (power 3 2) = 3 ^ 2 = 9. + +(defun power (n m) + "Raise N to an integer power M." + (cond + ((= m 0) 1) + ((= m 1) n) + (t (* n (power n (- m 1)))))) + +;; 1.3 Write a function that counts the number of atoms in an expression. For +;; example: (count-atoms '(a (b) c)) = 3. Notice that there is something of an +;; ambiguity in this: shoul (a nil c) count as 3 atoms, or as two, because it's +;; the equivalent to (a () c) ? + +(defun count-atoms (expr) + "Count how many atoms are in EXPR, disregarding NIL." + (cond + ((null expr) 0) + ((atom expr) 1) + (t (+ (count-atoms (first expr)) + (count-atoms (rest expr)))))) + +(defun count-all-atoms (expr &optional (if-null 1)) + "Count all atoms in EXPR, including NILs only in non-tail position." + (cond + ((null expr) if-null) + ((atom expr) 1) + (t (+ (count-all-atoms (first expr) 1) + (count-all-atoms (rest expr) 0))))) + +;; 1.4 Write a function that counts the number of times an expression occurs +;; anywhere in another expression. Example: (count-anywhere 'a '(a ((a) b) a)) +;; => 3. + +(defun count-anywhere (obj expr &optional (test #'eq)) + "Count how many times an OBJ appears anywhere in an EXPR." + (cond + ((null expr) 0) + ((atom expr) (if (funcall test obj expr) 1 0)) + (t (+ (count-anywhere obj (first expr) test) + (count-anywhere obj (rest expr) test))))) + +;; Exercise 1.5 [m] Write a function to compute the dot product of two +;; sequences of numbers, represented as lists. The dot product is computed by +;; multiplying corresponding elements and then adding up the resulting +;; products. Example: (dot-product '(10 20) '(3 4)) = 10 × 3 + 20 × 4 = 110 + +(defun dot-product (list1 list2) + "Compute the dot product of LIST1 and LIST2" + (apply #'+ (mapcar #'* list1 list2))) + + +;;; Chapter 2 + +(defun mappend (fn list) + "Apply FN to each element of LIST and append the results." + (apply #'append (mapcar fn list))) + +(defun one-of (set) + "Pick one element of SET, and make a list of it." + (list (random-elt set))) + +(defun random-elt (choices) + "Choose a random element from list CHOICES." + (elt choices (random (length choices)))) + +(defparameter *simple-grammar* + '((sentence (noun-phrase verb-phrase)) + (noun-phrase (Article Noun)) + (verb-phrase (Verb noun-phrase)) + (Article the a) + (Noun man ball woman table) + (Verb hit took saw liked)) + "A grammar for a trivial subset of English.") + +(defvar *grammar* *simple-grammar* + "The grammar used by `generate'.") + +(defun rule-lhs (rule) + "The left-hand side of a RULE." + (first rule)) + +(defun rule-rhs (rule) + "The right-hand side of a RULE." + (rest rule)) + +(defun rewrites (category) + "Return a list of the possible rewrites for CATEGORY." + (rule-rhs (assoc category *grammar*))) + +;; 2.1. Write a version of `generate' that uses `cond' but avoids calling +;; `rewrites' twice. +(defun generate (phrase) + "Generate a random LHS present in `*grammar*'." + (let ((rw-list (rewrites phrase))) + (cond ((listp phrase) (mappend #'generate phrase)) + (rw-list (generate (random-elt rw-list))) + (t (list phrase))))) + +;; 2.2. Write a version of `generate' that explicitly differentiates between +;; terminal symbols (those with no rewrite rules) and nonterminal symbols. + +;; I'm gonna be honest, this one is tougher. I'm going to let it sit a minute. +;; (defun generate2 (phrase) +;; (let ((rw-list (rewrites phrase))) +;; (if rw-list +;; (let ((relt (random-elt rw-list))) +;; (if (listp relt) +;; (mappend #'generate2 phrase) +;; (generate2 relt))) +;; (list phrase)))) + +(defparameter *bigger-grammar* + '((sentence (noun-phrase verb-phrase)) + (noun-phrase (Article Adj* Noun PP*) (Name) (Pronoun)) + (verb-phrase (Verb noun-phrase PP*)) + (PP* () (PP PP*)) + (Adj* () (Adj Adj*)) + (PP (Prep noun-phrase)) + (Prep to in by with on) + (Adj big little blue green adiabatic) + (Article the a) + (Name Pat Kim Lee Terry Robin) + (Noun man ball woman table) + (Verb hit took saw liked) + (Pronoun he she it these those that))) + +(setf *grammar* *bigger-grammar*) + +(defun generate-tree (phrase) + "Generate a random PHRASE, with a complete parse tree." + (cond ((listp phrase) (mapcar #'generate-tree phrase)) + ((rewrites phrase) (cons phrase + (generate-tree (random-elt (rewrites phrase))))) + (t (list phrase)))) + +(defun generate-all (phrase) + "Generate a list of all possible expansions of PHRASE." + (cond ((null phrase) (list nil)) + ((listp phrase) + (combine-all (generate-all (first phrase)) + (generate-all (rest phrase)))) + ((rewrites phrase) + (mappend #'generate-all (rewrites phrase))) + (t (list (list phrase))))) + +(defun combine-all (xlist ylist) + "Return a list of lists formed by appending a YLIST to an XLIST. + +E.g., (combine-all '((a) (b)) '((1) (2))) + => ((A 1) (B 1) (A 2) (B 2))." + (mappend #'(lambda (y) + (mapcar #'(lambda (x) (append x y)) xlist)) + ylist))