4.2 数式の表現変換プログラム(前置表現→内挿表現)

前置表現から内挿表現に変換する Lisp プログラム

関数 機能
(pre2in expr) 前置表現 expr を内挿表現に変換する

前置表現から内挿表現への変換は非常に簡単である。 なぜなら、二分木と同じで(左の被演算子→演算子→右の被演算子) と読んでいく再帰呼出しプログラムを書けばよいだけだからである。

プログラムリスト: pre2in.el


;;;---------------------------------------------------------------
;;; 前置表現から内挿表現への変換 (by 平野 拓一)
;;; 必要ファイル: in2pre.el
;;;---------------------------------------------------------------

;;;---------------------------------------------------------------
;;; 前置表現から内挿表現への変換
;;;---------------------------------------------------------------

; 前置表現から内挿表現へ変換する関数
(defun pre2in (expr)
    (pre2in_1 expr -1)
)

(defun pre2in_1 (expr wei_prev)
    ; ローカル変数 wei を使う
    (let (wei)
         (cond
             ;---- condition: 空リストの処理
             ((null expr) expr)
 
             ;---- condition: 負の数のとき f → ((f))
             ((and (atom expr)
                   (integerp expr)
                   (not (natnump expr)))
              (list (list expr)))

             ;---- condition: f → (f)
             ((atom expr) (list expr))

             ;---- condition: 関数呼び出し
             ((eq (weight (car expr)) 6) (pre2in_3 expr))

             ;---- condition: 演算順位を比べて括弧をつけるかどうか
             ; wei_prev > wei だったら括弧をつける
             (t (setq wei (weight (car expr)))
                (if (< wei wei_prev)
                    ;---- true: 括弧をつける
                    (list (pre2in_2 expr wei))
                    ;---- false: 括弧はつけない
                    (pre2in_2 expr wei)
                )
             )
         )
    )
)

;---- 2項演算の処理 ----
(defun pre2in_2 (expr wei)
    (append (pre2in_1 (cadr expr) wei)
            (list (car expr))
            (pre2in_1 (caddr expr) wei)
    )
)

;---- 関数呼び出しの処理 ----
(defun pre2in_3 (expr)
    (list (car expr)
          (pre2in_1 (cadr expr) -1)
    )
)

;;;---------------------------------------------------------------
;;; 確認テスト
;;;---------------------------------------------------------------

; 変数 expr に式を代入する
(setq expr '((1 + 3 * x) * 2 + sin (- x ^ 2) * log ( a )))

; 前置表現に変換する
(setq expr (in2pre expr))

; 前置表現を内挿表現に変換する
(pre2in expr)

;;
;; End of file
;;

実行例

入力 (setq expr '((1 + 3 * x) * 2 + sin (- x ^ 2) * log ( a )))
(setq expr (in2pre expr))
(pre2in expr)
出力 ((1 + 3 * x) * 2 + sin (0 - x ^ 2) * log (a))

Go Back