2012/12/05

「絶対音感ある人に30の質問」なるものを見付けたので答えてみた

ちょうど絶対音感について調べていたところこんなものを見付けた。

Q.1 お名前と、この質問の回答日を教えてください。
名前は不要。回答日は2012/12/05(1354709610)。
Q.2 年齢・性別をお願いします。
17歳、男
Q.3 今のお仕事を教えてください。
高校生
Q.4 初めて音楽の手ほどきを受けたのは何歳?そのときの楽器は?
4歳で音楽教室。しかしエレクトーンで右手と左手で同時に別の動きをできず辞める。
その頃には既に絶対音感があった
Q.5 あなたの絶対音感は先天性?それとも後天性?
物心ついたころというか、「音」を意識するようになったころには絶対音感があったので不明。
あと、学術的にどうなのかは知らないが、先天的だという話は聞く。
Q.6 ピアノのA (ラ)を何Hzでとらえていますか?
ピアノのチューニングによる。
俺の中で最も出番の多いイメージの「A」は442Hzくらい。
Q.7 暗譜は得意ですか?
たぶん。何回も聞いたりしてれば、2〜3つのパートなら憶えられると思う。
しかし今は楽器をやっていないのでクオリティや程度は不明。
Q.8 移調は得意ですか?
苦手とも言える。「ラ」の基準が440Hz周辺なのは変わらないが、転調した後のメロディを脳内再生して、その音名を認識することで苦労なしに転調は可能。そういう意味では苦手ではない。
Q.9 生活音(グラスの触れ合う音や掃除機のモーター音など)も聴音できますか?
原理的に不可能なもの(ホワイトノイズとか)でなければ。掃除機、グラスの音、電子レンジ、PCファン(これは複数の成分)など、特定の周波数が強く出るようなものは「ド」とか「ファ」とか音名で聞こえてくる。
Q.10 聴音しにくい(出来ない)音はありますか?
ある。PCのファン(機種による)とか。でも、じっと聞いていればわかる。
あと、人の会話の声みたいな、連続で不規則に変化しつづける音も苦手。でも、これも脳内で伸ばして再生すればわかる。
先述のとおり、ホワイトノイズとかは原理的に不可能。
Q.11 相対音感は持っていますか?
持ってない。しかし絶対音感で代用可能なこともあると思われる。欲しい。
Q.12 駅やお店で流れるBGM。ピッチが狂っていたときのあなたの反応は?
曲として成立していれば、基準のズレは気にならない。
しかし、「このメロディやこのピッチでこの音はおかしい(ズレている)」などは即座にわかる。
Q.13 絶対音感があって良かったこと。
屁の音がわかる。

嘘。
自分の好きな曲(主にアニソンやゲームサントラ)がすぐに口ずさめるようになる。
歌っていて、音がズレるとすぐに修正できる(はじめから目的の音を出すのは歌う訓練が必要なので別の問題)。
Q.14 絶対音感があって困ったこと。
屁の音がわかる。

