如何在Common Lisp中创建选择菜单?

时间:2018-12-07 20:47:28

标签: common-lisp

我有在options函数中创建的菜单,该菜单的功能是让用户输入数字(123)为了解决所选方法(DFSBFSBESTFS)的问题。该方法应该返回用户在此代码行中选择的内容 最后是(SearchProblem '(0 0 2 6 4) '(0 0 0 0 0) (Options))。问题是,当我编译问题时,它将显示此错误“使用参数DFS调用的未定义函数()。”。我该如何解决?

代码

; ----------------------------------------------------------------------------
; ******** Search Code for DFS  and other search methods
; ******** (expanding front and extending queue)
; ******** author:  AI lab
; ********
; ******** Κώδικας για DFS και άλλες μεθόδους αναζήτησης
; ******** (επέκταση μετώπου και διαχείριση ουράς)
; ******** Συγγραφέας: Εργαστήριο ΤΝ

; ----------------------------------------------------------------------------
; **** starting search 
; **** έναρξη αναζήτησης

(defun searchProblem (start-state goal method )
    ( cond
      ((StateValidation start-state)(print "Invalid data!") nil)

      ( T (findSolution (MakeFront start-state) (MakeQueue start-state) () goal method ) )
    )

    ;(print '____BEGIN_SEARCHING_____ )

)

; **** Checking for valid states

(defun StateValidation (state)
  (cond
      ( (or (> (first state) 3) (<(first state) 0)) t)
      (T nil)
  )
)
; ----------------------------------------------------------------------------
; **** Basic recursive function to create search tree (recursive tree expantion)
; **** Βασική αναδρομική συνάρτηση για δημιουργία δέντρου αναζήτησης (αναδρομική επέκταση δέντρου)

(defun FindSolution (front queue closed goal method )
  (cond 
    ((null front)                  'no_solution)
    ((mymember (car front) closed) (FindSolution (cdr front) (cdr queue) closed  goal method  ))
    ((equal (car front) goal)      (format T "This is the solution: ~a" (reverse (first queue))))
    (T (FindSolution (ExpandFront front method) (ExtendQueue queue method)  (cons (car front)  closed) goal method  ))
  )
)     

; ----------------------------------------------------------------------------
; **** FRONT 
; **** Διαχείριση Μετώπου

; ----------------------------------------------------------------------------
; ** initialization of front
; ** Αρχικοποίηση Μετώπου

(defun MakeFront (node)
  (list node)
)

; ----------------------------------------------------------------------------
; **** expanding front
; **** επέκταση μετώπου

(defun ExpandFront (front method)
  (cond
    ( (eq method 'DFS)  (append  ( removeNils ( findchildren (car front)))    (cdr front) )  )
    ( (eq method 'BFS)  (append (cdr front) ( removeNils (findchildren (car front)))))
    ( (eq method 'BESTFS) (sort (append ( removeNils ( findchildren (car front))) (cdr front))#'check) ) 
    (  T                 "other methods to be added"                                       )
  )
)

; ----------------------------------------------------------------------------
; **** QUEUE
; **** Διαχείριση ουράς

; ----------------------------------------------------------------------------
; ** initialization of queue
; ** Αρχικοποίηση ουράς

(defun MakeQueue (node)
  (list (list node))
)

; ----------------------------------------------------------------------------
; **** expanding queue
; **** επέκταση ουράς

 ;;; expanding queue

(defun ExtendQueue (queue method)
  (cond
    ( (eq method 'DFS)      (append  ( growPath (car queue))     (rest queue)  )  )  
    ( (eq method 'BFS)      (append  (rest queue)     (growPath (car queue))  )  ) 
    ( (eq method 'BESTFS)  (sort (append ( growPath (car queue) ) (rest queue))#'check1) )  
    (  T                     "other methods to be added"                         )
  )
)

(defun check (s1 s2)
    (< (+ (third s1) (fourth s1) (fifth s1)) (+ (third s2) (fourth s2) (fifth s2)) ) 
)

(defun check1 (s1 s2)
  (< (+ (third (first s1)) (fourth (first s1)) (fifth (first s1))) (+ (third (first s2)) (fourth (first s2)) (fifth (first s2))))
)

(defvar opt 0) ;Variable definition for the menu

;----------Otptions menu------------------------------------------------------ 
(defun Options ()
  ( print "Searching methods." )
  ( print "For DFS method press 1." )
  ( print "For BFS method press 2." )
  ( print "For BESTFS method press 3." )
  ( print "Choose searching method" )
  ( let (opt (read))) 
  (cond 
    ( ( = opt 1 )  (T (DFS) ) )
    ( ( = opt 2 )  (T (BFS) ) )
    ( ( = opt 3 )  (T (BESTFS) ) ) 
  )
  ( T (nil) )
)


; ----------------------------------------------------------------------------
; **** growing path towards each different child of the selected parent node
; **** επεκταση μονοπατιου προς καθε διαφορετικό παιδί-κόμβο από τον επιλεγμένο γονέα-κόμβο

(defun growPath (path)
  (removecycles (grow1 path (removeNils (findchildren (car path)))))
)

(defun grow1 (path children) 
  (cond 
    ((null children) nil                                                            )
    ( T              (cons (cons (car children) path) (grow1 path (cdr children)))  )
  )
)

; ----------------------------------------------------------------------------
; **** Supportive functions
; **** Υποστηρικτικές συναρτήσεις

(defun mymember(x Y)
  (cond 
    ((endp y)            nil                   )
    ((equal x (first y)) T                     )
    (T                  (mymember x (rest y))  )
  )
)

(defun removeNils (X)
  (cond 
    ((endp x)            nil                                    )
    ((eq (first x) NIL) (removeNils (rest x))                   )
    (T                  (cons (first x) (removeNils (rest x)))  )
  )
)

(defun removecycles (paths)
  (cond 
    ((null paths)                        nil                                          )
    ((member (caar paths) (cdar paths)) (removecycles (cdr paths))                    )
    (T                                  (cons (car paths) (removecycles (cdr paths))) )
  )
)

; ----------------------------------------------------------------------------
; **** Problem's World & Problem depending functions
; **** κόσμος του προβλήματος (αν απαιτείται) και συναρτήσεις σχετικές με το πρόβλημα

;;;; #### to be  added ####


(defvar capacity 5)

(defun goToGround (state)
  (cond
      ( (or (= (+ (third state) (fourth state) (fifth state)) 0)  (= (second state) capacity))
        (list 0 0 (third state)(fourth state)(fifth state))
      )
      (T nil)
  )
)

(defun goToFirst (state)
  (cond 
    (   
      (and (< (second state) capacity) (> (third state) 0))
      (goToFirst (list 1 (+ (second state) 1) (- (third state) 1) (fourth state) (fifth state)))
    )
    (T (list (first state) (second state) (third state) (fourth state) (fifth state)))
  )
)

(defun goToSecond (state)
  (cond
    ( 
      (and (< (second state) capacity) (> (fourth state) 0))
      (goToSecond (list 2 (+ (second state) 1) (third state) (- (fourth state) 1) (fifth state)))
    )
    (T (list (first state) (second state) (third state) (fourth state) (fifth state)))
  )
)

(defun goToThird (state)
  (cond 
    (
      (and (< (second state) capacity) (> (fifth state) 0))
      (goToThird (list 3 (+ (second state) 1) (third state) (fourth state) (- (fifth state) 1)))
    )
    (T (list (first state) (second state) (third state) (fourth state) (fifth state)))
  )
)

; ----------------------------------------------------------------------------
; ** function to find the children nodes of a parent state node
; ** συνάρτηση εύρεσης απογόνων

(defun findchildren (state) 
    (list (goToGround state) (goToFirst state) (goToSecond state) (goToThird state))
)

; ----------------------------------------------------------------------------
; ** Executing the code
; ** κλήση εκτέλεσης κώδικα

;(trace SearchProblem)
(SearchProblem '(0 0 2 6 4) '(0 0 0 0 0) (Options) )

2 个答案:

答案 0 :(得分:2)

我强烈建议您按照现有指南正确缩进common-lisp代码,否则括号会很混乱。

在这里,使用粘液和正则表达式搜索并替换,我正确地缩进了您的代码并简化了一些内容,并且通过这种缩进-发现了一些括号错误。 我纠正了它们。

通过缩进级别,您可以看到发生paren错误的地方。

对于您的问题,我建议:

(defun options ()
  (print "Searching methods.")
  (print "For DFS method press 1.")
  (print "For BFS method press 2.")
  (print "For BESTFS method press 3.")
  (print "Choose searching method")
  (let ((opt (read))) ;; here were some paren' mistakes! 
    (case opt         ;; case is the `switch` in cl
      (1 'DFS)
      (2 'BFS)
      (3 'BESTFS) ;; here was an erroneous parenthesis
      (otherwise 'nil)))) ;; here one paren' added

正确缩进了整个代码(使用emacs SLIME模式进行common-lisp缩进),并进行了一些更改以简化操作:

;; --------------------------------------------------
;; ******** Search Code for DFS  and other search methods
;; ******** (expanding front and extending queue)
;; ******** author:  AI lab
;; ********
;; ******** Κώδικας για DFS και άλλες μεθόδους αναζήτησης
;; ******** (επέκταση μετώπου και διαχείριση ουράς)
;; ******** Συγγραφέας: Εργαστήριο ΤΝ
;; --------------------------------------------------
;; **** starting search 
;; **** έναρξη αναζήτησης

(defun searchProblem (start-state goal method)
  (if (StateValidation start-state)
      (print "Invalid data!") ;; print returns nil
      (findSolution (MakeFront start-state)
                    (MakeQueue start-state)
                    ()
                    goal
                    method)))

;;**** Checking for valid states

(defun StateValidation 
    (or (> (first state) 3)
     (< (first state) 0))) ;; if condition is true, returns T else nil

;;--------------------------------------------------
;;**** Basic recursive function to create search tree (recursive tree expantion)
;;**** Βασική αναδρομική συνάρτηση για δημιουργία δέντρου αναζήτησης (αναδρομική επέκταση δέντρου)

(defun FindSolution (front queue closed goal method)
  (cond ((null front) 'no_solution)
        ((mymember (car front) closed)
         (FindSolution (cdr front)
                       (cdr queue)
                       closed
                       goal
                       method))
        ((equal (car front) goal)
         (format T "This is the solution: ~a" (reverse (first queue))))
        (T (FindSolution (ExpandFront front method)
                         (ExtendQueue queue method)
                         (cons (car front) closed)
                         goal
                         method))))

;;--------------------------------------------------
;;**** FRONT 
;;**** Διαχείριση Μετώπου

;;--------------------------------------------------
;;** initialization of front
;;** Αρχικοποίηση Μετώπου

(defun MakeFront (node)
  (list node))

;;--------------------------------------------------
;;**** expanding front
;;**** επέκταση μετώπου

(defun ExpandFront (front method)
  (case method
    (DFS (append (removeNils (findchildren (car front)))
                 (cdr front)))
    (BFS (append (cdr front)
                 (removeNils (findchildren (car front)))))
    (BESTFS (sort (append (removeNils (findchildren (car front)))
                          (cdr front)) #'check)) 
    (otherwise "other methods to be added")))

;;--------------------------------------------------
;;**** QUEUE
;;**** Διαχείριση ουράς

;;--------------------------------------------------
;;** initialization of queue
;;** Αρχικοποίηση ουράς

(defun MakeQueue (node)
  (list (list node)))

;;--------------------------------------------------
;;**** expanding queue
;;**** επέκταση ουράς
;;; expanding queue

(defun ExtendQueue (queue method)
  (case method
    (DFS (append (growPath (car queue))
                 (rest queue))) 
    (BFS (append (rest queue)
                 (growPath (car queue)))) 
    (BESTFS (sort (append (growPath (car queue))
                          (rest queue)) #'check1)) 
    (otherwise "other methods to be added")))

#|
(defun check (s1 s2)
  (< (+ (third s1)
        (fourth s1)
        (fifth s1))
     (+ (third s2)
        (fourth s2)
        (fifth s2))))
|#

(defun sum-3rd-to-5th (s)
  (+ (third s) (fourth s) (fifth s)))

(defun check (s1 s2)
  (< (sum-3rd-to-5th s1)
     (sum-3rd-to-5th s2)))

(defun check1 (s1 s2)
  (check (first s1) (first s2))) ;; this is equivalent to before - uses `check` above

(defvar opt 0) ;Variable definition for the menu

;;----------Otptions menu------------------------------------------------------

(defun options ()
  (print "Searching methods.")
  (print "For DFS method press 1.")
  (print "For BFS method press 2.")
  (print "For BESTFS method press 3.")
  (print "Choose searching method")
  (let ((opt (read))) ;; parenthesis mistakes also here! 
    (case opt
      (1 'DFS)
      (2 'BFS)
      (3 'BESTFS) ;; here was an erroneous paranthesis
      (otherwise 'nil)))) ;; here one added


;;--------------------------------------------------
;;**** growing path towards each different child of the selected parent node
;;**** επεκταση μονοπατιου προς καθε διαφορετικό παιδί-κόμβο από τον επιλεγμένο γονέα-κόμβο

(defun growPath (path)
  (removecycles (grow1 path (removeNils (findchildren (car path))))))

(defun grow1 (path children) 
  (cond ((null children) nil)
        (T (cons (cons (car children) path)
                 (grow1 path (cdr children))))))

;;--------------------------------------------------
;;**** Supportive functions
;;**** Υποστηρικτικές συναρτήσεις

#|
(defun mymember(x y)
  (cond ((null y) nil)
        ((equal x (first y)) T)
        (T (mymember x (rest y)))))

(defun removeNils (x)
  (cond ((null x) nil)
        ((eq (first x) NIL) (removeNils (rest x)))
        (T (cons (first x)
                 (removeNils (rest x))))))
|#



(defun mymember (x y)
  (member x y :test #'equal))

(defun removeNils (x)
  (remove-if #'null x))

(defun removecycles (paths)
  (cond ((null paths) nil) 
        ((member (caar paths)
                 (cdar paths))
         (removecycles (cdr paths)))
        (T (cons (car paths)
                 (removecycles (cdr paths))))))

;;--------------------------------------------------
;;**** Problem's World & Problem depending functions
;;**** κόσμος του προβλήματος (αν απαιτείται) και συναρτήσεις σχετικές με το πρόβλημα

#| isn't state a list of 5 elements?
(list (first state)
      (second state)
      (third state)
      (fourth state)
      (fifth state)) ;; ===> state
|#

;;;; #### to be added ####


(defvar capacity 5)

(defun goToGround (state)
  (if (or (zerop (sum-3rd-to-5th state))
          (zerop (second state) capacity))
      (list 0
            0
            (third state)
            (fourth state)
            (fifth state))
      nil))

(defun goToFirst (state)
  (if (and (< (second state) capacity)
           (> (third state) 0))
      (goToFirst (list 1
                       (1+ (second state))
                       (1- (third state))
                       (fourth state)
                       (fifth state)))
      state))

(defun goToSecond (state)
  (if (and (< (second state) capacity)
           (> (fourth state) 0))
      (goToSecond (list 2
                        (1+ (second state))
                        (third state)
                        (1- (fourth state))
                        (fifth state)))
      state))

(defun goToThird (state)
  (if (and (< (second state) capacity)
           (> (fifth state) 0))
      (goToThird (list 3
                       (1+ (second state))
                       (third state)
                       (fourth state)
                       (1- (fifth state))))
      state))

;;--------------------------------------------------
;;** function to find the children nodes of a parent state node
;;** συνάρτηση εύρεσης απογόνων

(defun findchildren (state) 
  (list (goToGround state)
        (goToFirst state)
        (goToSecond state)
        (goToThird state))) 

;;--------------------------------------------------
;;** Executing the code
;;** κλήση εκτέλεσης κώδικα

;; (trace SearchProblem)
(SearchProblem '(0 0 2 6 4)
               '(0 0 0 0 0)
               (Options))

答案 1 :(得分:1)

您正试图调用DFSBFSBESTFS作为函数。它们只是应该返回的符号,它们将作为参数传递给其他函数。

也不应该将它们包装在(T ...)中。并且(T (nil))必须是COND的子句,而不是后面的子句。同样,nil不应放在括号内,这意味着尝试将其作为函数来调用。不过,您实际上并不需要此子句,因为如果没有条件匹配,COND默认会返回NIL

测试opt的代码必须位于绑定它的let内部。

(defun Options ()
  ( print "Searching methods." )
  ( print "For DFS method press 1." )
  ( print "For BFS method press 2." )
  ( print "For BESTFS method press 3." )
  ( print "Choose searching method" )
  ( let (opt (read))
      (cond 
        ( ( = opt 1 )  'DFS )
        ( ( = opt 2 )  'BFS )
        ( ( = opt 3 )  'BESTFS ) 
        ( T nil )))
  )
)