|
Prev: sketch of union function problem
Next: Where To Begin
From: steve on 17 Feb 2006 08:51 Can anyone tell me why the following line generates an error (but still prints the correct output!)? It's a simple finite automata simulator; str is a list of integers (ASCII values); and the following line occurs when the recursive FA function encounters a character from outside of the alphabet {a, b} (or {97, 98} if you prefer): (princ (format "%s unrecognized input\nrejected\n" (char-to-string (car str))) lisp-out)) Wrong type argument: integer-or-marker-p, "y unrecognized input^Jrejected^J" Here is the whole program if necessary: ;Assignment: Finite Automata Simulator (cond ((get-buffer "*lisp-out*") (kill-buffer "*lisp-out*"))) (setq lisp-out (get-buffer-create "*lisp-out*")) (defun FA (str) (cond ((null str) state) ((equal (car str) 97) (cond ((equal state 1) (setq state 3)) ((equal state 2) (setq state 4)) ((equal state 3) (setq state 4)) ((equal state 4) (setq state 5)) ((equal state 5) (setq state 2)) ) (princ (format "a - > State %d\n" state) lisp-out) (setq i (+ i 1)) (FA (cdr str)) ) ((equal (car str) 98) (cond ((equal state 1) (setq state 5)) ((equal state 2) (setq state 1)) ((equal state 3) (setq state 2)) ((equal state 4) (setq state 4)) ((equal state 5) (setq state 3)) ) (princ (format "b - > State %d\n" state) lisp-out) (setq i (+ i 1)) (FA (cdr str)) ) (t (princ (format "%s unrecognized input\nrejected\n" (char-to-string (car str))) lisp-out)) ) ) (defun accept (state) (cond ((equal (% state 2) 1) 't) (t 'f) ) ) (setq keepgoing 't) (while keepgoing (setq s (read-string "String: ")) (princ (format "String: %s\n" s) lisp-out) (setq s (mapcar 'identity s)) (cond ((equal s '(101 110 100)) (princ (format "bye\n") lisp-out) (setq keepgoing nil) ) (t (princ (format "Start State 1\n") lisp-out) (setq state 1) (setq i 0) (cond ((accept (FA s)) (princ (format "accepted\n") lisp-out)) (t (princ (format "rejected\n") lisp-out)) ) ) ) )
From: steve on 17 Feb 2006 08:55 ....please ignore the final closing paren on the line of code in question...if you look at the full code you can see it has a matching open paren: (t (princ...))
From: Barry Margolin on 17 Feb 2006 09:07 In article <1140184295.965774.229200(a)g44g2000cwa.googlegroups.com>, steve(a)stevedurkin.net wrote: > Can anyone tell me why the following line generates an error (but still > prints the correct output!)? It's a simple finite automata simulator; > str is a list of integers (ASCII values); and the following line occurs > when the recursive FA function encounters a character from outside of > the alphabet {a, b} (or {97, 98} if you prefer): > > (princ (format "%s unrecognized input\nrejected\n" (char-to-string (car > str))) lisp-out)) > > Wrong type argument: integer-or-marker-p, "y unrecognized > input^Jrejected^J" princ returns its first argument after printing it, so FA is returning the error message. Your accept function passes the return value to %, but this isn't valid for strings. So either you need better error checking of the return value, or you need to ensure that FA always returns a state, even in the error case. > > Here is the whole program if necessary: > > ;Assignment: Finite Automata Simulator > > (cond ((get-buffer "*lisp-out*") (kill-buffer "*lisp-out*"))) > (setq lisp-out (get-buffer-create "*lisp-out*")) > > (defun FA (str) > (cond > ((null str) state) > ((equal (car str) 97) > (cond > ((equal state 1) (setq state 3)) > ((equal state 2) (setq state 4)) > ((equal state 3) (setq state 4)) > ((equal state 4) (setq state 5)) > ((equal state 5) (setq state 2)) > ) > (princ (format "a - > State %d\n" state) lisp-out) > (setq i (+ i 1)) > (FA (cdr str)) > ) > ((equal (car str) 98) > (cond > ((equal state 1) (setq state 5)) > ((equal state 2) (setq state 1)) > ((equal state 3) (setq state 2)) > ((equal state 4) (setq state 4)) > ((equal state 5) (setq state 3)) > ) > (princ (format "b - > State %d\n" state) lisp-out) > (setq i (+ i 1)) > (FA (cdr str)) > ) > (t (princ (format "%s unrecognized input\nrejected\n" (char-to-string > (car str))) lisp-out)) > ) > ) > > (defun accept (state) > (cond > ((equal (% state 2) 1) 't) > (t 'f) > ) > ) > > (setq keepgoing 't) > (while keepgoing > (setq s (read-string "String: ")) > (princ (format "String: %s\n" s) lisp-out) > (setq s (mapcar 'identity s)) > (cond > ((equal s '(101 110 100)) > (princ (format "bye\n") lisp-out) > (setq keepgoing nil) > ) > (t (princ (format "Start State 1\n") lisp-out) > (setq state 1) > (setq i 0) > (cond > ((accept (FA s)) (princ (format "accepted\n") lisp-out)) > (t (princ (format "rejected\n") lisp-out)) > ) > ) > ) > ) -- Barry Margolin, barmar(a)alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
From: Alexander Schmolck on 17 Feb 2006 09:40 steve(a)stevedurkin.net writes: > Here is the whole program if necessary: You already got an answer to your specific question, some other remarks (if this is just a one-of excercise, ignore what you think you don't need): - don't put ) on empty lines. It's considered bad style and if you understand how to use emacs properly you don't need to pay visual attention to those parens. - always declare global variables with defvar and local ones with let - 't is the same as t (the boolean true). I assume that instead of 'f you want nil (the boolean false and also the empty list). Then your accept function just becomes (defun accept (state) (equal (% state 2) 1)) ; (= (% state 2) 1) is more idiomatic - for two-armed conditionals you could also use if > (defun FA (str) > (cond > ((null str) state) > ((equal (car str) 97) You can also write (equal (car str) ?a). > (cond > ((equal state 1) (setq state 3)) > ((equal state 2) (setq state 4)) > ((equal state 3) (setq state 4)) > ((equal state 4) (setq state 5)) > ((equal state 5) (setq state 2)) > ) If you put a (require 'cl) at the top of your file, you could replace the cond with: (setq state (ecase state (1 3) (2 4) (3 4) (4 5) (5 2))) It's shorter, gives an error if state is not in 1..4 (if you don't want that use case instead) and should also be more efficient (not that it matters here). Similarly you could then also use (incf i) instead of (setq i (+ i 1)). 'as
From: steve on 17 Feb 2006 21:09 thanks for all the info...it is a one-of exercise, but i still appreciate all the information and advice.
|
Pages: 1 Prev: sketch of union function problem Next: Where To Begin |