嘘。
耳鳴りで「ドだ!」とかなる。だから何だよ、とセルフツッコミしてしまうので自分でも面倒だと思う。
Q.15 明日の夕ご飯、何食べたい?
不味くなければ何でもいい
Q.16 神様が来て、『明日から君の絶対音感をなくします。』と言ったらあなたはどうする?YES・NOで答えてみてください。
どっちがYESかは知らないが、ちょっと困る。困るけど相手が神じゃどうしようもない。
次に、神が本当に存在することに驚く。
さらに、なぜそれが神だと認識したのか、自分の精神について考察を始める。
Q.17 一度に何音までなら聴き取れますか?
和音はまとめて聞き取るのは難しく、音名は一音ずつ聞いているので、鳴り続けていれば倍音以外で12音階に含まれるものなら何音でも(よく考えたらそれって最高12音だな)。
まあどうせ一瞬だったら、その音を憶えて脳内で伸ばして再生して音名を判別するまでだけど。
倍音は難しい。普通ならC3とC4とかは別の音として区別するのは簡単だけど、ピアノでC2とC3とかと他の沢山の音を同時に出されると、端のオクターブ違いの音は区別しづらい。
つまり、音名はほぼ確実に当てられるけど高さは微妙になる
Q.18 イタリア音(ドレミ)とドイツ音(CDE)聴こえてくるのはどっち?使っているのは?
「ドレミ」。シャープやフラットは、曲によって同じ音(例えばC#)でも「ド」に聞こえたり「レ」に聞こえたりする。
「ド」という言葉で聞こえてきても、シャープ・フラットは確実に判定できる。
Q.19 歌詞のある曲を聴いたとき、まず聴こえてくるのは歌詞?それとも音名?
同時というか並列というか別次元。図形でいうところの色と形みたいな。
「緑の三角形」とか「赤の円」みたいに、別の質のモノとして同時に認識できる。
"Zero fill love"という歌の「CDE♭FGA♭B♭C」の音階で「ラシドレミファソラ」と喋っているのが一度に理解できる。少々気持ち悪いが。(この音名も脳内再生で認識して書いてる)
むしろ他の人は同次元の言葉として聞こえるの?
Q.20 音を聴いて色が見える‥ってことありますか?
それはない。耳から入ってきた情報は耳と脳だけで完結する。
「緑の三角形」を見て音は聞こえてこないのと同じ。
聞こえてくる人がいるとしたら、俺にはわからない感覚。
Q.21 初めて聴く曲でもすぐに楽器で再現できますか?
できる(楽器を弾ければ)。
ピアノはできないけど、バイオリンの運指(第1ポジションのみ)は憶えているので、メロディ(和音は練習が必要だけど)は「この指でこの弦をこうやって抑えて」とリアルタイムで指を動かせる。
指や認識が追い付かないような高速な曲じゃなければね!
Q.22 最近はまっていることは何ですか?
プログラミング、ドストエフスキーの著作の読書、CPU自作。
Q.23 好きな音楽のジャンルは?
アニソン全般、ゲームサントラ。
Q.24 これは一押し!という曲、またはCDはありますか?
ここに記すには余白が狭すぎる(ブログだけど)
Q.25 即興演奏できますか?
楽器が弾ければね…
Q.26 自分の子供にも絶対音感をつけたいですか?
俺のように苦痛なしにできるものなら是非。
Q.27 絶対音感持っていない人を羨ましいと思ったことありますか?
ない。音階外して歌っているのに自分で気付かない人を見るとイライラするし、可哀想に思う。
まあ実害は大して無いのだけれど。
Q.28 音楽の魅力って何でしょう?
気分が増幅されるところ。
明るい気分のときに暗い曲を聞いたり逆をしても気分には影響しないけど、気分に合った曲を聞くと程度や持続時間が大きくなる。
どちらにしろ心地良い。
Q.29 自分に何か質問して答えてみてください。(何問でも可)
Q.「あなたは自分に何を質問するか?また、その答えは?」
A.「『あなたは自分に何を質問するか?また、その答えは?』と質問する。その答えは、『『あなたは自分に何を質問するか?また、その答えは?』と質問す(以下略。
Q.30 おつかれさまでした。最後に一言、どうぞ。
ょぅι゛ょ!

2012/11/11

gentooのapache2.4で"Invalid Mutex directory"なるエラーが出たので対処した

システムは以下のとおり。

$ emerge --version Portage 2.2.0_alpha142 (default/linux/amd64/10.0/desktop, gcc-4.7.2, glibc-2.16.0, 3.6.6-gentoo x86_64) $ emerge -pv 'www-servers/apache' These are the packages that would be merged, in order: Calculating dependencies... done! [ebuild R ] www-servers/apache-2.4.3:2 USE="ldap ssl threads -debug -doc (-selinux) -static -suexec" APACHE2_MODULES="actions alias auth_basic authn_alias authn_anon authn_core authn_dbm authn_file authz_core authz_dbm authz_groupfile authz_host authz_owner authz_user autoindex cache cgi cgid dav dav_fs dav_lock deflate dir env expires ext_filter file_cache filter headers include info log_config logio mime mime_magic negotiation rewrite setenvif socache_shmcb speling status unique_id unixd userdir usertrack vhost_alias -access_compat -asis -auth_digest -authn_dbd -cache_disk -cern_meta -charset_lite -dbd -dumpio -ident -imagemap -lbmethod_bybusyness -lbmethod_byrequests -lbmethod_bytraffic -lbmethod_heartbeat -log_forensic -proxy -proxy_ajp -proxy_balancer -proxy_connect -proxy_ftp -proxy_http -proxy_scgi -reqtimeout -slotmem_shm -substitute -version" APACHE2_MPMS="-event -itk -peruser -prefork -worker" 0 kB

以下がエラーメッセージ。

# apache2ctl start * apache2 has detected an error in your setup: AH00526: Syntax error on line 60 of /etc/apache2/modules.d/40_mod_ssl.conf: Invalid Mutex directory in argument file:/run/apache_ssl_mutex * ERROR: apache2 failed to start
このディレクトリは、/etc/apache2/modules.d/40_mod_ssl.conf内で
/etc/apache2/modules.d/40_mod_ssl.conf
## Inter-Process Session Cache: # Configure the SSL Session Cache: First the mechanism to use and second the # expiring timeout (in seconds). #SSLSessionCache dbm:/run/ssl_scache SSLSessionCache shmcb:/run/ssl_scache(512000) SSLSessionCacheTimeout 300 ## Semaphore: # Configure the path to the mutual exclusion semaphore the SSL engine uses # internally for inter-process synchronization. Mutex file:/run/apache_ssl_mutex ssl-cache
のように指定されている。
常時使用するのではないというのなら、 # mkdir /run/apache_ssl_mutex で済む話だが、これを毎回するというのも面倒だ。

解決策としては、

  1. /etc/init.d/apache2 を変更して、起動時に無ければ作成させる
  2. 設定ファイルの方でtmpfs(メモリ上のファイルシステム。システムを再起動する毎に削除される)以外の場所を設定する
が考えられるが、tmpfs以外ってのはHDDへの負担やパフォーマンスへの影響が心配なので、1の選択肢をとることにする。

/etc/init.d/apache2内のstart()とrestart()で呼び出すのもいいかもしれないが、今回は設定ファイルの問題として検出されているのでcheckconf()から呼び出されるcheckconfd()を編集することにした。
なお、決め打ちを避けるためディレクトリ名はsedで取得する。

/etc/init.d/apache2
CONFIGFILE="${CONFIGFILE:-/etc/apache2/httpd.conf}" [ "${CONFIGFILE#/}" = "${CONFIGFILE}" ] && CONFIGFILE="${SERVERROOT}/${CONFIGFILE}" if [ ! -r "${CONFIGFILE}" ]; then eerror "Unable to read configuration file: ${CONFIGFILE}" return 1 fi # ここから # Create mutex directory for mod_ssl. # Portage makes the directory in tmpfs at once, so it disappears after reboot. # For details, see http://forums.gentoo.org/viewtopic-t-939604-start-0.html MODSSL_MUTEX_DIR="$(sed -e '/^Mutex/!d;s!^Mutex *file:\(/[^ ]*\) *ssl-cache *$!\1!' /etc/apache2/modules.d/40_mod_ssl.conf)" if [ ! -d ${MODSSL_MUTEX_DIR} ]; then einfo "${MODSSL_MUTEX_DIR} does not exist. creating." mkdir "${MODSSL_MUTEX_DIR}" fi # ここまで APACHE2_OPTS="${APACHE2_OPTS} -d ${SERVERROOT}" APACHE2_OPTS="${APACHE2_OPTS} -f ${CONFIGFILE}" [ -n "${STARTUPERRORLOG}" ] && APACHE2_OPTS="${APACHE2_OPTS} -E ${STARTUPERRORLOG}"
こうすればおk。

一応diffも。

2012/10/14

生命と同様、限りあるデータを扱えてこそのプログラマなので、Lazy Kで有限リストを実装してみた。あとついでにfoldrも

はじめに注意

コードの途中で「こんなのどこから出てきたんだよ」というようなメモの断片があるだろうが、それはgistに俺がコツコツ貯めておいたコンビネータ達である。
あのくらいは時間さえあれば簡単に作れたりするので、解説はしない(或いは、いくつかには初めから解説が付いている)。
あと、consの作り方は昔記事書いたのでそっち参照。

有限リストをどう実装するか

まず、リスト終端をどう判定するかを考える。

  1. ((a . True) (b . True) (c . True) (x . False) <ゴミ>)
  2. ((True . a) (True . b) (True . c) (False . x) <ゴミ>)
  3. (3 a b c <ゴミ>)
  4. 要素自体を述語に渡す

…等が考えられるが、選択肢4は任意の数列や関数列等、あらゆるデータが含まれ得るリストでは実用的ではない。
(これは、実用的なリストには必ずメタデータが必要ということでもある。)
また1は要素の生成が面倒(car、つまり先に登場するパラメータが変数でcdrがほぼ固定のため)、3はリスト自体の生成が面倒(リストを数えるのと要素数の後に付けるのに、データが2度必要なため)ということで、ここでは2の方法を採用することにする。

とりあえず使えるように

とりあえず、Lazy K インタプリタから渡される入力をこの形式のリストに変換する関数を作る。
ご存知のとおり、Lazy Kでは標準入力のバイト列が、(cons a (cons b (cons c ...)))という形でプログラムに渡される。
そして入力の末端の位置には256が入っており、以降はいくら次の要素を取っても256しか出てこない。
つまりこの無限リストのそれぞれを、car部がTrue(=K)であるようなconsセルのcdr部に入れて、最初に出てきた256の位置にcar部がFalse(=KI)であるような任意のconsを置いておけば良い。
まあ普通はcarとcdrが同じ場合は K<要素> とするのが楽なので今回もそうしよう。
さて、とりあえず標準入力を有限リストに変換する関数を arg2list = ll とおこう。
ちなみに、llと置く理由は以下を見ればわかる。
再帰が必要なコンビネータを作るときは、だいたい別のあるコンビネータが2回登場するような形でおきなおす。

lla = (<lt_eq><256>(aK))(K(K(KI)))(<cons>(<cons>K(aK))(ll(a(KI)))) = <lt_eq><256>(RKa)(K(K(KI)))(<cons>(<cons>K(RKa))(ll(R(KI)a))) = S(K(<lt_eq><256>))(RK)a(K(K(KI))) (<cons>(A(<cons>K)(RK)a)(A(ll)(R(KI))a)) Sa(Kb)c -> acb = S(K(<lt_eq><256>))(RK)a (K(K(KI))) (A<cons>(A(<cons>K)(RK))a)( SA(K(R(KI)))(ll) a) = S(K(<lt_eq><256>))(RK)a (K(K(KI))) (S(A<cons>(A(<cons>K)(RK)))(SA(K(R(KI))))(ll)a) S(SP(KQ))Ta -> SP(KQ)a(Ta) -> Pa(KQa)(Ta) -> PaQ(Ta) = S(S( S(K(<lt_eq><256>))(RK) )(K(K(K(KI))))) (S(A<cons>(A(<cons>K)(RK)))(SA(K(R(KI)))(ll))) a = S(S(S(K(<lt_eq><256>))(RK))(K(K(K(KI)))))(S(A<cons>(A(<cons>K)(RK)))(SA(K(R(KI)))(SIIl))) a = S(S(S(K(<lt_eq><256>))(RK))(K(K(K(KI))))) (S(A<cons>(A(<cons>K)(RK))) (A(SA(K(R(KI))))(SII) l )) a S(Ka)(S(Kb)c)d -> a(b(cd)) = S(K(S(S(S(K(<lt_eq><256>))(RK))(K(K(K(KI))))))) (S(K (S(A<cons>(A(<cons>K)(RK))))) (A(SA(K(R(KI))))(SII))) l a = S(K(S(S(S(K(<lt_eq><256>))(SI(KK)))(K(K(K(KI))))))) (S(K(S(A<cons> (A(<cons>K)(SI(KK))) ))) (A (S(S(KS)K)(K(SI(K(KI))))) (SII))) l a = S(K(S(S(S(K(<lt_eq><256>))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(<cons>))(S(K(<cons>K))(SI(KK))))))(S(K(S(S(KS)K)(K(SI(K(KI))))))(SII))) la = S(K(S(S(S(K(<lt_eq><256>))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(K(S(SI(KK))))K))(SI(KK))))))(S(K(S(S(KS)K)(K(SI(K(KI))))))(SII))) la <lt_eq><256> = S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K<256>) = S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I)))) = S(K(S(S(S(K(S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I))))))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(K(S(SI(KK))))K))(SI(KK))))))(S(K(S(S(KS)K)(K(SI(K(KI))))))(SII))) la = SII(S(K(S(S(S(K(S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I))))))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(K(S(SI(KK))))K))(SI(KK))))))(S(K(S(S(KS)K)(K(SI(K(KI))))))(SII)))) a よって arg2list = SII(S(K(S(S(S(K(S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I))))))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(K(S(SI(KK))))K))(SI(KK))))))(S(K(S(S(KS)K)(K(SI(K(KI))))))(SII))))

