2016-07-27 3 views
-2

Я не понимаю, почему моя программа ведет себя так, как она есть.LIST return in inested cond

(defvar A '((X Y Z) (J L O P) (G W U)) 

(defvar Z '(X W D U G)) 

(defvar STOP 'G) 

(defun ADD_to_Z(A2) 
    (prog() 
    (cond 
     ((equal (Member_Of_Z (list A2)) 0)) 
     (t (setq Z (append Z (list A2)))) 
    ) 
) 
) 

(defun Member_of_Z(cdr_A1) 

(prog(n temp) 
    (setq n 0) 
    (setq temp cdr_A1) 
    repeat 
    (cond 
    ((null temp) (return n)) 
    ((null (member (car temp) Z)) (setq n (+ n 1)) (setq temp (cdr temp))) 
    (t (setq n (+ n 0)) (setq temp (cdr temp))) 
    ) 
    (go repeat) 
) 
) 



(defun TEST(A) 

(prog(A1 A2) 

     (cond 
      ((null A) (return 'Fail)) 
      (t (setq A1 (car A)) (setq A (cdr A)) (setq A2 (car A1)) 
      (cond 
       ((equal (Member_Of_Z (cdr A1)) 0) 
       (cond 
       ((equal A2 STOP) (return 'SUCCESS)) 
       (t (ADD_to_Z A2) (setq A (cdr A)) (TEST A)) 
       ) 
      ) 
       (t (TEST A) ) 
      ) 
     ) 
    ) 

    ) 
    ) 

Цель функций: - Member_of_Z будет проверять, если все элементы из cdr A1 принадлежат Z. Если да, то он возвращает 0 (некоторое другое число еще в противном случае). Это то, что не происходит Это было предположить, чтобы вернуться УСПЕХ, когда А равно ((G W U))

  • ADD_to_Z добавит А2 до Я, когда Member_Of_Z не возвращает 0

Проблема: Не только кажется (в конце функции TEST, A по-прежнему равна его исходному значению, установленному defvar, хотя я изменяю его (setq A (cdr A)). Также УСПЕХ никогда не возвращается.

Не могли бы вы мне помочь?

+2

Изменение литералы не определено поведение (или определяется реализацией, никогда не Remeber) в CL. Если вы хотите изменить использование списка (список ... элементов), чтобы определить его вместо цитаты. – PuercoPop

+2

@PuercoPop Это, похоже, не изменяет литеральные данные, он просто присваивает новые значения 'A' (или пытается, но параметр функции затеняет привязку). – jkiiski

+3

Существует много логических ошибок, и стиль больше похож на Fortran, чем CL. Пример не работает, поскольку вы оставили функции, которые он использует, и поскольку вы не использовали пример с ожидаемым результатом, я понятия не имею, что это это делать. переменные 'defvar' не имеют своих' * earmuffs *, поэтому они неразличимы с лексическими переменными. Когда вы 'setq'-ing' A', это параметр в 'test', а не misnamed global, который вы меняете. – Sylwester

ответ

5

Шаг 1: используйте стандартное форматирование (исправление первой формы верхнего уровня).

(defvar A '((X Y Z) (J L O P) (G W U))) 

(defvar Z '(X W D U G)) 

(defvar STOP 'G) 

(defun ADD_to_Z (A2) 
    (prog() 
    (cond ((equal (Member_Of_Z (list A2)) 0)) 
      (t (setq Z (append Z (list A2))))))) 

(defun Member_of_Z (cdr_A1) 
    (prog (n temp) 
    (setq n 0) 
    (setq temp cdr_A1) 
    repeat 
    (cond ((null temp) (return n)) 
      ((null (member (car temp) Z)) (setq n (+ n 1)) (setq temp (cdr temp))) 
      (t (setq n (+ n 0)) (setq temp (cdr temp)))) 
    (go repeat))) 

(defun TEST (A) 
    (prog (A1 A2) 
    (cond ((null A) (return 'Fail)) 
      (t (setq A1 (car A)) 
      (setq A (cdr A)) 
      (setq A2 (car A1)) 
      (cond ((equal (Member_Of_Z (cdr A1)) 0) 
        (cond ((equal A2 STOP) (return 'SUCCESS)) 
          (t (ADD_to_Z A2) (setq A (cdr A)) (TEST A)))) 
        (t (TEST A))))))) 

Шаг 2: используйте стандартное обозначение.

(defvar *a* '((x y z) (j l o p) (g w u))) 

(defvar *z* '(x w d u g)) 

(defvar *stop* 'g) 

(defun add-to-z (a2) 
    (prog() 
    (cond ((equal (member-of-z (list a2)) 0)) 
      (t (setq *z* (append *z* (list a2))))))) 

(defun member-of-z (cdr-a1) 
    (prog (n temp) 
    (setq n 0) 
    (setq temp cdr-a1) 
    repeat 
    (cond ((null temp) (return n)) 
      ((null (member (car temp) *z*)) (setq n (+ n 1)) (setq temp (cdr temp))) 
      (t (setq n (+ n 0)) (setq temp (cdr temp)))) 
    (go repeat))) 

(defun test (a) 
    (prog (a1 a2) 
    (cond ((null a) (return 'fail)) 
      (t (setq a1 (car a)) 
      (setq a (cdr a)) 
      (setq a2 (car a1)) 
      (cond ((equal (member-of-z (cdr a1)) 0) 
        (cond ((equal a2 *stop*) (return 'success)) 
          (t (add-to-z a2) (setq a (cdr a)) (test a)))) 
        (t (test a))))))) 

Шаг 3: избавиться от PROG.

(defvar *a* '((x y z) (j l o p) (g w u))) 

(defvar *z* '(x w d u g)) 

(defvar *stop* 'g) 

(defun add-to-z (a2) 
    (cond ((equal (member-of-z (list a2)) 0)) 
     (t (setq *z* (append *z* (list a2)))))) 

(defun member-of-z (cdr-a1) 
    (let ((n 0) 
     (temp cdr-a1)) 
    repeat 
    (cond ((null temp) (return n)) 
      ((null (member (car temp) z)) (setq n (+ n 1)) (setq temp (cdr temp))) 
      (t (setq n (+ n 0)) (setq temp (cdr temp)))) 
    (go repeat))) 

(defun test (a) 
    (cond ((null a) (return 'fail)) 
     (t (let ((a1 (car a)) 
       (a (cdr a)) 
       (a2 (car a1))) 
      (cond ((equal (member-of-z (cdr a1)) 0) 
        (cond ((equal a2 *stop*) (return 'success)) 
          (t (add-to-z a2) (setq a (cdr a)) (test a)))) 
        (t (test a))))))) 

Шаг 4: заменить ручную петлю структурированным.

(defvar *a* '((x y z) (j l o p) (g w u))) 

(defvar *z* '(x w d u g)) 

(defvar *stop* 'g) 

(defun add-to-z (a2) 
    (cond ((equal (member-of-z (list a2)) 0)) 
     (t (setq *z* (append *z* (list a2)))))) 

(defun member-of-z (cdr-a1) 
    (let ((n 0) 
     (temp cdr-a1)) 
    (loop :for element :in temp 
      :unless (member element *z*) 
      :do (incf n)) 
    n)) 

(defun test (a) 
    (cond ((null a) (return 'fail)) 
     (t (let ((a1 (car a)) 
       (a (cdr a)) 
       (a2 (car a1))) 
      (cond ((equal (member-of-z (cdr a1)) 0) 
        (cond ((equal a2 *stop*) (return 'success)) 
          (t (add-to-z a2) (setq a (cdr a)) (test a)))) 
        (t (test a))))))) 

Шаг 5: заменить двухпозиционный COND на IF. Уменьшите формы RETURN, когда они находятся в любом положении (и они не работают так) в .

(defvar *a* '((x y z) (j l o p) (g w u))) 

(defvar *z* '(x w d u g)) 

(defvar *stop* 'g) 

(defun add-to-z (a2) 
    (if (equal (member-of-z (list a2)) 0) 
     nil 
     (setq *z* (append *z* (list a2))))) 

(defun member-of-z (cdr-a1) 
    (let ((n 0) 
     (temp cdr-a1)) 
    (loop :for element :in temp 
      :unless (member element *z*) 
      :do (incf n)) 
    n)) 

(defun test (a) 
    (if (null a) 
     'fail 
     (let ((a1 (car a)) 
      (a (cdr a)) 
      (a2 (car a1))) 
     (if (equal (member-of-z (cdr a1)) 0) 
      (if (equal a2 *stop*) 
       'success 
       (progn (add-to-z a2) (setq a (cdr a)) (test a))) 
      (test a))))) 

Шаг 6: заменить петлю простой функцией подсчета.

(defvar *a* '((x y z) (j l o p) (g w u))) 

(defvar *z* '(x w d u g)) 

(defvar *stop* 'g) 

(defun add-to-z (a2) 
    (if (equal (member-of-z (list a2)) 0) 
     nil 
     (setq *z* (append *z* (list a2))))) 

(defun member-of-z (cdr-a1) 
    (count-if-not (lambda (element) 
        (member element *z*)) 
       cdr-a1)) 

(defun test (a) 
    (if (null a) 
     'fail 
     (let ((a1 (car a)) 
      (a (cdr a)) 
      (a2 (car a1))) 
     (if (equal (member-of-z (cdr a1)) 0) 
      (if (equal a2 *stop*) 
       'success 
       (progn 
        (add-to-z a2) 
        (setq a (cdr a)) 
        (test a))) 
      (test a))))) 

На данный момент я до сих пор не знаю, что вы пытаетесь сделать. Может быть, вы хотите найти список в *a*, который полностью содержится в *z*:

(defun test (a) 
    (find-if (lambda (list) 
      (every (lambda (element) 
         (member element *z*)) 
        list)) 
      a)) 
+1

Вы можете использовать 'SUBSETP' в этом последнем фрагменте. Может быть, 'MEMBER-IF' будет лучше, так как код, кажется, возвращает« boolean »(SUCCESS/FAIL). – jkiiski

+0

Да, в моем примере есть недостающая функция, которая, как предполагается, вызывает 'TEST' при ошибке состояния. Функция проверяет, находится ли 'stop' в' z', если не запускается 'test'. 'test' должен делать все, что он делает, пока не найдет под-список в' a', все элементы которого находятся в 'z', а первый элемент (то есть его' car') равен 'stop'. Если это выполняется, оно возвращает 'success'. Мой вопрос: звезды \ * ... * 'гарантируют, что глобальный может быть вызван и перезаписан? Если бы я остановился на вашем шаге 2, код все равно будет работать (т. Е. Я буду пропускать только соответствующий синтаксис?) –

+0

@jkiiski, пожалуйста, просмотрите мой комментарий прямо над –