3

Little Schemer の第 9 章で、著者は次の 2 つの機能を提示します。

(define Q 
  (lambda (str n) 
    (cond 
      ((zero? (remainder (first$ str ) n)) 
        (Q (second$ str ) n)) 
      (t (build (first$ str ) 
        (lambda ( ) 
          (Q (second$ str ) n))))))) 

(define P
  (lambda (str)
    (build (first$ str)(lambda () (P (Q str (first$ str)))))))

そして、それらが次の実行で評価されることを提案します:

(frontier (P (second$ (second$ int)))  10)

Common Lisp で P および Q 関数をどのように記述しますか?

(私は Y-Combinator を自分で翻訳しましたが、これは難しいと思います)

--ヘルパー関数--

(define frontier
  (lambda (str n)
    (cond
      ((zero? n) (quote ()))
        (t (cons (first$ str) (frontier (second$ str) (sub1 n)))))))

(define str-maker
  (lambda (next n)
    (build n (lambda () (str-maker next (next n))))))

(define int (str-maker add1 0))

(define second$
  (lambda (str)
    ((second str))))

(define first$ first)

(define build
  (lambda (a1 a2)
    (cond
      (t (cons a1
        (cons a2 (quote ())))))))))

(define first
  (lambda (p)
    (cond
       (t (car p)))))

(define second
  (lambda (p)
    (cond
      (t (car (cdr p))))))

(define add1 
  (lambda (n)
    (+ 1 n)))

(define remainder 
  (lambda  (n m)
    (cond
      (t (- n (* m (/ n m ))))))

(免責事項 - これは宿題の質問ではありません - これは私の理解と学習のためのものです)

4

1 に答える 1

6

私は仮定しました:

  • P の定義では、"(Q (str (first$ str)))" は "(Q str (first$ str))" という意味でした。Q は 2 引数の関数だからです。
  • buildは、first$ と second$ が機能するものを作成するヘルパーです:リスト

これを念頭に置いて、Scheme を Common Lisp に直接変換すると、次のようになります。

(defun first$ (list) (first list))
(defun second$ (list) (funcall (second list)))
(defun build (a b) (list a b))

(defun frontier (str n)
  (if (zerop N)
    ()
    (cons (first$ str) (frontier (second$ str) (1- n)))))

(defun str-maker (next n)
  (list n (lambda () (str-maker next (funcall next n)))))

(setq int-maker (str-maker #'1+ 0))

(defun Q (str n)
  (if (zerop (rem (first$ str) n))
    (Q (second$ str) n)
    (list (first$ str) (lambda () (Q (second$ str) n)))))

(defun P (str)
  (list (first$ str) (lambda () (P (Q str (first$ str))))))

(frontier (P (second$ (second$ int-maker))) 10)

その最後の行は次を返します:

(2 3 5 7 11 13 17 19 23 29)

これはよく知られているシリーズなので、翻訳は成功していると思います:-)

于 2009-11-13T17:21:28.187 に答える