また、別に確認としてもう一度やりなおしたら長さは同じだけど別の形のものが現れたので、参考までに記録しておく。

lla = (<lt_eq><256>(aK))(K(K(KI)))(<cons>(<cons>K(aK))(ll(a(KI)))) cons_ a b = (cons (cons K a) b) = S(K cons) (cons K) a b = S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K) a b = <lt_eq><256>(RKa)(K(K(KI)))(<cons_>(aK)(ll(a(KI)))) = A(<lt_eq><256>)(RK)a(K(K(KI)))(<cons_>(RKa)(ll(R(KI)a))) = A(<lt_eq><256>)(SI(KK))a(K(K(KI)))(<cons_>(SI(KK)a)(ll(SI(K(KI))a))) = S(K(<lt_eq><256>))(SI(KK)) a (K(K(KI)))(S(K(<cons_>))(SI(KK))a( SII l (SI(K(KI)) a) )) S(S(K(S(KS)K))a)(Kb)xy -> ax(by) = S(K(<lt_eq><256>))(SI(KK)) a (K(K(KI)))(S(K(<cons_>))(SI(KK))a( S(S(K(S(KS)K))(SII))(K(SI(K(KI))))la)) = S(K(<lt_eq><256>))(SI(KK)) a (K(K(KI)))(S (S(K(<cons_>))(SI(KK))) (S(S(K(S(KS)K))(SII))(K(SI(K(KI))))l) a) S(SP(KQ))Ta -> SP(KQ)a(Ta) -> Pa(KQa)(Ta) -> PaQ(Ta) (P = S(K(<lt_eq><256>))(SI(KK)), Q = K(K(KI)), T = S(S(K(<cons_>))(SI(KK)))(S(S(K(S(KS)K))(SII))(K(SI(K(KI))))l) ) = S(S (S(K(<lt_eq><256>))(SI(KK))) (K (K(K(KI))) ))( S(S(K(<cons_>))(SI(KK)))(S(S(K(S(KS)K))(SII))(K(SI(K(KI))))l) )a S(Ka)(S(Kb)c)d -> a(b(cd)) = S(K( S(S(S(K(<lt_eq><256>))(SI(KK)))(K(K(K(KI))))) ))(S(K( S(S(K(<cons_>))(SI(KK))) ))( S(S(K(S(KS)K))(SII))(K(SI(K(KI)))) )) l a cons_ a b = (cons (cons K a) b) = S(K cons) (cons K) a b = S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K) a b = S(K(S(S(S(K(<lt_eq><256>))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K)))(SI(KK)))))(S(S(K(S(KS)K))(SII))(K(SI(K(KI)))))) la <lt_eq><256> = S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K<256>) = S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I)))) = S(K(S(S(S(K(S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I))))))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K)))(SI(KK)))))(S(S(K(S(KS)K))(SII))(K(SI(K(KI)))))) la = SII(S(K(S(S(S(K(S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I))))))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K)))(SI(KK)))))(S(S(K(S(KS)K))(SII))(K(SI(K(KI))))))) a よって arg2list = SII(S(K(S(S(S(K(S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I))))))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K)))(SI(KK)))))(S(S(K(S(KS)K))(SII))(K(SI(K(KI)))))))

この形式のリストを lazy k インタプリタの出力、あるいは戻り値として返す関数はmapによって可能なので今はまだ作らない。

さて、これから filter やら map やら色々な関数を作るが、その度に再帰など書きたくないので、 foldr を最初に作ることにする。
また、以後Boolとa型の値のペアの配列を[a]と略記することにする。

Axyz = S(KS)Kxyz = x(yz), Rxy = S(K(SI))Kxy = yx とおいておく。 foldr :: (a -> b -> b) -> b -> [a] -> b foldr step zero list = if (caar list) then step (cdar list) (foldr step zero (cdr list)) else zero foldr = ff、step = t、zero = z、list = l とおくと ffszl = lKK (s (lK(KI)) (ffsz(l(KI)))) z Trueの場合とfalseの場合を入れ替える ( not a = a False True = a(KI)K ) = lKK (KI)K z (t (lK(KI)) (fftz(l(KI)))) = lKK(KI)K z (t (<cons>K(KI)l) (fftz(R(KI)l))) = lKK(KI)K z (t (<cons>K(KI)l) (SA(K(R(KI)))(fftz)l)) = lKK(KI)K z (t (<cons>K(KI)l) (SA(K(R(KI)))(SIIftz)l)) = lKK(KI)K z (t (<cons>K(KI)l) ( SA(K(SI(K(KI)))) (SIIftz) l )) a(bcde) <- Aa(bcd)e <- A(Aa)(bc)de <- A(A(Aa))bcde <- S(K(S(K(S(Ka)))))bcde = lKK(KI)K z (t (<cons>K(KI)l) (S(K(S(K(S(K (SA(K(SI(K(KI))))) ))))) (SII)ftz l )) b(ac) <- Abac <- SA(Ka)bc = <cons>KK l (KI)K z (SA(K(<cons>K(KI))) tl (S(K(S(K(S(K (SA(K(SI(K(KI))))) ))))) (SII)ftz l )) = <cons>(KI)K (<cons>KK l) z ( S (SA(K(<cons>K(KI)))t) (S(K(S(K(S(K (SA(K(SI(K(KI))))) ))))) (SII)ftz) l ) = S(K(<cons>(KI)K))(<cons>KK) lz ( S (SA(K(<cons>K(KI)))t) (S(K(S(K(S(K (SA(K(SI(K(KI))))) ))))) (SII)ftz) l ) P(Qt)(Ttz) <- P(AKQtz)(Ttz) <- P((AKQ)tz)(Ttz) <- S(K(S(KP)))(AKQ)tz(Ttz) <- S(S(KS)(S(K(S(KP)))(AKQ)))Ttz S(S(KS)a)bcd -> acd(bcd) S(S(KS)(S(K(S(KP)))(S(KK)Q)))Ttz -> P(Qt)(Ttz) ( P = S, Q = SA(K(<cons>K(KI))), T = S(K(S(K(S(K(SA(K(SI(K(KI))))))))))(SII)f = S(K(<cons>(KI)K))(<cons>KK) lz ( S(S(KS)(S(K(S(KS)))(S(KK)(SA(K(<cons>K(KI)))))))(S(K(S(K(S(K(SA(K(SI(K(KI))))))))))(SII)f) t zl ) P(Qt)(Ttz) <- P(AKQtz)(Ttz) <- P((AKQ)tz)(Ttz) <- S(K(S(KP)))(AKQ)tz(Ttz) <- S(S(KS)(S(K(S(KP)))(AKQ)))Ttz S(S(KS)a)bcd -> acd(bcd) S(S(KS)(S(K(S(KP)))((S(KS)K)KQ)))Ttz -> P(Qt)(Ttz) ( P = S, Q = SA(K(<cons>K(KI))), T = S(K(S(K(S(K(SA(K(SI(K(KI))))))))))(SII)f = S(K(<cons>(KI)K))(<cons>KK) lz ( S(S(KS)(S(K(S(KS)))(S(KK)(SA(K(<cons>K(KI)))))))(S(K(S(K(S(K(SA(K(SI(K(KI))))))))))(SII)f) t zl ) adc(bcd) <- Sa(Kc)d(bcd) <- A(Sa)Kcd(bcd) <- S(S(KS)(A(Sa)K))bcd <- S(S(KS)(S(K(Sa))K))bcd S(S(KS)(S(K(Sa))K))bcd -> adc(bcd) = S(S(KS)(S(K(S( S(K(<cons>(KI)K))(<cons>KK) )))K)) ( S(S(KS)(S(K(S(KS)))(S(KK)(SA(K(<cons>K(KI)))))))(S(K(S(K(S(K(SA(K(SI(K(KI))))))))))(SII)f) t) zl P(Q(Ta)b) <- P(AQTab) <- S(K(S(KP)))(AQT)ab <- S(K(S(KP)))(S(KQ)T)ab (P = S(S(KS)(S(K(S(S(K(<cons>(KI)K))(<cons>KK))))K)), Q = S(S(KS)(S(K(S(KS)))(S(KK)(SA(K(<cons>K(KI))))))), T = S(K(S(K(S(K(SA(K(SI(K(KI))))))))))(SII) = S(K(S(K( S(S(KS)(S(K(S(S(K(<cons>(KI)K))(<cons>KK))))K)) )))) (S(K( S(S(KS)(S(K(S(KS)))(S(KK)(SA(K(<cons>K(KI))))))) ))( S(K(S(K(S(K(SA(K(SI(K(KI))))))))))(SII) )) ftzl = S(K(S(K(S(S(KS)(S(K(S(S(K(S(SI(K(KI)))(KK)))(S(SI(KK))(KK)))))K))))))(S(K(S(S(KS)(S(K(S(KS)))(S(KK)(S(S(KS)K)(K(S(SI(KK))(K(KI))))))))))(S(K(S(K(S(K(S(S(KS)K)(K(SI(K(KI))))))))))(SII)))ftzl よって f = SII(S(K(S(K(S(S(KS)(S(K(S(S(K(S(SI(K(KI)))(KK)))(S(SI(KK))(KK)))))K))))))(S(K(S(S(KS)(S(K(S(KS)))(S(KK)(S(S(KS)K)(K(S(SI(KK))(K(KI))))))))))(S(K(S(K(S(K(S(S(KS)K)(K(SI(K(KI))))))))))(SII)))) foldr = SII(S(K(S(K(S(S(KS)(S(K(S(S(K(S(SI(K(KI)))(KK)))(S(SI(KK))(KK)))))K))))))(S(K(S(S(KS)(S(K(S(KS)))(S(KK)(S(S(KS)K)(K(S(SI(KK))(K(KI))))))))))(S(K(S(K(S(K(S(S(KS)K)(K(SI(K(KI))))))))))(SII))))

とりあえず cons_ a b = (cons (cons K a) b) = S(K cons) (cons K) a b = S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K) a b としておいて、 foldr cons (K <258>) (cons_ 2 (cons_ 1 (cons_ 0 (K(K(KI)))))) で実験してみる。(ちなみに、「K(K(KI))」は「(cons (cons (KI) (KI)) (cons (KI) (KI)))」と同値。)
こうすると、評価後には cons 2 (cons 1 (cons 0 (K <258>))) となり、結果出力にはバイナリで「0x02 0x01 0x00」が出て、終了コードは2になるはずである。
ちなみにコード全体はこんなかんじ。

K( SII(S(K(S(K(S(S(KS)(S(K(S(S(K(S(SI(K(KI)))(KK)))(S(SI(KK))(KK)))))K))))))(S(K(S(S(KS)(S(K(S(KS)))(S(KK)(S(S(KS)K)(K(S(SI(KK))(K(KI))))))))))(S(K(S(K(S(K(S(S(KS)K)(K(SI(K(KI))))))))))(SII)))) (S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)) (K (S(S(KS)K)(S(S(KS)K)(SII(SII(S(S(KS)K)I))))) ) (S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K) (S(S(KS)K)I) (S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K) I (S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(SI(KK))))K) (KI) (K(K(KI))) ))) )

