「命題」は英語ではpropositionと書く。数値が0のとき真の値を返す関数zeropとか、偶数かどうかを判定する関数evenpとか、奇数かとうかを判定する関数oddpとか、そういうcommon lispの関数名末尾のpは多分、propositionの頭文字pからきている。
命題は真か偽の値を持つ。common lispでは真の値をT、偽の値を()とかNILで表現する。common lispで簡単な命題を3つ書いてみる。
(defun p1 (n) (= 0 (mod n 2))) (defun p2 (n) (= 0 (mod n 3))) (defun p3 (n) (= 0 (mod n 5)))
p1は2で割って余りが0なら真の値を返す命題、p2は3で割って余り0のとき真の命題、p3は5で割って余り0のとき真の命題、というつもりで書いた。
optimaというパターンマッチライブラリを使えば、真理値表のようなのもが書ける。
(ql:quickload :optima) (use-package :optima) (defun ppp (n) (match (list (p1 n) (p1 n) (p3 n)) ('(T T T ) " p1 ∧ p2 ∧ p3") ('(T T ()) " p1 ∧ p2 ∧¬p3") ('(T () T ) " p1 ∧¬p2 ∧ p3") ('(T () ()) " p1 ∧¬p2 ∧¬p3") ('(() T T ) "¬p1 ∧ p2 ∧ p3") ('(() T ()) "¬p1 ∧ p2 ∧¬p3") ('(() () T ) "¬p1 ∧¬p2 ∧ p3") ('(() () ()) "¬p1 ∧¬p2 ∧¬p3"))) ;; 使ってみる > (ppp 2) " p1 ∧¬p2 ∧¬p3" > (ppp 3) "¬p1 ∧ p2 ∧¬p3" > (ppp 5) "¬p1 ∧¬p2 ∧ p3" > (ppp 7) "¬p1 ∧¬p2 ∧¬p3" > (ppp (* 2 3 5)) " p1 ∧ p2 ∧ p3" > (ppp (* 2 3 5 7)) " p1 ∧ p2 ∧ p3" > (ppp (* 2 3)) " p1 ∧ p2 ∧¬p3" > (ppp (* 3 5)) "¬p1 ∧ p2 ∧ p3" > (ppp (* 2 5)) " p1 ∧¬p2 ∧ p3"
「optimaを使っての、この条件分岐のやり方なかなかいいな」と思ったので記した。