In this project you will explore functional programming and extend a generator of graph input files.
Also, for bonus marks, your can extend the current LISP code base.
make X=it
1 2 3 4 5 6 7
Note that everyone has to do "1 2 3 4" but after that, your numbers may change.
cd $HOME mkdir -p cs310 svn export http://unbox.org/wisp/var/timm/09/310/lib/proj3 proj3b cd proj3b chmod +x lisps ./lisps eg/random.lisp
If the above works, you should see something like this:
(0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9)
make submit
The following grammar is a partial description of one of the graph input files:
(defparameter *graph-spec*
'((?spec -> (?labels ?widths ?heights ?datas))
(?labels -> (label ?words nl))
(?words -> ?word (?word ?words))
(?word -> foo bar blah slug)
(?widths -> (width ?num nl))
(?num -> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
(?heights -> (height ?num nl))
(?datas -> ?datums2 (?datums2 ?datas))
(?datums2 -> (?datums1 ?datums1))
(?datums1 -> (?num ?num ?symbol nl))
(?symbol -> \* \# \+)
))
In this notation:
?spec -> (?labels ?widths ?heights ?datas)
(so this spec must have labels and widths and heights and data.)
(?word -> foo bar blah slug)
(so word can be either foo or bar or blah or slug.)
By randomly selecting from the disjunctions, it is possible to generate any number of graph input files; e.g. after doing the above set up, you should get:
1
2 ---| grammar.lisp |-----------------------------------------
3
4
5
6 label blah
7 width 15
8 height 14
9 6 7 + 11 16 + 14 8 # 6 17 # 15 10 + 15 3 # 1 19 # 5 1 + 8 7 + 9 9 *
10
11 label blah
12 width 11
13 height 18
14 16 20 + 15 9 * 19 8 * 8 3 #
15
16 label foo
17 width 17
18 height 3
19 15 14 # 20 16 # 19 10 + 9 6 # 20 1 + 5 3 +
20
21 label bar
22 width 10
23 height 3
24 17 7 # 11 17 # 20 16 + 3 20 #
25
26 label bar foo slug bar blah
27 width 15
28 height 2
29 19 5 + 4 17 #
30
31 label slug
32 width 11
33 height 2
34 19 3 + 20 3 #
35
36 label bar blah
37 width 19
38 height 14
39 18 4 # 17 8 * 18 10 * 8 15 * 9 1 + 17 9 *
40
41 label slug
42 width 20
43 height 15
44 2 3 * 19 11 #
45
46 label foo slug
47 width 17
48 height 16
49 19 3 * 3 7 #
50
51 label foo
52 width 9
53 height 18
54 15 3 + 2 14 +
As before, there is a file "lisps" that loads all the .lisp files (listed in alphabetically order) into a lisp shell.
If you add arguments to "lisps", you can customize the behavior:
Note that, as before, the standard Makefile commands still run such as
make --> runs one test make X=grammar.lisp run --> runs one test make X=grammar.lisp cache --> runs one test, caches the results make tests --> runs all tests make score --> scores the tests.
If your run "make score" you'll see that there is something wrong with the code:
make score *** - no handler for label *** - no handler for bottom *** - no handler for label *** - no handler for label *** - no handler for label *** - no handler for label *** - no handler for label *** - no handler for label *** - no handler for label 12 FAILED 6 PASSED
What is going on here is that the LISP code I have supplied can not (yet) draw graphs. For bonus marks, you might choose to fix that.
There are several things wrong with the above that you must fix:
WHAT TO SUBMIT: (1) a better version of grammar.lisp with a longer grammar for the graph inputs;
(2) test files eg/graphgrammer.lisp (and other) demonstrating that you can run some full graph in eg/graphgramer.dat.
WHAT TO SUBMIT: (3) same file, grammar.lisp, with the grammar changed so it does
have the above two issues; (4) test files eg/graphlines.lisp, etc.
Both the following require problems require a recursive walk through a nested list structure. In LISP, such a recursive descent looks like this:
(defun countr (x l) (cond ((null l) 0) ; case 1) empty list ((atom l) (if (eql x l) 1 0)) ; case 2) not a list (t ; case 3) isa list so ... (let ((n 0)) (dolist (one l n) ; we recurse (incf n (countr x one)))))))
WHAT TO SUBMIT: (5) a file checker.lisp, that implements the checker;
(6) test files eg/checker.lisp , etc.
(dotimes (i 20)
(let ((spec (generate '?spec)))
(if (sane spec)
(spec->lines spec))))
Note that not all the specs will be printed. So if your call this with "(dotimes (i 20) .." it is well possible you will only see, say, 18 specs. <6l>
WHAT TO SUBMIT: (7) a file sanity.lisp, that implements the checker;
(8) test files eg/sanity.lisp , etc.
WHAT TO SUBMIT: (9) a file, scifi.lisp; (10) test files
"eg/scifi.lisp" that generates 350 randomly generated files.
WHAT TO SUBMIT: (11) a file, prob.lisp that does the above
expansions (12) test files
"eg/prob.lisp" etc
WHAT TO SUBMIT:
Your file "testOut.txt" should include enough information so I can run your code. If you ha to include your st code, do so using a sub-directory of proj3b.
WHAT TO SUBMIT: (14) test files
eg/1.lisp ...eg/10.lisp etc.