2016-07-27 3 views
-2

私のプログラムがなぜ動作しているのか分かりません。機能のLISTネストされた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) ) 
      ) 
     ) 
    ) 

    ) 
    ) 

目標: - 彼らが行う場合cdr A1のがZに属しすべての要素が、それは(そうでない場合は、他のいくつかの他の数)は0を返すかどうMember_of_Zを確認します。唯一のAは思わない:これはが起きていないことは、Aが0

問題を返さないときMember_Of_Z ZにA2を追加します((G W U))

  • ADD_to_Zに等しい場合にSUCCESSを返すようにするとしたものです関数TESTの最後で、Aは(setq A (cdr A))で修正していますが、defvarで設定した元の値と同じです。また、SUCCESSは返されません。

    助けてくれませんか?

+2

変更リテラルはCLで未定義の動作(または定義された実装、決して思い出してくれる)です。リストの使用法(list ...要素)を変更して引用符ではなく定義する場合。 – PuercoPop

+2

@PuercoPopリテラルデータを変更しているようではありません。新しい値を 'A'に代入するだけです(または、しようとしていますが、関数パラメータがバインディングをシャドーしています)。 – jkiiski

+3

多くの論理エラーがあり、スタイルはCLよりもFortranに似ています。使用する関数を省略しているので、例は実行可能ではありません。また、期待される結果を使用例として与えていないので、やるべきことがある。 'defvar'変数には' * earmuffs * 'がありませんので、それらは字句変数と見分けがつきません。 'set'を' A'にすると 'test'のパラメータであり、あなたが変更しようとしている名前のないグローバルではありません。 @Sylwesterありがとう。 – 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:2節の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))))) 

この時点で、私はまだ何をしようとしているのか分かりません。おそらく、あなたは完全に*z*に含まれている*a*内のリストを見つけること をしたい:

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

最後のスニペットで 'SUBSETP'を使うことができます。コードが "ブール値"(SUCCESS/FAIL)を返しているようであるため、おそらく 'MEMBER-IF'も良いでしょう。 – jkiiski

+0

はい私の例では、条件の失敗で 'TEST'を呼び出すと思われる機能がありません。この関数は 'stop'が' z'にあるかどうかをチェックし、 'stop'が' test'を起動します。 'test'は、要素がすべて' z'で、最初の要素( 'car')が' stop'に等しい 'a'の部分リストを見つけるまで、すべてを行うと仮定します。これが満たされれば、「成功」を返します。私の質問は次のとおりです。* * * *星は地球を呼んで上書きすることができますか?あなたのステップ2で停止した場合、コードはまだ動作します(つまり、正しい構文だけが失われますか?) –

+0

@jkiiski上記のコメントを参照してください –

関連する問題