…で、このコードは意図した通りに実行されたので、どうやらfoldrは完成っぽい。

次に、foldrの詳しいテストも兼ねてarg2listをテストしてみる。 foldr cons (K<256>) (arg2list arg) = S(K(<foldr><cons>(K<256>)))<arg2list> <arg> は入力を出力にそのまま垂れ流すはずである。
以下がコード。

# catらしきもの # <compose> (<foldr> <cons>(<cons> <256> <256>)) <arg2list> S(K( # <foldr> SII(S(K(S(K(S(S(KS)(S(K(S(S(K(S(SI(K(KI)))(KK)))(S(SI(KK))(KK)))))K))))))(S(K(S(S(KS)(S(K(S(KS)))(S(KK)(S(S(KS)K)(K(S(SI(KK))(K(KI))))))))))(S(K(S(K(S(K(S(S(KS)K)(K(SI(K(KI))))))))))(SII)))) # <cons> (S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)) # <cons> <256> <256> = K<256> (K(SII(SII(S(S(KS)K)I)))) )) # <arg2list> (SII(S(K(S(S(S(K(S(S(K(S(K(S(SI(K(K(KI))))(KK)))))(SI(K(S(K(S(K(S(K(SI(KI)))))))(S(K(S(S(KS)(S(KK)S))(KK)))(S(K(S(S(KS)K)(K(S(KK)K))))(SI(K(S(K(S(K(S(K(SI))K))))(SS(KI)))))))))))(K(SII(SII(S(S(KS)K)I))))))(SI(KK)))(K(K(K(KI)))))))(S(K(S(S(K(S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)))(S(K(S(K(S(SI(KK))))K))(SI(KK))))))(S(K(S(S(KS)K)(K(SI(K(KI))))))(SII)))))

これも意図したとおりに動作した。どうやら両方とも問題なさそうだ。
ご存知のとおり、foldrでmapやfilterやfoldl等様々な関数が実装できるので、別の記事で解説する。 …つもりだったけど、gist見てもらえばいいか。

2012/10/08

linux kernel 3.6の仮想マシンでwalkmanへの曲転送がうまくいかなかった件

原因が不明なのだが、とりあえず報告まで。

先に環境を記しておく。

% emerge --version Portage 2.2.0_alpha134 (default/linux/amd64/10.0/desktop, gcc-4.7.2, glibc-2.15-r3, 3.6.0-gentoo x86_64)

ゲストOSの方はvirtualbox-bin、ver 4.2.0 r80737にWindows XP SP3。

何が起きたか

まず、Xアプリ(ver3の最終版とver4.0どちらも)とSonicStage CPの両方からWALKMAN(NW-A856とNW-S739Fの両方)への曲の転送がうまくいかない。
具体的には、転送自体は完了するが、WALKMAN側の曲ファイルが壊れている。
mp3ファイルは原形を留めている曲もあるにはあるが聞くに堪えるものでなく、ATRAC Advanced Losslessに至っては再生すら出来ない始末。
また、そういった曲をxアプリから再生しようとすると、停止するまで音が出ずに固まるか、壊れた音(ところどころ音が飛んでいたり、雑音のみだったり様々)が再生されるか、「楽曲を再生できません。ファイルを確認してください。 (エラーコード: 00003b6e)」というエラーが表示されたり様々な場合がある。


一方、ファイルを普通にコピー(ホストのnautilusやゲストのexplorer.exeで)しても、ファイルの損壊は見られなかった。

とりあえず闘う

何が原因かわからなかったので、とりあえずxアプリをアンインストール後、再インストール。駄目。
SonicStage CPをインストールして、そちらから転送。駄目。
両方ともアンインストール後、Media Libraryとやら(xアプリと一緒に勝手に入る)を削除、 C:\Program Files\Common Files\Sony Shared\ と C:\Documents and Settings\All Users\Application Data\Sony Corporation\ を全て削除、その後再インストール(この時点で元のデータは消失しているので注意)。駄目。
OSをクリーンインストール、アップデート、xアプリをインストール。駄目。

もうこの辺りで、どうもゲストOSが原因では無いと考えざるを得なかった。

突然の解決

そうなると、あとはホスト側の問題だ。
最近VirtualBoxをアップデートした記憶はないが、kernelを3.5.0から3.6.0にしたくらいしか心当たりがなかったので、3.5.0で起動。そしたら正常に転送できてしまった…

