直積を求める

foreach 的な発想がやっぱりミスリード。直積を求めるのが先決だ。

(setf pt0 '("XXX" ("x_A" "x_B" "x_C")))
(setf pt1 '("YYY" ("y_A" "y_B" "y_C")))

(defun make-pair (pt)
  (let ((src (car pt))
        (ln-dst (cadr pt)))
    (mapcar (lambda (x)
              (list src x))
            ln-dst)))

(defun chokux (ln-a ln-b)
  (reduce #'append
          (mapcar (lambda (ai)
                    (mapcar (lambda (bi)
                              (list ai bi))
                            ln-b))
                  ln-a)))

(defun test ()
  (chokux (make-pair pt0) (make-pair pt1)))

結果は

((("XXX" "x_A") ("YYY" "y_A")) (("XXX" "x_A") ("YYY" "y_B"))
 (("XXX" "x_A") ("YYY" "y_C")) (("XXX" "x_B") ("YYY" "y_A"))
 (("XXX" "x_B") ("YYY" "y_B")) (("XXX" "x_B") ("YYY" "y_C"))
 (("XXX" "x_C") ("YYY" "y_A")) (("XXX" "x_C") ("YYY" "y_B"))
 (("XXX" "x_C") ("YYY" "y_C")))

これを突き進めていくと SICP や On Lisp(実は SICP の焼き直しが散見される)の非決定性になるかな。call/cc で作ると無限列の直積も出来るしね。するとあれだな、無限の組み合わせの上位計算できるだけ、、、なんてことが選択できるんだな。