簡単に書いてるけど、この過程で24時間以上はかかってるからね…
3.6.1では治ってることを祈って、genkernelしてきます ノシ

追記(2012/10/09)

残念ながら kernel 3.6.1 もダメだった…
オプションが悪いのか設計そのものが悪いのか、わからないのでバグ報告もできそうにない…
当面は 3.5.0 を使うことにしますorz

追記(2012/10/13)

残念ながら kernel 3.6.2 もダメだったが、3.5.4 だとうまくいった。
どうも 3.6系列全体の問題っぽい。あるいはkernelの問題ではなく単に相性が悪いだけか…?

追記(2012/10/31)

kernel 3.6.4、xアプリ ver. 5.0.00.10262 だとうまくいった。
同時にアップデートしたから、kernelとxアプリどちらの問題なのかわからなかった…
しかしxアプリ、ver.4.0からいきなりver.5.0にいったあたり、なにか大きな問題があったのかもしれない(想像だが)。

2012/09/25

CPS変換の練習をしてみた

(define (foldr fun x args) (if (null? args) x (fun (car args) (foldr fun x (cdr args))))) を、CPS変換して末尾再帰にしようとした記録。

このページ なんでも継続 を参考にする。

foldr 自身より外側にある関数適用は fun であることを意識してやると、ちょっと簡単になった。

概形
(define (foldr/cps fun x args cont) (if (null? args) (cont x) ; something... ))
変換後に最も外側に来る関数は foldr/cps である(というかそれが目的)。
(define (foldr/cps fun x args cont) (if (null? args) (cont x) (foldr/cps fun x (cdr args) ; something... ))
最後に計算される(=最も外側の) fun に、内側の foldr の結果(res とする)を渡せば最終結果となる。
最終結果は外側の foldr の引数 cont に渡して(渡されて)終了となる。
; 最終的に(たぶん最後らへんに)実行されてほしい式 (cont (fun (car args) res))
最終的に内側の foldr/cps の第4引数(cont)が実行されることになるが、cont は手続きであるから、上の式を lambda で包む。
また、内側の foldr の計算結果(res)は、この lambda (内側の foldr から見た第4引数 cont)へ引数として渡されることに注意。
; 内側の foldr/cps の第4引数(cont) (lambda (res) (cont (fun (car args) res)))
合体!もうほとんどできてる。
(define (foldr/cps fun x args cont) (if (null? args) (cont x) (foldr/cps fun x (cdr args) (lambda (res) (cont (fun (car args) res))))))) ))
これで完成!
(define (foldr/cps fun x args cont) (if (null? args) (cont x) (foldr/cps fun x (cdr args) (let ((a (car args))) ; lambdaの中に(car args)を入れると計算が遅延されてしまう気がした (lambda (res) (cont (fun a res))))))) ))

ちょちょいと動かしてみたが、どうやら正しく動作してるっぽい。保証はできないけど。

結論。俺は説明が下手だ。あと、たぶんCPSの本質が掴めてない。

jdkのヘッダにパスが通ってなくてemergeが失敗した話。

media-video/aacskeys のビルドに失敗した。
原因はわかっていた。

src/aacskeys.h:8:17: 致命的エラー: jni.h: そのようなファイルやディレクトリはありません

調べたところ、jniとはJava Native Interfaceの略らしい。ということはjdk関連である。
さて、jdkのヘッダが無いとのことだが、ヘッダは確かに存在しており、
$JDK_HOME/include
にある($JDK_HOMEはユーザごとに異なる。rootではシステム全体の設定になっている)。
さて、これがmake時のINCLUDESとかgccの-Iオプションとかに入れられれば良いのだが、一筋縄にはいきそうにない。

今回は、gccが自動で読みにいく環境変数をいじる。
まず、システムのデフォルトのJava VMをJDKに変更する。(デフォルトの環境変数の設定を変更するため。後述)
# java-config -L でリストが出るので、左の番号を覚えておいて、たとえば

1) IcedTea JDK 7.2.2.1 [icedtea-7] 2) Sun JDK 1.6.0.33 [sun-jdk-1.6] *) Sun JRE 1.6.0.33 [sun-jre-bin-1.6]
となっているなら、2番のVMにしたいので # java-config -S 2 というふうにする。

で、gccがヘッダファイルを探しにいくパスは、Cなら C_INCLUDE_PATH 、C++なら CPLUS_INCLUDE_PATH である。
この両方にJDKのヘッダを追加したいが、あまり関係のないパッケージまで影響が及ぶようなところを弄りたくない。
そこで、portageには目的のパッケージのmergeのときだけ環境変数を変えられるような仕組みがあるので、それを利用する。

まず、 /etc/portage/package.env (無ければ作る)に

/etc/portage/package.env
media-video/aacskeys use-jdk-jni-headers

の1行を追加する。んで、 /etc/portage/env/use-jdk-jni-headers (新規ファイル)は

/etc/portage/env/use-jdk-jni-headers
C_INCLUDE_PATH="${JDK_HOME}/include:${JDK_HOME}/include/linux" CPLUS_INCLUDE_PATH="${JDK_HOME}/include:${JDK_HOME}/include/linux"

といった内容にする。
ここで、システムのVMがJDKでないとき(jreとか)は ${JDK_HOME}/include が存在しないので、パスの指定の意味がなくなってしまうことに注意。

これでmergeしなおすと、この場合なら media-video/aacskeys のビルドのときだけ jni.h がデフォルトで探索されるパスに含まれる。

2012/08/12

SKIコンビネータにてConsを作るまで

俺が如何なる考え方にてSKIコンビネータにてConsを作ることができたかを記録しておく。
もっと別の経路でやれば短くなるのかもしれないが。

この記事はS(KS)KとかS(K(SI))Kとかが、見た瞬間に何なのかわかるくらいの人向けなので、わからない人は別のところで勉強してからが良いかと。
まあ知らなくても見てればわかる人にはわかるだろうけど。

目的物

今回作るのは、Cons。 (Cons a b) f → f a b となるように作る。
こうすることで Car=True=K , Cdr=False=KI=SK と表記できるのは周知の事実である。
また、これを求める途中で(Cons a b)全体(つまりcar部とcdr部が埋め込まれた状態)の表記も求めることになる。

前提

基本的にS,K,Iは大文字、それ以外の変数には小文字アルファベットをあてる。
また、頻出のコンビネータとして以下のものには特別に大文字のアルファベットをあてる。 Axyz → S(KS)Kxyz → S(Ka)bc → a(bc) Rxy → S(K(SI))Kxy → SI(Kx)y → yx 上記の式の途中経過(Rx=SI(Kx) など)も多用するので忘れないように。

また、Consなど名称を用いてコンビネータを指す場合は、引数は空白で区切って記すことにする。 Cons a b Car → a といった具合である。
また、一文字のコンビネータのみを用いる場合も、括弧によっては空白や改行を使用する。

作ってみる (引数組み込み済)

経路

今回は、 fxy ← Rxfy ← Bxyf を目標として考えてみる。
また、最初に(Cons x y)の表現を求めたのち、Consと引数を分離することにしよう。

Bxyf → Rxfy

ここで注目すべきは、引数の順番。
xyf(123)からxfy(132)となっている。ここで Cxyz → xzy となるようなコンビネータCあるいはCxyの表現(zはConsの第3引数にあたるので組み込んではいけないが、xとyは良い)が求まれば、見出しの式と比べて C(Rx)yf → Rxfy → fxy とできる。
さて、ここでxの出現する順番(最初)が変わらないのはヒントとなる。
以下のような発想ができるかどうかが、成功と失敗の分かれ目なのかもしれない。
とはいっても、A=S(KS)Kを試行錯誤で手作りしたことのある人には経験として染み付いた考えかただと思われるが。 Sxyz → xz(yz) よって Sx(Ky)z → xz(Kyz) → xzy 簡単である。

さて、これによってCxyの表現がわかる。 Sx(Ky)z → xzyより S(Rx)(Ky)z → (Rx)zy → zxy よって Rx=SI(Kx) より (Cons x y) = S(SI(Kx))(Ky) 結果が出た。実際に計算してみると、 (Cons x y) Car = S(SI(Kx))(Ky)K → SI(Kx)K(KyK) → IK(KxK)y → kxy → x (Cons x y) Cdr = S(SI(Kx))(Ky)(KI) → SI(Kx)(KI)(Ky(KI)) → I(KI)(Kx(KI))y → KIxy → y たしかに正しい。あっけないものだ。
しかし問題(というか面倒)なのはここからなのだ。

Cons単体を作ってみる

幸運なことに、上で求めたものではx,yとも1回ずつ、順番を変えずに出現している。 そこで、まずは少々変形して (Cons x y) = S(Rx)(Ky) ← ASRx(Ky) = (ASR)x (Ky) とした上で、 Dxy → ax(by) となるようなDを求めてみる。
もちろんここでは a=(ASR), b=K である。

Dxy → ax(by)

こういうのは、いつものやり方が一番スマートに求まるものなので、無理に工夫せず普通に求める。

D = Scd とすると Dxy = Scdxy → cx(dx)y c = A のとき cx(dx)y = Ax(dx)y → x(dxy)

y側はなんとかなりそう。xの左にも何か付ける。
ex(dxy) ← A(ex)(dx)y ← AAex(dx)y
という感じでどうだろうか。これだと c = AAe である

c = AAe のとき cx(dx)y = AAex(dx)y → A(ex)(dx)y → ex(dxy) この場合 e = a である。 ここで dxy→by 、すなわち dx→b となってほしい。 dx → b より d = Kb このとき c = AAe = S(KA)e = S(K(S(KS)K))a である。 よって D = Scd = S (S(K(S(KS)K))a) (Kb) である。実際、 Dxy = S(S(K(S(KS)K))a)(Kb)xy = S(AAa)(Kb)xy → AAax(Kbx)y → A(ax)by → ax(by)
さて、 a=(ASR) 、 b=K であるから a = ASR → S(KS)R = S(KS)(S(K(SI))K) より D = S(S(K(S(KS)K))a)(Kb) = S( S (K(S(KS)K)) (S(KS)(S(K(SI))K)) )(KK) すなわち Cons = S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)

これでConsが求まった。確認してみよう。

Cons x y z = S (S(K(S(KS)K))(S(KS)(S(K(SI))K))) (KK) x yz → S (K(S(KS)K)) (S(KS)(S(K(SI))K)) x (KKx) yz → K(S(KS)K)x (S (KS) (S(K(SI))K) x) Kyz → S(KS)K (KSx (S(K(SI))Kx)) Kyz → S (KS) K (S(S(K(SI))Kx)) Kyz → KS(S(S(K(SI))Kx)) (K(S(S(K(SI))Kx))) Kyz → S (K(S(S(K(SI))Kx))) K y z → K(S(S(K(SI))Kx))y (Ky) z → S (S(K(SI))Kx) (Ky) z → S (K(SI)) K x z (Kyz) → K(SI)x (Kx) z y → SIx(Kx) zy → I(Kx)(x(Kx)) zy → Kx(x(Kx)) zy → xzy 合っている。よかった。

以上によってConsをSKIコンビネータにて表すことができた。

まとめ

(Cons x y) = S(SI(Kx))(Ky) Cons = S(S(K(S(KS)K))(S(KS)(S(K(SI))K)))(KK)

おまけ

最初に書いたとおり True=Car , False=Cdr なので、Consを利用して Not が簡単に書ける。 Not: Not True → False Not False → True Not = (Cons False True) = S(SI(K(KI)))(KK) 棚からぼたもち的かも。

追記

もっと簡単な発想でcar部・cdr部組み込みのconsは作れますね。

C = (Cons x y) とおく。 Cf → fxy C = Sab とすると Cf = Sabf → af(bf) a = Scd とすると af(bf) = Scdf(bf) → cf(df)(bf) ここで cf = f , df = x , bf = yであればよいので c = I , d = Kx , b = Ky よって a = Scd = SI(Kx) よって C = Sab = S(SI(Kx))(Ky)

2012/08/03

[メモ] クイズの答え

『世界でもっとも強力な9のアルゴリズム』で頭を鍛える の答えがわかったのでメモ。
【条件】
部屋の中には事前に何の情報も共有していないあなた、友人と敵の3人が居る
2者間の内緒話はできない(友人に何かを伝えると、必ず敵にもその内容が知られる)
3人とも無限の種類の色(要素色)を持っている
2種類以上の要素色を混ぜて混合色をつくることができる
混合色の色合いは、要素色の種類とその含有量で決まる
混合色からどの要素色がどの割合で混ぜられているかを知ることはできない

【目的】
あなたと友人の2人だけにしか分からない、秘密の色を設定する
(あなたと友人で秘密の色がどんな色であるかを共有する)
答えはこう。
  1. Aさんが色1、色2を作成。色1のみを公開。
  2. Bさんが色3を作成。
  3. Aさんが色1+色2を公開。
  4. Bさんが色1+色3を公開。
  5. Aさんが色1+色3に、自分の秘密の色2を混ぜる。
  6. Bさんが色1+色2に、自分の秘密の色3を混ぜる。
AさんとBさんのみに共有される色は、色1+色2+色3。

2012/07/05

xorg-serverとかati-driversをアップデートするとXが起動しなくなった話。

x11-drivers/ati-drivers-12.6_beta 以降を入れて xorg-server もバージョンを上げると、Xが起動しなくなった。
その時のXのログ。

Xorg.0.log
[ 116.232] X.Org X Server 1.12.2 Release Date: 2012-05-29 [ 116.232] X Protocol Version 11, Revision 0 [ 116.232] Build Operating System: Linux 3.2.12-gentoo x86_64 Gentoo [ 116.232] Current Operating System: Linux kaputnik-gentoo 3.2.12-gentoo #1 SMP Tue Jun 19 23:15:38 JST 2012 x86_64 [ 116.232] Kernel command line: BOOT_IMAGE=/boot/kernel-genkernel-x86_64-3.2.12-gentoo root=UUID=708416de-8957-475f-a0a7-9bd4f3562e71 udev rootfstype=ext4 video=uvesafb:mtrr:3,ywrap,1920x1080-32@60 vga=0x37f [ 116.233] Build Date: 05 July 2012 09:20:42PM [ 116.233] [ 116.233] Current version of pixman: 0.26.2 [ 116.233] Before reporting problems, check http://wiki.x.org to make sure that you have the latest version. [ 116.233] Markers: (--) probed, (**) from config file, (==) default setting, (++) from command line, (!!) notice, (II) informational, (WW) warning, (EE) error, (NI) not implemented, (??) unknown. [ 116.233] (==) Log file: "/var/log/Xorg.0.log", Time: Thu Jul 5 21:27:04 2012 [ 116.233] (==) Using system config directory "/usr/share/X11/xorg.conf.d" [ 116.233] (==) No Layout section. Using the first Screen section. [ 116.233] (==) No screen section available. Using defaults. [ 116.233] (**) |-->Screen "Default Screen Section" (0) [ 116.233] (**) | |-->Monitor "" [ 116.233] (==) No monitor specified for screen "Default Screen Section". Using a default monitor configuration. [ 116.233] (==) Automatically adding devices [ 116.233] (==) Automatically enabling devices [ 116.233] (==) FontPath set to: /usr/share/fonts/misc/, /usr/share/fonts/TTF/, /usr/share/fonts/OTF/, /usr/share/fonts/Type1/, /usr/share/fonts/100dpi/, /usr/share/fonts/75dpi/ [ 116.233] (==) ModulePath set to "/usr/lib64/xorg/modules" [ 116.233] (II) The server relies on udev to provide the list of input devices. If no devices become available, reconfigure udev or disable AutoAddDevices. [ 116.233] (II) Loader magic: 0x7c6ac0 [ 116.233] (II) Module ABI versions: [ 116.233] X.Org ANSI C Emulation: 0.4 [ 116.233] X.Org Video Driver: 12.0 [ 116.233] X.Org XInput driver : 16.0 [ 116.233] X.Org Server Extension : 6.0 [ 116.234] (--) PCI:*(0:0:2:0) 8086:0102:1458:d000 rev 9, Mem @ 0xfb800000/4194304, 0xe0000000/268435456, I/O @ 0x0000ff00/64 [ 116.234] (II) Open ACPI successful (/var/run/acpid.socket) [ 116.234] (II) LoadModule: "extmod" [ 116.234] (II) Loading /usr/lib64/xorg/modules/extensions/libextmod.so [ 116.234] (II) Module extmod: vendor="X.Org Foundation" [ 116.234] compiled for 1.12.2, module version = 1.0.0 [ 116.234] Module class: X.Org Server Extension [ 116.234] ABI class: X.Org Server Extension, version 6.0 [ 116.234] (II) Loading extension MIT-SCREEN-SAVER [ 116.234] (II) Loading extension XFree86-VidModeExtension [ 116.234] (II) Loading extension XFree86-DGA [ 116.234] (II) Loading extension DPMS [ 116.234] (II) Loading extension XVideo [ 116.234] (II) Loading extension XVideo-MotionCompensation [ 116.234] (II) Loading extension X-Resource [ 116.234] (II) LoadModule: "dbe" [ 116.234] (II) Loading /usr/lib64/xorg/modules/extensions/libdbe.so [ 116.234] (II) Module dbe: vendor="X.Org Foundation" [ 116.234] compiled for 1.12.2, module version = 1.0.0 [ 116.234] Module class: X.Org Server Extension [ 116.234] ABI class: X.Org Server Extension, version 6.0 [ 116.234] (II) Loading extension DOUBLE-BUFFER [ 116.234] (II) LoadModule: "glx" [ 116.234] (II) Loading /usr/lib64/xorg/modules/extensions/libglx.so [ 116.234] (II) Module glx: vendor="X.Org Foundation" [ 116.234] compiled for 1.12.2, module version = 1.0.0 [ 116.234] ABI class: X.Org Server Extension, version 6.0 [ 116.234] (==) AIGLX enabled [ 116.234] (II) Loading extension GLX [ 116.234] (II) LoadModule: "record" [ 116.234] (II) Loading /usr/lib64/xorg/modules/extensions/librecord.so [ 116.234] (II) Module record: vendor="X.Org Foundation" [ 116.234] compiled for 1.12.2, module version = 1.13.0 [ 116.234] Module class: X.Org Server Extension [ 116.234] ABI class: X.Org Server Extension, version 6.0 [ 116.234] (II) Loading extension RECORD [ 116.235] (II) LoadModule: "dri" [ 116.235] (II) Loading /usr/lib64/xorg/modules/extensions/libdri.so [ 116.235] (II) Module dri: vendor="X.Org Foundation" [ 116.235] compiled for 1.12.2, module version = 1.0.0 [ 116.235] ABI class: X.Org Server Extension, version 6.0 [ 116.235] (II) Loading extension XFree86-DRI [ 116.235] (II) LoadModule: "dri2" [ 116.235] (II) Loading /usr/lib64/xorg/modules/extensions/libdri2.so [ 116.235] (II) Module dri2: vendor="X.Org Foundation" [ 116.235] compiled for 1.12.2, module version = 1.2.0 [ 116.235] ABI class: X.Org Server Extension, version 6.0 [ 116.235] (II) Loading extension DRI2 [ 116.235] (==) Matched intel as autoconfigured driver 0 [ 116.235] (==) Matched vesa as autoconfigured driver 1 [ 116.235] (==) Matched fbdev as autoconfigured driver 2 [ 116.235] (==) Assigned the driver to the xf86ConfigLayout [ 116.235] (II) LoadModule: "intel" [ 116.235] (II) Loading /usr/lib64/xorg/modules/drivers/intel_drv.so [ 116.235] (II) Module intel: vendor="X.Org Foundation" [ 116.235] compiled for 1.11.4, module version = 2.19.0 [ 116.235] Module class: X.Org Video Driver [ 116.235] ABI class: X.Org Video Driver, version 11.0 [ 116.235] (EE) module ABI major version (11) doesn't match the server's version (12) [ 116.235] (II) UnloadModule: "intel" [ 116.235] (II) Unloading intel [ 116.235] (EE) Failed to load module "intel" (module requirement mismatch, 0) [ 116.235] (II) LoadModule: "vesa" [ 116.235] (WW) Warning, couldn't open module vesa [ 116.235] (II) UnloadModule: "vesa" [ 116.235] (II) Unloading vesa [ 116.235] (EE) Failed to load module "vesa" (module does not exist, 0) [ 116.235] (II) LoadModule: "fbdev" [ 116.236] (WW) Warning, couldn't open module fbdev [ 116.236] (II) UnloadModule: "fbdev" [ 116.236] (II) Unloading fbdev [ 116.236] (EE) Failed to load module "fbdev" (module does not exist, 0) [ 116.236] (EE) No drivers available. [ 116.236] Fatal server error: [ 116.236] no screens found [ 116.236] Please consult the The X.Org Foundation support at http://wiki.x.org for help. [ 116.236] Please also check the log file at "/var/log/Xorg.0.log" for additional information. [ 116.236]

ログの [ 116.235] (EE) module ABI major version (11) doesn't match the server's version (12) の部分から、モジュールがコンパイルされた時点とati-drivers, xorg-server等がコンパイルされた時点での gccのバージョンか何かの違いが原因だと推測。
$ qlist -I -C x11-drivers/ | xargs sudo emerge -1 を実行。再起動後、Xが正常に起動することを確認した。

追記 (2012/11/07)

module-rebuildなる便利なツールがあったのを忘れていた。 $ sudo module-rebuild rebuild で、必要なパッケージだけが再度buildされる。こっちを使うべき。

2012/07/02

xsessionでログインしたくなった

本当は xmonad.hs に書いてしまいたかったが、Ubuntuとgentooで共有するからには、コマンドの存在次第で分岐とか必要そうだったので、 ~/.xsession を使うことにした。その時のメモ。

  1. ~/.xsession を書く。無ければ作る。
  2. chmod +x ~/.xsession する。
  3. x11-apps/xsm と net-misc/keychain をmergeする。
  4. have fun!

こんな感じ。Ubuntuだともっと楽だった気がするけど、もう憶えてないのでパスで。

2012/05/15

zshで這いよられてみる

https://twitter.com/#!/Manabii_R/status/197645984208134144にインスパイアされて作ってみた。

u_nyah.sh
#!/bin/zsh export u_nyah_count=${u_nyah_count:-"1"} u_nyah_prompt() { pstr[1]='(」・ω・)」うー! ' pstr[2]='(/・ω・)/にゃー!' pstr[3]='(」・ω・)」うー! ' pstr[4]='(/・ω・)/にゃー!' pstr[5]='(」・ω・)」うー! ' pstr[6]='(/・ω・)/にゃー!' pstr[7]="Let'\(・ω・)/にゃー!" RPROMPT="$pstr[$u_nyah_count]" u_nyah_count=$(( $u_nyah_count + 1 )) if [ $u_nyah_count -gt 7 ] ; then export u_nyah_count=$(( $u_nyah_count - 7 )) fi } precmd_functions=($precmd_functions u_nyah_prompt)

使うには、source u_nyah.shするか、上の内容のshebang行を取り除いて~/.zshrcに突っ込む。
かんたん!

Let'\(・ω・)/にゃー!

2012/05/11

gentooでcpufreqを動かす

cpufreqdとかをインスコしてから何をすればいいかのメモ。
設定ファイルとかは省略。どっか他のページをggってくださいな

自動で起動するように

# sudo rc-update add cpufreqd default これでおk。

モジュールを自動でロード

これに引っ掛って苦労した…
ここの作業を抜くと、起動時に

 * cpufreqd requires the kernel to be configured with CONFIG_CPU_FREQ
 * Make sure that the appropiate kernel drivers for your CPU are
 * built-in or loaded.
 * ERROR: cpufreqd failed to start
とエラーが出る。

まず、現在のcpuの動作周波数を確認するのには $ cat /proc/cpuinfo | awk -F':' '$1~/^cpu MHz */{print $1}' でわかる。
さて、cpufreqdはカーネルにモジュールをロードしなければ動作しないらしい。
$ sudo depmod -n | grep -i cpu してみると、
alias acpi acpi_cpufreq
などという行があったので、 $ sudo modprobe acpi した瞬間、クロックが変化しだした。
どうやら俺の場合はこれでビンゴだったようだ。
あとは # vim /etc/conf.d/modules とでもして modules="vboxdrv acpi" といった感じでacpiを追加すれば完了。

Ubuntuでオフラインでの起動時に120秒待たされる原因がわかった

唐突だが、俺が使っているメインの娘はリビングにある。
そしてルータは最も遠い、親父の部屋にある。
つまり親父の作業中(だいたいは休日だが)はLANケーブルを引っこぬかれるのである。
つまりUbuntuで俺は休日の起動に120秒待たされる。
オフラインで起動したことがあるなら、「Waiting up to 60 more seconds for network configuration...」などというメッセージを見たことがあるはずだ。
今回Ubuntu12.04LTSを入れて再設定したところで存在を思いだしたので、原因の設定と解決法をここにメモしておく。

面倒なので、変更点の周辺のみを貼っておく。

/etc/init/failsafe.conf
# The point here is to wait for 2 minutes before forcibly booting # the system. Anything that is in an "or" condition with 'started # failsafe' in rc-sysinit deserves consideration for mentioning in # these messages. currently only static-network-up counts for that. sleep 20 # Plymouth errors should not stop the script because we *must* reach # the end of this script to avoid letting the system spin forever # waiting on it to start. $PLYMOUTH message --text="Waiting for network configuration..." || : #sleep 40 sleep 15 #$PLYMOUTH message --text="Waiting up to 60 more seconds for network configuration..." || : #sleep 59 $PLYMOUTH message --text="Booting system without full network configuration..." || : # give user 1 second to see this message since plymouth will go # away as soon as failsafe starts. sleep 1 exec initctl emit --no-wait failsafe-boot

丁寧な解説がはじめから付いているうえ元のコードもコメントアウトしてあるのでわかると思うが、このsleepというのが犯人である。
本来はネットワークが使用可能になるまで待機するためのものなのだろうが、オフラインでの起動でそれはありえないので時間を短くする。
ついでに、このplymouthというのはUbuntuの起動時のロゴと5つの点のスプラッシュ画面のやつらしい。

2012/03/19

jQueryのload()とdocument.write()の共存

個人情報さらしてみる。
このページを管理している(現時点)のは俺なんだが、jQueryを使い始めた当時は何故か、真っ白なページに
Powered by FC2.com
とだけ表示されていて、大いに困った。いえでもちょろめでも火狐でもこうなる。
火狐に至っては「wyciwyg://103//http://~~」とかわけのわからんパスに飛ばされる始末。
で、最終的になんとかこのトラブルを(とりあえず)解決したのでここに記録しておく。

ずっと「読み込み中」だからFirebugが使えない、しかもwyciwyg://って…

ローカルの鯖(Apache)では正しく動作していたのに、リモートでは動かない。
プログラミングではよくあることだと自分をなだめつつ調査開始。

まず、一瞬あるべき姿のページが表示されたのち、ページがリセットされて「Powered by FC2」の一行のみになる。
アドレスバーを見るも、以上は無さそうだが、なぜかFirebugとかがページを移動したときと同じ挙動をする。
履歴を見てみると、なんと「wyciwyg://##/http://~~~」となっていて、##の部分は毎回数字が変わる。
そこで「"wyciwyg://"」をggr。すると「wyciwyg://」ドキュメントへの不正アクセスというのが引っかかった。
(ついでに、「WYCIWYG」は"What You Cache Is What You Get"らしい。(→Wikipedia))
でもこれMozillaってことは、Firefoxじゃん。しかも
「修正済みのバージョン Firefox 2.0.0.5」
ふ・ざ・け・る・な!

「Powered by FC2」ェ…

これは手がかりにならないので、ChromeとIEで見てみると、やっぱりFirefoxと同じ症状(ただしwicywigではないが)。
仕方ないのでfc2鯖との相違点を探す。てか一行広告しかないじゃん。
てことで一行広告を調べる。
どうやらbody要素の最後に次の内容が入るようだ。

<script type="text/javascript"><!-- var fhp_c_pc = navigator.userAgent.toLowerCase(); var fhp_ie = ((fhp_c_pc.indexOf("msie") != -1) && (fhp_c_pc.indexOf("opera") == -1)); var fhp_cs, fhp_wt, fhp_dm; if (fhp_ie) { fhp_cs = document.charset; }else{ fhp_cs = document.characterSet; } fhp_dm = encodeURI(document.location); fhp_wt = ""; fhp_wt = '<' + 'script src="http://web.fc2.com/header.php?cs=' + fhp_cs + '&dm=' + fhp_dm + '" charset="UTF-8"><' + '/script>'; fhp_wt += '<' + 'script src="http://web.fc2.com/footer/footer.php?cs=' + fhp_cs + '&dm=' + fhp_dm + '"><' + '/script>'; document.write(fhp_wt); //--></script> <!-- FC2, inc.--> <img src="http://media.fc2.com/counter_img.php?id=50" style="visibility:hidden" alt="inserted by FC2 system" width="0" height="0" /> <!-- FC2, inc.-->

なんで直接入れないんだよ… これがさらに展開されて、document.write()で追記される。

http://web.fc2.com/header.php
fhp_head='';
web.fc2.com/footer/footer.php
//http://kesc.web.fc2.com/ document.write('<div id=\"fc2_footer\">'+"\n"); document.write('<span style=\"font-size:12px;\">'+"\n"); document.write('<br>'+"\n"); document.write('Powered by <a target=\"_blank\" href=\"http://fc2.com/\">FC2.com</a>'+"\n"); document.write('</span>'+"\n"); document.write('</div>'+"\n"); document.write(''+"\n"); move_fc2_footer(); function move_fc2_footer(){ if(!document.getElementById("fc2_footer")){return;}; var ff=document.getElementById("fc2_footer"); ff.style.textAlign="center"; ff.style.width="100%"; ff.style.lineHeight="14px"; }

開始タグと終了タグが別々に…
こういうのは処理系を開発する側としては辛いんだけどな…
というか、DOMがどうとか言ってるこのご時勢に、document.write()とかアリなのか?

そもそもdocument.write()がだな

再びggったところ、どうやらdocument.write()自体は問題ないらしい。
仕方ないので、htmlに仕込んだスクリプトをコメントアウトしながら原因調査。すると…
$(~).load()を入れるとdocument.write()のタイミングでおかしくなることが発覚。
やっぱAjaxとは相性悪いんだな…

しかし大人の社会とやらは

しかし、「相性が悪い」という理由で広告を消してしまうと契約違反なので、がんばってdocument.write()を動かさなければならない。
どうするか。
document.writeをオーバーライドするしかない。
普通に考えれば、

  1. document.write()の引数の文字列をためていく
  2. すべて読み終わったらタグ生成&表示
となりそうだが、ここで問題が。
document.write()で出力したscriptタグの内容って、もう一度document.write()を呼ぶんじゃね?
こりゃ参った。正攻法でなんとかしようと思ったら、かなり面倒になる。

というわけで、手抜きしました。

document.write()で開始と終了タグを別々に出力するとはいっても、たかが何ミリ秒のレベルだろ?
というわけで、

  1. はじめの書き込みから1000ms間は溜める
  2. 出力。以降は、2000msごとに出力
というかんじのスクリプトを組んだ。
iframeとかで読んだ別のページでもdocument.write()されても親の方に表示されてしまったりするが、現状では困ってないので無視。

jquery_use.js
var __tl_internal_document_write={cntnow:5,str:[],ready:false, add:function(str){ __tl_internal_document_write.str[__tl_internal_document_write.cntnow]+=str; }, show:function(){ if(__tl_internal_document_write.cntnow>0){ $(__tl_internal_document_write.str[__tl_internal_document_write.cntnow]).appendTo($(document.body)); __tl_internal_document_write.str[__tl_internal_document_write.cntnow--]=""; setTimeout(__tl_internal_document_write.show,2000); }else{ __tl_internal_document_write.cntnow=4; } }, fn:function(str){ __tl_internal_document_write.add(str); if(__tl_internal_document_write.ready){ setTimeout(__tl_internal_document_write.show,1000); } } }; // __tl_internal_document_write document.write=__tl_internal_document_write.fn; $(function(){ __tl_internal_document_write.ready=true; __tl_internal_document_write.show(""); });